Ejemplo n.º 1
0
 def wait(self):
     """Wait for child process to terminate.  Returns returncode
     attribute."""
     if self.returncode is None:
         obj = WaitForSingleObject(self._handle, INFINITE)
         self.returncode = GetExitCodeProcess(self._handle)
     return self.returncode
Ejemplo n.º 2
0
 def _internal_poll(self, _deadstate=None):
     """Check if child process has terminated.  Returns returncode
     attribute."""
     if self.returncode is None:
         if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
             self.returncode = GetExitCodeProcess(self._handle)
     return self.returncode
Ejemplo n.º 3
0
 def poll(self):
     """Check if child process has terminated.  Returns returncode
     attribute."""
     if self.returncode == None:
         if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
             self.returncode = GetExitCodeProcess(self._handle)
             _active.remove(self)
     return self.returncode
Ejemplo n.º 4
0
 def isalive(self):
     """Return True if the child is alive, False otherwise."""
     if self.exitstatus is not None:
         return False
     ret = WaitForSingleObject(self.child_handle, 0)
     if ret == WAIT_OBJECT_0:
         self.exitstatus = GetExitCodeProcess(self.child_handle)
         return False
     return True
Ejemplo n.º 5
0
 def wait(self, timeout=None):
     """Wait until the child exits. If timeout is not specified this
     blocks indefinately. Otherwise, timeout specifies the number of
     seconds to wait."""
     if self.exitstatus is not None:
         return
     if timeout is None:
         timeout = INFINITE
     else:
         timeout = 1000 * timeout
     ret = WaitForSingleObject(self.child_handle, timeout)
     if ret == WAIT_TIMEOUT:
         raise TIMEOUT('Timeout exceeded in wait().')
     self.exitstatus = GetExitCodeProcess(self.child_handle)
     return self.exitstatus
Ejemplo n.º 6
0
def run_as_admin(exe, params, as_admin=True):
    import win32com.shell.shell as shell
    import win32con
    from win32process import GetExitCodeProcess
    import win32event
    import pywintypes

    try:
        # Try to launch process as administrator in case exception was
        # due to insufficient privileges.
        # To make process call block, set `fMask` parameter to return
        # handle to process that can be monitored to wait for the
        # process to exit.  See the [SHELLEXECUTEINFO structure
        # documentation][1] for details.
        #
        # [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/bb759784%28v=vs.85%29.aspx
        SEE_MASK_NOASYNC = 0x00000100
        SEE_MASK_NOCLOSEPROCESS = 0x00000040
        WAIT_FOREVER = -1

        launch_kwargs = dict(lpFile=exe, lpParameters=params,
                             nShow=win32con.SW_SHOW,
                             fMask=(SEE_MASK_NOASYNC |
                                    SEE_MASK_NOCLOSEPROCESS))
        if as_admin:
            launch_kwargs['lpVerb'] = 'runas'
        process_info = shell.ShellExecuteEx(**launch_kwargs)
        win32event.WaitForSingleObject(process_info['hProcess'],
                                       WAIT_FOREVER)
        return_code = GetExitCodeProcess(process_info['hProcess'])
        if return_code == 0:
            return ''
        else:
            raise RuntimeError('Process returned error code: %s' % return_code)

    except pywintypes.error as e:
        if e.winerror == 1223:  # Error 1223 is elevation cancelled.
            raise CancelAction(e.strerror)
        else:
            raise
Ejemplo n.º 7
0
def run_as_admin(wait_exit: bool = True) -> Optional[int]:
    # noinspection PyUnresolvedReferences
    from win32com.shell.shell import ShellExecuteEx
    from win32event import WaitForSingleObject, INFINITE
    from win32process import GetExitCodeProcess
    # import win32con
    # noinspection PyUnresolvedReferences
    from win32com.shell import shellcon
    import win32api
    cmd = '"%s"' % sys.executable
    params = ' '.join(['"%s"' % x for x in sys.argv])
    proc = ShellExecuteEx(
        lpFile=cmd,
        lpParameters=params,
        lpVerb='runas',  # nShow=win32con.SW_SHOWNORMAL,
        fMask=shellcon.SEE_MASK_NOCLOSEPROCESS)
    if wait_exit:
        handle = proc['hProcess']
        WaitForSingleObject(handle, INFINITE)
        rc = GetExitCodeProcess(handle)
        win32api.CloseHandle(handle)
        return rc
