Esempio n. 1
0
def _safe_duplicate_handle(h):
  try:
    h = win32api.DuplicateHandle(win32process.GetCurrentProcess(),
                                 h,
                                 win32process.GetCurrentProcess(),
                                 0,
                                 True,
                                 win32con.DUPLICATE_SAME_ACCESS)
    return True, h
  except Exception as exc:
    if exc.winerror == winerror.ERROR_INVALID_HANDLE:
      return True, None
  return False, None
Esempio n. 2
0
 def get_process_handle(hProcess, handle):
     try:
         return win32api.DuplicateHandle(hProcess, handle, CURRENT_PROCESS,
                                         0, 0,
                                         win32con.DUPLICATE_SAME_ACCESS)
     except win32api.error, (errno, errctx, errmsg):
         if errno in (winerror.ERROR_ACCESS_DENIED,
                      winerror.ERROR_INVALID_PARAMETER,
                      winerror.ERROR_INVALID_HANDLE,
                      winerror.ERROR_NOT_SUPPORTED):
             return None
         else:
             raise
Esempio n. 3
0
def MakePrivateHandle(handle, replace = 1):
  """Turn an inherited handle into a non inherited one. This avoids the
  handle duplication that occurs on CreateProcess calls which can create
  uncloseable pipes."""

  ### Could change implementation to use SetHandleInformation()...

  flags = win32con.DUPLICATE_SAME_ACCESS
  proc = win32api.GetCurrentProcess()
  if replace: flags = flags | win32con.DUPLICATE_CLOSE_SOURCE
  newhandle = win32api.DuplicateHandle(proc,handle,proc,0,0,flags)
  if replace: handle.Detach() # handle was already deleted by the last call
  return newhandle
Esempio n. 4
0
	def startBackgroundProcess(self):
		"""Method to start a process running in the background.
		
		"""	
		with process_lock:
			# security attributes for pipes
			sAttrs = win32security.SECURITY_ATTRIBUTES()
			sAttrs.bInheritHandle = 1
	
			# create pipes for the process to write to
			hStdin_r, hStdin = win32pipe.CreatePipe(sAttrs, 0)
			hStdout = win32file.CreateFile(_stringToUnicode(self.fStdout), win32file.GENERIC_WRITE | win32file.GENERIC_READ,
			   win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
			   sAttrs, win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_NORMAL, None)
			hStderr = win32file.CreateFile(_stringToUnicode(self.fStderr), win32file.GENERIC_WRITE | win32file.GENERIC_READ,
			   win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
			   sAttrs, win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_NORMAL, None)

			# set the info structure for the new process.
			StartupInfo = win32process.STARTUPINFO()
			StartupInfo.hStdInput  = hStdin_r
			StartupInfo.hStdOutput = hStdout
			StartupInfo.hStdError  = hStderr
			StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

			# Create new handles for the thread ends of the pipes. The duplicated handles will
			# have their inheritence properties set to false so that any children inheriting these
			# handles will not have non-closeable handles to the pipes
			pid = win32api.GetCurrentProcess()
			tmp = win32api.DuplicateHandle(pid, hStdin, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS)
			win32file.CloseHandle(hStdin)
			hStdin = tmp

			# start the process, and close down the copies of the process handles
			# we have open after the process creation (no longer needed here)
			old_command = command = self.__quotePath(self.command)
			for arg in self.arguments: command = '%s %s' % (command, self.__quotePath(arg))
			try:
				self.__hProcess, self.__hThread, self.pid, self.__tid = win32process.CreateProcess( None, command, None, None, 1, 0, self.environs or None, os.path.normpath(self.workingDir), StartupInfo)
			except pywintypes.error as e:
				raise ProcessError("Error creating process %s: %s" % (old_command, e))

			win32file.CloseHandle(hStdin_r)
			win32file.CloseHandle(hStdout)
			win32file.CloseHandle(hStderr)

			# set the handle to the stdin of the process 
			self.__stdin = hStdin
Esempio n. 5
0
def _open_parent_file_handle(parent_process_handle,
                             parent_file_handle,
                             mode='r'):
    if mode not in ['r', 'w']:
        raise ValueError("mode must be 'r' or 'w'")
    my_file_handle = win32api.DuplicateHandle(
        parent_process_handle,
        parent_file_handle,
        win32api.GetCurrentProcess(),
        0,  #desiredAccess ignored because of DUPLICATE_SAME_ACCESS
        0,  #Inheritable
        win32con.DUPLICATE_SAME_ACCESS | win32con.DUPLICATE_CLOSE_SOURCE)
    infd = msvcrt.open_osfhandle(int(my_file_handle),
                                 os.O_RDONLY if mode == 'r' else os.O_WRONLY)
    f = _ParentPassedFile(os.fdopen(infd, mode), my_file_handle)
    return f
Esempio n. 6
0
    def __UninheritableHandle(self, handle):
        """Return a duplicate of a file handle that is not inheritable.

        'handle' -- A file handle.

        returns -- A new handle that is a non-inheritable duplicate of
        the 'handle'.

        This method should only be used under Windows."""

        assert sys.platform == "win32"

        current_process = win32api.GetCurrentProcess()
        return win32api.DuplicateHandle(current_process, handle,
                                        current_process, 0, 0,
                                        win32con.DUPLICATE_SAME_ACCESS)
