Spaces:
Running
Running
Upload 261 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- MLPY/Lib/site-packages/win32comext/adsi/__init__.py +122 -0
- MLPY/Lib/site-packages/win32comext/adsi/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/adsi/__pycache__/adsicon.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/adsi/adsi.pyd +0 -0
- MLPY/Lib/site-packages/win32comext/adsi/adsicon.py +340 -0
- MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/objectPicker.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/scp.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/search.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/test.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/adsi/demos/objectPicker.py +68 -0
- MLPY/Lib/site-packages/win32comext/adsi/demos/scp.py +565 -0
- MLPY/Lib/site-packages/win32comext/adsi/demos/search.py +152 -0
- MLPY/Lib/site-packages/win32comext/adsi/demos/test.py +273 -0
- MLPY/Lib/site-packages/win32comext/authorization/__init__.py +6 -0
- MLPY/Lib/site-packages/win32comext/authorization/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/authorization/authorization.pyd +0 -0
- MLPY/Lib/site-packages/win32comext/authorization/demos/EditSecurity.py +255 -0
- MLPY/Lib/site-packages/win32comext/authorization/demos/EditServiceSecurity.py +242 -0
- MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditSecurity.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditServiceSecurity.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axcontrol/__init__.py +4 -0
- MLPY/Lib/site-packages/win32comext/axcontrol/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axcontrol/axcontrol.pyd +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__init__.py +4 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/__init__.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/adb.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/codecontainer.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/contexts.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/debugger.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/documents.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/dump.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/expressions.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/gateways.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/stackframe.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/util.cpython-39.pyc +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/adb.py +480 -0
- MLPY/Lib/site-packages/win32comext/axdebug/axdebug.pyd +0 -0
- MLPY/Lib/site-packages/win32comext/axdebug/codecontainer.py +278 -0
- MLPY/Lib/site-packages/win32comext/axdebug/contexts.py +62 -0
- MLPY/Lib/site-packages/win32comext/axdebug/debugger.py +250 -0
- MLPY/Lib/site-packages/win32comext/axdebug/documents.py +140 -0
- MLPY/Lib/site-packages/win32comext/axdebug/dump.py +61 -0
- MLPY/Lib/site-packages/win32comext/axdebug/expressions.py +214 -0
- MLPY/Lib/site-packages/win32comext/axdebug/gateways.py +583 -0
- MLPY/Lib/site-packages/win32comext/axdebug/stackframe.py +179 -0
- MLPY/Lib/site-packages/win32comext/axdebug/util.py +141 -0
- MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/CreateObject.asp +19 -0
- MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/caps.asp +52 -0
- MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.asp +4 -0
- MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.html +10 -0
MLPY/Lib/site-packages/win32comext/adsi/__init__.py
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import win32com
|
2 |
+
import win32com.client
|
3 |
+
|
4 |
+
if type(__path__) == type(""):
|
5 |
+
# For freeze to work!
|
6 |
+
import sys
|
7 |
+
|
8 |
+
try:
|
9 |
+
import adsi
|
10 |
+
|
11 |
+
sys.modules["win32com.adsi.adsi"] = adsi
|
12 |
+
except ImportError:
|
13 |
+
pass
|
14 |
+
else:
|
15 |
+
# See if we have a special directory for the binaries (for developers)
|
16 |
+
win32com.__PackageSupportBuildPath__(__path__)
|
17 |
+
|
18 |
+
|
19 |
+
# Some helpers
|
20 |
+
# We want to _look_ like the ADSI module, but provide some additional
|
21 |
+
# helpers.
|
22 |
+
|
23 |
+
# Of specific note - most of the interfaces supported by ADSI
|
24 |
+
# derive from IDispatch - thus, you get the custome methods from the
|
25 |
+
# interface, as well as via IDispatch.
|
26 |
+
import pythoncom
|
27 |
+
|
28 |
+
from .adsi import *
|
29 |
+
|
30 |
+
LCID = 0
|
31 |
+
|
32 |
+
IDispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch]
|
33 |
+
IADsContainerType = pythoncom.TypeIIDs[adsi.IID_IADsContainer]
|
34 |
+
|
35 |
+
|
36 |
+
def _get_good_ret(
|
37 |
+
ob,
|
38 |
+
# Named arguments used internally
|
39 |
+
resultCLSID=None,
|
40 |
+
):
|
41 |
+
assert resultCLSID is None, "Now have type info for ADSI objects - fix me!"
|
42 |
+
# See if the object supports IDispatch
|
43 |
+
if hasattr(ob, "Invoke"):
|
44 |
+
import win32com.client.dynamic
|
45 |
+
|
46 |
+
name = "Dispatch wrapper around %r" % ob
|
47 |
+
return win32com.client.dynamic.Dispatch(ob, name, ADSIDispatch)
|
48 |
+
return ob
|
49 |
+
|
50 |
+
|
51 |
+
class ADSIEnumerator:
|
52 |
+
def __init__(self, ob):
|
53 |
+
# Query the object for the container interface.
|
54 |
+
self._cont_ = ob.QueryInterface(IID_IADsContainer)
|
55 |
+
self._oleobj_ = ADsBuildEnumerator(self._cont_) # a PyIADsEnumVARIANT
|
56 |
+
self.index = -1
|
57 |
+
|
58 |
+
def __getitem__(self, index):
|
59 |
+
return self.__GetIndex(index)
|
60 |
+
|
61 |
+
def __call__(self, index):
|
62 |
+
return self.__GetIndex(index)
|
63 |
+
|
64 |
+
def __GetIndex(self, index):
|
65 |
+
if type(index) != type(0):
|
66 |
+
raise TypeError("Only integer indexes are supported for enumerators")
|
67 |
+
if index != self.index + 1:
|
68 |
+
# Index requested out of sequence.
|
69 |
+
raise ValueError("You must index this object sequentially")
|
70 |
+
self.index = index
|
71 |
+
result = ADsEnumerateNext(self._oleobj_, 1)
|
72 |
+
if len(result):
|
73 |
+
return _get_good_ret(result[0])
|
74 |
+
# Failed - reset for next time around.
|
75 |
+
self.index = -1
|
76 |
+
self._oleobj_ = ADsBuildEnumerator(self._cont_) # a PyIADsEnumVARIANT
|
77 |
+
raise IndexError("list index out of range")
|
78 |
+
|
79 |
+
|
80 |
+
class ADSIDispatch(win32com.client.CDispatch):
|
81 |
+
def _wrap_dispatch_(
|
82 |
+
self, ob, userName=None, returnCLSID=None, UnicodeToString=None
|
83 |
+
):
|
84 |
+
assert UnicodeToString is None, "this is deprectated and will be removed"
|
85 |
+
if not userName:
|
86 |
+
userName = "ADSI-object"
|
87 |
+
olerepr = win32com.client.dynamic.MakeOleRepr(ob, None, None)
|
88 |
+
return ADSIDispatch(ob, olerepr, userName)
|
89 |
+
|
90 |
+
def _NewEnum(self):
|
91 |
+
try:
|
92 |
+
return ADSIEnumerator(self)
|
93 |
+
except pythoncom.com_error:
|
94 |
+
# doesnt support it - let our base try!
|
95 |
+
return win32com.client.CDispatch._NewEnum(self)
|
96 |
+
|
97 |
+
def __getattr__(self, attr):
|
98 |
+
try:
|
99 |
+
return getattr(self._oleobj_, attr)
|
100 |
+
except AttributeError:
|
101 |
+
return win32com.client.CDispatch.__getattr__(self, attr)
|
102 |
+
|
103 |
+
def QueryInterface(self, iid):
|
104 |
+
ret = self._oleobj_.QueryInterface(iid)
|
105 |
+
return _get_good_ret(ret)
|
106 |
+
|
107 |
+
|
108 |
+
# We override the global methods to do the right thing.
|
109 |
+
_ADsGetObject = ADsGetObject # The one in the .pyd
|
110 |
+
|
111 |
+
|
112 |
+
def ADsGetObject(path, iid=pythoncom.IID_IDispatch):
|
113 |
+
ret = _ADsGetObject(path, iid)
|
114 |
+
return _get_good_ret(ret)
|
115 |
+
|
116 |
+
|
117 |
+
_ADsOpenObject = ADsOpenObject
|
118 |
+
|
119 |
+
|
120 |
+
def ADsOpenObject(path, username, password, reserved=0, iid=pythoncom.IID_IDispatch):
|
121 |
+
ret = _ADsOpenObject(path, username, password, reserved, iid)
|
122 |
+
return _get_good_ret(ret)
|
MLPY/Lib/site-packages/win32comext/adsi/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (3.6 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/adsi/__pycache__/adsicon.cpython-39.pyc
ADDED
Binary file (11.6 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/adsi/adsi.pyd
ADDED
Binary file (97.8 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/adsi/adsicon.py
ADDED
@@ -0,0 +1,340 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
ADS_ATTR_CLEAR = 1
|
2 |
+
ADS_ATTR_UPDATE = 2
|
3 |
+
ADS_ATTR_APPEND = 3
|
4 |
+
ADS_ATTR_DELETE = 4
|
5 |
+
ADS_EXT_MINEXTDISPID = 1
|
6 |
+
ADS_EXT_MAXEXTDISPID = 16777215
|
7 |
+
ADS_EXT_INITCREDENTIALS = 1
|
8 |
+
ADS_EXT_INITIALIZE_COMPLETE = 2
|
9 |
+
|
10 |
+
ADS_SEARCHPREF_ASYNCHRONOUS = 0
|
11 |
+
ADS_SEARCHPREF_DEREF_ALIASES = 1
|
12 |
+
ADS_SEARCHPREF_SIZE_LIMIT = 2
|
13 |
+
ADS_SEARCHPREF_TIME_LIMIT = 3
|
14 |
+
ADS_SEARCHPREF_ATTRIBTYPES_ONLY = 4
|
15 |
+
ADS_SEARCHPREF_SEARCH_SCOPE = 5
|
16 |
+
ADS_SEARCHPREF_TIMEOUT = 6
|
17 |
+
ADS_SEARCHPREF_PAGESIZE = 7
|
18 |
+
ADS_SEARCHPREF_PAGED_TIME_LIMIT = 8
|
19 |
+
ADS_SEARCHPREF_CHASE_REFERRALS = 9
|
20 |
+
ADS_SEARCHPREF_SORT_ON = 10
|
21 |
+
ADS_SEARCHPREF_CACHE_RESULTS = 11
|
22 |
+
ADS_SEARCHPREF_DIRSYNC = 12
|
23 |
+
ADS_SEARCHPREF_TOMBSTONE = 13
|
24 |
+
|
25 |
+
ADS_SCOPE_BASE = 0
|
26 |
+
ADS_SCOPE_ONELEVEL = 1
|
27 |
+
ADS_SCOPE_SUBTREE = 2
|
28 |
+
|
29 |
+
ADS_SECURE_AUTHENTICATION = 0x1
|
30 |
+
ADS_USE_ENCRYPTION = 0x2
|
31 |
+
ADS_USE_SSL = 0x2
|
32 |
+
ADS_READONLY_SERVER = 0x4
|
33 |
+
ADS_PROMPT_CREDENTIALS = 0x8
|
34 |
+
ADS_NO_AUTHENTICATION = 0x10
|
35 |
+
ADS_FAST_BIND = 0x20
|
36 |
+
ADS_USE_SIGNING = 0x40
|
37 |
+
ADS_USE_SEALING = 0x80
|
38 |
+
ADS_USE_DELEGATION = 0x100
|
39 |
+
ADS_SERVER_BIND = 0x200
|
40 |
+
|
41 |
+
ADSTYPE_INVALID = 0
|
42 |
+
ADSTYPE_DN_STRING = ADSTYPE_INVALID + 1
|
43 |
+
ADSTYPE_CASE_EXACT_STRING = ADSTYPE_DN_STRING + 1
|
44 |
+
ADSTYPE_CASE_IGNORE_STRING = ADSTYPE_CASE_EXACT_STRING + 1
|
45 |
+
ADSTYPE_PRINTABLE_STRING = ADSTYPE_CASE_IGNORE_STRING + 1
|
46 |
+
ADSTYPE_NUMERIC_STRING = ADSTYPE_PRINTABLE_STRING + 1
|
47 |
+
ADSTYPE_BOOLEAN = ADSTYPE_NUMERIC_STRING + 1
|
48 |
+
ADSTYPE_INTEGER = ADSTYPE_BOOLEAN + 1
|
49 |
+
ADSTYPE_OCTET_STRING = ADSTYPE_INTEGER + 1
|
50 |
+
ADSTYPE_UTC_TIME = ADSTYPE_OCTET_STRING + 1
|
51 |
+
ADSTYPE_LARGE_INTEGER = ADSTYPE_UTC_TIME + 1
|
52 |
+
ADSTYPE_PROV_SPECIFIC = ADSTYPE_LARGE_INTEGER + 1
|
53 |
+
ADSTYPE_OBJECT_CLASS = ADSTYPE_PROV_SPECIFIC + 1
|
54 |
+
ADSTYPE_CASEIGNORE_LIST = ADSTYPE_OBJECT_CLASS + 1
|
55 |
+
ADSTYPE_OCTET_LIST = ADSTYPE_CASEIGNORE_LIST + 1
|
56 |
+
ADSTYPE_PATH = ADSTYPE_OCTET_LIST + 1
|
57 |
+
ADSTYPE_POSTALADDRESS = ADSTYPE_PATH + 1
|
58 |
+
ADSTYPE_TIMESTAMP = ADSTYPE_POSTALADDRESS + 1
|
59 |
+
ADSTYPE_BACKLINK = ADSTYPE_TIMESTAMP + 1
|
60 |
+
ADSTYPE_TYPEDNAME = ADSTYPE_BACKLINK + 1
|
61 |
+
ADSTYPE_HOLD = ADSTYPE_TYPEDNAME + 1
|
62 |
+
ADSTYPE_NETADDRESS = ADSTYPE_HOLD + 1
|
63 |
+
ADSTYPE_REPLICAPOINTER = ADSTYPE_NETADDRESS + 1
|
64 |
+
ADSTYPE_FAXNUMBER = ADSTYPE_REPLICAPOINTER + 1
|
65 |
+
ADSTYPE_EMAIL = ADSTYPE_FAXNUMBER + 1
|
66 |
+
ADSTYPE_NT_SECURITY_DESCRIPTOR = ADSTYPE_EMAIL + 1
|
67 |
+
ADSTYPE_UNKNOWN = ADSTYPE_NT_SECURITY_DESCRIPTOR + 1
|
68 |
+
ADSTYPE_DN_WITH_BINARY = ADSTYPE_UNKNOWN + 1
|
69 |
+
ADSTYPE_DN_WITH_STRING = ADSTYPE_DN_WITH_BINARY + 1
|
70 |
+
|
71 |
+
ADS_PROPERTY_CLEAR = 1
|
72 |
+
ADS_PROPERTY_UPDATE = 2
|
73 |
+
ADS_PROPERTY_APPEND = 3
|
74 |
+
ADS_PROPERTY_DELETE = 4
|
75 |
+
ADS_SYSTEMFLAG_DISALLOW_DELETE = -2147483648
|
76 |
+
ADS_SYSTEMFLAG_CONFIG_ALLOW_RENAME = 0x40000000
|
77 |
+
ADS_SYSTEMFLAG_CONFIG_ALLOW_MOVE = 0x20000000
|
78 |
+
ADS_SYSTEMFLAG_CONFIG_ALLOW_LIMITED_MOVE = 0x10000000
|
79 |
+
ADS_SYSTEMFLAG_DOMAIN_DISALLOW_RENAME = -2147483648
|
80 |
+
ADS_SYSTEMFLAG_DOMAIN_DISALLOW_MOVE = 0x4000000
|
81 |
+
ADS_SYSTEMFLAG_CR_NTDS_NC = 0x1
|
82 |
+
ADS_SYSTEMFLAG_CR_NTDS_DOMAIN = 0x2
|
83 |
+
ADS_SYSTEMFLAG_ATTR_NOT_REPLICATED = 0x1
|
84 |
+
ADS_SYSTEMFLAG_ATTR_IS_CONSTRUCTED = 0x4
|
85 |
+
ADS_GROUP_TYPE_GLOBAL_GROUP = 0x2
|
86 |
+
ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 0x4
|
87 |
+
ADS_GROUP_TYPE_LOCAL_GROUP = 0x4
|
88 |
+
ADS_GROUP_TYPE_UNIVERSAL_GROUP = 0x8
|
89 |
+
ADS_GROUP_TYPE_SECURITY_ENABLED = -2147483648
|
90 |
+
ADS_UF_SCRIPT = 0x1
|
91 |
+
ADS_UF_ACCOUNTDISABLE = 0x2
|
92 |
+
ADS_UF_HOMEDIR_REQUIRED = 0x8
|
93 |
+
ADS_UF_LOCKOUT = 0x10
|
94 |
+
ADS_UF_PASSWD_NOTREQD = 0x20
|
95 |
+
ADS_UF_PASSWD_CANT_CHANGE = 0x40
|
96 |
+
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x80
|
97 |
+
ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0x100
|
98 |
+
ADS_UF_NORMAL_ACCOUNT = 0x200
|
99 |
+
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0x800
|
100 |
+
ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x1000
|
101 |
+
ADS_UF_SERVER_TRUST_ACCOUNT = 0x2000
|
102 |
+
ADS_UF_DONT_EXPIRE_PASSWD = 0x10000
|
103 |
+
ADS_UF_MNS_LOGON_ACCOUNT = 0x20000
|
104 |
+
ADS_UF_SMARTCARD_REQUIRED = 0x40000
|
105 |
+
ADS_UF_TRUSTED_FOR_DELEGATION = 0x80000
|
106 |
+
ADS_UF_NOT_DELEGATED = 0x100000
|
107 |
+
ADS_UF_USE_DES_KEY_ONLY = 0x200000
|
108 |
+
ADS_UF_DONT_REQUIRE_PREAUTH = 0x400000
|
109 |
+
ADS_UF_PASSWORD_EXPIRED = 0x800000
|
110 |
+
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000
|
111 |
+
ADS_RIGHT_DELETE = 0x10000
|
112 |
+
ADS_RIGHT_READ_CONTROL = 0x20000
|
113 |
+
ADS_RIGHT_WRITE_DAC = 0x40000
|
114 |
+
ADS_RIGHT_WRITE_OWNER = 0x80000
|
115 |
+
ADS_RIGHT_SYNCHRONIZE = 0x100000
|
116 |
+
ADS_RIGHT_ACCESS_SYSTEM_SECURITY = 0x1000000
|
117 |
+
ADS_RIGHT_GENERIC_READ = -2147483648
|
118 |
+
ADS_RIGHT_GENERIC_WRITE = 0x40000000
|
119 |
+
ADS_RIGHT_GENERIC_EXECUTE = 0x20000000
|
120 |
+
ADS_RIGHT_GENERIC_ALL = 0x10000000
|
121 |
+
ADS_RIGHT_DS_CREATE_CHILD = 0x1
|
122 |
+
ADS_RIGHT_DS_DELETE_CHILD = 0x2
|
123 |
+
ADS_RIGHT_ACTRL_DS_LIST = 0x4
|
124 |
+
ADS_RIGHT_DS_SELF = 0x8
|
125 |
+
ADS_RIGHT_DS_READ_PROP = 0x10
|
126 |
+
ADS_RIGHT_DS_WRITE_PROP = 0x20
|
127 |
+
ADS_RIGHT_DS_DELETE_TREE = 0x40
|
128 |
+
ADS_RIGHT_DS_LIST_OBJECT = 0x80
|
129 |
+
ADS_RIGHT_DS_CONTROL_ACCESS = 0x100
|
130 |
+
ADS_ACETYPE_ACCESS_ALLOWED = 0
|
131 |
+
ADS_ACETYPE_ACCESS_DENIED = 0x1
|
132 |
+
ADS_ACETYPE_SYSTEM_AUDIT = 0x2
|
133 |
+
ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = 0x5
|
134 |
+
ADS_ACETYPE_ACCESS_DENIED_OBJECT = 0x6
|
135 |
+
ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = 0x7
|
136 |
+
ADS_ACETYPE_SYSTEM_ALARM_OBJECT = 0x8
|
137 |
+
ADS_ACETYPE_ACCESS_ALLOWED_CALLBACK = 0x9
|
138 |
+
ADS_ACETYPE_ACCESS_DENIED_CALLBACK = 0xA
|
139 |
+
ADS_ACETYPE_ACCESS_ALLOWED_CALLBACK_OBJECT = 0xB
|
140 |
+
ADS_ACETYPE_ACCESS_DENIED_CALLBACK_OBJECT = 0xC
|
141 |
+
ADS_ACETYPE_SYSTEM_AUDIT_CALLBACK = 0xD
|
142 |
+
ADS_ACETYPE_SYSTEM_ALARM_CALLBACK = 0xE
|
143 |
+
ADS_ACETYPE_SYSTEM_AUDIT_CALLBACK_OBJECT = 0xF
|
144 |
+
ADS_ACETYPE_SYSTEM_ALARM_CALLBACK_OBJECT = 0x10
|
145 |
+
ADS_ACEFLAG_INHERIT_ACE = 0x2
|
146 |
+
ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = 0x4
|
147 |
+
ADS_ACEFLAG_INHERIT_ONLY_ACE = 0x8
|
148 |
+
ADS_ACEFLAG_INHERITED_ACE = 0x10
|
149 |
+
ADS_ACEFLAG_VALID_INHERIT_FLAGS = 0x1F
|
150 |
+
ADS_ACEFLAG_SUCCESSFUL_ACCESS = 0x40
|
151 |
+
ADS_ACEFLAG_FAILED_ACCESS = 0x80
|
152 |
+
ADS_FLAG_OBJECT_TYPE_PRESENT = 0x1
|
153 |
+
ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT = 0x2
|
154 |
+
ADS_SD_CONTROL_SE_OWNER_DEFAULTED = 0x1
|
155 |
+
ADS_SD_CONTROL_SE_GROUP_DEFAULTED = 0x2
|
156 |
+
ADS_SD_CONTROL_SE_DACL_PRESENT = 0x4
|
157 |
+
ADS_SD_CONTROL_SE_DACL_DEFAULTED = 0x8
|
158 |
+
ADS_SD_CONTROL_SE_SACL_PRESENT = 0x10
|
159 |
+
ADS_SD_CONTROL_SE_SACL_DEFAULTED = 0x20
|
160 |
+
ADS_SD_CONTROL_SE_DACL_AUTO_INHERIT_REQ = 0x100
|
161 |
+
ADS_SD_CONTROL_SE_SACL_AUTO_INHERIT_REQ = 0x200
|
162 |
+
ADS_SD_CONTROL_SE_DACL_AUTO_INHERITED = 0x400
|
163 |
+
ADS_SD_CONTROL_SE_SACL_AUTO_INHERITED = 0x800
|
164 |
+
ADS_SD_CONTROL_SE_DACL_PROTECTED = 0x1000
|
165 |
+
ADS_SD_CONTROL_SE_SACL_PROTECTED = 0x2000
|
166 |
+
ADS_SD_CONTROL_SE_SELF_RELATIVE = 0x8000
|
167 |
+
ADS_SD_REVISION_DS = 4
|
168 |
+
ADS_NAME_TYPE_1779 = 1
|
169 |
+
ADS_NAME_TYPE_CANONICAL = 2
|
170 |
+
ADS_NAME_TYPE_NT4 = 3
|
171 |
+
ADS_NAME_TYPE_DISPLAY = 4
|
172 |
+
ADS_NAME_TYPE_DOMAIN_SIMPLE = 5
|
173 |
+
ADS_NAME_TYPE_ENTERPRISE_SIMPLE = 6
|
174 |
+
ADS_NAME_TYPE_GUID = 7
|
175 |
+
ADS_NAME_TYPE_UNKNOWN = 8
|
176 |
+
ADS_NAME_TYPE_USER_PRINCIPAL_NAME = 9
|
177 |
+
ADS_NAME_TYPE_CANONICAL_EX = 10
|
178 |
+
ADS_NAME_TYPE_SERVICE_PRINCIPAL_NAME = 11
|
179 |
+
ADS_NAME_TYPE_SID_OR_SID_HISTORY_NAME = 12
|
180 |
+
ADS_NAME_INITTYPE_DOMAIN = 1
|
181 |
+
ADS_NAME_INITTYPE_SERVER = 2
|
182 |
+
ADS_NAME_INITTYPE_GC = 3
|
183 |
+
ADS_OPTION_SERVERNAME = 0
|
184 |
+
ADS_OPTION_REFERRALS = ADS_OPTION_SERVERNAME + 1
|
185 |
+
ADS_OPTION_PAGE_SIZE = ADS_OPTION_REFERRALS + 1
|
186 |
+
ADS_OPTION_SECURITY_MASK = ADS_OPTION_PAGE_SIZE + 1
|
187 |
+
ADS_OPTION_MUTUAL_AUTH_STATUS = ADS_OPTION_SECURITY_MASK + 1
|
188 |
+
ADS_OPTION_QUOTA = ADS_OPTION_MUTUAL_AUTH_STATUS + 1
|
189 |
+
ADS_OPTION_PASSWORD_PORTNUMBER = ADS_OPTION_QUOTA + 1
|
190 |
+
ADS_OPTION_PASSWORD_METHOD = ADS_OPTION_PASSWORD_PORTNUMBER + 1
|
191 |
+
ADS_SECURITY_INFO_OWNER = 0x1
|
192 |
+
ADS_SECURITY_INFO_GROUP = 0x2
|
193 |
+
ADS_SECURITY_INFO_DACL = 0x4
|
194 |
+
ADS_SECURITY_INFO_SACL = 0x8
|
195 |
+
ADS_SETTYPE_FULL = 1
|
196 |
+
ADS_SETTYPE_PROVIDER = 2
|
197 |
+
ADS_SETTYPE_SERVER = 3
|
198 |
+
ADS_SETTYPE_DN = 4
|
199 |
+
ADS_FORMAT_WINDOWS = 1
|
200 |
+
ADS_FORMAT_WINDOWS_NO_SERVER = 2
|
201 |
+
ADS_FORMAT_WINDOWS_DN = 3
|
202 |
+
ADS_FORMAT_WINDOWS_PARENT = 4
|
203 |
+
ADS_FORMAT_X500 = 5
|
204 |
+
ADS_FORMAT_X500_NO_SERVER = 6
|
205 |
+
ADS_FORMAT_X500_DN = 7
|
206 |
+
ADS_FORMAT_X500_PARENT = 8
|
207 |
+
ADS_FORMAT_SERVER = 9
|
208 |
+
ADS_FORMAT_PROVIDER = 10
|
209 |
+
ADS_FORMAT_LEAF = 11
|
210 |
+
ADS_DISPLAY_FULL = 1
|
211 |
+
ADS_DISPLAY_VALUE_ONLY = 2
|
212 |
+
ADS_ESCAPEDMODE_DEFAULT = 1
|
213 |
+
ADS_ESCAPEDMODE_ON = 2
|
214 |
+
ADS_ESCAPEDMODE_OFF = 3
|
215 |
+
ADS_ESCAPEDMODE_OFF_EX = 4
|
216 |
+
ADS_PATH_FILE = 1
|
217 |
+
ADS_PATH_FILESHARE = 2
|
218 |
+
ADS_PATH_REGISTRY = 3
|
219 |
+
ADS_SD_FORMAT_IID = 1
|
220 |
+
ADS_SD_FORMAT_RAW = 2
|
221 |
+
ADS_SD_FORMAT_HEXSTRING = 3
|
222 |
+
|
223 |
+
|
224 |
+
# Generated by h2py from AdsErr.h
|
225 |
+
def _HRESULT_TYPEDEF_(_sc):
|
226 |
+
return _sc
|
227 |
+
|
228 |
+
|
229 |
+
E_ADS_BAD_PATHNAME = _HRESULT_TYPEDEF_((-2147463168))
|
230 |
+
E_ADS_INVALID_DOMAIN_OBJECT = _HRESULT_TYPEDEF_((-2147463167))
|
231 |
+
E_ADS_INVALID_USER_OBJECT = _HRESULT_TYPEDEF_((-2147463166))
|
232 |
+
E_ADS_INVALID_COMPUTER_OBJECT = _HRESULT_TYPEDEF_((-2147463165))
|
233 |
+
E_ADS_UNKNOWN_OBJECT = _HRESULT_TYPEDEF_((-2147463164))
|
234 |
+
E_ADS_PROPERTY_NOT_SET = _HRESULT_TYPEDEF_((-2147463163))
|
235 |
+
E_ADS_PROPERTY_NOT_SUPPORTED = _HRESULT_TYPEDEF_((-2147463162))
|
236 |
+
E_ADS_PROPERTY_INVALID = _HRESULT_TYPEDEF_((-2147463161))
|
237 |
+
E_ADS_BAD_PARAMETER = _HRESULT_TYPEDEF_((-2147463160))
|
238 |
+
E_ADS_OBJECT_UNBOUND = _HRESULT_TYPEDEF_((-2147463159))
|
239 |
+
E_ADS_PROPERTY_NOT_MODIFIED = _HRESULT_TYPEDEF_((-2147463158))
|
240 |
+
E_ADS_PROPERTY_MODIFIED = _HRESULT_TYPEDEF_((-2147463157))
|
241 |
+
E_ADS_CANT_CONVERT_DATATYPE = _HRESULT_TYPEDEF_((-2147463156))
|
242 |
+
E_ADS_PROPERTY_NOT_FOUND = _HRESULT_TYPEDEF_((-2147463155))
|
243 |
+
E_ADS_OBJECT_EXISTS = _HRESULT_TYPEDEF_((-2147463154))
|
244 |
+
E_ADS_SCHEMA_VIOLATION = _HRESULT_TYPEDEF_((-2147463153))
|
245 |
+
E_ADS_COLUMN_NOT_SET = _HRESULT_TYPEDEF_((-2147463152))
|
246 |
+
S_ADS_ERRORSOCCURRED = _HRESULT_TYPEDEF_(0x00005011)
|
247 |
+
S_ADS_NOMORE_ROWS = _HRESULT_TYPEDEF_(0x00005012)
|
248 |
+
S_ADS_NOMORE_COLUMNS = _HRESULT_TYPEDEF_(0x00005013)
|
249 |
+
E_ADS_INVALID_FILTER = _HRESULT_TYPEDEF_((-2147463148))
|
250 |
+
|
251 |
+
# ADS_DEREFENUM enum
|
252 |
+
ADS_DEREF_NEVER = 0
|
253 |
+
ADS_DEREF_SEARCHING = 1
|
254 |
+
ADS_DEREF_FINDING = 2
|
255 |
+
ADS_DEREF_ALWAYS = 3
|
256 |
+
|
257 |
+
# ADS_PREFERENCES_ENUM
|
258 |
+
ADSIPROP_ASYNCHRONOUS = 0
|
259 |
+
ADSIPROP_DEREF_ALIASES = 0x1
|
260 |
+
ADSIPROP_SIZE_LIMIT = 0x2
|
261 |
+
ADSIPROP_TIME_LIMIT = 0x3
|
262 |
+
ADSIPROP_ATTRIBTYPES_ONLY = 0x4
|
263 |
+
ADSIPROP_SEARCH_SCOPE = 0x5
|
264 |
+
ADSIPROP_TIMEOUT = 0x6
|
265 |
+
ADSIPROP_PAGESIZE = 0x7
|
266 |
+
ADSIPROP_PAGED_TIME_LIMIT = 0x8
|
267 |
+
ADSIPROP_CHASE_REFERRALS = 0x9
|
268 |
+
ADSIPROP_SORT_ON = 0xA
|
269 |
+
ADSIPROP_CACHE_RESULTS = 0xB
|
270 |
+
ADSIPROP_ADSIFLAG = 0xC
|
271 |
+
|
272 |
+
# ADSI_DIALECT_ENUM
|
273 |
+
ADSI_DIALECT_LDAP = 0
|
274 |
+
ADSI_DIALECT_SQL = 0x1
|
275 |
+
|
276 |
+
# ADS_CHASE_REFERRALS_ENUM
|
277 |
+
ADS_CHASE_REFERRALS_NEVER = 0
|
278 |
+
ADS_CHASE_REFERRALS_SUBORDINATE = 0x20
|
279 |
+
ADS_CHASE_REFERRALS_EXTERNAL = 0x40
|
280 |
+
ADS_CHASE_REFERRALS_ALWAYS = (
|
281 |
+
ADS_CHASE_REFERRALS_SUBORDINATE | ADS_CHASE_REFERRALS_EXTERNAL
|
282 |
+
)
|
283 |
+
|
284 |
+
# Generated by h2py from ObjSel.h
|
285 |
+
DSOP_SCOPE_TYPE_TARGET_COMPUTER = 0x00000001
|
286 |
+
DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN = 0x00000002
|
287 |
+
DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN = 0x00000004
|
288 |
+
DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN = 0x00000008
|
289 |
+
DSOP_SCOPE_TYPE_GLOBAL_CATALOG = 0x00000010
|
290 |
+
DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN = 0x00000020
|
291 |
+
DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN = 0x00000040
|
292 |
+
DSOP_SCOPE_TYPE_WORKGROUP = 0x00000080
|
293 |
+
DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE = 0x00000100
|
294 |
+
DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE = 0x00000200
|
295 |
+
DSOP_SCOPE_FLAG_STARTING_SCOPE = 0x00000001
|
296 |
+
DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT = 0x00000002
|
297 |
+
DSOP_SCOPE_FLAG_WANT_PROVIDER_LDAP = 0x00000004
|
298 |
+
DSOP_SCOPE_FLAG_WANT_PROVIDER_GC = 0x00000008
|
299 |
+
DSOP_SCOPE_FLAG_WANT_SID_PATH = 0x00000010
|
300 |
+
DSOP_SCOPE_FLAG_WANT_DOWNLEVEL_BUILTIN_PATH = 0x00000020
|
301 |
+
DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS = 0x00000040
|
302 |
+
DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS = 0x00000080
|
303 |
+
DSOP_SCOPE_FLAG_DEFAULT_FILTER_COMPUTERS = 0x00000100
|
304 |
+
DSOP_SCOPE_FLAG_DEFAULT_FILTER_CONTACTS = 0x00000200
|
305 |
+
DSOP_FILTER_INCLUDE_ADVANCED_VIEW = 0x00000001
|
306 |
+
DSOP_FILTER_USERS = 0x00000002
|
307 |
+
DSOP_FILTER_BUILTIN_GROUPS = 0x00000004
|
308 |
+
DSOP_FILTER_WELL_KNOWN_PRINCIPALS = 0x00000008
|
309 |
+
DSOP_FILTER_UNIVERSAL_GROUPS_DL = 0x00000010
|
310 |
+
DSOP_FILTER_UNIVERSAL_GROUPS_SE = 0x00000020
|
311 |
+
DSOP_FILTER_GLOBAL_GROUPS_DL = 0x00000040
|
312 |
+
DSOP_FILTER_GLOBAL_GROUPS_SE = 0x00000080
|
313 |
+
DSOP_FILTER_DOMAIN_LOCAL_GROUPS_DL = 0x00000100
|
314 |
+
DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE = 0x00000200
|
315 |
+
DSOP_FILTER_CONTACTS = 0x00000400
|
316 |
+
DSOP_FILTER_COMPUTERS = 0x00000800
|
317 |
+
DSOP_DOWNLEVEL_FILTER_USERS = -2147483647
|
318 |
+
DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS = -2147483646
|
319 |
+
DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS = -2147483644
|
320 |
+
DSOP_DOWNLEVEL_FILTER_COMPUTERS = -2147483640
|
321 |
+
DSOP_DOWNLEVEL_FILTER_WORLD = -2147483632
|
322 |
+
DSOP_DOWNLEVEL_FILTER_AUTHENTICATED_USER = -2147483616
|
323 |
+
DSOP_DOWNLEVEL_FILTER_ANONYMOUS = -2147483584
|
324 |
+
DSOP_DOWNLEVEL_FILTER_BATCH = -2147483520
|
325 |
+
DSOP_DOWNLEVEL_FILTER_CREATOR_OWNER = -2147483392
|
326 |
+
DSOP_DOWNLEVEL_FILTER_CREATOR_GROUP = -2147483136
|
327 |
+
DSOP_DOWNLEVEL_FILTER_DIALUP = -2147482624
|
328 |
+
DSOP_DOWNLEVEL_FILTER_INTERACTIVE = -2147481600
|
329 |
+
DSOP_DOWNLEVEL_FILTER_NETWORK = -2147479552
|
330 |
+
DSOP_DOWNLEVEL_FILTER_SERVICE = -2147475456
|
331 |
+
DSOP_DOWNLEVEL_FILTER_SYSTEM = -2147467264
|
332 |
+
DSOP_DOWNLEVEL_FILTER_EXCLUDE_BUILTIN_GROUPS = -2147450880
|
333 |
+
DSOP_DOWNLEVEL_FILTER_TERMINAL_SERVER = -2147418112
|
334 |
+
DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS = -2147352576
|
335 |
+
DSOP_DOWNLEVEL_FILTER_LOCAL_SERVICE = -2147221504
|
336 |
+
DSOP_DOWNLEVEL_FILTER_NETWORK_SERVICE = -2146959360
|
337 |
+
DSOP_DOWNLEVEL_FILTER_REMOTE_LOGON = -2146435072
|
338 |
+
DSOP_FLAG_MULTISELECT = 0x00000001
|
339 |
+
DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK = 0x00000002
|
340 |
+
CFSTR_DSOP_DS_SELECTION_LIST = "CFSTR_DSOP_DS_SELECTION_LIST"
|
MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/objectPicker.cpython-39.pyc
ADDED
Binary file (1.43 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/scp.cpython-39.pyc
ADDED
Binary file (11.9 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/search.cpython-39.pyc
ADDED
Binary file (3.98 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/test.cpython-39.pyc
ADDED
Binary file (6.8 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/adsi/demos/objectPicker.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# A demo for the IDsObjectPicker interface.
|
2 |
+
import pythoncom
|
3 |
+
import win32clipboard
|
4 |
+
from win32com.adsi import adsi
|
5 |
+
from win32com.adsi.adsicon import *
|
6 |
+
|
7 |
+
cf_objectpicker = win32clipboard.RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST)
|
8 |
+
|
9 |
+
|
10 |
+
def main():
|
11 |
+
hwnd = 0
|
12 |
+
|
13 |
+
# Create an instance of the object picker.
|
14 |
+
picker = pythoncom.CoCreateInstance(
|
15 |
+
adsi.CLSID_DsObjectPicker,
|
16 |
+
None,
|
17 |
+
pythoncom.CLSCTX_INPROC_SERVER,
|
18 |
+
adsi.IID_IDsObjectPicker,
|
19 |
+
)
|
20 |
+
|
21 |
+
# Create our scope init info.
|
22 |
+
siis = adsi.DSOP_SCOPE_INIT_INFOs(1)
|
23 |
+
sii = siis[0]
|
24 |
+
|
25 |
+
# Combine multiple scope types in a single array entry.
|
26 |
+
|
27 |
+
sii.type = (
|
28 |
+
DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN
|
29 |
+
)
|
30 |
+
|
31 |
+
# Set uplevel and downlevel filters to include only computer objects.
|
32 |
+
# Uplevel filters apply to both mixed and native modes.
|
33 |
+
# Notice that the uplevel and downlevel flags are different.
|
34 |
+
|
35 |
+
sii.filterFlags.uplevel.bothModes = DSOP_FILTER_COMPUTERS
|
36 |
+
sii.filterFlags.downlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS
|
37 |
+
|
38 |
+
# Initialize the interface.
|
39 |
+
picker.Initialize(
|
40 |
+
None, # Target is the local computer.
|
41 |
+
siis, # scope infos
|
42 |
+
DSOP_FLAG_MULTISELECT, # options
|
43 |
+
("objectGUID", "displayName"),
|
44 |
+
) # attributes to fetch
|
45 |
+
|
46 |
+
do = picker.InvokeDialog(hwnd)
|
47 |
+
# Extract the data from the IDataObject.
|
48 |
+
format_etc = (
|
49 |
+
cf_objectpicker,
|
50 |
+
None,
|
51 |
+
pythoncom.DVASPECT_CONTENT,
|
52 |
+
-1,
|
53 |
+
pythoncom.TYMED_HGLOBAL,
|
54 |
+
)
|
55 |
+
medium = do.GetData(format_etc)
|
56 |
+
data = adsi.StringAsDS_SELECTION_LIST(medium.data)
|
57 |
+
for item in data:
|
58 |
+
name, klass, adspath, upn, attrs, flags = item
|
59 |
+
print("Item", name)
|
60 |
+
print(" Class:", klass)
|
61 |
+
print(" AdsPath:", adspath)
|
62 |
+
print(" UPN:", upn)
|
63 |
+
print(" Attrs:", attrs)
|
64 |
+
print(" Flags:", flags)
|
65 |
+
|
66 |
+
|
67 |
+
if __name__ == "__main__":
|
68 |
+
main()
|
MLPY/Lib/site-packages/win32comext/adsi/demos/scp.py
ADDED
@@ -0,0 +1,565 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""A re-implementation of the MS DirectoryService samples related to services.
|
2 |
+
|
3 |
+
* Adds and removes an ActiveDirectory "Service Connection Point",
|
4 |
+
including managing the security on the object.
|
5 |
+
* Creates and registers Service Principal Names.
|
6 |
+
* Changes the username for a domain user.
|
7 |
+
|
8 |
+
Some of these functions are likely to become move to a module - but there
|
9 |
+
is also a little command-line-interface to try these functions out.
|
10 |
+
|
11 |
+
For example:
|
12 |
+
|
13 |
+
scp.py --account-name=domain\\user --service-class=PythonScpTest \\
|
14 |
+
--keyword=foo --keyword=bar --binding-string=bind_info \\
|
15 |
+
ScpCreate SpnCreate SpnRegister
|
16 |
+
|
17 |
+
would:
|
18 |
+
* Attempt to delete a Service Connection Point for the service class
|
19 |
+
'PythonScpTest'
|
20 |
+
* Attempt to create a Service Connection Point for that class, with 2
|
21 |
+
keywords and a binding string of 'bind_info'
|
22 |
+
* Create a Service Principal Name for the service and register it
|
23 |
+
|
24 |
+
to undo those changes, you could execute:
|
25 |
+
|
26 |
+
scp.py --account-name=domain\\user --service-class=PythonScpTest \\
|
27 |
+
SpnCreate SpnUnregister ScpDelete
|
28 |
+
|
29 |
+
which will:
|
30 |
+
* Create a SPN
|
31 |
+
* Unregister that SPN from the Active Directory.
|
32 |
+
* Delete the Service Connection Point
|
33 |
+
|
34 |
+
Executing with --test will create and remove one of everything.
|
35 |
+
"""
|
36 |
+
|
37 |
+
import optparse
|
38 |
+
import textwrap
|
39 |
+
import traceback
|
40 |
+
|
41 |
+
import ntsecuritycon as dscon
|
42 |
+
import win32api
|
43 |
+
import win32con
|
44 |
+
import win32security
|
45 |
+
import winerror
|
46 |
+
from win32com.adsi import adsi
|
47 |
+
from win32com.adsi.adsicon import *
|
48 |
+
from win32com.client import Dispatch
|
49 |
+
|
50 |
+
verbose = 1
|
51 |
+
g_createdSCP = None
|
52 |
+
g_createdSPNs = []
|
53 |
+
g_createdSPNLast = None
|
54 |
+
|
55 |
+
import logging
|
56 |
+
|
57 |
+
logger = logging # use logging module global methods for now.
|
58 |
+
|
59 |
+
# still a bit confused about log(n, ...) vs logger.info/debug()
|
60 |
+
|
61 |
+
|
62 |
+
# Returns distinguished name of SCP.
|
63 |
+
def ScpCreate(
|
64 |
+
service_binding_info,
|
65 |
+
service_class_name, # Service class string to store in SCP.
|
66 |
+
account_name=None, # Logon account that needs access to SCP.
|
67 |
+
container_name=None,
|
68 |
+
keywords=None,
|
69 |
+
object_class="serviceConnectionPoint",
|
70 |
+
dns_name_type="A",
|
71 |
+
dn=None,
|
72 |
+
dns_name=None,
|
73 |
+
):
|
74 |
+
container_name = container_name or service_class_name
|
75 |
+
if not dns_name:
|
76 |
+
# Get the DNS name of the local computer
|
77 |
+
dns_name = win32api.GetComputerNameEx(win32con.ComputerNameDnsFullyQualified)
|
78 |
+
# Get the distinguished name of the computer object for the local computer
|
79 |
+
if dn is None:
|
80 |
+
dn = win32api.GetComputerObjectName(win32con.NameFullyQualifiedDN)
|
81 |
+
|
82 |
+
# Compose the ADSpath and bind to the computer object for the local computer
|
83 |
+
comp = adsi.ADsGetObject("LDAP://" + dn, adsi.IID_IDirectoryObject)
|
84 |
+
|
85 |
+
# Publish the SCP as a child of the computer object
|
86 |
+
keywords = keywords or []
|
87 |
+
# Fill in the attribute values to be stored in the SCP.
|
88 |
+
attrs = [
|
89 |
+
("cn", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, (container_name,)),
|
90 |
+
("objectClass", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, (object_class,)),
|
91 |
+
("keywords", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, keywords),
|
92 |
+
("serviceDnsName", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, (dns_name,)),
|
93 |
+
(
|
94 |
+
"serviceDnsNameType",
|
95 |
+
ADS_ATTR_UPDATE,
|
96 |
+
ADSTYPE_CASE_IGNORE_STRING,
|
97 |
+
(dns_name_type,),
|
98 |
+
),
|
99 |
+
(
|
100 |
+
"serviceClassName",
|
101 |
+
ADS_ATTR_UPDATE,
|
102 |
+
ADSTYPE_CASE_IGNORE_STRING,
|
103 |
+
(service_class_name,),
|
104 |
+
),
|
105 |
+
(
|
106 |
+
"serviceBindingInformation",
|
107 |
+
ADS_ATTR_UPDATE,
|
108 |
+
ADSTYPE_CASE_IGNORE_STRING,
|
109 |
+
(service_binding_info,),
|
110 |
+
),
|
111 |
+
]
|
112 |
+
new = comp.CreateDSObject("cn=" + container_name, attrs)
|
113 |
+
logger.info("New connection point is at %s", container_name)
|
114 |
+
# Wrap in a usable IDispatch object.
|
115 |
+
new = Dispatch(new)
|
116 |
+
# And allow access to the SCP for the specified account name
|
117 |
+
AllowAccessToScpProperties(account_name, new)
|
118 |
+
return new
|
119 |
+
|
120 |
+
|
121 |
+
def ScpDelete(container_name, dn=None):
|
122 |
+
if dn is None:
|
123 |
+
dn = win32api.GetComputerObjectName(win32con.NameFullyQualifiedDN)
|
124 |
+
logger.debug("Removing connection point '%s' from %s", container_name, dn)
|
125 |
+
|
126 |
+
# Compose the ADSpath and bind to the computer object for the local computer
|
127 |
+
comp = adsi.ADsGetObject("LDAP://" + dn, adsi.IID_IDirectoryObject)
|
128 |
+
comp.DeleteDSObject("cn=" + container_name)
|
129 |
+
logger.info("Deleted service connection point '%s'", container_name)
|
130 |
+
|
131 |
+
|
132 |
+
# This function is described in detail in the MSDN article titled
|
133 |
+
# "Enabling Service Account to Access SCP Properties"
|
134 |
+
# From that article:
|
135 |
+
# The following sample code sets a pair of ACEs on a service connection point
|
136 |
+
# (SCP) object. The ACEs grant read/write access to the user or computer account
|
137 |
+
# under which the service instance will be running. Your service installation
|
138 |
+
# program calls this code to ensure that the service will be allowed to update
|
139 |
+
# its properties at run time. If you don't set ACEs like these, your service
|
140 |
+
# will get access-denied errors if it tries to modify the SCP's properties.
|
141 |
+
#
|
142 |
+
# The code uses the IADsSecurityDescriptor, IADsAccessControlList, and
|
143 |
+
# IADsAccessControlEntry interfaces to do the following:
|
144 |
+
# * Get the SCP object's security descriptor.
|
145 |
+
# * Set ACEs in the DACL of the security descriptor.
|
146 |
+
# * Set the security descriptor back on the SCP object.
|
147 |
+
|
148 |
+
|
149 |
+
def AllowAccessToScpProperties(
|
150 |
+
accountSAM, # Service account to allow access.
|
151 |
+
scpObject, # The IADs SCP object.
|
152 |
+
schemaIDGUIDs=( # Attributes to allow write-access to.
|
153 |
+
"{28630eb8-41d5-11d1-a9c1-0000f80367c1}", # serviceDNSName
|
154 |
+
"{b7b1311c-b82e-11d0-afee-0000f80367c1}", # serviceBindingInformation
|
155 |
+
),
|
156 |
+
):
|
157 |
+
# If no service account is specified, service runs under LocalSystem.
|
158 |
+
# So allow access to the computer account of the service's host.
|
159 |
+
if accountSAM:
|
160 |
+
trustee = accountSAM
|
161 |
+
else:
|
162 |
+
# Get the SAM account name of the computer object for the server.
|
163 |
+
trustee = win32api.GetComputerObjectName(win32con.NameSamCompatible)
|
164 |
+
|
165 |
+
# Get the nTSecurityDescriptor attribute
|
166 |
+
attribute = "nTSecurityDescriptor"
|
167 |
+
sd = getattr(scpObject, attribute)
|
168 |
+
acl = sd.DiscretionaryAcl
|
169 |
+
|
170 |
+
for sguid in schemaIDGUIDs:
|
171 |
+
ace = Dispatch(adsi.CLSID_AccessControlEntry)
|
172 |
+
|
173 |
+
# Set the properties of the ACE.
|
174 |
+
# Allow read and write access to the property.
|
175 |
+
ace.AccessMask = ADS_RIGHT_DS_READ_PROP | ADS_RIGHT_DS_WRITE_PROP
|
176 |
+
|
177 |
+
# Set the trustee, which is either the service account or the
|
178 |
+
# host computer account.
|
179 |
+
ace.Trustee = trustee
|
180 |
+
|
181 |
+
# Set the ACE type.
|
182 |
+
ace.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
|
183 |
+
|
184 |
+
# Set AceFlags to zero because ACE is not inheritable.
|
185 |
+
ace.AceFlags = 0
|
186 |
+
|
187 |
+
# Set Flags to indicate an ACE that protects a specified object.
|
188 |
+
ace.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT
|
189 |
+
|
190 |
+
# Set ObjectType to the schemaIDGUID of the attribute.
|
191 |
+
ace.ObjectType = sguid
|
192 |
+
|
193 |
+
# Add the ACEs to the DACL.
|
194 |
+
acl.AddAce(ace)
|
195 |
+
|
196 |
+
# Write the modified DACL back to the security descriptor.
|
197 |
+
sd.DiscretionaryAcl = acl
|
198 |
+
# Write the ntSecurityDescriptor property to the property cache.
|
199 |
+
setattr(scpObject, attribute, sd)
|
200 |
+
# SetInfo updates the SCP object in the directory.
|
201 |
+
scpObject.SetInfo()
|
202 |
+
logger.info("Set security on object for account '%s'" % (trustee,))
|
203 |
+
|
204 |
+
|
205 |
+
# Service Principal Names functions from the same sample.
|
206 |
+
# The example calls the DsWriteAccountSpn function, which stores the SPNs in
|
207 |
+
# Microsoft Active Directory under the servicePrincipalName attribute of the
|
208 |
+
# account object specified by the serviceAcctDN parameter. The account object
|
209 |
+
# corresponds to the logon account specified in the CreateService call for this
|
210 |
+
# service instance. If the logon account is a domain user account,
|
211 |
+
# serviceAcctDN must be the distinguished name of the account object in
|
212 |
+
# Active Directory for that user account. If the service's logon account is the
|
213 |
+
# LocalSystem account, serviceAcctDN must be the distinguished name of the
|
214 |
+
# computer account object for the host computer on which the service is
|
215 |
+
# installed. win32api.TranslateNames and win32security.DsCrackNames can
|
216 |
+
# be used to convert a domain\account format name to a distinguished name.
|
217 |
+
def SpnRegister(
|
218 |
+
serviceAcctDN, # DN of the service's logon account
|
219 |
+
spns, # List of SPNs to register
|
220 |
+
operation, # Add, replace, or delete SPNs
|
221 |
+
):
|
222 |
+
assert type(spns) not in [str, str] and hasattr(spns, "__iter__"), (
|
223 |
+
"spns must be a sequence of strings (got %r)" % spns
|
224 |
+
)
|
225 |
+
# Bind to a domain controller.
|
226 |
+
# Get the domain for the current user.
|
227 |
+
samName = win32api.GetUserNameEx(win32api.NameSamCompatible)
|
228 |
+
samName = samName.split("\\", 1)[0]
|
229 |
+
|
230 |
+
if not serviceAcctDN:
|
231 |
+
# Get the SAM account name of the computer object for the server.
|
232 |
+
serviceAcctDN = win32api.GetComputerObjectName(win32con.NameFullyQualifiedDN)
|
233 |
+
logger.debug("SpnRegister using DN '%s'", serviceAcctDN)
|
234 |
+
|
235 |
+
# Get the name of a domain controller in that domain.
|
236 |
+
info = win32security.DsGetDcName(
|
237 |
+
domainName=samName,
|
238 |
+
flags=dscon.DS_IS_FLAT_NAME
|
239 |
+
| dscon.DS_RETURN_DNS_NAME
|
240 |
+
| dscon.DS_DIRECTORY_SERVICE_REQUIRED,
|
241 |
+
)
|
242 |
+
# Bind to the domain controller.
|
243 |
+
handle = win32security.DsBind(info["DomainControllerName"])
|
244 |
+
|
245 |
+
# Write the SPNs to the service account or computer account.
|
246 |
+
logger.debug("DsWriteAccountSpn with spns %s")
|
247 |
+
win32security.DsWriteAccountSpn(
|
248 |
+
handle, # handle to the directory
|
249 |
+
operation, # Add or remove SPN from account's existing SPNs
|
250 |
+
serviceAcctDN, # DN of service account or computer account
|
251 |
+
spns,
|
252 |
+
) # names
|
253 |
+
|
254 |
+
# Unbind the DS in any case (but Python would do it anyway)
|
255 |
+
handle.Close()
|
256 |
+
|
257 |
+
|
258 |
+
def UserChangePassword(username_dn, new_password):
|
259 |
+
# set the password on the account.
|
260 |
+
# Use the distinguished name to bind to the account object.
|
261 |
+
accountPath = "LDAP://" + username_dn
|
262 |
+
user = adsi.ADsGetObject(accountPath, adsi.IID_IADsUser)
|
263 |
+
|
264 |
+
# Set the password on the account.
|
265 |
+
user.SetPassword(new_password)
|
266 |
+
|
267 |
+
|
268 |
+
# functions related to the command-line interface
|
269 |
+
def log(level, msg, *args):
|
270 |
+
if verbose >= level:
|
271 |
+
print(msg % args)
|
272 |
+
|
273 |
+
|
274 |
+
class _NoDefault:
|
275 |
+
pass
|
276 |
+
|
277 |
+
|
278 |
+
def _get_option(po, opt_name, default=_NoDefault):
|
279 |
+
parser, options = po
|
280 |
+
ret = getattr(options, opt_name, default)
|
281 |
+
if not ret and default is _NoDefault:
|
282 |
+
parser.error("The '%s' option must be specified for this operation" % opt_name)
|
283 |
+
if not ret:
|
284 |
+
ret = default
|
285 |
+
return ret
|
286 |
+
|
287 |
+
|
288 |
+
def _option_error(po, why):
|
289 |
+
parser = po[0]
|
290 |
+
parser.error(why)
|
291 |
+
|
292 |
+
|
293 |
+
def do_ScpCreate(po):
|
294 |
+
"""Create a Service Connection Point"""
|
295 |
+
global g_createdSCP
|
296 |
+
scp = ScpCreate(
|
297 |
+
_get_option(po, "binding_string"),
|
298 |
+
_get_option(po, "service_class"),
|
299 |
+
_get_option(po, "account_name_sam", None),
|
300 |
+
keywords=_get_option(po, "keywords", None),
|
301 |
+
)
|
302 |
+
g_createdSCP = scp
|
303 |
+
return scp.distinguishedName
|
304 |
+
|
305 |
+
|
306 |
+
def do_ScpDelete(po):
|
307 |
+
"""Delete a Service Connection Point"""
|
308 |
+
sc = _get_option(po, "service_class")
|
309 |
+
try:
|
310 |
+
ScpDelete(sc)
|
311 |
+
except adsi.error as details:
|
312 |
+
if details[0] != winerror.ERROR_DS_OBJ_NOT_FOUND:
|
313 |
+
raise
|
314 |
+
log(2, "ScpDelete ignoring ERROR_DS_OBJ_NOT_FOUND for service-class '%s'", sc)
|
315 |
+
return sc
|
316 |
+
|
317 |
+
|
318 |
+
def do_SpnCreate(po):
|
319 |
+
"""Create a Service Principal Name"""
|
320 |
+
# The 'service name' is the dn of our scp.
|
321 |
+
if g_createdSCP is None:
|
322 |
+
# Could accept an arg to avoid this?
|
323 |
+
_option_error(po, "ScpCreate must have been specified before SpnCreate")
|
324 |
+
# Create a Service Principal Name"
|
325 |
+
spns = win32security.DsGetSpn(
|
326 |
+
dscon.DS_SPN_SERVICE,
|
327 |
+
_get_option(po, "service_class"),
|
328 |
+
g_createdSCP.distinguishedName,
|
329 |
+
_get_option(po, "port", 0),
|
330 |
+
None,
|
331 |
+
None,
|
332 |
+
)
|
333 |
+
spn = spns[0]
|
334 |
+
log(2, "Created SPN: %s", spn)
|
335 |
+
global g_createdSPNLast
|
336 |
+
g_createdSPNLast = spn
|
337 |
+
g_createdSPNs.append(spn)
|
338 |
+
return spn
|
339 |
+
|
340 |
+
|
341 |
+
def do_SpnRegister(po):
|
342 |
+
"""Register a previously created Service Principal Name"""
|
343 |
+
if not g_createdSPNLast:
|
344 |
+
_option_error(po, "SpnCreate must appear before SpnRegister")
|
345 |
+
|
346 |
+
SpnRegister(
|
347 |
+
_get_option(po, "account_name_dn", None),
|
348 |
+
(g_createdSPNLast,),
|
349 |
+
dscon.DS_SPN_ADD_SPN_OP,
|
350 |
+
)
|
351 |
+
return g_createdSPNLast
|
352 |
+
|
353 |
+
|
354 |
+
def do_SpnUnregister(po):
|
355 |
+
"""Unregister a previously created Service Principal Name"""
|
356 |
+
if not g_createdSPNLast:
|
357 |
+
_option_error(po, "SpnCreate must appear before SpnUnregister")
|
358 |
+
SpnRegister(
|
359 |
+
_get_option(po, "account_name_dn", None),
|
360 |
+
(g_createdSPNLast,),
|
361 |
+
dscon.DS_SPN_DELETE_SPN_OP,
|
362 |
+
)
|
363 |
+
return g_createdSPNLast
|
364 |
+
|
365 |
+
|
366 |
+
def do_UserChangePassword(po):
|
367 |
+
"""Change the password for a specified user"""
|
368 |
+
UserChangePassword(_get_option(po, "account_name_dn"), _get_option(po, "password"))
|
369 |
+
return "Password changed OK"
|
370 |
+
|
371 |
+
|
372 |
+
handlers = (
|
373 |
+
("ScpCreate", do_ScpCreate),
|
374 |
+
("ScpDelete", do_ScpDelete),
|
375 |
+
("SpnCreate", do_SpnCreate),
|
376 |
+
("SpnRegister", do_SpnRegister),
|
377 |
+
("SpnUnregister", do_SpnUnregister),
|
378 |
+
("UserChangePassword", do_UserChangePassword),
|
379 |
+
)
|
380 |
+
|
381 |
+
|
382 |
+
class HelpFormatter(optparse.IndentedHelpFormatter):
|
383 |
+
def format_description(self, description):
|
384 |
+
return description
|
385 |
+
|
386 |
+
|
387 |
+
def main():
|
388 |
+
global verbose
|
389 |
+
_handlers_dict = {}
|
390 |
+
|
391 |
+
arg_descs = []
|
392 |
+
for arg, func in handlers:
|
393 |
+
this_desc = "\n".join(textwrap.wrap(func.__doc__, subsequent_indent=" " * 8))
|
394 |
+
arg_descs.append(" %s: %s" % (arg, this_desc))
|
395 |
+
_handlers_dict[arg.lower()] = func
|
396 |
+
|
397 |
+
description = __doc__ + "\ncommands:\n" + "\n".join(arg_descs) + "\n"
|
398 |
+
|
399 |
+
parser = optparse.OptionParser(
|
400 |
+
usage="%prog [options] command ...",
|
401 |
+
description=description,
|
402 |
+
formatter=HelpFormatter(),
|
403 |
+
)
|
404 |
+
|
405 |
+
parser.add_option(
|
406 |
+
"-v",
|
407 |
+
action="count",
|
408 |
+
dest="verbose",
|
409 |
+
default=1,
|
410 |
+
help="increase the verbosity of status messages",
|
411 |
+
)
|
412 |
+
|
413 |
+
parser.add_option(
|
414 |
+
"-q", "--quiet", action="store_true", help="Don't print any status messages"
|
415 |
+
)
|
416 |
+
|
417 |
+
parser.add_option(
|
418 |
+
"-t",
|
419 |
+
"--test",
|
420 |
+
action="store_true",
|
421 |
+
help="Execute a mini-test suite, providing defaults for most options and args",
|
422 |
+
),
|
423 |
+
|
424 |
+
parser.add_option(
|
425 |
+
"",
|
426 |
+
"--show-tracebacks",
|
427 |
+
action="store_true",
|
428 |
+
help="Show the tracebacks for any exceptions",
|
429 |
+
)
|
430 |
+
|
431 |
+
parser.add_option("", "--service-class", help="The service class name to use")
|
432 |
+
|
433 |
+
parser.add_option(
|
434 |
+
"", "--port", default=0, help="The port number to associate with the SPN"
|
435 |
+
)
|
436 |
+
|
437 |
+
parser.add_option(
|
438 |
+
"", "--binding-string", help="The binding string to use for SCP creation"
|
439 |
+
)
|
440 |
+
|
441 |
+
parser.add_option(
|
442 |
+
"", "--account-name", help="The account name to use (default is LocalSystem)"
|
443 |
+
)
|
444 |
+
|
445 |
+
parser.add_option("", "--password", help="The password to set.")
|
446 |
+
|
447 |
+
parser.add_option(
|
448 |
+
"",
|
449 |
+
"--keyword",
|
450 |
+
action="append",
|
451 |
+
dest="keywords",
|
452 |
+
help="""A keyword to add to the SCP. May be specified
|
453 |
+
multiple times""",
|
454 |
+
)
|
455 |
+
|
456 |
+
parser.add_option(
|
457 |
+
"",
|
458 |
+
"--log-level",
|
459 |
+
help="""The log-level to use - may be a number or a logging
|
460 |
+
module constant""",
|
461 |
+
default=str(logging.WARNING),
|
462 |
+
)
|
463 |
+
|
464 |
+
options, args = parser.parse_args()
|
465 |
+
po = (parser, options)
|
466 |
+
# fixup misc
|
467 |
+
try:
|
468 |
+
options.port = int(options.port)
|
469 |
+
except (TypeError, ValueError):
|
470 |
+
parser.error("--port must be numeric")
|
471 |
+
# fixup log-level
|
472 |
+
try:
|
473 |
+
log_level = int(options.log_level)
|
474 |
+
except (TypeError, ValueError):
|
475 |
+
try:
|
476 |
+
log_level = int(getattr(logging, options.log_level.upper()))
|
477 |
+
except (ValueError, TypeError, AttributeError):
|
478 |
+
parser.error("Invalid --log-level value")
|
479 |
+
try:
|
480 |
+
sl = logger.setLevel
|
481 |
+
# logger is a real logger
|
482 |
+
except AttributeError:
|
483 |
+
# logger is logging module
|
484 |
+
sl = logging.getLogger().setLevel
|
485 |
+
sl(log_level)
|
486 |
+
# Check -q/-v
|
487 |
+
if options.quiet and options.verbose:
|
488 |
+
parser.error("Can't specify --quiet and --verbose")
|
489 |
+
if options.quiet:
|
490 |
+
options.verbose -= 1
|
491 |
+
verbose = options.verbose
|
492 |
+
# --test
|
493 |
+
if options.test:
|
494 |
+
if args:
|
495 |
+
parser.error("Can't specify args with --test")
|
496 |
+
|
497 |
+
args = "ScpDelete ScpCreate SpnCreate SpnRegister SpnUnregister ScpDelete"
|
498 |
+
log(1, "--test - pretending args are:\n %s", args)
|
499 |
+
args = args.split()
|
500 |
+
if not options.service_class:
|
501 |
+
options.service_class = "PythonScpTest"
|
502 |
+
log(2, "--test: --service-class=%s", options.service_class)
|
503 |
+
if not options.keywords:
|
504 |
+
options.keywords = "Python Powered".split()
|
505 |
+
log(2, "--test: --keyword=%s", options.keywords)
|
506 |
+
if not options.binding_string:
|
507 |
+
options.binding_string = "test binding string"
|
508 |
+
log(2, "--test: --binding-string=%s", options.binding_string)
|
509 |
+
|
510 |
+
# check args
|
511 |
+
if not args:
|
512 |
+
parser.error("No command specified (use --help for valid commands)")
|
513 |
+
for arg in args:
|
514 |
+
if arg.lower() not in _handlers_dict:
|
515 |
+
parser.error("Invalid command '%s' (use --help for valid commands)" % arg)
|
516 |
+
|
517 |
+
# Patch up account-name.
|
518 |
+
if options.account_name:
|
519 |
+
log(2, "Translating account name '%s'", options.account_name)
|
520 |
+
options.account_name_sam = win32security.TranslateName(
|
521 |
+
options.account_name, win32api.NameUnknown, win32api.NameSamCompatible
|
522 |
+
)
|
523 |
+
log(2, "NameSamCompatible is '%s'", options.account_name_sam)
|
524 |
+
options.account_name_dn = win32security.TranslateName(
|
525 |
+
options.account_name, win32api.NameUnknown, win32api.NameFullyQualifiedDN
|
526 |
+
)
|
527 |
+
log(2, "NameFullyQualifiedDNis '%s'", options.account_name_dn)
|
528 |
+
|
529 |
+
# do it.
|
530 |
+
for arg in args:
|
531 |
+
handler = _handlers_dict[arg.lower()] # already been validated
|
532 |
+
if handler is None:
|
533 |
+
parser.error("Invalid command '%s'" % arg)
|
534 |
+
err_msg = None
|
535 |
+
try:
|
536 |
+
try:
|
537 |
+
log(2, "Executing '%s'...", arg)
|
538 |
+
result = handler(po)
|
539 |
+
log(1, "%s: %s", arg, result)
|
540 |
+
except:
|
541 |
+
if options.show_tracebacks:
|
542 |
+
print("--show-tracebacks specified - dumping exception")
|
543 |
+
traceback.print_exc()
|
544 |
+
raise
|
545 |
+
except adsi.error as xxx_todo_changeme:
|
546 |
+
(hr, desc, exc, argerr) = xxx_todo_changeme.args
|
547 |
+
if exc:
|
548 |
+
extra_desc = exc[2]
|
549 |
+
else:
|
550 |
+
extra_desc = ""
|
551 |
+
err_msg = desc
|
552 |
+
if extra_desc:
|
553 |
+
err_msg += "\n\t" + extra_desc
|
554 |
+
except win32api.error as xxx_todo_changeme1:
|
555 |
+
(hr, func, msg) = xxx_todo_changeme1.args
|
556 |
+
err_msg = msg
|
557 |
+
if err_msg:
|
558 |
+
log(1, "Command '%s' failed: %s", arg, err_msg)
|
559 |
+
|
560 |
+
|
561 |
+
if __name__ == "__main__":
|
562 |
+
try:
|
563 |
+
main()
|
564 |
+
except KeyboardInterrupt:
|
565 |
+
print("*** Interrupted")
|
MLPY/Lib/site-packages/win32comext/adsi/demos/search.py
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pythoncom
|
2 |
+
import pywintypes
|
3 |
+
import win32security
|
4 |
+
from win32com.adsi import adsi, adsicon
|
5 |
+
from win32com.adsi.adsicon import *
|
6 |
+
|
7 |
+
options = None # set to optparse options object
|
8 |
+
|
9 |
+
ADsTypeNameMap = {}
|
10 |
+
|
11 |
+
|
12 |
+
def getADsTypeName(type_val):
|
13 |
+
# convert integer type to the 'typename' as known in the headerfiles.
|
14 |
+
if not ADsTypeNameMap:
|
15 |
+
for n, v in adsicon.__dict__.items():
|
16 |
+
if n.startswith("ADSTYPE_"):
|
17 |
+
ADsTypeNameMap[v] = n
|
18 |
+
return ADsTypeNameMap.get(type_val, hex(type_val))
|
19 |
+
|
20 |
+
|
21 |
+
def _guid_from_buffer(b):
|
22 |
+
return pywintypes.IID(b, True)
|
23 |
+
|
24 |
+
|
25 |
+
def _sid_from_buffer(b):
|
26 |
+
return str(pywintypes.SID(b))
|
27 |
+
|
28 |
+
|
29 |
+
_null_converter = lambda x: x
|
30 |
+
|
31 |
+
converters = {
|
32 |
+
"objectGUID": _guid_from_buffer,
|
33 |
+
"objectSid": _sid_from_buffer,
|
34 |
+
"instanceType": getADsTypeName,
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
def log(level, msg, *args):
|
39 |
+
if options.verbose >= level:
|
40 |
+
print("log:", msg % args)
|
41 |
+
|
42 |
+
|
43 |
+
def getGC():
|
44 |
+
cont = adsi.ADsOpenObject(
|
45 |
+
"GC:", options.user, options.password, 0, adsi.IID_IADsContainer
|
46 |
+
)
|
47 |
+
enum = adsi.ADsBuildEnumerator(cont)
|
48 |
+
# Only 1 child of the global catalog.
|
49 |
+
for e in enum:
|
50 |
+
gc = e.QueryInterface(adsi.IID_IDirectorySearch)
|
51 |
+
return gc
|
52 |
+
return None
|
53 |
+
|
54 |
+
|
55 |
+
def print_attribute(col_data):
|
56 |
+
prop_name, prop_type, values = col_data
|
57 |
+
if values is not None:
|
58 |
+
log(2, "property '%s' has type '%s'", prop_name, getADsTypeName(prop_type))
|
59 |
+
value = [converters.get(prop_name, _null_converter)(v[0]) for v in values]
|
60 |
+
if len(value) == 1:
|
61 |
+
value = value[0]
|
62 |
+
print(" %s=%r" % (prop_name, value))
|
63 |
+
else:
|
64 |
+
print(" %s is None" % (prop_name,))
|
65 |
+
|
66 |
+
|
67 |
+
def search():
|
68 |
+
gc = getGC()
|
69 |
+
if gc is None:
|
70 |
+
log(0, "Can't find the global catalog")
|
71 |
+
return
|
72 |
+
|
73 |
+
prefs = [(ADS_SEARCHPREF_SEARCH_SCOPE, (ADS_SCOPE_SUBTREE,))]
|
74 |
+
hr, statuses = gc.SetSearchPreference(prefs)
|
75 |
+
log(3, "SetSearchPreference returned %d/%r", hr, statuses)
|
76 |
+
|
77 |
+
if options.attributes:
|
78 |
+
attributes = options.attributes.split(",")
|
79 |
+
else:
|
80 |
+
attributes = None
|
81 |
+
|
82 |
+
h = gc.ExecuteSearch(options.filter, attributes)
|
83 |
+
hr = gc.GetNextRow(h)
|
84 |
+
while hr != S_ADS_NOMORE_ROWS:
|
85 |
+
print("-- new row --")
|
86 |
+
if attributes is None:
|
87 |
+
# Loop over all columns returned
|
88 |
+
while 1:
|
89 |
+
col_name = gc.GetNextColumnName(h)
|
90 |
+
if col_name is None:
|
91 |
+
break
|
92 |
+
data = gc.GetColumn(h, col_name)
|
93 |
+
print_attribute(data)
|
94 |
+
else:
|
95 |
+
# loop over attributes specified.
|
96 |
+
for a in attributes:
|
97 |
+
try:
|
98 |
+
data = gc.GetColumn(h, a)
|
99 |
+
print_attribute(data)
|
100 |
+
except adsi.error as details:
|
101 |
+
if details[0] != E_ADS_COLUMN_NOT_SET:
|
102 |
+
raise
|
103 |
+
print_attribute((a, None, None))
|
104 |
+
hr = gc.GetNextRow(h)
|
105 |
+
gc.CloseSearchHandle(h)
|
106 |
+
|
107 |
+
|
108 |
+
def main():
|
109 |
+
global options
|
110 |
+
from optparse import OptionParser
|
111 |
+
|
112 |
+
parser = OptionParser()
|
113 |
+
parser.add_option(
|
114 |
+
"-f", "--file", dest="filename", help="write report to FILE", metavar="FILE"
|
115 |
+
)
|
116 |
+
parser.add_option(
|
117 |
+
"-v",
|
118 |
+
"--verbose",
|
119 |
+
action="count",
|
120 |
+
default=1,
|
121 |
+
help="increase verbosity of output",
|
122 |
+
)
|
123 |
+
parser.add_option(
|
124 |
+
"-q", "--quiet", action="store_true", help="suppress output messages"
|
125 |
+
)
|
126 |
+
|
127 |
+
parser.add_option("-U", "--user", help="specify the username used to connect")
|
128 |
+
parser.add_option("-P", "--password", help="specify the password used to connect")
|
129 |
+
parser.add_option(
|
130 |
+
"",
|
131 |
+
"--filter",
|
132 |
+
default="(&(objectCategory=person)(objectClass=User))",
|
133 |
+
help="specify the search filter",
|
134 |
+
)
|
135 |
+
parser.add_option(
|
136 |
+
"", "--attributes", help="comma sep'd list of attribute names to print"
|
137 |
+
)
|
138 |
+
|
139 |
+
options, args = parser.parse_args()
|
140 |
+
if options.quiet:
|
141 |
+
if options.verbose != 1:
|
142 |
+
parser.error("Can not use '--verbose' and '--quiet'")
|
143 |
+
options.verbose = 0
|
144 |
+
|
145 |
+
if args:
|
146 |
+
parser.error("You need not specify args")
|
147 |
+
|
148 |
+
search()
|
149 |
+
|
150 |
+
|
151 |
+
if __name__ == "__main__":
|
152 |
+
main()
|
MLPY/Lib/site-packages/win32comext/adsi/demos/test.py
ADDED
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import string
|
2 |
+
import sys
|
3 |
+
|
4 |
+
import pythoncom
|
5 |
+
import win32api
|
6 |
+
from win32com.adsi import *
|
7 |
+
|
8 |
+
verbose_level = 0
|
9 |
+
|
10 |
+
server = "" # Must have trailing /
|
11 |
+
local_name = win32api.GetComputerName()
|
12 |
+
|
13 |
+
|
14 |
+
def DumpRoot():
|
15 |
+
"Dumps the root DSE"
|
16 |
+
path = "LDAP://%srootDSE" % server
|
17 |
+
rootdse = ADsGetObject(path)
|
18 |
+
|
19 |
+
for item in rootdse.Get("SupportedLDAPVersion"):
|
20 |
+
print("%s supports ldap version %s" % (path, item))
|
21 |
+
|
22 |
+
attributes = ["CurrentTime", "defaultNamingContext"]
|
23 |
+
for attr in attributes:
|
24 |
+
val = rootdse.Get(attr)
|
25 |
+
print(" %s=%s" % (attr, val))
|
26 |
+
|
27 |
+
|
28 |
+
###############################################
|
29 |
+
#
|
30 |
+
# Code taken from article titled:
|
31 |
+
# Reading attributeSchema and classSchema Objects
|
32 |
+
def _DumpClass(child):
|
33 |
+
attrs = "Abstract lDAPDisplayName schemaIDGUID schemaNamingContext attributeSyntax oMSyntax"
|
34 |
+
_DumpTheseAttributes(child, string.split(attrs))
|
35 |
+
|
36 |
+
|
37 |
+
def _DumpAttribute(child):
|
38 |
+
attrs = "lDAPDisplayName schemaIDGUID adminDescription adminDisplayName rDNAttID defaultHidingValue defaultObjectCategory systemOnly defaultSecurityDescriptor"
|
39 |
+
_DumpTheseAttributes(child, string.split(attrs))
|
40 |
+
|
41 |
+
|
42 |
+
def _DumpTheseAttributes(child, attrs):
|
43 |
+
for attr in attrs:
|
44 |
+
try:
|
45 |
+
val = child.Get(attr)
|
46 |
+
except pythoncom.com_error as details:
|
47 |
+
continue
|
48 |
+
# ###
|
49 |
+
(hr, msg, exc, arg) = details
|
50 |
+
if exc and exc[2]:
|
51 |
+
msg = exc[2]
|
52 |
+
val = "<Error: %s>" % (msg,)
|
53 |
+
if verbose_level >= 2:
|
54 |
+
print(" %s: %s=%s" % (child.Class, attr, val))
|
55 |
+
|
56 |
+
|
57 |
+
def DumpSchema():
|
58 |
+
"Dumps the default DSE schema"
|
59 |
+
# Bind to rootDSE to get the schemaNamingContext property.
|
60 |
+
path = "LDAP://%srootDSE" % server
|
61 |
+
rootdse = ADsGetObject(path)
|
62 |
+
name = rootdse.Get("schemaNamingContext")
|
63 |
+
|
64 |
+
# Bind to the actual schema container.
|
65 |
+
path = "LDAP://" + server + name
|
66 |
+
print("Binding to", path)
|
67 |
+
ob = ADsGetObject(path)
|
68 |
+
nclasses = nattr = nsub = nunk = 0
|
69 |
+
|
70 |
+
# Enumerate the attribute and class objects in the schema container.
|
71 |
+
for child in ob:
|
72 |
+
# Find out if this is a class, attribute, or subSchema object.
|
73 |
+
class_name = child.Class
|
74 |
+
if class_name == "classSchema":
|
75 |
+
_DumpClass(child)
|
76 |
+
nclasses = nclasses + 1
|
77 |
+
elif class_name == "attributeSchema":
|
78 |
+
_DumpAttribute(child)
|
79 |
+
nattr = nattr + 1
|
80 |
+
elif class_name == "subSchema":
|
81 |
+
nsub = nsub + 1
|
82 |
+
else:
|
83 |
+
print("Unknown class:", class_name)
|
84 |
+
nunk = nunk + 1
|
85 |
+
if verbose_level:
|
86 |
+
print("Processed", nclasses, "classes")
|
87 |
+
print("Processed", nattr, "attributes")
|
88 |
+
print("Processed", nsub, "sub-schema's")
|
89 |
+
print("Processed", nunk, "unknown types")
|
90 |
+
|
91 |
+
|
92 |
+
def _DumpObject(ob, level=0):
|
93 |
+
prefix = " " * level
|
94 |
+
print("%s%s object: %s" % (prefix, ob.Class, ob.Name))
|
95 |
+
# Do the directory object thing
|
96 |
+
try:
|
97 |
+
dir_ob = ADsGetObject(ob.ADsPath, IID_IDirectoryObject)
|
98 |
+
except pythoncom.com_error:
|
99 |
+
dir_ob = None
|
100 |
+
if dir_ob is not None:
|
101 |
+
info = dir_ob.GetObjectInformation()
|
102 |
+
print("%s RDN='%s', ObjectDN='%s'" % (prefix, info.RDN, info.ObjectDN))
|
103 |
+
# Create a list of names to fetch
|
104 |
+
names = ["distinguishedName"]
|
105 |
+
attrs = dir_ob.GetObjectAttributes(names)
|
106 |
+
for attr in attrs:
|
107 |
+
for val, typ in attr.Values:
|
108 |
+
print("%s Attribute '%s' = %s" % (prefix, attr.AttrName, val))
|
109 |
+
|
110 |
+
for child in ob:
|
111 |
+
_DumpObject(child, level + 1)
|
112 |
+
|
113 |
+
|
114 |
+
def DumpAllObjects():
|
115 |
+
"Recursively dump the entire directory!"
|
116 |
+
path = "LDAP://%srootDSE" % server
|
117 |
+
rootdse = ADsGetObject(path)
|
118 |
+
name = rootdse.Get("defaultNamingContext")
|
119 |
+
|
120 |
+
# Bind to the actual schema container.
|
121 |
+
path = "LDAP://" + server + name
|
122 |
+
print("Binding to", path)
|
123 |
+
ob = ADsGetObject(path)
|
124 |
+
|
125 |
+
# Enumerate the attribute and class objects in the schema container.
|
126 |
+
_DumpObject(ob)
|
127 |
+
|
128 |
+
|
129 |
+
##########################################################
|
130 |
+
#
|
131 |
+
# Code taken from article:
|
132 |
+
# Example Code for Enumerating Schema Classes, Attributes, and Syntaxes
|
133 |
+
|
134 |
+
# Fill a map with VT_ datatypes, to give us better names:
|
135 |
+
vt_map = {}
|
136 |
+
for name, val in pythoncom.__dict__.items():
|
137 |
+
if name[:3] == "VT_":
|
138 |
+
vt_map[val] = name
|
139 |
+
|
140 |
+
|
141 |
+
def DumpSchema2():
|
142 |
+
"Dumps the schema using an alternative technique"
|
143 |
+
path = "LDAP://%sschema" % (server,)
|
144 |
+
schema = ADsGetObject(path, IID_IADsContainer)
|
145 |
+
nclass = nprop = nsyntax = 0
|
146 |
+
for item in schema:
|
147 |
+
item_class = string.lower(item.Class)
|
148 |
+
if item_class == "class":
|
149 |
+
items = []
|
150 |
+
if item.Abstract:
|
151 |
+
items.append("Abstract")
|
152 |
+
if item.Auxiliary:
|
153 |
+
items.append("Auxiliary")
|
154 |
+
# if item.Structural: items.append("Structural")
|
155 |
+
desc = string.join(items, ", ")
|
156 |
+
import win32com.util
|
157 |
+
|
158 |
+
iid_name = win32com.util.IIDToInterfaceName(item.PrimaryInterface)
|
159 |
+
if verbose_level >= 2:
|
160 |
+
print(
|
161 |
+
"Class: Name=%s, Flags=%s, Primary Interface=%s"
|
162 |
+
% (item.Name, desc, iid_name)
|
163 |
+
)
|
164 |
+
nclass = nclass + 1
|
165 |
+
elif item_class == "property":
|
166 |
+
if item.MultiValued:
|
167 |
+
val_type = "Multi-Valued"
|
168 |
+
else:
|
169 |
+
val_type = "Single-Valued"
|
170 |
+
if verbose_level >= 2:
|
171 |
+
print("Property: Name=%s, %s" % (item.Name, val_type))
|
172 |
+
nprop = nprop + 1
|
173 |
+
elif item_class == "syntax":
|
174 |
+
data_type = vt_map.get(item.OleAutoDataType, "<unknown type>")
|
175 |
+
if verbose_level >= 2:
|
176 |
+
print("Syntax: Name=%s, Datatype = %s" % (item.Name, data_type))
|
177 |
+
nsyntax = nsyntax + 1
|
178 |
+
if verbose_level >= 1:
|
179 |
+
print("Processed", nclass, "classes")
|
180 |
+
print("Processed", nprop, "properties")
|
181 |
+
print("Processed", nsyntax, "syntax items")
|
182 |
+
|
183 |
+
|
184 |
+
def DumpGC():
|
185 |
+
"Dumps the GC: object (whatever that is!)"
|
186 |
+
ob = ADsGetObject("GC:", IID_IADsContainer)
|
187 |
+
for sub_ob in ob:
|
188 |
+
print("GC ob: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath))
|
189 |
+
|
190 |
+
|
191 |
+
def DumpLocalUsers():
|
192 |
+
"Dumps the local machine users"
|
193 |
+
path = "WinNT://%s,computer" % (local_name,)
|
194 |
+
ob = ADsGetObject(path, IID_IADsContainer)
|
195 |
+
ob.put_Filter(["User", "Group"])
|
196 |
+
for sub_ob in ob:
|
197 |
+
print("User/Group: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath))
|
198 |
+
|
199 |
+
|
200 |
+
def DumpLocalGroups():
|
201 |
+
"Dumps the local machine groups"
|
202 |
+
path = "WinNT://%s,computer" % (local_name,)
|
203 |
+
ob = ADsGetObject(path, IID_IADsContainer)
|
204 |
+
|
205 |
+
ob.put_Filter(["Group"])
|
206 |
+
for sub_ob in ob:
|
207 |
+
print("Group: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath))
|
208 |
+
# get the members
|
209 |
+
members = sub_ob.Members()
|
210 |
+
for member in members:
|
211 |
+
print(" Group member: %s (%s)" % (member.Name, member.ADsPath))
|
212 |
+
|
213 |
+
|
214 |
+
def usage(tests):
|
215 |
+
import os
|
216 |
+
|
217 |
+
print("Usage: %s [-s server ] [-v] [Test ...]" % os.path.basename(sys.argv[0]))
|
218 |
+
print(" -v : Verbose - print more information")
|
219 |
+
print(" -s : server - execute the tests against the named server")
|
220 |
+
print("where Test is one of:")
|
221 |
+
for t in tests:
|
222 |
+
print(t.__name__, ":", t.__doc__)
|
223 |
+
print()
|
224 |
+
print("If not tests are specified, all tests are run")
|
225 |
+
sys.exit(1)
|
226 |
+
|
227 |
+
|
228 |
+
def main():
|
229 |
+
import getopt
|
230 |
+
import traceback
|
231 |
+
|
232 |
+
tests = []
|
233 |
+
for ob in globals().values():
|
234 |
+
if type(ob) == type(main) and ob.__doc__:
|
235 |
+
tests.append(ob)
|
236 |
+
opts, args = getopt.getopt(sys.argv[1:], "s:hv")
|
237 |
+
for opt, val in opts:
|
238 |
+
if opt == "-s":
|
239 |
+
if val[-1] not in "\\/":
|
240 |
+
val = val + "/"
|
241 |
+
global server
|
242 |
+
server = val
|
243 |
+
if opt == "-h":
|
244 |
+
usage(tests)
|
245 |
+
if opt == "-v":
|
246 |
+
global verbose_level
|
247 |
+
verbose_level = verbose_level + 1
|
248 |
+
|
249 |
+
if len(args) == 0:
|
250 |
+
print("Running all tests - use '-h' to see command-line options...")
|
251 |
+
dotests = tests
|
252 |
+
else:
|
253 |
+
dotests = []
|
254 |
+
for arg in args:
|
255 |
+
for t in tests:
|
256 |
+
if t.__name__ == arg:
|
257 |
+
dotests.append(t)
|
258 |
+
break
|
259 |
+
else:
|
260 |
+
print("Test '%s' unknown - skipping" % arg)
|
261 |
+
if not len(dotests):
|
262 |
+
print("Nothing to do!")
|
263 |
+
usage(tests)
|
264 |
+
for test in dotests:
|
265 |
+
try:
|
266 |
+
test()
|
267 |
+
except:
|
268 |
+
print("Test %s failed" % test.__name__)
|
269 |
+
traceback.print_exc()
|
270 |
+
|
271 |
+
|
272 |
+
if __name__ == "__main__":
|
273 |
+
main()
|
MLPY/Lib/site-packages/win32comext/authorization/__init__.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This is a python package
|
2 |
+
# __PackageSupportBuildPath__ not needed for distutil based builds,
|
3 |
+
# but not everyone is there yet.
|
4 |
+
import win32com
|
5 |
+
|
6 |
+
win32com.__PackageSupportBuildPath__(__path__)
|
MLPY/Lib/site-packages/win32comext/authorization/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (233 Bytes). View file
|
|
MLPY/Lib/site-packages/win32comext/authorization/authorization.pyd
ADDED
Binary file (29.7 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/authorization/demos/EditSecurity.py
ADDED
@@ -0,0 +1,255 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
import ntsecuritycon
|
4 |
+
import pythoncom
|
5 |
+
import win32api
|
6 |
+
import win32com.server.policy
|
7 |
+
import win32con
|
8 |
+
import win32security
|
9 |
+
from ntsecuritycon import (
|
10 |
+
CONTAINER_INHERIT_ACE,
|
11 |
+
FILE_ALL_ACCESS,
|
12 |
+
FILE_APPEND_DATA,
|
13 |
+
FILE_GENERIC_EXECUTE,
|
14 |
+
FILE_GENERIC_READ,
|
15 |
+
FILE_GENERIC_WRITE,
|
16 |
+
FILE_READ_ATTRIBUTES,
|
17 |
+
FILE_READ_DATA,
|
18 |
+
FILE_READ_EA,
|
19 |
+
FILE_WRITE_ATTRIBUTES,
|
20 |
+
FILE_WRITE_DATA,
|
21 |
+
FILE_WRITE_EA,
|
22 |
+
INHERIT_ONLY_ACE,
|
23 |
+
OBJECT_INHERIT_ACE,
|
24 |
+
PSPCB_SI_INITDIALOG,
|
25 |
+
READ_CONTROL,
|
26 |
+
SI_ACCESS_CONTAINER,
|
27 |
+
SI_ACCESS_GENERAL,
|
28 |
+
SI_ACCESS_PROPERTY,
|
29 |
+
SI_ACCESS_SPECIFIC,
|
30 |
+
SI_ADVANCED,
|
31 |
+
SI_CONTAINER,
|
32 |
+
SI_EDIT_ALL,
|
33 |
+
SI_EDIT_AUDITS,
|
34 |
+
SI_EDIT_PROPERTIES,
|
35 |
+
SI_PAGE_ADVPERM,
|
36 |
+
SI_PAGE_AUDIT,
|
37 |
+
SI_PAGE_OWNER,
|
38 |
+
SI_PAGE_PERM,
|
39 |
+
SI_PAGE_TITLE,
|
40 |
+
SI_RESET,
|
41 |
+
STANDARD_RIGHTS_EXECUTE,
|
42 |
+
STANDARD_RIGHTS_READ,
|
43 |
+
STANDARD_RIGHTS_WRITE,
|
44 |
+
SYNCHRONIZE,
|
45 |
+
WRITE_DAC,
|
46 |
+
WRITE_OWNER,
|
47 |
+
)
|
48 |
+
from pythoncom import IID_NULL
|
49 |
+
from win32com.authorization import authorization
|
50 |
+
from win32com.shell.shellcon import ( # # Msg parameter to PropertySheetPageCallback
|
51 |
+
PSPCB_CREATE,
|
52 |
+
PSPCB_RELEASE,
|
53 |
+
)
|
54 |
+
from win32security import CONTAINER_INHERIT_ACE, INHERIT_ONLY_ACE, OBJECT_INHERIT_ACE
|
55 |
+
|
56 |
+
|
57 |
+
class SecurityInformation(win32com.server.policy.DesignatedWrapPolicy):
|
58 |
+
_com_interfaces_ = [authorization.IID_ISecurityInformation]
|
59 |
+
_public_methods_ = [
|
60 |
+
"GetObjectInformation",
|
61 |
+
"GetSecurity",
|
62 |
+
"SetSecurity",
|
63 |
+
"GetAccessRights",
|
64 |
+
"GetInheritTypes",
|
65 |
+
"MapGeneric",
|
66 |
+
"PropertySheetPageCallback",
|
67 |
+
]
|
68 |
+
|
69 |
+
def __init__(self, FileName):
|
70 |
+
self.FileName = FileName
|
71 |
+
self._wrap_(self)
|
72 |
+
|
73 |
+
def GetObjectInformation(self):
|
74 |
+
"""Identifies object whose security will be modified, and determines options available
|
75 |
+
to the end user"""
|
76 |
+
flags = SI_ADVANCED | SI_EDIT_ALL | SI_PAGE_TITLE | SI_RESET
|
77 |
+
if os.path.isdir(self.FileName):
|
78 |
+
flags |= SI_CONTAINER
|
79 |
+
hinstance = 0 ## handle to module containing string resources
|
80 |
+
servername = "" ## name of authenticating server if not local machine
|
81 |
+
objectname = os.path.split(self.FileName)[1]
|
82 |
+
pagetitle = "Python ACL Editor"
|
83 |
+
if os.path.isdir(self.FileName):
|
84 |
+
pagetitle += " (dir)"
|
85 |
+
else:
|
86 |
+
pagetitle += " (file)"
|
87 |
+
objecttype = IID_NULL
|
88 |
+
return flags, hinstance, servername, objectname, pagetitle, objecttype
|
89 |
+
|
90 |
+
def GetSecurity(self, requestedinfo, bdefault):
|
91 |
+
"""Requests the existing permissions for object"""
|
92 |
+
if bdefault:
|
93 |
+
## This is invoked if the 'Default' button is pressed (only present if SI_RESET is passed
|
94 |
+
## with the flags in GetObjectInfo). Passing an empty SD with a NULL Dacl
|
95 |
+
## should cause inherited ACL from parent dir or default dacl from user's token to be used
|
96 |
+
return win32security.SECURITY_DESCRIPTOR()
|
97 |
+
else:
|
98 |
+
## GetFileSecurity sometimes fails to return flags indicating that an ACE is inherited
|
99 |
+
return win32security.GetNamedSecurityInfo(
|
100 |
+
self.FileName, win32security.SE_FILE_OBJECT, requestedinfo
|
101 |
+
)
|
102 |
+
|
103 |
+
def SetSecurity(self, requestedinfo, sd):
|
104 |
+
"""Applies permissions to the object"""
|
105 |
+
owner = sd.GetSecurityDescriptorOwner()
|
106 |
+
group = sd.GetSecurityDescriptorGroup()
|
107 |
+
dacl = sd.GetSecurityDescriptorDacl()
|
108 |
+
sacl = sd.GetSecurityDescriptorSacl()
|
109 |
+
win32security.SetNamedSecurityInfo(
|
110 |
+
self.FileName,
|
111 |
+
win32security.SE_FILE_OBJECT,
|
112 |
+
requestedinfo,
|
113 |
+
owner,
|
114 |
+
group,
|
115 |
+
dacl,
|
116 |
+
sacl,
|
117 |
+
)
|
118 |
+
## should also handle recursive operations here
|
119 |
+
|
120 |
+
def GetAccessRights(self, objecttype, flags):
|
121 |
+
"""Returns a tuple of (AccessRights, DefaultAccess), where AccessRights is a sequence of tuples representing
|
122 |
+
SI_ACCESS structs, containing (guid, access mask, Name, flags). DefaultAccess indicates which of the
|
123 |
+
AccessRights will be used initially when a new ACE is added (zero based).
|
124 |
+
Flags can contain SI_ACCESS_SPECIFIC,SI_ACCESS_GENERAL,SI_ACCESS_CONTAINER,SI_ACCESS_PROPERTY,
|
125 |
+
CONTAINER_INHERIT_ACE,INHERIT_ONLY_ACE,OBJECT_INHERIT_ACE
|
126 |
+
"""
|
127 |
+
## input flags: SI_ADVANCED,SI_EDIT_AUDITS,SI_EDIT_PROPERTIES indicating which property sheet is requesting the rights
|
128 |
+
if (objecttype is not None) and (objecttype != IID_NULL):
|
129 |
+
## Should not be true for file objects. Usually only used with DS objects that support security for
|
130 |
+
## their properties
|
131 |
+
raise NotImplementedError("Object type is not supported")
|
132 |
+
|
133 |
+
if os.path.isdir(self.FileName):
|
134 |
+
file_append_data_desc = "Create subfolders"
|
135 |
+
file_write_data_desc = "Create Files"
|
136 |
+
else:
|
137 |
+
file_append_data_desc = "Append data"
|
138 |
+
file_write_data_desc = "Write data"
|
139 |
+
|
140 |
+
accessrights = [
|
141 |
+
(
|
142 |
+
IID_NULL,
|
143 |
+
FILE_GENERIC_READ,
|
144 |
+
"Generic read",
|
145 |
+
SI_ACCESS_GENERAL
|
146 |
+
| SI_ACCESS_SPECIFIC
|
147 |
+
| OBJECT_INHERIT_ACE
|
148 |
+
| CONTAINER_INHERIT_ACE,
|
149 |
+
),
|
150 |
+
(
|
151 |
+
IID_NULL,
|
152 |
+
FILE_GENERIC_WRITE,
|
153 |
+
"Generic write",
|
154 |
+
SI_ACCESS_GENERAL
|
155 |
+
| SI_ACCESS_SPECIFIC
|
156 |
+
| OBJECT_INHERIT_ACE
|
157 |
+
| CONTAINER_INHERIT_ACE,
|
158 |
+
),
|
159 |
+
(
|
160 |
+
IID_NULL,
|
161 |
+
win32con.DELETE,
|
162 |
+
"Delete",
|
163 |
+
SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
|
164 |
+
),
|
165 |
+
(
|
166 |
+
IID_NULL,
|
167 |
+
WRITE_OWNER,
|
168 |
+
"Change owner",
|
169 |
+
SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
|
170 |
+
),
|
171 |
+
(
|
172 |
+
IID_NULL,
|
173 |
+
READ_CONTROL,
|
174 |
+
"Read Permissions",
|
175 |
+
SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
|
176 |
+
),
|
177 |
+
(
|
178 |
+
IID_NULL,
|
179 |
+
WRITE_DAC,
|
180 |
+
"Change permissions",
|
181 |
+
SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
|
182 |
+
),
|
183 |
+
(
|
184 |
+
IID_NULL,
|
185 |
+
FILE_APPEND_DATA,
|
186 |
+
file_append_data_desc,
|
187 |
+
SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
|
188 |
+
),
|
189 |
+
(
|
190 |
+
IID_NULL,
|
191 |
+
FILE_WRITE_DATA,
|
192 |
+
file_write_data_desc,
|
193 |
+
SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
|
194 |
+
),
|
195 |
+
]
|
196 |
+
return (accessrights, 0)
|
197 |
+
|
198 |
+
def MapGeneric(self, guid, aceflags, mask):
|
199 |
+
"""Converts generic access rights to specific rights. This implementation uses standard file system rights,
|
200 |
+
but you can map them any way that suits your application.
|
201 |
+
"""
|
202 |
+
return win32security.MapGenericMask(
|
203 |
+
mask,
|
204 |
+
(
|
205 |
+
FILE_GENERIC_READ,
|
206 |
+
FILE_GENERIC_WRITE,
|
207 |
+
FILE_GENERIC_EXECUTE,
|
208 |
+
FILE_ALL_ACCESS,
|
209 |
+
),
|
210 |
+
)
|
211 |
+
|
212 |
+
def GetInheritTypes(self):
|
213 |
+
"""Specifies which types of ACE inheritance are supported.
|
214 |
+
Returns a sequence of tuples representing SI_INHERIT_TYPE structs, containing
|
215 |
+
(object type guid, inheritance flags, display name). Guid is usually only used with
|
216 |
+
Directory Service objects.
|
217 |
+
"""
|
218 |
+
return (
|
219 |
+
(IID_NULL, 0, "Only current object"),
|
220 |
+
(IID_NULL, OBJECT_INHERIT_ACE, "Files inherit permissions"),
|
221 |
+
(IID_NULL, CONTAINER_INHERIT_ACE, "Sub Folders inherit permissions"),
|
222 |
+
(
|
223 |
+
IID_NULL,
|
224 |
+
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
|
225 |
+
"Files and subfolders",
|
226 |
+
),
|
227 |
+
)
|
228 |
+
|
229 |
+
def PropertySheetPageCallback(self, hwnd, msg, pagetype):
|
230 |
+
"""Invoked each time a property sheet page is created or destroyed."""
|
231 |
+
## page types from SI_PAGE_TYPE enum: SI_PAGE_PERM SI_PAGE_ADVPERM SI_PAGE_AUDIT SI_PAGE_OWNER
|
232 |
+
## msg: PSPCB_CREATE, PSPCB_RELEASE, PSPCB_SI_INITDIALOG
|
233 |
+
return None
|
234 |
+
|
235 |
+
def EditSecurity(self, owner_hwnd=0):
|
236 |
+
"""Creates an ACL editor dialog based on parameters returned by interface methods"""
|
237 |
+
isi = pythoncom.WrapObject(
|
238 |
+
self, authorization.IID_ISecurityInformation, pythoncom.IID_IUnknown
|
239 |
+
)
|
240 |
+
authorization.EditSecurity(owner_hwnd, isi)
|
241 |
+
|
242 |
+
|
243 |
+
## folder permissions
|
244 |
+
temp_dir = win32api.GetTempPath()
|
245 |
+
dir_name = win32api.GetTempFileName(temp_dir, "isi")[0]
|
246 |
+
print(dir_name)
|
247 |
+
os.remove(dir_name)
|
248 |
+
os.mkdir(dir_name)
|
249 |
+
si = SecurityInformation(dir_name)
|
250 |
+
si.EditSecurity()
|
251 |
+
|
252 |
+
## file permissions
|
253 |
+
fname = win32api.GetTempFileName(dir_name, "isi")[0]
|
254 |
+
si = SecurityInformation(fname)
|
255 |
+
si.EditSecurity()
|
MLPY/Lib/site-packages/win32comext/authorization/demos/EditServiceSecurity.py
ADDED
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Implements a permissions editor for services.
|
3 |
+
Service can be specified as plain name for local machine,
|
4 |
+
or as a remote service of the form \\machinename\service
|
5 |
+
"""
|
6 |
+
|
7 |
+
import os
|
8 |
+
|
9 |
+
import ntsecuritycon
|
10 |
+
import pythoncom
|
11 |
+
import win32api
|
12 |
+
import win32com.server.policy
|
13 |
+
import win32con
|
14 |
+
import win32security
|
15 |
+
import win32service
|
16 |
+
from win32com.authorization import authorization
|
17 |
+
|
18 |
+
SERVICE_GENERIC_EXECUTE = (
|
19 |
+
win32service.SERVICE_START
|
20 |
+
| win32service.SERVICE_STOP
|
21 |
+
| win32service.SERVICE_PAUSE_CONTINUE
|
22 |
+
| win32service.SERVICE_USER_DEFINED_CONTROL
|
23 |
+
)
|
24 |
+
SERVICE_GENERIC_READ = (
|
25 |
+
win32service.SERVICE_QUERY_CONFIG
|
26 |
+
| win32service.SERVICE_QUERY_STATUS
|
27 |
+
| win32service.SERVICE_INTERROGATE
|
28 |
+
| win32service.SERVICE_ENUMERATE_DEPENDENTS
|
29 |
+
)
|
30 |
+
SERVICE_GENERIC_WRITE = win32service.SERVICE_CHANGE_CONFIG
|
31 |
+
|
32 |
+
from ntsecuritycon import (
|
33 |
+
CONTAINER_INHERIT_ACE,
|
34 |
+
INHERIT_ONLY_ACE,
|
35 |
+
OBJECT_INHERIT_ACE,
|
36 |
+
PSPCB_SI_INITDIALOG,
|
37 |
+
READ_CONTROL,
|
38 |
+
SI_ACCESS_CONTAINER,
|
39 |
+
SI_ACCESS_GENERAL,
|
40 |
+
SI_ACCESS_PROPERTY,
|
41 |
+
SI_ACCESS_SPECIFIC,
|
42 |
+
SI_ADVANCED,
|
43 |
+
SI_CONTAINER,
|
44 |
+
SI_EDIT_ALL,
|
45 |
+
SI_EDIT_AUDITS,
|
46 |
+
SI_EDIT_PROPERTIES,
|
47 |
+
SI_PAGE_ADVPERM,
|
48 |
+
SI_PAGE_AUDIT,
|
49 |
+
SI_PAGE_OWNER,
|
50 |
+
SI_PAGE_PERM,
|
51 |
+
SI_PAGE_TITLE,
|
52 |
+
SI_RESET,
|
53 |
+
STANDARD_RIGHTS_EXECUTE,
|
54 |
+
STANDARD_RIGHTS_READ,
|
55 |
+
STANDARD_RIGHTS_WRITE,
|
56 |
+
WRITE_DAC,
|
57 |
+
WRITE_OWNER,
|
58 |
+
)
|
59 |
+
from pythoncom import IID_NULL
|
60 |
+
from win32com.shell.shellcon import ( # # Msg parameter to PropertySheetPageCallback
|
61 |
+
PSPCB_CREATE,
|
62 |
+
PSPCB_RELEASE,
|
63 |
+
)
|
64 |
+
from win32security import CONTAINER_INHERIT_ACE, INHERIT_ONLY_ACE, OBJECT_INHERIT_ACE
|
65 |
+
|
66 |
+
|
67 |
+
class ServiceSecurity(win32com.server.policy.DesignatedWrapPolicy):
|
68 |
+
_com_interfaces_ = [authorization.IID_ISecurityInformation]
|
69 |
+
_public_methods_ = [
|
70 |
+
"GetObjectInformation",
|
71 |
+
"GetSecurity",
|
72 |
+
"SetSecurity",
|
73 |
+
"GetAccessRights",
|
74 |
+
"GetInheritTypes",
|
75 |
+
"MapGeneric",
|
76 |
+
"PropertySheetPageCallback",
|
77 |
+
]
|
78 |
+
|
79 |
+
def __init__(self, ServiceName):
|
80 |
+
self.ServiceName = ServiceName
|
81 |
+
self._wrap_(self)
|
82 |
+
|
83 |
+
def GetObjectInformation(self):
|
84 |
+
"""Identifies object whose security will be modified, and determines options available
|
85 |
+
to the end user"""
|
86 |
+
flags = SI_ADVANCED | SI_EDIT_ALL | SI_PAGE_TITLE | SI_RESET
|
87 |
+
hinstance = 0 ## handle to module containing string resources
|
88 |
+
servername = "" ## name of authenticating server if not local machine
|
89 |
+
|
90 |
+
## service name can contain remote machine name of the form \\Server\ServiceName
|
91 |
+
objectname = os.path.split(self.ServiceName)[1]
|
92 |
+
pagetitle = "Service Permissions for " + self.ServiceName
|
93 |
+
objecttype = IID_NULL
|
94 |
+
return flags, hinstance, servername, objectname, pagetitle, objecttype
|
95 |
+
|
96 |
+
def GetSecurity(self, requestedinfo, bdefault):
|
97 |
+
"""Requests the existing permissions for object"""
|
98 |
+
if bdefault:
|
99 |
+
return win32security.SECURITY_DESCRIPTOR()
|
100 |
+
else:
|
101 |
+
return win32security.GetNamedSecurityInfo(
|
102 |
+
self.ServiceName, win32security.SE_SERVICE, requestedinfo
|
103 |
+
)
|
104 |
+
|
105 |
+
def SetSecurity(self, requestedinfo, sd):
|
106 |
+
"""Applies permissions to the object"""
|
107 |
+
owner = sd.GetSecurityDescriptorOwner()
|
108 |
+
group = sd.GetSecurityDescriptorGroup()
|
109 |
+
dacl = sd.GetSecurityDescriptorDacl()
|
110 |
+
sacl = sd.GetSecurityDescriptorSacl()
|
111 |
+
win32security.SetNamedSecurityInfo(
|
112 |
+
self.ServiceName,
|
113 |
+
win32security.SE_SERVICE,
|
114 |
+
requestedinfo,
|
115 |
+
owner,
|
116 |
+
group,
|
117 |
+
dacl,
|
118 |
+
sacl,
|
119 |
+
)
|
120 |
+
|
121 |
+
def GetAccessRights(self, objecttype, flags):
|
122 |
+
"""Returns a tuple of (AccessRights, DefaultAccess), where AccessRights is a sequence of tuples representing
|
123 |
+
SI_ACCESS structs, containing (guid, access mask, Name, flags). DefaultAccess indicates which of the
|
124 |
+
AccessRights will be used initially when a new ACE is added (zero based).
|
125 |
+
Flags can contain SI_ACCESS_SPECIFIC,SI_ACCESS_GENERAL,SI_ACCESS_CONTAINER,SI_ACCESS_PROPERTY,
|
126 |
+
CONTAINER_INHERIT_ACE,INHERIT_ONLY_ACE,OBJECT_INHERIT_ACE
|
127 |
+
"""
|
128 |
+
## input flags: SI_ADVANCED,SI_EDIT_AUDITS,SI_EDIT_PROPERTIES indicating which property sheet is requesting the rights
|
129 |
+
if (objecttype is not None) and (objecttype != IID_NULL):
|
130 |
+
## Not relevent for services
|
131 |
+
raise NotImplementedError("Object type is not supported")
|
132 |
+
|
133 |
+
## ???? for some reason, the DACL for a service will not retain ACCESS_SYSTEM_SECURITY in an ACE ????
|
134 |
+
## (IID_NULL, win32con.ACCESS_SYSTEM_SECURITY, 'View/change audit settings', SI_ACCESS_SPECIFIC),
|
135 |
+
|
136 |
+
accessrights = [
|
137 |
+
(
|
138 |
+
IID_NULL,
|
139 |
+
win32service.SERVICE_ALL_ACCESS,
|
140 |
+
"Full control",
|
141 |
+
SI_ACCESS_GENERAL,
|
142 |
+
),
|
143 |
+
(IID_NULL, SERVICE_GENERIC_READ, "Generic read", SI_ACCESS_GENERAL),
|
144 |
+
(IID_NULL, SERVICE_GENERIC_WRITE, "Generic write", SI_ACCESS_GENERAL),
|
145 |
+
(
|
146 |
+
IID_NULL,
|
147 |
+
SERVICE_GENERIC_EXECUTE,
|
148 |
+
"Start/Stop/Pause service",
|
149 |
+
SI_ACCESS_GENERAL,
|
150 |
+
),
|
151 |
+
(IID_NULL, READ_CONTROL, "Read Permissions", SI_ACCESS_GENERAL),
|
152 |
+
(IID_NULL, WRITE_DAC, "Change permissions", SI_ACCESS_GENERAL),
|
153 |
+
(IID_NULL, WRITE_OWNER, "Change owner", SI_ACCESS_GENERAL),
|
154 |
+
(IID_NULL, win32con.DELETE, "Delete service", SI_ACCESS_GENERAL),
|
155 |
+
(IID_NULL, win32service.SERVICE_START, "Start service", SI_ACCESS_SPECIFIC),
|
156 |
+
(IID_NULL, win32service.SERVICE_STOP, "Stop service", SI_ACCESS_SPECIFIC),
|
157 |
+
(
|
158 |
+
IID_NULL,
|
159 |
+
win32service.SERVICE_PAUSE_CONTINUE,
|
160 |
+
"Pause/unpause service",
|
161 |
+
SI_ACCESS_SPECIFIC,
|
162 |
+
),
|
163 |
+
(
|
164 |
+
IID_NULL,
|
165 |
+
win32service.SERVICE_USER_DEFINED_CONTROL,
|
166 |
+
"Execute user defined operations",
|
167 |
+
SI_ACCESS_SPECIFIC,
|
168 |
+
),
|
169 |
+
(
|
170 |
+
IID_NULL,
|
171 |
+
win32service.SERVICE_QUERY_CONFIG,
|
172 |
+
"Read configuration",
|
173 |
+
SI_ACCESS_SPECIFIC,
|
174 |
+
),
|
175 |
+
(
|
176 |
+
IID_NULL,
|
177 |
+
win32service.SERVICE_CHANGE_CONFIG,
|
178 |
+
"Change configuration",
|
179 |
+
SI_ACCESS_SPECIFIC,
|
180 |
+
),
|
181 |
+
(
|
182 |
+
IID_NULL,
|
183 |
+
win32service.SERVICE_ENUMERATE_DEPENDENTS,
|
184 |
+
"List dependent services",
|
185 |
+
SI_ACCESS_SPECIFIC,
|
186 |
+
),
|
187 |
+
(
|
188 |
+
IID_NULL,
|
189 |
+
win32service.SERVICE_QUERY_STATUS,
|
190 |
+
"Query status",
|
191 |
+
SI_ACCESS_SPECIFIC,
|
192 |
+
),
|
193 |
+
(
|
194 |
+
IID_NULL,
|
195 |
+
win32service.SERVICE_INTERROGATE,
|
196 |
+
"Query status (immediate)",
|
197 |
+
SI_ACCESS_SPECIFIC,
|
198 |
+
),
|
199 |
+
]
|
200 |
+
return (accessrights, 0)
|
201 |
+
|
202 |
+
def MapGeneric(self, guid, aceflags, mask):
|
203 |
+
"""Converts generic access rights to specific rights."""
|
204 |
+
return win32security.MapGenericMask(
|
205 |
+
mask,
|
206 |
+
(
|
207 |
+
SERVICE_GENERIC_READ,
|
208 |
+
SERVICE_GENERIC_WRITE,
|
209 |
+
SERVICE_GENERIC_EXECUTE,
|
210 |
+
win32service.SERVICE_ALL_ACCESS,
|
211 |
+
),
|
212 |
+
)
|
213 |
+
|
214 |
+
def GetInheritTypes(self):
|
215 |
+
"""Specifies which types of ACE inheritance are supported.
|
216 |
+
Services don't use any inheritance
|
217 |
+
"""
|
218 |
+
return ((IID_NULL, 0, "Only current object"),)
|
219 |
+
|
220 |
+
def PropertySheetPageCallback(self, hwnd, msg, pagetype):
|
221 |
+
"""Invoked each time a property sheet page is created or destroyed."""
|
222 |
+
## page types from SI_PAGE_TYPE enum: SI_PAGE_PERM SI_PAGE_ADVPERM SI_PAGE_AUDIT SI_PAGE_OWNER
|
223 |
+
## msg: PSPCB_CREATE, PSPCB_RELEASE, PSPCB_SI_INITDIALOG
|
224 |
+
return None
|
225 |
+
|
226 |
+
def EditSecurity(self, owner_hwnd=0):
|
227 |
+
"""Creates an ACL editor dialog based on parameters returned by interface methods"""
|
228 |
+
isi = pythoncom.WrapObject(
|
229 |
+
self, authorization.IID_ISecurityInformation, pythoncom.IID_IUnknown
|
230 |
+
)
|
231 |
+
authorization.EditSecurity(owner_hwnd, isi)
|
232 |
+
|
233 |
+
|
234 |
+
if __name__ == "__main__":
|
235 |
+
# Find the first service on local machine and edit its permissions
|
236 |
+
scm = win32service.OpenSCManager(
|
237 |
+
None, None, win32service.SC_MANAGER_ENUMERATE_SERVICE
|
238 |
+
)
|
239 |
+
svcs = win32service.EnumServicesStatus(scm)
|
240 |
+
win32service.CloseServiceHandle(scm)
|
241 |
+
si = ServiceSecurity(svcs[0][0])
|
242 |
+
si.EditSecurity()
|
MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditSecurity.cpython-39.pyc
ADDED
Binary file (6.49 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditServiceSecurity.cpython-39.pyc
ADDED
Binary file (6.34 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axcontrol/__init__.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# See if we have a special directory for the binaries (for developers)
|
2 |
+
import win32com
|
3 |
+
|
4 |
+
win32com.__PackageSupportBuildPath__(__path__)
|
MLPY/Lib/site-packages/win32comext/axcontrol/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (229 Bytes). View file
|
|
MLPY/Lib/site-packages/win32comext/axcontrol/axcontrol.pyd
ADDED
Binary file (144 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__init__.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# See if we have a special directory for the binaries (for developers)
|
2 |
+
import win32com
|
3 |
+
|
4 |
+
win32com.__PackageSupportBuildPath__(__path__)
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (227 Bytes). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/adb.cpython-39.pyc
ADDED
Binary file (13.1 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/codecontainer.cpython-39.pyc
ADDED
Binary file (7.8 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/contexts.cpython-39.pyc
ADDED
Binary file (2.32 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/debugger.cpython-39.pyc
ADDED
Binary file (7.29 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/documents.cpython-39.pyc
ADDED
Binary file (5.04 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/dump.cpython-39.pyc
ADDED
Binary file (1.67 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/expressions.cpython-39.pyc
ADDED
Binary file (6.89 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/gateways.cpython-39.pyc
ADDED
Binary file (22.9 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/stackframe.cpython-39.pyc
ADDED
Binary file (5.67 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/util.cpython-39.pyc
ADDED
Binary file (3.31 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/adb.py
ADDED
@@ -0,0 +1,480 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""The glue between the Python debugger interface and the Active Debugger interface
|
2 |
+
"""
|
3 |
+
import _thread
|
4 |
+
import bdb
|
5 |
+
import os
|
6 |
+
import sys
|
7 |
+
import traceback
|
8 |
+
|
9 |
+
import pythoncom
|
10 |
+
import win32api
|
11 |
+
import win32com.client.connect
|
12 |
+
from win32com.axdebug.util import _wrap, _wrap_remove, trace
|
13 |
+
from win32com.server.util import unwrap
|
14 |
+
|
15 |
+
from . import axdebug, gateways, stackframe
|
16 |
+
|
17 |
+
|
18 |
+
def fnull(*args):
|
19 |
+
pass
|
20 |
+
|
21 |
+
|
22 |
+
try:
|
23 |
+
os.environ["DEBUG_AXDEBUG"]
|
24 |
+
debugging = 1
|
25 |
+
except KeyError:
|
26 |
+
debugging = 0
|
27 |
+
|
28 |
+
traceenter = fnull # trace enter of functions
|
29 |
+
tracev = fnull # verbose trace
|
30 |
+
|
31 |
+
if debugging:
|
32 |
+
traceenter = trace # trace enter of functions
|
33 |
+
tracev = trace # verbose trace
|
34 |
+
|
35 |
+
|
36 |
+
class OutputReflector:
|
37 |
+
def __init__(self, file, writefunc):
|
38 |
+
self.writefunc = writefunc
|
39 |
+
self.file = file
|
40 |
+
|
41 |
+
def __getattr__(self, name):
|
42 |
+
return getattr(self.file, name)
|
43 |
+
|
44 |
+
def write(self, message):
|
45 |
+
self.writefunc(message)
|
46 |
+
self.file.write(message)
|
47 |
+
|
48 |
+
|
49 |
+
def _dumpf(frame):
|
50 |
+
if frame is None:
|
51 |
+
return "<None>"
|
52 |
+
else:
|
53 |
+
addn = "(with trace!)"
|
54 |
+
if frame.f_trace is None:
|
55 |
+
addn = " **No Trace Set **"
|
56 |
+
return "Frame at %d, file %s, line: %d%s" % (
|
57 |
+
id(frame),
|
58 |
+
frame.f_code.co_filename,
|
59 |
+
frame.f_lineno,
|
60 |
+
addn,
|
61 |
+
)
|
62 |
+
|
63 |
+
|
64 |
+
g_adb = None
|
65 |
+
|
66 |
+
|
67 |
+
def OnSetBreakPoint(codeContext, breakPointState, lineNo):
|
68 |
+
try:
|
69 |
+
fileName = codeContext.codeContainer.GetFileName()
|
70 |
+
# inject the code into linecache.
|
71 |
+
import linecache
|
72 |
+
|
73 |
+
linecache.cache[fileName] = 0, 0, codeContext.codeContainer.GetText(), fileName
|
74 |
+
g_adb._OnSetBreakPoint(fileName, codeContext, breakPointState, lineNo + 1)
|
75 |
+
except:
|
76 |
+
traceback.print_exc()
|
77 |
+
|
78 |
+
|
79 |
+
class Adb(bdb.Bdb, gateways.RemoteDebugApplicationEvents):
|
80 |
+
def __init__(self):
|
81 |
+
self.debugApplication = None
|
82 |
+
self.debuggingThread = None
|
83 |
+
self.debuggingThreadStateHandle = None
|
84 |
+
self.stackSnifferCookie = self.stackSniffer = None
|
85 |
+
self.codeContainerProvider = None
|
86 |
+
self.debuggingThread = None
|
87 |
+
self.breakFlags = None
|
88 |
+
self.breakReason = None
|
89 |
+
self.appDebugger = None
|
90 |
+
self.appEventConnection = None
|
91 |
+
self.logicalbotframe = None # Anything at this level or below does not exist!
|
92 |
+
self.currentframe = None # The frame we are currently in.
|
93 |
+
self.recursiveData = [] # Data saved for each reentery on this thread.
|
94 |
+
bdb.Bdb.__init__(self)
|
95 |
+
self._threadprotectlock = _thread.allocate_lock()
|
96 |
+
self.reset()
|
97 |
+
|
98 |
+
def canonic(self, fname):
|
99 |
+
if fname[0] == "<":
|
100 |
+
return fname
|
101 |
+
return bdb.Bdb.canonic(self, fname)
|
102 |
+
|
103 |
+
def reset(self):
|
104 |
+
traceenter("adb.reset")
|
105 |
+
bdb.Bdb.reset(self)
|
106 |
+
|
107 |
+
def __xxxxx__set_break(self, filename, lineno, cond=None):
|
108 |
+
# As per standard one, except no linecache checking!
|
109 |
+
if filename not in self.breaks:
|
110 |
+
self.breaks[filename] = []
|
111 |
+
list = self.breaks[filename]
|
112 |
+
if lineno in list:
|
113 |
+
return "There is already a breakpoint there!"
|
114 |
+
list.append(lineno)
|
115 |
+
if cond is not None:
|
116 |
+
self.cbreaks[filename, lineno] = cond
|
117 |
+
|
118 |
+
def stop_here(self, frame):
|
119 |
+
traceenter("stop_here", _dumpf(frame), _dumpf(self.stopframe))
|
120 |
+
# As per bdb.stop_here, except for logicalbotframe
|
121 |
+
## if self.stopframe is None:
|
122 |
+
## return 1
|
123 |
+
if frame is self.stopframe:
|
124 |
+
return 1
|
125 |
+
|
126 |
+
tracev("stop_here said 'No'!")
|
127 |
+
return 0
|
128 |
+
|
129 |
+
def break_here(self, frame):
|
130 |
+
traceenter("break_here", self.breakFlags, _dumpf(frame))
|
131 |
+
self.breakReason = None
|
132 |
+
if self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_HALT:
|
133 |
+
self.breakReason = axdebug.BREAKREASON_DEBUGGER_HALT
|
134 |
+
elif self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_BLOCK:
|
135 |
+
self.breakReason = axdebug.BREAKREASON_DEBUGGER_BLOCK
|
136 |
+
elif self.breakFlags == axdebug.APPBREAKFLAG_STEP:
|
137 |
+
self.breakReason = axdebug.BREAKREASON_STEP
|
138 |
+
else:
|
139 |
+
print("Calling base 'break_here' with", self.breaks)
|
140 |
+
if bdb.Bdb.break_here(self, frame):
|
141 |
+
self.breakReason = axdebug.BREAKREASON_BREAKPOINT
|
142 |
+
return self.breakReason is not None
|
143 |
+
|
144 |
+
def break_anywhere(self, frame):
|
145 |
+
traceenter("break_anywhere", _dumpf(frame))
|
146 |
+
if self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_HALT:
|
147 |
+
self.breakReason = axdebug.BREAKREASON_DEBUGGER_HALT
|
148 |
+
return 1
|
149 |
+
rc = bdb.Bdb.break_anywhere(self, frame)
|
150 |
+
tracev("break_anywhere", _dumpf(frame), "returning", rc)
|
151 |
+
return rc
|
152 |
+
|
153 |
+
def dispatch_return(self, frame, arg):
|
154 |
+
traceenter("dispatch_return", _dumpf(frame), arg)
|
155 |
+
if self.logicalbotframe is frame:
|
156 |
+
# We dont want to debug parent frames.
|
157 |
+
tracev("dispatch_return resetting sys.trace")
|
158 |
+
sys.settrace(None)
|
159 |
+
return
|
160 |
+
# self.bSetTrace = 0
|
161 |
+
self.currentframe = frame.f_back
|
162 |
+
return bdb.Bdb.dispatch_return(self, frame, arg)
|
163 |
+
|
164 |
+
def dispatch_line(self, frame):
|
165 |
+
traceenter("dispatch_line", _dumpf(frame), _dumpf(self.botframe))
|
166 |
+
# trace("logbotframe is", _dumpf(self.logicalbotframe), "botframe is", self.botframe)
|
167 |
+
if frame is self.logicalbotframe:
|
168 |
+
trace("dispatch_line", _dumpf(frame), "for bottom frame returing tracer")
|
169 |
+
# The next code executed in the frame above may be a builtin (eg, apply())
|
170 |
+
# in which sys.trace needs to be set.
|
171 |
+
sys.settrace(self.trace_dispatch)
|
172 |
+
# And return the tracer incase we are about to execute Python code,
|
173 |
+
# in which case sys tracer is ignored!
|
174 |
+
return self.trace_dispatch
|
175 |
+
|
176 |
+
if self.codeContainerProvider.FromFileName(frame.f_code.co_filename) is None:
|
177 |
+
trace(
|
178 |
+
"dispatch_line has no document for", _dumpf(frame), "- skipping trace!"
|
179 |
+
)
|
180 |
+
return None
|
181 |
+
self.currentframe = (
|
182 |
+
frame # So the stack sniffer knows our most recent, debuggable code.
|
183 |
+
)
|
184 |
+
return bdb.Bdb.dispatch_line(self, frame)
|
185 |
+
|
186 |
+
def dispatch_call(self, frame, arg):
|
187 |
+
traceenter("dispatch_call", _dumpf(frame))
|
188 |
+
frame.f_locals["__axstack_address__"] = axdebug.GetStackAddress()
|
189 |
+
if frame is self.botframe:
|
190 |
+
trace("dispatch_call is self.botframe - returning tracer")
|
191 |
+
return self.trace_dispatch
|
192 |
+
# Not our bottom frame. If we have a document for it,
|
193 |
+
# then trace it, otherwise run at full speed.
|
194 |
+
if self.codeContainerProvider.FromFileName(frame.f_code.co_filename) is None:
|
195 |
+
trace(
|
196 |
+
"dispatch_call has no document for", _dumpf(frame), "- skipping trace!"
|
197 |
+
)
|
198 |
+
## sys.settrace(None)
|
199 |
+
return None
|
200 |
+
return self.trace_dispatch
|
201 |
+
|
202 |
+
# rc = bdb.Bdb.dispatch_call(self, frame, arg)
|
203 |
+
# trace("dispatch_call", _dumpf(frame),"returned",rc)
|
204 |
+
# return rc
|
205 |
+
|
206 |
+
def trace_dispatch(self, frame, event, arg):
|
207 |
+
traceenter("trace_dispatch", _dumpf(frame), event, arg)
|
208 |
+
if self.debugApplication is None:
|
209 |
+
trace("trace_dispatch has no application!")
|
210 |
+
return # None
|
211 |
+
return bdb.Bdb.trace_dispatch(self, frame, event, arg)
|
212 |
+
|
213 |
+
#
|
214 |
+
# The user functions do bugger all!
|
215 |
+
#
|
216 |
+
# def user_call(self, frame, argument_list):
|
217 |
+
# traceenter("user_call",_dumpf(frame))
|
218 |
+
|
219 |
+
def user_line(self, frame):
|
220 |
+
traceenter("user_line", _dumpf(frame))
|
221 |
+
# Traces at line zero
|
222 |
+
if frame.f_lineno != 0:
|
223 |
+
breakReason = self.breakReason
|
224 |
+
if breakReason is None:
|
225 |
+
breakReason = axdebug.BREAKREASON_STEP
|
226 |
+
self._HandleBreakPoint(frame, None, breakReason)
|
227 |
+
|
228 |
+
def user_return(self, frame, return_value):
|
229 |
+
# traceenter("user_return",_dumpf(frame),return_value)
|
230 |
+
bdb.Bdb.user_return(self, frame, return_value)
|
231 |
+
|
232 |
+
def user_exception(self, frame, exc_info):
|
233 |
+
# traceenter("user_exception")
|
234 |
+
bdb.Bdb.user_exception(self, frame, exc_info)
|
235 |
+
|
236 |
+
def _HandleBreakPoint(self, frame, tb, reason):
|
237 |
+
traceenter(
|
238 |
+
"Calling HandleBreakPoint with reason", reason, "at frame", _dumpf(frame)
|
239 |
+
)
|
240 |
+
traceenter(" Current frame is", _dumpf(self.currentframe))
|
241 |
+
try:
|
242 |
+
resumeAction = self.debugApplication.HandleBreakPoint(reason)
|
243 |
+
tracev("HandleBreakPoint returned with ", resumeAction)
|
244 |
+
except pythoncom.com_error as details:
|
245 |
+
# Eeek - the debugger is dead, or something serious is happening.
|
246 |
+
# Assume we should continue
|
247 |
+
resumeAction = axdebug.BREAKRESUMEACTION_CONTINUE
|
248 |
+
trace("HandleBreakPoint FAILED with", details)
|
249 |
+
|
250 |
+
self.stack = []
|
251 |
+
self.curindex = 0
|
252 |
+
if resumeAction == axdebug.BREAKRESUMEACTION_ABORT:
|
253 |
+
self.set_quit()
|
254 |
+
elif resumeAction == axdebug.BREAKRESUMEACTION_CONTINUE:
|
255 |
+
tracev("resume action is continue")
|
256 |
+
self.set_continue()
|
257 |
+
elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_INTO:
|
258 |
+
tracev("resume action is step")
|
259 |
+
self.set_step()
|
260 |
+
elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_OVER:
|
261 |
+
tracev("resume action is next")
|
262 |
+
self.set_next(frame)
|
263 |
+
elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_OUT:
|
264 |
+
tracev("resume action is stop out")
|
265 |
+
self.set_return(frame)
|
266 |
+
else:
|
267 |
+
raise ValueError("unknown resume action flags")
|
268 |
+
self.breakReason = None
|
269 |
+
|
270 |
+
def set_trace(self):
|
271 |
+
self.breakReason = axdebug.BREAKREASON_LANGUAGE_INITIATED
|
272 |
+
bdb.Bdb.set_trace(self)
|
273 |
+
|
274 |
+
def CloseApp(self):
|
275 |
+
traceenter("ClosingApp")
|
276 |
+
self.reset()
|
277 |
+
self.logicalbotframe = None
|
278 |
+
if self.stackSnifferCookie is not None:
|
279 |
+
try:
|
280 |
+
self.debugApplication.RemoveStackFrameSniffer(self.stackSnifferCookie)
|
281 |
+
|
282 |
+
except pythoncom.com_error:
|
283 |
+
trace(
|
284 |
+
"*** Could not RemoveStackFrameSniffer %d"
|
285 |
+
% (self.stackSnifferCookie)
|
286 |
+
)
|
287 |
+
if self.stackSniffer:
|
288 |
+
_wrap_remove(self.stackSniffer)
|
289 |
+
self.stackSnifferCookie = self.stackSniffer = None
|
290 |
+
|
291 |
+
if self.appEventConnection is not None:
|
292 |
+
self.appEventConnection.Disconnect()
|
293 |
+
self.appEventConnection = None
|
294 |
+
self.debugApplication = None
|
295 |
+
self.appDebugger = None
|
296 |
+
if self.codeContainerProvider is not None:
|
297 |
+
self.codeContainerProvider.Close()
|
298 |
+
self.codeContainerProvider = None
|
299 |
+
|
300 |
+
def AttachApp(self, debugApplication, codeContainerProvider):
|
301 |
+
# traceenter("AttachApp", debugApplication, codeContainerProvider)
|
302 |
+
self.codeContainerProvider = codeContainerProvider
|
303 |
+
self.debugApplication = debugApplication
|
304 |
+
self.stackSniffer = _wrap(
|
305 |
+
stackframe.DebugStackFrameSniffer(self), axdebug.IID_IDebugStackFrameSniffer
|
306 |
+
)
|
307 |
+
self.stackSnifferCookie = debugApplication.AddStackFrameSniffer(
|
308 |
+
self.stackSniffer
|
309 |
+
)
|
310 |
+
# trace("StackFrameSniffer added (%d)" % self.stackSnifferCookie)
|
311 |
+
|
312 |
+
# Connect to the application events.
|
313 |
+
self.appEventConnection = win32com.client.connect.SimpleConnection(
|
314 |
+
self.debugApplication, self, axdebug.IID_IRemoteDebugApplicationEvents
|
315 |
+
)
|
316 |
+
|
317 |
+
def ResetAXDebugging(self):
|
318 |
+
traceenter("ResetAXDebugging", self, "with refcount", len(self.recursiveData))
|
319 |
+
if win32api.GetCurrentThreadId() != self.debuggingThread:
|
320 |
+
trace("ResetAXDebugging called on other thread")
|
321 |
+
return
|
322 |
+
|
323 |
+
if len(self.recursiveData) == 0:
|
324 |
+
# print "ResetAXDebugging called for final time."
|
325 |
+
self.logicalbotframe = None
|
326 |
+
self.debuggingThread = None
|
327 |
+
self.currentframe = None
|
328 |
+
self.debuggingThreadStateHandle = None
|
329 |
+
return
|
330 |
+
|
331 |
+
(
|
332 |
+
self.logbotframe,
|
333 |
+
self.stopframe,
|
334 |
+
self.currentframe,
|
335 |
+
self.debuggingThreadStateHandle,
|
336 |
+
) = self.recursiveData[0]
|
337 |
+
self.recursiveData = self.recursiveData[1:]
|
338 |
+
|
339 |
+
def SetupAXDebugging(self, baseFrame=None, userFrame=None):
|
340 |
+
"""Get ready for potential debugging. Must be called on the thread
|
341 |
+
that is being debugged.
|
342 |
+
"""
|
343 |
+
# userFrame is for non AXScript debugging. This is the first frame of the
|
344 |
+
# users code.
|
345 |
+
if userFrame is None:
|
346 |
+
userFrame = baseFrame
|
347 |
+
else:
|
348 |
+
# We have missed the "dispatch_call" function, so set this up now!
|
349 |
+
userFrame.f_locals["__axstack_address__"] = axdebug.GetStackAddress()
|
350 |
+
|
351 |
+
traceenter("SetupAXDebugging", self)
|
352 |
+
self._threadprotectlock.acquire()
|
353 |
+
try:
|
354 |
+
thisThread = win32api.GetCurrentThreadId()
|
355 |
+
if self.debuggingThread is None:
|
356 |
+
self.debuggingThread = thisThread
|
357 |
+
else:
|
358 |
+
if self.debuggingThread != thisThread:
|
359 |
+
trace("SetupAXDebugging called on other thread - ignored!")
|
360 |
+
return
|
361 |
+
# push our context.
|
362 |
+
self.recursiveData.insert(
|
363 |
+
0,
|
364 |
+
(
|
365 |
+
self.logicalbotframe,
|
366 |
+
self.stopframe,
|
367 |
+
self.currentframe,
|
368 |
+
self.debuggingThreadStateHandle,
|
369 |
+
),
|
370 |
+
)
|
371 |
+
finally:
|
372 |
+
self._threadprotectlock.release()
|
373 |
+
|
374 |
+
trace("SetupAXDebugging has base frame as", _dumpf(baseFrame))
|
375 |
+
self.botframe = baseFrame
|
376 |
+
self.stopframe = userFrame
|
377 |
+
self.logicalbotframe = baseFrame
|
378 |
+
self.currentframe = None
|
379 |
+
self.debuggingThreadStateHandle = axdebug.GetThreadStateHandle()
|
380 |
+
|
381 |
+
self._BreakFlagsChanged()
|
382 |
+
|
383 |
+
# RemoteDebugApplicationEvents
|
384 |
+
def OnConnectDebugger(self, appDebugger):
|
385 |
+
traceenter("OnConnectDebugger", appDebugger)
|
386 |
+
self.appDebugger = appDebugger
|
387 |
+
# Reflect output to appDebugger
|
388 |
+
writefunc = lambda s: appDebugger.onDebugOutput(s)
|
389 |
+
sys.stdout = OutputReflector(sys.stdout, writefunc)
|
390 |
+
sys.stderr = OutputReflector(sys.stderr, writefunc)
|
391 |
+
|
392 |
+
def OnDisconnectDebugger(self):
|
393 |
+
traceenter("OnDisconnectDebugger")
|
394 |
+
# Stop reflecting output
|
395 |
+
if isinstance(sys.stdout, OutputReflector):
|
396 |
+
sys.stdout = sys.stdout.file
|
397 |
+
if isinstance(sys.stderr, OutputReflector):
|
398 |
+
sys.stderr = sys.stderr.file
|
399 |
+
self.appDebugger = None
|
400 |
+
self.set_quit()
|
401 |
+
|
402 |
+
def OnSetName(self, name):
|
403 |
+
traceenter("OnSetName", name)
|
404 |
+
|
405 |
+
def OnDebugOutput(self, string):
|
406 |
+
traceenter("OnDebugOutput", string)
|
407 |
+
|
408 |
+
def OnClose(self):
|
409 |
+
traceenter("OnClose")
|
410 |
+
|
411 |
+
def OnEnterBreakPoint(self, rdat):
|
412 |
+
traceenter("OnEnterBreakPoint", rdat)
|
413 |
+
|
414 |
+
def OnLeaveBreakPoint(self, rdat):
|
415 |
+
traceenter("OnLeaveBreakPoint", rdat)
|
416 |
+
|
417 |
+
def OnCreateThread(self, rdat):
|
418 |
+
traceenter("OnCreateThread", rdat)
|
419 |
+
|
420 |
+
def OnDestroyThread(self, rdat):
|
421 |
+
traceenter("OnDestroyThread", rdat)
|
422 |
+
|
423 |
+
def OnBreakFlagChange(self, abf, rdat):
|
424 |
+
traceenter("Debugger OnBreakFlagChange", abf, rdat)
|
425 |
+
self.breakFlags = abf
|
426 |
+
self._BreakFlagsChanged()
|
427 |
+
|
428 |
+
def _BreakFlagsChanged(self):
|
429 |
+
traceenter(
|
430 |
+
"_BreakFlagsChanged to %s with our thread = %s, and debugging thread = %s"
|
431 |
+
% (self.breakFlags, self.debuggingThread, win32api.GetCurrentThreadId())
|
432 |
+
)
|
433 |
+
trace("_BreakFlagsChanged has breaks", self.breaks)
|
434 |
+
# If a request comes on our debugging thread, then do it now!
|
435 |
+
# if self.debuggingThread!=win32api.GetCurrentThreadId():
|
436 |
+
# return
|
437 |
+
|
438 |
+
if len(self.breaks) or self.breakFlags:
|
439 |
+
if self.logicalbotframe:
|
440 |
+
trace("BreakFlagsChange with bot frame", _dumpf(self.logicalbotframe))
|
441 |
+
# We have frames not to be debugged (eg, Scripting engine frames
|
442 |
+
# (sys.settrace will be set when out logicalbotframe is hit -
|
443 |
+
# this may not be the right thing to do, as it may not cause the
|
444 |
+
# immediate break we desire.)
|
445 |
+
self.logicalbotframe.f_trace = self.trace_dispatch
|
446 |
+
else:
|
447 |
+
trace("BreakFlagsChanged, but no bottom frame")
|
448 |
+
if self.stopframe is not None:
|
449 |
+
self.stopframe.f_trace = self.trace_dispatch
|
450 |
+
# If we have the thread-state for the thread being debugged, then
|
451 |
+
# we dynamically set its trace function - it is possible that the thread
|
452 |
+
# being debugged is in a blocked call (eg, a message box) and we
|
453 |
+
# want to hit the debugger the instant we return
|
454 |
+
if (
|
455 |
+
self.debuggingThreadStateHandle is not None
|
456 |
+
and self.breakFlags
|
457 |
+
and self.debuggingThread != win32api.GetCurrentThreadId()
|
458 |
+
):
|
459 |
+
axdebug.SetThreadStateTrace(
|
460 |
+
self.debuggingThreadStateHandle, self.trace_dispatch
|
461 |
+
)
|
462 |
+
|
463 |
+
def _OnSetBreakPoint(self, key, codeContext, bps, lineNo):
|
464 |
+
traceenter("_OnSetBreakPoint", self, key, codeContext, bps, lineNo)
|
465 |
+
if bps == axdebug.BREAKPOINT_ENABLED:
|
466 |
+
problem = self.set_break(key, lineNo)
|
467 |
+
if problem:
|
468 |
+
print("*** set_break failed -", problem)
|
469 |
+
trace("_OnSetBreakPoint just set BP and has breaks", self.breaks)
|
470 |
+
else:
|
471 |
+
self.clear_break(key, lineNo)
|
472 |
+
self._BreakFlagsChanged()
|
473 |
+
trace("_OnSetBreakPoint leaving with breaks", self.breaks)
|
474 |
+
|
475 |
+
|
476 |
+
def Debugger():
|
477 |
+
global g_adb
|
478 |
+
if g_adb is None:
|
479 |
+
g_adb = Adb()
|
480 |
+
return g_adb
|
MLPY/Lib/site-packages/win32comext/axdebug/axdebug.pyd
ADDED
Binary file (285 kB). View file
|
|
MLPY/Lib/site-packages/win32comext/axdebug/codecontainer.py
ADDED
@@ -0,0 +1,278 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""A utility class for a code container.
|
2 |
+
|
3 |
+
A code container is a class which holds source code for a debugger. It knows how
|
4 |
+
to color the text, and also how to translate lines into offsets, and back.
|
5 |
+
"""
|
6 |
+
|
7 |
+
import sys
|
8 |
+
import tokenize
|
9 |
+
|
10 |
+
import win32api
|
11 |
+
import winerror
|
12 |
+
from win32com.axdebug import axdebug
|
13 |
+
from win32com.server.exception import Exception
|
14 |
+
|
15 |
+
from . import contexts
|
16 |
+
from .util import RaiseNotImpl, _wrap
|
17 |
+
|
18 |
+
_keywords = {} # set of Python keywords
|
19 |
+
for name in """
|
20 |
+
and assert break class continue def del elif else except exec
|
21 |
+
finally for from global if import in is lambda not
|
22 |
+
or pass print raise return try while
|
23 |
+
""".split():
|
24 |
+
_keywords[name] = 1
|
25 |
+
|
26 |
+
|
27 |
+
class SourceCodeContainer:
|
28 |
+
def __init__(
|
29 |
+
self,
|
30 |
+
text,
|
31 |
+
fileName="<Remove Me!>",
|
32 |
+
sourceContext=0,
|
33 |
+
startLineNumber=0,
|
34 |
+
site=None,
|
35 |
+
debugDocument=None,
|
36 |
+
):
|
37 |
+
self.sourceContext = sourceContext # The source context added by a smart host.
|
38 |
+
self.text = text
|
39 |
+
if text:
|
40 |
+
self._buildlines()
|
41 |
+
self.nextLineNo = 0
|
42 |
+
self.fileName = fileName
|
43 |
+
self.codeContexts = {}
|
44 |
+
self.site = site
|
45 |
+
self.startLineNumber = startLineNumber
|
46 |
+
self.debugDocument = None
|
47 |
+
|
48 |
+
def _Close(self):
|
49 |
+
self.text = self.lines = self.lineOffsets = None
|
50 |
+
self.codeContexts = None
|
51 |
+
self.debugDocument = None
|
52 |
+
self.site = None
|
53 |
+
self.sourceContext = None
|
54 |
+
|
55 |
+
def GetText(self):
|
56 |
+
return self.text
|
57 |
+
|
58 |
+
def GetName(self, dnt):
|
59 |
+
assert 0, "You must subclass this"
|
60 |
+
|
61 |
+
def GetFileName(self):
|
62 |
+
return self.fileName
|
63 |
+
|
64 |
+
def GetPositionOfLine(self, cLineNumber):
|
65 |
+
self.GetText() # Prime us.
|
66 |
+
try:
|
67 |
+
return self.lineOffsets[cLineNumber]
|
68 |
+
except IndexError:
|
69 |
+
raise Exception(scode=winerror.S_FALSE)
|
70 |
+
|
71 |
+
def GetLineOfPosition(self, charPos):
|
72 |
+
self.GetText() # Prime us.
|
73 |
+
lastOffset = 0
|
74 |
+
lineNo = 0
|
75 |
+
for lineOffset in self.lineOffsets[1:]:
|
76 |
+
if lineOffset > charPos:
|
77 |
+
break
|
78 |
+
lastOffset = lineOffset
|
79 |
+
lineNo = lineNo + 1
|
80 |
+
else: # for not broken.
|
81 |
+
# print "Cant find", charPos, "in", self.lineOffsets
|
82 |
+
raise Exception(scode=winerror.S_FALSE)
|
83 |
+
# print "GLOP ret=",lineNo, (charPos-lastOffset)
|
84 |
+
return lineNo, (charPos - lastOffset)
|
85 |
+
|
86 |
+
def GetNextLine(self):
|
87 |
+
if self.nextLineNo >= len(self.lines):
|
88 |
+
self.nextLineNo = 0 # auto-reset.
|
89 |
+
return ""
|
90 |
+
rc = self.lines[self.nextLineNo]
|
91 |
+
self.nextLineNo = self.nextLineNo + 1
|
92 |
+
return rc
|
93 |
+
|
94 |
+
def GetLine(self, num):
|
95 |
+
self.GetText() # Prime us.
|
96 |
+
return self.lines[num]
|
97 |
+
|
98 |
+
def GetNumChars(self):
|
99 |
+
return len(self.GetText())
|
100 |
+
|
101 |
+
def GetNumLines(self):
|
102 |
+
self.GetText() # Prime us.
|
103 |
+
return len(self.lines)
|
104 |
+
|
105 |
+
def _buildline(self, pos):
|
106 |
+
i = self.text.find("\n", pos)
|
107 |
+
if i < 0:
|
108 |
+
newpos = len(self.text)
|
109 |
+
else:
|
110 |
+
newpos = i + 1
|
111 |
+
r = self.text[pos:newpos]
|
112 |
+
return r, newpos
|
113 |
+
|
114 |
+
def _buildlines(self):
|
115 |
+
self.lines = []
|
116 |
+
self.lineOffsets = [0]
|
117 |
+
line, pos = self._buildline(0)
|
118 |
+
while line:
|
119 |
+
self.lines.append(line)
|
120 |
+
self.lineOffsets.append(pos)
|
121 |
+
line, pos = self._buildline(pos)
|
122 |
+
|
123 |
+
def _ProcessToken(self, type, token, spos, epos, line):
|
124 |
+
srow, scol = spos
|
125 |
+
erow, ecol = epos
|
126 |
+
self.GetText() # Prime us.
|
127 |
+
linenum = srow - 1 # Lines zero based for us too.
|
128 |
+
realCharPos = self.lineOffsets[linenum] + scol
|
129 |
+
numskipped = realCharPos - self.lastPos
|
130 |
+
if numskipped == 0:
|
131 |
+
pass
|
132 |
+
elif numskipped == 1:
|
133 |
+
self.attrs.append(axdebug.SOURCETEXT_ATTR_COMMENT)
|
134 |
+
else:
|
135 |
+
self.attrs.append((axdebug.SOURCETEXT_ATTR_COMMENT, numskipped))
|
136 |
+
kwSize = len(token)
|
137 |
+
self.lastPos = realCharPos + kwSize
|
138 |
+
attr = 0
|
139 |
+
|
140 |
+
if type == tokenize.NAME:
|
141 |
+
if token in _keywords:
|
142 |
+
attr = axdebug.SOURCETEXT_ATTR_KEYWORD
|
143 |
+
elif type == tokenize.STRING:
|
144 |
+
attr = axdebug.SOURCETEXT_ATTR_STRING
|
145 |
+
elif type == tokenize.NUMBER:
|
146 |
+
attr = axdebug.SOURCETEXT_ATTR_NUMBER
|
147 |
+
elif type == tokenize.OP:
|
148 |
+
attr = axdebug.SOURCETEXT_ATTR_OPERATOR
|
149 |
+
elif type == tokenize.COMMENT:
|
150 |
+
attr = axdebug.SOURCETEXT_ATTR_COMMENT
|
151 |
+
# else attr remains zero...
|
152 |
+
if kwSize == 0:
|
153 |
+
pass
|
154 |
+
elif kwSize == 1:
|
155 |
+
self.attrs.append(attr)
|
156 |
+
else:
|
157 |
+
self.attrs.append((attr, kwSize))
|
158 |
+
|
159 |
+
def GetSyntaxColorAttributes(self):
|
160 |
+
self.lastPos = 0
|
161 |
+
self.attrs = []
|
162 |
+
try:
|
163 |
+
tokenize.tokenize(self.GetNextLine, self._ProcessToken)
|
164 |
+
except tokenize.TokenError:
|
165 |
+
pass # Ignore - will cause all subsequent text to be commented.
|
166 |
+
numAtEnd = len(self.GetText()) - self.lastPos
|
167 |
+
if numAtEnd:
|
168 |
+
self.attrs.append((axdebug.SOURCETEXT_ATTR_COMMENT, numAtEnd))
|
169 |
+
return self.attrs
|
170 |
+
|
171 |
+
# We also provide and manage DebugDocumentContext objects
|
172 |
+
def _MakeDebugCodeContext(self, lineNo, charPos, len):
|
173 |
+
return _wrap(
|
174 |
+
contexts.DebugCodeContext(lineNo, charPos, len, self, self.site),
|
175 |
+
axdebug.IID_IDebugCodeContext,
|
176 |
+
)
|
177 |
+
|
178 |
+
# Make a context at the given position. It should take up the entire context.
|
179 |
+
def _MakeContextAtPosition(self, charPos):
|
180 |
+
lineNo, offset = self.GetLineOfPosition(charPos)
|
181 |
+
try:
|
182 |
+
endPos = self.GetPositionOfLine(lineNo + 1)
|
183 |
+
except:
|
184 |
+
endPos = charPos
|
185 |
+
codecontext = self._MakeDebugCodeContext(lineNo, charPos, endPos - charPos)
|
186 |
+
return codecontext
|
187 |
+
|
188 |
+
# Returns a DebugCodeContext. debugDocument can be None for smart hosts.
|
189 |
+
def GetCodeContextAtPosition(self, charPos):
|
190 |
+
# trace("GetContextOfPos", charPos, maxChars)
|
191 |
+
# Convert to line number.
|
192 |
+
lineNo, offset = self.GetLineOfPosition(charPos)
|
193 |
+
charPos = self.GetPositionOfLine(lineNo)
|
194 |
+
try:
|
195 |
+
cc = self.codeContexts[charPos]
|
196 |
+
# trace(" GetContextOfPos using existing")
|
197 |
+
except KeyError:
|
198 |
+
cc = self._MakeContextAtPosition(charPos)
|
199 |
+
self.codeContexts[charPos] = cc
|
200 |
+
return cc
|
201 |
+
|
202 |
+
|
203 |
+
class SourceModuleContainer(SourceCodeContainer):
|
204 |
+
def __init__(self, module):
|
205 |
+
self.module = module
|
206 |
+
if hasattr(module, "__file__"):
|
207 |
+
fname = self.module.__file__
|
208 |
+
# Check for .pyc or .pyo or even .pys!
|
209 |
+
if fname[-1] in ["O", "o", "C", "c", "S", "s"]:
|
210 |
+
fname = fname[:-1]
|
211 |
+
try:
|
212 |
+
fname = win32api.GetFullPathName(fname)
|
213 |
+
except win32api.error:
|
214 |
+
pass
|
215 |
+
else:
|
216 |
+
if module.__name__ == "__main__" and len(sys.argv) > 0:
|
217 |
+
fname = sys.argv[0]
|
218 |
+
else:
|
219 |
+
fname = "<Unknown!>"
|
220 |
+
SourceCodeContainer.__init__(self, None, fname)
|
221 |
+
|
222 |
+
def GetText(self):
|
223 |
+
if self.text is None:
|
224 |
+
fname = self.GetFileName()
|
225 |
+
if fname:
|
226 |
+
try:
|
227 |
+
self.text = open(fname, "r").read()
|
228 |
+
except IOError as details:
|
229 |
+
self.text = "# Exception opening file\n# %s" % (repr(details))
|
230 |
+
else:
|
231 |
+
self.text = "# No file available for module '%s'" % (self.module)
|
232 |
+
self._buildlines()
|
233 |
+
return self.text
|
234 |
+
|
235 |
+
def GetName(self, dnt):
|
236 |
+
name = self.module.__name__
|
237 |
+
try:
|
238 |
+
fname = win32api.GetFullPathName(self.module.__file__)
|
239 |
+
except win32api.error:
|
240 |
+
fname = self.module.__file__
|
241 |
+
except AttributeError:
|
242 |
+
fname = name
|
243 |
+
if dnt == axdebug.DOCUMENTNAMETYPE_APPNODE:
|
244 |
+
return name.split(".")[-1]
|
245 |
+
elif dnt == axdebug.DOCUMENTNAMETYPE_TITLE:
|
246 |
+
return fname
|
247 |
+
elif dnt == axdebug.DOCUMENTNAMETYPE_FILE_TAIL:
|
248 |
+
return os.path.split(fname)[1]
|
249 |
+
elif dnt == axdebug.DOCUMENTNAMETYPE_URL:
|
250 |
+
return "file:%s" % fname
|
251 |
+
else:
|
252 |
+
raise Exception(scode=winerror.E_UNEXPECTED)
|
253 |
+
|
254 |
+
|
255 |
+
if __name__ == "__main__":
|
256 |
+
import sys
|
257 |
+
|
258 |
+
sys.path.append(".")
|
259 |
+
import ttest
|
260 |
+
|
261 |
+
sc = SourceModuleContainer(ttest)
|
262 |
+
# sc = SourceCodeContainer(open(sys.argv[1], "rb").read(), sys.argv[1])
|
263 |
+
attrs = sc.GetSyntaxColorAttributes()
|
264 |
+
attrlen = 0
|
265 |
+
for attr in attrs:
|
266 |
+
if type(attr) == type(()):
|
267 |
+
attrlen = attrlen + attr[1]
|
268 |
+
else:
|
269 |
+
attrlen = attrlen + 1
|
270 |
+
text = sc.GetText()
|
271 |
+
if attrlen != len(text):
|
272 |
+
print("Lengths dont match!!! (%d/%d)" % (attrlen, len(text)))
|
273 |
+
|
274 |
+
# print "Attributes:"
|
275 |
+
# print attrs
|
276 |
+
print("GetLineOfPos=", sc.GetLineOfPosition(0))
|
277 |
+
print("GetLineOfPos=", sc.GetLineOfPosition(4))
|
278 |
+
print("GetLineOfPos=", sc.GetLineOfPosition(10))
|
MLPY/Lib/site-packages/win32comext/axdebug/contexts.py
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
""" A module for managing the AXDebug I*Contexts
|
2 |
+
|
3 |
+
"""
|
4 |
+
import pythoncom
|
5 |
+
import win32com.server.util
|
6 |
+
|
7 |
+
from . import adb, axdebug, gateways
|
8 |
+
|
9 |
+
# Utility function for wrapping object created by this module.
|
10 |
+
from .util import _wrap, _wrap_remove, trace
|
11 |
+
|
12 |
+
|
13 |
+
class DebugCodeContext(gateways.DebugCodeContext, gateways.DebugDocumentContext):
|
14 |
+
# NOTE: We also implement the IDebugDocumentContext interface for Simple Hosts.
|
15 |
+
# Thus, debugDocument may be NULL when we have smart hosts - but in that case, we
|
16 |
+
# wont be called upon to provide it.
|
17 |
+
_public_methods_ = (
|
18 |
+
gateways.DebugCodeContext._public_methods_
|
19 |
+
+ gateways.DebugDocumentContext._public_methods_
|
20 |
+
)
|
21 |
+
_com_interfaces_ = (
|
22 |
+
gateways.DebugCodeContext._com_interfaces_
|
23 |
+
+ gateways.DebugDocumentContext._com_interfaces_
|
24 |
+
)
|
25 |
+
|
26 |
+
def __init__(self, lineNo, charPos, len, codeContainer, debugSite):
|
27 |
+
self.debugSite = debugSite
|
28 |
+
self.offset = charPos
|
29 |
+
self.length = len
|
30 |
+
self.breakPointState = 0
|
31 |
+
self.lineno = lineNo
|
32 |
+
gateways.DebugCodeContext.__init__(self)
|
33 |
+
self.codeContainer = codeContainer
|
34 |
+
|
35 |
+
def _Close(self):
|
36 |
+
self.debugSite = None
|
37 |
+
|
38 |
+
def GetDocumentContext(self):
|
39 |
+
if self.debugSite is not None:
|
40 |
+
# We have a smart host - let him give it to us.
|
41 |
+
return self.debugSite.GetDocumentContextFromPosition(
|
42 |
+
self.codeContainer.sourceContext, self.offset, self.length
|
43 |
+
)
|
44 |
+
else:
|
45 |
+
# Simple host - Fine - Ill do it myself!
|
46 |
+
return _wrap(self, axdebug.IID_IDebugDocumentContext)
|
47 |
+
|
48 |
+
def SetBreakPoint(self, bps):
|
49 |
+
self.breakPointState = bps
|
50 |
+
adb.OnSetBreakPoint(self, bps, self.lineno)
|
51 |
+
|
52 |
+
# The DebugDocumentContext methods for simple hosts.
|
53 |
+
def GetDocument(self):
|
54 |
+
return self.codeContainer.debugDocument
|
55 |
+
|
56 |
+
def EnumCodeContexts(self):
|
57 |
+
return _wrap(EnumDebugCodeContexts([self]), axdebug.IID_IEnumDebugCodeContexts)
|
58 |
+
|
59 |
+
|
60 |
+
class EnumDebugCodeContexts(gateways.EnumDebugCodeContexts):
|
61 |
+
def _wrap(self, obj):
|
62 |
+
return _wrap(obj, axdebug.IID_IDebugCodeContext)
|
MLPY/Lib/site-packages/win32comext/axdebug/debugger.py
ADDED
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import string
|
3 |
+
import sys
|
4 |
+
|
5 |
+
import pythoncom
|
6 |
+
import win32api
|
7 |
+
from win32com.axdebug import (
|
8 |
+
adb,
|
9 |
+
axdebug,
|
10 |
+
codecontainer,
|
11 |
+
contexts,
|
12 |
+
documents,
|
13 |
+
expressions,
|
14 |
+
gateways,
|
15 |
+
)
|
16 |
+
from win32com.axdebug.util import _wrap, _wrap_remove, trace
|
17 |
+
from win32com.axscript import axscript
|
18 |
+
|
19 |
+
currentDebugger = None
|
20 |
+
|
21 |
+
|
22 |
+
class ModuleTreeNode:
|
23 |
+
"""Helper class for building a module tree"""
|
24 |
+
|
25 |
+
def __init__(self, module):
|
26 |
+
modName = module.__name__
|
27 |
+
self.moduleName = modName
|
28 |
+
self.module = module
|
29 |
+
self.realNode = None
|
30 |
+
self.cont = codecontainer.SourceModuleContainer(module)
|
31 |
+
|
32 |
+
def __repr__(self):
|
33 |
+
return "<ModuleTreeNode wrapping %s>" % (self.module)
|
34 |
+
|
35 |
+
def Attach(self, parentRealNode):
|
36 |
+
self.realNode.Attach(parentRealNode)
|
37 |
+
|
38 |
+
def Close(self):
|
39 |
+
self.module = None
|
40 |
+
self.cont = None
|
41 |
+
self.realNode = None
|
42 |
+
|
43 |
+
|
44 |
+
def BuildModule(module, built_nodes, rootNode, create_node_fn, create_node_args):
|
45 |
+
if module:
|
46 |
+
keep = module.__name__
|
47 |
+
keep = keep and (built_nodes.get(module) is None)
|
48 |
+
if keep and hasattr(module, "__file__"):
|
49 |
+
keep = string.lower(os.path.splitext(module.__file__)[1]) not in [
|
50 |
+
".pyd",
|
51 |
+
".dll",
|
52 |
+
]
|
53 |
+
# keep = keep and module.__name__=='__main__'
|
54 |
+
if module and keep:
|
55 |
+
# print "keeping", module.__name__
|
56 |
+
node = ModuleTreeNode(module)
|
57 |
+
built_nodes[module] = node
|
58 |
+
realNode = create_node_fn(*(node,) + create_node_args)
|
59 |
+
node.realNode = realNode
|
60 |
+
|
61 |
+
# Split into parent nodes.
|
62 |
+
parts = string.split(module.__name__, ".")
|
63 |
+
if parts[-1][:8] == "__init__":
|
64 |
+
parts = parts[:-1]
|
65 |
+
parent = string.join(parts[:-1], ".")
|
66 |
+
parentNode = rootNode
|
67 |
+
if parent:
|
68 |
+
parentModule = sys.modules[parent]
|
69 |
+
BuildModule(
|
70 |
+
parentModule, built_nodes, rootNode, create_node_fn, create_node_args
|
71 |
+
)
|
72 |
+
if parentModule in built_nodes:
|
73 |
+
parentNode = built_nodes[parentModule].realNode
|
74 |
+
node.Attach(parentNode)
|
75 |
+
|
76 |
+
|
77 |
+
def RefreshAllModules(builtItems, rootNode, create_node, create_node_args):
|
78 |
+
for module in list(sys.modules.values()):
|
79 |
+
BuildModule(module, builtItems, rootNode, create_node, create_node_args)
|
80 |
+
|
81 |
+
|
82 |
+
# realNode = pdm.CreateDebugDocumentHelper(None) # DebugDocumentHelper node?
|
83 |
+
# app.CreateApplicationNode() # doc provider node.
|
84 |
+
|
85 |
+
|
86 |
+
class CodeContainerProvider(documents.CodeContainerProvider):
|
87 |
+
def __init__(self, axdebugger):
|
88 |
+
self.axdebugger = axdebugger
|
89 |
+
documents.CodeContainerProvider.__init__(self)
|
90 |
+
self.currentNumModules = len(sys.modules)
|
91 |
+
self.nodes = {}
|
92 |
+
self.axdebugger.RefreshAllModules(self.nodes, self)
|
93 |
+
|
94 |
+
def FromFileName(self, fname):
|
95 |
+
### It appears we cant add modules during a debug session!
|
96 |
+
# if self.currentNumModules != len(sys.modules):
|
97 |
+
# self.axdebugger.RefreshAllModules(self.nodes, self)
|
98 |
+
# self.currentNumModules = len(sys.modules)
|
99 |
+
# for key in self.ccsAndNodes.keys():
|
100 |
+
# print "File:", key
|
101 |
+
return documents.CodeContainerProvider.FromFileName(self, fname)
|
102 |
+
|
103 |
+
def Close(self):
|
104 |
+
documents.CodeContainerProvider.Close(self)
|
105 |
+
self.axdebugger = None
|
106 |
+
print("Closing %d nodes" % (len(self.nodes)))
|
107 |
+
for node in self.nodes.values():
|
108 |
+
node.Close()
|
109 |
+
self.nodes = {}
|
110 |
+
|
111 |
+
|
112 |
+
class OriginalInterfaceMaker:
|
113 |
+
def MakeInterfaces(self, pdm):
|
114 |
+
app = self.pdm.CreateApplication()
|
115 |
+
self.cookie = pdm.AddApplication(app)
|
116 |
+
root = app.GetRootNode()
|
117 |
+
return app, root
|
118 |
+
|
119 |
+
def CloseInterfaces(self, pdm):
|
120 |
+
pdm.RemoveApplication(self.cookie)
|
121 |
+
|
122 |
+
|
123 |
+
class SimpleHostStyleInterfaceMaker:
|
124 |
+
def MakeInterfaces(self, pdm):
|
125 |
+
app = pdm.GetDefaultApplication()
|
126 |
+
root = app.GetRootNode()
|
127 |
+
return app, root
|
128 |
+
|
129 |
+
def CloseInterfaces(self, pdm):
|
130 |
+
pass
|
131 |
+
|
132 |
+
|
133 |
+
class AXDebugger:
|
134 |
+
def __init__(self, interfaceMaker=None, processName=None):
|
135 |
+
if processName is None:
|
136 |
+
processName = "Python Process"
|
137 |
+
if interfaceMaker is None:
|
138 |
+
interfaceMaker = SimpleHostStyleInterfaceMaker()
|
139 |
+
|
140 |
+
self.pydebugger = adb.Debugger()
|
141 |
+
|
142 |
+
self.pdm = pythoncom.CoCreateInstance(
|
143 |
+
axdebug.CLSID_ProcessDebugManager,
|
144 |
+
None,
|
145 |
+
pythoncom.CLSCTX_ALL,
|
146 |
+
axdebug.IID_IProcessDebugManager,
|
147 |
+
)
|
148 |
+
|
149 |
+
self.app, self.root = interfaceMaker.MakeInterfaces(self.pdm)
|
150 |
+
self.app.SetName(processName)
|
151 |
+
self.interfaceMaker = interfaceMaker
|
152 |
+
|
153 |
+
expressionProvider = _wrap(
|
154 |
+
expressions.ProvideExpressionContexts(),
|
155 |
+
axdebug.IID_IProvideExpressionContexts,
|
156 |
+
)
|
157 |
+
self.expressionCookie = self.app.AddGlobalExpressionContextProvider(
|
158 |
+
expressionProvider
|
159 |
+
)
|
160 |
+
|
161 |
+
contProvider = CodeContainerProvider(self)
|
162 |
+
self.pydebugger.AttachApp(self.app, contProvider)
|
163 |
+
|
164 |
+
def Break(self):
|
165 |
+
# Get the frame we start debugging from - this is the frame 1 level up
|
166 |
+
try:
|
167 |
+
1 + ""
|
168 |
+
except:
|
169 |
+
frame = sys.exc_info()[2].tb_frame.f_back
|
170 |
+
|
171 |
+
# Get/create the debugger, and tell it to break.
|
172 |
+
self.app.StartDebugSession()
|
173 |
+
# self.app.CauseBreak()
|
174 |
+
|
175 |
+
self.pydebugger.SetupAXDebugging(None, frame)
|
176 |
+
self.pydebugger.set_trace()
|
177 |
+
|
178 |
+
def Close(self):
|
179 |
+
self.pydebugger.ResetAXDebugging()
|
180 |
+
self.interfaceMaker.CloseInterfaces(self.pdm)
|
181 |
+
self.pydebugger.CloseApp()
|
182 |
+
self.app.RemoveGlobalExpressionContextProvider(self.expressionCookie)
|
183 |
+
self.expressionCookie = None
|
184 |
+
|
185 |
+
self.pdm = None
|
186 |
+
self.app = None
|
187 |
+
self.pydebugger = None
|
188 |
+
self.root = None
|
189 |
+
|
190 |
+
def RefreshAllModules(self, nodes, containerProvider):
|
191 |
+
RefreshAllModules(
|
192 |
+
nodes, self.root, self.CreateApplicationNode, (containerProvider,)
|
193 |
+
)
|
194 |
+
|
195 |
+
def CreateApplicationNode(self, node, containerProvider):
|
196 |
+
realNode = self.app.CreateApplicationNode()
|
197 |
+
|
198 |
+
document = documents.DebugDocumentText(node.cont)
|
199 |
+
document = _wrap(document, axdebug.IID_IDebugDocument)
|
200 |
+
|
201 |
+
node.cont.debugDocument = document
|
202 |
+
|
203 |
+
provider = documents.DebugDocumentProvider(document)
|
204 |
+
provider = _wrap(provider, axdebug.IID_IDebugDocumentProvider)
|
205 |
+
realNode.SetDocumentProvider(provider)
|
206 |
+
|
207 |
+
containerProvider.AddCodeContainer(node.cont, realNode)
|
208 |
+
return realNode
|
209 |
+
|
210 |
+
|
211 |
+
def _GetCurrentDebugger():
|
212 |
+
global currentDebugger
|
213 |
+
if currentDebugger is None:
|
214 |
+
currentDebugger = AXDebugger()
|
215 |
+
return currentDebugger
|
216 |
+
|
217 |
+
|
218 |
+
def Break():
|
219 |
+
_GetCurrentDebugger().Break()
|
220 |
+
|
221 |
+
|
222 |
+
brk = Break
|
223 |
+
set_trace = Break
|
224 |
+
|
225 |
+
|
226 |
+
def dosomethingelse():
|
227 |
+
a = 2
|
228 |
+
b = "Hi there"
|
229 |
+
|
230 |
+
|
231 |
+
def dosomething():
|
232 |
+
a = 1
|
233 |
+
b = 2
|
234 |
+
dosomethingelse()
|
235 |
+
|
236 |
+
|
237 |
+
def test():
|
238 |
+
Break()
|
239 |
+
input("Waiting...")
|
240 |
+
dosomething()
|
241 |
+
print("Done")
|
242 |
+
|
243 |
+
|
244 |
+
if __name__ == "__main__":
|
245 |
+
print("About to test the debugging interfaces!")
|
246 |
+
test()
|
247 |
+
print(
|
248 |
+
" %d/%d com objects still alive"
|
249 |
+
% (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
|
250 |
+
)
|
MLPY/Lib/site-packages/win32comext/axdebug/documents.py
ADDED
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
""" Management of documents for AXDebugging.
|
2 |
+
"""
|
3 |
+
|
4 |
+
|
5 |
+
import pythoncom
|
6 |
+
import win32api
|
7 |
+
from win32com.server.exception import Exception
|
8 |
+
from win32com.server.util import unwrap
|
9 |
+
|
10 |
+
from . import axdebug, codecontainer, contexts, gateways
|
11 |
+
from .util import RaiseNotImpl, _wrap, _wrap_remove, trace
|
12 |
+
|
13 |
+
# def trace(*args):
|
14 |
+
# pass
|
15 |
+
|
16 |
+
|
17 |
+
def GetGoodFileName(fname):
|
18 |
+
if fname[0] != "<":
|
19 |
+
return win32api.GetFullPathName(fname)
|
20 |
+
return fname
|
21 |
+
|
22 |
+
|
23 |
+
class DebugDocumentProvider(gateways.DebugDocumentProvider):
|
24 |
+
def __init__(self, doc):
|
25 |
+
self.doc = doc
|
26 |
+
|
27 |
+
def GetName(self, dnt):
|
28 |
+
return self.doc.GetName(dnt)
|
29 |
+
|
30 |
+
def GetDocumentClassId(self):
|
31 |
+
return self.doc.GetDocumentClassId()
|
32 |
+
|
33 |
+
def GetDocument(self):
|
34 |
+
return self.doc
|
35 |
+
|
36 |
+
|
37 |
+
class DebugDocumentText(
|
38 |
+
gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument
|
39 |
+
):
|
40 |
+
_com_interfaces_ = (
|
41 |
+
gateways.DebugDocumentInfo._com_interfaces_
|
42 |
+
+ gateways.DebugDocumentText._com_interfaces_
|
43 |
+
+ gateways.DebugDocument._com_interfaces_
|
44 |
+
)
|
45 |
+
_public_methods_ = (
|
46 |
+
gateways.DebugDocumentInfo._public_methods_
|
47 |
+
+ gateways.DebugDocumentText._public_methods_
|
48 |
+
+ gateways.DebugDocument._public_methods_
|
49 |
+
)
|
50 |
+
|
51 |
+
# A class which implements a DebugDocumentText, using the functionality
|
52 |
+
# provided by a codeContainer
|
53 |
+
def __init__(self, codeContainer):
|
54 |
+
gateways.DebugDocumentText.__init__(self)
|
55 |
+
gateways.DebugDocumentInfo.__init__(self)
|
56 |
+
gateways.DebugDocument.__init__(self)
|
57 |
+
self.codeContainer = codeContainer
|
58 |
+
|
59 |
+
def _Close(self):
|
60 |
+
self.docContexts = None
|
61 |
+
# self.codeContainer._Close()
|
62 |
+
self.codeContainer = None
|
63 |
+
|
64 |
+
# IDebugDocumentInfo
|
65 |
+
def GetName(self, dnt):
|
66 |
+
return self.codeContainer.GetName(dnt)
|
67 |
+
|
68 |
+
def GetDocumentClassId(self):
|
69 |
+
return "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"
|
70 |
+
|
71 |
+
# IDebugDocument has no methods!
|
72 |
+
#
|
73 |
+
|
74 |
+
# IDebugDocumentText methods.
|
75 |
+
# def GetDocumentAttributes
|
76 |
+
def GetSize(self):
|
77 |
+
# trace("GetSize")
|
78 |
+
return self.codeContainer.GetNumLines(), self.codeContainer.GetNumChars()
|
79 |
+
|
80 |
+
def GetPositionOfLine(self, cLineNumber):
|
81 |
+
return self.codeContainer.GetPositionOfLine(cLineNumber)
|
82 |
+
|
83 |
+
def GetLineOfPosition(self, charPos):
|
84 |
+
return self.codeContainer.GetLineOfPosition(charPos)
|
85 |
+
|
86 |
+
def GetText(self, charPos, maxChars, wantAttr):
|
87 |
+
# Get all the attributes, else the tokenizer will get upset.
|
88 |
+
# XXX - not yet!
|
89 |
+
# trace("GetText", charPos, maxChars, wantAttr)
|
90 |
+
cont = self.codeContainer
|
91 |
+
attr = cont.GetSyntaxColorAttributes()
|
92 |
+
return cont.GetText(), attr
|
93 |
+
|
94 |
+
def GetPositionOfContext(self, context):
|
95 |
+
trace("GetPositionOfContext", context)
|
96 |
+
context = unwrap(context)
|
97 |
+
return context.offset, context.length
|
98 |
+
|
99 |
+
# Return a DebugDocumentContext.
|
100 |
+
def GetContextOfPosition(self, charPos, maxChars):
|
101 |
+
# Make one
|
102 |
+
doc = _wrap(self, axdebug.IID_IDebugDocument)
|
103 |
+
rc = self.codeContainer.GetCodeContextAtPosition(charPos)
|
104 |
+
return rc.QueryInterface(axdebug.IID_IDebugDocumentContext)
|
105 |
+
|
106 |
+
|
107 |
+
class CodeContainerProvider:
|
108 |
+
"""An abstract Python class which provides code containers!
|
109 |
+
|
110 |
+
Given a Python file name (as the debugger knows it by) this will
|
111 |
+
return a CodeContainer interface suitable for use.
|
112 |
+
|
113 |
+
This provides a simple base imlpementation that simply supports
|
114 |
+
a dictionary of nodes and providers.
|
115 |
+
"""
|
116 |
+
|
117 |
+
def __init__(self):
|
118 |
+
self.ccsAndNodes = {}
|
119 |
+
|
120 |
+
def AddCodeContainer(self, cc, node=None):
|
121 |
+
fname = GetGoodFileName(cc.fileName)
|
122 |
+
self.ccsAndNodes[fname] = cc, node
|
123 |
+
|
124 |
+
def FromFileName(self, fname):
|
125 |
+
cc, node = self.ccsAndNodes.get(GetGoodFileName(fname), (None, None))
|
126 |
+
# if cc is None:
|
127 |
+
# print "FromFileName for %s returning None" % fname
|
128 |
+
return cc
|
129 |
+
|
130 |
+
def Close(self):
|
131 |
+
for cc, node in self.ccsAndNodes.values():
|
132 |
+
try:
|
133 |
+
# Must close the node before closing the provider
|
134 |
+
# as node may make calls on provider (eg Reset breakpoints etc)
|
135 |
+
if node is not None:
|
136 |
+
node.Close()
|
137 |
+
cc._Close()
|
138 |
+
except pythoncom.com_error:
|
139 |
+
pass
|
140 |
+
self.ccsAndNodes = {}
|
MLPY/Lib/site-packages/win32comext/axdebug/dump.py
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import traceback
|
2 |
+
|
3 |
+
import pythoncom
|
4 |
+
from win32com.axdebug import axdebug
|
5 |
+
from win32com.client.util import Enumerator
|
6 |
+
|
7 |
+
|
8 |
+
def DumpDebugApplicationNode(node, level=0):
|
9 |
+
# Recursive dump of a DebugApplicationNode
|
10 |
+
spacer = " " * level
|
11 |
+
for desc, attr in [
|
12 |
+
("Node Name", axdebug.DOCUMENTNAMETYPE_APPNODE),
|
13 |
+
("Title", axdebug.DOCUMENTNAMETYPE_TITLE),
|
14 |
+
("Filename", axdebug.DOCUMENTNAMETYPE_FILE_TAIL),
|
15 |
+
("URL", axdebug.DOCUMENTNAMETYPE_URL),
|
16 |
+
]:
|
17 |
+
try:
|
18 |
+
info = node.GetName(attr)
|
19 |
+
except pythoncom.com_error:
|
20 |
+
info = "<N/A>"
|
21 |
+
print("%s%s: %s" % (spacer, desc, info))
|
22 |
+
try:
|
23 |
+
doc = node.GetDocument()
|
24 |
+
except pythoncom.com_error:
|
25 |
+
doc = None
|
26 |
+
if doc:
|
27 |
+
doctext = doc.QueryInterface(axdebug.IID_IDebugDocumentText)
|
28 |
+
numLines, numChars = doctext.GetSize()
|
29 |
+
# text, attr = doctext.GetText(0, 20, 1)
|
30 |
+
text, attr = doctext.GetText(0, numChars, 1)
|
31 |
+
print(
|
32 |
+
"%sText is %s, %d bytes long" % (spacer, repr(text[:40] + "..."), len(text))
|
33 |
+
)
|
34 |
+
else:
|
35 |
+
print("%s%s" % (spacer, "<No document available>"))
|
36 |
+
|
37 |
+
for child in Enumerator(node.EnumChildren()):
|
38 |
+
DumpDebugApplicationNode(child, level + 1)
|
39 |
+
|
40 |
+
|
41 |
+
def dumpall():
|
42 |
+
dm = pythoncom.CoCreateInstance(
|
43 |
+
axdebug.CLSID_MachineDebugManager,
|
44 |
+
None,
|
45 |
+
pythoncom.CLSCTX_ALL,
|
46 |
+
axdebug.IID_IMachineDebugManager,
|
47 |
+
)
|
48 |
+
e = Enumerator(dm.EnumApplications())
|
49 |
+
for app in e:
|
50 |
+
print("Application: %s" % app.GetName())
|
51 |
+
node = (
|
52 |
+
app.GetRootNode()
|
53 |
+
) # of type PyIDebugApplicationNode->PyIDebugDocumentProvider->PyIDebugDocumentInfo
|
54 |
+
DumpDebugApplicationNode(node)
|
55 |
+
|
56 |
+
|
57 |
+
if __name__ == "__main__":
|
58 |
+
try:
|
59 |
+
dumpall()
|
60 |
+
except:
|
61 |
+
traceback.print_exc()
|
MLPY/Lib/site-packages/win32comext/axdebug/expressions.py
ADDED
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import io
|
2 |
+
import string
|
3 |
+
import sys
|
4 |
+
import traceback
|
5 |
+
from pprint import pprint
|
6 |
+
|
7 |
+
import winerror
|
8 |
+
from win32com.server.exception import COMException
|
9 |
+
|
10 |
+
from . import axdebug, gateways
|
11 |
+
from .util import RaiseNotImpl, _wrap, _wrap_remove
|
12 |
+
|
13 |
+
|
14 |
+
# Given an object, return a nice string
|
15 |
+
def MakeNiceString(ob):
|
16 |
+
stream = io.StringIO()
|
17 |
+
pprint(ob, stream)
|
18 |
+
return string.strip(stream.getvalue())
|
19 |
+
|
20 |
+
|
21 |
+
class ProvideExpressionContexts(gateways.ProvideExpressionContexts):
|
22 |
+
pass
|
23 |
+
|
24 |
+
|
25 |
+
class ExpressionContext(gateways.DebugExpressionContext):
|
26 |
+
def __init__(self, frame):
|
27 |
+
self.frame = frame
|
28 |
+
|
29 |
+
def ParseLanguageText(self, code, radix, delim, flags):
|
30 |
+
return _wrap(
|
31 |
+
Expression(self.frame, code, radix, delim, flags),
|
32 |
+
axdebug.IID_IDebugExpression,
|
33 |
+
)
|
34 |
+
|
35 |
+
def GetLanguageInfo(self):
|
36 |
+
# print "GetLanguageInfo"
|
37 |
+
return "Python", "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"
|
38 |
+
|
39 |
+
|
40 |
+
class Expression(gateways.DebugExpression):
|
41 |
+
def __init__(self, frame, code, radix, delim, flags):
|
42 |
+
self.callback = None
|
43 |
+
self.frame = frame
|
44 |
+
self.code = code
|
45 |
+
self.radix = radix
|
46 |
+
self.delim = delim
|
47 |
+
self.flags = flags
|
48 |
+
self.isComplete = 0
|
49 |
+
self.result = None
|
50 |
+
self.hresult = winerror.E_UNEXPECTED
|
51 |
+
|
52 |
+
def Start(self, callback):
|
53 |
+
try:
|
54 |
+
try:
|
55 |
+
try:
|
56 |
+
self.result = eval(
|
57 |
+
self.code, self.frame.f_globals, self.frame.f_locals
|
58 |
+
)
|
59 |
+
except SyntaxError:
|
60 |
+
exec(self.code, self.frame.f_globals, self.frame.f_locals)
|
61 |
+
self.result = ""
|
62 |
+
self.hresult = 0
|
63 |
+
except:
|
64 |
+
l = traceback.format_exception_only(
|
65 |
+
sys.exc_info()[0], sys.exc_info()[1]
|
66 |
+
)
|
67 |
+
# l is a list of strings with trailing "\n"
|
68 |
+
self.result = string.join(map(lambda s: s[:-1], l), "\n")
|
69 |
+
self.hresult = winerror.E_FAIL
|
70 |
+
finally:
|
71 |
+
self.isComplete = 1
|
72 |
+
callback.onComplete()
|
73 |
+
|
74 |
+
def Abort(self):
|
75 |
+
print("** ABORT **")
|
76 |
+
|
77 |
+
def QueryIsComplete(self):
|
78 |
+
return self.isComplete
|
79 |
+
|
80 |
+
def GetResultAsString(self):
|
81 |
+
# print "GetStrAsResult returning", self.result
|
82 |
+
return self.hresult, MakeNiceString(self.result)
|
83 |
+
|
84 |
+
def GetResultAsDebugProperty(self):
|
85 |
+
result = _wrap(
|
86 |
+
DebugProperty(self.code, self.result, None, self.hresult),
|
87 |
+
axdebug.IID_IDebugProperty,
|
88 |
+
)
|
89 |
+
return self.hresult, result
|
90 |
+
|
91 |
+
|
92 |
+
def MakeEnumDebugProperty(object, dwFieldSpec, nRadix, iid, stackFrame=None):
|
93 |
+
name_vals = []
|
94 |
+
if hasattr(object, "items") and hasattr(object, "keys"): # If it is a dict.
|
95 |
+
name_vals = iter(object.items())
|
96 |
+
dictionary = object
|
97 |
+
elif hasattr(object, "__dict__"): # object with dictionary, module
|
98 |
+
name_vals = iter(object.__dict__.items())
|
99 |
+
dictionary = object.__dict__
|
100 |
+
infos = []
|
101 |
+
for name, val in name_vals:
|
102 |
+
infos.append(
|
103 |
+
GetPropertyInfo(name, val, dwFieldSpec, nRadix, 0, dictionary, stackFrame)
|
104 |
+
)
|
105 |
+
return _wrap(EnumDebugPropertyInfo(infos), axdebug.IID_IEnumDebugPropertyInfo)
|
106 |
+
|
107 |
+
|
108 |
+
def GetPropertyInfo(
|
109 |
+
obname, obvalue, dwFieldSpec, nRadix, hresult=0, dictionary=None, stackFrame=None
|
110 |
+
):
|
111 |
+
# returns a tuple
|
112 |
+
name = typ = value = fullname = attrib = dbgprop = None
|
113 |
+
if dwFieldSpec & axdebug.DBGPROP_INFO_VALUE:
|
114 |
+
value = MakeNiceString(obvalue)
|
115 |
+
if dwFieldSpec & axdebug.DBGPROP_INFO_NAME:
|
116 |
+
name = obname
|
117 |
+
if dwFieldSpec & axdebug.DBGPROP_INFO_TYPE:
|
118 |
+
if hresult:
|
119 |
+
typ = "Error"
|
120 |
+
else:
|
121 |
+
try:
|
122 |
+
typ = type(obvalue).__name__
|
123 |
+
except AttributeError:
|
124 |
+
typ = str(type(obvalue))
|
125 |
+
if dwFieldSpec & axdebug.DBGPROP_INFO_FULLNAME:
|
126 |
+
fullname = obname
|
127 |
+
if dwFieldSpec & axdebug.DBGPROP_INFO_ATTRIBUTES:
|
128 |
+
if hasattr(obvalue, "has_key") or hasattr(
|
129 |
+
obvalue, "__dict__"
|
130 |
+
): # If it is a dict or object
|
131 |
+
attrib = axdebug.DBGPROP_ATTRIB_VALUE_IS_EXPANDABLE
|
132 |
+
else:
|
133 |
+
attrib = 0
|
134 |
+
if dwFieldSpec & axdebug.DBGPROP_INFO_DEBUGPROP:
|
135 |
+
dbgprop = _wrap(
|
136 |
+
DebugProperty(name, obvalue, None, hresult, dictionary, stackFrame),
|
137 |
+
axdebug.IID_IDebugProperty,
|
138 |
+
)
|
139 |
+
return name, typ, value, fullname, attrib, dbgprop
|
140 |
+
|
141 |
+
|
142 |
+
from win32com.server.util import ListEnumeratorGateway
|
143 |
+
|
144 |
+
|
145 |
+
class EnumDebugPropertyInfo(ListEnumeratorGateway):
|
146 |
+
"""A class to expose a Python sequence as an EnumDebugCodeContexts
|
147 |
+
|
148 |
+
Create an instance of this class passing a sequence (list, tuple, or
|
149 |
+
any sequence protocol supporting object) and it will automatically
|
150 |
+
support the EnumDebugCodeContexts interface for the object.
|
151 |
+
|
152 |
+
"""
|
153 |
+
|
154 |
+
_public_methods_ = ListEnumeratorGateway._public_methods_ + ["GetCount"]
|
155 |
+
_com_interfaces_ = [axdebug.IID_IEnumDebugPropertyInfo]
|
156 |
+
|
157 |
+
def GetCount(self):
|
158 |
+
return len(self._list_)
|
159 |
+
|
160 |
+
def _wrap(self, ob):
|
161 |
+
return ob
|
162 |
+
|
163 |
+
|
164 |
+
class DebugProperty:
|
165 |
+
_com_interfaces_ = [axdebug.IID_IDebugProperty]
|
166 |
+
_public_methods_ = [
|
167 |
+
"GetPropertyInfo",
|
168 |
+
"GetExtendedInfo",
|
169 |
+
"SetValueAsString",
|
170 |
+
"EnumMembers",
|
171 |
+
"GetParent",
|
172 |
+
]
|
173 |
+
|
174 |
+
def __init__(
|
175 |
+
self, name, value, parent=None, hresult=0, dictionary=None, stackFrame=None
|
176 |
+
):
|
177 |
+
self.name = name
|
178 |
+
self.value = value
|
179 |
+
self.parent = parent
|
180 |
+
self.hresult = hresult
|
181 |
+
self.dictionary = dictionary
|
182 |
+
self.stackFrame = stackFrame
|
183 |
+
|
184 |
+
def GetPropertyInfo(self, dwFieldSpec, nRadix):
|
185 |
+
return GetPropertyInfo(
|
186 |
+
self.name,
|
187 |
+
self.value,
|
188 |
+
dwFieldSpec,
|
189 |
+
nRadix,
|
190 |
+
self.hresult,
|
191 |
+
dictionary,
|
192 |
+
stackFrame,
|
193 |
+
)
|
194 |
+
|
195 |
+
def GetExtendedInfo(self): ### Note - not in the framework.
|
196 |
+
RaiseNotImpl("DebugProperty::GetExtendedInfo")
|
197 |
+
|
198 |
+
def SetValueAsString(self, value, radix):
|
199 |
+
if self.stackFrame and self.dictionary:
|
200 |
+
self.dictionary[self.name] = eval(
|
201 |
+
value, self.stackFrame.f_globals, self.stackFrame.f_locals
|
202 |
+
)
|
203 |
+
else:
|
204 |
+
RaiseNotImpl("DebugProperty::SetValueAsString")
|
205 |
+
|
206 |
+
def EnumMembers(self, dwFieldSpec, nRadix, iid):
|
207 |
+
# Returns IEnumDebugPropertyInfo
|
208 |
+
return MakeEnumDebugProperty(
|
209 |
+
self.value, dwFieldSpec, nRadix, iid, self.stackFrame
|
210 |
+
)
|
211 |
+
|
212 |
+
def GetParent(self):
|
213 |
+
# return IDebugProperty
|
214 |
+
RaiseNotImpl("DebugProperty::GetParent")
|
MLPY/Lib/site-packages/win32comext/axdebug/gateways.py
ADDED
@@ -0,0 +1,583 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Classes which describe interfaces.
|
2 |
+
|
3 |
+
import pythoncom
|
4 |
+
import win32com.server.connect
|
5 |
+
import winerror
|
6 |
+
from win32com.axdebug import axdebug
|
7 |
+
from win32com.axdebug.util import RaiseNotImpl, _wrap
|
8 |
+
from win32com.server.exception import Exception
|
9 |
+
from win32com.server.util import ListEnumeratorGateway
|
10 |
+
|
11 |
+
|
12 |
+
class EnumDebugCodeContexts(ListEnumeratorGateway):
|
13 |
+
"""A class to expose a Python sequence as an EnumDebugCodeContexts
|
14 |
+
|
15 |
+
Create an instance of this class passing a sequence (list, tuple, or
|
16 |
+
any sequence protocol supporting object) and it will automatically
|
17 |
+
support the EnumDebugCodeContexts interface for the object.
|
18 |
+
|
19 |
+
"""
|
20 |
+
|
21 |
+
_com_interfaces_ = [axdebug.IID_IEnumDebugCodeContexts]
|
22 |
+
|
23 |
+
|
24 |
+
class EnumDebugStackFrames(ListEnumeratorGateway):
|
25 |
+
"""A class to expose a Python sequence as an EnumDebugStackFrames
|
26 |
+
|
27 |
+
Create an instance of this class passing a sequence (list, tuple, or
|
28 |
+
any sequence protocol supporting object) and it will automatically
|
29 |
+
support the EnumDebugStackFrames interface for the object.
|
30 |
+
|
31 |
+
"""
|
32 |
+
|
33 |
+
_com_interfaces_ = [axdebug.IID_IEnumDebugStackFrames]
|
34 |
+
|
35 |
+
|
36 |
+
class EnumDebugApplicationNodes(ListEnumeratorGateway):
|
37 |
+
"""A class to expose a Python sequence as an EnumDebugStackFrames
|
38 |
+
|
39 |
+
Create an instance of this class passing a sequence (list, tuple, or
|
40 |
+
any sequence protocol supporting object) and it will automatically
|
41 |
+
support the EnumDebugApplicationNodes interface for the object.
|
42 |
+
|
43 |
+
"""
|
44 |
+
|
45 |
+
_com_interfaces_ = [axdebug.IID_IEnumDebugApplicationNodes]
|
46 |
+
|
47 |
+
|
48 |
+
class EnumRemoteDebugApplications(ListEnumeratorGateway):
|
49 |
+
_com_interfaces_ = [axdebug.IID_IEnumRemoteDebugApplications]
|
50 |
+
|
51 |
+
|
52 |
+
class EnumRemoteDebugApplicationThreads(ListEnumeratorGateway):
|
53 |
+
_com_interfaces_ = [axdebug.IID_IEnumRemoteDebugApplicationThreads]
|
54 |
+
|
55 |
+
|
56 |
+
class DebugDocumentInfo:
|
57 |
+
_public_methods_ = ["GetName", "GetDocumentClassId"]
|
58 |
+
_com_interfaces_ = [axdebug.IID_IDebugDocumentInfo]
|
59 |
+
|
60 |
+
def __init__(self):
|
61 |
+
pass
|
62 |
+
|
63 |
+
def GetName(self, dnt):
|
64 |
+
"""Get the one of the name of the document
|
65 |
+
dnt -- int DOCUMENTNAMETYPE
|
66 |
+
"""
|
67 |
+
RaiseNotImpl("GetName")
|
68 |
+
|
69 |
+
def GetDocumentClassId(self):
|
70 |
+
"""
|
71 |
+
Result must be an IID object (or string representing one).
|
72 |
+
"""
|
73 |
+
RaiseNotImpl("GetDocumentClassId")
|
74 |
+
|
75 |
+
|
76 |
+
class DebugDocumentProvider(DebugDocumentInfo):
|
77 |
+
_public_methods_ = DebugDocumentInfo._public_methods_ + ["GetDocument"]
|
78 |
+
_com_interfaces_ = DebugDocumentInfo._com_interfaces_ + [
|
79 |
+
axdebug.IID_IDebugDocumentProvider
|
80 |
+
]
|
81 |
+
|
82 |
+
def GetDocument(self):
|
83 |
+
RaiseNotImpl("GetDocument")
|
84 |
+
|
85 |
+
|
86 |
+
class DebugApplicationNode(DebugDocumentProvider):
|
87 |
+
"""Provides the functionality of IDebugDocumentProvider, plus a context within a project tree."""
|
88 |
+
|
89 |
+
_public_methods_ = (
|
90 |
+
"""EnumChildren GetParent SetDocumentProvider
|
91 |
+
Close Attach Detach""".split()
|
92 |
+
+ DebugDocumentProvider._public_methods_
|
93 |
+
)
|
94 |
+
_com_interfaces_ = [
|
95 |
+
axdebug.IID_IDebugDocumentProvider
|
96 |
+
] + DebugDocumentProvider._com_interfaces_
|
97 |
+
|
98 |
+
def __init__(self):
|
99 |
+
DebugDocumentProvider.__init__(self)
|
100 |
+
|
101 |
+
def EnumChildren(self):
|
102 |
+
# Result is type PyIEnumDebugApplicationNodes
|
103 |
+
RaiseNotImpl("EnumChildren")
|
104 |
+
|
105 |
+
def GetParent(self):
|
106 |
+
# result is type PyIDebugApplicationNode
|
107 |
+
RaiseNotImpl("GetParent")
|
108 |
+
|
109 |
+
def SetDocumentProvider(self, pddp): # PyIDebugDocumentProvider pddp
|
110 |
+
# void result.
|
111 |
+
RaiseNotImpl("SetDocumentProvider")
|
112 |
+
|
113 |
+
def Close(self):
|
114 |
+
# void result.
|
115 |
+
RaiseNotImpl("Close")
|
116 |
+
|
117 |
+
def Attach(self, parent): # PyIDebugApplicationNode
|
118 |
+
# void result.
|
119 |
+
RaiseNotImpl("Attach")
|
120 |
+
|
121 |
+
def Detach(self):
|
122 |
+
# void result.
|
123 |
+
RaiseNotImpl("Detach")
|
124 |
+
|
125 |
+
|
126 |
+
class DebugApplicationNodeEvents:
|
127 |
+
"""Event interface for DebugApplicationNode object."""
|
128 |
+
|
129 |
+
_public_methods_ = "onAddChild onRemoveChild onDetach".split()
|
130 |
+
_com_interfaces_ = [axdebug.IID_IDebugApplicationNodeEvents]
|
131 |
+
|
132 |
+
def __init__(self):
|
133 |
+
pass
|
134 |
+
|
135 |
+
def onAddChild(self, child): # PyIDebugApplicationNode
|
136 |
+
# void result.
|
137 |
+
RaiseNotImpl("onAddChild")
|
138 |
+
|
139 |
+
def onRemoveChild(self, child): # PyIDebugApplicationNode
|
140 |
+
# void result.
|
141 |
+
RaiseNotImpl("onRemoveChild")
|
142 |
+
|
143 |
+
def onDetach(self):
|
144 |
+
# void result.
|
145 |
+
RaiseNotImpl("onDetach")
|
146 |
+
|
147 |
+
def onAttach(self, parent): # PyIDebugApplicationNode
|
148 |
+
# void result.
|
149 |
+
RaiseNotImpl("onAttach")
|
150 |
+
|
151 |
+
|
152 |
+
class DebugDocument(DebugDocumentInfo):
|
153 |
+
"""The base interface to all debug documents."""
|
154 |
+
|
155 |
+
_public_methods_ = DebugDocumentInfo._public_methods_
|
156 |
+
_com_interfaces_ = [axdebug.IID_IDebugDocument] + DebugDocumentInfo._com_interfaces_
|
157 |
+
|
158 |
+
|
159 |
+
class DebugDocumentText(DebugDocument):
|
160 |
+
"""The interface to a text only debug document."""
|
161 |
+
|
162 |
+
_com_interfaces_ = [axdebug.IID_IDebugDocumentText] + DebugDocument._com_interfaces_
|
163 |
+
_public_methods_ = [
|
164 |
+
"GetDocumentAttributes",
|
165 |
+
"GetSize",
|
166 |
+
"GetPositionOfLine",
|
167 |
+
"GetLineOfPosition",
|
168 |
+
"GetText",
|
169 |
+
"GetPositionOfContext",
|
170 |
+
"GetContextOfPosition",
|
171 |
+
] + DebugDocument._public_methods_
|
172 |
+
|
173 |
+
def __init__(self):
|
174 |
+
pass
|
175 |
+
|
176 |
+
# IDebugDocumentText
|
177 |
+
def GetDocumentAttributes(self):
|
178 |
+
# Result is int (TEXT_DOC_ATTR)
|
179 |
+
RaiseNotImpl("GetDocumentAttributes")
|
180 |
+
|
181 |
+
def GetSize(self):
|
182 |
+
# Result is (numLines, numChars)
|
183 |
+
RaiseNotImpl("GetSize")
|
184 |
+
|
185 |
+
def GetPositionOfLine(self, cLineNumber):
|
186 |
+
# Result is int char position
|
187 |
+
RaiseNotImpl("GetPositionOfLine")
|
188 |
+
|
189 |
+
def GetLineOfPosition(self, charPos):
|
190 |
+
# Result is int, int (lineNo, offset)
|
191 |
+
RaiseNotImpl("GetLineOfPosition")
|
192 |
+
|
193 |
+
def GetText(self, charPos, maxChars, wantAttr):
|
194 |
+
"""Params
|
195 |
+
charPos -- integer
|
196 |
+
maxChars -- integer
|
197 |
+
wantAttr -- Should the function compute attributes.
|
198 |
+
|
199 |
+
Return value must be (string, attribtues). attributes may be
|
200 |
+
None if(not wantAttr)
|
201 |
+
"""
|
202 |
+
RaiseNotImpl("GetText")
|
203 |
+
|
204 |
+
def GetPositionOfContext(self, debugDocumentContext):
|
205 |
+
"""Params
|
206 |
+
debugDocumentContext -- a PyIDebugDocumentContext object.
|
207 |
+
|
208 |
+
Return value must be (charPos, numChars)
|
209 |
+
"""
|
210 |
+
RaiseNotImpl("GetPositionOfContext")
|
211 |
+
|
212 |
+
def GetContextOfPosition(self, charPos, maxChars):
|
213 |
+
"""Params are integers.
|
214 |
+
Return value must be PyIDebugDocumentContext object
|
215 |
+
"""
|
216 |
+
print(self)
|
217 |
+
RaiseNotImpl("GetContextOfPosition")
|
218 |
+
|
219 |
+
|
220 |
+
class DebugDocumentTextExternalAuthor:
|
221 |
+
"""Allow external editors to edit file-based debugger documents, and to notify the document when the source file has been changed."""
|
222 |
+
|
223 |
+
_public_methods_ = ["GetPathName", "GetFileName", "NotifyChanged"]
|
224 |
+
_com_interfaces_ = [axdebug.IID_IDebugDocumentTextExternalAuthor]
|
225 |
+
|
226 |
+
def __init__(self):
|
227 |
+
pass
|
228 |
+
|
229 |
+
def GetPathName(self):
|
230 |
+
"""Return the full path (including file name) to the document's source file.
|
231 |
+
|
232 |
+
Result must be (filename, fIsOriginal), where
|
233 |
+
- if fIsOriginalPath is TRUE if the path refers to the original file for the document.
|
234 |
+
- if fIsOriginalPath is FALSE if the path refers to a newly created temporary file.
|
235 |
+
|
236 |
+
raise Exception(winerror.E_FAIL) if no source file can be created/determined.
|
237 |
+
"""
|
238 |
+
RaiseNotImpl("GetPathName")
|
239 |
+
|
240 |
+
def GetFileName(self):
|
241 |
+
"""Return just the name of the document, with no path information. (Used for "Save As...")
|
242 |
+
|
243 |
+
Result is a string
|
244 |
+
"""
|
245 |
+
RaiseNotImpl("GetFileName")
|
246 |
+
|
247 |
+
def NotifyChanged(self):
|
248 |
+
"""Notify the host that the document's source file has been saved and
|
249 |
+
that its contents should be refreshed.
|
250 |
+
"""
|
251 |
+
RaiseNotImpl("NotifyChanged")
|
252 |
+
|
253 |
+
|
254 |
+
class DebugDocumentTextEvents:
|
255 |
+
_public_methods_ = """onDestroy onInsertText onRemoveText
|
256 |
+
onReplaceText onUpdateTextAttributes
|
257 |
+
onUpdateDocumentAttributes""".split()
|
258 |
+
_com_interfaces_ = [axdebug.IID_IDebugDocumentTextEvents]
|
259 |
+
|
260 |
+
def __init__(self):
|
261 |
+
pass
|
262 |
+
|
263 |
+
def onDestroy(self):
|
264 |
+
# Result is void.
|
265 |
+
RaiseNotImpl("onDestroy")
|
266 |
+
|
267 |
+
def onInsertText(self, cCharacterPosition, cNumToInsert):
|
268 |
+
# Result is void.
|
269 |
+
RaiseNotImpl("onInsertText")
|
270 |
+
|
271 |
+
def onRemoveText(self, cCharacterPosition, cNumToRemove):
|
272 |
+
# Result is void.
|
273 |
+
RaiseNotImpl("onRemoveText")
|
274 |
+
|
275 |
+
def onReplaceText(self, cCharacterPosition, cNumToReplace):
|
276 |
+
# Result is void.
|
277 |
+
RaiseNotImpl("onReplaceText")
|
278 |
+
|
279 |
+
def onUpdateTextAttributes(self, cCharacterPosition, cNumToUpdate):
|
280 |
+
# Result is void.
|
281 |
+
RaiseNotImpl("onUpdateTextAttributes")
|
282 |
+
|
283 |
+
def onUpdateDocumentAttributes(self, textdocattr): # TEXT_DOC_ATTR
|
284 |
+
# Result is void.
|
285 |
+
RaiseNotImpl("onUpdateDocumentAttributes")
|
286 |
+
|
287 |
+
|
288 |
+
class DebugDocumentContext:
|
289 |
+
_public_methods_ = ["GetDocument", "EnumCodeContexts"]
|
290 |
+
_com_interfaces_ = [axdebug.IID_IDebugDocumentContext]
|
291 |
+
|
292 |
+
def __init__(self):
|
293 |
+
pass
|
294 |
+
|
295 |
+
def GetDocument(self):
|
296 |
+
"""Return value must be a PyIDebugDocument object"""
|
297 |
+
RaiseNotImpl("GetDocument")
|
298 |
+
|
299 |
+
def EnumCodeContexts(self):
|
300 |
+
"""Return value must be a PyIEnumDebugCodeContexts object"""
|
301 |
+
RaiseNotImpl("EnumCodeContexts")
|
302 |
+
|
303 |
+
|
304 |
+
class DebugCodeContext:
|
305 |
+
_public_methods_ = ["GetDocumentContext", "SetBreakPoint"]
|
306 |
+
_com_interfaces_ = [axdebug.IID_IDebugCodeContext]
|
307 |
+
|
308 |
+
def __init__(self):
|
309 |
+
pass
|
310 |
+
|
311 |
+
def GetDocumentContext(self):
|
312 |
+
"""Return value must be a PyIDebugDocumentContext object"""
|
313 |
+
RaiseNotImpl("GetDocumentContext")
|
314 |
+
|
315 |
+
def SetBreakPoint(self, bps):
|
316 |
+
"""bps -- an integer with flags."""
|
317 |
+
RaiseNotImpl("SetBreakPoint")
|
318 |
+
|
319 |
+
|
320 |
+
class DebugStackFrame:
|
321 |
+
"""Abstraction representing a logical stack frame on the stack of a thread."""
|
322 |
+
|
323 |
+
_public_methods_ = [
|
324 |
+
"GetCodeContext",
|
325 |
+
"GetDescriptionString",
|
326 |
+
"GetLanguageString",
|
327 |
+
"GetThread",
|
328 |
+
"GetDebugProperty",
|
329 |
+
]
|
330 |
+
_com_interfaces_ = [axdebug.IID_IDebugStackFrame]
|
331 |
+
|
332 |
+
def __init__(self):
|
333 |
+
pass
|
334 |
+
|
335 |
+
def GetCodeContext(self):
|
336 |
+
"""Returns the current code context associated with the stack frame.
|
337 |
+
|
338 |
+
Return value must be a IDebugCodeContext object
|
339 |
+
"""
|
340 |
+
RaiseNotImpl("GetCodeContext")
|
341 |
+
|
342 |
+
def GetDescriptionString(self, fLong):
|
343 |
+
"""Returns a textual description of the stack frame.
|
344 |
+
|
345 |
+
fLong -- A flag indicating if the long name is requested.
|
346 |
+
"""
|
347 |
+
RaiseNotImpl("GetDescriptionString")
|
348 |
+
|
349 |
+
def GetLanguageString(self):
|
350 |
+
"""Returns a short or long textual description of the language.
|
351 |
+
|
352 |
+
fLong -- A flag indicating if the long name is requested.
|
353 |
+
"""
|
354 |
+
RaiseNotImpl("GetLanguageString")
|
355 |
+
|
356 |
+
def GetThread(self):
|
357 |
+
"""Returns the thread associated with this stack frame.
|
358 |
+
|
359 |
+
Result must be a IDebugApplicationThread
|
360 |
+
"""
|
361 |
+
RaiseNotImpl("GetThread")
|
362 |
+
|
363 |
+
def GetDebugProperty(self):
|
364 |
+
RaiseNotImpl("GetDebugProperty")
|
365 |
+
|
366 |
+
|
367 |
+
class DebugDocumentHost:
|
368 |
+
"""The interface from the IDebugDocumentHelper back to
|
369 |
+
the smart host or language engine. This interface
|
370 |
+
exposes host specific functionality such as syntax coloring.
|
371 |
+
"""
|
372 |
+
|
373 |
+
_public_methods_ = [
|
374 |
+
"GetDeferredText",
|
375 |
+
"GetScriptTextAttributes",
|
376 |
+
"OnCreateDocumentContext",
|
377 |
+
"GetPathName",
|
378 |
+
"GetFileName",
|
379 |
+
"NotifyChanged",
|
380 |
+
]
|
381 |
+
_com_interfaces_ = [axdebug.IID_IDebugDocumentHost]
|
382 |
+
|
383 |
+
def __init__(self):
|
384 |
+
pass
|
385 |
+
|
386 |
+
def GetDeferredText(self, dwTextStartCookie, maxChars, bWantAttr):
|
387 |
+
RaiseNotImpl("GetDeferredText")
|
388 |
+
|
389 |
+
def GetScriptTextAttributes(self, codeText, delimterText, flags):
|
390 |
+
# Result must be an attribute sequence of same "length" as the code.
|
391 |
+
RaiseNotImpl("GetScriptTextAttributes")
|
392 |
+
|
393 |
+
def OnCreateDocumentContext(self):
|
394 |
+
# Result must be a PyIUnknown
|
395 |
+
RaiseNotImpl("OnCreateDocumentContext")
|
396 |
+
|
397 |
+
def GetPathName(self):
|
398 |
+
# Result must be (string, int) where the int is a BOOL
|
399 |
+
# - TRUE if the path refers to the original file for the document.
|
400 |
+
# - FALSE if the path refers to a newly created temporary file.
|
401 |
+
# - raise Exception(scode=E_FAIL) if no source file can be created/determined.
|
402 |
+
RaiseNotImpl("GetPathName")
|
403 |
+
|
404 |
+
def GetFileName(self):
|
405 |
+
# Result is a string with just the name of the document, no path information.
|
406 |
+
RaiseNotImpl("GetFileName")
|
407 |
+
|
408 |
+
def NotifyChanged(self):
|
409 |
+
RaiseNotImpl("NotifyChanged")
|
410 |
+
|
411 |
+
|
412 |
+
# Additional gateway related functions.
|
413 |
+
|
414 |
+
|
415 |
+
class DebugDocumentTextConnectServer:
|
416 |
+
_public_methods_ = (
|
417 |
+
win32com.server.connect.IConnectionPointContainer_methods
|
418 |
+
+ win32com.server.connect.IConnectionPoint_methods
|
419 |
+
)
|
420 |
+
_com_interfaces_ = [
|
421 |
+
pythoncom.IID_IConnectionPoint,
|
422 |
+
pythoncom.IID_IConnectionPointContainer,
|
423 |
+
]
|
424 |
+
|
425 |
+
# IConnectionPoint interfaces
|
426 |
+
def __init__(self):
|
427 |
+
self.cookieNo = -1
|
428 |
+
self.connections = {}
|
429 |
+
|
430 |
+
def EnumConnections(self):
|
431 |
+
RaiseNotImpl("EnumConnections")
|
432 |
+
|
433 |
+
def GetConnectionInterface(self):
|
434 |
+
RaiseNotImpl("GetConnectionInterface")
|
435 |
+
|
436 |
+
def GetConnectionPointContainer(self):
|
437 |
+
return _wrap(self)
|
438 |
+
|
439 |
+
def Advise(self, pUnk):
|
440 |
+
# Creates a connection to the client. Simply allocate a new cookie,
|
441 |
+
# find the clients interface, and store it in a dictionary.
|
442 |
+
interface = pUnk.QueryInterface(axdebug.IID_IDebugDocumentTextEvents, 1)
|
443 |
+
self.cookieNo = self.cookieNo + 1
|
444 |
+
self.connections[self.cookieNo] = interface
|
445 |
+
return self.cookieNo
|
446 |
+
|
447 |
+
def Unadvise(self, cookie):
|
448 |
+
# Destroy a connection - simply delete interface from the map.
|
449 |
+
try:
|
450 |
+
del self.connections[cookie]
|
451 |
+
except KeyError:
|
452 |
+
return Exception(scode=winerror.E_UNEXPECTED)
|
453 |
+
|
454 |
+
# IConnectionPointContainer interfaces
|
455 |
+
def EnumConnectionPoints(self):
|
456 |
+
RaiseNotImpl("EnumConnectionPoints")
|
457 |
+
|
458 |
+
def FindConnectionPoint(self, iid):
|
459 |
+
# Find a connection we support. Only support the single event interface.
|
460 |
+
if iid == axdebug.IID_IDebugDocumentTextEvents:
|
461 |
+
return _wrap(self)
|
462 |
+
raise Exception(scode=winerror.E_NOINTERFACE) # ??
|
463 |
+
|
464 |
+
|
465 |
+
class RemoteDebugApplicationEvents:
|
466 |
+
_public_methods_ = [
|
467 |
+
"OnConnectDebugger",
|
468 |
+
"OnDisconnectDebugger",
|
469 |
+
"OnSetName",
|
470 |
+
"OnDebugOutput",
|
471 |
+
"OnClose",
|
472 |
+
"OnEnterBreakPoint",
|
473 |
+
"OnLeaveBreakPoint",
|
474 |
+
"OnCreateThread",
|
475 |
+
"OnDestroyThread",
|
476 |
+
"OnBreakFlagChange",
|
477 |
+
]
|
478 |
+
_com_interfaces_ = [axdebug.IID_IRemoteDebugApplicationEvents]
|
479 |
+
|
480 |
+
def OnConnectDebugger(self, appDebugger):
|
481 |
+
"""appDebugger -- a PyIApplicationDebugger"""
|
482 |
+
RaiseNotImpl("OnConnectDebugger")
|
483 |
+
|
484 |
+
def OnDisconnectDebugger(self):
|
485 |
+
RaiseNotImpl("OnDisconnectDebugger")
|
486 |
+
|
487 |
+
def OnSetName(self, name):
|
488 |
+
RaiseNotImpl("OnSetName")
|
489 |
+
|
490 |
+
def OnDebugOutput(self, string):
|
491 |
+
RaiseNotImpl("OnDebugOutput")
|
492 |
+
|
493 |
+
def OnClose(self):
|
494 |
+
RaiseNotImpl("OnClose")
|
495 |
+
|
496 |
+
def OnEnterBreakPoint(self, rdat):
|
497 |
+
"""rdat -- PyIRemoteDebugApplicationThread"""
|
498 |
+
RaiseNotImpl("OnEnterBreakPoint")
|
499 |
+
|
500 |
+
def OnLeaveBreakPoint(self, rdat):
|
501 |
+
"""rdat -- PyIRemoteDebugApplicationThread"""
|
502 |
+
RaiseNotImpl("OnLeaveBreakPoint")
|
503 |
+
|
504 |
+
def OnCreateThread(self, rdat):
|
505 |
+
"""rdat -- PyIRemoteDebugApplicationThread"""
|
506 |
+
RaiseNotImpl("OnCreateThread")
|
507 |
+
|
508 |
+
def OnDestroyThread(self, rdat):
|
509 |
+
"""rdat -- PyIRemoteDebugApplicationThread"""
|
510 |
+
RaiseNotImpl("OnDestroyThread")
|
511 |
+
|
512 |
+
def OnBreakFlagChange(self, abf, rdat):
|
513 |
+
"""abf -- int - one of the axdebug.APPBREAKFLAGS constants
|
514 |
+
rdat -- PyIRemoteDebugApplicationThread
|
515 |
+
RaiseNotImpl("OnBreakFlagChange")
|
516 |
+
"""
|
517 |
+
|
518 |
+
|
519 |
+
class DebugExpressionContext:
|
520 |
+
_public_methods_ = ["ParseLanguageText", "GetLanguageInfo"]
|
521 |
+
_com_interfaces_ = [axdebug.IID_IDebugExpressionContext]
|
522 |
+
|
523 |
+
def __init__(self):
|
524 |
+
pass
|
525 |
+
|
526 |
+
def ParseLanguageText(self, code, radix, delim, flags):
|
527 |
+
"""
|
528 |
+
result is IDebugExpression
|
529 |
+
"""
|
530 |
+
RaiseNotImpl("ParseLanguageText")
|
531 |
+
|
532 |
+
def GetLanguageInfo(self):
|
533 |
+
"""
|
534 |
+
result is (string langName, iid langId)
|
535 |
+
"""
|
536 |
+
RaiseNotImpl("GetLanguageInfo")
|
537 |
+
|
538 |
+
|
539 |
+
class DebugExpression:
|
540 |
+
_public_methods_ = [
|
541 |
+
"Start",
|
542 |
+
"Abort",
|
543 |
+
"QueryIsComplete",
|
544 |
+
"GetResultAsString",
|
545 |
+
"GetResultAsDebugProperty",
|
546 |
+
]
|
547 |
+
_com_interfaces_ = [axdebug.IID_IDebugExpression]
|
548 |
+
|
549 |
+
def Start(self, callback):
|
550 |
+
"""
|
551 |
+
callback -- an IDebugExpressionCallback
|
552 |
+
|
553 |
+
result - void
|
554 |
+
"""
|
555 |
+
RaiseNotImpl("Start")
|
556 |
+
|
557 |
+
def Abort(self):
|
558 |
+
"""
|
559 |
+
no params
|
560 |
+
result -- void
|
561 |
+
"""
|
562 |
+
RaiseNotImpl("Abort")
|
563 |
+
|
564 |
+
def QueryIsComplete(self):
|
565 |
+
"""
|
566 |
+
no params
|
567 |
+
result -- void
|
568 |
+
"""
|
569 |
+
RaiseNotImpl("QueryIsComplete")
|
570 |
+
|
571 |
+
def GetResultAsString(self):
|
572 |
+
RaiseNotImpl("GetResultAsString")
|
573 |
+
|
574 |
+
def GetResultAsDebugProperty(self):
|
575 |
+
RaiseNotImpl("GetResultAsDebugProperty")
|
576 |
+
|
577 |
+
|
578 |
+
class ProvideExpressionContexts:
|
579 |
+
_public_methods_ = ["EnumExpressionContexts"]
|
580 |
+
_com_interfaces_ = [axdebug.IID_IProvideExpressionContexts]
|
581 |
+
|
582 |
+
def EnumExpressionContexts(self):
|
583 |
+
RaiseNotImpl("EnumExpressionContexts")
|
MLPY/Lib/site-packages/win32comext/axdebug/stackframe.py
ADDED
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""Support for stack-frames.
|
2 |
+
|
3 |
+
Provides Implements a nearly complete wrapper for a stack frame.
|
4 |
+
"""
|
5 |
+
|
6 |
+
import pythoncom
|
7 |
+
from win32com.server.exception import COMException
|
8 |
+
|
9 |
+
from . import axdebug, expressions, gateways
|
10 |
+
from .util import RaiseNotImpl, _wrap, trace
|
11 |
+
|
12 |
+
# def trace(*args):
|
13 |
+
# pass
|
14 |
+
|
15 |
+
|
16 |
+
class EnumDebugStackFrames(gateways.EnumDebugStackFrames):
|
17 |
+
"""A class that given a debugger object, can return an enumerator
|
18 |
+
of DebugStackFrame objects.
|
19 |
+
"""
|
20 |
+
|
21 |
+
def __init__(self, debugger):
|
22 |
+
infos = []
|
23 |
+
frame = debugger.currentframe
|
24 |
+
# print "Stack check"
|
25 |
+
while frame:
|
26 |
+
# print " Checking frame", frame.f_code.co_filename, frame.f_lineno-1, frame.f_trace,
|
27 |
+
# Get a DebugCodeContext for the stack frame. If we fail, then it
|
28 |
+
# is not debuggable, and therefore not worth displaying.
|
29 |
+
cc = debugger.codeContainerProvider.FromFileName(frame.f_code.co_filename)
|
30 |
+
if cc is not None:
|
31 |
+
try:
|
32 |
+
address = frame.f_locals["__axstack_address__"]
|
33 |
+
except KeyError:
|
34 |
+
# print "Couldnt find stack address for",frame.f_code.co_filename, frame.f_lineno-1
|
35 |
+
# Use this one, even tho it is wrong :-(
|
36 |
+
address = axdebug.GetStackAddress()
|
37 |
+
frameInfo = (
|
38 |
+
DebugStackFrame(frame, frame.f_lineno - 1, cc),
|
39 |
+
address,
|
40 |
+
address + 1,
|
41 |
+
0,
|
42 |
+
None,
|
43 |
+
)
|
44 |
+
infos.append(frameInfo)
|
45 |
+
# print "- Kept!"
|
46 |
+
# else:
|
47 |
+
# print "- rejected"
|
48 |
+
frame = frame.f_back
|
49 |
+
|
50 |
+
gateways.EnumDebugStackFrames.__init__(self, infos, 0)
|
51 |
+
|
52 |
+
# def __del__(self):
|
53 |
+
# print "EnumDebugStackFrames dieing"
|
54 |
+
|
55 |
+
def Next(self, count):
|
56 |
+
return gateways.EnumDebugStackFrames.Next(self, count)
|
57 |
+
|
58 |
+
# def _query_interface_(self, iid):
|
59 |
+
# from win32com.util import IIDToInterfaceName
|
60 |
+
# print "EnumDebugStackFrames QI with %s (%s)" % (IIDToInterfaceName(iid), str(iid))
|
61 |
+
# return 0
|
62 |
+
def _wrap(self, obj):
|
63 |
+
# This enum returns a tuple, with 2 com objects in it.
|
64 |
+
obFrame, min, lim, fFinal, obFinal = obj
|
65 |
+
obFrame = _wrap(obFrame, axdebug.IID_IDebugStackFrame)
|
66 |
+
if obFinal:
|
67 |
+
obFinal = _wrap(obFinal, pythoncom.IID_IUnknown)
|
68 |
+
return obFrame, min, lim, fFinal, obFinal
|
69 |
+
|
70 |
+
|
71 |
+
class DebugStackFrame(gateways.DebugStackFrame):
|
72 |
+
def __init__(self, frame, lineno, codeContainer):
|
73 |
+
self.frame = frame
|
74 |
+
self.lineno = lineno
|
75 |
+
self.codeContainer = codeContainer
|
76 |
+
self.expressionContext = None
|
77 |
+
|
78 |
+
# def __del__(self):
|
79 |
+
# print "DSF dieing"
|
80 |
+
def _query_interface_(self, iid):
|
81 |
+
if iid == axdebug.IID_IDebugExpressionContext:
|
82 |
+
if self.expressionContext is None:
|
83 |
+
self.expressionContext = _wrap(
|
84 |
+
expressions.ExpressionContext(self.frame),
|
85 |
+
axdebug.IID_IDebugExpressionContext,
|
86 |
+
)
|
87 |
+
return self.expressionContext
|
88 |
+
# from win32com.util import IIDToInterfaceName
|
89 |
+
# print "DebugStackFrame QI with %s (%s)" % (IIDToInterfaceName(iid), str(iid))
|
90 |
+
return 0
|
91 |
+
|
92 |
+
#
|
93 |
+
# The following need implementation
|
94 |
+
def GetThread(self):
|
95 |
+
"""Returns the thread associated with this stack frame.
|
96 |
+
|
97 |
+
Result must be a IDebugApplicationThread
|
98 |
+
"""
|
99 |
+
RaiseNotImpl("GetThread")
|
100 |
+
|
101 |
+
def GetCodeContext(self):
|
102 |
+
offset = self.codeContainer.GetPositionOfLine(self.lineno)
|
103 |
+
return self.codeContainer.GetCodeContextAtPosition(offset)
|
104 |
+
|
105 |
+
#
|
106 |
+
# The following are usefully implemented
|
107 |
+
def GetDescriptionString(self, fLong):
|
108 |
+
filename = self.frame.f_code.co_filename
|
109 |
+
s = ""
|
110 |
+
if 0: # fLong:
|
111 |
+
s = s + filename
|
112 |
+
if self.frame.f_code.co_name:
|
113 |
+
s = s + self.frame.f_code.co_name
|
114 |
+
else:
|
115 |
+
s = s + "<lambda>"
|
116 |
+
return s
|
117 |
+
|
118 |
+
def GetLanguageString(self, fLong):
|
119 |
+
if fLong:
|
120 |
+
return "Python ActiveX Scripting Engine"
|
121 |
+
else:
|
122 |
+
return "Python"
|
123 |
+
|
124 |
+
def GetDebugProperty(self):
|
125 |
+
return _wrap(StackFrameDebugProperty(self.frame), axdebug.IID_IDebugProperty)
|
126 |
+
|
127 |
+
|
128 |
+
class DebugStackFrameSniffer:
|
129 |
+
_public_methods_ = ["EnumStackFrames"]
|
130 |
+
_com_interfaces_ = [axdebug.IID_IDebugStackFrameSniffer]
|
131 |
+
|
132 |
+
def __init__(self, debugger):
|
133 |
+
self.debugger = debugger
|
134 |
+
trace("DebugStackFrameSniffer instantiated")
|
135 |
+
|
136 |
+
# def __del__(self):
|
137 |
+
# print "DSFS dieing"
|
138 |
+
def EnumStackFrames(self):
|
139 |
+
trace("DebugStackFrameSniffer.EnumStackFrames called")
|
140 |
+
return _wrap(
|
141 |
+
EnumDebugStackFrames(self.debugger), axdebug.IID_IEnumDebugStackFrames
|
142 |
+
)
|
143 |
+
|
144 |
+
|
145 |
+
# A DebugProperty for a stack frame.
|
146 |
+
class StackFrameDebugProperty:
|
147 |
+
_com_interfaces_ = [axdebug.IID_IDebugProperty]
|
148 |
+
_public_methods_ = [
|
149 |
+
"GetPropertyInfo",
|
150 |
+
"GetExtendedInfo",
|
151 |
+
"SetValueAsString",
|
152 |
+
"EnumMembers",
|
153 |
+
"GetParent",
|
154 |
+
]
|
155 |
+
|
156 |
+
def __init__(self, frame):
|
157 |
+
self.frame = frame
|
158 |
+
|
159 |
+
def GetPropertyInfo(self, dwFieldSpec, nRadix):
|
160 |
+
RaiseNotImpl("StackFrameDebugProperty::GetPropertyInfo")
|
161 |
+
|
162 |
+
def GetExtendedInfo(self): ### Note - not in the framework.
|
163 |
+
RaiseNotImpl("StackFrameDebugProperty::GetExtendedInfo")
|
164 |
+
|
165 |
+
def SetValueAsString(self, value, radix):
|
166 |
+
#
|
167 |
+
RaiseNotImpl("DebugProperty::SetValueAsString")
|
168 |
+
|
169 |
+
def EnumMembers(self, dwFieldSpec, nRadix, iid):
|
170 |
+
print("EnumMembers", dwFieldSpec, nRadix, iid)
|
171 |
+
from . import expressions
|
172 |
+
|
173 |
+
return expressions.MakeEnumDebugProperty(
|
174 |
+
self.frame.f_locals, dwFieldSpec, nRadix, iid, self.frame
|
175 |
+
)
|
176 |
+
|
177 |
+
def GetParent(self):
|
178 |
+
# return IDebugProperty
|
179 |
+
RaiseNotImpl("DebugProperty::GetParent")
|
MLPY/Lib/site-packages/win32comext/axdebug/util.py
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Utility function for wrapping objects. Centralising allows me to turn
|
2 |
+
# debugging on and off for the entire package in a single spot.
|
3 |
+
|
4 |
+
import os
|
5 |
+
import sys
|
6 |
+
|
7 |
+
import win32api
|
8 |
+
import win32com.server.util
|
9 |
+
import winerror
|
10 |
+
from win32com.server.exception import Exception
|
11 |
+
|
12 |
+
try:
|
13 |
+
os.environ["DEBUG_AXDEBUG"]
|
14 |
+
debugging = 1
|
15 |
+
except KeyError:
|
16 |
+
debugging = 0
|
17 |
+
|
18 |
+
|
19 |
+
def trace(*args):
|
20 |
+
if not debugging:
|
21 |
+
return
|
22 |
+
print(str(win32api.GetCurrentThreadId()) + ":", end=" ")
|
23 |
+
for arg in args:
|
24 |
+
print(arg, end=" ")
|
25 |
+
print()
|
26 |
+
|
27 |
+
|
28 |
+
# The AXDebugging implementation assumes that the returned COM pointers are in
|
29 |
+
# some cases identical. Eg, from a C++ perspective:
|
30 |
+
# p->GetSomeInterface( &p1 );
|
31 |
+
# p->GetSomeInterface( &p2 );
|
32 |
+
# p1==p2
|
33 |
+
# By default, this is _not_ true for Python.
|
34 |
+
# (Now this is only true for Document objects, and Python
|
35 |
+
# now does ensure this.
|
36 |
+
|
37 |
+
all_wrapped = {}
|
38 |
+
|
39 |
+
|
40 |
+
def _wrap_nodebug(object, iid):
|
41 |
+
return win32com.server.util.wrap(object, iid)
|
42 |
+
|
43 |
+
|
44 |
+
def _wrap_debug(object, iid):
|
45 |
+
import win32com.server.policy
|
46 |
+
|
47 |
+
dispatcher = win32com.server.policy.DispatcherWin32trace
|
48 |
+
return win32com.server.util.wrap(object, iid, useDispatcher=dispatcher)
|
49 |
+
|
50 |
+
|
51 |
+
if debugging:
|
52 |
+
_wrap = _wrap_debug
|
53 |
+
else:
|
54 |
+
_wrap = _wrap_nodebug
|
55 |
+
|
56 |
+
|
57 |
+
def _wrap_remove(object, iid=None):
|
58 |
+
# Old - no longer used or necessary!
|
59 |
+
return
|
60 |
+
|
61 |
+
|
62 |
+
def _dump_wrapped():
|
63 |
+
from win32com.server.util import unwrap
|
64 |
+
|
65 |
+
print("Wrapped items:")
|
66 |
+
for key, items in all_wrapped.items():
|
67 |
+
print(key, end=" ")
|
68 |
+
try:
|
69 |
+
ob = unwrap(key)
|
70 |
+
print(ob, sys.getrefcount(ob))
|
71 |
+
except:
|
72 |
+
print("<error>")
|
73 |
+
|
74 |
+
|
75 |
+
def RaiseNotImpl(who=None):
|
76 |
+
if who is not None:
|
77 |
+
print("********* Function %s Raising E_NOTIMPL ************" % (who))
|
78 |
+
|
79 |
+
# Print a sort-of "traceback", dumping all the frames leading to here.
|
80 |
+
try:
|
81 |
+
1 / 0
|
82 |
+
except:
|
83 |
+
frame = sys.exc_info()[2].tb_frame
|
84 |
+
while frame:
|
85 |
+
print("File: %s, Line: %d" % (frame.f_code.co_filename, frame.f_lineno))
|
86 |
+
frame = frame.f_back
|
87 |
+
|
88 |
+
# and raise the exception for COM
|
89 |
+
raise Exception(scode=winerror.E_NOTIMPL)
|
90 |
+
|
91 |
+
|
92 |
+
import win32com.server.policy
|
93 |
+
|
94 |
+
|
95 |
+
class Dispatcher(win32com.server.policy.DispatcherWin32trace):
|
96 |
+
def __init__(self, policyClass, object):
|
97 |
+
win32com.server.policy.DispatcherTrace.__init__(self, policyClass, object)
|
98 |
+
import win32traceutil # Sets up everything.
|
99 |
+
|
100 |
+
# print "Object with win32trace dispatcher created (object=%s)" % `object`
|
101 |
+
|
102 |
+
def _QueryInterface_(self, iid):
|
103 |
+
rc = win32com.server.policy.DispatcherBase._QueryInterface_(self, iid)
|
104 |
+
# if not rc:
|
105 |
+
# self._trace_("in _QueryInterface_ with unsupported IID %s (%s)\n" % (IIDToInterfaceName(iid),iid))
|
106 |
+
return rc
|
107 |
+
|
108 |
+
def _Invoke_(self, dispid, lcid, wFlags, args):
|
109 |
+
print(
|
110 |
+
"In Invoke with",
|
111 |
+
dispid,
|
112 |
+
lcid,
|
113 |
+
wFlags,
|
114 |
+
args,
|
115 |
+
"with object",
|
116 |
+
self.policy._obj_,
|
117 |
+
)
|
118 |
+
try:
|
119 |
+
rc = win32com.server.policy.DispatcherBase._Invoke_(
|
120 |
+
self, dispid, lcid, wFlags, args
|
121 |
+
)
|
122 |
+
# print "Invoke of", dispid, "returning", rc
|
123 |
+
return rc
|
124 |
+
except Exception:
|
125 |
+
t, v, tb = sys.exc_info()
|
126 |
+
tb = None # A cycle
|
127 |
+
scode = v.scode
|
128 |
+
try:
|
129 |
+
desc = " (" + str(v.description) + ")"
|
130 |
+
except AttributeError:
|
131 |
+
desc = ""
|
132 |
+
print(
|
133 |
+
"*** Invoke of %s raised COM exception 0x%x%s" % (dispid, scode, desc)
|
134 |
+
)
|
135 |
+
except:
|
136 |
+
print("*** Invoke of %s failed:" % dispid)
|
137 |
+
typ, val, tb = sys.exc_info()
|
138 |
+
import traceback
|
139 |
+
|
140 |
+
traceback.print_exception(typ, val, tb)
|
141 |
+
raise
|
MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/CreateObject.asp
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<HTML>
|
2 |
+
|
3 |
+
<SCRIPT Language="Python" RUNAT=Server>
|
4 |
+
|
5 |
+
# Just for the sake of the demo, our Python script engine
|
6 |
+
# will create a Python.Interpreter COM object, and call that.
|
7 |
+
|
8 |
+
# This is completely useless, as the Python Script Engine is
|
9 |
+
# completely normal Python, and ASP does not impose retrictions, so
|
10 |
+
# there is nothing the COM object can do that we can not do natively.
|
11 |
+
|
12 |
+
o = Server.CreateObject("Python.Interpreter")
|
13 |
+
|
14 |
+
Response.Write("Python says 1+1=" + str(o.Eval("1+1")))
|
15 |
+
|
16 |
+
</SCRIPT>
|
17 |
+
|
18 |
+
</HTML>
|
19 |
+
|
MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/caps.asp
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<%@ Language=Python %>
|
2 |
+
<HTML>
|
3 |
+
|
4 |
+
<HEAD>
|
5 |
+
|
6 |
+
<BODY BACKGROUND="/samples/images/backgrnd.gif">
|
7 |
+
|
8 |
+
<TITLE>Python test</TITLE>
|
9 |
+
|
10 |
+
</HEAD>
|
11 |
+
|
12 |
+
<BODY BGCOLOR="FFFFFF">
|
13 |
+
|
14 |
+
<SCRIPT Language="Python" RUNAT=Server>
|
15 |
+
# NOTE that the <% tags below execute _before_ these tags!
|
16 |
+
Response.Write("Hello from Python<P>")
|
17 |
+
Response.Write("Browser is "+bc.browser)
|
18 |
+
import win32api # Should be no problem using win32api in ASP pages.
|
19 |
+
Response.Write("<p>Win32 username is "+win32api.GetUserName())
|
20 |
+
</SCRIPT>
|
21 |
+
|
22 |
+
<BODY BGCOLOR="FFFFFF">
|
23 |
+
|
24 |
+
<%
|
25 |
+
import sys
|
26 |
+
print sys.path
|
27 |
+
from win32com.axscript.asputil import *
|
28 |
+
print "Hello"
|
29 |
+
print "There"
|
30 |
+
print "How are you"
|
31 |
+
%>
|
32 |
+
|
33 |
+
<%bc = Server.CreateObject("MSWC.BrowserType")%>
|
34 |
+
<BODY BGCOLOR="FFFFFF">
|
35 |
+
<table border=1>
|
36 |
+
<tr><td>Browser</td><td> <%=bc.browser %>
|
37 |
+
<tr><td>Version</td><td> <%=bc.version %> </td></TR>
|
38 |
+
<tr><td>Frames</td><td>
|
39 |
+
<%Response.Write( iif(bc.frames, "TRUE", "FALSE")) %></td></TR>
|
40 |
+
<tr><td>Tables</td><td>
|
41 |
+
<%Response.Write( iif (bc.tables, "TRUE", "FALSE")) %></td></TR>
|
42 |
+
<tr><td>BackgroundSounds</td><td>
|
43 |
+
<%Response.Write( iif(bc.BackgroundSounds, "TRUE", "FALSE"))%></td></TR>
|
44 |
+
<tr><td>VBScript</td><td>
|
45 |
+
<%Response.Write( iif(bc.vbscript, "TRUE", "FALSE"))%></td></TR>
|
46 |
+
<tr><td>JavaScript</td><td>
|
47 |
+
<%Response.Write( iif(bc.javascript, "TRUE", "FALSE"))%></td></TR>
|
48 |
+
|
49 |
+
</table>
|
50 |
+
|
51 |
+
</body>
|
52 |
+
</html>
|
MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.asp
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<%@ language=python%>
|
2 |
+
<html>
|
3 |
+
<%Response.Redirect("test1.html")%>
|
4 |
+
</html>
|
MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.html
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html>
|
2 |
+
<head>
|
3 |
+
<body>
|
4 |
+
GOT There
|
5 |
+
<script language=javascript>
|
6 |
+
location.href ="http://192.168.0.1/Python/interrupt/test.asp"
|
7 |
+
</script>
|
8 |
+
</body>
|
9 |
+
</head>
|
10 |
+
</html>
|