Example #1
0
    def chdir_llimpl(path):
        """This is a reimplementation of the C library's chdir function,
        but one that produces Win32 errors instead of DOS error codes.
        chdir is essentially a wrapper around SetCurrentDirectory; however,
        it also needs to set "magic" environment variables indicating
        the per-drive current directory, which are of the form =<drive>:
        """
        if not win32traits.SetCurrentDirectory(path):
            raise rwin32.lastWindowsError()
        MAX_PATH = rwin32.MAX_PATH
        assert MAX_PATH > 0

        with traits.scoped_alloc_buffer(MAX_PATH) as path:
            res = win32traits.GetCurrentDirectory(MAX_PATH + 1, path.raw)
            if not res:
                raise rwin32.lastWindowsError()
            res = rffi.cast(lltype.Signed, res)
            assert res > 0
            if res <= MAX_PATH + 1:
                new_path = path.str(res)
            else:
                with traits.scoped_alloc_buffer(res) as path:
                    res = win32traits.GetCurrentDirectory(res, path.raw)
                    if not res:
                        raise rwin32.lastWindowsError()
                    res = rffi.cast(lltype.Signed, res)
                    assert res > 0
                    new_path = path.str(res)
        if isUNC(new_path):
            return
        if not win32traits.SetEnvironmentVariable(magic_envvar(new_path), new_path):
            raise rwin32.lastWindowsError()
Example #2
0
 def os_utime_llimpl(path, tp):
     hFile = CreateFile(path,
                        FILE_WRITE_ATTRIBUTES, 0,
                        None, OPEN_EXISTING,
                        FILE_FLAG_BACKUP_SEMANTICS,
                        rwin32.NULL_HANDLE)
     if hFile == rwin32.INVALID_HANDLE_VALUE:
         raise rwin32.lastWindowsError()
     ctime = lltype.nullptr(rwin32.FILETIME)
     atime = lltype.malloc(rwin32.FILETIME, flavor='raw')
     mtime = lltype.malloc(rwin32.FILETIME, flavor='raw')
     try:
         if tp is None:
             now = lltype.malloc(rwin32.SYSTEMTIME, flavor='raw')
             try:
                 GetSystemTime(now)
                 if (not SystemTimeToFileTime(now, atime) or
                     not SystemTimeToFileTime(now, mtime)):
                     raise rwin32.lastWindowsError()
             finally:
                 lltype.free(now, flavor='raw')
         else:
             actime, modtime = tp
             time_t_to_FILE_TIME(actime, atime)
             time_t_to_FILE_TIME(modtime, mtime)
         if not SetFileTime(hFile, ctime, atime, mtime):
             raise rwin32.lastWindowsError()
     finally:
         rwin32.CloseHandle(hFile)
         lltype.free(atime, flavor='raw')
         lltype.free(mtime, flavor='raw')
Example #3
0
    def do_poll(self, space, timeout):
        from pypy.module._multiprocessing.interp_win32 import (
            _PeekNamedPipe, _GetTickCount, _Sleep)
        from rpython.rlib import rwin32
        from pypy.interpreter.error import wrap_windowserror
        bytes_ptr = lltype.malloc(rffi.CArrayPtr(rwin32.DWORD).TO, 1,
                                 flavor='raw')
        try:
            if not _PeekNamedPipe(self.handle, rffi.NULL, 0,
                                  lltype.nullptr(rwin32.LPDWORD.TO),
                                  bytes_ptr,
                                  lltype.nullptr(rwin32.LPDWORD.TO)):
                raise wrap_windowserror(space, rwin32.lastWindowsError())
            bytes = bytes_ptr[0]
        finally:
            lltype.free(bytes_ptr, flavor='raw')

        if timeout == 0.0:
            return bytes > 0

        block = timeout < 0
        if not block:
            # XXX does not check for overflow
            deadline = intmask(_GetTickCount()) + int(1000 * timeout + 0.5)
        else:
            deadline = 0

        _Sleep(0)

        delay = 1
        while True:
            bytes_ptr = lltype.malloc(rffi.CArrayPtr(rwin32.DWORD).TO, 1,
                                     flavor='raw')
            try:
                if not _PeekNamedPipe(self.handle, rffi.NULL, 0,
                                      lltype.nullptr(rwin32.LPDWORD.TO),
                                      bytes_ptr,
                                      lltype.nullptr(rwin32.LPDWORD.TO)):
                    raise wrap_windowserror(space, rwin32.lastWindowsError())
                bytes = bytes_ptr[0]
            finally:
                lltype.free(bytes_ptr, flavor='raw')

            if bytes > 0:
                return True

            if not block:
                now = intmask(_GetTickCount())
                if now > deadline:
                    return False
                diff = deadline - now
                if delay > diff:
                    delay = diff
            else:
                delay += 1

            if delay >= 20:
                delay = 20
            _Sleep(delay)