Esempio n. 7
0
    def __init__(self, no):
        print "file:", no
        hpros = win32api.GetCurrentProcess()
        self.fno = win32api.DuplicateHandle(hpros, no, hpros, 0, 0, 2)
        om.create_object(self)
        self.buffer = ""
        self.recv_buffer = create_string_buffer(64)
        self.send_buffer = create_string_buffer(64)

        self.send_ch = SL.channel()
        self.recv_ch = SL.channel()

        self.recvol = OVERLAPPED()
        self.sendol = OVERLAPPED()

        self.recv_wsabuf = WSABUF()
        self.send_wsabuf = WSABUF()
Esempio n. 8
0
    def createProcess(self, cmd):
        self.start_time = time.time()

        hInputRead, hInputWriteTemp = self.newPipe()
        hOutReadTemp, hOutWrite = self.newPipe()
        pid = win32api.GetCurrentProcess()
        # This one is duplicated as inheritable.
        hErrWrite = win32api.DuplicateHandle(pid, hOutWrite, pid, 0, 1,
                                       win32con.DUPLICATE_SAME_ACCESS)

        # These are non-inheritable duplicates.
        hOutRead = self.dup(hOutReadTemp)
        hInputWrite = self.dup(hInputWriteTemp)
        # dup() closed hOutReadTemp, hInputWriteTemp

        si = win32process.STARTUPINFO()
        si.hStdInput = hInputRead
        si.hStdOutput = hOutWrite
        si.hStdError = hErrWrite
        si.dwFlags = win32process.STARTF_USESTDHANDLES | \
                     win32process.STARTF_USESHOWWINDOW
        si.wShowWindow = win32con.SW_HIDE

        # pass True to allow handles to be inherited.  Inheritance is
        # problematic in general, but should work in the controlled
        # circumstances of a service process.
        create_flags = win32process.CREATE_NEW_CONSOLE
        info = win32process.CreateProcess(None, cmd, None, None, True,
                                          create_flags, None, None, si)
        # (NOTE: these really aren't necessary for Python - they are closed
        # as soon as they are collected)
        hOutWrite.Close()
        hErrWrite.Close()
        hInputRead.Close()
        # We don't use stdin
        hInputWrite.Close()

        # start a thread collecting output
        t = threading.Thread(
            target=self.outputCaptureThread,
            args = (hOutRead, ))
        t.start()
        self.output_thread = t
        return info
 def manage_request(self, request, client_address):
   try:
     procHandle = win32api.GetCurrentProcess()
     th = win32api.DuplicateHandle(procHandle, win32api.GetCurrentThread(), procHandle, 0, 0, win32con.DUPLICATE_SAME_ACCESS)
     try:
       # Pretend Python doesn't have the interpreter lock.
       self.lckThreadHandles.acquire()
       self.thread_handles.append(th)
       self.lckThreadHandles.release()
       try:
         self.finish_request(request, client_address)
       except:
         s = StringIO.StringIO()
         traceback.print_exc(file=s)
         self.servicemanager.LogErrorMsg(s.getvalue())
     finally:
       # Pretend Python doesn't have the interpreter lock...
       self.lckThreadHandles.acquire()
       self.thread_handles.remove(th)
       self.lckThreadHandles.release()
   except:
     s = StringIO.StringIO()
     traceback.print_exc(file=s)
     self.servicemanager.LogErrorMsg(s.getvalue())
Esempio n. 10
0
File: win.py Progetto: umutbb/hubble
def make_inheritable(token):
    '''Create an inheritable handle'''
    return win32api.DuplicateHandle(win32api.GetCurrentProcess(), token,
                                    win32api.GetCurrentProcess(), 0, 1,
                                    win32con.DUPLICATE_SAME_ACCESS)
Esempio n. 11
0
    def run(self, cmdline):
        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create pipes
        hStdin_r, self.hStdin_w = win32pipe.CreatePipe(sAttrs, 0)
        self.hStdout_r, hStdout_w = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderr_r, hStderr_w = win32pipe.CreatePipe(sAttrs, 0)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdInput = hStdin_r
        StartupInfo.hStdOutput = hStdout_w
        StartupInfo.hStdError = hStderr_w
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES
        # Mark doesn't support wShowWindow yet.
        # StartupInfo.dwFlags = StartupInfo.dwFlags | win32process.STARTF_USESHOWWINDOW
        # StartupInfo.wShowWindow = win32con.SW_HIDE

        # Create new output read handles and the input write handle. Set
        # the inheritance properties to FALSE. Otherwise, the child inherits
        # the these handles; resulting in non-closeable handles to the pipes
        # being created.
        pid = win32api.GetCurrentProcess()

        tmp = win32api.DuplicateHandle(
            pid,
            self.hStdin_w,
            pid,
            0,
            0,  # non-inheritable!!
            win32con.DUPLICATE_SAME_ACCESS)
        # Close the inhertible version of the handle
        win32file.CloseHandle(self.hStdin_w)
        self.hStdin_w = tmp
        tmp = win32api.DuplicateHandle(
            pid,
            self.hStdout_r,
            pid,
            0,
            0,  # non-inheritable!
            win32con.DUPLICATE_SAME_ACCESS)
        # Close the inhertible version of the handle
        win32file.CloseHandle(self.hStdout_r)
        self.hStdout_r = tmp

        # start the process.
        hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
            None,  # program
            cmdline,  # command line
            None,  # process security attributes
            None,  # thread attributes
            1,  # inherit handles, or USESTDHANDLES won't work.
            # creation flags. Don't access the console.
            0,  # Don't need anything here.
            # If you're in a GUI app, you should use
            # CREATE_NEW_CONSOLE here, or any subprocesses
            # might fall victim to the problem described in:
            # KB article: Q156755, cmd.exe requires
            # an NT console in order to perform redirection..
            None,  # no new environment
            None,  # current directory (stay where we are)
            StartupInfo)
        # normally, we would save the pid etc. here...

        # Child is launched. Close the parents copy of those pipe handles
        # that only the child should have open.
        # You need to make sure that no handles to the write end of the
        # output pipe are maintained in this process or else the pipe will
        # not close when the child process exits and the ReadFile will hang.
        win32file.CloseHandle(hStderr_w)
        win32file.CloseHandle(hStdout_w)
        win32file.CloseHandle(hStdin_r)

        self.stdin = os.fdopen(msvcrt.open_osfhandle(self.hStdin_w, 0), "wb")
        self.stdin.write('hmmmmm\r\n')
        self.stdin.flush()
        self.stdin.close()

        self.stdout = os.fdopen(msvcrt.open_osfhandle(self.hStdout_r, 0), "rb")
        print("Read on stdout: ", repr(self.stdout.read()))

        self.stderr = os.fdopen(msvcrt.open_osfhandle(self.hStderr_r, 0), "rb")
        print("Read on stderr: ", repr(self.stderr.read()))
