comtypes 1.4.4__zip → 1.4.5__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.
Files changed (130) hide show
  1. {comtypes-1.4.4 → comtypes-1.4.5}/CHANGES.txt +12 -0
  2. {comtypes-1.4.4/comtypes.egg-info → comtypes-1.4.5}/PKG-INFO +1 -1
  3. comtypes-1.4.5/comtypes/__init__.py +268 -0
  4. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_comobject.py +2 -1
  5. comtypes-1.4.5/comtypes/_idl_stuff.py +67 -0
  6. comtypes-1.4.5/comtypes/_post_coinit/__init__.py +15 -0
  7. comtypes-1.4.5/comtypes/_post_coinit/bstr.py +30 -0
  8. comtypes-1.4.5/comtypes/_post_coinit/misc.py +385 -0
  9. comtypes-1.4.5/comtypes/_post_coinit/unknwn.py +537 -0
  10. comtypes-1.4.5/comtypes/_py_instance_method.py +13 -0
  11. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_safearray.py +3 -2
  12. comtypes-1.4.5/comtypes/_tlib_version_checker.py +18 -0
  13. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/automation.py +22 -6
  14. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/_generate.py +2 -1
  15. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/hints.pyi +34 -0
  16. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/safearray.py +11 -4
  17. comtypes-1.4.5/comtypes/stream.py +65 -0
  18. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_client.py +11 -0
  19. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_dispifc_records.py +1 -1
  20. comtypes-1.4.5/comtypes/test/test_dispifc_safearrays.py +89 -0
  21. comtypes-1.4.5/comtypes/test/test_istream.py +53 -0
  22. comtypes-1.4.5/comtypes/test/test_midl_safearray_create.py +100 -0
  23. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_wmi.py +11 -18
  24. {comtypes-1.4.4 → comtypes-1.4.5/comtypes.egg-info}/PKG-INFO +1 -1
  25. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes.egg-info/SOURCES.txt +11 -0
  26. {comtypes-1.4.4 → comtypes-1.4.5}/setup.cfg +1 -0
  27. comtypes-1.4.4/comtypes/__init__.py +0 -1229
  28. {comtypes-1.4.4 → comtypes-1.4.5}/LICENSE.txt +0 -0
  29. {comtypes-1.4.4 → comtypes-1.4.5}/MANIFEST.in +0 -0
  30. {comtypes-1.4.4 → comtypes-1.4.5}/README.md +0 -0
  31. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/GUID.py +0 -0
  32. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_memberspec.py +0 -0
  33. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_meta.py +0 -0
  34. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_npsupport.py +0 -0
  35. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/clear_cache.py +0 -0
  36. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/__init__.py +0 -0
  37. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/_code_cache.py +0 -0
  38. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/_constants.py +0 -0
  39. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/_events.py +0 -0
  40. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/dynamic.py +0 -0
  41. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/lazybind.py +0 -0
  42. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/connectionpoints.py +0 -0
  43. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/errorinfo.py +0 -0
  44. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/git.py +0 -0
  45. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/hresult.py +0 -0
  46. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/logutil.py +0 -0
  47. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/messageloop.py +0 -0
  48. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/patcher.py +0 -0
  49. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/persist.py +0 -0
  50. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/__init__.py +0 -0
  51. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/automation.py +0 -0
  52. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/connectionpoints.py +0 -0
  53. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/inprocserver.py +0 -0
  54. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/localserver.py +0 -0
  55. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/register.py +0 -0
  56. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/w_getopt.py +0 -0
  57. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/shelllink.py +0 -0
  58. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestComServer.idl +0 -0
  59. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestComServer.py +0 -0
  60. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestComServer.tlb +0 -0
  61. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestDispServer.idl +0 -0
  62. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestDispServer.py +0 -0
  63. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestDispServer.tlb +0 -0
  64. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/__init__.py +0 -0
  65. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/find_memleak.py +0 -0
  66. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/mylib.idl +0 -0
  67. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/mylib.tlb +0 -0
  68. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/mytypelib.idl +0 -0
  69. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/runtests.py +0 -0
  70. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/setup.py +0 -0
  71. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_BSTR.py +0 -0
  72. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_DISPPARAMS.py +0 -0
  73. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_GUID.py +0 -0
  74. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_QueryService.py +0 -0
  75. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_agilent.py +0 -0
  76. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_avmc.py +0 -0
  77. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_basic.py +0 -0
  78. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_casesensitivity.py +0 -0
  79. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_clear_cache.py +0 -0
  80. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_client_dynamic.py +0 -0
  81. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_client_regenerate_modules.py +0 -0
  82. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_collections.py +0 -0
  83. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_comserver.py +0 -0
  84. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_createwrappers.py +0 -0
  85. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_dict.py +0 -0
  86. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_dispinterface.py +0 -0
  87. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_dyndispatch.py +0 -0
  88. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_excel.py +0 -0
  89. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_findgendir.py +0 -0
  90. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_getactiveobj.py +0 -0
  91. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_ie.py +0 -0
  92. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_ienum.py +0 -0
  93. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_imfattributes.py +0 -0
  94. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_inout_args.py +0 -0
  95. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_jscript.js +0 -0
  96. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_msscript.py +0 -0
  97. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_npsupport.py +0 -0
  98. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_outparam.py +0 -0
  99. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_propputref.py +0 -0
  100. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_pump_events.py +0 -0
  101. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_safearray.py +0 -0
  102. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_sapi.py +0 -0
  103. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_server.py +0 -0
  104. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_showevents.py +0 -0
  105. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_subinterface.py +0 -0
  106. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_typeinfo.py +0 -0
  107. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_urlhistory.py +0 -0
  108. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_variant.py +0 -0
  109. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_win32com_interop.py +0 -0
  110. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_word.py +0 -0
  111. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/urlhist.tlb +0 -0
  112. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/__init__.py +0 -0
  113. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/__init__.py +0 -0
  114. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/codegenerator.py +0 -0
  115. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/helpers.py +0 -0
  116. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  117. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/namespaces.py +0 -0
  118. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/packing.py +0 -0
  119. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/typeannotator.py +0 -0
  120. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/tlbparser.py +0 -0
  121. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/typedesc.py +0 -0
  122. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/typedesc_base.py +0 -0
  123. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/typeinfo.py +0 -0
  124. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/util.py +0 -0
  125. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/viewobject.py +0 -0
  126. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes.egg-info/dependency_links.txt +0 -0
  127. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes.egg-info/entry_points.txt +0 -0
  128. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes.egg-info/top_level.txt +0 -0
  129. {comtypes-1.4.4 → comtypes-1.4.5}/pyproject.toml +0 -0
  130. {comtypes-1.4.4 → comtypes-1.4.5}/setup.py +0 -0
