From eadc0c6963c0b8246b71e9b5351e8dc8c387d580 Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Thu, 24 Mar 2016 18:14:45 +0100 Subject: [PATCH] More COM interfaces/ API --- ctypes_generation/com_parser.py | 2 +- windows/com.py | 39 ++++++++++++++++++++++++--- windows/generated_def/interfaces.py | 42 +++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/ctypes_generation/com_parser.py b/ctypes_generation/com_parser.py index 58c763a..0938216 100644 --- a/ctypes_generation/com_parser.py +++ b/ctypes_generation/com_parser.py @@ -57,7 +57,7 @@ def initial_processing( data): class WinComParser(Parser): PARAM_INFO = ["__RPC__deref_out", "__RPC__in", "__RPC__deref_out_opt", "__RPC__out", "__RPC__in_opt", "__RPC__deref_opt_inout_opt"] - PARAM_INFO_WITH_VALUE = ["__RPC__in_ecount", "__RPC__out_ecount_part", "__RPC__in_ecount_full"] + PARAM_INFO_WITH_VALUE = ["__RPC__in_ecount", "__RPC__out_ecount_part", "__RPC__in_ecount_full", "__RPC__in_range", "__RPC__out_ecount_full"] def __init__(self, data): data = initial_processing(data) diff --git a/windows/com.py b/windows/com.py index d6bc65b..05ddd16 100644 --- a/windows/com.py +++ b/windows/com.py @@ -3,11 +3,16 @@ import ctypes import functools from ctypes.wintypes import HRESULT, byref, pointer +import windows from windows import winproxy +from windows.generated_def.winstructs import * + from windows.generated_def import RPC_C_IMP_LEVEL_IMPERSONATE, CLSCTX_INPROC_SERVER from windows.generated_def import interfaces from windows.generated_def.interfaces import generate_IID, IID + + # Simple Implem to create COM Interface in Python (COM -> Python) def create_c_callable(func, types, keepalive=[]): func_type = ctypes.WINFUNCTYPE(*types) @@ -17,21 +22,49 @@ def create_c_callable(func, types, keepalive=[]): keepalive.append(c_callable) return c_callback_addr + def init(): t = winproxy.CoInitializeEx() if t: return t return winproxy.CoInitializeSecurity(0, -1, None, 0, 0, RPC_C_IMP_LEVEL_IMPERSONATE, 0,0,0) + + +class ImprovedVariant(VARIANT): + @property + def asbstr(self): + if self.vt != VT_BSTR: + raise ValueError("asbstr on non-bstr variant") + #import pdb;pdb.set_trace() + return self._VARIANT_NAME_3.bstrVal + + @property + def aslong(self): + if not self.vt in [VT_I4, VT_BOOL]: + raise ValueError("aslong on non-long variant") + return self._VARIANT_NAME_3.lVal + + @property + def asbool(self): + if not self.vt in [VT_BOOL]: + raise ValueError("get_bstr on non-bool variant") + return bool(self.aslong) + + @property + def asdispatch(self): + if not self.vt in [VT_DISPATCH]: + raise ValueError("asdispatch on non-VT_DISPATCH variant") + return interfaces.IDispatch(self._VARIANT_NAME_3.pdispVal) + + + def create_instance(clsiid, targetinterface, custom_iid=None): if custom_iid is None: custom_iid = targetinterface.IID return winproxy.CoCreateInstance(byref(clsiid), None, CLSCTX_INPROC_SERVER, byref(custom_iid), byref(targetinterface)) - - - class ComVtable(object): # Name, types _funcs_ = [("QueryInterface", [ctypes.HRESULT, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]), diff --git a/windows/generated_def/interfaces.py b/windows/generated_def/interfaces.py index cb5d671..3380774 100644 --- a/windows/generated_def/interfaces.py +++ b/windows/generated_def/interfaces.py @@ -42,6 +42,48 @@ class COMInterface(ctypes.c_void_p): return functools.partial(self._functions_[name], self) return super(COMInterface, self).__getattribute__(name) +class IDispatch(COMInterface): + IID = generate_IID(0x00020400, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, name="IDispatch", strid="00020400-0000-0000-C000-000000000046") + + _functions_ = { + #QueryInterface -> riid:REFIID, ppvObject:**void + "QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"), + #AddRef -> + "AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"), + #Release -> + "Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"), + #GetTypeInfoCount -> pctinfo:*UINT + "GetTypeInfoCount": ctypes.WINFUNCTYPE(HRESULT, POINTER(UINT))(3, "GetTypeInfoCount"), + #GetTypeInfo -> iTInfo:UINT, lcid:LCID, ppTInfo:**ITypeInfo + "GetTypeInfo": ctypes.WINFUNCTYPE(HRESULT, UINT, LCID, POINTER(POINTER(ITypeInfo)))(4, "GetTypeInfo"), + #GetIDsOfNames -> riid:REFIID, rgszNames:*LPOLESTR, cNames:UINT, lcid:LCID, rgDispId:*DISPID + "GetIDsOfNames": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(LPOLESTR), UINT, LCID, POINTER(DISPID))(5, "GetIDsOfNames"), + #Invoke -> dispIdMember:DISPID, riid:REFIID, lcid:LCID, wFlags:WORD, pDispParams:*DISPPARAMS, pVarResult:*VARIANT, pExcepInfo:*EXCEPINFO, puArgErr:*UINT + "Invoke": ctypes.WINFUNCTYPE(HRESULT, DISPID, REFIID, LCID, WORD, POINTER(DISPPARAMS), POINTER(VARIANT), POINTER(EXCEPINFO), POINTER(UINT))(6, "Invoke"), + } + + +class IEnumVARIANT(COMInterface): + IID = generate_IID(0x00020404, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, name="IEnumVARIANT", strid="00020404-0000-0000-C000-000000000046") + + _functions_ = { + #QueryInterface -> riid:REFIID, ppvObject:**void + "QueryInterface": ctypes.WINFUNCTYPE(HRESULT, REFIID, POINTER(PVOID))(0, "QueryInterface"), + #AddRef -> + "AddRef": ctypes.WINFUNCTYPE(ULONG)(1, "AddRef"), + #Release -> + "Release": ctypes.WINFUNCTYPE(ULONG)(2, "Release"), + #Next -> celt:ULONG, rgVar:*VARIANT, pCeltFetched:*ULONG + "Next": ctypes.WINFUNCTYPE(HRESULT, ULONG, POINTER(VARIANT), POINTER(ULONG))(3, "Next"), + #Skip -> celt:ULONG + "Skip": ctypes.WINFUNCTYPE(HRESULT, ULONG)(4, "Skip"), + #Reset -> + "Reset": ctypes.WINFUNCTYPE(HRESULT)(5, "Reset"), + #Clone -> ppEnum:**IEnumVARIANT + "Clone": ctypes.WINFUNCTYPE(HRESULT, POINTER(PVOID))(6, "Clone"), + } + + class IEnumWbemClassObject(COMInterface): IID = generate_IID(0x027947E1, 0xD731, 0x11CE, 0xA3, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, name="IEnumWbemClassObject", strid="027947E1-D731-11CE-A357-000000000001")