Esempio n. 12
0
def DuplicateHandle(handle):
  """Duplicates a win32 handle."""
  proc = win32api.GetCurrentProcess()
  return win32api.DuplicateHandle(proc,handle,proc,0,0,win32con.DUPLICATE_SAME_ACCESS)
Esempio n. 13
0
    def __init__(self, reactor, protocol, command, args, environment, path):
        _pollingfile._PollingTimer.__init__(self, reactor)
        self.protocol = protocol

        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create the pipes which will connect to the secondary process
        self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0)
        hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0)

        win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT,
                                          None, None)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdOutput = hStdoutW
        StartupInfo.hStdError = hStderrW
        StartupInfo.hStdInput = hStdinR
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

        # Create new handles whose inheritance property is false
        pid = win32api.GetCurrentProcess()

        tmp = win32api.DuplicateHandle(pid, self.hStdoutR, pid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdoutR)
        self.hStdoutR = tmp

        tmp = win32api.DuplicateHandle(pid, self.hStderrR, pid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStderrR)
        self.hStderrR = tmp

        tmp = win32api.DuplicateHandle(pid, self.hStdinW, pid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdinW)
        self.hStdinW = tmp

        # Add the specified environment to the current environment - this is
        # necessary because certain operations are only supported on Windows
        # if certain environment variables are present.
        env = os.environ.copy()
        env.update(environment or {})

        # create the process
        cmdline = ' '.join([cmdLineQuote(a) for a in args])
        # TODO: error detection here.
        self.hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
            command, cmdline, None, None, 1, 0, env, path, StartupInfo)
        win32file.CloseHandle(hThread)

        # close handles which only the child will use
        win32file.CloseHandle(hStderrW)
        win32file.CloseHandle(hStdoutW)
        win32file.CloseHandle(hStdinR)

        self.closed = 0
        self.closedNotifies = 0

        # set up everything
        self.stdout = _pollingfile._PollableReadPipe(
            self.hStdoutR,
            lambda data: self.protocol.childDataReceived(1, data),
            self.outConnectionLost)

        self.stderr = _pollingfile._PollableReadPipe(
            self.hStderrR,
            lambda data: self.protocol.childDataReceived(2, data),
            self.errConnectionLost)

        self.stdin = _pollingfile._PollableWritePipe(self.hStdinW,
                                                     self.inConnectionLost)

        for pipewatcher in self.stdout, self.stderr, self.stdin:
            self._addPollableResource(pipewatcher)

        # notify protocol
        self.protocol.makeConnection(self)