Example #4
0
 def chmod_llimpl(path, mode):
     attr = win32traits.GetFileAttributes(path)
     if attr == win32traits.INVALID_FILE_ATTRIBUTES:
         raise rwin32.lastWindowsError()
     if mode & 0200: # _S_IWRITE
         attr &= ~win32traits.FILE_ATTRIBUTE_READONLY
     else:
         attr |= win32traits.FILE_ATTRIBUTE_READONLY
     if not win32traits.SetFileAttributes(path, attr):
         raise rwin32.lastWindowsError()
Example #5
0
    def do_recv_string(self, space, buflength, maxlength):
        from pypy.module._multiprocessing.interp_win32 import (
            _ReadFile, _PeekNamedPipe, ERROR_BROKEN_PIPE, ERROR_MORE_DATA)
        from rpython.rlib import rwin32
        from pypy.interpreter.error import wrap_windowserror

        read_ptr = lltype.malloc(rffi.CArrayPtr(rwin32.DWORD).TO, 1,
                                 flavor='raw')
        left_ptr = lltype.malloc(rffi.CArrayPtr(rwin32.DWORD).TO, 1,
                                 flavor='raw')
        try:
            result = _ReadFile(self.handle,
                               self.buffer, min(self.BUFFER_SIZE, buflength),
                               read_ptr, rffi.NULL)
            if result:
                return intmask(read_ptr[0]), lltype.nullptr(rffi.CCHARP.TO)

            err = rwin32.GetLastError()
            if err == ERROR_BROKEN_PIPE:
                raise OperationError(space.w_EOFError, space.w_None)
            elif err != ERROR_MORE_DATA:
                raise wrap_windowserror(space, WindowsError(err, "_ReadFile"))

            # More data...
            if not _PeekNamedPipe(self.handle, rffi.NULL, 0,
                                  lltype.nullptr(rwin32.LPDWORD.TO),
                                  lltype.nullptr(rwin32.LPDWORD.TO),
                                  left_ptr):
                raise wrap_windowserror(space, rwin32.lastWindowsError())

            length = intmask(read_ptr[0] + left_ptr[0])
            if length > maxlength: # bad message, close connection
                self.flags &= ~READABLE
                if self.flags == 0:
                    self.close()
                raise OperationError(space.w_IOError, space.wrap(
                    "bad message length"))

            newbuf = lltype.malloc(rffi.CCHARP.TO, length + 1, flavor='raw')
            for i in range(read_ptr[0]):
                newbuf[i] = self.buffer[i]

            result = _ReadFile(self.handle,
                               rffi.ptradd(newbuf, read_ptr[0]), left_ptr[0],
                               read_ptr, rffi.NULL)
            if not result:
                rffi.free_charp(newbuf)
                raise wrap_windowserror(space, rwin32.lastWindowsError())

            assert read_ptr[0] == left_ptr[0]
            return length, newbuf
        finally:
            lltype.free(read_ptr, flavor='raw')
            lltype.free(left_ptr, flavor='raw')
Example #6
0
def ExpandEnvironmentStrings(source):
    with rffi.scoped_unicode2wcharp(source) as src_buf:
        size = _ExpandEnvironmentStringsW(src_buf,
                                          lltype.nullptr(rffi.CWCHARP.TO), 0)
        if size == 0:
            raise rwin32.lastWindowsError("ExpandEnvironmentStrings")
        size = intmask(size)
        with rffi.scoped_alloc_unicodebuffer(size) as dest_buf:
            if _ExpandEnvironmentStringsW(src_buf,
                                          dest_buf.raw, size) == 0:
                raise rwin32.lastWindowsError("ExpandEnvironmentStrings")
            return dest_buf.str(size - 1) # remove trailing \0
