From cf6c813002bcd742aef2fce32ed81da7e09bea80 Mon Sep 17 00:00:00 2001 From: hakril Date: Sat, 24 Nov 2018 21:42:07 +0100 Subject: [PATCH] ComInterface now expose a callback for ctypes error handling. Allow COM interface to change/handle the raised Exception --- ctypes_generation/definitions/com/template.py | 35 ++++++++++++++++++- windows/winproxy/error.py | 7 +--- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/ctypes_generation/definitions/com/template.py b/ctypes_generation/definitions/com/template.py index b07145e..1de40cf 100644 --- a/ctypes_generation/definitions/com/template.py +++ b/ctypes_generation/definitions/com/template.py @@ -4,13 +4,38 @@ import ctypes generate_IID = IID.from_raw + +class COMHRESULT(HRESULT): + _type_ = HRESULT._type_ + def _check_retval_(self): + # We CAN NOT try to adapt the self.value and transform it with flags + # here, we need to do it with the errcheck + # So we have the peer-interface callback system on errcheck :) + return self.value # The value will be send to errcheck :) + class COMInterface(ctypes.c_void_p): _functions_ = { } + # So COMInterface completely bypass the HRESULT + # return value check on restype by setting the restype to COMHRESULT + # But we add the 'errcheck' callbakc capacity for all COMInterface and subclasses + # So the default implem of the callbakc must have the same behavior as + # standard HRESULT restype. + # This is why default errcheck callback call ctypes._check_HRESULT + def _default_errcheck(self, result, func, args): + ctypes._check_HRESULT(result) + return args + def __getattr__(self, name): if name in self._functions_: - return functools.partial(self._functions_[name], self) + winfunc = self._functions_[name] + # Hacking the HRESULT _check_retval_ and + # letting COMInterface.errcheck do the work of validating / raising + winfunc.restype = COMHRESULT + effective_errcheck = getattr(self, "errcheck", self._default_errcheck) + winfunc.errcheck = effective_errcheck + return functools.partial(winfunc, self) return super(COMInterface, self).__getattribute__(name) def __repr__(self): @@ -23,3 +48,11 @@ class COMInterface(ctypes.c_void_p): self.QueryInterface(interface.IID, interface) return interface + + + + + + + + diff --git a/windows/winproxy/error.py b/windows/winproxy/error.py index c1769c3..315a915 100644 --- a/windows/winproxy/error.py +++ b/windows/winproxy/error.py @@ -25,12 +25,7 @@ class WinproxyError(WindowsError): # winproxy Error check - -# Try None instead :') -def no_error_check(func_name, result, func, args): - """No error check""" - return args - +no_error_check = None def fail_on_minus_one(func_name, result, func, args): """Raise WinproxyError if call result is -1"""