Esempio n. 14
0
    def startBackgroundProcess(self):
        """Method to start a process running in the background.
		
		"""
        with process_lock:
            # security attributes for pipes
            sAttrs = win32security.SECURITY_ATTRIBUTES()
            sAttrs.bInheritHandle = 1

            # create pipes for the process to write to
            hStdin_r, hStdin = win32pipe.CreatePipe(sAttrs, 0)
            hStdout = win32file.CreateFile(
                self.stdout, win32file.GENERIC_WRITE | win32file.GENERIC_READ,
                win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ
                | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS,
                win32file.FILE_ATTRIBUTE_NORMAL, None)
            hStderr = win32file.CreateFile(
                self.stderr, win32file.GENERIC_WRITE | win32file.GENERIC_READ,
                win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ
                | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS,
                win32file.FILE_ATTRIBUTE_NORMAL, None)

            try:

                # set the info structure for the new process.
                StartupInfo = win32process.STARTUPINFO()
                StartupInfo.hStdInput = hStdin_r
                StartupInfo.hStdOutput = hStdout
                StartupInfo.hStdError = hStderr
                StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

                # Create new handles for the thread ends of the pipes. The duplicated handles will
                # have their inheritence properties set to false so that any children inheriting these
                # handles will not have non-closeable handles to the pipes
                pid = win32api.GetCurrentProcess()
                tmp = win32api.DuplicateHandle(pid, hStdin, pid, 0, 0,
                                               win32con.DUPLICATE_SAME_ACCESS)
                win32file.CloseHandle(hStdin)
                hStdin = tmp

                # start the process, and close down the copies of the process handles
                # we have open after the process creation (no longer needed here)
                old_command = command = self.__quotePath(self.command)
                for arg in self.arguments:
                    command = '%s %s' % (command, self.__quotePath(arg))

                # Windows CreateProcess maximum lpCommandLine length is 32,768
                # http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx
                if len(command) >= 32768:  # pragma: no cover
                    raise ValueError(
                        "Command line length exceeded 32768 characters: %s..."
                        % command[:1000])

                dwCreationFlags = 0
                if IS_PRE_WINDOWS_8:  # pragma: no cover
                    # In case PySys is itself running in a job, might need to explicitly breakaway from it so we can give
                    # it its own, but only for old pre-windows 8/2012, which support nested jobs
                    dwCreationFlags = dwCreationFlags | win32process.CREATE_BREAKAWAY_FROM_JOB

                if self.command.lower().endswith(('.bat', '.cmd')):
                    # If we don't start suspended there's a slight race condition but due to some issues with
                    # initially-suspended processes hanging (seen many years ago), to be safe, only bother to close the
                    # race condition for shell scripts (which is the main use case for this anyway)
                    dwCreationFlags = dwCreationFlags | win32con.CREATE_SUSPENDED

                self.__job = self._createParentJob()

                try:
                    self.__hProcess, self.__hThread, self.pid, self.__tid = win32process.CreateProcess(
                        None, command, None, None, 1,
                        dwCreationFlags, self.environs,
                        os.path.normpath(self.workingDir), StartupInfo)
                except pywintypes.error as e:
                    raise ProcessError("Error creating process %s: %s" %
                                       (old_command, e))

                try:
                    if not self.disableKillingChildProcesses:
                        win32job.AssignProcessToJobObject(
                            self.__job, self.__hProcess)
                    else:
                        self.__job = None  # pragma: no cover
                except Exception as e:  # pragma: no cover
                    # Shouldn't fail unless process already terminated (which can happen since
                    # if we didn't use SUSPENDED there's an inherent race here)
                    if win32process.GetExitCodeProcess(
                            self.__hProcess) == win32con.STILL_ACTIVE:
                        log.warning(
                            'Failed to associate process %s with new job: %s (this may prevent automatic cleanup of child processes)'
                            % (self, e))

                    # force use of TerminateProcess not TerminateJobObject if this failed
                    self.__job = None

                if (dwCreationFlags & win32con.CREATE_SUSPENDED) != 0:
                    win32process.ResumeThread(self.__hThread)
            finally:
                win32file.CloseHandle(hStdin_r)
                win32file.CloseHandle(hStdout)
                win32file.CloseHandle(hStderr)

            # set the handle to the stdin of the process
            self.__stdin = hStdin
Esempio n. 15
0
    def __init__(self,
                 args,
                 bufsize=0,
                 stdin=None,
                 stdout=None,
                 stderr=None,
                 universal_newlines=False,
                 close_fds=False,
                 timeout_for_child_stream_duplication_event=30,
                 **kwargs):
        if not isinstance(bufsize, int):
            raise TypeError("bufsize must be an integer")

        self.commandline_passed = {}
        self._cleanup_on_terminate = []
        for s, p, m in [('stdin', stdin, 'w'), ('stdout', stdout, 'r'),
                        ('stderr', stderr, 'r')]:
            if p is None:
                self.commandline_passed[s] = (None, 'null')

            elif p == subprocess.PIPE:

                if m == 'r':
                    mode = 'rU' if universal_newlines else 'rb'
                else:
                    mode = 'wb'

                piperead, pipewrite = os.pipe()
                myfile = os.fdopen(pipewrite if m == 'w' else piperead, mode,
                                   bufsize)
                childhandle = str(
                    int(
                        msvcrt.get_osfhandle(pipewrite if m ==
                                             'r' else piperead)))
                self._cleanup_on_terminate.append(pipewrite if m ==
                                                  'r' else piperead)
                self.commandline_passed[s] = (myfile, childhandle, piperead,
                                              pipewrite)
            else:
                if isinstance(p, int):
                    childhandle = msvcrt.get_osfhandle(stdin)
                else:
                    # Assuming file-like object
                    childhandle = msvcrt.get_osfhandle(p.fileno())

                #The base implementation duplicates the handle, so we will too
                #It doesn't need to be inheritable for us, though
                cp = win32api.GetCurrentProcess()
                childhandle = win32api.DuplicateHandle(
                    cp,
                    childhandle,
                    cp,
                    0,  #desiredAccess ignored because of DUPLICATE_SAME_ACCESS
                    0,  #Inheritable
                    win32con.DUPLICATE_SAME_ACCESS)

                self.commandline_passed[s] = (None, str(int(childhandle)),
                                              childhandle, p)

        self._wait_for_child_duplication_event = win32event.CreateEvent(
            None,
            1,  #bManualReset
            0,
            None)

        args += [
            str(os.getpid()),
            str(int(self._wait_for_child_duplication_event)),
            self.commandline_passed['stdin'][1],
            self.commandline_passed['stdout'][1],
            self.commandline_passed['stderr'][1],
        ]

        super(HandlesOverCommandLinePopen,
              self).__init__(args,
                             bufsize=bufsize,
                             stdin=None,
                             stdout=None,
                             stderr=None,
                             close_fds=close_fds,
                             universal_newlines=universal_newlines,
                             **kwargs)

        if timeout_for_child_stream_duplication_event:
            if not self.wait_for_child_stream_duplication_event(
                    timeout_for_child_stream_duplication_event):
                logger.warning(
                    "Timed out waiting for child process to duplicate its io streams"
                )

        self.stdin = self.commandline_passed['stdin'][0]
        self.stdout = self.commandline_passed['stdout'][0]
        self.stderr = self.commandline_passed['stderr'][0]