@@ -1,1229 +0,0 @@
1
- # comtypes version numbers follow semver (http://semver.org/) and PEP 440
2
- __version__ = "1.4.4"
3
-
4
- import atexit
5
- from ctypes import *
6
- from ctypes import _Pointer, _SimpleCData
7
-
8
- try:
9
- from _ctypes import COMError
10
- except ImportError as e:
11
- msg = "\n".join(
12
- (
13
- "COM technology not available (maybe it's the wrong platform).",
14
- "Note that COM is only supported on Windows.",
15
- "For more details, please check: "
16
- "https://learn.microsoft.com/en-us/windows/win32/com",
17
- )
18
- )
19
- raise ImportError(msg) from e
20
- import logging
21
- import os
22
- import sys
23
- import types
24
-
25
- # fmt: off
26
- from typing import (
27
- Any, ClassVar, overload, TYPE_CHECKING, TypeVar,
28
- # instead of `builtins`. see PEP585
29
- Dict, List, Tuple, Type,
30
- # instead of `collections.abc`. see PEP585
31
- Callable, Iterable, Iterator,
32
- # instead of `A | B` and `None | A`. see PEP604
33
- Optional, Union as _UnionT, # avoiding confusion with `ctypes.Union`
34
- )
35
- # fmt: on
36
- if TYPE_CHECKING:
37
- from ctypes import _CData # only in `typeshed`, private in runtime
38
- from comtypes import hints as hints # type: ignore
39
- else:
40
- _CData = _SimpleCData.__mro__[:-1][-1]
41
-
42
- from comtypes.GUID import GUID
43
- from comtypes import patcher
44
- from comtypes._npsupport import interop as npsupport
45
- from comtypes._memberspec import (
46
- ComMemberGenerator,
47
- _ComMemberSpec,
48
- DispMemberGenerator,
49
- _DispMemberSpec,
50
- _encode_idl,
51
- _resolve_argspec,
52
- )
53
-
54
-
55
- _all_slice = slice(None, None, None)
56
-
57
-
58
- class NullHandler(logging.Handler):
59
- """A Handler that does nothing."""
60
-
61
- def emit(self, record):
62
- pass
63
-
64
-
65
- logger = logging.getLogger(__name__)
66
-
67
- # Add a NULL handler to the comtypes logger. This prevents getting a
68
- # message like this:
69
- # No handlers could be found for logger "comtypes"
70
- # when logging is not configured and logger.error() is called.
71
- logger.addHandler(NullHandler())
72
-
73
-
74
- def _check_version(actual, tlib_cached_mtime=None):
75
- from comtypes.tools.codegenerator import version as required
76
-
77
- if actual != required:
78
- raise ImportError("Wrong version")
79
- if not hasattr(sys, "frozen"):
80
- g = sys._getframe(1).f_globals
81
- tlb_path = g.get("typelib_path")
82
- try:
83
- tlib_curr_mtime = os.stat(tlb_path).st_mtime
84
- except (OSError, TypeError):
85
- return
86
- if not tlib_cached_mtime or abs(tlib_curr_mtime - tlib_cached_mtime) >= 1:
87
- raise ImportError("Typelib different than module")
88
-
89
-
90
- pythonapi.PyInstanceMethod_New.argtypes = [py_object]
91
- pythonapi.PyInstanceMethod_New.restype = py_object
92
- PyInstanceMethod_Type = type(pythonapi.PyInstanceMethod_New(id))
93
-
94
-
95
- def instancemethod(func, inst, cls):
96
- mth = PyInstanceMethod_Type(func)
97
- if inst is None:
98
- return mth
99
- return mth.__get__(inst)
100
-
101
-
102
- class ReturnHRESULT(Exception):
103
- """ReturnHRESULT(hresult, text)
104
-
105
- Return a hresult code from a COM method implementation
106
- without logging an error.
107
- """
108
-
109
-
110
- # class IDLWarning(UserWarning):
111
- # "Warn about questionable type information"
112
-
113
- _GUID = GUID
114
- IID = GUID
115
- DWORD = c_ulong
116
-
117
- wireHWND = c_ulong
118
-
119
- ################################################################
120
- # About COM apartments:
121
- # http://blogs.msdn.com/larryosterman/archive/2004/04/28/122240.aspx
122
- ################################################################
123
-
124
- ################################################################
125
- # constants for object creation
126
- CLSCTX_INPROC_SERVER = 1
127
- CLSCTX_INPROC_HANDLER = 2
128
- CLSCTX_LOCAL_SERVER = 4
129
-
130
- CLSCTX_INPROC = 3
131
- CLSCTX_SERVER = 5
132
- CLSCTX_ALL = 7
133
-
134
- CLSCTX_INPROC_SERVER16 = 8
135
- CLSCTX_REMOTE_SERVER = 16
136
- CLSCTX_INPROC_HANDLER16 = 32
137
- CLSCTX_RESERVED1 = 64
138
- CLSCTX_RESERVED2 = 128
139
- CLSCTX_RESERVED3 = 256
140
- CLSCTX_RESERVED4 = 512
141
- CLSCTX_NO_CODE_DOWNLOAD = 1024
142
- CLSCTX_RESERVED5 = 2048
143
- CLSCTX_NO_CUSTOM_MARSHAL = 4096
144
- CLSCTX_ENABLE_CODE_DOWNLOAD = 8192
145
- CLSCTX_NO_FAILURE_LOG = 16384
146
- CLSCTX_DISABLE_AAA = 32768
147
- CLSCTX_ENABLE_AAA = 65536
148
- CLSCTX_FROM_DEFAULT_CONTEXT = 131072
149
-
150
- tagCLSCTX = c_int # enum
151
- CLSCTX = tagCLSCTX
152
-
153
- # Constants for security setups
154
- SEC_WINNT_AUTH_IDENTITY_UNICODE = 0x2
155
- RPC_C_AUTHN_WINNT = 10
156
- RPC_C_AUTHZ_NONE = 0
157
- RPC_C_AUTHN_LEVEL_CONNECT = 2
158
- RPC_C_IMP_LEVEL_IMPERSONATE = 3
159
- EOAC_NONE = 0
160
-
161
-
162
- ################################################################
163
- # Initialization and shutdown
164
- _ole32 = oledll.ole32
165
- _ole32_nohresult = windll.ole32 # use this for functions that don't return a HRESULT
166
-
167
- COINIT_MULTITHREADED = 0x0
168
- COINIT_APARTMENTTHREADED = 0x2
169
- COINIT_DISABLE_OLE1DDE = 0x4
170
- COINIT_SPEED_OVER_MEMORY = 0x8
171
-
172
-
173
- def CoInitialize():
174
- return CoInitializeEx(COINIT_APARTMENTTHREADED)
175
-
176
-
177
- def CoInitializeEx(flags=None):
178
- if flags is None:
179
- flags = getattr(sys, "coinit_flags", COINIT_APARTMENTTHREADED)
180
- logger.debug("CoInitializeEx(None, %s)", flags)
181
- _ole32.CoInitializeEx(None, flags)
182
-
183
-
184
- # COM is initialized automatically for the thread that imports this
185
- # module for the first time. sys.coinit_flags is passed as parameter
186
- # to CoInitializeEx, if defined, otherwise COINIT_APARTMENTTHREADED
187
- # (COINIT_MULTITHREADED on Windows CE) is used.
188
- #
189
- # A shutdown function is registered with atexit, so that
190
- # CoUninitialize is called when Python is shut down.
191
- CoInitializeEx()
192
-
193
- # We need to have CoUninitialize for multithreaded model where we have
194
- # to initialize and uninitialize COM for every new thread (except main)
195
- # in which we are using COM
196
- def CoUninitialize():
197
- logger.debug("CoUninitialize()")
198
- _ole32_nohresult.CoUninitialize()
199
-
200
-
201
- def _shutdown(
202
- func=_ole32_nohresult.CoUninitialize,
203
- _debug=logger.debug,
204
- _exc_clear=getattr(sys, "exc_clear", lambda: None),
205
- ):
206
- # Make sure no COM pointers stay in exception frames.
207
- _exc_clear()
208
- # Sometimes, CoUninitialize, running at Python shutdown,
209
- # raises an exception. We suppress this when __debug__ is
210
- # False.
211
- _debug("Calling CoUninitialize()")
212
- if __debug__:
213
- func()
214
- else:
215
- try:
216
- func()
217
- except WindowsError:
218
- pass
219
- # Set the flag which means that calling obj.Release() is no longer
220
- # needed.
221
- if _cominterface_meta is not None:
222
- _cominterface_meta._com_shutting_down = True
223
- _debug("CoUninitialize() done.")
224
-
225
-
226
- atexit.register(_shutdown)
227
-
228
- ################################################################
229
- # global registries.
230
-
231
- # allows to find interface classes by guid strings (iid)
232
- com_interface_registry = {}
233
-
234
- # allows to find coclasses by guid strings (clsid)
235
- com_coclass_registry = {}
236
-
237
-
238
- def _is_object(obj):
239
- """This function determines if the argument is a COM object. It
240
- is used in several places to determine whether propputref or
241
- propput setters have to be used."""
242
- from comtypes.automation import VARIANT
243
-
244
- # A COM pointer is an 'Object'
245
- if isinstance(obj, POINTER(IUnknown)):
246
- return True
247
- # A COM pointer in a VARIANT is an 'Object', too
248
- elif isinstance(obj, VARIANT) and isinstance(obj.value, POINTER(IUnknown)):
249
- return True
250
- # It may be a dynamic dispatch object.
251
- return hasattr(obj, "_comobj")
252
-
253
-
254
- ################################################################
255
- # The metaclasses...
256
-
257
-
258
- class _cominterface_meta(type):
259
- """Metaclass for COM interfaces. Automatically creates high level
260
- methods from COMMETHOD lists.
261
- """
262
-
263
- _case_insensitive_: bool
264
- _iid_: GUID
265
- _methods_: List[_ComMemberSpec]
266
- _disp_methods_: List[_DispMemberSpec]
267
-
268
- # This flag is set to True by the atexit handler which calls
269
- # CoUninitialize.
270
- _com_shutting_down = False
271
-
272
- # Creates also a POINTER type for the newly created class.
273
- def __new__(cls, name, bases, namespace):
274
- methods = namespace.pop("_methods_", None)
275
- dispmethods = namespace.pop("_disp_methods_", None)
276
- new_cls = type.__new__(cls, name, bases, namespace)
277
-
278
- if methods is not None:
279
- new_cls._methods_ = methods
280
- if dispmethods is not None:
281
- new_cls._disp_methods_ = dispmethods
282
-
283
- # If we sublass a COM interface, for example:
284
- #
285
- # class IDispatch(IUnknown):
286
- # ....
287
- #
288
- # then we need to make sure that POINTER(IDispatch) is a
289
- # subclass of POINTER(IUnknown) because of the way ctypes
290
- # typechecks work.
291
- if bases == (object,):
292
- _ptr_bases = (new_cls, _compointer_base)
293
- else:
294
- _ptr_bases = (new_cls, POINTER(bases[0]))
295
-
296
- # The interface 'new_cls' is used as a mixin.
297
- p = type(_compointer_base)(
298
- "POINTER(%s)" % new_cls.__name__,
299
- _ptr_bases,
300
- {"__com_interface__": new_cls, "_needs_com_addref_": None},
301
- )
302
-
303
- from ctypes import _pointer_type_cache
304
-
305
- _pointer_type_cache[new_cls] = p
306
-
307
- if new_cls._case_insensitive_:
308
-
309
- @patcher.Patch(p)
310
- class CaseInsensitive(object):
311
- # case insensitive attributes for COM methods and properties
312
- def __getattr__(self, name):
313
- """Implement case insensitive access to methods and properties"""
314
- try:
315
- fixed_name = self.__map_case__[name.lower()]
316
- except KeyError:
317
- raise AttributeError(name)
318
- if fixed_name != name: # prevent unbounded recursion
319
- return getattr(self, fixed_name)
320
- raise AttributeError(name)
321
-
322
- # __setattr__ is pretty heavy-weight, because it is called for
323
- # EVERY attribute assignment. Settings a non-com attribute
324
- # through this function takes 8.6 usec, while without this
325
- # function it takes 0.7 sec - 12 times slower.
326
- #
327
- # How much faster would this be if implemented in C?
328
- def __setattr__(self, name, value):
329
- """Implement case insensitive access to methods and properties"""
330
- object.__setattr__(
331
- self, self.__map_case__.get(name.lower(), name), value
332
- )
333
-
334
- @patcher.Patch(POINTER(p))
335
- class ReferenceFix(object):
336
- def __setitem__(self, index, value):
337
- # We override the __setitem__ method of the
338
- # POINTER(POINTER(interface)) type, so that the COM
339
- # reference count is managed correctly.
340
- #
341
- # This is so that we can implement COM methods that have to
342
- # return COM pointers more easily and consistent. Instead of
343
- # using CopyComPointer in the method implementation, we can
344
- # simply do:
345
- #
346
- # def GetTypeInfo(self, this, ..., pptinfo):
347
- # if not pptinfo: return E_POINTER
348
- # pptinfo[0] = a_com_interface_pointer
349
- # return S_OK
350
- if index != 0:
351
- # CopyComPointer, which is in _ctypes, does only
352
- # handle an index of 0. This code does what
353
- # CopyComPointer should do if index != 0.
354
- if bool(value):
355
- value.AddRef()
356
- super(POINTER(p), self).__setitem__(index, value)
357
- return
358
- from _ctypes import CopyComPointer
359
-
360
- CopyComPointer(value, self)
361
-
362
- return new_cls
363
-
364
- def __setattr__(self, name, value):
365
- if name == "_methods_":
366
- # XXX I'm no longer sure why the code generator generates
367
- # "_methods_ = []" in the interface definition, and later
368
- # overrides this by "Interface._methods_ = [...]
369
- # assert self.__dict__.get("_methods_", None) is None
370
- self._make_methods(value)
371
- self._make_specials()
372
- elif name == "_disp_methods_":
373
- assert self.__dict__.get("_disp_methods_", None) is None
374
- self._make_dispmethods(value)
375
- self._make_specials()
376
- type.__setattr__(self, name, value)
377
-
378
- def _make_specials(self):
379
- # This call installs methods that forward the Python protocols
380
- # to COM protocols.
381
-
382
- def has_name(name):
383
- # Determine whether a property or method named 'name'
384
- # exists
385
- if self._case_insensitive_:
386
- return name.lower() in self.__map_case__
387
- return hasattr(self, name)
388
-
389
- # XXX These special methods should be generated by the code generator.
390
- if has_name("Count"):
391
-
392
- @patcher.Patch(self)
393
- class _(object):
394
- def __len__(self):
395
- "Return the the 'self.Count' property."
396
- return self.Count
397
-
398
- if has_name("Item"):
399
-
400
- @patcher.Patch(self)
401
- class _(object):
402
- # 'Item' is the 'default' value. Make it available by
403
- # calling the instance (Not sure this makes sense, but
404
- # win32com does this also).
405
- def __call__(self, *args, **kw):
406
- "Return 'self.Item(*args, **kw)'"
407
- return self.Item(*args, **kw)
408
-
409
- # does this make sense? It seems that all standard typelibs I've
410
- # seen so far that support .Item also support ._NewEnum
411
- @patcher.no_replace
412
- def __getitem__(self, index):
413
- "Return 'self.Item(index)'"
414
- # Handle tuples and all-slice
415
- if isinstance(index, tuple):
416
- args = index
417
- elif index == _all_slice:
418
- args = ()
419
- else:
420
- args = (index,)
421
-
422
- try:
423
- result = self.Item(*args)
424
- except COMError as err:
425
- (hresult, text, details) = err.args
426
- if hresult == -2147352565: # DISP_E_BADINDEX
427
- raise IndexError("invalid index")
428
- else:
429
- raise
430
-
431
- # Note that result may be NULL COM pointer. There is no way
432
- # to interpret this properly, so it is returned as-is.
433
-
434
- # Hm, should we call __ctypes_from_outparam__ on the
435
- # result?
436
- return result
437
-
438
- @patcher.no_replace
439
- def __setitem__(self, index, value):
440
- "Attempt 'self.Item[index] = value'"
441
- try:
442
- self.Item[index] = value
443
- except COMError as err:
444
- (hresult, text, details) = err.args
445
- if hresult == -2147352565: # DISP_E_BADINDEX
446
- raise IndexError("invalid index")
447
- else:
448
- raise
449
- except TypeError:
450
- msg = "%r object does not support item assignment"
451
- raise TypeError(msg % type(self))
452
-
453
- if has_name("_NewEnum"):
454
-
455
- @patcher.Patch(self)
456
- class _(object):
457
- def __iter__(self):
458
- "Return an iterator over the _NewEnum collection."
459
- # This method returns a pointer to _some_ _NewEnum interface.
460
- # It relies on the fact that the code generator creates next()
461
- # methods for them automatically.
462
- #
463
- # Better would maybe to return an object that
464
- # implements the Python iterator protocol, and
465
- # forwards the calls to the COM interface.
466
- enum = self._NewEnum
467
- if isinstance(enum, types.MethodType):
468
- # _NewEnum should be a propget property, with dispid -4.
469
- #
470
- # Sometimes, however, it is a method.
471
- enum = enum()
472
- if hasattr(enum, "Next"):
473
- return enum
474
- # _NewEnum returns an IUnknown pointer, QueryInterface() it to
475
- # IEnumVARIANT
476
- from comtypes.automation import IEnumVARIANT
477
-
478
- return enum.QueryInterface(IEnumVARIANT)
479
-
480
- def _make_case_insensitive(self):
481
- # The __map_case__ dictionary maps lower case names to the
482
- # names in the original spelling to enable case insensitive
483
- # method and attribute access.
484
- try:
485
- self.__dict__["__map_case__"]
486
- except KeyError:
487
- d = {}
488
- d.update(getattr(self, "__map_case__", {}))
489
- self.__map_case__ = d
490
-
491
- def _make_dispmethods(self, methods: List[_DispMemberSpec]) -> None:
492
- if self._case_insensitive_:
493
- self._make_case_insensitive()
494
- # create dispinterface methods and properties on the interface 'self'
495
- member_gen = DispMemberGenerator(self.__name__)
496
- for m in methods:
497
- member_gen.add(m)
498
- for name, func_or_prop, is_prop in member_gen.items():
499
- setattr(self, name, func_or_prop)
500
- # COM is case insensitive.
501
- # For a method, this is the real name. For a property,
502
- # this is the name WITHOUT the _set_ or _get_ prefix.
503
- if self._case_insensitive_:
504
- self.__map_case__[name.lower()] = name
505
- if is_prop:
506
- self.__map_case__[name[5:].lower()] = name[5:]
507
- for name, accessor in member_gen.properties():
508
- setattr(self, name, accessor)
509
- # COM is case insensitive
510
- if self._case_insensitive_:
511
- self.__map_case__[name.lower()] = name
512
-
513
- def __get_baseinterface_methodcount(self):
514
- "Return the number of com methods in the base interfaces"
515
- try:
516
- result = 0
517
- for itf in self.mro()[1:-1]:
518
- result += len(itf.__dict__["_methods_"])
519
- return result
520
- except KeyError as err:
521
- (name,) = err.args
522
- if name == "_methods_":
523
- raise TypeError("baseinterface '%s' has no _methods_" % itf.__name__)
524
- raise
525
-
526
- def _make_methods(self, methods: List[_ComMemberSpec]) -> None:
527
- if self._case_insensitive_:
528
- self._make_case_insensitive()
529
- # register com interface. we insist on an _iid_ in THIS class!
530
- try:
531
- iid = self.__dict__["_iid_"]
532
- except KeyError:
533
- raise AttributeError("this class must define an _iid_")
534
- else:
535
- com_interface_registry[str(iid)] = self
536
- # create members
537
- vtbl_offset = self.__get_baseinterface_methodcount()
538
- member_gen = ComMemberGenerator(self.__name__, vtbl_offset, self._iid_)
539
- # create private low level, and public high level methods
540
- for m in methods:
541
- member_gen.add(m)
542
- for name, func, raw_func, is_prop in member_gen.methods():
543
- raw_mth = instancemethod(raw_func, None, self)
544
- setattr(self, "_%s__com_%s" % (self.__name__, name), raw_mth)
545
- mth = instancemethod(func, None, self)
546
- if not is_prop:
547
- # We install the method in the class, except when it's a property.
548
- # And we make sure we don't overwrite a property that's already present.
549
- mthname = name if not hasattr(self, name) else ("_%s" % name)
550
- setattr(self, mthname, mth)
551
- # For a method, this is the real name.
552
- # For a property, this is the name WITHOUT the _set_ or _get_ prefix.
553
- if self._case_insensitive_:
554
- self.__map_case__[name.lower()] = name
555
- if is_prop:
556
- self.__map_case__[name[5:].lower()] = name[5:]
557
- # create public properties / attribute accessors
558
- for name, accessor in member_gen.properties():
559
- # Again, we should not overwrite class attributes that are already present.
560
- propname = name if not hasattr(self, name) else ("_%s" % name)
561
- setattr(self, propname, accessor)
562
- # COM is case insensitive
563
- if self._case_insensitive_:
564
- self.__map_case__[name.lower()] = name
565
-
566
-
567
- ################################################################
568
-
569
-
570
- class _compointer_meta(type(c_void_p), _cominterface_meta):
571
- "metaclass for COM interface pointer classes"
572
- # no functionality, but needed to avoid a metaclass conflict
573
-
574
-
575
- class _compointer_base(c_void_p, metaclass=_compointer_meta):
576
- "base class for COM interface pointer classes"
577
-
578
- def __del__(self, _debug=logger.debug):
579
- "Release the COM refcount we own."
580
- if self:
581
- # comtypes calls CoUninitialize() when the atexit handlers
582
- # runs. CoUninitialize() cleans up the COM objects that
583
- # are still alive. Python COM pointers may still be
584
- # present but we can no longer call Release() on them -
585
- # this may give a protection fault. So we need the
586
- # _com_shutting_down flag.
587
- #
588
- if not type(self)._com_shutting_down:
589
- _debug("Release %s", self)
590
- self.Release()
591
-
592
- def __cmp__(self, other):
593
- """Compare pointers to COM interfaces."""
594
- # COM identity rule
595
- #
596
- # XXX To compare COM interface pointers, should we
597
- # automatically QueryInterface for IUnknown on both items, and
598
- # compare the pointer values?
599
- if not isinstance(other, _compointer_base):
600
- return 1
601
-
602
- # get the value property of the c_void_p baseclass, this is the pointer value
603
- return cmp(
604
- super(_compointer_base, self).value, super(_compointer_base, other).value
605
- )
606
-
607
- def __eq__(self, other):
608
- if not isinstance(other, _compointer_base):
609
- return False
610
- # get the value property of the c_void_p baseclass, this is the pointer value
611
- return (
612
- super(_compointer_base, self).value == super(_compointer_base, other).value
613
- )
614
-
615
- def __hash__(self):
616
- """Return the hash value of the pointer."""
617
- # hash the pointer values
618
- return hash(super(_compointer_base, self).value)
619
-
620
- # redefine the .value property; return the object itself.
621
- def __get_value(self):
622
- return self
623
-
624
- value = property(__get_value, doc="""Return self.""")
625
-
626
- def __repr__(self):
627
- ptr = super(_compointer_base, self).value
628
- return "<%s ptr=0x%x at %x>" % (self.__class__.__name__, ptr or 0, id(self))
629
-
630
- # This fixes the problem when there are multiple python interface types
631
- # wrapping the same COM interface. This could happen because some interfaces
632
- # are contained in multiple typelibs.
633
- #
634
- # It also allows to pass a CoClass instance to an api
635
- # expecting a COM interface.
636
- @classmethod
637
- def from_param(cls, value):
638
- """Convert 'value' into a COM pointer to the interface.
639
-
640
- This method accepts a COM pointer, or a CoClass instance
641
- which is QueryInterface()d."""
642
- if value is None:
643
- return None
644
- # CLF: 2013-01-18
645
- # A default value of 0, meaning null, can pass through to here.
646
- if value == 0:
647
- return None
648
- if isinstance(value, cls):
649
- return value
650
- # multiple python interface types for the same COM interface.
651
- # Do we need more checks here?
652
- if cls._iid_ == getattr(value, "_iid_", None):
653
- return value
654
- # Accept an CoClass instance which exposes the interface required.
655
- try:
656
- table = value._com_pointers_
657
- except AttributeError:
658
- pass
659
- else:
660
- try:
661
- # a kind of QueryInterface
662
- return table[cls._iid_]
663
- except KeyError:
664
- raise TypeError("Interface %s not supported" % cls._iid_)
665
- return value.QueryInterface(cls.__com_interface__)
666
-
667
-
668
- ################################################################
669
-
670
-
671
- class BSTR(_SimpleCData):
672
- "The windows BSTR data type"
673
- _type_ = "X"
674
- _needsfree = False
675
-
676
- def __repr__(self):
677
- return "%s(%r)" % (self.__class__.__name__, self.value)
678
-
679
- def __ctypes_from_outparam__(self):
680
- self._needsfree = True
681
- return self.value
682
-
683
- def __del__(self, _free=windll.oleaut32.SysFreeString):
684
- # Free the string if self owns the memory
685
- # or if instructed by __ctypes_from_outparam__.
686
- if self._b_base_ is None or self._needsfree:
687
- _free(self)
688
-
689
- @classmethod
690
- def from_param(cls, value):
691
- """Convert into a foreign function call parameter."""
692
- if isinstance(value, cls):
693
- return value
694
- # Although the builtin SimpleCData.from_param call does the
695
- # right thing, it doesn't ensure that SysFreeString is called
696
- # on destruction.
697
- return cls(value)
698
-
699
-
700
- ################################################################
701
- # IDL stuff
702
-
703
-
704
- class helpstring(str):
705
- "Specifies the helpstring for a COM method or property."
706
-
707
-
708
- class defaultvalue(object):
709
- "Specifies the default value for parameters marked optional."
710
-
711
- def __init__(self, value):
712
- self.value = value
713
-
714
-
715
- class dispid(int):
716
- "Specifies the DISPID of a method or property."
717
-
718
-
719
- # XXX STDMETHOD, COMMETHOD, DISPMETHOD, and DISPPROPERTY should return
720
- # instances with more methods or properties, and should not behave as an unpackable.
721
-
722
-
723
- def STDMETHOD(restype, name, argtypes=()) -> _ComMemberSpec:
724
- "Specifies a COM method slot without idlflags"
725
- return _ComMemberSpec(restype, name, argtypes, None, (), None)
726
-
727
-
728
- def DISPMETHOD(idlflags, restype, name, *argspec) -> _DispMemberSpec:
729
- "Specifies a method of a dispinterface"
730
- return _DispMemberSpec("DISPMETHOD", name, tuple(idlflags), restype, argspec)
731
-
732
-
733
- def DISPPROPERTY(idlflags, proptype, name) -> _DispMemberSpec:
734
- "Specifies a property of a dispinterface"
735
- return _DispMemberSpec("DISPPROPERTY", name, tuple(idlflags), proptype, ())
736
-
737
-
738
- # tuple(idlflags) is for the method itself: (dispid, 'readonly')
739
-
740
- # sample generated code:
741
- # DISPPROPERTY([5, 'readonly'], OLE_YSIZE_HIMETRIC, 'Height'),
742
- # DISPMETHOD(
743
- # [6], None, 'Render', ([], c_int, 'hdc'), ([], c_int, 'x'), ([], c_int, 'y')
744
- # )
745
-
746
-
747
- def COMMETHOD(idlflags, restype, methodname, *argspec) -> _ComMemberSpec:
748
- """Specifies a COM method slot with idlflags.
749
-
750
- XXX should explain the sematics of the arguments.
751
- """
752
- # collect all helpstring instances
753
- # We should suppress docstrings when Python is started with -OO
754
- # join them together(does this make sense?) and replace by None if empty.
755
- helptext = "".join(t for t in idlflags if isinstance(t, helpstring)) or None
756
- paramflags, argtypes = _resolve_argspec(argspec)
757
- if "propget" in idlflags:
758
- name = "_get_%s" % methodname
759
- elif "propput" in idlflags:
760
- name = "_set_%s" % methodname
761
- elif "propputref" in idlflags:
762
- name = "_setref_%s" % methodname
763
- else:
764
- name = methodname
765
- return _ComMemberSpec(
766
- restype, name, argtypes, paramflags, tuple(idlflags), helptext
767
- )
768
-
769
-
770
- ################################################################
771
- # IUnknown, the root of all evil...
772
-
773
- _T_IUnknown = TypeVar("_T_IUnknown", bound="IUnknown")
774
-
775
- if TYPE_CHECKING:
776
-
777
- class _IUnknown_Base(c_void_p, metaclass=_cominterface_meta): # type: ignore
778
- """This is workaround to avoid false-positive of static type checking.
779
-
780
- `IUnknown` behaves as a ctypes type, and `POINTER` can take it.
781
- This behavior is defined by some metaclasses in runtime.
782
-
783
- In runtime, this symbol in the namespace is just alias for
784
- `builtins.object`.
785
- """
786
-
787
- ...
788
-
789
- else:
790
- _IUnknown_Base = object
791
-
792
-
793
- class IUnknown(_IUnknown_Base, metaclass=_cominterface_meta):
794
- """The most basic COM interface.
795
-
796
- Each subclasses of IUnknown must define these class attributes:
797
-
798
- _iid_ - a GUID instance defining the identifier of this interface
799
-
800
- _methods_ - a list of methods for this interface.
801
-
802
- The _methods_ list must in VTable order. Methods are specified
803
- with STDMETHOD or COMMETHOD calls.
804
- """
805
-
806
- _case_insensitive_: ClassVar[bool] = False
807
- _iid_: ClassVar[GUID] = GUID("{00000000-0000-0000-C000-000000000046}")
808
- _methods_: ClassVar[List[_ComMemberSpec]] = [
809
- STDMETHOD(HRESULT, "QueryInterface", [POINTER(GUID), POINTER(c_void_p)]),
810
- STDMETHOD(c_ulong, "AddRef"),
811
- STDMETHOD(c_ulong, "Release"),
812
- ]
813
-
814
- # NOTE: Why not `QueryInterface(T) -> _Pointer[T]`?
815
- # Any static type checkers is not able to provide members of `T` from `_Pointer[T]`,
816
- # regardless of the pointer is able to access members of contents in runtime.
817
- # And if `isinstance(p, POINTER(T))` is `True`, then `isinstance(p, T)` is also `True`.
818
- # So returning `T` is not a lie, and good way to know what members the class has.
819
- def QueryInterface(
820
- self, interface: Type[_T_IUnknown], iid: Optional[GUID] = None
821
- ) -> _T_IUnknown:
822
- """QueryInterface(interface) -> instance"""
823
- p = POINTER(interface)()
824
- if iid is None:
825
- iid = interface._iid_
826
- self.__com_QueryInterface(byref(iid), byref(p)) # type: ignore
827
- clsid = self.__dict__.get("__clsid")
828
- if clsid is not None:
829
- p.__dict__["__clsid"] = clsid
830
- return p # type: ignore
831
-
832
- # these are only so that they get a docstring.
833
- # XXX There should be other ways to install a docstring.
834
- def AddRef(self) -> int:
835
- """Increase the internal refcount by one and return it."""
836
- return self.__com_AddRef() # type: ignore
837
-
838
- def Release(self) -> int:
839
- """Decrease the internal refcount by one and return it."""
840
- return self.__com_Release() # type: ignore
841
-
842
-
843
- ################################################################
844
- # IPersist is a trivial interface, which allows to ask an object about
845
- # its clsid.
846
- class IPersist(IUnknown):
847
- _iid_ = GUID("{0000010C-0000-0000-C000-000000000046}")
848
- _idlflags_ = []
849
- _methods_ = [
850
- COMMETHOD([], HRESULT, "GetClassID", (["out"], POINTER(GUID), "pClassID")),
851
- ]
852
- if TYPE_CHECKING:
853
- # Should this be "normal" method that calls `self._GetClassID`?
854
- def GetClassID(self) -> GUID:
855
- """Returns the CLSID that uniquely represents an object class that
856
- defines the code that can manipulate the object's data.
857
- """
858
- ...
859
-
860
-
861
- class IServiceProvider(IUnknown):
862
- _iid_ = GUID("{6D5140C1-7436-11CE-8034-00AA006009FA}")
863
- _QueryService: Callable[[Any, Any, Any], int]
864
- # Overridden QueryService to make it nicer to use (passing it an
865
- # interface and it returns a pointer to that interface)
866
- def QueryService(
867
- self, serviceIID: GUID, interface: Type[_T_IUnknown]
868
- ) -> _T_IUnknown:
869
- p = POINTER(interface)()
870
- self._QueryService(byref(serviceIID), byref(interface._iid_), byref(p))
871
- return p # type: ignore
872
-
873
- _methods_ = [
874
- COMMETHOD(
875
- [],
876
- HRESULT,
877
- "QueryService",
878
- (["in"], POINTER(GUID), "guidService"),
879
- (["in"], POINTER(GUID), "riid"),
880
- (["in"], POINTER(c_void_p), "ppvObject"),
881
- )
882
- ]
883
-
884
-
885
- ################################################################
886
-
887
-
888
- @overload
889
- def CoGetObject(displayname: str, interface: None) -> IUnknown:
890
- ...
891
-
892
-
893
- @overload
894
- def CoGetObject(displayname: str, interface: Type[_T_IUnknown]) -> _T_IUnknown:
895
- ...
896
-
897
-
898
- def CoGetObject(displayname: str, interface: Optional[Type[IUnknown]]) -> IUnknown:
899
- """Convert a displayname to a moniker, then bind and return the object
900
- identified by the moniker."""
901
- if interface is None:
902
- interface = IUnknown
903
- punk = POINTER(interface)()
904
- # Do we need a way to specify the BIND_OPTS parameter?
905
- _ole32.CoGetObject(str(displayname), None, byref(interface._iid_), byref(punk))
906
- return punk # type: ignore
907
-
908
-
909
- _pUnkOuter = Type["_Pointer[IUnknown]"]
910
-
911
-
912
- @overload
913
- def CoCreateInstance(
914
- clsid: GUID,
915
- interface: None = None,
916
- clsctx: Optional[int] = None,
917
- punkouter: Optional[_pUnkOuter] = None,
918
- ) -> IUnknown:
919
- ...
920
-
921
-
922
- @overload
923
- def CoCreateInstance(
924
- clsid: GUID,
925
- interface: Type[_T_IUnknown],
926
- clsctx: Optional[int] = None,
927
- punkouter: Optional[_pUnkOuter] = None,
928
- ) -> _T_IUnknown:
929
- ...
930
-
931
-
932
- def CoCreateInstance(
933
- clsid: GUID,
934
- interface: Optional[Type[IUnknown]] = None,
935
- clsctx: Optional[int] = None,
936
- punkouter: Optional[_pUnkOuter] = None,
937
- ) -> IUnknown:
938
- """The basic windows api to create a COM class object and return a
939
- pointer to an interface.
940
- """
941
- if clsctx is None:
942
- clsctx = CLSCTX_SERVER
943
- if interface is None:
944
- interface = IUnknown
945
- p = POINTER(interface)()
946
- iid = interface._iid_
947
- _ole32.CoCreateInstance(byref(clsid), punkouter, clsctx, byref(iid), byref(p))
948
- return p # type: ignore
949
-
950
-
951
- if TYPE_CHECKING:
952
-
953
- @overload
954
- def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
955
- # type: (GUID, Optional[int], Optional[COSERVERINFO], None) -> hints.IClassFactory
956
- pass
957
-
958
- @overload
959
- def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
960
- # type: (GUID, Optional[int], Optional[COSERVERINFO], Type[_T_IUnknown]) -> _T_IUnknown
961
- pass
962
-
963
-
964
- def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
965
- # type: (GUID, Optional[int], Optional[COSERVERINFO], Optional[Type[IUnknown]]) -> IUnknown
966
- if clsctx is None:
967
- clsctx = CLSCTX_SERVER
968
- if interface is None:
969
- import comtypes.server
970
-
971
- interface = comtypes.server.IClassFactory
972
- p = POINTER(interface)()
973
- _CoGetClassObject(clsid, clsctx, pServerInfo, interface._iid_, byref(p))
974
- return p # type: ignore
975
-
976
-
977
- @overload
978
- def GetActiveObject(clsid: GUID, interface: None = None) -> IUnknown:
979
- ...
980
-
981
-
982
- @overload
983
- def GetActiveObject(clsid: GUID, interface: Type[_T_IUnknown]) -> _T_IUnknown:
984
- ...
985
-
986
-
987
- def GetActiveObject(
988
- clsid: GUID, interface: Optional[Type[IUnknown]] = None
989
- ) -> IUnknown:
990
- """Retrieves a pointer to a running object"""
991
- p = POINTER(IUnknown)()
992
- oledll.oleaut32.GetActiveObject(byref(clsid), None, byref(p))
993
- if interface is not None:
994
- p = p.QueryInterface(interface) # type: ignore
995
- return p # type: ignore
996
-
997
-
998
- class MULTI_QI(Structure):
999
- _fields_ = [("pIID", POINTER(GUID)), ("pItf", POINTER(c_void_p)), ("hr", HRESULT)]
1000
- if TYPE_CHECKING:
1001
- pIID: GUID
1002
- pItf: _Pointer[c_void_p]
1003
- hr: HRESULT
1004
-
1005
-
1006
- class _COAUTHIDENTITY(Structure):
1007
- _fields_ = [
1008
- ("User", POINTER(c_ushort)),
1009
- ("UserLength", c_ulong),
1010
- ("Domain", POINTER(c_ushort)),
1011
- ("DomainLength", c_ulong),
1012
- ("Password", POINTER(c_ushort)),
1013
- ("PasswordLength", c_ulong),
1014
- ("Flags", c_ulong),
1015
- ]
1016
-
1017
-
1018
- COAUTHIDENTITY = _COAUTHIDENTITY
1019
-
1020
-
1021
- class _COAUTHINFO(Structure):
1022
- _fields_ = [
1023
- ("dwAuthnSvc", c_ulong),
1024
- ("dwAuthzSvc", c_ulong),
1025
- ("pwszServerPrincName", c_wchar_p),
1026
- ("dwAuthnLevel", c_ulong),
1027
- ("dwImpersonationLevel", c_ulong),
1028
- ("pAuthIdentityData", POINTER(_COAUTHIDENTITY)),
1029
- ("dwCapabilities", c_ulong),
1030
- ]
1031
-
1032
-
1033
- COAUTHINFO = _COAUTHINFO
1034
-
1035
-
1036
- class _COSERVERINFO(Structure):
1037
- _fields_ = [
1038
- ("dwReserved1", c_ulong),
1039
- ("pwszName", c_wchar_p),
1040
- ("pAuthInfo", POINTER(_COAUTHINFO)),
1041
- ("dwReserved2", c_ulong),
1042
- ]
1043
- if TYPE_CHECKING:
1044
- dwReserved1: int
1045
- pwszName: Optional[str]
1046
- pAuthInfo: _COAUTHINFO
1047
- dwReserved2: int
1048
-
1049
-
1050
- COSERVERINFO = _COSERVERINFO
1051
- _CoGetClassObject = _ole32.CoGetClassObject
1052
- _CoGetClassObject.argtypes = [
1053
- POINTER(GUID),
1054
- DWORD,
1055
- POINTER(COSERVERINFO),
1056
- POINTER(GUID),
1057
- POINTER(c_void_p),
1058
- ]
1059
-
1060
-
1061
- class tagBIND_OPTS(Structure):
1062
- _fields_ = [
1063
- ("cbStruct", c_ulong),
1064
- ("grfFlags", c_ulong),
1065
- ("grfMode", c_ulong),
1066
- ("dwTickCountDeadline", c_ulong),
1067
- ]
1068
-
1069
-
1070
- # XXX Add __init__ which sets cbStruct?
1071
- BIND_OPTS = tagBIND_OPTS
1072
-
1073
-
1074
- class tagBIND_OPTS2(Structure):
1075
- _fields_ = [
1076
- ("cbStruct", c_ulong),
1077
- ("grfFlags", c_ulong),
1078
- ("grfMode", c_ulong),
1079
- ("dwTickCountDeadline", c_ulong),
1080
- ("dwTrackFlags", c_ulong),
1081
- ("dwClassContext", c_ulong),
1082
- ("locale", c_ulong),
1083
- ("pServerInfo", POINTER(_COSERVERINFO)),
1084
- ]
1085
-
1086
-
1087
- # XXX Add __init__ which sets cbStruct?
1088
- BINDOPTS2 = tagBIND_OPTS2
1089
-
1090
- # Structures for security setups
1091
- #########################################
1092
- class _SEC_WINNT_AUTH_IDENTITY(Structure):
1093
- _fields_ = [
1094
- ("User", POINTER(c_ushort)),
1095
- ("UserLength", c_ulong),
1096
- ("Domain", POINTER(c_ushort)),
1097
- ("DomainLength", c_ulong),
1098
- ("Password", POINTER(c_ushort)),
1099
- ("PasswordLength", c_ulong),
1100
- ("Flags", c_ulong),
1101
- ]
1102
-
1103
-
1104
- SEC_WINNT_AUTH_IDENTITY = _SEC_WINNT_AUTH_IDENTITY
1105
-
1106
-
1107
- class _SOLE_AUTHENTICATION_INFO(Structure):
1108
- _fields_ = [
1109
- ("dwAuthnSvc", c_ulong),
1110
- ("dwAuthzSvc", c_ulong),
1111
- ("pAuthInfo", POINTER(_SEC_WINNT_AUTH_IDENTITY)),
1112
- ]
1113
-
1114
-
1115
- SOLE_AUTHENTICATION_INFO = _SOLE_AUTHENTICATION_INFO
1116
-
1117
-
1118
- class _SOLE_AUTHENTICATION_LIST(Structure):
1119
- _fields_ = [
1120
- ("cAuthInfo", c_ulong),
1121
- ("pAuthInfo", POINTER(_SOLE_AUTHENTICATION_INFO)),
1122
- ]
1123
-
1124
-
1125
- SOLE_AUTHENTICATION_LIST = _SOLE_AUTHENTICATION_LIST
1126
-
1127
-
1128
- @overload
1129
- def CoCreateInstanceEx(
1130
- clsid: GUID,
1131
- interface: None = None,
1132
- clsctx: Optional[int] = None,
1133
- machine: Optional[str] = None,
1134
- pServerInfo: Optional[COSERVERINFO] = None,
1135
- ) -> IUnknown:
1136
- ...
1137
-
1138
-
1139
- @overload
1140
- def CoCreateInstanceEx(
1141
- clsid: GUID,
1142
- interface: Type[_T_IUnknown],
1143
- clsctx: Optional[int] = None,
1144
- machine: Optional[str] = None,
1145
- pServerInfo: Optional[COSERVERINFO] = None,
1146
- ) -> _T_IUnknown:
1147
- ...
1148
-
1149
-
1150
- def CoCreateInstanceEx(
1151
- clsid: GUID,
1152
- interface: Optional[Type[IUnknown]] = None,
1153
- clsctx: Optional[int] = None,
1154
- machine: Optional[str] = None,
1155
- pServerInfo: Optional[COSERVERINFO] = None,
1156
- ) -> IUnknown:
1157
- """The basic windows api to create a COM class object and return a
1158
- pointer to an interface, possibly on another machine.
1159
-
1160
- Passing both "machine" and "pServerInfo" results in a ValueError.
1161
-
1162
- """
1163
- if clsctx is None:
1164
- clsctx = CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER
1165
-
1166
- if pServerInfo is not None:
1167
- if machine is not None:
1168
- msg = "Can not specify both machine name and server info"
1169
- raise ValueError(msg)
1170
- elif machine is not None:
1171
- serverinfo = COSERVERINFO()
1172
- serverinfo.pwszName = machine
1173
- pServerInfo = byref(serverinfo) # type: ignore
1174
-
1175
- if interface is None:
1176
- interface = IUnknown
1177
- multiqi = MULTI_QI()
1178
- multiqi.pIID = pointer(interface._iid_) # type: ignore
1179
- _ole32.CoCreateInstanceEx(
1180
- byref(clsid), None, clsctx, pServerInfo, 1, byref(multiqi)
1181
- )
1182
- return cast(multiqi.pItf, POINTER(interface)) # type: ignore
1183
-
1184
-
1185
- ################################################################
1186
- from comtypes._comobject import COMObject
1187
-
1188
- # What's a coclass?
1189
- # a POINTER to a coclass is allowed as parameter in a function declaration:
1190
- # http://msdn.microsoft.com/library/en-us/midl/midl/oleautomation.asp
1191
-
1192
- from comtypes._meta import _coclass_meta
1193
-
1194
-
1195
- class CoClass(COMObject, metaclass=_coclass_meta):
1196
- pass
1197
-
1198
-
1199
- ################################################################
1200
-
1201
-
1202
- # fmt: off
1203
- __known_symbols__ = [
1204
- "BIND_OPTS", "tagBIND_OPTS", "BINDOPTS2", "tagBIND_OPTS2", "BSTR",
1205
- "_check_version", "CLSCTX", "tagCLSCTX", "CLSCTX_ALL",
1206
- "CLSCTX_DISABLE_AAA", "CLSCTX_ENABLE_AAA", "CLSCTX_ENABLE_CODE_DOWNLOAD",
1207
- "CLSCTX_FROM_DEFAULT_CONTEXT", "CLSCTX_INPROC", "CLSCTX_INPROC_HANDLER",
1208
- "CLSCTX_INPROC_HANDLER16", "CLSCTX_INPROC_SERVER",
1209
- "CLSCTX_INPROC_SERVER16", "CLSCTX_LOCAL_SERVER", "CLSCTX_NO_CODE_DOWNLOAD",
1210
- "CLSCTX_NO_CUSTOM_MARSHAL", "CLSCTX_NO_FAILURE_LOG",
1211
- "CLSCTX_REMOTE_SERVER", "CLSCTX_RESERVED1", "CLSCTX_RESERVED2",
1212
- "CLSCTX_RESERVED3", "CLSCTX_RESERVED4", "CLSCTX_RESERVED5",
1213
- "CLSCTX_SERVER", "_COAUTHIDENTITY", "COAUTHIDENTITY", "_COAUTHINFO",
1214
- "COAUTHINFO", "CoClass", "CoCreateInstance", "CoCreateInstanceEx",
1215
- "_CoGetClassObject", "CoGetClassObject", "CoGetObject",
1216
- "COINIT_APARTMENTTHREADED", "COINIT_DISABLE_OLE1DDE",
1217
- "COINIT_MULTITHREADED", "COINIT_SPEED_OVER_MEMORY", "CoInitialize",
1218
- "CoInitializeEx", "COMError", "COMMETHOD", "COMObject", "_COSERVERINFO",
1219
- "COSERVERINFO", "CoUninitialize", "dispid", "DISPMETHOD", "DISPPROPERTY",
1220
- "DWORD", "EOAC_NONE", "GetActiveObject", "_GUID", "GUID", "helpstring",
1221
- "IID", "IPersist", "IServiceProvider", "IUnknown", "MULTI_QI",
1222
- "ReturnHRESULT", "RPC_C_AUTHN_LEVEL_CONNECT", "RPC_C_AUTHN_WINNT",
1223
- "RPC_C_AUTHZ_NONE", "RPC_C_IMP_LEVEL_IMPERSONATE",
1224
- "_SEC_WINNT_AUTH_IDENTITY", "SEC_WINNT_AUTH_IDENTITY",
1225
- "SEC_WINNT_AUTH_IDENTITY_UNICODE", "_SOLE_AUTHENTICATION_INFO",
1226
- "SOLE_AUTHENTICATION_INFO", "_SOLE_AUTHENTICATION_LIST",
1227
- "SOLE_AUTHENTICATION_LIST", "STDMETHOD", "wireHWND",
1228
- ]
1229
- # fmt: on