def w_parseKeyUsage(space, pCertCtx, flags): with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as size_ptr: if not CertGetEnhancedKeyUsage(pCertCtx, flags, lltype.nullptr(CERT_ENHKEY_USAGE), size_ptr): last_error = rwin32.lastSavedWindowsError() if last_error.winerror == CRYPT_E_NOT_FOUND: return space.w_True raise wrap_windowserror(space, last_error) size = intmask(size_ptr[0]) with lltype.scoped_alloc(rffi.CCHARP.TO, size) as buf: usage = rffi.cast(PCERT_ENHKEY_USAGE, buf) # Now get the actual enhanced usage property if not CertGetEnhancedKeyUsage(pCertCtx, flags, usage, size_ptr): last_error= rwin32.lastSavedWindowsError() if last_error.winerror == CRYPT_E_NOT_FOUND: return space.w_True raise wrap_windowserror(space, last_error) result_w = [None] * usage.c_cUsageIdentifier for i in range(usage.c_cUsageIdentifier): if not usage.c_rgpszUsageIdentifier[i]: continue result_w[i] = space.wrap(rffi.charp2str( usage.c_rgpszUsageIdentifier[i])) return space.newset(result_w)
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.lastSavedWindowsError() 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.lastSavedWindowsError() 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.lastSavedWindowsError() 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.lastSavedWindowsError()
def enum_crls_w(space, store_name): """enum_crls(store_name) -> [] Retrieve CRLs from Windows' cert store. store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide more cert storages, too. The function returns a list of (bytes, encoding_type) tuples. The encoding_type flag can be interpreted with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING.""" result_w = [] pCrlCtx = lltype.nullptr(CRL_CONTEXT) hStore = CertOpenSystemStore(None, store_name) if not hStore: raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) try: while True: pCrlCtx = CertEnumCRLsInStore(hStore, pCrlCtx) if not pCrlCtx: break w_crl = space.newbytes( rffi.charpsize2str(pCrlCtx.c_pbCrlEncoded, intmask(pCrlCtx.c_cbCrlEncoded))) w_enc = w_certEncodingType(space, pCrlCtx.c_dwCertEncodingType) result_w.append(space.newtuple([w_crl, w_enc])) except: raise finally: if pCrlCtx: # loop ended with an error, need to clean up context manually CertFreeCRLContext(pCrlCtx) if not CertCloseStore(hStore, 0): # This error case might shadow another exception. raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) return space.newlist(result_w)
def os_utime_llimpl(path, tp): hFile = win32traits.CreateFile(path, win32traits.FILE_WRITE_ATTRIBUTES, 0, None, win32traits.OPEN_EXISTING, win32traits.FILE_FLAG_BACKUP_SEMANTICS, rwin32.NULL_HANDLE) if hFile == rwin32.INVALID_HANDLE_VALUE: raise rwin32.lastSavedWindowsError() 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.lastSavedWindowsError() 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.lastSavedWindowsError() finally: rwin32.CloseHandle(hFile) lltype.free(atime, flavor='raw') lltype.free(mtime, flavor='raw')
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.lastSavedWindowsError()) 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.lastSavedWindowsError()) 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)
def w_parseKeyUsage(space, pCertCtx, flags): with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as size_ptr: if not CertGetEnhancedKeyUsage( pCertCtx, flags, lltype.nullptr(CERT_ENHKEY_USAGE), size_ptr): last_error = rwin32.lastSavedWindowsError() if last_error.winerror == CRYPT_E_NOT_FOUND: return space.w_True raise wrap_windowserror(space, last_error) size = intmask(size_ptr[0]) with lltype.scoped_alloc(rffi.CCHARP.TO, size) as buf: usage = rffi.cast(PCERT_ENHKEY_USAGE, buf) # Now get the actual enhanced usage property if not CertGetEnhancedKeyUsage(pCertCtx, flags, usage, size_ptr): last_error = rwin32.lastSavedWindowsError() if last_error.winerror == CRYPT_E_NOT_FOUND: return space.w_True raise wrap_windowserror(space, last_error) result_w = [None] * usage.c_cUsageIdentifier for i in range(usage.c_cUsageIdentifier): if not usage.c_rgpszUsageIdentifier[i]: continue result_w[i] = space.wrap( rffi.charp2str(usage.c_rgpszUsageIdentifier[i])) return space.newset(result_w)
def enum_crls_w(space, store_name): """enum_crls(store_name) -> [] Retrieve CRLs from Windows' cert store. store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide more cert storages, too. The function returns a list of (bytes, encoding_type) tuples. The encoding_type flag can be interpreted with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING.""" result_w = [] pCrlCtx = lltype.nullptr(CRL_CONTEXT) hStore = CertOpenSystemStore(None, store_name) if not hStore: raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) try: while True: pCrlCtx = CertEnumCRLsInStore(hStore, pCrlCtx) if not pCrlCtx: break w_crl = space.wrapbytes( rffi.charpsize2str(pCrlCtx.c_pbCrlEncoded, intmask(pCrlCtx.c_cbCrlEncoded))) w_enc = w_certEncodingType(space, pCrlCtx.c_dwCertEncodingType) result_w.append(space.newtuple([w_crl, w_enc])) except: raise finally: if pCrlCtx: # loop ended with an error, need to clean up context manually CertFreeCRLContext(pCrlCtx) if not CertCloseStore(hStore, 0): # This error case might shadow another exception. raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) return space.newlist(result_w)
def _getfinalpathname_llimpl(path): if not win32traits.check_GetFinalPathNameByHandle(): raise LLNotImplemented("GetFinalPathNameByHandle not available on " "this platform") hFile = win32traits.CreateFile(path, 0, 0, None, win32traits.OPEN_EXISTING, win32traits.FILE_FLAG_BACKUP_SEMANTICS, rwin32.NULL_HANDLE) if hFile == rwin32.INVALID_HANDLE_VALUE: raise rwin32.lastSavedWindowsError("CreateFile") VOLUME_NAME_DOS = rffi.cast(rwin32.DWORD, win32traits.VOLUME_NAME_DOS) try: usize = win32traits.GetFinalPathNameByHandle( hFile, lltype.nullptr(traits.CCHARP.TO), rffi.cast(rwin32.DWORD, 0), VOLUME_NAME_DOS) if usize == 0: raise rwin32.lastSavedWindowsError("GetFinalPathNameByHandle") size = rffi.cast(lltype.Signed, usize) with rffi.scoped_alloc_unicodebuffer(size + 1) as buf: result = win32traits.GetFinalPathNameByHandle( hFile, buf.raw, usize, VOLUME_NAME_DOS) if result == 0: raise rwin32.lastSavedWindowsError("GetFinalPathNameByHandle") return buf.str(rffi.cast(lltype.Signed, result)) finally: rwin32.CloseHandle(hFile)
def chmod_llimpl(path, mode): attr = win32traits.GetFileAttributes(path) if attr == win32traits.INVALID_FILE_ATTRIBUTES: raise rwin32.lastSavedWindowsError() if mode & 0200: # _S_IWRITE attr &= ~win32traits.FILE_ATTRIBUTE_READONLY else: attr |= win32traits.FILE_ATTRIBUTE_READONLY if not win32traits.SetFileAttributes(path, attr): raise rwin32.lastSavedWindowsError()
def do_recv_string(self, space, buflength, maxlength): from _multiprocess.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_saved() 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.lastSavedWindowsError()) length = intmask(read_ptr[0]) + intmask(left_ptr[0]) if length > maxlength: # bad message, close connection self.flags &= ~READABLE if self.flags == 0: self.close() raise oefmt(space.w_IOError, "bad message length") newbuf = lltype.malloc(rffi.CCHARP.TO, length + 1, flavor='raw') length_read = intmask(read_ptr[0]) for i in range(length_read): newbuf[i] = self.buffer[i] result = _ReadFile(self.handle, rffi.ptradd(newbuf, length_read), left_ptr[0], read_ptr, rffi.NULL) if not result: rffi.free_charp(newbuf) raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) assert r_uint(read_ptr[0]) == r_uint(left_ptr[0]) return length, newbuf finally: lltype.free(read_ptr, flavor='raw') lltype.free(left_ptr, flavor='raw')
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_saved() 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.lastSavedWindowsError()) 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.lastSavedWindowsError()) assert read_ptr[0] == left_ptr[0] return length, newbuf finally: lltype.free(read_ptr, flavor='raw') lltype.free(left_ptr, flavor='raw')
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.lastSavedWindowsError("ExpandEnvironmentStrings") size = intmask(size) with rffi.scoped_alloc_unicodebuffer(size) as dest_buf: if _ExpandEnvironmentStringsW(src_buf, dest_buf.raw, size) == 0: raise rwin32.lastSavedWindowsError("ExpandEnvironmentStrings") return dest_buf.str(size - 1) # remove trailing \0
def utf8_encode_mbcs(s, errors, errorhandler, force_replace=True): # TODO: do the encoding without decoding utf8 -> unicode uni = s.decode('utf8') lgt = len(uni) if not force_replace and errors not in ('strict', 'replace'): msg = "mbcs encoding does not support errors='%s'" % errors errorhandler('strict', 'mbcs', msg, s, 0, 0) if lgt == 0: return '' if force_replace or errors == 'replace': flags = 0 used_default_p = lltype.nullptr(BOOLP.TO) else: # strict flags = rwin32.WC_NO_BEST_FIT_CHARS used_default_p = lltype.malloc(BOOLP.TO, 1, flavor='raw') used_default_p[0] = rffi.cast(rwin32.BOOL, False) try: with rffi.scoped_nonmoving_unicodebuffer(uni) as dataptr: # first get the size of the result mbcssize = WideCharToMultiByte(CP_ACP, flags, dataptr, lgt, None, 0, None, used_default_p) if mbcssize == 0: raise rwin32.lastSavedWindowsError() # If we used a default char, then we failed! if (used_default_p and rffi.cast(lltype.Bool, used_default_p[0])): errorhandler('strict', 'mbcs', "invalid character", s, 0, 0) with rffi.scoped_alloc_buffer(mbcssize) as buf: # do the conversion if WideCharToMultiByte(CP_ACP, flags, dataptr, lgt, buf.raw, mbcssize, None, used_default_p) == 0: raise rwin32.lastSavedWindowsError() if (used_default_p and rffi.cast(lltype.Bool, used_default_p[0])): errorhandler('strict', 'mbcs', "invalid character", s, 0, 0) result = buf.str(mbcssize) assert result is not None return result finally: if used_default_p: lltype.free(used_default_p, flavor='raw')
def ConnectNamedPipe(space, w_handle, w_overlapped): handle = handle_w(space, w_handle) overlapped = space.int_w(w_overlapped) if overlapped: raise oefmt(space.w_NotImplementedError, "expected a NULL pointer") if not _ConnectNamedPipe(handle, rffi.NULL): raise wrap_windowserror(space, rwin32.lastSavedWindowsError())
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.lastSavedWindowsError())
def utf8_encode_code_page(cp, s, errors, errorhandler): """Encode a utf8 string s using code page cp and the given errors/errorhandler. Returns a encoded byte string """ name = _code_page_name(cp) lgt = len(s) if lgt == 0: return '' flags = _encode_code_page_flags(cp, errors) if cp in (rwin32.CP_UTF8, rwin32.CP_UTF7): used_default_p = lltype.nullptr(BOOLP.TO) else: used_default_p = lltype.malloc(BOOLP.TO, 1, flavor='raw') # Encode one codpoint at a time to allow the errorhandlers to do # their thing chars = lltype.malloc(rffi.CWCHARP.TO, 2, flavor='raw') res = StringBuilder(lgt) try: with rffi.scoped_alloc_buffer(4) as buf: pos = 0 # TODO: update s if obj != s is returned from an errorhandler for uni in Utf8StringIterator(s): if used_default_p: used_default_p[0] = rffi.cast(rwin32.BOOL, False) if uni < 0x10000: chars[0] = rffi.cast(lltype.UniChar, uni) charsize = 1 else: chars[0] = Py_UNICODE_HIGH_SURROGATE(uni) chars[1] = Py_UNICODE_LOW_SURROGATE(uni) charsize = 2 # first get the size of the result outsize = WideCharToMultiByte(cp, flags, chars, charsize, buf.raw, 4, None, used_default_p) if outsize > 0: if not (used_default_p and used_default_p[0]): r = buf.str(outsize) assert r is not None res.append(r) pos += 1 continue elif rwin32.GetLastError_saved( ) != rwin32.ERROR_NO_UNICODE_TRANSLATION: raise rwin32.lastSavedWindowsError() # If we used a default char, then we failed! r, pos, retype, obj = errorhandler(errors, name, "invalid character", s, pos, pos + 1) res.append(r) pos += 1 finally: lltype.free(chars, flavor='raw') if used_default_p: lltype.free(used_default_p, flavor='raw') return res.build()
def resize(self, newsize): if _POSIX: if not has_mremap: raise RValueError("mmap: resizing not available--no mremap()") # resize the underlying file first, if there is one if self.fd >= 0: 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_no_err(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.lastSavedWindowsError() if self.map_handle: rwin32.CloseHandle_no_err(self.map_handle) self.map_handle = INVALID_HANDLE raise winerror
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.lastSavedWindowsError("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.lastSavedWindowsError("CryptGenRandom") return rffi.charpsize2str(rffi.cast(rffi.CCHARP, buf), n)
def _getfileinformation_llimpl(fd): hFile = rwin32.get_osfhandle(fd) with lltype.scoped_alloc( win32traits.BY_HANDLE_FILE_INFORMATION) as info: if win32traits.GetFileInformationByHandle(hFile, info) == 0: raise rwin32.lastSavedWindowsError("_getfileinformation") return (rffi.cast(lltype.Signed, info.c_dwVolumeSerialNumber), rffi.cast(lltype.Signed, info.c_nFileIndexHigh), rffi.cast(lltype.Signed, info.c_nFileIndexLow))
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_no_err(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.lastSavedWindowsError() if self.map_handle: rwin32.CloseHandle_no_err(self.map_handle) self.map_handle = INVALID_HANDLE raise winerror
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.lastSavedWindowsError("ReleaseSemaphore") return previous_ptr[0] + 1 finally: lltype.free(previous_ptr, flavor='raw')
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 as e: raise wrap_windowserror(space, e) if not _setCtrlHandlerRoutine(globalState.interrupt_event): raise wrap_windowserror(space, rwin32.lastSavedWindowsError("SetConsoleCtrlHandler"))
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.lastSavedWindowsError()) return w_handle(space, handle)
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.lastSavedWindowsError("ReleaseSemaphore") return intmask(previous_ptr[0]) + 1 finally: lltype.free(previous_ptr, flavor='raw')
def _decode_cp_error(s, errorhandler, encoding, errors, final, start, end): # late import to avoid circular import from pypy.interpreter.unicodehelper import _str_decode_utf8_slowpath if rwin32.GetLastError_saved() == rwin32.ERROR_NO_UNICODE_TRANSLATION: msg = ("No mapping for the Unicode character exists in the target " "multi-byte code page.") r, ignore1, ignore2 = _str_decode_utf8_slowpath( s[start:end], errors, final, errorhandler, False) return r, end else: raise rwin32.lastSavedWindowsError()
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 as e: raise wrap_windowserror(space, e) if not _setCtrlHandlerRoutine(globalState.interrupt_event): raise wrap_windowserror( space, rwin32.lastSavedWindowsError("SetConsoleCtrlHandler"))
def enum_certificates_w(space, store_name): """enum_certificates(store_name) -> [] Retrieve certificates from Windows' cert store. store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide more cert storages, too. The function returns a list of (bytes, encoding_type, trust) tuples. The encoding_type flag can be interpreted with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either a set of OIDs or the boolean True.""" result_w = [] pCertCtx = lltype.nullptr(CERT_CONTEXT) hStore = CertOpenSystemStore(None, store_name) if not hStore: raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) try: while True: pCertCtx = CertEnumCertificatesInStore(hStore, pCertCtx) if not pCertCtx: break w_cert = space.newbytes( rffi.charpsize2str(pCertCtx.c_pbCertEncoded, intmask(pCertCtx.c_cbCertEncoded))) w_enc = w_certEncodingType(space, pCertCtx.c_dwCertEncodingType) w_keyusage = w_parseKeyUsage( space, pCertCtx, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG) if space.is_w(w_keyusage, space.w_True): w_keyusage = w_parseKeyUsage( space, pCertCtx, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG) result_w.append(space.newtuple([w_cert, w_enc, w_keyusage])) except: raise finally: if pCertCtx: # loop ended with an error, need to clean up context manually CertFreeCertificateContext(pCertCtx) if not CertCloseStore(hStore, 0): # This error case might shadow another exception. raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) return space.newlist(result_w)
def enum_certificates_w(space, store_name): """enum_certificates(store_name) -> [] Retrieve certificates from Windows' cert store. store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide more cert storages, too. The function returns a list of (bytes, encoding_type, trust) tuples. The encoding_type flag can be interpreted with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either a set of OIDs or the boolean True.""" result_w = [] pCertCtx = lltype.nullptr(CERT_CONTEXT) hStore = CertOpenSystemStore(None, store_name) if not hStore: raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) try: while True: pCertCtx = CertEnumCertificatesInStore(hStore, pCertCtx) if not pCertCtx: break w_cert = space.wrapbytes( rffi.charpsize2str(pCertCtx.c_pbCertEncoded, intmask(pCertCtx.c_cbCertEncoded))) w_enc = w_certEncodingType(space, pCertCtx.c_dwCertEncodingType) w_keyusage = w_parseKeyUsage( space, pCertCtx, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG) if space.is_w(w_keyusage, space.w_True): w_keyusage = w_parseKeyUsage( space, pCertCtx, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG) result_w.append(space.newtuple([w_cert, w_enc, w_keyusage])) except: raise finally: if pCertCtx: # loop ended with an error, need to clean up context manually CertFreeCertificateContext(pCertCtx) if not CertCloseStore(hStore, 0): # This error case might shadow another exception. raise wrap_windowserror(space, rwin32.lastSavedWindowsError()) return space.newlist(result_w)
def _unibuf_to_utf8(dataptr, insize): """Encode the widechar unicode buffer u to utf8 Should never error, since the buffer comes from a call to MultiByteToWideChar """ flags = 0 cp = rwin32.CP_UTF8 used_default_p = lltype.nullptr(BOOLP.TO) # first get the size of the result outsize = WideCharToMultiByte(cp, flags, dataptr, insize, None, 0, None, used_default_p) if outsize == 0: raise rwin32.lastSavedWindowsError() with rffi.scoped_alloc_buffer(outsize) as buf: # do the conversion if WideCharToMultiByte(cp, flags, dataptr, insize, buf.raw, outsize, None, used_default_p) == 0: raise rwin32.lastSavedWindowsError() result = buf.str(outsize) assert result is not None return result
def CreateNamedPipe(space, name, openmode, pipemode, maxinstances, outputsize, inputsize, timeout, w_security): security = space.int_w(w_security) if security: raise oefmt(space.w_NotImplementedError, "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.lastSavedWindowsError()) return w_handle(space, handle)
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.lastSavedWindowsError()) return w_handle(space, handle)
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.lastSavedWindowsError("_getfullpathname failed") result = traits.charp2str(lpBuffer) return result finally: lltype.free(lpBuffer, flavor='raw')
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 oefmt(space.w_NotImplementedError, "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.lastSavedWindowsError()) return w_handle(space, handle)
def process_time(space, w_info=None): from rpython.rlib.rposix import GetCurrentProcess, GetProcessTimes current_process = GetCurrentProcess() with lltype.scoped_alloc(rwin32.FILETIME) as creation_time, \ lltype.scoped_alloc(rwin32.FILETIME) as exit_time, \ lltype.scoped_alloc(rwin32.FILETIME) as kernel_time, \ lltype.scoped_alloc(rwin32.FILETIME) as user_time: worked = GetProcessTimes(current_process, creation_time, exit_time, kernel_time, user_time) if not worked: raise wrap_oserror( space, rwin32.lastSavedWindowsError("GetProcessTimes")) kernel_time2 = (kernel_time.c_dwLowDateTime | r_ulonglong(kernel_time.c_dwHighDateTime) << 32) user_time2 = (user_time.c_dwLowDateTime | r_ulonglong(user_time.c_dwHighDateTime) << 32) if w_info is not None: _setinfo(space, w_info, "GetProcessTimes()", 1e-7, True, False) return space.newfloat((float(kernel_time2) + float(user_time2)) * 1e-7)
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.lastSavedWindowsError()) finally: lltype.free(state, flavor="raw") lltype.free(statep, flavor="raw")
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.lastSavedWindowsError()) finally: lltype.free(state, flavor='raw') lltype.free(statep, flavor='raw')
def monotonic(space, w_info=None): result = 0 HAS_GETTICKCOUNT64 = time_state.check_GetTickCount64() if HAS_GETTICKCOUNT64: result = time_state.GetTickCount64() * 1e-3 else: ticks = _GetTickCount() if ticks < time_state.last_ticks: time_state.n_overflow += 1 time_state.last_ticks = ticks result = math.ldexp(time_state.n_overflow, 32) result = result + ticks result = result * 1e-3 if w_info is not None: if HAS_GETTICKCOUNT64: implementation = "GetTickCount64()" else: implementation = "GetTickCount()" resolution = 1e-7 with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as time_adjustment, \ lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as time_increment, \ lltype.scoped_alloc(rwin32.LPBOOL.TO, 1) as is_time_adjustment_disabled: ok = _GetSystemTimeAdjustment(time_adjustment, time_increment, is_time_adjustment_disabled) if not ok: # Is this right? Cargo culting... raise wrap_oserror( space, rwin32.lastSavedWindowsError( "GetSystemTimeAdjustment")) resolution = resolution * time_increment[0] _setinfo(space, w_info, implementation, resolution, True, False) return space.newfloat(result)
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.lastSavedWindowsError() 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.lastSavedWindowsError() if m.map_handle: rwin32.CloseHandle_no_err(m.map_handle) m.map_handle = INVALID_HANDLE raise winerror
def CloseHandle(space, w_handle): handle = handle_w(space, w_handle) if not rwin32.CloseHandle(handle): raise wrap_windowserror(space, rwin32.lastSavedWindowsError())
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.lastSavedWindowsError()) 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.lastSavedWindowsError()) 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)
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.lastSavedWindowsError() 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.lastSavedWindowsError() if m.map_handle: rwin32.CloseHandle_no_err(m.map_handle) m.map_handle = INVALID_HANDLE raise winerror
def WaitNamedPipe(space, name, timeout): # Careful: zero means "default value specified by CreateNamedPipe()" if not _WaitNamedPipe(name, timeout): raise wrap_windowserror(space, rwin32.lastSavedWindowsError())