Esempio n. 16
0
    def __init__(self, cmd, mode='t', cwd=None, env=None, avatar=None):
        log.info("Process.__init__(cmd=%r, mode=%r, cwd=%r, env=%r)", cmd,
                 mode, cwd, env)
        # Keep a reference to ensure it is around for this object's destruction.
        self.__log = log
        self.mCmd = cmd
        self.mCwd = cwd
        self.mEnv = env
        self.mAvatar = avatar
        self.mMode = mode
        if self.mMode not in ('t', 'b'):
            raise ProcessError("'mode' must be 't' or 'b'.")
        self.mClosed = False

        si = win32process.STARTUPINFO()
        si.dwFlags = (win32con.STARTF_USESTDHANDLES
                      ^ win32con.STARTF_USESHOWWINDOW)

        # Create pipes for std handles.
        # (Set the bInheritHandle flag so pipe handles are inherited.)
        saAttr = pywintypes.SECURITY_ATTRIBUTES()
        saAttr.bInheritHandle = 1
        #XXX Should maybe try with os.pipe. Dunno what that does for
        #    inheritability though.
        hChildStdinRd, hChildStdinWr = win32pipe.CreatePipe(saAttr, 0)
        hChildStdoutRd, hChildStdoutWr = win32pipe.CreatePipe(saAttr, 0)
        hChildStderrRd, hChildStderrWr = win32pipe.CreatePipe(saAttr, 0)

        try:
            # Duplicate the parent ends of the pipes so they are not
            # inherited.
            hChildStdinWrDup = win32api.DuplicateHandle(
                win32api.GetCurrentProcess(),
                hChildStdinWr,
                win32api.GetCurrentProcess(),
                0,
                0,  # not inherited
                DUPLICATE_SAME_ACCESS)
            win32api.CloseHandle(hChildStdinWr)
            self._hChildStdinWr = hChildStdinWrDup
            hChildStdoutRdDup = win32api.DuplicateHandle(
                win32api.GetCurrentProcess(),
                hChildStdoutRd,
                win32api.GetCurrentProcess(),
                0,
                0,  # not inherited
                DUPLICATE_SAME_ACCESS)
            win32api.CloseHandle(hChildStdoutRd)
            self._hChildStdoutRd = hChildStdoutRdDup
            hChildStderrRdDup = win32api.DuplicateHandle(
                win32api.GetCurrentProcess(),
                hChildStderrRd,
                win32api.GetCurrentProcess(),
                0,
                0,  # not inherited
                DUPLICATE_SAME_ACCESS)
            win32api.CloseHandle(hChildStderrRd)
            self._hChildStderrRd = hChildStderrRdDup

            # Set the translation mode and buffering.
            self._mode = 't'
            if self._mode == 't':
                flags = os.O_TEXT
            else:
                flags = 0
            fdChildStdinWr = msvcrt.open_osfhandle(self._hChildStdinWr, flags)
            fdChildStdoutRd = msvcrt.open_osfhandle(self._hChildStdoutRd,
                                                    flags)
            fdChildStderrRd = msvcrt.open_osfhandle(self._hChildStderrRd,
                                                    flags)

            self.stdin = _FileWrapper(descriptor=fdChildStdinWr,
                                      handle=self._hChildStdinWr)
            logres.info("[%s] Process._start(): create child stdin: %r",
                        id(self), self.stdin)
            self.stdout = _FileWrapper(descriptor=fdChildStdoutRd,
                                       handle=self._hChildStdoutRd)
            logres.info("[%s] Process._start(): create child stdout: %r",
                        id(self), self.stdout)
            self.stderr = _FileWrapper(descriptor=fdChildStderrRd,
                                       handle=self._hChildStderrRd)
            logres.info("[%s] Process._start(): create child stderr: %r",
                        id(self), self.stderr)

            si.hStdInput = hChildStdinRd
            si.hStdOutput = hChildStdoutWr
            si.hStdError = hChildStderrWr
            #si.wShowWindow = show
            si.wShowWindow = 1
            si.dwFlags |= win32process.STARTF_USESTDHANDLES

            creation_flags = win32process.CREATE_NEW_CONSOLE
            (self.mProcess, self.mThread, self.mProcessId, self.mThreadId)\
               = _safeCreateProcess(
                  self.mAvatar,    # Avatar
                  None,            # App name
                  cmd,             # Command
                  None,            # Process security attribs
                  None,            # Primary thread security attribs
                  1,               # Handles are inherited
                  creation_flags,  # Creation Flags
                  self.mEnv,       # Environment
                  self.mCwd,       # Current Working Directory
                  si)              # STARTUPINFO

        finally:
            # Close child ends of pipes on the parent's side (the
            # parent's ends of the pipe are closed in the _FileWrappers.)
            win32file.CloseHandle(hChildStdinRd)
            win32file.CloseHandle(hChildStdoutWr)
            win32file.CloseHandle(hChildStderrWr)