Ejemplo n.º 8
0
 def isAlive(self):
     """Returns true if the editor process is still alive"""
     return GetExitCodeProcess(self.handle) == 259
Ejemplo n.º 9
0
def _call_command(command,
                  logoutput=False,
                  cwd=None,
                  env=None,
                  wait_for_finish=True,
                  timeout=None,
                  user=None):
    # TODO implement timeout, wait_for_finish
    Logger.info("Executing %s" % (command))
    if user:
        domain, username = UserHelper.parse_user_name(user, ".")

        proc_token = OpenProcessToken(GetCurrentProcess(),
                                      TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES)

        old_states = []

        privileges = [
            SE_ASSIGNPRIMARYTOKEN_NAME,
            SE_INCREASE_QUOTA_NAME,
        ]

        for priv in privileges:
            old_states.append(QueryPrivilegeState(proc_token, priv))
            AdjustPrivilege(proc_token, priv)
            QueryPrivilegeState(proc_token, priv)

        user_token = LogonUser(username, domain, Script.get_password(user),
                               win32con.LOGON32_LOGON_SERVICE,
                               win32con.LOGON32_PROVIDER_DEFAULT)
        env_token = DuplicateTokenEx(user_token, SecurityIdentification,
                                     TOKEN_QUERY, TokenPrimary)
        # getting updated environment for impersonated user and merge it with custom env
        current_env = CreateEnvironmentBlock(env_token, False)
        current_env = _merge_env(current_env, env)

        si = STARTUPINFO()
        out_handle, err_handle, out_file, err_file = _create_tmp_files(
            current_env)
        ok, si.hStdInput = _safe_duplicate_handle(
            GetStdHandle(STD_INPUT_HANDLE))
        if not ok:
            raise Exception("Unable to create StdInput for child process")
        ok, si.hStdOutput = _safe_duplicate_handle(out_handle)
        if not ok:
            raise Exception("Unable to create StdOut for child process")
        ok, si.hStdError = _safe_duplicate_handle(err_handle)
        if not ok:
            raise Exception("Unable to create StdErr for child process")

        Logger.debug("Redirecting stdout to '{0}', stderr to '{1}'".format(
            out_file.name, err_file.name))

        si.dwFlags = win32con.STARTF_USESTDHANDLES
        si.lpDesktop = ""

        try:
            info = CreateProcessAsUser(user_token, None, command, None, None,
                                       1, win32con.CREATE_NO_WINDOW,
                                       current_env, cwd, si)
            hProcess, hThread, dwProcessId, dwThreadId = info
            hThread.Close()

            try:
                WaitForSingleObject(hProcess, INFINITE)
            except KeyboardInterrupt:
                pass
            out, err = _get_files_output(out_file, err_file)
            code = GetExitCodeProcess(hProcess)
        finally:
            for priv in privileges:
                old_state = old_states.pop(0)
                AdjustPrivilege(proc_token, priv, old_state)
    else:
        # getting updated environment for current process and merge it with custom env
        cur_token = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY)
        current_env = CreateEnvironmentBlock(cur_token, False)
        current_env = _merge_env(current_env, env)
        proc = subprocess.Popen(command,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT,
                                cwd=cwd,
                                env=current_env,
                                shell=False)
        out, err = proc.communicate()
        code = proc.returncode

    if logoutput and out:
        Logger.info(out)
    if logoutput and err:
        Logger.info(err)
    return code, out, err