<reponame>marlon-sousa/nvda<filename>source/comHelper.py
#comHelper.py
#A part of NonVisual Desktop Access (NVDA)
#Copyright (C) 2013 NV Access Limited
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.

"""Utilities to help with issues related to COM.
"""

import subprocess
import ctypes
import comtypes.client.dynamic
from comtypes import IUnknown
from comtypes.automation import IDispatch
import oleacc
import config

MK_E_UNAVAILABLE = -2147221021
CO_E_CLASSSTRING = -2147221005

def _lresultFromGetActiveObject(progid, dynamic):
	o = comtypes.client.GetActiveObject(progid, dynamic=dynamic)
	if not isinstance(o, IUnknown):
		o = o._comobj
	return oleacc.LresultFromObject(0, o)

def getActiveObject(progid, dynamic=False,appModule=None):
	"""Get an active COM object, handling privilege issues.
	This is similar to comtypes.client.GetActiveObject
	except that it can retrieve objects from normal processes when NVDA is running with uiAccess.
	"""
	if appModule:
		if not appModule.helperLocalBindingHandle:
			raise ValueError("appModule does not have a binding handle")
		import NVDAHelper
		p=ctypes.POINTER(comtypes.IUnknown)()
		res=NVDAHelper.localLib.nvdaInProcUtils_getActiveObject(appModule.helperLocalBindingHandle,progid,ctypes.byref(p))
		if res!=0:
			raise ctypes.WinError(res)
		if not p:
			raise RuntimeError("NULL IUnknown pointer")
		if dynamic:
			return comtypes.client.dynamic.Dispatch(p.QueryInterface(IDispatch))
		else:
			return comtypes.client.GetBestInterface(p)
	try:
		return comtypes.client.GetActiveObject(progid, dynamic=dynamic)
	except WindowsError as e:
		if e.winerror not in (MK_E_UNAVAILABLE, CO_E_CLASSSTRING):
			# This isn't related to privileges.
			raise
	p = subprocess.Popen((config.SLAVE_FILENAME, "comGetActiveObject", progid, "%d" % dynamic),
		stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
	try:
		try:
			lres = int(p.stdout.readline())
		except ValueError:
			raise RuntimeError("Helper process unable to get object; see log for details")
		o = oleacc.ObjectFromLresult(lres, 0,
			IDispatch if dynamic else IUnknown)
		if dynamic:
			o = comtypes.client.dynamic.Dispatch(o)
		return o
	finally:
		# This will cause EOF for the waiting process, which will then exit.
		p.stdin.close()
		p.wait()
		p.stdout.close()

#comHelper.py
#A part of NonVisual Desktop Access (NVDA)
#Copyright (C) 2013 NV Access Limited
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.

"""Utilities to help with issues related to COM.
"""

import subprocess
import ctypes
import comtypes.client.dynamic
from comtypes import IUnknown
from comtypes.automation import IDispatch
import oleacc
import config

MK_E_UNAVAILABLE = -2147221021
CO_E_CLASSSTRING = -2147221005

def _lresultFromGetActiveObject(progid, dynamic):
	o = comtypes.client.GetActiveObject(progid, dynamic=dynamic)
	if not isinstance(o, IUnknown):
		o = o._comobj
	return oleacc.LresultFromObject(0, o)

def getActiveObject(progid, dynamic=False,appModule=None):
	"""Get an active COM object, handling privilege issues.
	This is similar to comtypes.client.GetActiveObject
	except that it can retrieve objects from normal processes when NVDA is running with uiAccess.
	"""
	if appModule:
		if not appModule.helperLocalBindingHandle:
			raise ValueError("appModule does not have a binding handle")
		import NVDAHelper
		p=ctypes.POINTER(comtypes.IUnknown)()
		res=NVDAHelper.localLib.nvdaInProcUtils_getActiveObject(appModule.helperLocalBindingHandle,progid,ctypes.byref(p))
		if res!=0:
			raise ctypes.WinError(res)
		if not p:
			raise RuntimeError("NULL IUnknown pointer")
		if dynamic:
			return comtypes.client.dynamic.Dispatch(p.QueryInterface(IDispatch))
		else:
			return comtypes.client.GetBestInterface(p)
	try:
		return comtypes.client.GetActiveObject(progid, dynamic=dynamic)
	except WindowsError as e:
		if e.winerror not in (MK_E_UNAVAILABLE, CO_E_CLASSSTRING):
			# This isn't related to privileges.
			raise
	p = subprocess.Popen((config.SLAVE_FILENAME, "comGetActiveObject", progid, "%d" % dynamic),
		stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
	try:
		try:
			lres = int(p.stdout.readline())
		except ValueError:
			raise RuntimeError("Helper process unable to get object; see log for details")
		o = oleacc.ObjectFromLresult(lres, 0,
			IDispatch if dynamic else IUnknown)
		if dynamic:
			o = comtypes.client.dynamic.Dispatch(o)
		return o
	finally:
		# This will cause EOF for the waiting process, which will then exit.
		p.stdin.close()
		p.wait()
		p.stdout.close()
#comHelper.py #A part of NonVisual Desktop Access (NVDA) #Copyright (C) 2013 NV Access Limited #This file is covered by the GNU General Public License. #See the file COPYING for more details. Utilities to help with issues related to COM. Get an active COM object, handling privilege issues.
 	This is similar to comtypes.client.GetActiveObject
 	except that it can retrieve objects from normal processes when NVDA is running with uiAccess. # This isn't related to privileges. # This will cause EOF for the waiting process, which will then exit.