cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# -*- coding: utf-8 -*-
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# $Id$
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThis module is here to externalize some Windows specifics that gives pychecker
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsynca hard time when running on non-Windows systems.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__copyright__ = \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCopyright (C) 2010-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThis file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncavailable from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncyou can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGeneral Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncFoundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsynchope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThe contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncof the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync(CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncYou may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncterms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__version__ = "$Revision$"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Standard Python imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport os
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Windows specific imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport win32api; # pylint: disable=F0401
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport win32con; # pylint: disable=F0401
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport win32console; # pylint: disable=F0401
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport win32event; # pylint: disable=F0401
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport win32process; # pylint: disable=F0401
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Validation Kit imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testdriver import reporter;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Windows specific implementation of base functions.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef processInterrupt(uPid):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The Windows version of base.processInterrupt
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note! This doesn't work terribly well with a lot of processes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32console.GenerateConsoleCtrlEvent(win32con.CTRL_BREAK_EVENT, uPid);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #GenerateConsoleCtrlEvent = ctypes.windll.kernel32.GenerateConsoleCtrlEvent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #rc = GenerateConsoleCtrlEvent(1, uPid);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #reporter.log('GenerateConsoleCtrlEvent -> %s' % (rc,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('uPid=%s' % (uPid,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef postThreadMesssageClose(uTid):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Posts a WM_CLOSE message to the specified thread."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.PostThreadMessage(uTid, win32con.WM_CLOSE, 0, 0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('uTid=%s' % (uTid,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef postThreadMesssageQuit(uTid):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Posts a WM_QUIT message to the specified thread."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.PostThreadMessage(uTid, win32con.WM_QUIT, 0x40010004, 0); # DBG_TERMINATE_PROCESS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('uTid=%s' % (uTid,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef processTerminate(uPid):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ The Windows version of base.processTerminate """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync hProcess = win32api.OpenProcess(win32con.PROCESS_TERMINATE, False, uPid);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('uPid=%s' % (uPid,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32process.TerminateProcess(hProcess, 0x40010004); # DBG_TERMINATE_PROCESS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('uPid=%s' % (uPid,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.CloseHandle(hProcess)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef processKill(uPid):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ The Windows version of base.processKill """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return processTerminate(uPid);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef processExists(uPid):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ The Windows version of base.processExists """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync hProcess = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION, False, uPid);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('uPid=%s' % (uPid,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.CloseHandle(hProcess)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef processCheckPidAndName(uPid, sName):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ The Windows version of base.processCheckPidAndName """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = processExists(uPid);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fRc is True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from win32com.client import GetObject; # pylint: disable=F0401
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oWmi = GetObject('winmgmts:');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoProcesses = oWmi.InstancesOf('Win32_Process');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oProcess in aoProcesses:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if long(oProcess.Properties_("ProcessId").Value) == uPid:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCurName = oProcess.Properties_("Name").Value;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.log2('uPid=%s sName=%s sCurName=%s' % (uPid, sName, sCurName));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName = sName.lower();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCurName = sCurName.lower();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if os.path.basename(sName) == sName:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCurName = os.path.basename(sCurName);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sCurName == sName \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sCurName + '.exe' == sName \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sCurName == sName + '.exe':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('uPid=%s sName=%s' % (uPid, sName));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fRc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Some helper functions.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef processCreate(sName, asArgs):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns a (pid, handle, tid) tuple on success. (-1, None) on failure (logged).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Construct a command line.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine = '';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sArg in asArgs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sCmdLine == '':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine += '"';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine += ' "';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine += sArg;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine += '"';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try start the process.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dwCreationFlags = win32con.CREATE_NEW_PROCESS_GROUP;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStartupInfo = win32process.STARTUPINFO();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (hProcess, hThread, uPid, uTid) = win32process.CreateProcess(sName,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine, # CommandLine
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync None, # ProcessAttributes
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync None, # ThreadAttibutes
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 1, # fInheritHandles
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dwCreationFlags,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync None, # Environment
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync None, # CurrentDirectory.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStartupInfo);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('sName="%s" sCmdLine="%s"' % (sName, sCmdLine));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (-1, None, -1);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Dispense with the thread handle.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.CloseHandle(hThread);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try get full access to the process.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync hProcessFullAccess = win32api.DuplicateHandle( \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.GetCurrentProcess(), \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync hProcess, \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.GetCurrentProcess(), \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32con.PROCESS_TERMINATE \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync | win32con.PROCESS_QUERY_INFORMATION \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync | win32con.SYNCHRONIZE \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync | win32con.DELETE, \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync False, \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.CloseHandle(hProcess);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync hProcess = hProcessFullAccess;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.log2('processCreate -> %#x, hProcess=%#x' % (uPid, hProcess,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (uPid, hProcess, uTid);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef processPollByHandle(hProcess):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Polls the process handle to see if it has finished (True) or not (False).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dwWait = win32event.WaitForSingleObject(hProcess, 0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('hProcess=%s %#x' % (hProcess, hProcess,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return dwWait != win32con.WAIT_TIMEOUT; #0x102; #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef processTerminateByHandle(hProcess):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Terminates the process.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync win32api.TerminateProcess(hProcess, 0x40010004); # DBG_TERMINATE_PROCESS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync reporter.logXcpt('hProcess=%s %#x' % (hProcess, hProcess,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync