comtypes 1.4.8__zip → 1.4.10__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {comtypes-1.4.8 → comtypes-1.4.10}/CHANGES.txt +40 -0
- {comtypes-1.4.8/comtypes.egg-info → comtypes-1.4.10}/PKG-INFO +4 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/README.md +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/GUID.py +38 -16
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/__init__.py +36 -16
- comtypes-1.4.10/comtypes/_comobject.py +562 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_memberspec.py +93 -13
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_meta.py +1 -0
- comtypes-1.4.10/comtypes/_post_coinit/_cominterface_meta_patcher.py +152 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/bstr.py +12 -5
- comtypes-1.4.8/comtypes/_py_instance_method.py → comtypes-1.4.10/comtypes/_post_coinit/instancemethod.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/misc.py +60 -25
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/unknwn.py +26 -176
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_safearray.py +3 -4
- comtypes-1.4.10/comtypes/_vtbl.py +448 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/automation.py +46 -49
- comtypes-1.4.10/comtypes/client/__init__.py +42 -0
- comtypes-1.4.10/comtypes/client/_activeobj.py +46 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_code_cache.py +10 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_constants.py +1 -1
- comtypes-1.4.10/comtypes/client/_create.py +147 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_events.py +58 -13
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_generate.py +7 -11
- comtypes-1.4.10/comtypes/client/_managing.py +114 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/dynamic.py +2 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/lazybind.py +12 -13
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/connectionpoints.py +2 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/errorinfo.py +22 -9
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/git.py +5 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/hints.pyi +7 -15
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/logutil.py +15 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/messageloop.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/persist.py +3 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/safearray.py +17 -5
- comtypes-1.4.10/comtypes/server/__init__.py +104 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/automation.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/connectionpoints.py +5 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/inprocserver.py +25 -17
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/localserver.py +49 -19
- comtypes-1.4.10/comtypes/server/register.py +478 -0
- comtypes-1.4.10/comtypes/server/w_getopt.py +48 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/shelllink.py +16 -33
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/stream.py +7 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.py +6 -7
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.py +4 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/__init__.py +10 -12
- comtypes-1.4.10/comtypes/test/find_memleak.py +72 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/runtests.py +1 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/setup.py +2 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_BSTR.py +10 -23
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_GUID.py +1 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_QueryService.py +1 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_agilent.py +4 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_avmc.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_basic.py +12 -6
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_casesensitivity.py +3 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_clear_cache.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client_dynamic.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client_regenerate_modules.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_collections.py +4 -4
- comtypes-1.4.10/comtypes/test/test_comobject.py +146 -0
- comtypes-1.4.10/comtypes/test/test_comserver.py +349 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_createwrappers.py +2 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dispifc_records.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dispifc_safearrays.py +1 -1
- comtypes-1.4.10/comtypes/test/test_dispinterface.py +153 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dyndispatch.py +1 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_excel.py +22 -12
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_findgendir.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_getactiveobj.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_ie.py +19 -9
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_ienum.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_imfattributes.py +13 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_inout_args.py +8 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_midl_safearray_create.py +14 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_monikers.py +23 -9
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_msscript.py +2 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_npsupport.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_outparam.py +37 -14
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_persist.py +2 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_recordinfo.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_safearray.py +1 -90
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_sapi.py +4 -1
- comtypes-1.4.10/comtypes/test/test_server.py +350 -0
- comtypes-1.4.10/comtypes/test/test_server_register.py +524 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_shelllink.py +2 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_showevents.py +7 -17
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_storage.py +12 -6
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_stream.py +16 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_subinterface.py +4 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_typeannotator.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_typeinfo.py +19 -7
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_urlhistory.py +7 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_variant.py +3 -19
- comtypes-1.4.10/comtypes/test/test_w_getopt.py +29 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_win32com_interop.py +80 -36
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_wmi.py +0 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_word.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/codegenerator.py +166 -440
- comtypes-1.4.10/comtypes/tools/codegenerator/comments.py +79 -0
- comtypes-1.4.10/comtypes/tools/codegenerator/heads.py +192 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/helpers.py +11 -14
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/namespaces.py +13 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/packing.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/typeannotator.py +19 -9
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/tlbparser.py +22 -23
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/typedesc.py +4 -8
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/typedesc_base.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/typeinfo.py +159 -63
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/viewobject.py +3 -9
- {comtypes-1.4.8 → comtypes-1.4.10/comtypes.egg-info}/PKG-INFO +4 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/SOURCES.txt +11 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/pyproject.toml +12 -19
- comtypes-1.4.8/comtypes/_comobject.py +0 -833
- comtypes-1.4.8/comtypes/_idl_stuff.py +0 -67
- comtypes-1.4.8/comtypes/client/__init__.py +0 -323
- comtypes-1.4.8/comtypes/server/__init__.py +0 -70
- comtypes-1.4.8/comtypes/server/register.py +0 -431
- comtypes-1.4.8/comtypes/server/w_getopt.py +0 -75
- comtypes-1.4.8/comtypes/test/find_memleak.py +0 -76
- comtypes-1.4.8/comtypes/test/test_comserver.py +0 -239
- comtypes-1.4.8/comtypes/test/test_dispinterface.py +0 -137
- comtypes-1.4.8/comtypes/test/test_propputref.py +0 -40
- comtypes-1.4.8/comtypes/test/test_server.py +0 -354
- {comtypes-1.4.8 → comtypes-1.4.10}/LICENSE.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/MANIFEST.in +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_npsupport.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_tlib_version_checker.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/clear_cache.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/hresult.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/patcher.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mylib.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dict.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/urlhist.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/modulenamer.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/util.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/entry_points.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/setup.cfg +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/setup.py +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from ctypes import *
|
|
3
|
-
from
|
|
3
|
+
from ctypes.wintypes import DWORD, ULONG
|
|
4
|
+
|
|
5
|
+
from comtypes import BSTR, COMMETHOD, GUID, HRESULT, IUnknown
|
|
4
6
|
from comtypes.hresult import *
|
|
5
7
|
|
|
6
8
|
LPCOLESTR = c_wchar_p
|
|
7
|
-
DWORD = c_ulong
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class ICreateErrorInfo(IUnknown):
|
|
@@ -45,26 +46,38 @@ class ISupportErrorInfo(IUnknown):
|
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
################################################################
|
|
48
|
-
_oleaut32 =
|
|
49
|
+
_oleaut32 = OleDLL("oleaut32")
|
|
50
|
+
|
|
51
|
+
_CreateErrorInfo = _oleaut32.CreateErrorInfo
|
|
52
|
+
_CreateErrorInfo.argtypes = [POINTER(POINTER(ICreateErrorInfo))]
|
|
53
|
+
_CreateErrorInfo.restype = HRESULT
|
|
54
|
+
|
|
55
|
+
_GetErrorInfo = _oleaut32.GetErrorInfo
|
|
56
|
+
_GetErrorInfo.argtypes = [ULONG, POINTER(POINTER(IErrorInfo))]
|
|
57
|
+
_GetErrorInfo.restype = HRESULT
|
|
58
|
+
|
|
59
|
+
_SetErrorInfo = _oleaut32.SetErrorInfo
|
|
60
|
+
_SetErrorInfo.argtypes = [ULONG, POINTER(IErrorInfo)]
|
|
61
|
+
_SetErrorInfo.restype = HRESULT
|
|
49
62
|
|
|
50
63
|
|
|
51
64
|
def CreateErrorInfo():
|
|
52
65
|
cei = POINTER(ICreateErrorInfo)()
|
|
53
|
-
|
|
66
|
+
_CreateErrorInfo(byref(cei))
|
|
54
67
|
return cei
|
|
55
68
|
|
|
56
69
|
|
|
57
70
|
def GetErrorInfo():
|
|
58
71
|
"""Get the error information for the current thread."""
|
|
59
72
|
errinfo = POINTER(IErrorInfo)()
|
|
60
|
-
if S_OK ==
|
|
73
|
+
if S_OK == _GetErrorInfo(0, byref(errinfo)):
|
|
61
74
|
return errinfo
|
|
62
75
|
return None
|
|
63
76
|
|
|
64
77
|
|
|
65
78
|
def SetErrorInfo(errinfo):
|
|
66
79
|
"""Set error information for the current thread."""
|
|
67
|
-
return
|
|
80
|
+
return _SetErrorInfo(0, errinfo)
|
|
68
81
|
|
|
69
82
|
|
|
70
83
|
def ReportError(
|
|
@@ -89,7 +102,7 @@ def ReportError(
|
|
|
89
102
|
ei.SetSource(
|
|
90
103
|
progid
|
|
91
104
|
) # progid for the class or application that created the error
|
|
92
|
-
|
|
105
|
+
_SetErrorInfo(0, ei)
|
|
93
106
|
return hresult
|
|
94
107
|
|
|
95
108
|
|
|
@@ -103,9 +116,9 @@ def ReportException(
|
|
|
103
116
|
tb = tb.tb_next
|
|
104
117
|
line = tb.tb_frame.f_lineno
|
|
105
118
|
name = tb.tb_frame.f_globals["__name__"]
|
|
106
|
-
text = "
|
|
119
|
+
text = f"{typ}: {value} ({name}, line {line:d})"
|
|
107
120
|
else:
|
|
108
|
-
text = "
|
|
121
|
+
text = f"{typ}: {value}"
|
|
109
122
|
return ReportError(
|
|
110
123
|
text,
|
|
111
124
|
iid,
|
|
@@ -5,18 +5,18 @@ between different threading appartments.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from ctypes import *
|
|
8
|
+
from ctypes.wintypes import DWORD
|
|
9
|
+
|
|
8
10
|
from comtypes import (
|
|
9
|
-
|
|
10
|
-
STDMETHOD,
|
|
11
|
+
CLSCTX_INPROC_SERVER,
|
|
11
12
|
COMMETHOD,
|
|
12
13
|
GUID,
|
|
13
14
|
HRESULT,
|
|
15
|
+
STDMETHOD,
|
|
14
16
|
CoCreateInstance,
|
|
15
|
-
|
|
17
|
+
IUnknown,
|
|
16
18
|
)
|
|
17
19
|
|
|
18
|
-
DWORD = c_ulong
|
|
19
|
-
|
|
20
20
|
|
|
21
21
|
class IGlobalInterfaceTable(IUnknown):
|
|
22
22
|
_iid_ = GUID("{00000146-0000-0000-C000-000000000046}")
|
|
@@ -3,17 +3,11 @@
|
|
|
3
3
|
# - utilities for type hints.
|
|
4
4
|
import ctypes
|
|
5
5
|
import sys
|
|
6
|
-
from typing import Any as Any, ClassVar, Generic, NoReturn, TypeVar, overload
|
|
6
|
+
from typing import Any as Any, ClassVar, Generic, NoReturn, Protocol, TypeVar, overload
|
|
7
7
|
from typing import Optional, Union as _UnionT
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import Tuple as Tuple, Type
|
|
9
9
|
from typing import Callable, Iterator, Sequence
|
|
10
10
|
|
|
11
|
-
if sys.version_info >= (3, 8):
|
|
12
|
-
from typing import Protocol
|
|
13
|
-
from typing import Literal as Literal
|
|
14
|
-
else:
|
|
15
|
-
from typing_extensions import Protocol
|
|
16
|
-
from typing_extensions import Literal as Literal
|
|
17
11
|
if sys.version_info >= (3, 9):
|
|
18
12
|
from typing import Annotated as Annotated
|
|
19
13
|
else:
|
|
@@ -30,10 +24,11 @@ else:
|
|
|
30
24
|
from typing_extensions import Self as Self
|
|
31
25
|
|
|
32
26
|
import comtypes
|
|
33
|
-
from comtypes import IUnknown as IUnknown, GUID as GUID
|
|
27
|
+
from comtypes import IUnknown as IUnknown, COMObject as COMObject, GUID as GUID
|
|
34
28
|
from comtypes.automation import IDispatch as IDispatch, VARIANT as VARIANT
|
|
35
29
|
from comtypes.server import IClassFactory as IClassFactory
|
|
36
|
-
from comtypes.
|
|
30
|
+
from comtypes.server import localserver as localserver
|
|
31
|
+
from comtypes.typeinfo import ITypeInfo as ITypeInfo, ITypeLib as ITypeLib
|
|
37
32
|
from comtypes._safearray import tagSAFEARRAY as tagSAFEARRAY
|
|
38
33
|
|
|
39
34
|
Incomplete: TypeAlias = Any
|
|
@@ -74,6 +69,8 @@ class LP_SAFEARRAY(ctypes._Pointer[tagSAFEARRAY], Generic[_CT]):
|
|
|
74
69
|
def unpack(self: LP_SAFEARRAY[_T_Struct]) -> Sequence[_T_Struct]: ...
|
|
75
70
|
@overload
|
|
76
71
|
def unpack(self) -> Sequence[Any]: ...
|
|
72
|
+
@classmethod
|
|
73
|
+
def from_param(cls, value: Any, /) -> Self: ...
|
|
77
74
|
|
|
78
75
|
_T_coclass = TypeVar("_T_coclass", bound=comtypes.CoClass)
|
|
79
76
|
|
|
@@ -85,11 +82,6 @@ class FirstComItfOf(Generic[_T_coclass]):
|
|
|
85
82
|
as an argument.
|
|
86
83
|
"""
|
|
87
84
|
|
|
88
|
-
class _MethodTypeDesc(Protocol):
|
|
89
|
-
arguments: List[Tuple[Any, str, List[str], Optional[Any]]]
|
|
90
|
-
idlflags: List[str]
|
|
91
|
-
name: str
|
|
92
|
-
|
|
93
85
|
_P_Put = ParamSpec("_P_Put")
|
|
94
86
|
_R_Put = TypeVar("_R_Put")
|
|
95
87
|
_P_PutRef = ParamSpec("_P_PutRef")
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
# logutil.py
|
|
2
|
-
import logging
|
|
2
|
+
import logging
|
|
3
|
+
from ctypes import WinDLL
|
|
4
|
+
from ctypes.wintypes import LPCSTR, LPCWSTR
|
|
5
|
+
|
|
6
|
+
_kernel32 = WinDLL("kernel32")
|
|
7
|
+
|
|
8
|
+
_OutputDebugStringA = _kernel32.OutputDebugStringA
|
|
9
|
+
_OutputDebugStringA.argtypes = [LPCSTR]
|
|
10
|
+
_OutputDebugStringA.restype = None
|
|
11
|
+
|
|
12
|
+
_OutputDebugStringW = _kernel32.OutputDebugStringW
|
|
13
|
+
_OutputDebugStringW.argtypes = [LPCWSTR]
|
|
14
|
+
_OutputDebugStringW.restype = None
|
|
3
15
|
|
|
4
16
|
|
|
5
17
|
class NTDebugHandler(logging.Handler):
|
|
6
18
|
def emit(
|
|
7
19
|
self,
|
|
8
20
|
record,
|
|
9
|
-
writeA=
|
|
10
|
-
writeW=
|
|
21
|
+
writeA=_OutputDebugStringA,
|
|
22
|
+
writeW=_OutputDebugStringW,
|
|
11
23
|
):
|
|
12
24
|
text = self.format(record)
|
|
13
25
|
if isinstance(text, str):
|
|
@@ -10,13 +10,11 @@ The 'DictPropertyBag' class is a class implementing the IPropertyBag
|
|
|
10
10
|
interface, useful in client code.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
from ctypes import c_int, c_ulong, c_ushort, c_wchar_p
|
|
14
|
-
from ctypes import
|
|
15
|
-
from ctypes.wintypes import WORD, DWORD, BOOL
|
|
13
|
+
from ctypes import POINTER, Structure, c_int, c_ulong, c_ushort, c_wchar_p
|
|
14
|
+
from ctypes.wintypes import BOOL, DWORD, WORD
|
|
16
15
|
from typing import TYPE_CHECKING
|
|
17
16
|
|
|
18
|
-
from comtypes import GUID,
|
|
19
|
-
from comtypes import IPersist
|
|
17
|
+
from comtypes import COMMETHOD, GUID, HRESULT, IPersist, IUnknown
|
|
20
18
|
from comtypes.automation import VARIANT, tagEXCEPINFO
|
|
21
19
|
|
|
22
20
|
if TYPE_CHECKING:
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import threading
|
|
2
1
|
import array
|
|
2
|
+
import threading
|
|
3
|
+
from ctypes import POINTER, Structure, byref, c_long, cast, memmove, pointer, sizeof
|
|
3
4
|
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
4
6
|
import comtypes
|
|
5
|
-
from
|
|
6
|
-
from comtypes import _safearray, IUnknown, com_interface_registry
|
|
7
|
+
from comtypes import IUnknown, _safearray, com_interface_registry
|
|
7
8
|
from comtypes.patcher import Patch
|
|
8
9
|
|
|
9
10
|
if TYPE_CHECKING:
|
|
10
11
|
from typing import Type, TypeVar
|
|
12
|
+
|
|
11
13
|
from comtypes import hints # type: ignore
|
|
12
14
|
|
|
13
15
|
_CT = TypeVar("_CT", bound=comtypes._CData)
|
|
@@ -73,11 +75,12 @@ def _midlSAFEARRAY(itemtype: "Type[_CT]") -> "Type[hints.LP_SAFEARRAY[_CT]]":
|
|
|
73
75
|
def _make_safearray_type(itemtype):
|
|
74
76
|
# Create and return a subclass of tagSAFEARRAY
|
|
75
77
|
from comtypes.automation import (
|
|
76
|
-
|
|
78
|
+
VT_DISPATCH,
|
|
79
|
+
VT_HRESULT,
|
|
77
80
|
VT_RECORD,
|
|
78
81
|
VT_UNKNOWN,
|
|
79
82
|
IDispatch,
|
|
80
|
-
|
|
83
|
+
_ctype_to_vartype,
|
|
81
84
|
)
|
|
82
85
|
|
|
83
86
|
meta = type(_safearray.tagSAFEARRAY)
|
|
@@ -123,6 +126,15 @@ def _make_safearray_type(itemtype):
|
|
|
123
126
|
one-dimensional arrays. To create multidimensional arrys,
|
|
124
127
|
numpy arrays must be passed.
|
|
125
128
|
"""
|
|
129
|
+
if cls._vartype_ == VT_HRESULT:
|
|
130
|
+
raise TypeError(
|
|
131
|
+
# There are COM type libraries that define the
|
|
132
|
+
# `_midlSAFEARRAY(HRESULT)` type; however, creating `HRESULT`
|
|
133
|
+
# safearray pointer instance does not work.
|
|
134
|
+
# See also: https://github.com/enthought/comtypes/issues/668
|
|
135
|
+
"Cannot create SAFEARRAY type VT_HRESULT."
|
|
136
|
+
)
|
|
137
|
+
|
|
126
138
|
if comtypes.npsupport.isndarray(value):
|
|
127
139
|
return cls.create_from_ndarray(value, extra)
|
|
128
140
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
from ctypes import HRESULT, POINTER, OleDLL, byref, c_void_p
|
|
3
|
+
from ctypes.wintypes import DWORD, LPVOID
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Optional, Type
|
|
5
|
+
|
|
6
|
+
import comtypes
|
|
7
|
+
import comtypes.client
|
|
8
|
+
import comtypes.client.dynamic
|
|
9
|
+
from comtypes import GUID, STDMETHOD, IUnknown
|
|
10
|
+
from comtypes.automation import IDispatch
|
|
11
|
+
from comtypes.GUID import REFCLSID
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from ctypes import _Pointer
|
|
15
|
+
|
|
16
|
+
from comtypes import hints # type: ignore
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
################################################################
|
|
20
|
+
# Interfaces
|
|
21
|
+
class IClassFactory(IUnknown):
|
|
22
|
+
_iid_ = GUID("{00000001-0000-0000-C000-000000000046}")
|
|
23
|
+
_methods_ = [
|
|
24
|
+
STDMETHOD(
|
|
25
|
+
HRESULT,
|
|
26
|
+
"CreateInstance",
|
|
27
|
+
[POINTER(IUnknown), POINTER(GUID), POINTER(ctypes.c_void_p)],
|
|
28
|
+
),
|
|
29
|
+
STDMETHOD(HRESULT, "LockServer", [ctypes.c_int]),
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
def CreateInstance(
|
|
33
|
+
self,
|
|
34
|
+
punkouter: Optional[Type["_Pointer[IUnknown]"]] = None,
|
|
35
|
+
interface: Optional[Type[IUnknown]] = None,
|
|
36
|
+
dynamic: bool = False,
|
|
37
|
+
) -> Any:
|
|
38
|
+
if dynamic:
|
|
39
|
+
if interface is not None:
|
|
40
|
+
raise ValueError("interface and dynamic are mutually exclusive")
|
|
41
|
+
itf = IDispatch
|
|
42
|
+
elif interface is None:
|
|
43
|
+
itf = IUnknown
|
|
44
|
+
else:
|
|
45
|
+
itf = interface
|
|
46
|
+
obj = POINTER(itf)()
|
|
47
|
+
self.__com_CreateInstance(punkouter, itf._iid_, byref(obj)) # type: ignore
|
|
48
|
+
if dynamic:
|
|
49
|
+
return comtypes.client.dynamic.Dispatch(obj)
|
|
50
|
+
elif interface is None:
|
|
51
|
+
# An interface was not specified, so return the best.
|
|
52
|
+
return comtypes.client.GetBestInterface(obj)
|
|
53
|
+
# An interface was specified and obj is already that interface.
|
|
54
|
+
return obj
|
|
55
|
+
|
|
56
|
+
if TYPE_CHECKING:
|
|
57
|
+
|
|
58
|
+
def LockServer(self, fLock: int) -> hints.Hresult: ...
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# class IExternalConnection(IUnknown):
|
|
62
|
+
# _iid_ = GUID("{00000019-0000-0000-C000-000000000046}")
|
|
63
|
+
# _methods_ = [
|
|
64
|
+
# STDMETHOD(HRESULT, "AddConnection", [c_ulong, c_ulong]),
|
|
65
|
+
# STDMETHOD(HRESULT, "ReleaseConnection", [c_ulong, c_ulong, c_ulong])]
|
|
66
|
+
|
|
67
|
+
# The following code is untested:
|
|
68
|
+
|
|
69
|
+
ACTIVEOBJECT_STRONG = 0x0
|
|
70
|
+
ACTIVEOBJECT_WEAK = 0x1
|
|
71
|
+
|
|
72
|
+
_oleaut32 = OleDLL("oleaut32")
|
|
73
|
+
|
|
74
|
+
_RegisterActiveObject = _oleaut32.RegisterActiveObject
|
|
75
|
+
_RegisterActiveObject.argtypes = [
|
|
76
|
+
c_void_p,
|
|
77
|
+
REFCLSID,
|
|
78
|
+
DWORD,
|
|
79
|
+
POINTER(DWORD),
|
|
80
|
+
]
|
|
81
|
+
_RegisterActiveObject.restype = HRESULT
|
|
82
|
+
|
|
83
|
+
_RevokeActiveObject = _oleaut32.RevokeActiveObject
|
|
84
|
+
_RevokeActiveObject.argtypes = [
|
|
85
|
+
DWORD,
|
|
86
|
+
LPVOID,
|
|
87
|
+
]
|
|
88
|
+
_RevokeActiveObject.restype = HRESULT
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def RegisterActiveObject(comobj: comtypes.COMObject, weak: bool = True) -> int:
|
|
92
|
+
punk = comobj._com_pointers_[IUnknown._iid_]
|
|
93
|
+
clsid = comobj._reg_clsid_
|
|
94
|
+
if weak:
|
|
95
|
+
flags = ACTIVEOBJECT_WEAK
|
|
96
|
+
else:
|
|
97
|
+
flags = ACTIVEOBJECT_STRONG
|
|
98
|
+
handle = ctypes.c_ulong()
|
|
99
|
+
_RegisterActiveObject(punk, byref(clsid), flags, byref(handle))
|
|
100
|
+
return handle.value
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def RevokeActiveObject(handle: int) -> None:
|
|
104
|
+
_RevokeActiveObject(handle, None)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from ctypes import *
|
|
2
|
-
|
|
3
|
+
|
|
4
|
+
from comtypes import COMError, COMObject, IUnknown
|
|
5
|
+
from comtypes.automation import IDispatch
|
|
6
|
+
from comtypes.connectionpoints import IConnectionPoint
|
|
3
7
|
from comtypes.hresult import *
|
|
4
8
|
from comtypes.typeinfo import LoadRegTypeLib
|
|
5
|
-
from comtypes.connectionpoints import IConnectionPoint
|
|
6
|
-
from comtypes.automation import IDispatch
|
|
7
|
-
|
|
8
|
-
import logging
|
|
9
9
|
|
|
10
10
|
logger = logging.getLogger(__name__)
|
|
11
11
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import ctypes
|
|
2
|
-
from comtypes import COMObject, GUID
|
|
3
|
-
from comtypes.server import IClassFactory
|
|
4
|
-
from comtypes.hresult import *
|
|
5
|
-
|
|
6
|
-
import sys
|
|
7
2
|
import logging
|
|
3
|
+
import sys
|
|
8
4
|
import winreg
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Literal, Optional, Type
|
|
6
|
+
|
|
7
|
+
from comtypes import GUID, COMObject, IUnknown, hresult
|
|
8
|
+
from comtypes.server import IClassFactory
|
|
9
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ctypes import _Pointer
|
|
10
12
|
|
|
11
13
|
logger = logging.getLogger(__name__)
|
|
12
14
|
_debug = logger.debug
|
|
@@ -18,33 +20,39 @@ _critical = logger.critical
|
|
|
18
20
|
class ClassFactory(COMObject):
|
|
19
21
|
_com_interfaces_ = [IClassFactory]
|
|
20
22
|
|
|
21
|
-
def __init__(self, cls):
|
|
23
|
+
def __init__(self, cls: Type[COMObject]) -> None:
|
|
22
24
|
super(ClassFactory, self).__init__()
|
|
23
25
|
self._cls = cls
|
|
24
26
|
|
|
25
|
-
def IClassFactory_CreateInstance(
|
|
27
|
+
def IClassFactory_CreateInstance(
|
|
28
|
+
self,
|
|
29
|
+
this: Any,
|
|
30
|
+
punkOuter: Optional[Type["_Pointer[IUnknown]"]],
|
|
31
|
+
riid: "_Pointer[GUID]",
|
|
32
|
+
ppv: ctypes.c_void_p,
|
|
33
|
+
) -> int:
|
|
26
34
|
_debug("ClassFactory.CreateInstance(%s)", riid[0])
|
|
27
35
|
result = self._cls().IUnknown_QueryInterface(None, riid, ppv)
|
|
28
36
|
_debug("CreateInstance() -> %s", result)
|
|
29
37
|
return result
|
|
30
38
|
|
|
31
|
-
def IClassFactory_LockServer(self, this, fLock):
|
|
39
|
+
def IClassFactory_LockServer(self, this: Any, fLock: bool) -> Literal[0]:
|
|
32
40
|
if fLock:
|
|
33
41
|
COMObject.__server__.Lock()
|
|
34
42
|
else:
|
|
35
43
|
COMObject.__server__.Unlock()
|
|
36
|
-
return S_OK
|
|
44
|
+
return hresult.S_OK
|
|
37
45
|
|
|
38
46
|
|
|
39
47
|
# will be set by py2exe boot script 'from outside'
|
|
40
48
|
_clsid_to_class = {}
|
|
41
49
|
|
|
42
50
|
|
|
43
|
-
def inproc_find_class(clsid):
|
|
51
|
+
def inproc_find_class(clsid: GUID) -> Type[COMObject]:
|
|
44
52
|
if _clsid_to_class:
|
|
45
53
|
return _clsid_to_class[clsid]
|
|
46
54
|
|
|
47
|
-
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, "CLSID
|
|
55
|
+
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, f"CLSID\\{clsid}\\InprocServer32")
|
|
48
56
|
try:
|
|
49
57
|
pathdir = winreg.QueryValueEx(key, "PythonPath")[0]
|
|
50
58
|
except:
|
|
@@ -70,7 +78,7 @@ def inproc_find_class(clsid):
|
|
|
70
78
|
_logging_configured = False
|
|
71
79
|
|
|
72
80
|
|
|
73
|
-
def _setup_logging(clsid):
|
|
81
|
+
def _setup_logging(clsid: GUID) -> None:
|
|
74
82
|
"""Read from the registry, and configure the logging module.
|
|
75
83
|
|
|
76
84
|
Currently, the handler (NTDebugHandler) is hardcoded.
|
|
@@ -109,7 +117,7 @@ def _setup_logging(clsid):
|
|
|
109
117
|
logging.getLogger(name).setLevel(level)
|
|
110
118
|
|
|
111
119
|
|
|
112
|
-
def DllGetClassObject(rclsid, riid, ppv):
|
|
120
|
+
def DllGetClassObject(rclsid: int, riid: int, ppv: int) -> int:
|
|
113
121
|
COMObject.__run_inprocserver__()
|
|
114
122
|
|
|
115
123
|
iid = GUID.from_address(riid)
|
|
@@ -127,7 +135,7 @@ def DllGetClassObject(rclsid, riid, ppv):
|
|
|
127
135
|
|
|
128
136
|
cls = inproc_find_class(clsid)
|
|
129
137
|
if not cls:
|
|
130
|
-
return CLASS_E_CLASSNOTAVAILABLE
|
|
138
|
+
return hresult.CLASS_E_CLASSNOTAVAILABLE
|
|
131
139
|
|
|
132
140
|
result = ClassFactory(cls).IUnknown_QueryInterface(
|
|
133
141
|
None, ctypes.pointer(iid), ctypes.c_void_p(ppv)
|
|
@@ -136,12 +144,12 @@ def DllGetClassObject(rclsid, riid, ppv):
|
|
|
136
144
|
return result
|
|
137
145
|
except Exception:
|
|
138
146
|
_critical("DllGetClassObject", exc_info=True)
|
|
139
|
-
return E_FAIL
|
|
147
|
+
return hresult.E_FAIL
|
|
140
148
|
|
|
141
149
|
|
|
142
|
-
def DllCanUnloadNow():
|
|
150
|
+
def DllCanUnloadNow() -> Literal[1]: # S_FALSE
|
|
143
151
|
COMObject.__run_inprocserver__()
|
|
144
152
|
result = COMObject.__server__.DllCanUnloadNow()
|
|
145
153
|
# To avoid a memory leak when PyInitialize()/PyUninitialize() are
|
|
146
154
|
# called several times, we refuse to unload the dll.
|
|
147
|
-
return S_FALSE
|
|
155
|
+
return hresult.S_FALSE
|
|
@@ -1,10 +1,23 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
from ctypes import *
|
|
3
|
-
import comtypes
|
|
4
|
-
from comtypes.hresult import *
|
|
5
|
-
from comtypes.server import IClassFactory
|
|
6
1
|
import logging
|
|
7
2
|
import queue
|
|
3
|
+
from ctypes import (
|
|
4
|
+
HRESULT,
|
|
5
|
+
POINTER,
|
|
6
|
+
OleDLL,
|
|
7
|
+
byref,
|
|
8
|
+
c_ulong,
|
|
9
|
+
c_void_p,
|
|
10
|
+
)
|
|
11
|
+
from ctypes.wintypes import DWORD, LPDWORD
|
|
12
|
+
from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Type
|
|
13
|
+
|
|
14
|
+
import comtypes
|
|
15
|
+
from comtypes import GUID, hresult
|
|
16
|
+
from comtypes.server import IClassFactory
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from ctypes import _Pointer
|
|
20
|
+
|
|
8
21
|
|
|
9
22
|
logger = logging.getLogger(__name__)
|
|
10
23
|
_debug = logger.debug
|
|
@@ -15,38 +28,49 @@ REGCLS_MULTI_SEPARATE = 2 # multiple use, but separate control over each
|
|
|
15
28
|
REGCLS_SUSPENDED = 4 # register it as suspended, will be activated
|
|
16
29
|
REGCLS_SURROGATE = 8 # must be used when a surrogate process
|
|
17
30
|
|
|
31
|
+
_ole32 = OleDLL("ole32")
|
|
32
|
+
|
|
33
|
+
REFCLSID = POINTER(GUID)
|
|
34
|
+
_CoRegisterClassObject = _ole32.CoRegisterClassObject
|
|
35
|
+
_CoRegisterClassObject.argtypes = [REFCLSID, c_void_p, DWORD, DWORD, LPDWORD]
|
|
36
|
+
_CoRegisterClassObject.restype = HRESULT
|
|
37
|
+
|
|
38
|
+
_CoRevokeClassObject = _ole32.CoRevokeClassObject
|
|
39
|
+
_CoRevokeClassObject.argtypes = [DWORD]
|
|
40
|
+
_CoRevokeClassObject.restype = HRESULT
|
|
41
|
+
|
|
18
42
|
|
|
19
|
-
def run(classes):
|
|
43
|
+
def run(classes: Sequence[Type[comtypes.COMObject]]) -> None:
|
|
20
44
|
classobjects = [ClassFactory(cls) for cls in classes]
|
|
21
45
|
comtypes.COMObject.__run_localserver__(classobjects)
|
|
22
46
|
|
|
23
47
|
|
|
24
48
|
class ClassFactory(comtypes.COMObject):
|
|
25
49
|
_com_interfaces_ = [IClassFactory]
|
|
26
|
-
_locks = 0
|
|
27
|
-
_queue = None
|
|
28
|
-
regcls = REGCLS_MULTIPLEUSE
|
|
50
|
+
_locks: int = 0
|
|
51
|
+
_queue: Optional[queue.Queue] = None
|
|
52
|
+
regcls: int = REGCLS_MULTIPLEUSE
|
|
29
53
|
|
|
30
|
-
def __init__(self, cls, *args, **kw):
|
|
54
|
+
def __init__(self, cls: Type[comtypes.COMObject], *args, **kw) -> None:
|
|
31
55
|
super(ClassFactory, self).__init__()
|
|
32
56
|
self._cls = cls
|
|
33
57
|
self._register_class()
|
|
34
58
|
self._args = args
|
|
35
59
|
self._kw = kw
|
|
36
60
|
|
|
37
|
-
def IUnknown_AddRef(self, this):
|
|
61
|
+
def IUnknown_AddRef(self, this: Any) -> int:
|
|
38
62
|
return 2
|
|
39
63
|
|
|
40
|
-
def IUnknown_Release(self, this):
|
|
64
|
+
def IUnknown_Release(self, this: Any) -> int:
|
|
41
65
|
return 1
|
|
42
66
|
|
|
43
|
-
def _register_class(self):
|
|
67
|
+
def _register_class(self) -> None:
|
|
44
68
|
regcls = getattr(self._cls, "_regcls_", self.regcls)
|
|
45
69
|
cookie = c_ulong()
|
|
46
70
|
ptr = self._com_pointers_[comtypes.IUnknown._iid_]
|
|
47
71
|
clsctx = self._cls._reg_clsctx_
|
|
48
72
|
clsctx &= ~comtypes.CLSCTX_INPROC # reset the inproc flags
|
|
49
|
-
|
|
73
|
+
_CoRegisterClassObject(
|
|
50
74
|
byref(comtypes.GUID(self._cls._reg_clsid_)),
|
|
51
75
|
ptr,
|
|
52
76
|
clsctx,
|
|
@@ -55,19 +79,25 @@ class ClassFactory(comtypes.COMObject):
|
|
|
55
79
|
)
|
|
56
80
|
self.cookie = cookie
|
|
57
81
|
|
|
58
|
-
def _revoke_class(self):
|
|
59
|
-
|
|
82
|
+
def _revoke_class(self) -> None:
|
|
83
|
+
_CoRevokeClassObject(self.cookie)
|
|
60
84
|
|
|
61
|
-
def CreateInstance(
|
|
85
|
+
def CreateInstance(
|
|
86
|
+
self,
|
|
87
|
+
this: Any,
|
|
88
|
+
punkOuter: Optional[Type["_Pointer[comtypes.IUnknown]"]],
|
|
89
|
+
riid: "_Pointer[comtypes.GUID]",
|
|
90
|
+
ppv: c_void_p,
|
|
91
|
+
) -> int:
|
|
62
92
|
_debug("ClassFactory.CreateInstance(%s)", riid[0])
|
|
63
93
|
obj = self._cls(*self._args, **self._kw)
|
|
64
94
|
result = obj.IUnknown_QueryInterface(None, riid, ppv)
|
|
65
95
|
_debug("CreateInstance() -> %s", result)
|
|
66
96
|
return result
|
|
67
97
|
|
|
68
|
-
def LockServer(self, this, fLock):
|
|
98
|
+
def LockServer(self, this: Any, fLock: bool) -> Literal[0]:
|
|
69
99
|
if fLock:
|
|
70
100
|
comtypes.COMObject.__server__.Lock()
|
|
71
101
|
else:
|
|
72
102
|
comtypes.COMObject.__server__.Unlock()
|
|
73
|
-
return S_OK
|
|
103
|
+
return hresult.S_OK
|