def duplicate(handle, target_process=None, inheritable=False): '''Duplicate a handle. (target_process is a handle not a pid!)''' if target_process is None: target_process = _winapi.GetCurrentProcess() return _winapi.DuplicateHandle(_winapi.GetCurrentProcess(), handle, target_process, 0, inheritable, _winapi.DUPLICATE_SAME_ACCESS)
def _make_inheritable(self, handle): """Return a duplicate of handle, which is inheritable""" h = _winapi.DuplicateHandle( _winapi.GetCurrentProcess(), handle, _winapi.GetCurrentProcess(), 0, 1, _winapi.DUPLICATE_SAME_ACCESS) return Handle(h)
def _make_inheritable_handle(fd): """Return a duplicate of handle, which is inheritable""" h = _winapi.DuplicateHandle(_winapi.GetCurrentProcess(), msvcrt.get_osfhandle(fd), _winapi.GetCurrentProcess(), 0, 1, _winapi.DUPLICATE_SAME_ACCESS) return subprocess.Handle(h)
def make_inheritable_handle(fd): """Create inheritable duplicate of handle from file descriptor""" h = _winapi.DuplicateHandle(_winapi.GetCurrentProcess(), msvcrt.get_osfhandle(fd), _winapi.GetCurrentProcess(), 0, 1, _winapi.DUPLICATE_SAME_ACCESS) return subprocess.Handle(h)
def steal_handle(source_pid, handle): """Steal a handle from process identified by source_pid.""" source_process_handle = _winapi.OpenProcess(_winapi. PROCESS_DUP_HANDLE, False, source_pid) try: return _winapi.DuplicateHandle(source_process_handle, handle, _winapi.GetCurrentProcess(), 0, False, _winapi. DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE) finally: _winapi.CloseHandle(source_process_handle)
def __init__(self, handle, access, pid=None): if pid is None: pid = os.getpid() proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, pid) try: self._handle = _winapi.DuplicateHandle(_winapi. GetCurrentProcess(), handle, proc, access, False, 0) finally: _winapi.CloseHandle(proc) self._access = access self._pid = pid
def duplicate(handle, target_process=None, inheritable=False, *, source_process=None): '''Duplicate a handle. (target_process is a handle not a pid!)''' current_process = _winapi.GetCurrentProcess() if source_process is None: source_process = current_process if target_process is None: target_process = current_process return _winapi.DuplicateHandle( source_process, handle, target_process, 0, inheritable, _winapi.DUPLICATE_SAME_ACCESS)
def detach(self): # retrieve handle from process which currently owns it if self._pid == os.getpid(): return self._handle proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, self._pid) try: return _winapi.DuplicateHandle( proc, self._handle, _winapi.GetCurrentProcess(), self._access, False, _winapi.DUPLICATE_CLOSE_SOURCE) finally: _winapi.CloseHandle(proc)
def detach(self): """Get the handle. This should only be called once.""" if self._pid == os.getpid(): return self._handle proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, self._pid) try: return _winapi.DuplicateHandle(proc, self._handle, _winapi. GetCurrentProcess(), self._access, False, _winapi. DUPLICATE_CLOSE_SOURCE) finally: _winapi.CloseHandle(proc)
def __init__(self, handle, access, pid=None): if pid is None: # We just duplicate the handle in the current process and # let the receiving process steal the handle. pid = os.getpid() proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, pid) try: self._handle = _winapi.DuplicateHandle( _winapi.GetCurrentProcess(), handle, proc, access, False, 0) finally: _winapi.CloseHandle(proc) self._access = access self._pid = pid
def detach(self): '''Get the handle. This should only be called once.''' # retrieve handle from process which currently owns it if self._pid == os.getpid(): # The handle has already been duplicated for this process. return self._handle # We must steal the handle from the process whose pid is self._pid. proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, self._pid) try: return _winapi.DuplicateHandle( proc, self._handle, _winapi.GetCurrentProcess(), self._access, False, _winapi.DUPLICATE_CLOSE_SOURCE) finally: _winapi.CloseHandle(proc)
def _make_inheritable(self, handle): h = _winapi.DuplicateHandle(_winapi.GetCurrentProcess(), handle, _winapi.GetCurrentProcess(), 0, 1, _winapi.DUPLICATE_SAME_ACCESS) return Handle(h)