Esempio n. 17
0
    def __init__(self, reactor, protocol, command, args, environment, path):
        """
        Create a new child process.
        """
        _pollingfile._PollingTimer.__init__(self, reactor)
        BaseProcess.__init__(self, protocol)

        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create the pipes which will connect to the secondary process
        self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0)
        hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0)

        win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT,
                                          None, None)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdOutput = hStdoutW
        StartupInfo.hStdError = hStderrW
        StartupInfo.hStdInput = hStdinR
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

        # Create new handles whose inheritance property is false
        currentPid = win32api.GetCurrentProcess()

        tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid,
                                       0, 0, win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdoutR)
        self.hStdoutR = tmp

        tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid,
                                       0, 0, win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStderrR)
        self.hStderrR = tmp

        tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0,
                                       0, win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdinW)
        self.hStdinW = tmp

        # Add the specified environment to the current environment - this is
        # necessary because certain operations are only supported on Windows
        # if certain environment variables are present.

        env = os.environ.copy()
        env.update(environment or {})
        env = {
            os.fsdecode(key): os.fsdecode(value)
            for key, value in env.items()
        }

        # Make sure all the arguments are Unicode.
        args = [os.fsdecode(x) for x in args]

        cmdline = quoteArguments(args)

        # The command, too, needs to be Unicode, if it is a value.
        command = os.fsdecode(command) if command else command
        path = os.fsdecode(path) if path else path

        # TODO: error detection here.  See #2787 and #4184.
        def doCreate():
            flags = win32con.CREATE_NO_WINDOW
            self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess(
                command, cmdline, None, None, 1, flags, env, path, StartupInfo)

        try:
            doCreate()
        except pywintypes.error as pwte:
            if not _invalidWin32App(pwte):
                # This behavior isn't _really_ documented, but let's make it
                # consistent with the behavior that is documented.
                raise OSError(pwte)
            else:
                # look for a shebang line.  Insert the original 'command'
                # (actually a script) into the new arguments list.
                sheb = _findShebang(command)
                if sheb is None:
                    raise OSError("%r is neither a Windows executable, "
                                  "nor a script with a shebang line" % command)
                else:
                    args = list(args)
                    args.insert(0, command)
                    cmdline = quoteArguments(args)
                    origcmd = command
                    command = sheb
                    try:
                        # Let's try again.
                        doCreate()
                    except pywintypes.error as pwte2:
                        # d'oh, failed again!
                        if _invalidWin32App(pwte2):
                            raise OSError("%r has an invalid shebang line: "
                                          "%r is not a valid executable" %
                                          (origcmd, sheb))
                        raise OSError(pwte2)

        # close handles which only the child will use
        win32file.CloseHandle(hStderrW)
        win32file.CloseHandle(hStdoutW)
        win32file.CloseHandle(hStdinR)

        # set up everything
        self.stdout = _pollingfile._PollableReadPipe(
            self.hStdoutR,
            lambda data: self.proto.childDataReceived(1, data),
            self.outConnectionLost,
        )

        self.stderr = _pollingfile._PollableReadPipe(
            self.hStderrR,
            lambda data: self.proto.childDataReceived(2, data),
            self.errConnectionLost,
        )

        self.stdin = _pollingfile._PollableWritePipe(self.hStdinW,
                                                     self.inConnectionLost)

        for pipewatcher in self.stdout, self.stderr, self.stdin:
            self._addPollableResource(pipewatcher)

        # notify protocol
        self.proto.makeConnection(self)

        self._addPollableResource(_Reaper(self))