Example #7
0
def ConnectNamedPipe(space, w_handle, w_overlapped):
    handle = handle_w(space, w_handle)
    overlapped = space.int_w(w_overlapped)
    if overlapped:
        raise OperationError(space.w_NotImplementedError,
                             space.wrap("expected a NULL pointer"))
    if not _ConnectNamedPipe(handle, rffi.NULL):
        raise wrap_windowserror(space, rwin32.lastWindowsError())
Example #8
0
    def resize(self, newsize):
        if _POSIX:
            if not has_mremap:
                raise RValueError("mmap: resizing not available--no mremap()")

            # resize the underlying file first
            os.ftruncate(self.fd, self.offset + newsize)

            # now resize the mmap
            newdata = c_mremap(self.getptr(0), self.size, newsize,
                               MREMAP_MAYMOVE or 0)
            self.setdata(newdata, newsize)
        elif _MS_WINDOWS:
            # disconnect the mapping
            self.unmap()
            rwin32.CloseHandle(self.map_handle)

            # move to the desired EOF position
            if _64BIT:
                newsize_high = (self.offset + newsize) >> 32
                newsize_low = (self.offset + newsize) & 0xFFFFFFFF
                offset_high = self.offset >> 32
                offset_low = self.offset & 0xFFFFFFFF
            else:
                newsize_high = 0
                newsize_low = self.offset + newsize
                offset_high = 0
                offset_low = self.offset

            FILE_BEGIN = 0
            high_ref = lltype.malloc(PLONG.TO, 1, flavor='raw')
            try:
                high_ref[0] = rffi.cast(LONG, newsize_high)
                SetFilePointer(self.file_handle, newsize_low, high_ref,
                               FILE_BEGIN)
            finally:
                lltype.free(high_ref, flavor='raw')
            # resize the file
            SetEndOfFile(self.file_handle)
            # create another mapping object and remap the file view
            res = CreateFileMapping(self.file_handle, NULL, PAGE_READWRITE,
                                    newsize_high, newsize_low, self.tagname)
            self.map_handle = res

            if self.map_handle:
                data = MapViewOfFile(self.map_handle, FILE_MAP_WRITE,
                                     offset_high, offset_low, newsize)
                if data:
                    # XXX we should have a real LPVOID which must always be casted
                    charp = rffi.cast(LPCSTR, data)
                    self.setdata(charp, newsize)
                    return
            winerror = rwin32.lastWindowsError()
            if self.map_handle:
                rwin32.CloseHandle(self.map_handle)
            self.map_handle = INVALID_HANDLE
            raise winerror
Example #9
0
    def urandom(context, n):
        provider = context[0]
        if not provider:
            # This handle is never explicitly released. The operating
            # system will release it when the process terminates.
            if not CryptAcquireContext(
                context, None, None,
                PROV_RSA_FULL, CRYPT_VERIFYCONTEXT):
                raise rwin32.lastWindowsError("CryptAcquireContext")
            provider = context[0]
        # TODO(win64) This is limited to 2**31
        with lltype.scoped_alloc(rffi.CArray(rwin32.BYTE), n,
                                 zero=True, # zero seed
                                 ) as buf:
            if not CryptGenRandom(provider, n, buf):
                raise rwin32.lastWindowsError("CryptGenRandom")

            return rffi.charpsize2str(rffi.cast(rffi.CCHARP, buf), n)
Example #10
0
 def semlock_getvalue(self, space):
     if rwin32.WaitForSingleObject(self.handle, 0) == rwin32.WAIT_TIMEOUT:
         return 0
     previous_ptr = lltype.malloc(rffi.LONGP.TO, 1, flavor='raw')
     try:
         if not _ReleaseSemaphore(self.handle, 1, previous_ptr):
             raise rwin32.lastWindowsError("ReleaseSemaphore")
         return previous_ptr[0] + 1
     finally:
         lltype.free(previous_ptr, flavor='raw')
Example #11
0
 def getfullpathname_llimpl(path):
     nBufferLength = rwin32.MAX_PATH + 1
     lpBuffer = lltype.malloc(traits.CCHARP.TO, nBufferLength, flavor='raw')
     try:
         res = win32traits.GetFullPathName(
             path, rffi.cast(rwin32.DWORD, nBufferLength),
             lpBuffer, lltype.nullptr(win32traits.LPSTRP.TO))
         if res == 0:
             raise rwin32.lastWindowsError("_getfullpathname failed")
         result = traits.charp2str(lpBuffer)
         return result
     finally:
         lltype.free(lpBuffer, flavor='raw')
Example #12
0
def CreateNamedPipe(space, name, openmode, pipemode, maxinstances,
                    outputsize, inputsize, timeout, w_security):
    security = space.int_w(w_security)
    if security:
        raise OperationError(space.w_NotImplementedError,
                             space.wrap("expected a NULL pointer"))
    handle = _CreateNamedPipe(
        name, openmode, pipemode, maxinstances,
        outputsize, inputsize, timeout, rffi.NULL)

    if handle == rwin32.INVALID_HANDLE_VALUE:
        raise wrap_windowserror(space, rwin32.lastWindowsError())

    return w_handle(space, handle)
Example #13
0
def CreateFile(space, filename, access, share, w_security,
               disposition, flags, w_templatefile):
    security = space.int_w(w_security)
    templatefile = space.int_w(w_templatefile)
    if security or templatefile:
        raise OperationError(space.w_NotImplementedError,
                             space.wrap("expected a NULL pointer"))

    handle = _CreateFile(filename, access, share, rffi.NULL,
                         disposition, flags, rwin32.NULL_HANDLE)

    if handle == rwin32.INVALID_HANDLE_VALUE:
        raise wrap_windowserror(space, rwin32.lastWindowsError())

    return w_handle(space, handle)
Example #14
0
    class GlobalState:
        def __init__(self):
            self.init()

        def init(self):
            self.interrupt_event = rwin32.NULL_HANDLE

        def startup(self, space):
            # Initialize the event handle used to signal Ctrl-C
            try:
                globalState.interrupt_event = rwin32.CreateEvent(
                    rffi.NULL, True, False, rffi.NULL)
            except WindowsError, e:
                raise wrap_windowserror(space, e)
            if not _setCtrlHandlerRoutine(globalState.interrupt_event):
                raise wrap_windowserror(
                    space, rwin32.lastWindowsError("SetConsoleCtrlHandler"))
Example #15
0
def SetNamedPipeHandleState(space, w_handle, w_pipemode, w_maxinstances,
                            w_timeout):
    handle = handle_w(space, w_handle)
    state = lltype.malloc(rffi.CArrayPtr(rffi.UINT).TO, 3, flavor='raw')
    statep = lltype.malloc(rffi.CArrayPtr(rffi.UINTP).TO, 3, flavor='raw',
                           zero=True)
    try:
        if not space.is_w(w_pipemode, space.w_None):
            state[0] = space.uint_w(w_pipemode)
            statep[0] = rffi.ptradd(state, 0)
        if not space.is_w(w_maxinstances, space.w_None):
            state[1] = space.uint_w(w_maxinstances)
            statep[1] = rffi.ptradd(state, 1)
        if not space.is_w(w_timeout, space.w_None):
            state[2] = space.uint_w(w_timeout)
            statep[2] = rffi.ptradd(state, 2)
        if not _SetNamedPipeHandleState(handle, statep[0], statep[1],
                                        statep[2]):
            raise wrap_windowserror(space, rwin32.lastWindowsError())
    finally:
        lltype.free(state, flavor='raw')
        lltype.free(statep, flavor='raw')
Example #16
0
def WaitNamedPipe(space, name, timeout):
    # Careful: zero means "default value specified by CreateNamedPipe()"
    if not _WaitNamedPipe(name, timeout):
        raise wrap_windowserror(space, rwin32.lastWindowsError())
Example #17
0
def CloseHandle(space, w_handle):
    handle = handle_w(space, w_handle)
    if not rwin32.CloseHandle(handle):
        raise wrap_windowserror(space, rwin32.lastWindowsError())