Esempio n. 18
0
    def __init__(self, reactor, protocol, command, args, environment, path):
        self.reactor = reactor
        self.protocol = protocol
        self.outBuffer = reactor.AllocateReadBuffer(self.bufferSize)
        self.errBuffer = reactor.AllocateReadBuffer(self.bufferSize)
        # This is the buffer for *reading* stdin, which is only done to
        # determine if the other end of the pipe was closed.
        self.inBuffer = reactor.AllocateReadBuffer(self.bufferSize)
        # IO operation classes
        self.readOutOp = ops.ReadOutOp(self)
        self.readErrOp = ops.ReadErrOp(self)
        self.readInOp = ops.ReadInOp(self)
        self.writeInOp = ops.WriteInOp(self)

        self.writeBuffer = ""
        self.writing = False
        self.finished = False
        self.offset = 0
        self.writeBufferedSize = 0
        self.closingStdin = False
        self.closedStdin = False
        self.closedStdout = False
        self.closedStderr = False
        # Stdio handles
        self.hChildStdinRd = None
        self.hChildStdinWr = None
        self.hChildStdinWrDup = None
        self.hChildStdoutRd = None
        self.hChildStdoutWr = None
        self.hChildStdoutRdDup = None
        self.hChildStderrRd = None
        self.hChildStderrWr = None
        self.hChildStderrRdDup = None

        self.closedNotifies = 0  # increments to 3 (for stdin, stdout, stderr)
        self.closed = False  # set to true when all 3 handles close
        self.exited = False  # set to true when WFMO thread gets signalled proc handle.  See doWaitForProcessExit.

        # Set the bInheritHandle flag so pipe handles are inherited.
        saAttr = win32security.SECURITY_ATTRIBUTES()
        saAttr.bInheritHandle = 1

        currentPid = win32api.GetCurrentProcess(
        )  # -1 which stands for current process
        self.pid = os.getpid()  # unique pid for pipe naming

        # Create a pipe for the child process's STDOUT.
        self.stdoutPipeName = r"\\.\pipe\twisted-iocp-stdout-%d-%d-%d" % (
            self.pid, counter.next(), time.time())
        self.hChildStdoutRd = win32pipe.CreateNamedPipe(
            self.stdoutPipeName,
            win32con.PIPE_ACCESS_INBOUND
            | win32con.FILE_FLAG_OVERLAPPED,  # open mode
            win32con.PIPE_TYPE_BYTE,  # pipe mode
            1,  # max instances
            self.pipeBufferSize,  # out buffer size
            self.pipeBufferSize,  # in buffer size
            0,  # timeout 
            saAttr)

        self.hChildStdoutWr = win32file.CreateFile(
            self.stdoutPipeName, win32con.GENERIC_WRITE,
            win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE, saAttr,
            win32con.OPEN_EXISTING, win32con.FILE_FLAG_OVERLAPPED, 0)

        # Create noninheritable read handle and close the inheritable read
        # handle.
        self.hChildStdoutRdDup = win32api.DuplicateHandle(
            currentPid, self.hChildStdoutRd, currentPid, 0, 0,
            win32con.DUPLICATE_SAME_ACCESS)
        win32api.CloseHandle(self.hChildStdoutRd)
        self.hChildStdoutRd = self.hChildStdoutRdDup

        # Create a pipe for the child process's STDERR.
        self.stderrPipeName = r"\\.\pipe\twisted-iocp-stderr-%d-%d-%d" % (
            self.pid, counter.next(), time.time())
        self.hChildStderrRd = win32pipe.CreateNamedPipe(
            self.stderrPipeName,
            win32con.PIPE_ACCESS_INBOUND
            | win32con.FILE_FLAG_OVERLAPPED,  # open mode
            win32con.PIPE_TYPE_BYTE,  # pipe mode
            1,  # max instances
            self.pipeBufferSize,  # out buffer size
            self.pipeBufferSize,  # in buffer size
            0,  # timeout 
            saAttr)
        self.hChildStderrWr = win32file.CreateFile(
            self.stderrPipeName, win32con.GENERIC_WRITE,
            win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE, saAttr,
            win32con.OPEN_EXISTING, win32con.FILE_FLAG_OVERLAPPED, 0)

        # Create noninheritable read handle and close the inheritable read
        # handle.
        self.hChildStderrRdDup = win32api.DuplicateHandle(
            currentPid, self.hChildStderrRd, currentPid, 0, 0,
            win32con.DUPLICATE_SAME_ACCESS)
        win32api.CloseHandle(self.hChildStderrRd)
        self.hChildStderrRd = self.hChildStderrRdDup

        # Create a pipe for the child process's STDIN. This one is opened
        # in duplex mode so we can read from it too in order to detect when
        # the child closes their end of the pipe.
        self.stdinPipeName = r"\\.\pipe\twisted-iocp-stdin-%d-%d-%d" % (
            self.pid, counter.next(), time.time())
        self.hChildStdinWr = win32pipe.CreateNamedPipe(
            self.stdinPipeName,
            win32con.PIPE_ACCESS_DUPLEX
            | win32con.FILE_FLAG_OVERLAPPED,  # open mode
            win32con.PIPE_TYPE_BYTE,  # pipe mode
            1,  # max instances
            self.pipeBufferSize,  # out buffer size
            self.pipeBufferSize,  # in buffer size
            0,  # timeout 
            saAttr)

        self.hChildStdinRd = win32file.CreateFile(
            self.stdinPipeName, win32con.GENERIC_READ,
            win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE, saAttr,
            win32con.OPEN_EXISTING, win32con.FILE_FLAG_OVERLAPPED, 0)

        # Duplicate the write handle to the pipe so it is not inherited.
        self.hChildStdinWrDup = win32api.DuplicateHandle(
            currentPid, self.hChildStdinWr, currentPid, 0, 0,
            win32con.DUPLICATE_SAME_ACCESS)
        win32api.CloseHandle(self.hChildStdinWr)
        self.hChildStdinWr = self.hChildStdinWrDup

        # set the info structure for the new process.  This is where
        # we tell the process to use the pipes for stdout/err/in.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdOutput = self.hChildStdoutWr
        StartupInfo.hStdError = self.hChildStderrWr
        StartupInfo.hStdInput = self.hChildStdinRd
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

        # create the process
        cmdline = quoteArguments(args)
        self.hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
            command,  # name
            cmdline,  # command line
            None,  # process security attributes
            None,  # primary thread security attributes
            1,  # handles are inherited
            0,  # creation flags
            environment,  # if NULL, use parent environment
            path,  # current directory
            StartupInfo)  # STARTUPINFO pointer

        # close handles which only the child will use
        win32file.CloseHandle(self.hChildStderrWr)
        win32file.CloseHandle(self.hChildStdoutWr)
        win32file.CloseHandle(self.hChildStdinRd)

        # Begin reading on stdout and stderr, before we have output on them.
        self.readOutOp.initiateOp(self.hChildStdoutRd, self.outBuffer)
        self.readErrOp.initiateOp(self.hChildStderrRd, self.errBuffer)
        # Read stdin which was opened in duplex mode so we can detect when
        # the child closed their end of the pipe.
        self.readInOp.initiateOp(self.hChildStdinWr, self.inBuffer)

        # When the process is done, call connectionLost().
        # This function returns right away.  Note I call this after
        # protocol.makeConnection to ensure that the protocol doesn't
        # have processEnded called before protocol.makeConnection.
        self.reactor.processWaiter.beginWait(self.reactor, self.hProcess, self)

        # notify protocol by calling protocol.makeConnection and specifying
        # ourself as the transport.
        self.protocol.makeConnection(self)