Example #18
0
    def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT, offset=0):
        # XXX flags is or-ed into access by now.
        flags = 0
        # check size boundaries
        _check_map_size(length)
        map_size = length
        if offset < 0:
            raise RValueError("negative offset")

        flProtect = 0
        dwDesiredAccess = 0
        fh = NULL_HANDLE

        if access == ACCESS_READ:
            flProtect = PAGE_READONLY
            dwDesiredAccess = FILE_MAP_READ
        elif access == _ACCESS_DEFAULT or access == ACCESS_WRITE:
            flProtect = PAGE_READWRITE
            dwDesiredAccess = FILE_MAP_WRITE
        elif access == ACCESS_COPY:
            flProtect = PAGE_WRITECOPY
            dwDesiredAccess = FILE_MAP_COPY
        else:
            raise RValueError("mmap invalid access parameter.")

        # assume -1 and 0 both mean invalid file descriptor
        # to 'anonymously' map memory.
        if fileno != -1 and fileno != 0:
            fh = rwin32.get_osfhandle(fileno)
            # Win9x appears to need us seeked to zero
            # SEEK_SET = 0
            # libc._lseek(fileno, 0, SEEK_SET)

            # check file size
            try:
                low, high = _get_file_size(fh)
            except OSError:
                pass     # ignore non-seeking files and errors and trust map_size
            else:
                if not high and low <= sys.maxint:
                    size = low
                else:
                    # not so sure if the signed/unsigned strictness is a good idea:
                    high = rffi.cast(lltype.Unsigned, high)
                    low = rffi.cast(lltype.Unsigned, low)
                    size = (high << 32) + low
                    size = rffi.cast(lltype.Signed, size)
                if map_size == 0:
                    if size == 0:
                        raise RValueError("cannot mmap an empty file")
                    if offset > size:
                        raise RValueError(
                            "mmap offset is greater than file size")
                    map_size = int(size - offset)
                    if map_size != size - offset:
                        raise RValueError("mmap length is too large")
                elif offset + map_size > size:
                    raise RValueError("mmap length is greater than file size")

        m = MMap(access, offset)
        m.file_handle = INVALID_HANDLE
        m.map_handle = INVALID_HANDLE
        if fh:
            # it is necessary to duplicate the handle, so the
            # Python code can close it on us
            handle_ref = lltype.malloc(LPHANDLE.TO, 1, flavor='raw')
            handle_ref[0] = m.file_handle
            try:
                res = DuplicateHandle(GetCurrentProcess(), # source process handle
                                      fh, # handle to be duplicated
                                      GetCurrentProcess(), # target process handle
                                      handle_ref, # result
                                      0, # access - ignored due to options value
                                      False, # inherited by child procs?
                                      DUPLICATE_SAME_ACCESS) # options
                if not res:
                    raise rwin32.lastWindowsError()
                m.file_handle = handle_ref[0]
            finally:
                lltype.free(handle_ref, flavor='raw')

            if not map_size:
                low, high = _get_file_size(fh)
                if _64BIT:
                    map_size = (low << 32) + 1
                else:
                    if high:
                        # file is too large to map completely
                        map_size = -1
                    else:
                        map_size = low

        if tagname:
            m.tagname = tagname

        # DWORD is a 4-byte int. If int > 4-byte it must be divided
        if _64BIT:
            size_hi = (map_size + offset) >> 32
            size_lo = (map_size + offset) & 0xFFFFFFFF
            offset_hi = offset >> 32
            offset_lo = offset & 0xFFFFFFFF
        else:
            size_hi = 0
            size_lo = map_size + offset
            offset_hi = 0
            offset_lo = offset

        flProtect |= flags
        m.map_handle = CreateFileMapping(m.file_handle, NULL, flProtect,
                                         size_hi, size_lo, m.tagname)

        if m.map_handle:
            data = MapViewOfFile(m.map_handle, dwDesiredAccess,
                                 offset_hi, offset_lo, length)
            if data:
                # XXX we should have a real LPVOID which must always be casted
                charp = rffi.cast(LPCSTR, data)
                m.setdata(charp, map_size)
                return m
        winerror = rwin32.lastWindowsError()
        if m.map_handle:
            rwin32.CloseHandle(m.map_handle)
        m.map_handle = INVALID_HANDLE
        raise winerror