Esempio n. 19
0
def processCreate(sName, asArgs):
    """
    Returns a (pid, handle, tid) tuple on success. (-1, None) on failure (logged).
    """

    # Construct a command line.
    sCmdLine = ''
    for sArg in asArgs:
        if sCmdLine == '':
            sCmdLine += '"'
        else:
            sCmdLine += ' "'
        sCmdLine += sArg
        sCmdLine += '"'

    # Try start the process.
    # pylint: disable=no-member
    dwCreationFlags = win32con.CREATE_NEW_PROCESS_GROUP
    oStartupInfo = win32process.STARTUPINFO()
    # pylint: disable=c-extension-no-member
    try:
        (hProcess, hThread, uPid, uTid) = win32process.CreateProcess(
            sName,  # pylint: disable=c-extension-no-member
            sCmdLine,  # CommandLine
            None,  # ProcessAttributes
            None,  # ThreadAttibutes
            1,  # fInheritHandles
            dwCreationFlags,
            None,  # Environment
            None,  # CurrentDirectory.
            oStartupInfo)
    except:
        reporter.logXcpt('sName="%s" sCmdLine="%s"' % (sName, sCmdLine))
        return (-1, None, -1)

    # Dispense with the thread handle.
    try:
        hThread.Close()
        # win32api.CloseHandle(hThread);
    except:
        reporter.logXcpt()

    # Try get full access to the process.
    try:
        hProcessFullAccess = win32api.DuplicateHandle(  # pylint: disable=c-extension-no-member
            win32api.GetCurrentProcess(),  # pylint: disable=c-extension-no-member
            hProcess,
            win32api.GetCurrentProcess(),  # pylint: disable=c-extension-no-member
            win32con.PROCESS_TERMINATE
            | win32con.PROCESS_QUERY_INFORMATION
            | win32con.SYNCHRONIZE
            | win32con.DELETE,
            False,
            0)
        hProcess.Close()
        # win32api.CloseHandle(hProcess);
        hProcess = hProcessFullAccess
    except:
        reporter.logXcpt()
    reporter.log2('processCreate -> %#x, hProcess=%s %#x' % (
        uPid,
        hProcess,
        hProcess.handle,
    ))
    return (uPid, hProcess, uTid)
Esempio n. 20
0
    def __init__(self, reactor, protocol, command, args, environment, path):
        _pollingfile._PollingTimer.__init__(self, reactor)
        BaseProcess.__init__(self, protocol)

        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create the pipes which will connect to the secondary process
        self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0)
        hStdinR,  self.hStdinW  = win32pipe.CreatePipe(sAttrs, 0)

        win32pipe.SetNamedPipeHandleState(self.hStdinW,
                                          win32pipe.PIPE_NOWAIT,
                                          None,
                                          None)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdOutput = hStdoutW
        StartupInfo.hStdError  = hStderrW
        StartupInfo.hStdInput  = hStdinR
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

        # Create new handles whose inheritance property is false
        currentPid = win32api.GetCurrentProcess()

        tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdoutR)
        self.hStdoutR = tmp

        tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStderrR)
        self.hStderrR = tmp

        tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0, 0,
                                       win32con.DUPLICATE_SAME_ACCESS)
        win32file.CloseHandle(self.hStdinW)
        self.hStdinW = tmp

        # Add the specified environment to the current environment - this is
        # necessary because certain operations are only supported on Windows
        # if certain environment variables are present.

        env = os.environ.copy()
        env.update(environment or {})

        cmdline = quoteArguments(args)
        # TODO: error detection here.
        def doCreate():
            self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess(
                command, cmdline, None, None, 1, 0, env, path, StartupInfo)
        try:
            doCreate()
        except pywintypes.error, pwte:
            if not _invalidWin32App(pwte):
                # This behavior isn't _really_ documented, but let's make it
                # consistent with the behavior that is documented.
                raise OSError(pwte)
            else:
                # look for a shebang line.  Insert the original 'command'
                # (actually a script) into the new arguments list.
                sheb = _findShebang(command)
                if sheb is None:
                    raise OSError(
                        "%r is neither a Windows executable, "
                        "nor a script with a shebang line" % command)
                else:
                    args = list(args)
                    args.insert(0, command)
                    cmdline = quoteArguments(args)
                    origcmd = command
                    command = sheb
                    try:
                        # Let's try again.
                        doCreate()
                    except pywintypes.error, pwte2:
                        # d'oh, failed again!
                        if _invalidWin32App(pwte2):
                            raise OSError(
                                "%r has an invalid shebang line: "
                                "%r is not a valid executable" % (
                                    origcmd, sheb))
                        raise OSError(pwte2)
Esempio n. 21
0
import msvcrt
import win32api
import win32con

# Get file descriptor from argument
ppid = int(sys.argv[1])
pipearg = int(sys.argv[2])
pipe2arg = int(sys.argv[3])

curproc = win32api.GetCurrentProcess()
parent_process = win32api.OpenProcess(win32con.PROCESS_DUP_HANDLE, 0, int(ppid))

in_file_handle = win32api.DuplicateHandle(
                       parent_process,
                       pipearg,
                       curproc,
                       0, #desiredAccess ignored because of DUPLICATE_SAME_ACCESS
                       0, #Inheritable
                       win32con.DUPLICATE_SAME_ACCESS | win32con.DUPLICATE_CLOSE_SOURCE)

out_file_handle = win32api.DuplicateHandle(
                       parent_process,
                       pipe2arg,
                       curproc,
                       0, #desiredAccess ignored because of DUPLICATE_SAME_ACCESS
                       0, #Inheritable
                       win32con.DUPLICATE_SAME_ACCESS | win32con.DUPLICATE_CLOSE_SOURCE)

pipeinfd = msvcrt.open_osfhandle(int(in_file_handle), os.O_RDONLY)
pipeoutfd = msvcrt.open_osfhandle(int(out_file_handle), os.O_WRONLY)
Esempio n. 22
0
 def make_inheritable(token):
     """Return a duplicate of handle, which is inheritable"""
     return win32api.DuplicateHandle(win32api.GetCurrentProcess(),
                                     token,
                                     win32api.GetCurrentProcess(), 0, 1,
                                     win32con.DUPLICATE_SAME_ACCESS)
Esempio n. 23
0
 def make_inheritable(self, handle):
     p = win32api.GetCurrentProcess()
     ret = win32api.DuplicateHandle(p, handle, p, 0, 1,
                                    win32con.DUPLICATE_SAME_ACCESS)
     win32api.CloseHandle(handle)
     return ret