diff --git a/MLPY/Lib/site-packages/win32comext/adsi/__init__.py b/MLPY/Lib/site-packages/win32comext/adsi/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ab95196f6895603c34c2e6bcf25fe5746ba8ed80 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/adsi/__init__.py @@ -0,0 +1,122 @@ +import win32com +import win32com.client + +if type(__path__) == type(""): + # For freeze to work! + import sys + + try: + import adsi + + sys.modules["win32com.adsi.adsi"] = adsi + except ImportError: + pass +else: + # See if we have a special directory for the binaries (for developers) + win32com.__PackageSupportBuildPath__(__path__) + + +# Some helpers +# We want to _look_ like the ADSI module, but provide some additional +# helpers. + +# Of specific note - most of the interfaces supported by ADSI +# derive from IDispatch - thus, you get the custome methods from the +# interface, as well as via IDispatch. +import pythoncom + +from .adsi import * + +LCID = 0 + +IDispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch] +IADsContainerType = pythoncom.TypeIIDs[adsi.IID_IADsContainer] + + +def _get_good_ret( + ob, + # Named arguments used internally + resultCLSID=None, +): + assert resultCLSID is None, "Now have type info for ADSI objects - fix me!" + # See if the object supports IDispatch + if hasattr(ob, "Invoke"): + import win32com.client.dynamic + + name = "Dispatch wrapper around %r" % ob + return win32com.client.dynamic.Dispatch(ob, name, ADSIDispatch) + return ob + + +class ADSIEnumerator: + def __init__(self, ob): + # Query the object for the container interface. + self._cont_ = ob.QueryInterface(IID_IADsContainer) + self._oleobj_ = ADsBuildEnumerator(self._cont_) # a PyIADsEnumVARIANT + self.index = -1 + + def __getitem__(self, index): + return self.__GetIndex(index) + + def __call__(self, index): + return self.__GetIndex(index) + + def __GetIndex(self, index): + if type(index) != type(0): + raise TypeError("Only integer indexes are supported for enumerators") + if index != self.index + 1: + # Index requested out of sequence. + raise ValueError("You must index this object sequentially") + self.index = index + result = ADsEnumerateNext(self._oleobj_, 1) + if len(result): + return _get_good_ret(result[0]) + # Failed - reset for next time around. + self.index = -1 + self._oleobj_ = ADsBuildEnumerator(self._cont_) # a PyIADsEnumVARIANT + raise IndexError("list index out of range") + + +class ADSIDispatch(win32com.client.CDispatch): + def _wrap_dispatch_( + self, ob, userName=None, returnCLSID=None, UnicodeToString=None + ): + assert UnicodeToString is None, "this is deprectated and will be removed" + if not userName: + userName = "ADSI-object" + olerepr = win32com.client.dynamic.MakeOleRepr(ob, None, None) + return ADSIDispatch(ob, olerepr, userName) + + def _NewEnum(self): + try: + return ADSIEnumerator(self) + except pythoncom.com_error: + # doesnt support it - let our base try! + return win32com.client.CDispatch._NewEnum(self) + + def __getattr__(self, attr): + try: + return getattr(self._oleobj_, attr) + except AttributeError: + return win32com.client.CDispatch.__getattr__(self, attr) + + def QueryInterface(self, iid): + ret = self._oleobj_.QueryInterface(iid) + return _get_good_ret(ret) + + +# We override the global methods to do the right thing. +_ADsGetObject = ADsGetObject # The one in the .pyd + + +def ADsGetObject(path, iid=pythoncom.IID_IDispatch): + ret = _ADsGetObject(path, iid) + return _get_good_ret(ret) + + +_ADsOpenObject = ADsOpenObject + + +def ADsOpenObject(path, username, password, reserved=0, iid=pythoncom.IID_IDispatch): + ret = _ADsOpenObject(path, username, password, reserved, iid) + return _get_good_ret(ret) diff --git a/MLPY/Lib/site-packages/win32comext/adsi/__pycache__/__init__.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/adsi/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd069b6d48a49056ac0c4bb65aab6e13f7c49457 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/adsi/__pycache__/__init__.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/adsi/__pycache__/adsicon.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/adsi/__pycache__/adsicon.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..187d3be33f1092f1f2410048cf2cfa67f1f37c1e Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/adsi/__pycache__/adsicon.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/adsi/adsi.pyd b/MLPY/Lib/site-packages/win32comext/adsi/adsi.pyd new file mode 100644 index 0000000000000000000000000000000000000000..31006a516148760710baa300318a9af1dccaa226 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/adsi/adsi.pyd differ diff --git a/MLPY/Lib/site-packages/win32comext/adsi/adsicon.py b/MLPY/Lib/site-packages/win32comext/adsi/adsicon.py new file mode 100644 index 0000000000000000000000000000000000000000..9944aefaf93158d1f85fdb59d2c872662cf279cd --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/adsi/adsicon.py @@ -0,0 +1,340 @@ +ADS_ATTR_CLEAR = 1 +ADS_ATTR_UPDATE = 2 +ADS_ATTR_APPEND = 3 +ADS_ATTR_DELETE = 4 +ADS_EXT_MINEXTDISPID = 1 +ADS_EXT_MAXEXTDISPID = 16777215 +ADS_EXT_INITCREDENTIALS = 1 +ADS_EXT_INITIALIZE_COMPLETE = 2 + +ADS_SEARCHPREF_ASYNCHRONOUS = 0 +ADS_SEARCHPREF_DEREF_ALIASES = 1 +ADS_SEARCHPREF_SIZE_LIMIT = 2 +ADS_SEARCHPREF_TIME_LIMIT = 3 +ADS_SEARCHPREF_ATTRIBTYPES_ONLY = 4 +ADS_SEARCHPREF_SEARCH_SCOPE = 5 +ADS_SEARCHPREF_TIMEOUT = 6 +ADS_SEARCHPREF_PAGESIZE = 7 +ADS_SEARCHPREF_PAGED_TIME_LIMIT = 8 +ADS_SEARCHPREF_CHASE_REFERRALS = 9 +ADS_SEARCHPREF_SORT_ON = 10 +ADS_SEARCHPREF_CACHE_RESULTS = 11 +ADS_SEARCHPREF_DIRSYNC = 12 +ADS_SEARCHPREF_TOMBSTONE = 13 + +ADS_SCOPE_BASE = 0 +ADS_SCOPE_ONELEVEL = 1 +ADS_SCOPE_SUBTREE = 2 + +ADS_SECURE_AUTHENTICATION = 0x1 +ADS_USE_ENCRYPTION = 0x2 +ADS_USE_SSL = 0x2 +ADS_READONLY_SERVER = 0x4 +ADS_PROMPT_CREDENTIALS = 0x8 +ADS_NO_AUTHENTICATION = 0x10 +ADS_FAST_BIND = 0x20 +ADS_USE_SIGNING = 0x40 +ADS_USE_SEALING = 0x80 +ADS_USE_DELEGATION = 0x100 +ADS_SERVER_BIND = 0x200 + +ADSTYPE_INVALID = 0 +ADSTYPE_DN_STRING = ADSTYPE_INVALID + 1 +ADSTYPE_CASE_EXACT_STRING = ADSTYPE_DN_STRING + 1 +ADSTYPE_CASE_IGNORE_STRING = ADSTYPE_CASE_EXACT_STRING + 1 +ADSTYPE_PRINTABLE_STRING = ADSTYPE_CASE_IGNORE_STRING + 1 +ADSTYPE_NUMERIC_STRING = ADSTYPE_PRINTABLE_STRING + 1 +ADSTYPE_BOOLEAN = ADSTYPE_NUMERIC_STRING + 1 +ADSTYPE_INTEGER = ADSTYPE_BOOLEAN + 1 +ADSTYPE_OCTET_STRING = ADSTYPE_INTEGER + 1 +ADSTYPE_UTC_TIME = ADSTYPE_OCTET_STRING + 1 +ADSTYPE_LARGE_INTEGER = ADSTYPE_UTC_TIME + 1 +ADSTYPE_PROV_SPECIFIC = ADSTYPE_LARGE_INTEGER + 1 +ADSTYPE_OBJECT_CLASS = ADSTYPE_PROV_SPECIFIC + 1 +ADSTYPE_CASEIGNORE_LIST = ADSTYPE_OBJECT_CLASS + 1 +ADSTYPE_OCTET_LIST = ADSTYPE_CASEIGNORE_LIST + 1 +ADSTYPE_PATH = ADSTYPE_OCTET_LIST + 1 +ADSTYPE_POSTALADDRESS = ADSTYPE_PATH + 1 +ADSTYPE_TIMESTAMP = ADSTYPE_POSTALADDRESS + 1 +ADSTYPE_BACKLINK = ADSTYPE_TIMESTAMP + 1 +ADSTYPE_TYPEDNAME = ADSTYPE_BACKLINK + 1 +ADSTYPE_HOLD = ADSTYPE_TYPEDNAME + 1 +ADSTYPE_NETADDRESS = ADSTYPE_HOLD + 1 +ADSTYPE_REPLICAPOINTER = ADSTYPE_NETADDRESS + 1 +ADSTYPE_FAXNUMBER = ADSTYPE_REPLICAPOINTER + 1 +ADSTYPE_EMAIL = ADSTYPE_FAXNUMBER + 1 +ADSTYPE_NT_SECURITY_DESCRIPTOR = ADSTYPE_EMAIL + 1 +ADSTYPE_UNKNOWN = ADSTYPE_NT_SECURITY_DESCRIPTOR + 1 +ADSTYPE_DN_WITH_BINARY = ADSTYPE_UNKNOWN + 1 +ADSTYPE_DN_WITH_STRING = ADSTYPE_DN_WITH_BINARY + 1 + +ADS_PROPERTY_CLEAR = 1 +ADS_PROPERTY_UPDATE = 2 +ADS_PROPERTY_APPEND = 3 +ADS_PROPERTY_DELETE = 4 +ADS_SYSTEMFLAG_DISALLOW_DELETE = -2147483648 +ADS_SYSTEMFLAG_CONFIG_ALLOW_RENAME = 0x40000000 +ADS_SYSTEMFLAG_CONFIG_ALLOW_MOVE = 0x20000000 +ADS_SYSTEMFLAG_CONFIG_ALLOW_LIMITED_MOVE = 0x10000000 +ADS_SYSTEMFLAG_DOMAIN_DISALLOW_RENAME = -2147483648 +ADS_SYSTEMFLAG_DOMAIN_DISALLOW_MOVE = 0x4000000 +ADS_SYSTEMFLAG_CR_NTDS_NC = 0x1 +ADS_SYSTEMFLAG_CR_NTDS_DOMAIN = 0x2 +ADS_SYSTEMFLAG_ATTR_NOT_REPLICATED = 0x1 +ADS_SYSTEMFLAG_ATTR_IS_CONSTRUCTED = 0x4 +ADS_GROUP_TYPE_GLOBAL_GROUP = 0x2 +ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 0x4 +ADS_GROUP_TYPE_LOCAL_GROUP = 0x4 +ADS_GROUP_TYPE_UNIVERSAL_GROUP = 0x8 +ADS_GROUP_TYPE_SECURITY_ENABLED = -2147483648 +ADS_UF_SCRIPT = 0x1 +ADS_UF_ACCOUNTDISABLE = 0x2 +ADS_UF_HOMEDIR_REQUIRED = 0x8 +ADS_UF_LOCKOUT = 0x10 +ADS_UF_PASSWD_NOTREQD = 0x20 +ADS_UF_PASSWD_CANT_CHANGE = 0x40 +ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x80 +ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0x100 +ADS_UF_NORMAL_ACCOUNT = 0x200 +ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0x800 +ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x1000 +ADS_UF_SERVER_TRUST_ACCOUNT = 0x2000 +ADS_UF_DONT_EXPIRE_PASSWD = 0x10000 +ADS_UF_MNS_LOGON_ACCOUNT = 0x20000 +ADS_UF_SMARTCARD_REQUIRED = 0x40000 +ADS_UF_TRUSTED_FOR_DELEGATION = 0x80000 +ADS_UF_NOT_DELEGATED = 0x100000 +ADS_UF_USE_DES_KEY_ONLY = 0x200000 +ADS_UF_DONT_REQUIRE_PREAUTH = 0x400000 +ADS_UF_PASSWORD_EXPIRED = 0x800000 +ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000 +ADS_RIGHT_DELETE = 0x10000 +ADS_RIGHT_READ_CONTROL = 0x20000 +ADS_RIGHT_WRITE_DAC = 0x40000 +ADS_RIGHT_WRITE_OWNER = 0x80000 +ADS_RIGHT_SYNCHRONIZE = 0x100000 +ADS_RIGHT_ACCESS_SYSTEM_SECURITY = 0x1000000 +ADS_RIGHT_GENERIC_READ = -2147483648 +ADS_RIGHT_GENERIC_WRITE = 0x40000000 +ADS_RIGHT_GENERIC_EXECUTE = 0x20000000 +ADS_RIGHT_GENERIC_ALL = 0x10000000 +ADS_RIGHT_DS_CREATE_CHILD = 0x1 +ADS_RIGHT_DS_DELETE_CHILD = 0x2 +ADS_RIGHT_ACTRL_DS_LIST = 0x4 +ADS_RIGHT_DS_SELF = 0x8 +ADS_RIGHT_DS_READ_PROP = 0x10 +ADS_RIGHT_DS_WRITE_PROP = 0x20 +ADS_RIGHT_DS_DELETE_TREE = 0x40 +ADS_RIGHT_DS_LIST_OBJECT = 0x80 +ADS_RIGHT_DS_CONTROL_ACCESS = 0x100 +ADS_ACETYPE_ACCESS_ALLOWED = 0 +ADS_ACETYPE_ACCESS_DENIED = 0x1 +ADS_ACETYPE_SYSTEM_AUDIT = 0x2 +ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = 0x5 +ADS_ACETYPE_ACCESS_DENIED_OBJECT = 0x6 +ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = 0x7 +ADS_ACETYPE_SYSTEM_ALARM_OBJECT = 0x8 +ADS_ACETYPE_ACCESS_ALLOWED_CALLBACK = 0x9 +ADS_ACETYPE_ACCESS_DENIED_CALLBACK = 0xA +ADS_ACETYPE_ACCESS_ALLOWED_CALLBACK_OBJECT = 0xB +ADS_ACETYPE_ACCESS_DENIED_CALLBACK_OBJECT = 0xC +ADS_ACETYPE_SYSTEM_AUDIT_CALLBACK = 0xD +ADS_ACETYPE_SYSTEM_ALARM_CALLBACK = 0xE +ADS_ACETYPE_SYSTEM_AUDIT_CALLBACK_OBJECT = 0xF +ADS_ACETYPE_SYSTEM_ALARM_CALLBACK_OBJECT = 0x10 +ADS_ACEFLAG_INHERIT_ACE = 0x2 +ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = 0x4 +ADS_ACEFLAG_INHERIT_ONLY_ACE = 0x8 +ADS_ACEFLAG_INHERITED_ACE = 0x10 +ADS_ACEFLAG_VALID_INHERIT_FLAGS = 0x1F +ADS_ACEFLAG_SUCCESSFUL_ACCESS = 0x40 +ADS_ACEFLAG_FAILED_ACCESS = 0x80 +ADS_FLAG_OBJECT_TYPE_PRESENT = 0x1 +ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT = 0x2 +ADS_SD_CONTROL_SE_OWNER_DEFAULTED = 0x1 +ADS_SD_CONTROL_SE_GROUP_DEFAULTED = 0x2 +ADS_SD_CONTROL_SE_DACL_PRESENT = 0x4 +ADS_SD_CONTROL_SE_DACL_DEFAULTED = 0x8 +ADS_SD_CONTROL_SE_SACL_PRESENT = 0x10 +ADS_SD_CONTROL_SE_SACL_DEFAULTED = 0x20 +ADS_SD_CONTROL_SE_DACL_AUTO_INHERIT_REQ = 0x100 +ADS_SD_CONTROL_SE_SACL_AUTO_INHERIT_REQ = 0x200 +ADS_SD_CONTROL_SE_DACL_AUTO_INHERITED = 0x400 +ADS_SD_CONTROL_SE_SACL_AUTO_INHERITED = 0x800 +ADS_SD_CONTROL_SE_DACL_PROTECTED = 0x1000 +ADS_SD_CONTROL_SE_SACL_PROTECTED = 0x2000 +ADS_SD_CONTROL_SE_SELF_RELATIVE = 0x8000 +ADS_SD_REVISION_DS = 4 +ADS_NAME_TYPE_1779 = 1 +ADS_NAME_TYPE_CANONICAL = 2 +ADS_NAME_TYPE_NT4 = 3 +ADS_NAME_TYPE_DISPLAY = 4 +ADS_NAME_TYPE_DOMAIN_SIMPLE = 5 +ADS_NAME_TYPE_ENTERPRISE_SIMPLE = 6 +ADS_NAME_TYPE_GUID = 7 +ADS_NAME_TYPE_UNKNOWN = 8 +ADS_NAME_TYPE_USER_PRINCIPAL_NAME = 9 +ADS_NAME_TYPE_CANONICAL_EX = 10 +ADS_NAME_TYPE_SERVICE_PRINCIPAL_NAME = 11 +ADS_NAME_TYPE_SID_OR_SID_HISTORY_NAME = 12 +ADS_NAME_INITTYPE_DOMAIN = 1 +ADS_NAME_INITTYPE_SERVER = 2 +ADS_NAME_INITTYPE_GC = 3 +ADS_OPTION_SERVERNAME = 0 +ADS_OPTION_REFERRALS = ADS_OPTION_SERVERNAME + 1 +ADS_OPTION_PAGE_SIZE = ADS_OPTION_REFERRALS + 1 +ADS_OPTION_SECURITY_MASK = ADS_OPTION_PAGE_SIZE + 1 +ADS_OPTION_MUTUAL_AUTH_STATUS = ADS_OPTION_SECURITY_MASK + 1 +ADS_OPTION_QUOTA = ADS_OPTION_MUTUAL_AUTH_STATUS + 1 +ADS_OPTION_PASSWORD_PORTNUMBER = ADS_OPTION_QUOTA + 1 +ADS_OPTION_PASSWORD_METHOD = ADS_OPTION_PASSWORD_PORTNUMBER + 1 +ADS_SECURITY_INFO_OWNER = 0x1 +ADS_SECURITY_INFO_GROUP = 0x2 +ADS_SECURITY_INFO_DACL = 0x4 +ADS_SECURITY_INFO_SACL = 0x8 +ADS_SETTYPE_FULL = 1 +ADS_SETTYPE_PROVIDER = 2 +ADS_SETTYPE_SERVER = 3 +ADS_SETTYPE_DN = 4 +ADS_FORMAT_WINDOWS = 1 +ADS_FORMAT_WINDOWS_NO_SERVER = 2 +ADS_FORMAT_WINDOWS_DN = 3 +ADS_FORMAT_WINDOWS_PARENT = 4 +ADS_FORMAT_X500 = 5 +ADS_FORMAT_X500_NO_SERVER = 6 +ADS_FORMAT_X500_DN = 7 +ADS_FORMAT_X500_PARENT = 8 +ADS_FORMAT_SERVER = 9 +ADS_FORMAT_PROVIDER = 10 +ADS_FORMAT_LEAF = 11 +ADS_DISPLAY_FULL = 1 +ADS_DISPLAY_VALUE_ONLY = 2 +ADS_ESCAPEDMODE_DEFAULT = 1 +ADS_ESCAPEDMODE_ON = 2 +ADS_ESCAPEDMODE_OFF = 3 +ADS_ESCAPEDMODE_OFF_EX = 4 +ADS_PATH_FILE = 1 +ADS_PATH_FILESHARE = 2 +ADS_PATH_REGISTRY = 3 +ADS_SD_FORMAT_IID = 1 +ADS_SD_FORMAT_RAW = 2 +ADS_SD_FORMAT_HEXSTRING = 3 + + +# Generated by h2py from AdsErr.h +def _HRESULT_TYPEDEF_(_sc): + return _sc + + +E_ADS_BAD_PATHNAME = _HRESULT_TYPEDEF_((-2147463168)) +E_ADS_INVALID_DOMAIN_OBJECT = _HRESULT_TYPEDEF_((-2147463167)) +E_ADS_INVALID_USER_OBJECT = _HRESULT_TYPEDEF_((-2147463166)) +E_ADS_INVALID_COMPUTER_OBJECT = _HRESULT_TYPEDEF_((-2147463165)) +E_ADS_UNKNOWN_OBJECT = _HRESULT_TYPEDEF_((-2147463164)) +E_ADS_PROPERTY_NOT_SET = _HRESULT_TYPEDEF_((-2147463163)) +E_ADS_PROPERTY_NOT_SUPPORTED = _HRESULT_TYPEDEF_((-2147463162)) +E_ADS_PROPERTY_INVALID = _HRESULT_TYPEDEF_((-2147463161)) +E_ADS_BAD_PARAMETER = _HRESULT_TYPEDEF_((-2147463160)) +E_ADS_OBJECT_UNBOUND = _HRESULT_TYPEDEF_((-2147463159)) +E_ADS_PROPERTY_NOT_MODIFIED = _HRESULT_TYPEDEF_((-2147463158)) +E_ADS_PROPERTY_MODIFIED = _HRESULT_TYPEDEF_((-2147463157)) +E_ADS_CANT_CONVERT_DATATYPE = _HRESULT_TYPEDEF_((-2147463156)) +E_ADS_PROPERTY_NOT_FOUND = _HRESULT_TYPEDEF_((-2147463155)) +E_ADS_OBJECT_EXISTS = _HRESULT_TYPEDEF_((-2147463154)) +E_ADS_SCHEMA_VIOLATION = _HRESULT_TYPEDEF_((-2147463153)) +E_ADS_COLUMN_NOT_SET = _HRESULT_TYPEDEF_((-2147463152)) +S_ADS_ERRORSOCCURRED = _HRESULT_TYPEDEF_(0x00005011) +S_ADS_NOMORE_ROWS = _HRESULT_TYPEDEF_(0x00005012) +S_ADS_NOMORE_COLUMNS = _HRESULT_TYPEDEF_(0x00005013) +E_ADS_INVALID_FILTER = _HRESULT_TYPEDEF_((-2147463148)) + +# ADS_DEREFENUM enum +ADS_DEREF_NEVER = 0 +ADS_DEREF_SEARCHING = 1 +ADS_DEREF_FINDING = 2 +ADS_DEREF_ALWAYS = 3 + +# ADS_PREFERENCES_ENUM +ADSIPROP_ASYNCHRONOUS = 0 +ADSIPROP_DEREF_ALIASES = 0x1 +ADSIPROP_SIZE_LIMIT = 0x2 +ADSIPROP_TIME_LIMIT = 0x3 +ADSIPROP_ATTRIBTYPES_ONLY = 0x4 +ADSIPROP_SEARCH_SCOPE = 0x5 +ADSIPROP_TIMEOUT = 0x6 +ADSIPROP_PAGESIZE = 0x7 +ADSIPROP_PAGED_TIME_LIMIT = 0x8 +ADSIPROP_CHASE_REFERRALS = 0x9 +ADSIPROP_SORT_ON = 0xA +ADSIPROP_CACHE_RESULTS = 0xB +ADSIPROP_ADSIFLAG = 0xC + +# ADSI_DIALECT_ENUM +ADSI_DIALECT_LDAP = 0 +ADSI_DIALECT_SQL = 0x1 + +# ADS_CHASE_REFERRALS_ENUM +ADS_CHASE_REFERRALS_NEVER = 0 +ADS_CHASE_REFERRALS_SUBORDINATE = 0x20 +ADS_CHASE_REFERRALS_EXTERNAL = 0x40 +ADS_CHASE_REFERRALS_ALWAYS = ( + ADS_CHASE_REFERRALS_SUBORDINATE | ADS_CHASE_REFERRALS_EXTERNAL +) + +# Generated by h2py from ObjSel.h +DSOP_SCOPE_TYPE_TARGET_COMPUTER = 0x00000001 +DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN = 0x00000002 +DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN = 0x00000004 +DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN = 0x00000008 +DSOP_SCOPE_TYPE_GLOBAL_CATALOG = 0x00000010 +DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN = 0x00000020 +DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN = 0x00000040 +DSOP_SCOPE_TYPE_WORKGROUP = 0x00000080 +DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE = 0x00000100 +DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE = 0x00000200 +DSOP_SCOPE_FLAG_STARTING_SCOPE = 0x00000001 +DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT = 0x00000002 +DSOP_SCOPE_FLAG_WANT_PROVIDER_LDAP = 0x00000004 +DSOP_SCOPE_FLAG_WANT_PROVIDER_GC = 0x00000008 +DSOP_SCOPE_FLAG_WANT_SID_PATH = 0x00000010 +DSOP_SCOPE_FLAG_WANT_DOWNLEVEL_BUILTIN_PATH = 0x00000020 +DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS = 0x00000040 +DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS = 0x00000080 +DSOP_SCOPE_FLAG_DEFAULT_FILTER_COMPUTERS = 0x00000100 +DSOP_SCOPE_FLAG_DEFAULT_FILTER_CONTACTS = 0x00000200 +DSOP_FILTER_INCLUDE_ADVANCED_VIEW = 0x00000001 +DSOP_FILTER_USERS = 0x00000002 +DSOP_FILTER_BUILTIN_GROUPS = 0x00000004 +DSOP_FILTER_WELL_KNOWN_PRINCIPALS = 0x00000008 +DSOP_FILTER_UNIVERSAL_GROUPS_DL = 0x00000010 +DSOP_FILTER_UNIVERSAL_GROUPS_SE = 0x00000020 +DSOP_FILTER_GLOBAL_GROUPS_DL = 0x00000040 +DSOP_FILTER_GLOBAL_GROUPS_SE = 0x00000080 +DSOP_FILTER_DOMAIN_LOCAL_GROUPS_DL = 0x00000100 +DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE = 0x00000200 +DSOP_FILTER_CONTACTS = 0x00000400 +DSOP_FILTER_COMPUTERS = 0x00000800 +DSOP_DOWNLEVEL_FILTER_USERS = -2147483647 +DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS = -2147483646 +DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS = -2147483644 +DSOP_DOWNLEVEL_FILTER_COMPUTERS = -2147483640 +DSOP_DOWNLEVEL_FILTER_WORLD = -2147483632 +DSOP_DOWNLEVEL_FILTER_AUTHENTICATED_USER = -2147483616 +DSOP_DOWNLEVEL_FILTER_ANONYMOUS = -2147483584 +DSOP_DOWNLEVEL_FILTER_BATCH = -2147483520 +DSOP_DOWNLEVEL_FILTER_CREATOR_OWNER = -2147483392 +DSOP_DOWNLEVEL_FILTER_CREATOR_GROUP = -2147483136 +DSOP_DOWNLEVEL_FILTER_DIALUP = -2147482624 +DSOP_DOWNLEVEL_FILTER_INTERACTIVE = -2147481600 +DSOP_DOWNLEVEL_FILTER_NETWORK = -2147479552 +DSOP_DOWNLEVEL_FILTER_SERVICE = -2147475456 +DSOP_DOWNLEVEL_FILTER_SYSTEM = -2147467264 +DSOP_DOWNLEVEL_FILTER_EXCLUDE_BUILTIN_GROUPS = -2147450880 +DSOP_DOWNLEVEL_FILTER_TERMINAL_SERVER = -2147418112 +DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS = -2147352576 +DSOP_DOWNLEVEL_FILTER_LOCAL_SERVICE = -2147221504 +DSOP_DOWNLEVEL_FILTER_NETWORK_SERVICE = -2146959360 +DSOP_DOWNLEVEL_FILTER_REMOTE_LOGON = -2146435072 +DSOP_FLAG_MULTISELECT = 0x00000001 +DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK = 0x00000002 +CFSTR_DSOP_DS_SELECTION_LIST = "CFSTR_DSOP_DS_SELECTION_LIST" diff --git a/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/objectPicker.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/objectPicker.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c68449f87771cf3c4712ad10bbc1e27e0ee2d203 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/objectPicker.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/scp.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/scp.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a0a1ef74068530824a0f3187c345077f6e7a172 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/scp.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/search.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/search.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed42c1d18822a3ef0402b2e9f48259a84b68b49a Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/search.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/test.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8bdb4ca262e107305149437fdb637fb90a6867de Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/adsi/demos/__pycache__/test.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/adsi/demos/objectPicker.py b/MLPY/Lib/site-packages/win32comext/adsi/demos/objectPicker.py new file mode 100644 index 0000000000000000000000000000000000000000..5df4245997f7ac56b78a37295956894991b39803 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/adsi/demos/objectPicker.py @@ -0,0 +1,68 @@ +# A demo for the IDsObjectPicker interface. +import pythoncom +import win32clipboard +from win32com.adsi import adsi +from win32com.adsi.adsicon import * + +cf_objectpicker = win32clipboard.RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST) + + +def main(): + hwnd = 0 + + # Create an instance of the object picker. + picker = pythoncom.CoCreateInstance( + adsi.CLSID_DsObjectPicker, + None, + pythoncom.CLSCTX_INPROC_SERVER, + adsi.IID_IDsObjectPicker, + ) + + # Create our scope init info. + siis = adsi.DSOP_SCOPE_INIT_INFOs(1) + sii = siis[0] + + # Combine multiple scope types in a single array entry. + + sii.type = ( + DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN + ) + + # Set uplevel and downlevel filters to include only computer objects. + # Uplevel filters apply to both mixed and native modes. + # Notice that the uplevel and downlevel flags are different. + + sii.filterFlags.uplevel.bothModes = DSOP_FILTER_COMPUTERS + sii.filterFlags.downlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS + + # Initialize the interface. + picker.Initialize( + None, # Target is the local computer. + siis, # scope infos + DSOP_FLAG_MULTISELECT, # options + ("objectGUID", "displayName"), + ) # attributes to fetch + + do = picker.InvokeDialog(hwnd) + # Extract the data from the IDataObject. + format_etc = ( + cf_objectpicker, + None, + pythoncom.DVASPECT_CONTENT, + -1, + pythoncom.TYMED_HGLOBAL, + ) + medium = do.GetData(format_etc) + data = adsi.StringAsDS_SELECTION_LIST(medium.data) + for item in data: + name, klass, adspath, upn, attrs, flags = item + print("Item", name) + print(" Class:", klass) + print(" AdsPath:", adspath) + print(" UPN:", upn) + print(" Attrs:", attrs) + print(" Flags:", flags) + + +if __name__ == "__main__": + main() diff --git a/MLPY/Lib/site-packages/win32comext/adsi/demos/scp.py b/MLPY/Lib/site-packages/win32comext/adsi/demos/scp.py new file mode 100644 index 0000000000000000000000000000000000000000..d1a4ca05ec38fd1915bede59ed68b613549ca139 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/adsi/demos/scp.py @@ -0,0 +1,565 @@ +"""A re-implementation of the MS DirectoryService samples related to services. + +* Adds and removes an ActiveDirectory "Service Connection Point", + including managing the security on the object. +* Creates and registers Service Principal Names. +* Changes the username for a domain user. + +Some of these functions are likely to become move to a module - but there +is also a little command-line-interface to try these functions out. + +For example: + +scp.py --account-name=domain\\user --service-class=PythonScpTest \\ + --keyword=foo --keyword=bar --binding-string=bind_info \\ + ScpCreate SpnCreate SpnRegister + +would: +* Attempt to delete a Service Connection Point for the service class + 'PythonScpTest' +* Attempt to create a Service Connection Point for that class, with 2 + keywords and a binding string of 'bind_info' +* Create a Service Principal Name for the service and register it + +to undo those changes, you could execute: + +scp.py --account-name=domain\\user --service-class=PythonScpTest \\ + SpnCreate SpnUnregister ScpDelete + +which will: +* Create a SPN +* Unregister that SPN from the Active Directory. +* Delete the Service Connection Point + +Executing with --test will create and remove one of everything. +""" + +import optparse +import textwrap +import traceback + +import ntsecuritycon as dscon +import win32api +import win32con +import win32security +import winerror +from win32com.adsi import adsi +from win32com.adsi.adsicon import * +from win32com.client import Dispatch + +verbose = 1 +g_createdSCP = None +g_createdSPNs = [] +g_createdSPNLast = None + +import logging + +logger = logging # use logging module global methods for now. + +# still a bit confused about log(n, ...) vs logger.info/debug() + + +# Returns distinguished name of SCP. +def ScpCreate( + service_binding_info, + service_class_name, # Service class string to store in SCP. + account_name=None, # Logon account that needs access to SCP. + container_name=None, + keywords=None, + object_class="serviceConnectionPoint", + dns_name_type="A", + dn=None, + dns_name=None, +): + container_name = container_name or service_class_name + if not dns_name: + # Get the DNS name of the local computer + dns_name = win32api.GetComputerNameEx(win32con.ComputerNameDnsFullyQualified) + # Get the distinguished name of the computer object for the local computer + if dn is None: + dn = win32api.GetComputerObjectName(win32con.NameFullyQualifiedDN) + + # Compose the ADSpath and bind to the computer object for the local computer + comp = adsi.ADsGetObject("LDAP://" + dn, adsi.IID_IDirectoryObject) + + # Publish the SCP as a child of the computer object + keywords = keywords or [] + # Fill in the attribute values to be stored in the SCP. + attrs = [ + ("cn", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, (container_name,)), + ("objectClass", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, (object_class,)), + ("keywords", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, keywords), + ("serviceDnsName", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, (dns_name,)), + ( + "serviceDnsNameType", + ADS_ATTR_UPDATE, + ADSTYPE_CASE_IGNORE_STRING, + (dns_name_type,), + ), + ( + "serviceClassName", + ADS_ATTR_UPDATE, + ADSTYPE_CASE_IGNORE_STRING, + (service_class_name,), + ), + ( + "serviceBindingInformation", + ADS_ATTR_UPDATE, + ADSTYPE_CASE_IGNORE_STRING, + (service_binding_info,), + ), + ] + new = comp.CreateDSObject("cn=" + container_name, attrs) + logger.info("New connection point is at %s", container_name) + # Wrap in a usable IDispatch object. + new = Dispatch(new) + # And allow access to the SCP for the specified account name + AllowAccessToScpProperties(account_name, new) + return new + + +def ScpDelete(container_name, dn=None): + if dn is None: + dn = win32api.GetComputerObjectName(win32con.NameFullyQualifiedDN) + logger.debug("Removing connection point '%s' from %s", container_name, dn) + + # Compose the ADSpath and bind to the computer object for the local computer + comp = adsi.ADsGetObject("LDAP://" + dn, adsi.IID_IDirectoryObject) + comp.DeleteDSObject("cn=" + container_name) + logger.info("Deleted service connection point '%s'", container_name) + + +# This function is described in detail in the MSDN article titled +# "Enabling Service Account to Access SCP Properties" +# From that article: +# The following sample code sets a pair of ACEs on a service connection point +# (SCP) object. The ACEs grant read/write access to the user or computer account +# under which the service instance will be running. Your service installation +# program calls this code to ensure that the service will be allowed to update +# its properties at run time. If you don't set ACEs like these, your service +# will get access-denied errors if it tries to modify the SCP's properties. +# +# The code uses the IADsSecurityDescriptor, IADsAccessControlList, and +# IADsAccessControlEntry interfaces to do the following: +# * Get the SCP object's security descriptor. +# * Set ACEs in the DACL of the security descriptor. +# * Set the security descriptor back on the SCP object. + + +def AllowAccessToScpProperties( + accountSAM, # Service account to allow access. + scpObject, # The IADs SCP object. + schemaIDGUIDs=( # Attributes to allow write-access to. + "{28630eb8-41d5-11d1-a9c1-0000f80367c1}", # serviceDNSName + "{b7b1311c-b82e-11d0-afee-0000f80367c1}", # serviceBindingInformation + ), +): + # If no service account is specified, service runs under LocalSystem. + # So allow access to the computer account of the service's host. + if accountSAM: + trustee = accountSAM + else: + # Get the SAM account name of the computer object for the server. + trustee = win32api.GetComputerObjectName(win32con.NameSamCompatible) + + # Get the nTSecurityDescriptor attribute + attribute = "nTSecurityDescriptor" + sd = getattr(scpObject, attribute) + acl = sd.DiscretionaryAcl + + for sguid in schemaIDGUIDs: + ace = Dispatch(adsi.CLSID_AccessControlEntry) + + # Set the properties of the ACE. + # Allow read and write access to the property. + ace.AccessMask = ADS_RIGHT_DS_READ_PROP | ADS_RIGHT_DS_WRITE_PROP + + # Set the trustee, which is either the service account or the + # host computer account. + ace.Trustee = trustee + + # Set the ACE type. + ace.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT + + # Set AceFlags to zero because ACE is not inheritable. + ace.AceFlags = 0 + + # Set Flags to indicate an ACE that protects a specified object. + ace.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT + + # Set ObjectType to the schemaIDGUID of the attribute. + ace.ObjectType = sguid + + # Add the ACEs to the DACL. + acl.AddAce(ace) + + # Write the modified DACL back to the security descriptor. + sd.DiscretionaryAcl = acl + # Write the ntSecurityDescriptor property to the property cache. + setattr(scpObject, attribute, sd) + # SetInfo updates the SCP object in the directory. + scpObject.SetInfo() + logger.info("Set security on object for account '%s'" % (trustee,)) + + +# Service Principal Names functions from the same sample. +# The example calls the DsWriteAccountSpn function, which stores the SPNs in +# Microsoft Active Directory under the servicePrincipalName attribute of the +# account object specified by the serviceAcctDN parameter. The account object +# corresponds to the logon account specified in the CreateService call for this +# service instance. If the logon account is a domain user account, +# serviceAcctDN must be the distinguished name of the account object in +# Active Directory for that user account. If the service's logon account is the +# LocalSystem account, serviceAcctDN must be the distinguished name of the +# computer account object for the host computer on which the service is +# installed. win32api.TranslateNames and win32security.DsCrackNames can +# be used to convert a domain\account format name to a distinguished name. +def SpnRegister( + serviceAcctDN, # DN of the service's logon account + spns, # List of SPNs to register + operation, # Add, replace, or delete SPNs +): + assert type(spns) not in [str, str] and hasattr(spns, "__iter__"), ( + "spns must be a sequence of strings (got %r)" % spns + ) + # Bind to a domain controller. + # Get the domain for the current user. + samName = win32api.GetUserNameEx(win32api.NameSamCompatible) + samName = samName.split("\\", 1)[0] + + if not serviceAcctDN: + # Get the SAM account name of the computer object for the server. + serviceAcctDN = win32api.GetComputerObjectName(win32con.NameFullyQualifiedDN) + logger.debug("SpnRegister using DN '%s'", serviceAcctDN) + + # Get the name of a domain controller in that domain. + info = win32security.DsGetDcName( + domainName=samName, + flags=dscon.DS_IS_FLAT_NAME + | dscon.DS_RETURN_DNS_NAME + | dscon.DS_DIRECTORY_SERVICE_REQUIRED, + ) + # Bind to the domain controller. + handle = win32security.DsBind(info["DomainControllerName"]) + + # Write the SPNs to the service account or computer account. + logger.debug("DsWriteAccountSpn with spns %s") + win32security.DsWriteAccountSpn( + handle, # handle to the directory + operation, # Add or remove SPN from account's existing SPNs + serviceAcctDN, # DN of service account or computer account + spns, + ) # names + + # Unbind the DS in any case (but Python would do it anyway) + handle.Close() + + +def UserChangePassword(username_dn, new_password): + # set the password on the account. + # Use the distinguished name to bind to the account object. + accountPath = "LDAP://" + username_dn + user = adsi.ADsGetObject(accountPath, adsi.IID_IADsUser) + + # Set the password on the account. + user.SetPassword(new_password) + + +# functions related to the command-line interface +def log(level, msg, *args): + if verbose >= level: + print(msg % args) + + +class _NoDefault: + pass + + +def _get_option(po, opt_name, default=_NoDefault): + parser, options = po + ret = getattr(options, opt_name, default) + if not ret and default is _NoDefault: + parser.error("The '%s' option must be specified for this operation" % opt_name) + if not ret: + ret = default + return ret + + +def _option_error(po, why): + parser = po[0] + parser.error(why) + + +def do_ScpCreate(po): + """Create a Service Connection Point""" + global g_createdSCP + scp = ScpCreate( + _get_option(po, "binding_string"), + _get_option(po, "service_class"), + _get_option(po, "account_name_sam", None), + keywords=_get_option(po, "keywords", None), + ) + g_createdSCP = scp + return scp.distinguishedName + + +def do_ScpDelete(po): + """Delete a Service Connection Point""" + sc = _get_option(po, "service_class") + try: + ScpDelete(sc) + except adsi.error as details: + if details[0] != winerror.ERROR_DS_OBJ_NOT_FOUND: + raise + log(2, "ScpDelete ignoring ERROR_DS_OBJ_NOT_FOUND for service-class '%s'", sc) + return sc + + +def do_SpnCreate(po): + """Create a Service Principal Name""" + # The 'service name' is the dn of our scp. + if g_createdSCP is None: + # Could accept an arg to avoid this? + _option_error(po, "ScpCreate must have been specified before SpnCreate") + # Create a Service Principal Name" + spns = win32security.DsGetSpn( + dscon.DS_SPN_SERVICE, + _get_option(po, "service_class"), + g_createdSCP.distinguishedName, + _get_option(po, "port", 0), + None, + None, + ) + spn = spns[0] + log(2, "Created SPN: %s", spn) + global g_createdSPNLast + g_createdSPNLast = spn + g_createdSPNs.append(spn) + return spn + + +def do_SpnRegister(po): + """Register a previously created Service Principal Name""" + if not g_createdSPNLast: + _option_error(po, "SpnCreate must appear before SpnRegister") + + SpnRegister( + _get_option(po, "account_name_dn", None), + (g_createdSPNLast,), + dscon.DS_SPN_ADD_SPN_OP, + ) + return g_createdSPNLast + + +def do_SpnUnregister(po): + """Unregister a previously created Service Principal Name""" + if not g_createdSPNLast: + _option_error(po, "SpnCreate must appear before SpnUnregister") + SpnRegister( + _get_option(po, "account_name_dn", None), + (g_createdSPNLast,), + dscon.DS_SPN_DELETE_SPN_OP, + ) + return g_createdSPNLast + + +def do_UserChangePassword(po): + """Change the password for a specified user""" + UserChangePassword(_get_option(po, "account_name_dn"), _get_option(po, "password")) + return "Password changed OK" + + +handlers = ( + ("ScpCreate", do_ScpCreate), + ("ScpDelete", do_ScpDelete), + ("SpnCreate", do_SpnCreate), + ("SpnRegister", do_SpnRegister), + ("SpnUnregister", do_SpnUnregister), + ("UserChangePassword", do_UserChangePassword), +) + + +class HelpFormatter(optparse.IndentedHelpFormatter): + def format_description(self, description): + return description + + +def main(): + global verbose + _handlers_dict = {} + + arg_descs = [] + for arg, func in handlers: + this_desc = "\n".join(textwrap.wrap(func.__doc__, subsequent_indent=" " * 8)) + arg_descs.append(" %s: %s" % (arg, this_desc)) + _handlers_dict[arg.lower()] = func + + description = __doc__ + "\ncommands:\n" + "\n".join(arg_descs) + "\n" + + parser = optparse.OptionParser( + usage="%prog [options] command ...", + description=description, + formatter=HelpFormatter(), + ) + + parser.add_option( + "-v", + action="count", + dest="verbose", + default=1, + help="increase the verbosity of status messages", + ) + + parser.add_option( + "-q", "--quiet", action="store_true", help="Don't print any status messages" + ) + + parser.add_option( + "-t", + "--test", + action="store_true", + help="Execute a mini-test suite, providing defaults for most options and args", + ), + + parser.add_option( + "", + "--show-tracebacks", + action="store_true", + help="Show the tracebacks for any exceptions", + ) + + parser.add_option("", "--service-class", help="The service class name to use") + + parser.add_option( + "", "--port", default=0, help="The port number to associate with the SPN" + ) + + parser.add_option( + "", "--binding-string", help="The binding string to use for SCP creation" + ) + + parser.add_option( + "", "--account-name", help="The account name to use (default is LocalSystem)" + ) + + parser.add_option("", "--password", help="The password to set.") + + parser.add_option( + "", + "--keyword", + action="append", + dest="keywords", + help="""A keyword to add to the SCP. May be specified + multiple times""", + ) + + parser.add_option( + "", + "--log-level", + help="""The log-level to use - may be a number or a logging + module constant""", + default=str(logging.WARNING), + ) + + options, args = parser.parse_args() + po = (parser, options) + # fixup misc + try: + options.port = int(options.port) + except (TypeError, ValueError): + parser.error("--port must be numeric") + # fixup log-level + try: + log_level = int(options.log_level) + except (TypeError, ValueError): + try: + log_level = int(getattr(logging, options.log_level.upper())) + except (ValueError, TypeError, AttributeError): + parser.error("Invalid --log-level value") + try: + sl = logger.setLevel + # logger is a real logger + except AttributeError: + # logger is logging module + sl = logging.getLogger().setLevel + sl(log_level) + # Check -q/-v + if options.quiet and options.verbose: + parser.error("Can't specify --quiet and --verbose") + if options.quiet: + options.verbose -= 1 + verbose = options.verbose + # --test + if options.test: + if args: + parser.error("Can't specify args with --test") + + args = "ScpDelete ScpCreate SpnCreate SpnRegister SpnUnregister ScpDelete" + log(1, "--test - pretending args are:\n %s", args) + args = args.split() + if not options.service_class: + options.service_class = "PythonScpTest" + log(2, "--test: --service-class=%s", options.service_class) + if not options.keywords: + options.keywords = "Python Powered".split() + log(2, "--test: --keyword=%s", options.keywords) + if not options.binding_string: + options.binding_string = "test binding string" + log(2, "--test: --binding-string=%s", options.binding_string) + + # check args + if not args: + parser.error("No command specified (use --help for valid commands)") + for arg in args: + if arg.lower() not in _handlers_dict: + parser.error("Invalid command '%s' (use --help for valid commands)" % arg) + + # Patch up account-name. + if options.account_name: + log(2, "Translating account name '%s'", options.account_name) + options.account_name_sam = win32security.TranslateName( + options.account_name, win32api.NameUnknown, win32api.NameSamCompatible + ) + log(2, "NameSamCompatible is '%s'", options.account_name_sam) + options.account_name_dn = win32security.TranslateName( + options.account_name, win32api.NameUnknown, win32api.NameFullyQualifiedDN + ) + log(2, "NameFullyQualifiedDNis '%s'", options.account_name_dn) + + # do it. + for arg in args: + handler = _handlers_dict[arg.lower()] # already been validated + if handler is None: + parser.error("Invalid command '%s'" % arg) + err_msg = None + try: + try: + log(2, "Executing '%s'...", arg) + result = handler(po) + log(1, "%s: %s", arg, result) + except: + if options.show_tracebacks: + print("--show-tracebacks specified - dumping exception") + traceback.print_exc() + raise + except adsi.error as xxx_todo_changeme: + (hr, desc, exc, argerr) = xxx_todo_changeme.args + if exc: + extra_desc = exc[2] + else: + extra_desc = "" + err_msg = desc + if extra_desc: + err_msg += "\n\t" + extra_desc + except win32api.error as xxx_todo_changeme1: + (hr, func, msg) = xxx_todo_changeme1.args + err_msg = msg + if err_msg: + log(1, "Command '%s' failed: %s", arg, err_msg) + + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("*** Interrupted") diff --git a/MLPY/Lib/site-packages/win32comext/adsi/demos/search.py b/MLPY/Lib/site-packages/win32comext/adsi/demos/search.py new file mode 100644 index 0000000000000000000000000000000000000000..22c6a25811e53eb7b14f47cbb17958fad8c65444 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/adsi/demos/search.py @@ -0,0 +1,152 @@ +import pythoncom +import pywintypes +import win32security +from win32com.adsi import adsi, adsicon +from win32com.adsi.adsicon import * + +options = None # set to optparse options object + +ADsTypeNameMap = {} + + +def getADsTypeName(type_val): + # convert integer type to the 'typename' as known in the headerfiles. + if not ADsTypeNameMap: + for n, v in adsicon.__dict__.items(): + if n.startswith("ADSTYPE_"): + ADsTypeNameMap[v] = n + return ADsTypeNameMap.get(type_val, hex(type_val)) + + +def _guid_from_buffer(b): + return pywintypes.IID(b, True) + + +def _sid_from_buffer(b): + return str(pywintypes.SID(b)) + + +_null_converter = lambda x: x + +converters = { + "objectGUID": _guid_from_buffer, + "objectSid": _sid_from_buffer, + "instanceType": getADsTypeName, +} + + +def log(level, msg, *args): + if options.verbose >= level: + print("log:", msg % args) + + +def getGC(): + cont = adsi.ADsOpenObject( + "GC:", options.user, options.password, 0, adsi.IID_IADsContainer + ) + enum = adsi.ADsBuildEnumerator(cont) + # Only 1 child of the global catalog. + for e in enum: + gc = e.QueryInterface(adsi.IID_IDirectorySearch) + return gc + return None + + +def print_attribute(col_data): + prop_name, prop_type, values = col_data + if values is not None: + log(2, "property '%s' has type '%s'", prop_name, getADsTypeName(prop_type)) + value = [converters.get(prop_name, _null_converter)(v[0]) for v in values] + if len(value) == 1: + value = value[0] + print(" %s=%r" % (prop_name, value)) + else: + print(" %s is None" % (prop_name,)) + + +def search(): + gc = getGC() + if gc is None: + log(0, "Can't find the global catalog") + return + + prefs = [(ADS_SEARCHPREF_SEARCH_SCOPE, (ADS_SCOPE_SUBTREE,))] + hr, statuses = gc.SetSearchPreference(prefs) + log(3, "SetSearchPreference returned %d/%r", hr, statuses) + + if options.attributes: + attributes = options.attributes.split(",") + else: + attributes = None + + h = gc.ExecuteSearch(options.filter, attributes) + hr = gc.GetNextRow(h) + while hr != S_ADS_NOMORE_ROWS: + print("-- new row --") + if attributes is None: + # Loop over all columns returned + while 1: + col_name = gc.GetNextColumnName(h) + if col_name is None: + break + data = gc.GetColumn(h, col_name) + print_attribute(data) + else: + # loop over attributes specified. + for a in attributes: + try: + data = gc.GetColumn(h, a) + print_attribute(data) + except adsi.error as details: + if details[0] != E_ADS_COLUMN_NOT_SET: + raise + print_attribute((a, None, None)) + hr = gc.GetNextRow(h) + gc.CloseSearchHandle(h) + + +def main(): + global options + from optparse import OptionParser + + parser = OptionParser() + parser.add_option( + "-f", "--file", dest="filename", help="write report to FILE", metavar="FILE" + ) + parser.add_option( + "-v", + "--verbose", + action="count", + default=1, + help="increase verbosity of output", + ) + parser.add_option( + "-q", "--quiet", action="store_true", help="suppress output messages" + ) + + parser.add_option("-U", "--user", help="specify the username used to connect") + parser.add_option("-P", "--password", help="specify the password used to connect") + parser.add_option( + "", + "--filter", + default="(&(objectCategory=person)(objectClass=User))", + help="specify the search filter", + ) + parser.add_option( + "", "--attributes", help="comma sep'd list of attribute names to print" + ) + + options, args = parser.parse_args() + if options.quiet: + if options.verbose != 1: + parser.error("Can not use '--verbose' and '--quiet'") + options.verbose = 0 + + if args: + parser.error("You need not specify args") + + search() + + +if __name__ == "__main__": + main() diff --git a/MLPY/Lib/site-packages/win32comext/adsi/demos/test.py b/MLPY/Lib/site-packages/win32comext/adsi/demos/test.py new file mode 100644 index 0000000000000000000000000000000000000000..a1dba34dc5ee851dc20971fa648736263b4b5650 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/adsi/demos/test.py @@ -0,0 +1,273 @@ +import string +import sys + +import pythoncom +import win32api +from win32com.adsi import * + +verbose_level = 0 + +server = "" # Must have trailing / +local_name = win32api.GetComputerName() + + +def DumpRoot(): + "Dumps the root DSE" + path = "LDAP://%srootDSE" % server + rootdse = ADsGetObject(path) + + for item in rootdse.Get("SupportedLDAPVersion"): + print("%s supports ldap version %s" % (path, item)) + + attributes = ["CurrentTime", "defaultNamingContext"] + for attr in attributes: + val = rootdse.Get(attr) + print(" %s=%s" % (attr, val)) + + +############################################### +# +# Code taken from article titled: +# Reading attributeSchema and classSchema Objects +def _DumpClass(child): + attrs = "Abstract lDAPDisplayName schemaIDGUID schemaNamingContext attributeSyntax oMSyntax" + _DumpTheseAttributes(child, string.split(attrs)) + + +def _DumpAttribute(child): + attrs = "lDAPDisplayName schemaIDGUID adminDescription adminDisplayName rDNAttID defaultHidingValue defaultObjectCategory systemOnly defaultSecurityDescriptor" + _DumpTheseAttributes(child, string.split(attrs)) + + +def _DumpTheseAttributes(child, attrs): + for attr in attrs: + try: + val = child.Get(attr) + except pythoncom.com_error as details: + continue + # ### + (hr, msg, exc, arg) = details + if exc and exc[2]: + msg = exc[2] + val = "" % (msg,) + if verbose_level >= 2: + print(" %s: %s=%s" % (child.Class, attr, val)) + + +def DumpSchema(): + "Dumps the default DSE schema" + # Bind to rootDSE to get the schemaNamingContext property. + path = "LDAP://%srootDSE" % server + rootdse = ADsGetObject(path) + name = rootdse.Get("schemaNamingContext") + + # Bind to the actual schema container. + path = "LDAP://" + server + name + print("Binding to", path) + ob = ADsGetObject(path) + nclasses = nattr = nsub = nunk = 0 + + # Enumerate the attribute and class objects in the schema container. + for child in ob: + # Find out if this is a class, attribute, or subSchema object. + class_name = child.Class + if class_name == "classSchema": + _DumpClass(child) + nclasses = nclasses + 1 + elif class_name == "attributeSchema": + _DumpAttribute(child) + nattr = nattr + 1 + elif class_name == "subSchema": + nsub = nsub + 1 + else: + print("Unknown class:", class_name) + nunk = nunk + 1 + if verbose_level: + print("Processed", nclasses, "classes") + print("Processed", nattr, "attributes") + print("Processed", nsub, "sub-schema's") + print("Processed", nunk, "unknown types") + + +def _DumpObject(ob, level=0): + prefix = " " * level + print("%s%s object: %s" % (prefix, ob.Class, ob.Name)) + # Do the directory object thing + try: + dir_ob = ADsGetObject(ob.ADsPath, IID_IDirectoryObject) + except pythoncom.com_error: + dir_ob = None + if dir_ob is not None: + info = dir_ob.GetObjectInformation() + print("%s RDN='%s', ObjectDN='%s'" % (prefix, info.RDN, info.ObjectDN)) + # Create a list of names to fetch + names = ["distinguishedName"] + attrs = dir_ob.GetObjectAttributes(names) + for attr in attrs: + for val, typ in attr.Values: + print("%s Attribute '%s' = %s" % (prefix, attr.AttrName, val)) + + for child in ob: + _DumpObject(child, level + 1) + + +def DumpAllObjects(): + "Recursively dump the entire directory!" + path = "LDAP://%srootDSE" % server + rootdse = ADsGetObject(path) + name = rootdse.Get("defaultNamingContext") + + # Bind to the actual schema container. + path = "LDAP://" + server + name + print("Binding to", path) + ob = ADsGetObject(path) + + # Enumerate the attribute and class objects in the schema container. + _DumpObject(ob) + + +########################################################## +# +# Code taken from article: +# Example Code for Enumerating Schema Classes, Attributes, and Syntaxes + +# Fill a map with VT_ datatypes, to give us better names: +vt_map = {} +for name, val in pythoncom.__dict__.items(): + if name[:3] == "VT_": + vt_map[val] = name + + +def DumpSchema2(): + "Dumps the schema using an alternative technique" + path = "LDAP://%sschema" % (server,) + schema = ADsGetObject(path, IID_IADsContainer) + nclass = nprop = nsyntax = 0 + for item in schema: + item_class = string.lower(item.Class) + if item_class == "class": + items = [] + if item.Abstract: + items.append("Abstract") + if item.Auxiliary: + items.append("Auxiliary") + # if item.Structural: items.append("Structural") + desc = string.join(items, ", ") + import win32com.util + + iid_name = win32com.util.IIDToInterfaceName(item.PrimaryInterface) + if verbose_level >= 2: + print( + "Class: Name=%s, Flags=%s, Primary Interface=%s" + % (item.Name, desc, iid_name) + ) + nclass = nclass + 1 + elif item_class == "property": + if item.MultiValued: + val_type = "Multi-Valued" + else: + val_type = "Single-Valued" + if verbose_level >= 2: + print("Property: Name=%s, %s" % (item.Name, val_type)) + nprop = nprop + 1 + elif item_class == "syntax": + data_type = vt_map.get(item.OleAutoDataType, "") + if verbose_level >= 2: + print("Syntax: Name=%s, Datatype = %s" % (item.Name, data_type)) + nsyntax = nsyntax + 1 + if verbose_level >= 1: + print("Processed", nclass, "classes") + print("Processed", nprop, "properties") + print("Processed", nsyntax, "syntax items") + + +def DumpGC(): + "Dumps the GC: object (whatever that is!)" + ob = ADsGetObject("GC:", IID_IADsContainer) + for sub_ob in ob: + print("GC ob: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath)) + + +def DumpLocalUsers(): + "Dumps the local machine users" + path = "WinNT://%s,computer" % (local_name,) + ob = ADsGetObject(path, IID_IADsContainer) + ob.put_Filter(["User", "Group"]) + for sub_ob in ob: + print("User/Group: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath)) + + +def DumpLocalGroups(): + "Dumps the local machine groups" + path = "WinNT://%s,computer" % (local_name,) + ob = ADsGetObject(path, IID_IADsContainer) + + ob.put_Filter(["Group"]) + for sub_ob in ob: + print("Group: %s (%s)" % (sub_ob.Name, sub_ob.ADsPath)) + # get the members + members = sub_ob.Members() + for member in members: + print(" Group member: %s (%s)" % (member.Name, member.ADsPath)) + + +def usage(tests): + import os + + print("Usage: %s [-s server ] [-v] [Test ...]" % os.path.basename(sys.argv[0])) + print(" -v : Verbose - print more information") + print(" -s : server - execute the tests against the named server") + print("where Test is one of:") + for t in tests: + print(t.__name__, ":", t.__doc__) + print() + print("If not tests are specified, all tests are run") + sys.exit(1) + + +def main(): + import getopt + import traceback + + tests = [] + for ob in globals().values(): + if type(ob) == type(main) and ob.__doc__: + tests.append(ob) + opts, args = getopt.getopt(sys.argv[1:], "s:hv") + for opt, val in opts: + if opt == "-s": + if val[-1] not in "\\/": + val = val + "/" + global server + server = val + if opt == "-h": + usage(tests) + if opt == "-v": + global verbose_level + verbose_level = verbose_level + 1 + + if len(args) == 0: + print("Running all tests - use '-h' to see command-line options...") + dotests = tests + else: + dotests = [] + for arg in args: + for t in tests: + if t.__name__ == arg: + dotests.append(t) + break + else: + print("Test '%s' unknown - skipping" % arg) + if not len(dotests): + print("Nothing to do!") + usage(tests) + for test in dotests: + try: + test() + except: + print("Test %s failed" % test.__name__) + traceback.print_exc() + + +if __name__ == "__main__": + main() diff --git a/MLPY/Lib/site-packages/win32comext/authorization/__init__.py b/MLPY/Lib/site-packages/win32comext/authorization/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3a893267ed404c4d980001d4b383b0882c4e7c08 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/authorization/__init__.py @@ -0,0 +1,6 @@ +# This is a python package +# __PackageSupportBuildPath__ not needed for distutil based builds, +# but not everyone is there yet. +import win32com + +win32com.__PackageSupportBuildPath__(__path__) diff --git a/MLPY/Lib/site-packages/win32comext/authorization/__pycache__/__init__.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/authorization/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d22fc5fc278a045af74dfbf6551c0d5e6b13f760 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/authorization/__pycache__/__init__.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/authorization/authorization.pyd b/MLPY/Lib/site-packages/win32comext/authorization/authorization.pyd new file mode 100644 index 0000000000000000000000000000000000000000..4c473bd0baf49054bdcf5e64324cf0bc383a3c9b Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/authorization/authorization.pyd differ diff --git a/MLPY/Lib/site-packages/win32comext/authorization/demos/EditSecurity.py b/MLPY/Lib/site-packages/win32comext/authorization/demos/EditSecurity.py new file mode 100644 index 0000000000000000000000000000000000000000..d961bc0d1824cc64e0339690aae2c13ad9f56141 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/authorization/demos/EditSecurity.py @@ -0,0 +1,255 @@ +import os + +import ntsecuritycon +import pythoncom +import win32api +import win32com.server.policy +import win32con +import win32security +from ntsecuritycon import ( + CONTAINER_INHERIT_ACE, + FILE_ALL_ACCESS, + FILE_APPEND_DATA, + FILE_GENERIC_EXECUTE, + FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_READ_ATTRIBUTES, + FILE_READ_DATA, + FILE_READ_EA, + FILE_WRITE_ATTRIBUTES, + FILE_WRITE_DATA, + FILE_WRITE_EA, + INHERIT_ONLY_ACE, + OBJECT_INHERIT_ACE, + PSPCB_SI_INITDIALOG, + READ_CONTROL, + SI_ACCESS_CONTAINER, + SI_ACCESS_GENERAL, + SI_ACCESS_PROPERTY, + SI_ACCESS_SPECIFIC, + SI_ADVANCED, + SI_CONTAINER, + SI_EDIT_ALL, + SI_EDIT_AUDITS, + SI_EDIT_PROPERTIES, + SI_PAGE_ADVPERM, + SI_PAGE_AUDIT, + SI_PAGE_OWNER, + SI_PAGE_PERM, + SI_PAGE_TITLE, + SI_RESET, + STANDARD_RIGHTS_EXECUTE, + STANDARD_RIGHTS_READ, + STANDARD_RIGHTS_WRITE, + SYNCHRONIZE, + WRITE_DAC, + WRITE_OWNER, +) +from pythoncom import IID_NULL +from win32com.authorization import authorization +from win32com.shell.shellcon import ( # # Msg parameter to PropertySheetPageCallback + PSPCB_CREATE, + PSPCB_RELEASE, +) +from win32security import CONTAINER_INHERIT_ACE, INHERIT_ONLY_ACE, OBJECT_INHERIT_ACE + + +class SecurityInformation(win32com.server.policy.DesignatedWrapPolicy): + _com_interfaces_ = [authorization.IID_ISecurityInformation] + _public_methods_ = [ + "GetObjectInformation", + "GetSecurity", + "SetSecurity", + "GetAccessRights", + "GetInheritTypes", + "MapGeneric", + "PropertySheetPageCallback", + ] + + def __init__(self, FileName): + self.FileName = FileName + self._wrap_(self) + + def GetObjectInformation(self): + """Identifies object whose security will be modified, and determines options available + to the end user""" + flags = SI_ADVANCED | SI_EDIT_ALL | SI_PAGE_TITLE | SI_RESET + if os.path.isdir(self.FileName): + flags |= SI_CONTAINER + hinstance = 0 ## handle to module containing string resources + servername = "" ## name of authenticating server if not local machine + objectname = os.path.split(self.FileName)[1] + pagetitle = "Python ACL Editor" + if os.path.isdir(self.FileName): + pagetitle += " (dir)" + else: + pagetitle += " (file)" + objecttype = IID_NULL + return flags, hinstance, servername, objectname, pagetitle, objecttype + + def GetSecurity(self, requestedinfo, bdefault): + """Requests the existing permissions for object""" + if bdefault: + ## This is invoked if the 'Default' button is pressed (only present if SI_RESET is passed + ## with the flags in GetObjectInfo). Passing an empty SD with a NULL Dacl + ## should cause inherited ACL from parent dir or default dacl from user's token to be used + return win32security.SECURITY_DESCRIPTOR() + else: + ## GetFileSecurity sometimes fails to return flags indicating that an ACE is inherited + return win32security.GetNamedSecurityInfo( + self.FileName, win32security.SE_FILE_OBJECT, requestedinfo + ) + + def SetSecurity(self, requestedinfo, sd): + """Applies permissions to the object""" + owner = sd.GetSecurityDescriptorOwner() + group = sd.GetSecurityDescriptorGroup() + dacl = sd.GetSecurityDescriptorDacl() + sacl = sd.GetSecurityDescriptorSacl() + win32security.SetNamedSecurityInfo( + self.FileName, + win32security.SE_FILE_OBJECT, + requestedinfo, + owner, + group, + dacl, + sacl, + ) + ## should also handle recursive operations here + + def GetAccessRights(self, objecttype, flags): + """Returns a tuple of (AccessRights, DefaultAccess), where AccessRights is a sequence of tuples representing + SI_ACCESS structs, containing (guid, access mask, Name, flags). DefaultAccess indicates which of the + AccessRights will be used initially when a new ACE is added (zero based). + Flags can contain SI_ACCESS_SPECIFIC,SI_ACCESS_GENERAL,SI_ACCESS_CONTAINER,SI_ACCESS_PROPERTY, + CONTAINER_INHERIT_ACE,INHERIT_ONLY_ACE,OBJECT_INHERIT_ACE + """ + ## input flags: SI_ADVANCED,SI_EDIT_AUDITS,SI_EDIT_PROPERTIES indicating which property sheet is requesting the rights + if (objecttype is not None) and (objecttype != IID_NULL): + ## Should not be true for file objects. Usually only used with DS objects that support security for + ## their properties + raise NotImplementedError("Object type is not supported") + + if os.path.isdir(self.FileName): + file_append_data_desc = "Create subfolders" + file_write_data_desc = "Create Files" + else: + file_append_data_desc = "Append data" + file_write_data_desc = "Write data" + + accessrights = [ + ( + IID_NULL, + FILE_GENERIC_READ, + "Generic read", + SI_ACCESS_GENERAL + | SI_ACCESS_SPECIFIC + | OBJECT_INHERIT_ACE + | CONTAINER_INHERIT_ACE, + ), + ( + IID_NULL, + FILE_GENERIC_WRITE, + "Generic write", + SI_ACCESS_GENERAL + | SI_ACCESS_SPECIFIC + | OBJECT_INHERIT_ACE + | CONTAINER_INHERIT_ACE, + ), + ( + IID_NULL, + win32con.DELETE, + "Delete", + SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, + ), + ( + IID_NULL, + WRITE_OWNER, + "Change owner", + SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, + ), + ( + IID_NULL, + READ_CONTROL, + "Read Permissions", + SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, + ), + ( + IID_NULL, + WRITE_DAC, + "Change permissions", + SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, + ), + ( + IID_NULL, + FILE_APPEND_DATA, + file_append_data_desc, + SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, + ), + ( + IID_NULL, + FILE_WRITE_DATA, + file_write_data_desc, + SI_ACCESS_SPECIFIC | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, + ), + ] + return (accessrights, 0) + + def MapGeneric(self, guid, aceflags, mask): + """Converts generic access rights to specific rights. This implementation uses standard file system rights, + but you can map them any way that suits your application. + """ + return win32security.MapGenericMask( + mask, + ( + FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_GENERIC_EXECUTE, + FILE_ALL_ACCESS, + ), + ) + + def GetInheritTypes(self): + """Specifies which types of ACE inheritance are supported. + Returns a sequence of tuples representing SI_INHERIT_TYPE structs, containing + (object type guid, inheritance flags, display name). Guid is usually only used with + Directory Service objects. + """ + return ( + (IID_NULL, 0, "Only current object"), + (IID_NULL, OBJECT_INHERIT_ACE, "Files inherit permissions"), + (IID_NULL, CONTAINER_INHERIT_ACE, "Sub Folders inherit permissions"), + ( + IID_NULL, + CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, + "Files and subfolders", + ), + ) + + def PropertySheetPageCallback(self, hwnd, msg, pagetype): + """Invoked each time a property sheet page is created or destroyed.""" + ## page types from SI_PAGE_TYPE enum: SI_PAGE_PERM SI_PAGE_ADVPERM SI_PAGE_AUDIT SI_PAGE_OWNER + ## msg: PSPCB_CREATE, PSPCB_RELEASE, PSPCB_SI_INITDIALOG + return None + + def EditSecurity(self, owner_hwnd=0): + """Creates an ACL editor dialog based on parameters returned by interface methods""" + isi = pythoncom.WrapObject( + self, authorization.IID_ISecurityInformation, pythoncom.IID_IUnknown + ) + authorization.EditSecurity(owner_hwnd, isi) + + +## folder permissions +temp_dir = win32api.GetTempPath() +dir_name = win32api.GetTempFileName(temp_dir, "isi")[0] +print(dir_name) +os.remove(dir_name) +os.mkdir(dir_name) +si = SecurityInformation(dir_name) +si.EditSecurity() + +## file permissions +fname = win32api.GetTempFileName(dir_name, "isi")[0] +si = SecurityInformation(fname) +si.EditSecurity() diff --git a/MLPY/Lib/site-packages/win32comext/authorization/demos/EditServiceSecurity.py b/MLPY/Lib/site-packages/win32comext/authorization/demos/EditServiceSecurity.py new file mode 100644 index 0000000000000000000000000000000000000000..86d60414c12b6b69cb60ecbcbdd57405a267fde6 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/authorization/demos/EditServiceSecurity.py @@ -0,0 +1,242 @@ +""" +Implements a permissions editor for services. +Service can be specified as plain name for local machine, +or as a remote service of the form \\machinename\service +""" + +import os + +import ntsecuritycon +import pythoncom +import win32api +import win32com.server.policy +import win32con +import win32security +import win32service +from win32com.authorization import authorization + +SERVICE_GENERIC_EXECUTE = ( + win32service.SERVICE_START + | win32service.SERVICE_STOP + | win32service.SERVICE_PAUSE_CONTINUE + | win32service.SERVICE_USER_DEFINED_CONTROL +) +SERVICE_GENERIC_READ = ( + win32service.SERVICE_QUERY_CONFIG + | win32service.SERVICE_QUERY_STATUS + | win32service.SERVICE_INTERROGATE + | win32service.SERVICE_ENUMERATE_DEPENDENTS +) +SERVICE_GENERIC_WRITE = win32service.SERVICE_CHANGE_CONFIG + +from ntsecuritycon import ( + CONTAINER_INHERIT_ACE, + INHERIT_ONLY_ACE, + OBJECT_INHERIT_ACE, + PSPCB_SI_INITDIALOG, + READ_CONTROL, + SI_ACCESS_CONTAINER, + SI_ACCESS_GENERAL, + SI_ACCESS_PROPERTY, + SI_ACCESS_SPECIFIC, + SI_ADVANCED, + SI_CONTAINER, + SI_EDIT_ALL, + SI_EDIT_AUDITS, + SI_EDIT_PROPERTIES, + SI_PAGE_ADVPERM, + SI_PAGE_AUDIT, + SI_PAGE_OWNER, + SI_PAGE_PERM, + SI_PAGE_TITLE, + SI_RESET, + STANDARD_RIGHTS_EXECUTE, + STANDARD_RIGHTS_READ, + STANDARD_RIGHTS_WRITE, + WRITE_DAC, + WRITE_OWNER, +) +from pythoncom import IID_NULL +from win32com.shell.shellcon import ( # # Msg parameter to PropertySheetPageCallback + PSPCB_CREATE, + PSPCB_RELEASE, +) +from win32security import CONTAINER_INHERIT_ACE, INHERIT_ONLY_ACE, OBJECT_INHERIT_ACE + + +class ServiceSecurity(win32com.server.policy.DesignatedWrapPolicy): + _com_interfaces_ = [authorization.IID_ISecurityInformation] + _public_methods_ = [ + "GetObjectInformation", + "GetSecurity", + "SetSecurity", + "GetAccessRights", + "GetInheritTypes", + "MapGeneric", + "PropertySheetPageCallback", + ] + + def __init__(self, ServiceName): + self.ServiceName = ServiceName + self._wrap_(self) + + def GetObjectInformation(self): + """Identifies object whose security will be modified, and determines options available + to the end user""" + flags = SI_ADVANCED | SI_EDIT_ALL | SI_PAGE_TITLE | SI_RESET + hinstance = 0 ## handle to module containing string resources + servername = "" ## name of authenticating server if not local machine + + ## service name can contain remote machine name of the form \\Server\ServiceName + objectname = os.path.split(self.ServiceName)[1] + pagetitle = "Service Permissions for " + self.ServiceName + objecttype = IID_NULL + return flags, hinstance, servername, objectname, pagetitle, objecttype + + def GetSecurity(self, requestedinfo, bdefault): + """Requests the existing permissions for object""" + if bdefault: + return win32security.SECURITY_DESCRIPTOR() + else: + return win32security.GetNamedSecurityInfo( + self.ServiceName, win32security.SE_SERVICE, requestedinfo + ) + + def SetSecurity(self, requestedinfo, sd): + """Applies permissions to the object""" + owner = sd.GetSecurityDescriptorOwner() + group = sd.GetSecurityDescriptorGroup() + dacl = sd.GetSecurityDescriptorDacl() + sacl = sd.GetSecurityDescriptorSacl() + win32security.SetNamedSecurityInfo( + self.ServiceName, + win32security.SE_SERVICE, + requestedinfo, + owner, + group, + dacl, + sacl, + ) + + def GetAccessRights(self, objecttype, flags): + """Returns a tuple of (AccessRights, DefaultAccess), where AccessRights is a sequence of tuples representing + SI_ACCESS structs, containing (guid, access mask, Name, flags). DefaultAccess indicates which of the + AccessRights will be used initially when a new ACE is added (zero based). + Flags can contain SI_ACCESS_SPECIFIC,SI_ACCESS_GENERAL,SI_ACCESS_CONTAINER,SI_ACCESS_PROPERTY, + CONTAINER_INHERIT_ACE,INHERIT_ONLY_ACE,OBJECT_INHERIT_ACE + """ + ## input flags: SI_ADVANCED,SI_EDIT_AUDITS,SI_EDIT_PROPERTIES indicating which property sheet is requesting the rights + if (objecttype is not None) and (objecttype != IID_NULL): + ## Not relevent for services + raise NotImplementedError("Object type is not supported") + + ## ???? for some reason, the DACL for a service will not retain ACCESS_SYSTEM_SECURITY in an ACE ???? + ## (IID_NULL, win32con.ACCESS_SYSTEM_SECURITY, 'View/change audit settings', SI_ACCESS_SPECIFIC), + + accessrights = [ + ( + IID_NULL, + win32service.SERVICE_ALL_ACCESS, + "Full control", + SI_ACCESS_GENERAL, + ), + (IID_NULL, SERVICE_GENERIC_READ, "Generic read", SI_ACCESS_GENERAL), + (IID_NULL, SERVICE_GENERIC_WRITE, "Generic write", SI_ACCESS_GENERAL), + ( + IID_NULL, + SERVICE_GENERIC_EXECUTE, + "Start/Stop/Pause service", + SI_ACCESS_GENERAL, + ), + (IID_NULL, READ_CONTROL, "Read Permissions", SI_ACCESS_GENERAL), + (IID_NULL, WRITE_DAC, "Change permissions", SI_ACCESS_GENERAL), + (IID_NULL, WRITE_OWNER, "Change owner", SI_ACCESS_GENERAL), + (IID_NULL, win32con.DELETE, "Delete service", SI_ACCESS_GENERAL), + (IID_NULL, win32service.SERVICE_START, "Start service", SI_ACCESS_SPECIFIC), + (IID_NULL, win32service.SERVICE_STOP, "Stop service", SI_ACCESS_SPECIFIC), + ( + IID_NULL, + win32service.SERVICE_PAUSE_CONTINUE, + "Pause/unpause service", + SI_ACCESS_SPECIFIC, + ), + ( + IID_NULL, + win32service.SERVICE_USER_DEFINED_CONTROL, + "Execute user defined operations", + SI_ACCESS_SPECIFIC, + ), + ( + IID_NULL, + win32service.SERVICE_QUERY_CONFIG, + "Read configuration", + SI_ACCESS_SPECIFIC, + ), + ( + IID_NULL, + win32service.SERVICE_CHANGE_CONFIG, + "Change configuration", + SI_ACCESS_SPECIFIC, + ), + ( + IID_NULL, + win32service.SERVICE_ENUMERATE_DEPENDENTS, + "List dependent services", + SI_ACCESS_SPECIFIC, + ), + ( + IID_NULL, + win32service.SERVICE_QUERY_STATUS, + "Query status", + SI_ACCESS_SPECIFIC, + ), + ( + IID_NULL, + win32service.SERVICE_INTERROGATE, + "Query status (immediate)", + SI_ACCESS_SPECIFIC, + ), + ] + return (accessrights, 0) + + def MapGeneric(self, guid, aceflags, mask): + """Converts generic access rights to specific rights.""" + return win32security.MapGenericMask( + mask, + ( + SERVICE_GENERIC_READ, + SERVICE_GENERIC_WRITE, + SERVICE_GENERIC_EXECUTE, + win32service.SERVICE_ALL_ACCESS, + ), + ) + + def GetInheritTypes(self): + """Specifies which types of ACE inheritance are supported. + Services don't use any inheritance + """ + return ((IID_NULL, 0, "Only current object"),) + + def PropertySheetPageCallback(self, hwnd, msg, pagetype): + """Invoked each time a property sheet page is created or destroyed.""" + ## page types from SI_PAGE_TYPE enum: SI_PAGE_PERM SI_PAGE_ADVPERM SI_PAGE_AUDIT SI_PAGE_OWNER + ## msg: PSPCB_CREATE, PSPCB_RELEASE, PSPCB_SI_INITDIALOG + return None + + def EditSecurity(self, owner_hwnd=0): + """Creates an ACL editor dialog based on parameters returned by interface methods""" + isi = pythoncom.WrapObject( + self, authorization.IID_ISecurityInformation, pythoncom.IID_IUnknown + ) + authorization.EditSecurity(owner_hwnd, isi) + + +if __name__ == "__main__": + # Find the first service on local machine and edit its permissions + scm = win32service.OpenSCManager( + None, None, win32service.SC_MANAGER_ENUMERATE_SERVICE + ) + svcs = win32service.EnumServicesStatus(scm) + win32service.CloseServiceHandle(scm) + si = ServiceSecurity(svcs[0][0]) + si.EditSecurity() diff --git a/MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditSecurity.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditSecurity.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4bfc0bb8aaf610b1342ef481263a673ca1bb7fc2 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditSecurity.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditServiceSecurity.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditServiceSecurity.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f830ec59127668667837c83d6f1a75c83efeedb Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/authorization/demos/__pycache__/EditServiceSecurity.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axcontrol/__init__.py b/MLPY/Lib/site-packages/win32comext/axcontrol/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8d5db8b9375cce5e37b013fc099e1ccc4ba4374e --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axcontrol/__init__.py @@ -0,0 +1,4 @@ +# See if we have a special directory for the binaries (for developers) +import win32com + +win32com.__PackageSupportBuildPath__(__path__) diff --git a/MLPY/Lib/site-packages/win32comext/axcontrol/__pycache__/__init__.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axcontrol/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c778f371200873e5b2ec2bec91e67654626168e Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axcontrol/__pycache__/__init__.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axcontrol/axcontrol.pyd b/MLPY/Lib/site-packages/win32comext/axcontrol/axcontrol.pyd new file mode 100644 index 0000000000000000000000000000000000000000..40cb13efb8d20aab01709722d253e1391db7d154 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axcontrol/axcontrol.pyd differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__init__.py b/MLPY/Lib/site-packages/win32comext/axdebug/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8d5db8b9375cce5e37b013fc099e1ccc4ba4374e --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/__init__.py @@ -0,0 +1,4 @@ +# See if we have a special directory for the binaries (for developers) +import win32com + +win32com.__PackageSupportBuildPath__(__path__) diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/__init__.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71178700f57f2a299cc95f4355e6e0db15214847 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/__init__.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/adb.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/adb.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..364a0a2d957ccaef3245aa297cba0c997ca3b858 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/adb.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/codecontainer.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/codecontainer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ec4f19dba228c0a22b75185eb39fa96054fb89c Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/codecontainer.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/contexts.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/contexts.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f6fc912fcbe72c1eba9fe4060ddc79e81b02fb1 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/contexts.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/debugger.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/debugger.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b50fc5f42eab9109558d9a155c707c26cfcdc6d3 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/debugger.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/documents.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/documents.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b66c4a6a6c4860cf9e36be002d7670b4e2554ec Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/documents.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/dump.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/dump.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95469e351c75572d51cf476025fdd8c871292852 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/dump.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/expressions.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/expressions.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a46196af4f30e28d2a417d1c8299f809ee2a39a3 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/expressions.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/gateways.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/gateways.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27edc2e5757106a1a6472f3c2f5860bf99090ebe Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/gateways.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/stackframe.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/stackframe.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5958ffd4c28b861c7b30e342eaf43422413dd66 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/stackframe.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/util.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/util.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45c112fc31efceb4792a32633dd9e6659542e1a3 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/__pycache__/util.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/adb.py b/MLPY/Lib/site-packages/win32comext/axdebug/adb.py new file mode 100644 index 0000000000000000000000000000000000000000..812c23e62a1801d2c1f61d528c6360d11f4a9e7d --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/adb.py @@ -0,0 +1,480 @@ +"""The glue between the Python debugger interface and the Active Debugger interface +""" +import _thread +import bdb +import os +import sys +import traceback + +import pythoncom +import win32api +import win32com.client.connect +from win32com.axdebug.util import _wrap, _wrap_remove, trace +from win32com.server.util import unwrap + +from . import axdebug, gateways, stackframe + + +def fnull(*args): + pass + + +try: + os.environ["DEBUG_AXDEBUG"] + debugging = 1 +except KeyError: + debugging = 0 + +traceenter = fnull # trace enter of functions +tracev = fnull # verbose trace + +if debugging: + traceenter = trace # trace enter of functions + tracev = trace # verbose trace + + +class OutputReflector: + def __init__(self, file, writefunc): + self.writefunc = writefunc + self.file = file + + def __getattr__(self, name): + return getattr(self.file, name) + + def write(self, message): + self.writefunc(message) + self.file.write(message) + + +def _dumpf(frame): + if frame is None: + return "" + else: + addn = "(with trace!)" + if frame.f_trace is None: + addn = " **No Trace Set **" + return "Frame at %d, file %s, line: %d%s" % ( + id(frame), + frame.f_code.co_filename, + frame.f_lineno, + addn, + ) + + +g_adb = None + + +def OnSetBreakPoint(codeContext, breakPointState, lineNo): + try: + fileName = codeContext.codeContainer.GetFileName() + # inject the code into linecache. + import linecache + + linecache.cache[fileName] = 0, 0, codeContext.codeContainer.GetText(), fileName + g_adb._OnSetBreakPoint(fileName, codeContext, breakPointState, lineNo + 1) + except: + traceback.print_exc() + + +class Adb(bdb.Bdb, gateways.RemoteDebugApplicationEvents): + def __init__(self): + self.debugApplication = None + self.debuggingThread = None + self.debuggingThreadStateHandle = None + self.stackSnifferCookie = self.stackSniffer = None + self.codeContainerProvider = None + self.debuggingThread = None + self.breakFlags = None + self.breakReason = None + self.appDebugger = None + self.appEventConnection = None + self.logicalbotframe = None # Anything at this level or below does not exist! + self.currentframe = None # The frame we are currently in. + self.recursiveData = [] # Data saved for each reentery on this thread. + bdb.Bdb.__init__(self) + self._threadprotectlock = _thread.allocate_lock() + self.reset() + + def canonic(self, fname): + if fname[0] == "<": + return fname + return bdb.Bdb.canonic(self, fname) + + def reset(self): + traceenter("adb.reset") + bdb.Bdb.reset(self) + + def __xxxxx__set_break(self, filename, lineno, cond=None): + # As per standard one, except no linecache checking! + if filename not in self.breaks: + self.breaks[filename] = [] + list = self.breaks[filename] + if lineno in list: + return "There is already a breakpoint there!" + list.append(lineno) + if cond is not None: + self.cbreaks[filename, lineno] = cond + + def stop_here(self, frame): + traceenter("stop_here", _dumpf(frame), _dumpf(self.stopframe)) + # As per bdb.stop_here, except for logicalbotframe + ## if self.stopframe is None: + ## return 1 + if frame is self.stopframe: + return 1 + + tracev("stop_here said 'No'!") + return 0 + + def break_here(self, frame): + traceenter("break_here", self.breakFlags, _dumpf(frame)) + self.breakReason = None + if self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_HALT: + self.breakReason = axdebug.BREAKREASON_DEBUGGER_HALT + elif self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_BLOCK: + self.breakReason = axdebug.BREAKREASON_DEBUGGER_BLOCK + elif self.breakFlags == axdebug.APPBREAKFLAG_STEP: + self.breakReason = axdebug.BREAKREASON_STEP + else: + print("Calling base 'break_here' with", self.breaks) + if bdb.Bdb.break_here(self, frame): + self.breakReason = axdebug.BREAKREASON_BREAKPOINT + return self.breakReason is not None + + def break_anywhere(self, frame): + traceenter("break_anywhere", _dumpf(frame)) + if self.breakFlags == axdebug.APPBREAKFLAG_DEBUGGER_HALT: + self.breakReason = axdebug.BREAKREASON_DEBUGGER_HALT + return 1 + rc = bdb.Bdb.break_anywhere(self, frame) + tracev("break_anywhere", _dumpf(frame), "returning", rc) + return rc + + def dispatch_return(self, frame, arg): + traceenter("dispatch_return", _dumpf(frame), arg) + if self.logicalbotframe is frame: + # We dont want to debug parent frames. + tracev("dispatch_return resetting sys.trace") + sys.settrace(None) + return + # self.bSetTrace = 0 + self.currentframe = frame.f_back + return bdb.Bdb.dispatch_return(self, frame, arg) + + def dispatch_line(self, frame): + traceenter("dispatch_line", _dumpf(frame), _dumpf(self.botframe)) + # trace("logbotframe is", _dumpf(self.logicalbotframe), "botframe is", self.botframe) + if frame is self.logicalbotframe: + trace("dispatch_line", _dumpf(frame), "for bottom frame returing tracer") + # The next code executed in the frame above may be a builtin (eg, apply()) + # in which sys.trace needs to be set. + sys.settrace(self.trace_dispatch) + # And return the tracer incase we are about to execute Python code, + # in which case sys tracer is ignored! + return self.trace_dispatch + + if self.codeContainerProvider.FromFileName(frame.f_code.co_filename) is None: + trace( + "dispatch_line has no document for", _dumpf(frame), "- skipping trace!" + ) + return None + self.currentframe = ( + frame # So the stack sniffer knows our most recent, debuggable code. + ) + return bdb.Bdb.dispatch_line(self, frame) + + def dispatch_call(self, frame, arg): + traceenter("dispatch_call", _dumpf(frame)) + frame.f_locals["__axstack_address__"] = axdebug.GetStackAddress() + if frame is self.botframe: + trace("dispatch_call is self.botframe - returning tracer") + return self.trace_dispatch + # Not our bottom frame. If we have a document for it, + # then trace it, otherwise run at full speed. + if self.codeContainerProvider.FromFileName(frame.f_code.co_filename) is None: + trace( + "dispatch_call has no document for", _dumpf(frame), "- skipping trace!" + ) + ## sys.settrace(None) + return None + return self.trace_dispatch + + # rc = bdb.Bdb.dispatch_call(self, frame, arg) + # trace("dispatch_call", _dumpf(frame),"returned",rc) + # return rc + + def trace_dispatch(self, frame, event, arg): + traceenter("trace_dispatch", _dumpf(frame), event, arg) + if self.debugApplication is None: + trace("trace_dispatch has no application!") + return # None + return bdb.Bdb.trace_dispatch(self, frame, event, arg) + + # + # The user functions do bugger all! + # + # def user_call(self, frame, argument_list): + # traceenter("user_call",_dumpf(frame)) + + def user_line(self, frame): + traceenter("user_line", _dumpf(frame)) + # Traces at line zero + if frame.f_lineno != 0: + breakReason = self.breakReason + if breakReason is None: + breakReason = axdebug.BREAKREASON_STEP + self._HandleBreakPoint(frame, None, breakReason) + + def user_return(self, frame, return_value): + # traceenter("user_return",_dumpf(frame),return_value) + bdb.Bdb.user_return(self, frame, return_value) + + def user_exception(self, frame, exc_info): + # traceenter("user_exception") + bdb.Bdb.user_exception(self, frame, exc_info) + + def _HandleBreakPoint(self, frame, tb, reason): + traceenter( + "Calling HandleBreakPoint with reason", reason, "at frame", _dumpf(frame) + ) + traceenter(" Current frame is", _dumpf(self.currentframe)) + try: + resumeAction = self.debugApplication.HandleBreakPoint(reason) + tracev("HandleBreakPoint returned with ", resumeAction) + except pythoncom.com_error as details: + # Eeek - the debugger is dead, or something serious is happening. + # Assume we should continue + resumeAction = axdebug.BREAKRESUMEACTION_CONTINUE + trace("HandleBreakPoint FAILED with", details) + + self.stack = [] + self.curindex = 0 + if resumeAction == axdebug.BREAKRESUMEACTION_ABORT: + self.set_quit() + elif resumeAction == axdebug.BREAKRESUMEACTION_CONTINUE: + tracev("resume action is continue") + self.set_continue() + elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_INTO: + tracev("resume action is step") + self.set_step() + elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_OVER: + tracev("resume action is next") + self.set_next(frame) + elif resumeAction == axdebug.BREAKRESUMEACTION_STEP_OUT: + tracev("resume action is stop out") + self.set_return(frame) + else: + raise ValueError("unknown resume action flags") + self.breakReason = None + + def set_trace(self): + self.breakReason = axdebug.BREAKREASON_LANGUAGE_INITIATED + bdb.Bdb.set_trace(self) + + def CloseApp(self): + traceenter("ClosingApp") + self.reset() + self.logicalbotframe = None + if self.stackSnifferCookie is not None: + try: + self.debugApplication.RemoveStackFrameSniffer(self.stackSnifferCookie) + + except pythoncom.com_error: + trace( + "*** Could not RemoveStackFrameSniffer %d" + % (self.stackSnifferCookie) + ) + if self.stackSniffer: + _wrap_remove(self.stackSniffer) + self.stackSnifferCookie = self.stackSniffer = None + + if self.appEventConnection is not None: + self.appEventConnection.Disconnect() + self.appEventConnection = None + self.debugApplication = None + self.appDebugger = None + if self.codeContainerProvider is not None: + self.codeContainerProvider.Close() + self.codeContainerProvider = None + + def AttachApp(self, debugApplication, codeContainerProvider): + # traceenter("AttachApp", debugApplication, codeContainerProvider) + self.codeContainerProvider = codeContainerProvider + self.debugApplication = debugApplication + self.stackSniffer = _wrap( + stackframe.DebugStackFrameSniffer(self), axdebug.IID_IDebugStackFrameSniffer + ) + self.stackSnifferCookie = debugApplication.AddStackFrameSniffer( + self.stackSniffer + ) + # trace("StackFrameSniffer added (%d)" % self.stackSnifferCookie) + + # Connect to the application events. + self.appEventConnection = win32com.client.connect.SimpleConnection( + self.debugApplication, self, axdebug.IID_IRemoteDebugApplicationEvents + ) + + def ResetAXDebugging(self): + traceenter("ResetAXDebugging", self, "with refcount", len(self.recursiveData)) + if win32api.GetCurrentThreadId() != self.debuggingThread: + trace("ResetAXDebugging called on other thread") + return + + if len(self.recursiveData) == 0: + # print "ResetAXDebugging called for final time." + self.logicalbotframe = None + self.debuggingThread = None + self.currentframe = None + self.debuggingThreadStateHandle = None + return + + ( + self.logbotframe, + self.stopframe, + self.currentframe, + self.debuggingThreadStateHandle, + ) = self.recursiveData[0] + self.recursiveData = self.recursiveData[1:] + + def SetupAXDebugging(self, baseFrame=None, userFrame=None): + """Get ready for potential debugging. Must be called on the thread + that is being debugged. + """ + # userFrame is for non AXScript debugging. This is the first frame of the + # users code. + if userFrame is None: + userFrame = baseFrame + else: + # We have missed the "dispatch_call" function, so set this up now! + userFrame.f_locals["__axstack_address__"] = axdebug.GetStackAddress() + + traceenter("SetupAXDebugging", self) + self._threadprotectlock.acquire() + try: + thisThread = win32api.GetCurrentThreadId() + if self.debuggingThread is None: + self.debuggingThread = thisThread + else: + if self.debuggingThread != thisThread: + trace("SetupAXDebugging called on other thread - ignored!") + return + # push our context. + self.recursiveData.insert( + 0, + ( + self.logicalbotframe, + self.stopframe, + self.currentframe, + self.debuggingThreadStateHandle, + ), + ) + finally: + self._threadprotectlock.release() + + trace("SetupAXDebugging has base frame as", _dumpf(baseFrame)) + self.botframe = baseFrame + self.stopframe = userFrame + self.logicalbotframe = baseFrame + self.currentframe = None + self.debuggingThreadStateHandle = axdebug.GetThreadStateHandle() + + self._BreakFlagsChanged() + + # RemoteDebugApplicationEvents + def OnConnectDebugger(self, appDebugger): + traceenter("OnConnectDebugger", appDebugger) + self.appDebugger = appDebugger + # Reflect output to appDebugger + writefunc = lambda s: appDebugger.onDebugOutput(s) + sys.stdout = OutputReflector(sys.stdout, writefunc) + sys.stderr = OutputReflector(sys.stderr, writefunc) + + def OnDisconnectDebugger(self): + traceenter("OnDisconnectDebugger") + # Stop reflecting output + if isinstance(sys.stdout, OutputReflector): + sys.stdout = sys.stdout.file + if isinstance(sys.stderr, OutputReflector): + sys.stderr = sys.stderr.file + self.appDebugger = None + self.set_quit() + + def OnSetName(self, name): + traceenter("OnSetName", name) + + def OnDebugOutput(self, string): + traceenter("OnDebugOutput", string) + + def OnClose(self): + traceenter("OnClose") + + def OnEnterBreakPoint(self, rdat): + traceenter("OnEnterBreakPoint", rdat) + + def OnLeaveBreakPoint(self, rdat): + traceenter("OnLeaveBreakPoint", rdat) + + def OnCreateThread(self, rdat): + traceenter("OnCreateThread", rdat) + + def OnDestroyThread(self, rdat): + traceenter("OnDestroyThread", rdat) + + def OnBreakFlagChange(self, abf, rdat): + traceenter("Debugger OnBreakFlagChange", abf, rdat) + self.breakFlags = abf + self._BreakFlagsChanged() + + def _BreakFlagsChanged(self): + traceenter( + "_BreakFlagsChanged to %s with our thread = %s, and debugging thread = %s" + % (self.breakFlags, self.debuggingThread, win32api.GetCurrentThreadId()) + ) + trace("_BreakFlagsChanged has breaks", self.breaks) + # If a request comes on our debugging thread, then do it now! + # if self.debuggingThread!=win32api.GetCurrentThreadId(): + # return + + if len(self.breaks) or self.breakFlags: + if self.logicalbotframe: + trace("BreakFlagsChange with bot frame", _dumpf(self.logicalbotframe)) + # We have frames not to be debugged (eg, Scripting engine frames + # (sys.settrace will be set when out logicalbotframe is hit - + # this may not be the right thing to do, as it may not cause the + # immediate break we desire.) + self.logicalbotframe.f_trace = self.trace_dispatch + else: + trace("BreakFlagsChanged, but no bottom frame") + if self.stopframe is not None: + self.stopframe.f_trace = self.trace_dispatch + # If we have the thread-state for the thread being debugged, then + # we dynamically set its trace function - it is possible that the thread + # being debugged is in a blocked call (eg, a message box) and we + # want to hit the debugger the instant we return + if ( + self.debuggingThreadStateHandle is not None + and self.breakFlags + and self.debuggingThread != win32api.GetCurrentThreadId() + ): + axdebug.SetThreadStateTrace( + self.debuggingThreadStateHandle, self.trace_dispatch + ) + + def _OnSetBreakPoint(self, key, codeContext, bps, lineNo): + traceenter("_OnSetBreakPoint", self, key, codeContext, bps, lineNo) + if bps == axdebug.BREAKPOINT_ENABLED: + problem = self.set_break(key, lineNo) + if problem: + print("*** set_break failed -", problem) + trace("_OnSetBreakPoint just set BP and has breaks", self.breaks) + else: + self.clear_break(key, lineNo) + self._BreakFlagsChanged() + trace("_OnSetBreakPoint leaving with breaks", self.breaks) + + +def Debugger(): + global g_adb + if g_adb is None: + g_adb = Adb() + return g_adb diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/axdebug.pyd b/MLPY/Lib/site-packages/win32comext/axdebug/axdebug.pyd new file mode 100644 index 0000000000000000000000000000000000000000..9a8481903aa303776feca6d1925f57320ae0e80d Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axdebug/axdebug.pyd differ diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/codecontainer.py b/MLPY/Lib/site-packages/win32comext/axdebug/codecontainer.py new file mode 100644 index 0000000000000000000000000000000000000000..a7a2e24566fd5bec963a7fbff009be2037190972 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/codecontainer.py @@ -0,0 +1,278 @@ +"""A utility class for a code container. + +A code container is a class which holds source code for a debugger. It knows how +to color the text, and also how to translate lines into offsets, and back. +""" + +import sys +import tokenize + +import win32api +import winerror +from win32com.axdebug import axdebug +from win32com.server.exception import Exception + +from . import contexts +from .util import RaiseNotImpl, _wrap + +_keywords = {} # set of Python keywords +for name in """ + and assert break class continue def del elif else except exec + finally for from global if import in is lambda not + or pass print raise return try while + """.split(): + _keywords[name] = 1 + + +class SourceCodeContainer: + def __init__( + self, + text, + fileName="", + sourceContext=0, + startLineNumber=0, + site=None, + debugDocument=None, + ): + self.sourceContext = sourceContext # The source context added by a smart host. + self.text = text + if text: + self._buildlines() + self.nextLineNo = 0 + self.fileName = fileName + self.codeContexts = {} + self.site = site + self.startLineNumber = startLineNumber + self.debugDocument = None + + def _Close(self): + self.text = self.lines = self.lineOffsets = None + self.codeContexts = None + self.debugDocument = None + self.site = None + self.sourceContext = None + + def GetText(self): + return self.text + + def GetName(self, dnt): + assert 0, "You must subclass this" + + def GetFileName(self): + return self.fileName + + def GetPositionOfLine(self, cLineNumber): + self.GetText() # Prime us. + try: + return self.lineOffsets[cLineNumber] + except IndexError: + raise Exception(scode=winerror.S_FALSE) + + def GetLineOfPosition(self, charPos): + self.GetText() # Prime us. + lastOffset = 0 + lineNo = 0 + for lineOffset in self.lineOffsets[1:]: + if lineOffset > charPos: + break + lastOffset = lineOffset + lineNo = lineNo + 1 + else: # for not broken. + # print "Cant find", charPos, "in", self.lineOffsets + raise Exception(scode=winerror.S_FALSE) + # print "GLOP ret=",lineNo, (charPos-lastOffset) + return lineNo, (charPos - lastOffset) + + def GetNextLine(self): + if self.nextLineNo >= len(self.lines): + self.nextLineNo = 0 # auto-reset. + return "" + rc = self.lines[self.nextLineNo] + self.nextLineNo = self.nextLineNo + 1 + return rc + + def GetLine(self, num): + self.GetText() # Prime us. + return self.lines[num] + + def GetNumChars(self): + return len(self.GetText()) + + def GetNumLines(self): + self.GetText() # Prime us. + return len(self.lines) + + def _buildline(self, pos): + i = self.text.find("\n", pos) + if i < 0: + newpos = len(self.text) + else: + newpos = i + 1 + r = self.text[pos:newpos] + return r, newpos + + def _buildlines(self): + self.lines = [] + self.lineOffsets = [0] + line, pos = self._buildline(0) + while line: + self.lines.append(line) + self.lineOffsets.append(pos) + line, pos = self._buildline(pos) + + def _ProcessToken(self, type, token, spos, epos, line): + srow, scol = spos + erow, ecol = epos + self.GetText() # Prime us. + linenum = srow - 1 # Lines zero based for us too. + realCharPos = self.lineOffsets[linenum] + scol + numskipped = realCharPos - self.lastPos + if numskipped == 0: + pass + elif numskipped == 1: + self.attrs.append(axdebug.SOURCETEXT_ATTR_COMMENT) + else: + self.attrs.append((axdebug.SOURCETEXT_ATTR_COMMENT, numskipped)) + kwSize = len(token) + self.lastPos = realCharPos + kwSize + attr = 0 + + if type == tokenize.NAME: + if token in _keywords: + attr = axdebug.SOURCETEXT_ATTR_KEYWORD + elif type == tokenize.STRING: + attr = axdebug.SOURCETEXT_ATTR_STRING + elif type == tokenize.NUMBER: + attr = axdebug.SOURCETEXT_ATTR_NUMBER + elif type == tokenize.OP: + attr = axdebug.SOURCETEXT_ATTR_OPERATOR + elif type == tokenize.COMMENT: + attr = axdebug.SOURCETEXT_ATTR_COMMENT + # else attr remains zero... + if kwSize == 0: + pass + elif kwSize == 1: + self.attrs.append(attr) + else: + self.attrs.append((attr, kwSize)) + + def GetSyntaxColorAttributes(self): + self.lastPos = 0 + self.attrs = [] + try: + tokenize.tokenize(self.GetNextLine, self._ProcessToken) + except tokenize.TokenError: + pass # Ignore - will cause all subsequent text to be commented. + numAtEnd = len(self.GetText()) - self.lastPos + if numAtEnd: + self.attrs.append((axdebug.SOURCETEXT_ATTR_COMMENT, numAtEnd)) + return self.attrs + + # We also provide and manage DebugDocumentContext objects + def _MakeDebugCodeContext(self, lineNo, charPos, len): + return _wrap( + contexts.DebugCodeContext(lineNo, charPos, len, self, self.site), + axdebug.IID_IDebugCodeContext, + ) + + # Make a context at the given position. It should take up the entire context. + def _MakeContextAtPosition(self, charPos): + lineNo, offset = self.GetLineOfPosition(charPos) + try: + endPos = self.GetPositionOfLine(lineNo + 1) + except: + endPos = charPos + codecontext = self._MakeDebugCodeContext(lineNo, charPos, endPos - charPos) + return codecontext + + # Returns a DebugCodeContext. debugDocument can be None for smart hosts. + def GetCodeContextAtPosition(self, charPos): + # trace("GetContextOfPos", charPos, maxChars) + # Convert to line number. + lineNo, offset = self.GetLineOfPosition(charPos) + charPos = self.GetPositionOfLine(lineNo) + try: + cc = self.codeContexts[charPos] + # trace(" GetContextOfPos using existing") + except KeyError: + cc = self._MakeContextAtPosition(charPos) + self.codeContexts[charPos] = cc + return cc + + +class SourceModuleContainer(SourceCodeContainer): + def __init__(self, module): + self.module = module + if hasattr(module, "__file__"): + fname = self.module.__file__ + # Check for .pyc or .pyo or even .pys! + if fname[-1] in ["O", "o", "C", "c", "S", "s"]: + fname = fname[:-1] + try: + fname = win32api.GetFullPathName(fname) + except win32api.error: + pass + else: + if module.__name__ == "__main__" and len(sys.argv) > 0: + fname = sys.argv[0] + else: + fname = "" + SourceCodeContainer.__init__(self, None, fname) + + def GetText(self): + if self.text is None: + fname = self.GetFileName() + if fname: + try: + self.text = open(fname, "r").read() + except IOError as details: + self.text = "# Exception opening file\n# %s" % (repr(details)) + else: + self.text = "# No file available for module '%s'" % (self.module) + self._buildlines() + return self.text + + def GetName(self, dnt): + name = self.module.__name__ + try: + fname = win32api.GetFullPathName(self.module.__file__) + except win32api.error: + fname = self.module.__file__ + except AttributeError: + fname = name + if dnt == axdebug.DOCUMENTNAMETYPE_APPNODE: + return name.split(".")[-1] + elif dnt == axdebug.DOCUMENTNAMETYPE_TITLE: + return fname + elif dnt == axdebug.DOCUMENTNAMETYPE_FILE_TAIL: + return os.path.split(fname)[1] + elif dnt == axdebug.DOCUMENTNAMETYPE_URL: + return "file:%s" % fname + else: + raise Exception(scode=winerror.E_UNEXPECTED) + + +if __name__ == "__main__": + import sys + + sys.path.append(".") + import ttest + + sc = SourceModuleContainer(ttest) + # sc = SourceCodeContainer(open(sys.argv[1], "rb").read(), sys.argv[1]) + attrs = sc.GetSyntaxColorAttributes() + attrlen = 0 + for attr in attrs: + if type(attr) == type(()): + attrlen = attrlen + attr[1] + else: + attrlen = attrlen + 1 + text = sc.GetText() + if attrlen != len(text): + print("Lengths dont match!!! (%d/%d)" % (attrlen, len(text))) + + # print "Attributes:" + # print attrs + print("GetLineOfPos=", sc.GetLineOfPosition(0)) + print("GetLineOfPos=", sc.GetLineOfPosition(4)) + print("GetLineOfPos=", sc.GetLineOfPosition(10)) diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/contexts.py b/MLPY/Lib/site-packages/win32comext/axdebug/contexts.py new file mode 100644 index 0000000000000000000000000000000000000000..858166394335060cdf84ebeb286679145f812b90 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/contexts.py @@ -0,0 +1,62 @@ +""" A module for managing the AXDebug I*Contexts + +""" +import pythoncom +import win32com.server.util + +from . import adb, axdebug, gateways + +# Utility function for wrapping object created by this module. +from .util import _wrap, _wrap_remove, trace + + +class DebugCodeContext(gateways.DebugCodeContext, gateways.DebugDocumentContext): + # NOTE: We also implement the IDebugDocumentContext interface for Simple Hosts. + # Thus, debugDocument may be NULL when we have smart hosts - but in that case, we + # wont be called upon to provide it. + _public_methods_ = ( + gateways.DebugCodeContext._public_methods_ + + gateways.DebugDocumentContext._public_methods_ + ) + _com_interfaces_ = ( + gateways.DebugCodeContext._com_interfaces_ + + gateways.DebugDocumentContext._com_interfaces_ + ) + + def __init__(self, lineNo, charPos, len, codeContainer, debugSite): + self.debugSite = debugSite + self.offset = charPos + self.length = len + self.breakPointState = 0 + self.lineno = lineNo + gateways.DebugCodeContext.__init__(self) + self.codeContainer = codeContainer + + def _Close(self): + self.debugSite = None + + def GetDocumentContext(self): + if self.debugSite is not None: + # We have a smart host - let him give it to us. + return self.debugSite.GetDocumentContextFromPosition( + self.codeContainer.sourceContext, self.offset, self.length + ) + else: + # Simple host - Fine - Ill do it myself! + return _wrap(self, axdebug.IID_IDebugDocumentContext) + + def SetBreakPoint(self, bps): + self.breakPointState = bps + adb.OnSetBreakPoint(self, bps, self.lineno) + + # The DebugDocumentContext methods for simple hosts. + def GetDocument(self): + return self.codeContainer.debugDocument + + def EnumCodeContexts(self): + return _wrap(EnumDebugCodeContexts([self]), axdebug.IID_IEnumDebugCodeContexts) + + +class EnumDebugCodeContexts(gateways.EnumDebugCodeContexts): + def _wrap(self, obj): + return _wrap(obj, axdebug.IID_IDebugCodeContext) diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/debugger.py b/MLPY/Lib/site-packages/win32comext/axdebug/debugger.py new file mode 100644 index 0000000000000000000000000000000000000000..3157586bcede5375e519f189b44ef9365ef34d13 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/debugger.py @@ -0,0 +1,250 @@ +import os +import string +import sys + +import pythoncom +import win32api +from win32com.axdebug import ( + adb, + axdebug, + codecontainer, + contexts, + documents, + expressions, + gateways, +) +from win32com.axdebug.util import _wrap, _wrap_remove, trace +from win32com.axscript import axscript + +currentDebugger = None + + +class ModuleTreeNode: + """Helper class for building a module tree""" + + def __init__(self, module): + modName = module.__name__ + self.moduleName = modName + self.module = module + self.realNode = None + self.cont = codecontainer.SourceModuleContainer(module) + + def __repr__(self): + return "" % (self.module) + + def Attach(self, parentRealNode): + self.realNode.Attach(parentRealNode) + + def Close(self): + self.module = None + self.cont = None + self.realNode = None + + +def BuildModule(module, built_nodes, rootNode, create_node_fn, create_node_args): + if module: + keep = module.__name__ + keep = keep and (built_nodes.get(module) is None) + if keep and hasattr(module, "__file__"): + keep = string.lower(os.path.splitext(module.__file__)[1]) not in [ + ".pyd", + ".dll", + ] + # keep = keep and module.__name__=='__main__' + if module and keep: + # print "keeping", module.__name__ + node = ModuleTreeNode(module) + built_nodes[module] = node + realNode = create_node_fn(*(node,) + create_node_args) + node.realNode = realNode + + # Split into parent nodes. + parts = string.split(module.__name__, ".") + if parts[-1][:8] == "__init__": + parts = parts[:-1] + parent = string.join(parts[:-1], ".") + parentNode = rootNode + if parent: + parentModule = sys.modules[parent] + BuildModule( + parentModule, built_nodes, rootNode, create_node_fn, create_node_args + ) + if parentModule in built_nodes: + parentNode = built_nodes[parentModule].realNode + node.Attach(parentNode) + + +def RefreshAllModules(builtItems, rootNode, create_node, create_node_args): + for module in list(sys.modules.values()): + BuildModule(module, builtItems, rootNode, create_node, create_node_args) + + +# realNode = pdm.CreateDebugDocumentHelper(None) # DebugDocumentHelper node? +# app.CreateApplicationNode() # doc provider node. + + +class CodeContainerProvider(documents.CodeContainerProvider): + def __init__(self, axdebugger): + self.axdebugger = axdebugger + documents.CodeContainerProvider.__init__(self) + self.currentNumModules = len(sys.modules) + self.nodes = {} + self.axdebugger.RefreshAllModules(self.nodes, self) + + def FromFileName(self, fname): + ### It appears we cant add modules during a debug session! + # if self.currentNumModules != len(sys.modules): + # self.axdebugger.RefreshAllModules(self.nodes, self) + # self.currentNumModules = len(sys.modules) + # for key in self.ccsAndNodes.keys(): + # print "File:", key + return documents.CodeContainerProvider.FromFileName(self, fname) + + def Close(self): + documents.CodeContainerProvider.Close(self) + self.axdebugger = None + print("Closing %d nodes" % (len(self.nodes))) + for node in self.nodes.values(): + node.Close() + self.nodes = {} + + +class OriginalInterfaceMaker: + def MakeInterfaces(self, pdm): + app = self.pdm.CreateApplication() + self.cookie = pdm.AddApplication(app) + root = app.GetRootNode() + return app, root + + def CloseInterfaces(self, pdm): + pdm.RemoveApplication(self.cookie) + + +class SimpleHostStyleInterfaceMaker: + def MakeInterfaces(self, pdm): + app = pdm.GetDefaultApplication() + root = app.GetRootNode() + return app, root + + def CloseInterfaces(self, pdm): + pass + + +class AXDebugger: + def __init__(self, interfaceMaker=None, processName=None): + if processName is None: + processName = "Python Process" + if interfaceMaker is None: + interfaceMaker = SimpleHostStyleInterfaceMaker() + + self.pydebugger = adb.Debugger() + + self.pdm = pythoncom.CoCreateInstance( + axdebug.CLSID_ProcessDebugManager, + None, + pythoncom.CLSCTX_ALL, + axdebug.IID_IProcessDebugManager, + ) + + self.app, self.root = interfaceMaker.MakeInterfaces(self.pdm) + self.app.SetName(processName) + self.interfaceMaker = interfaceMaker + + expressionProvider = _wrap( + expressions.ProvideExpressionContexts(), + axdebug.IID_IProvideExpressionContexts, + ) + self.expressionCookie = self.app.AddGlobalExpressionContextProvider( + expressionProvider + ) + + contProvider = CodeContainerProvider(self) + self.pydebugger.AttachApp(self.app, contProvider) + + def Break(self): + # Get the frame we start debugging from - this is the frame 1 level up + try: + 1 + "" + except: + frame = sys.exc_info()[2].tb_frame.f_back + + # Get/create the debugger, and tell it to break. + self.app.StartDebugSession() + # self.app.CauseBreak() + + self.pydebugger.SetupAXDebugging(None, frame) + self.pydebugger.set_trace() + + def Close(self): + self.pydebugger.ResetAXDebugging() + self.interfaceMaker.CloseInterfaces(self.pdm) + self.pydebugger.CloseApp() + self.app.RemoveGlobalExpressionContextProvider(self.expressionCookie) + self.expressionCookie = None + + self.pdm = None + self.app = None + self.pydebugger = None + self.root = None + + def RefreshAllModules(self, nodes, containerProvider): + RefreshAllModules( + nodes, self.root, self.CreateApplicationNode, (containerProvider,) + ) + + def CreateApplicationNode(self, node, containerProvider): + realNode = self.app.CreateApplicationNode() + + document = documents.DebugDocumentText(node.cont) + document = _wrap(document, axdebug.IID_IDebugDocument) + + node.cont.debugDocument = document + + provider = documents.DebugDocumentProvider(document) + provider = _wrap(provider, axdebug.IID_IDebugDocumentProvider) + realNode.SetDocumentProvider(provider) + + containerProvider.AddCodeContainer(node.cont, realNode) + return realNode + + +def _GetCurrentDebugger(): + global currentDebugger + if currentDebugger is None: + currentDebugger = AXDebugger() + return currentDebugger + + +def Break(): + _GetCurrentDebugger().Break() + + +brk = Break +set_trace = Break + + +def dosomethingelse(): + a = 2 + b = "Hi there" + + +def dosomething(): + a = 1 + b = 2 + dosomethingelse() + + +def test(): + Break() + input("Waiting...") + dosomething() + print("Done") + + +if __name__ == "__main__": + print("About to test the debugging interfaces!") + test() + print( + " %d/%d com objects still alive" + % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount()) + ) diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/documents.py b/MLPY/Lib/site-packages/win32comext/axdebug/documents.py new file mode 100644 index 0000000000000000000000000000000000000000..d039cf40f09dc65741e74c05accc131b494a8d44 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/documents.py @@ -0,0 +1,140 @@ +""" Management of documents for AXDebugging. +""" + + +import pythoncom +import win32api +from win32com.server.exception import Exception +from win32com.server.util import unwrap + +from . import axdebug, codecontainer, contexts, gateways +from .util import RaiseNotImpl, _wrap, _wrap_remove, trace + +# def trace(*args): +# pass + + +def GetGoodFileName(fname): + if fname[0] != "<": + return win32api.GetFullPathName(fname) + return fname + + +class DebugDocumentProvider(gateways.DebugDocumentProvider): + def __init__(self, doc): + self.doc = doc + + def GetName(self, dnt): + return self.doc.GetName(dnt) + + def GetDocumentClassId(self): + return self.doc.GetDocumentClassId() + + def GetDocument(self): + return self.doc + + +class DebugDocumentText( + gateways.DebugDocumentInfo, gateways.DebugDocumentText, gateways.DebugDocument +): + _com_interfaces_ = ( + gateways.DebugDocumentInfo._com_interfaces_ + + gateways.DebugDocumentText._com_interfaces_ + + gateways.DebugDocument._com_interfaces_ + ) + _public_methods_ = ( + gateways.DebugDocumentInfo._public_methods_ + + gateways.DebugDocumentText._public_methods_ + + gateways.DebugDocument._public_methods_ + ) + + # A class which implements a DebugDocumentText, using the functionality + # provided by a codeContainer + def __init__(self, codeContainer): + gateways.DebugDocumentText.__init__(self) + gateways.DebugDocumentInfo.__init__(self) + gateways.DebugDocument.__init__(self) + self.codeContainer = codeContainer + + def _Close(self): + self.docContexts = None + # self.codeContainer._Close() + self.codeContainer = None + + # IDebugDocumentInfo + def GetName(self, dnt): + return self.codeContainer.GetName(dnt) + + def GetDocumentClassId(self): + return "{DF630910-1C1D-11d0-AE36-8C0F5E000000}" + + # IDebugDocument has no methods! + # + + # IDebugDocumentText methods. + # def GetDocumentAttributes + def GetSize(self): + # trace("GetSize") + return self.codeContainer.GetNumLines(), self.codeContainer.GetNumChars() + + def GetPositionOfLine(self, cLineNumber): + return self.codeContainer.GetPositionOfLine(cLineNumber) + + def GetLineOfPosition(self, charPos): + return self.codeContainer.GetLineOfPosition(charPos) + + def GetText(self, charPos, maxChars, wantAttr): + # Get all the attributes, else the tokenizer will get upset. + # XXX - not yet! + # trace("GetText", charPos, maxChars, wantAttr) + cont = self.codeContainer + attr = cont.GetSyntaxColorAttributes() + return cont.GetText(), attr + + def GetPositionOfContext(self, context): + trace("GetPositionOfContext", context) + context = unwrap(context) + return context.offset, context.length + + # Return a DebugDocumentContext. + def GetContextOfPosition(self, charPos, maxChars): + # Make one + doc = _wrap(self, axdebug.IID_IDebugDocument) + rc = self.codeContainer.GetCodeContextAtPosition(charPos) + return rc.QueryInterface(axdebug.IID_IDebugDocumentContext) + + +class CodeContainerProvider: + """An abstract Python class which provides code containers! + + Given a Python file name (as the debugger knows it by) this will + return a CodeContainer interface suitable for use. + + This provides a simple base imlpementation that simply supports + a dictionary of nodes and providers. + """ + + def __init__(self): + self.ccsAndNodes = {} + + def AddCodeContainer(self, cc, node=None): + fname = GetGoodFileName(cc.fileName) + self.ccsAndNodes[fname] = cc, node + + def FromFileName(self, fname): + cc, node = self.ccsAndNodes.get(GetGoodFileName(fname), (None, None)) + # if cc is None: + # print "FromFileName for %s returning None" % fname + return cc + + def Close(self): + for cc, node in self.ccsAndNodes.values(): + try: + # Must close the node before closing the provider + # as node may make calls on provider (eg Reset breakpoints etc) + if node is not None: + node.Close() + cc._Close() + except pythoncom.com_error: + pass + self.ccsAndNodes = {} diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/dump.py b/MLPY/Lib/site-packages/win32comext/axdebug/dump.py new file mode 100644 index 0000000000000000000000000000000000000000..26ee51e0d0ffed6973336db0ce8f5a9b37ce8e15 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/dump.py @@ -0,0 +1,61 @@ +import traceback + +import pythoncom +from win32com.axdebug import axdebug +from win32com.client.util import Enumerator + + +def DumpDebugApplicationNode(node, level=0): + # Recursive dump of a DebugApplicationNode + spacer = " " * level + for desc, attr in [ + ("Node Name", axdebug.DOCUMENTNAMETYPE_APPNODE), + ("Title", axdebug.DOCUMENTNAMETYPE_TITLE), + ("Filename", axdebug.DOCUMENTNAMETYPE_FILE_TAIL), + ("URL", axdebug.DOCUMENTNAMETYPE_URL), + ]: + try: + info = node.GetName(attr) + except pythoncom.com_error: + info = "" + print("%s%s: %s" % (spacer, desc, info)) + try: + doc = node.GetDocument() + except pythoncom.com_error: + doc = None + if doc: + doctext = doc.QueryInterface(axdebug.IID_IDebugDocumentText) + numLines, numChars = doctext.GetSize() + # text, attr = doctext.GetText(0, 20, 1) + text, attr = doctext.GetText(0, numChars, 1) + print( + "%sText is %s, %d bytes long" % (spacer, repr(text[:40] + "..."), len(text)) + ) + else: + print("%s%s" % (spacer, "")) + + for child in Enumerator(node.EnumChildren()): + DumpDebugApplicationNode(child, level + 1) + + +def dumpall(): + dm = pythoncom.CoCreateInstance( + axdebug.CLSID_MachineDebugManager, + None, + pythoncom.CLSCTX_ALL, + axdebug.IID_IMachineDebugManager, + ) + e = Enumerator(dm.EnumApplications()) + for app in e: + print("Application: %s" % app.GetName()) + node = ( + app.GetRootNode() + ) # of type PyIDebugApplicationNode->PyIDebugDocumentProvider->PyIDebugDocumentInfo + DumpDebugApplicationNode(node) + + +if __name__ == "__main__": + try: + dumpall() + except: + traceback.print_exc() diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/expressions.py b/MLPY/Lib/site-packages/win32comext/axdebug/expressions.py new file mode 100644 index 0000000000000000000000000000000000000000..28c7b904570bcb0287f2d5103840c364269edf91 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/expressions.py @@ -0,0 +1,214 @@ +import io +import string +import sys +import traceback +from pprint import pprint + +import winerror +from win32com.server.exception import COMException + +from . import axdebug, gateways +from .util import RaiseNotImpl, _wrap, _wrap_remove + + +# Given an object, return a nice string +def MakeNiceString(ob): + stream = io.StringIO() + pprint(ob, stream) + return string.strip(stream.getvalue()) + + +class ProvideExpressionContexts(gateways.ProvideExpressionContexts): + pass + + +class ExpressionContext(gateways.DebugExpressionContext): + def __init__(self, frame): + self.frame = frame + + def ParseLanguageText(self, code, radix, delim, flags): + return _wrap( + Expression(self.frame, code, radix, delim, flags), + axdebug.IID_IDebugExpression, + ) + + def GetLanguageInfo(self): + # print "GetLanguageInfo" + return "Python", "{DF630910-1C1D-11d0-AE36-8C0F5E000000}" + + +class Expression(gateways.DebugExpression): + def __init__(self, frame, code, radix, delim, flags): + self.callback = None + self.frame = frame + self.code = code + self.radix = radix + self.delim = delim + self.flags = flags + self.isComplete = 0 + self.result = None + self.hresult = winerror.E_UNEXPECTED + + def Start(self, callback): + try: + try: + try: + self.result = eval( + self.code, self.frame.f_globals, self.frame.f_locals + ) + except SyntaxError: + exec(self.code, self.frame.f_globals, self.frame.f_locals) + self.result = "" + self.hresult = 0 + except: + l = traceback.format_exception_only( + sys.exc_info()[0], sys.exc_info()[1] + ) + # l is a list of strings with trailing "\n" + self.result = string.join(map(lambda s: s[:-1], l), "\n") + self.hresult = winerror.E_FAIL + finally: + self.isComplete = 1 + callback.onComplete() + + def Abort(self): + print("** ABORT **") + + def QueryIsComplete(self): + return self.isComplete + + def GetResultAsString(self): + # print "GetStrAsResult returning", self.result + return self.hresult, MakeNiceString(self.result) + + def GetResultAsDebugProperty(self): + result = _wrap( + DebugProperty(self.code, self.result, None, self.hresult), + axdebug.IID_IDebugProperty, + ) + return self.hresult, result + + +def MakeEnumDebugProperty(object, dwFieldSpec, nRadix, iid, stackFrame=None): + name_vals = [] + if hasattr(object, "items") and hasattr(object, "keys"): # If it is a dict. + name_vals = iter(object.items()) + dictionary = object + elif hasattr(object, "__dict__"): # object with dictionary, module + name_vals = iter(object.__dict__.items()) + dictionary = object.__dict__ + infos = [] + for name, val in name_vals: + infos.append( + GetPropertyInfo(name, val, dwFieldSpec, nRadix, 0, dictionary, stackFrame) + ) + return _wrap(EnumDebugPropertyInfo(infos), axdebug.IID_IEnumDebugPropertyInfo) + + +def GetPropertyInfo( + obname, obvalue, dwFieldSpec, nRadix, hresult=0, dictionary=None, stackFrame=None +): + # returns a tuple + name = typ = value = fullname = attrib = dbgprop = None + if dwFieldSpec & axdebug.DBGPROP_INFO_VALUE: + value = MakeNiceString(obvalue) + if dwFieldSpec & axdebug.DBGPROP_INFO_NAME: + name = obname + if dwFieldSpec & axdebug.DBGPROP_INFO_TYPE: + if hresult: + typ = "Error" + else: + try: + typ = type(obvalue).__name__ + except AttributeError: + typ = str(type(obvalue)) + if dwFieldSpec & axdebug.DBGPROP_INFO_FULLNAME: + fullname = obname + if dwFieldSpec & axdebug.DBGPROP_INFO_ATTRIBUTES: + if hasattr(obvalue, "has_key") or hasattr( + obvalue, "__dict__" + ): # If it is a dict or object + attrib = axdebug.DBGPROP_ATTRIB_VALUE_IS_EXPANDABLE + else: + attrib = 0 + if dwFieldSpec & axdebug.DBGPROP_INFO_DEBUGPROP: + dbgprop = _wrap( + DebugProperty(name, obvalue, None, hresult, dictionary, stackFrame), + axdebug.IID_IDebugProperty, + ) + return name, typ, value, fullname, attrib, dbgprop + + +from win32com.server.util import ListEnumeratorGateway + + +class EnumDebugPropertyInfo(ListEnumeratorGateway): + """A class to expose a Python sequence as an EnumDebugCodeContexts + + Create an instance of this class passing a sequence (list, tuple, or + any sequence protocol supporting object) and it will automatically + support the EnumDebugCodeContexts interface for the object. + + """ + + _public_methods_ = ListEnumeratorGateway._public_methods_ + ["GetCount"] + _com_interfaces_ = [axdebug.IID_IEnumDebugPropertyInfo] + + def GetCount(self): + return len(self._list_) + + def _wrap(self, ob): + return ob + + +class DebugProperty: + _com_interfaces_ = [axdebug.IID_IDebugProperty] + _public_methods_ = [ + "GetPropertyInfo", + "GetExtendedInfo", + "SetValueAsString", + "EnumMembers", + "GetParent", + ] + + def __init__( + self, name, value, parent=None, hresult=0, dictionary=None, stackFrame=None + ): + self.name = name + self.value = value + self.parent = parent + self.hresult = hresult + self.dictionary = dictionary + self.stackFrame = stackFrame + + def GetPropertyInfo(self, dwFieldSpec, nRadix): + return GetPropertyInfo( + self.name, + self.value, + dwFieldSpec, + nRadix, + self.hresult, + dictionary, + stackFrame, + ) + + def GetExtendedInfo(self): ### Note - not in the framework. + RaiseNotImpl("DebugProperty::GetExtendedInfo") + + def SetValueAsString(self, value, radix): + if self.stackFrame and self.dictionary: + self.dictionary[self.name] = eval( + value, self.stackFrame.f_globals, self.stackFrame.f_locals + ) + else: + RaiseNotImpl("DebugProperty::SetValueAsString") + + def EnumMembers(self, dwFieldSpec, nRadix, iid): + # Returns IEnumDebugPropertyInfo + return MakeEnumDebugProperty( + self.value, dwFieldSpec, nRadix, iid, self.stackFrame + ) + + def GetParent(self): + # return IDebugProperty + RaiseNotImpl("DebugProperty::GetParent") diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/gateways.py b/MLPY/Lib/site-packages/win32comext/axdebug/gateways.py new file mode 100644 index 0000000000000000000000000000000000000000..d87e85b3350070fa8fdb33d228d687403a255bbc --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/gateways.py @@ -0,0 +1,583 @@ +# Classes which describe interfaces. + +import pythoncom +import win32com.server.connect +import winerror +from win32com.axdebug import axdebug +from win32com.axdebug.util import RaiseNotImpl, _wrap +from win32com.server.exception import Exception +from win32com.server.util import ListEnumeratorGateway + + +class EnumDebugCodeContexts(ListEnumeratorGateway): + """A class to expose a Python sequence as an EnumDebugCodeContexts + + Create an instance of this class passing a sequence (list, tuple, or + any sequence protocol supporting object) and it will automatically + support the EnumDebugCodeContexts interface for the object. + + """ + + _com_interfaces_ = [axdebug.IID_IEnumDebugCodeContexts] + + +class EnumDebugStackFrames(ListEnumeratorGateway): + """A class to expose a Python sequence as an EnumDebugStackFrames + + Create an instance of this class passing a sequence (list, tuple, or + any sequence protocol supporting object) and it will automatically + support the EnumDebugStackFrames interface for the object. + + """ + + _com_interfaces_ = [axdebug.IID_IEnumDebugStackFrames] + + +class EnumDebugApplicationNodes(ListEnumeratorGateway): + """A class to expose a Python sequence as an EnumDebugStackFrames + + Create an instance of this class passing a sequence (list, tuple, or + any sequence protocol supporting object) and it will automatically + support the EnumDebugApplicationNodes interface for the object. + + """ + + _com_interfaces_ = [axdebug.IID_IEnumDebugApplicationNodes] + + +class EnumRemoteDebugApplications(ListEnumeratorGateway): + _com_interfaces_ = [axdebug.IID_IEnumRemoteDebugApplications] + + +class EnumRemoteDebugApplicationThreads(ListEnumeratorGateway): + _com_interfaces_ = [axdebug.IID_IEnumRemoteDebugApplicationThreads] + + +class DebugDocumentInfo: + _public_methods_ = ["GetName", "GetDocumentClassId"] + _com_interfaces_ = [axdebug.IID_IDebugDocumentInfo] + + def __init__(self): + pass + + def GetName(self, dnt): + """Get the one of the name of the document + dnt -- int DOCUMENTNAMETYPE + """ + RaiseNotImpl("GetName") + + def GetDocumentClassId(self): + """ + Result must be an IID object (or string representing one). + """ + RaiseNotImpl("GetDocumentClassId") + + +class DebugDocumentProvider(DebugDocumentInfo): + _public_methods_ = DebugDocumentInfo._public_methods_ + ["GetDocument"] + _com_interfaces_ = DebugDocumentInfo._com_interfaces_ + [ + axdebug.IID_IDebugDocumentProvider + ] + + def GetDocument(self): + RaiseNotImpl("GetDocument") + + +class DebugApplicationNode(DebugDocumentProvider): + """Provides the functionality of IDebugDocumentProvider, plus a context within a project tree.""" + + _public_methods_ = ( + """EnumChildren GetParent SetDocumentProvider + Close Attach Detach""".split() + + DebugDocumentProvider._public_methods_ + ) + _com_interfaces_ = [ + axdebug.IID_IDebugDocumentProvider + ] + DebugDocumentProvider._com_interfaces_ + + def __init__(self): + DebugDocumentProvider.__init__(self) + + def EnumChildren(self): + # Result is type PyIEnumDebugApplicationNodes + RaiseNotImpl("EnumChildren") + + def GetParent(self): + # result is type PyIDebugApplicationNode + RaiseNotImpl("GetParent") + + def SetDocumentProvider(self, pddp): # PyIDebugDocumentProvider pddp + # void result. + RaiseNotImpl("SetDocumentProvider") + + def Close(self): + # void result. + RaiseNotImpl("Close") + + def Attach(self, parent): # PyIDebugApplicationNode + # void result. + RaiseNotImpl("Attach") + + def Detach(self): + # void result. + RaiseNotImpl("Detach") + + +class DebugApplicationNodeEvents: + """Event interface for DebugApplicationNode object.""" + + _public_methods_ = "onAddChild onRemoveChild onDetach".split() + _com_interfaces_ = [axdebug.IID_IDebugApplicationNodeEvents] + + def __init__(self): + pass + + def onAddChild(self, child): # PyIDebugApplicationNode + # void result. + RaiseNotImpl("onAddChild") + + def onRemoveChild(self, child): # PyIDebugApplicationNode + # void result. + RaiseNotImpl("onRemoveChild") + + def onDetach(self): + # void result. + RaiseNotImpl("onDetach") + + def onAttach(self, parent): # PyIDebugApplicationNode + # void result. + RaiseNotImpl("onAttach") + + +class DebugDocument(DebugDocumentInfo): + """The base interface to all debug documents.""" + + _public_methods_ = DebugDocumentInfo._public_methods_ + _com_interfaces_ = [axdebug.IID_IDebugDocument] + DebugDocumentInfo._com_interfaces_ + + +class DebugDocumentText(DebugDocument): + """The interface to a text only debug document.""" + + _com_interfaces_ = [axdebug.IID_IDebugDocumentText] + DebugDocument._com_interfaces_ + _public_methods_ = [ + "GetDocumentAttributes", + "GetSize", + "GetPositionOfLine", + "GetLineOfPosition", + "GetText", + "GetPositionOfContext", + "GetContextOfPosition", + ] + DebugDocument._public_methods_ + + def __init__(self): + pass + + # IDebugDocumentText + def GetDocumentAttributes(self): + # Result is int (TEXT_DOC_ATTR) + RaiseNotImpl("GetDocumentAttributes") + + def GetSize(self): + # Result is (numLines, numChars) + RaiseNotImpl("GetSize") + + def GetPositionOfLine(self, cLineNumber): + # Result is int char position + RaiseNotImpl("GetPositionOfLine") + + def GetLineOfPosition(self, charPos): + # Result is int, int (lineNo, offset) + RaiseNotImpl("GetLineOfPosition") + + def GetText(self, charPos, maxChars, wantAttr): + """Params + charPos -- integer + maxChars -- integer + wantAttr -- Should the function compute attributes. + + Return value must be (string, attribtues). attributes may be + None if(not wantAttr) + """ + RaiseNotImpl("GetText") + + def GetPositionOfContext(self, debugDocumentContext): + """Params + debugDocumentContext -- a PyIDebugDocumentContext object. + + Return value must be (charPos, numChars) + """ + RaiseNotImpl("GetPositionOfContext") + + def GetContextOfPosition(self, charPos, maxChars): + """Params are integers. + Return value must be PyIDebugDocumentContext object + """ + print(self) + RaiseNotImpl("GetContextOfPosition") + + +class DebugDocumentTextExternalAuthor: + """Allow external editors to edit file-based debugger documents, and to notify the document when the source file has been changed.""" + + _public_methods_ = ["GetPathName", "GetFileName", "NotifyChanged"] + _com_interfaces_ = [axdebug.IID_IDebugDocumentTextExternalAuthor] + + def __init__(self): + pass + + def GetPathName(self): + """Return the full path (including file name) to the document's source file. + + Result must be (filename, fIsOriginal), where + - if fIsOriginalPath is TRUE if the path refers to the original file for the document. + - if fIsOriginalPath is FALSE if the path refers to a newly created temporary file. + + raise Exception(winerror.E_FAIL) if no source file can be created/determined. + """ + RaiseNotImpl("GetPathName") + + def GetFileName(self): + """Return just the name of the document, with no path information. (Used for "Save As...") + + Result is a string + """ + RaiseNotImpl("GetFileName") + + def NotifyChanged(self): + """Notify the host that the document's source file has been saved and + that its contents should be refreshed. + """ + RaiseNotImpl("NotifyChanged") + + +class DebugDocumentTextEvents: + _public_methods_ = """onDestroy onInsertText onRemoveText + onReplaceText onUpdateTextAttributes + onUpdateDocumentAttributes""".split() + _com_interfaces_ = [axdebug.IID_IDebugDocumentTextEvents] + + def __init__(self): + pass + + def onDestroy(self): + # Result is void. + RaiseNotImpl("onDestroy") + + def onInsertText(self, cCharacterPosition, cNumToInsert): + # Result is void. + RaiseNotImpl("onInsertText") + + def onRemoveText(self, cCharacterPosition, cNumToRemove): + # Result is void. + RaiseNotImpl("onRemoveText") + + def onReplaceText(self, cCharacterPosition, cNumToReplace): + # Result is void. + RaiseNotImpl("onReplaceText") + + def onUpdateTextAttributes(self, cCharacterPosition, cNumToUpdate): + # Result is void. + RaiseNotImpl("onUpdateTextAttributes") + + def onUpdateDocumentAttributes(self, textdocattr): # TEXT_DOC_ATTR + # Result is void. + RaiseNotImpl("onUpdateDocumentAttributes") + + +class DebugDocumentContext: + _public_methods_ = ["GetDocument", "EnumCodeContexts"] + _com_interfaces_ = [axdebug.IID_IDebugDocumentContext] + + def __init__(self): + pass + + def GetDocument(self): + """Return value must be a PyIDebugDocument object""" + RaiseNotImpl("GetDocument") + + def EnumCodeContexts(self): + """Return value must be a PyIEnumDebugCodeContexts object""" + RaiseNotImpl("EnumCodeContexts") + + +class DebugCodeContext: + _public_methods_ = ["GetDocumentContext", "SetBreakPoint"] + _com_interfaces_ = [axdebug.IID_IDebugCodeContext] + + def __init__(self): + pass + + def GetDocumentContext(self): + """Return value must be a PyIDebugDocumentContext object""" + RaiseNotImpl("GetDocumentContext") + + def SetBreakPoint(self, bps): + """bps -- an integer with flags.""" + RaiseNotImpl("SetBreakPoint") + + +class DebugStackFrame: + """Abstraction representing a logical stack frame on the stack of a thread.""" + + _public_methods_ = [ + "GetCodeContext", + "GetDescriptionString", + "GetLanguageString", + "GetThread", + "GetDebugProperty", + ] + _com_interfaces_ = [axdebug.IID_IDebugStackFrame] + + def __init__(self): + pass + + def GetCodeContext(self): + """Returns the current code context associated with the stack frame. + + Return value must be a IDebugCodeContext object + """ + RaiseNotImpl("GetCodeContext") + + def GetDescriptionString(self, fLong): + """Returns a textual description of the stack frame. + + fLong -- A flag indicating if the long name is requested. + """ + RaiseNotImpl("GetDescriptionString") + + def GetLanguageString(self): + """Returns a short or long textual description of the language. + + fLong -- A flag indicating if the long name is requested. + """ + RaiseNotImpl("GetLanguageString") + + def GetThread(self): + """Returns the thread associated with this stack frame. + + Result must be a IDebugApplicationThread + """ + RaiseNotImpl("GetThread") + + def GetDebugProperty(self): + RaiseNotImpl("GetDebugProperty") + + +class DebugDocumentHost: + """The interface from the IDebugDocumentHelper back to + the smart host or language engine. This interface + exposes host specific functionality such as syntax coloring. + """ + + _public_methods_ = [ + "GetDeferredText", + "GetScriptTextAttributes", + "OnCreateDocumentContext", + "GetPathName", + "GetFileName", + "NotifyChanged", + ] + _com_interfaces_ = [axdebug.IID_IDebugDocumentHost] + + def __init__(self): + pass + + def GetDeferredText(self, dwTextStartCookie, maxChars, bWantAttr): + RaiseNotImpl("GetDeferredText") + + def GetScriptTextAttributes(self, codeText, delimterText, flags): + # Result must be an attribute sequence of same "length" as the code. + RaiseNotImpl("GetScriptTextAttributes") + + def OnCreateDocumentContext(self): + # Result must be a PyIUnknown + RaiseNotImpl("OnCreateDocumentContext") + + def GetPathName(self): + # Result must be (string, int) where the int is a BOOL + # - TRUE if the path refers to the original file for the document. + # - FALSE if the path refers to a newly created temporary file. + # - raise Exception(scode=E_FAIL) if no source file can be created/determined. + RaiseNotImpl("GetPathName") + + def GetFileName(self): + # Result is a string with just the name of the document, no path information. + RaiseNotImpl("GetFileName") + + def NotifyChanged(self): + RaiseNotImpl("NotifyChanged") + + +# Additional gateway related functions. + + +class DebugDocumentTextConnectServer: + _public_methods_ = ( + win32com.server.connect.IConnectionPointContainer_methods + + win32com.server.connect.IConnectionPoint_methods + ) + _com_interfaces_ = [ + pythoncom.IID_IConnectionPoint, + pythoncom.IID_IConnectionPointContainer, + ] + + # IConnectionPoint interfaces + def __init__(self): + self.cookieNo = -1 + self.connections = {} + + def EnumConnections(self): + RaiseNotImpl("EnumConnections") + + def GetConnectionInterface(self): + RaiseNotImpl("GetConnectionInterface") + + def GetConnectionPointContainer(self): + return _wrap(self) + + def Advise(self, pUnk): + # Creates a connection to the client. Simply allocate a new cookie, + # find the clients interface, and store it in a dictionary. + interface = pUnk.QueryInterface(axdebug.IID_IDebugDocumentTextEvents, 1) + self.cookieNo = self.cookieNo + 1 + self.connections[self.cookieNo] = interface + return self.cookieNo + + def Unadvise(self, cookie): + # Destroy a connection - simply delete interface from the map. + try: + del self.connections[cookie] + except KeyError: + return Exception(scode=winerror.E_UNEXPECTED) + + # IConnectionPointContainer interfaces + def EnumConnectionPoints(self): + RaiseNotImpl("EnumConnectionPoints") + + def FindConnectionPoint(self, iid): + # Find a connection we support. Only support the single event interface. + if iid == axdebug.IID_IDebugDocumentTextEvents: + return _wrap(self) + raise Exception(scode=winerror.E_NOINTERFACE) # ?? + + +class RemoteDebugApplicationEvents: + _public_methods_ = [ + "OnConnectDebugger", + "OnDisconnectDebugger", + "OnSetName", + "OnDebugOutput", + "OnClose", + "OnEnterBreakPoint", + "OnLeaveBreakPoint", + "OnCreateThread", + "OnDestroyThread", + "OnBreakFlagChange", + ] + _com_interfaces_ = [axdebug.IID_IRemoteDebugApplicationEvents] + + def OnConnectDebugger(self, appDebugger): + """appDebugger -- a PyIApplicationDebugger""" + RaiseNotImpl("OnConnectDebugger") + + def OnDisconnectDebugger(self): + RaiseNotImpl("OnDisconnectDebugger") + + def OnSetName(self, name): + RaiseNotImpl("OnSetName") + + def OnDebugOutput(self, string): + RaiseNotImpl("OnDebugOutput") + + def OnClose(self): + RaiseNotImpl("OnClose") + + def OnEnterBreakPoint(self, rdat): + """rdat -- PyIRemoteDebugApplicationThread""" + RaiseNotImpl("OnEnterBreakPoint") + + def OnLeaveBreakPoint(self, rdat): + """rdat -- PyIRemoteDebugApplicationThread""" + RaiseNotImpl("OnLeaveBreakPoint") + + def OnCreateThread(self, rdat): + """rdat -- PyIRemoteDebugApplicationThread""" + RaiseNotImpl("OnCreateThread") + + def OnDestroyThread(self, rdat): + """rdat -- PyIRemoteDebugApplicationThread""" + RaiseNotImpl("OnDestroyThread") + + def OnBreakFlagChange(self, abf, rdat): + """abf -- int - one of the axdebug.APPBREAKFLAGS constants + rdat -- PyIRemoteDebugApplicationThread + RaiseNotImpl("OnBreakFlagChange") + """ + + +class DebugExpressionContext: + _public_methods_ = ["ParseLanguageText", "GetLanguageInfo"] + _com_interfaces_ = [axdebug.IID_IDebugExpressionContext] + + def __init__(self): + pass + + def ParseLanguageText(self, code, radix, delim, flags): + """ + result is IDebugExpression + """ + RaiseNotImpl("ParseLanguageText") + + def GetLanguageInfo(self): + """ + result is (string langName, iid langId) + """ + RaiseNotImpl("GetLanguageInfo") + + +class DebugExpression: + _public_methods_ = [ + "Start", + "Abort", + "QueryIsComplete", + "GetResultAsString", + "GetResultAsDebugProperty", + ] + _com_interfaces_ = [axdebug.IID_IDebugExpression] + + def Start(self, callback): + """ + callback -- an IDebugExpressionCallback + + result - void + """ + RaiseNotImpl("Start") + + def Abort(self): + """ + no params + result -- void + """ + RaiseNotImpl("Abort") + + def QueryIsComplete(self): + """ + no params + result -- void + """ + RaiseNotImpl("QueryIsComplete") + + def GetResultAsString(self): + RaiseNotImpl("GetResultAsString") + + def GetResultAsDebugProperty(self): + RaiseNotImpl("GetResultAsDebugProperty") + + +class ProvideExpressionContexts: + _public_methods_ = ["EnumExpressionContexts"] + _com_interfaces_ = [axdebug.IID_IProvideExpressionContexts] + + def EnumExpressionContexts(self): + RaiseNotImpl("EnumExpressionContexts") diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/stackframe.py b/MLPY/Lib/site-packages/win32comext/axdebug/stackframe.py new file mode 100644 index 0000000000000000000000000000000000000000..edc3fe8cb849eff3877d8256cf3491c74ed58d1e --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/stackframe.py @@ -0,0 +1,179 @@ +"""Support for stack-frames. + +Provides Implements a nearly complete wrapper for a stack frame. +""" + +import pythoncom +from win32com.server.exception import COMException + +from . import axdebug, expressions, gateways +from .util import RaiseNotImpl, _wrap, trace + +# def trace(*args): +# pass + + +class EnumDebugStackFrames(gateways.EnumDebugStackFrames): + """A class that given a debugger object, can return an enumerator + of DebugStackFrame objects. + """ + + def __init__(self, debugger): + infos = [] + frame = debugger.currentframe + # print "Stack check" + while frame: + # print " Checking frame", frame.f_code.co_filename, frame.f_lineno-1, frame.f_trace, + # Get a DebugCodeContext for the stack frame. If we fail, then it + # is not debuggable, and therefore not worth displaying. + cc = debugger.codeContainerProvider.FromFileName(frame.f_code.co_filename) + if cc is not None: + try: + address = frame.f_locals["__axstack_address__"] + except KeyError: + # print "Couldnt find stack address for",frame.f_code.co_filename, frame.f_lineno-1 + # Use this one, even tho it is wrong :-( + address = axdebug.GetStackAddress() + frameInfo = ( + DebugStackFrame(frame, frame.f_lineno - 1, cc), + address, + address + 1, + 0, + None, + ) + infos.append(frameInfo) + # print "- Kept!" + # else: + # print "- rejected" + frame = frame.f_back + + gateways.EnumDebugStackFrames.__init__(self, infos, 0) + + # def __del__(self): + # print "EnumDebugStackFrames dieing" + + def Next(self, count): + return gateways.EnumDebugStackFrames.Next(self, count) + + # def _query_interface_(self, iid): + # from win32com.util import IIDToInterfaceName + # print "EnumDebugStackFrames QI with %s (%s)" % (IIDToInterfaceName(iid), str(iid)) + # return 0 + def _wrap(self, obj): + # This enum returns a tuple, with 2 com objects in it. + obFrame, min, lim, fFinal, obFinal = obj + obFrame = _wrap(obFrame, axdebug.IID_IDebugStackFrame) + if obFinal: + obFinal = _wrap(obFinal, pythoncom.IID_IUnknown) + return obFrame, min, lim, fFinal, obFinal + + +class DebugStackFrame(gateways.DebugStackFrame): + def __init__(self, frame, lineno, codeContainer): + self.frame = frame + self.lineno = lineno + self.codeContainer = codeContainer + self.expressionContext = None + + # def __del__(self): + # print "DSF dieing" + def _query_interface_(self, iid): + if iid == axdebug.IID_IDebugExpressionContext: + if self.expressionContext is None: + self.expressionContext = _wrap( + expressions.ExpressionContext(self.frame), + axdebug.IID_IDebugExpressionContext, + ) + return self.expressionContext + # from win32com.util import IIDToInterfaceName + # print "DebugStackFrame QI with %s (%s)" % (IIDToInterfaceName(iid), str(iid)) + return 0 + + # + # The following need implementation + def GetThread(self): + """Returns the thread associated with this stack frame. + + Result must be a IDebugApplicationThread + """ + RaiseNotImpl("GetThread") + + def GetCodeContext(self): + offset = self.codeContainer.GetPositionOfLine(self.lineno) + return self.codeContainer.GetCodeContextAtPosition(offset) + + # + # The following are usefully implemented + def GetDescriptionString(self, fLong): + filename = self.frame.f_code.co_filename + s = "" + if 0: # fLong: + s = s + filename + if self.frame.f_code.co_name: + s = s + self.frame.f_code.co_name + else: + s = s + "" + return s + + def GetLanguageString(self, fLong): + if fLong: + return "Python ActiveX Scripting Engine" + else: + return "Python" + + def GetDebugProperty(self): + return _wrap(StackFrameDebugProperty(self.frame), axdebug.IID_IDebugProperty) + + +class DebugStackFrameSniffer: + _public_methods_ = ["EnumStackFrames"] + _com_interfaces_ = [axdebug.IID_IDebugStackFrameSniffer] + + def __init__(self, debugger): + self.debugger = debugger + trace("DebugStackFrameSniffer instantiated") + + # def __del__(self): + # print "DSFS dieing" + def EnumStackFrames(self): + trace("DebugStackFrameSniffer.EnumStackFrames called") + return _wrap( + EnumDebugStackFrames(self.debugger), axdebug.IID_IEnumDebugStackFrames + ) + + +# A DebugProperty for a stack frame. +class StackFrameDebugProperty: + _com_interfaces_ = [axdebug.IID_IDebugProperty] + _public_methods_ = [ + "GetPropertyInfo", + "GetExtendedInfo", + "SetValueAsString", + "EnumMembers", + "GetParent", + ] + + def __init__(self, frame): + self.frame = frame + + def GetPropertyInfo(self, dwFieldSpec, nRadix): + RaiseNotImpl("StackFrameDebugProperty::GetPropertyInfo") + + def GetExtendedInfo(self): ### Note - not in the framework. + RaiseNotImpl("StackFrameDebugProperty::GetExtendedInfo") + + def SetValueAsString(self, value, radix): + # + RaiseNotImpl("DebugProperty::SetValueAsString") + + def EnumMembers(self, dwFieldSpec, nRadix, iid): + print("EnumMembers", dwFieldSpec, nRadix, iid) + from . import expressions + + return expressions.MakeEnumDebugProperty( + self.frame.f_locals, dwFieldSpec, nRadix, iid, self.frame + ) + + def GetParent(self): + # return IDebugProperty + RaiseNotImpl("DebugProperty::GetParent") diff --git a/MLPY/Lib/site-packages/win32comext/axdebug/util.py b/MLPY/Lib/site-packages/win32comext/axdebug/util.py new file mode 100644 index 0000000000000000000000000000000000000000..c3d4f733f6652b103bf4389f21ea87460b1cacd6 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axdebug/util.py @@ -0,0 +1,141 @@ +# Utility function for wrapping objects. Centralising allows me to turn +# debugging on and off for the entire package in a single spot. + +import os +import sys + +import win32api +import win32com.server.util +import winerror +from win32com.server.exception import Exception + +try: + os.environ["DEBUG_AXDEBUG"] + debugging = 1 +except KeyError: + debugging = 0 + + +def trace(*args): + if not debugging: + return + print(str(win32api.GetCurrentThreadId()) + ":", end=" ") + for arg in args: + print(arg, end=" ") + print() + + +# The AXDebugging implementation assumes that the returned COM pointers are in +# some cases identical. Eg, from a C++ perspective: +# p->GetSomeInterface( &p1 ); +# p->GetSomeInterface( &p2 ); +# p1==p2 +# By default, this is _not_ true for Python. +# (Now this is only true for Document objects, and Python +# now does ensure this. + +all_wrapped = {} + + +def _wrap_nodebug(object, iid): + return win32com.server.util.wrap(object, iid) + + +def _wrap_debug(object, iid): + import win32com.server.policy + + dispatcher = win32com.server.policy.DispatcherWin32trace + return win32com.server.util.wrap(object, iid, useDispatcher=dispatcher) + + +if debugging: + _wrap = _wrap_debug +else: + _wrap = _wrap_nodebug + + +def _wrap_remove(object, iid=None): + # Old - no longer used or necessary! + return + + +def _dump_wrapped(): + from win32com.server.util import unwrap + + print("Wrapped items:") + for key, items in all_wrapped.items(): + print(key, end=" ") + try: + ob = unwrap(key) + print(ob, sys.getrefcount(ob)) + except: + print("") + + +def RaiseNotImpl(who=None): + if who is not None: + print("********* Function %s Raising E_NOTIMPL ************" % (who)) + + # Print a sort-of "traceback", dumping all the frames leading to here. + try: + 1 / 0 + except: + frame = sys.exc_info()[2].tb_frame + while frame: + print("File: %s, Line: %d" % (frame.f_code.co_filename, frame.f_lineno)) + frame = frame.f_back + + # and raise the exception for COM + raise Exception(scode=winerror.E_NOTIMPL) + + +import win32com.server.policy + + +class Dispatcher(win32com.server.policy.DispatcherWin32trace): + def __init__(self, policyClass, object): + win32com.server.policy.DispatcherTrace.__init__(self, policyClass, object) + import win32traceutil # Sets up everything. + + # print "Object with win32trace dispatcher created (object=%s)" % `object` + + def _QueryInterface_(self, iid): + rc = win32com.server.policy.DispatcherBase._QueryInterface_(self, iid) + # if not rc: + # self._trace_("in _QueryInterface_ with unsupported IID %s (%s)\n" % (IIDToInterfaceName(iid),iid)) + return rc + + def _Invoke_(self, dispid, lcid, wFlags, args): + print( + "In Invoke with", + dispid, + lcid, + wFlags, + args, + "with object", + self.policy._obj_, + ) + try: + rc = win32com.server.policy.DispatcherBase._Invoke_( + self, dispid, lcid, wFlags, args + ) + # print "Invoke of", dispid, "returning", rc + return rc + except Exception: + t, v, tb = sys.exc_info() + tb = None # A cycle + scode = v.scode + try: + desc = " (" + str(v.description) + ")" + except AttributeError: + desc = "" + print( + "*** Invoke of %s raised COM exception 0x%x%s" % (dispid, scode, desc) + ) + except: + print("*** Invoke of %s failed:" % dispid) + typ, val, tb = sys.exc_info() + import traceback + + traceback.print_exception(typ, val, tb) + raise diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/CreateObject.asp b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/CreateObject.asp new file mode 100644 index 0000000000000000000000000000000000000000..5338c0a0623f78ac77ee8d3a054e3ab010ecb3e8 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/CreateObject.asp @@ -0,0 +1,19 @@ + + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/caps.asp b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/caps.asp new file mode 100644 index 0000000000000000000000000000000000000000..6b0342aa3217de498872a4b17764102636757680 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/caps.asp @@ -0,0 +1,52 @@ +<%@ Language=Python %> + + + + + + +Python test + + + + + + + + + +<% +import sys +print sys.path +from win32com.axscript.asputil import * +print "Hello" +print "There" +print "How are you" +%> + +<%bc = Server.CreateObject("MSWC.BrowserType")%> + + + + + + + + + +
Browser <%=bc.browser %> +
Version <%=bc.version %>
Frames +<%Response.Write( iif(bc.frames, "TRUE", "FALSE")) %>
Tables +<%Response.Write( iif (bc.tables, "TRUE", "FALSE")) %>
BackgroundSounds +<%Response.Write( iif(bc.BackgroundSounds, "TRUE", "FALSE"))%>
VBScript +<%Response.Write( iif(bc.vbscript, "TRUE", "FALSE"))%>
JavaScript +<%Response.Write( iif(bc.javascript, "TRUE", "FALSE"))%>
+ + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.asp b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.asp new file mode 100644 index 0000000000000000000000000000000000000000..ee77703f69e323830af237d49376868c6187817f --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.asp @@ -0,0 +1,4 @@ +<%@ language=python%> + +<%Response.Redirect("test1.html")%> + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.html b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.html new file mode 100644 index 0000000000000000000000000000000000000000..0b7f055989e6d63a48f4c5d3f3a47d8a3408e23c --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test.html @@ -0,0 +1,10 @@ + + + +GOT There + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test1.asp b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test1.asp new file mode 100644 index 0000000000000000000000000000000000000000..a936dd99524a67348b37ff31ae269792cb160f57 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test1.asp @@ -0,0 +1,6 @@ +<%@ language =Python%> + + +<%Response.Redirect("test.html")%> + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test1.html b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test1.html new file mode 100644 index 0000000000000000000000000000000000000000..6f1d9b2f148330d95ac6154ba3a041b4f8fe9b73 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/interrupt/test1.html @@ -0,0 +1,11 @@ + + + +GOT HERE + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/tut1.asp b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/tut1.asp new file mode 100644 index 0000000000000000000000000000000000000000..dcbb047cd1f4465eaa6e492ab54775f1f22dedea --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/asp/tut1.asp @@ -0,0 +1,11 @@ + + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/MarqueeText1.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/MarqueeText1.htm new file mode 100644 index 0000000000000000000000000000000000000000..85a676f8133b46a332441410732597c7bb69a9ea --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/MarqueeText1.htm @@ -0,0 +1,25 @@ + + + + Internet Workshop + + + + +

+
+

Python AX Script Engine +
Demo using the Marquee Control +
Mark Hammond. + +

This is really quite a boring demo, as the Marquee control does everything. However, there is Python code behind the buttons that change the speed. This code is all of 2 lines per button!!! + +

For more information on Python as an ActiveX scripting language, see + +

Python +
http://www.python.org + +
+ + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/calc.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/calc.htm new file mode 100644 index 0000000000000000000000000000000000000000..7c7fb48d40439ca72804feb288d5558a40b9461a --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/calc.htm @@ -0,0 +1,116 @@ + +Python Script sample: Calculator + + + + +

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Calculator

+ +
+ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/dbgtest.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/dbgtest.htm new file mode 100644 index 0000000000000000000000000000000000000000..7ee9468d5862ea4c949e11a3806b4dd1d8b18b98 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/dbgtest.htm @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo.htm new file mode 100644 index 0000000000000000000000000000000000000000..a828bac216173e0abad15d82a8bdce8c2989f035 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo.htm @@ -0,0 +1,26 @@ + + +Python AXScript Demos + + + + + + + + + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_check.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_check.htm new file mode 100644 index 0000000000000000000000000000000000000000..f0e09f9d80099a63838e4db4dbe033599f42209b --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_check.htm @@ -0,0 +1,42 @@ + +

Engine Registration

+ + + +

The Python ActiveX Scripting Engine is not currently registered.

+ +

Due to a privacy +concern discovered in the engine, the use of Python inside IE has been disabled.

+ +Before any of the supplied demos will work, the engine must be successfully registered. + +

To install a version of the engine, that does work with IE, you can execute the Python program +win32com\axscript\client\pyscript_rexec.py must be run. You can either do this manually, or follow the instructions below.

+ +

Register the engine now!

+ +

If you have read about the privacy +concern and still wish to register the engine, just follow the process outlined below:

+
    +
  1. Click on the link below +
  2. A dialog will be presented asking if the file should be opened or saved to disk. Select "Open it". +
  3. A Console program will briefly open, while the server is registered. +
+ +

Register the engine now + +

Checking the registration

+After the registration is complete, simply hit the Reload button. If the +registration was successful, the page will change to the Python/AvtiveX Demo Page. + + + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_intro.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_intro.htm new file mode 100644 index 0000000000000000000000000000000000000000..b8c811d8de77011ad2339e091a7c029a603e908c --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_intro.htm @@ -0,0 +1,38 @@ + + + +

+ Python ActiveX Scripting Demonstation + +

+ +

Congratulations on installing the Python ActiveX Scripting Engine

+ +

Be warned that there is a privacy +concern with this engine. Please read this information, including how to disable the feature.

+ + +

Object model

+

Except as described below, the object module exposed should be similar to that exposed +by Visual Basic, etc. Due to the nature of ActiveX Scripting, the details for each +host are different, but Python should work "correctly". + +

The object model exposed via Python for MSIE is not as seamless as VB. The biggest limitation is +the concept of a "local" namespace. For example, in VB, you can +code text="Hi there", but in Python, you must code +MyForm.ThisButton.Text="Hi There". See the foo2 sample +for futher details. + +

Known bugs and problems

+
    +
  • This release seems to have broken Aaron's mouse-trace sample. No idea why, and Im supposed to be looking into it. +

  • Builtin objects such as MARQUEE are giving me grief. Objects accessed via forms are generally +no problem. +

  • If you are trying to use Python with the Windows Scripting Host, note that +.pys files are not correct registered - you will need to explicitely +specify either cscript.exe or wscript.exe on the command line. +

+ + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_menu.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_menu.htm new file mode 100644 index 0000000000000000000000000000000000000000..ba23a434c68621e7cc3bf4b53d274a6586ba669b --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/demo_menu.htm @@ -0,0 +1,16 @@ + + +

Scripting Demos

+

An Introduction to the +scripting engine. + +

The Calculator Demo is a very +cool sample written by Aaron Watters. + +

Mouse track is another of +Aaron's samples, and shows how fast the Python engine is! + +

The foo2 sample is mainly used +for debugging and testing, but does show some forms in action. + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/docwrite.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/docwrite.htm new file mode 100644 index 0000000000000000000000000000000000000000..c95b7902ebf14d2149a8c9e871ff5bbe216c1ce6 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/docwrite.htm @@ -0,0 +1,25 @@ + + +A page generated by Python + + + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/foo2.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/foo2.htm new file mode 100644 index 0000000000000000000000000000000000000000..d5e0c4a624099739d2b933d0dbc3e2a8e1380d84 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/foo2.htm @@ -0,0 +1,105 @@ + + + + + + + +

The caption on the first button is set by the Window Load code. Clicking +that button changes the text in the first edit box. + +

The second button changes its own text when clicked. + +

The fourth button calls a global function, defined in the global 'script' scope, +rather than the 'MyForm' scope. + +

+ + + + + + + + + + + +

+

+And here is a second form +

+

+ + + + + + + +

+ + + + + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/form.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/form.htm new file mode 100644 index 0000000000000000000000000000000000000000..97a239f3626409a900ccbbadb356947898d51846 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/form.htm @@ -0,0 +1,25 @@ + + + +
+ Name
+ Address
+ + + + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/marqueeDemo.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/marqueeDemo.htm new file mode 100644 index 0000000000000000000000000000000000000000..33847c1d7c2dd971c8d6ba7205b1217d6deaec86 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/marqueeDemo.htm @@ -0,0 +1,60 @@ + + + + Internet Workshop + + + + +

+
+

Marquee Demo + +

+ + + + + + + + + + +

+ + + + + + + + +

  +


+Notes: +

+ + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/mousetrack.htm b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/mousetrack.htm new file mode 100644 index 0000000000000000000000000000000000000000..d307a4a6feb06ae515bd280485f607226c973043 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/mousetrack.htm @@ -0,0 +1,83 @@ + + +Python Scripting sample: Mouse tracking + + + + +
+ + +
 
+
+ +

+A mouse tracking demo. Move the mouse over the image above... + + + +

+ + + + + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/pycom_blowing.gif b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/pycom_blowing.gif new file mode 100644 index 0000000000000000000000000000000000000000..0d65a2928962860cf8b675b5192a43b165f31350 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/ie/pycom_blowing.gif differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/blank.pys b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/blank.pys new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/excel.pys b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/excel.pys new file mode 100644 index 0000000000000000000000000000000000000000..9c8fe751b4d8241aab45fc14ee166a9bf270823b --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/excel.pys @@ -0,0 +1,34 @@ +#app=WScript.Application +#app._print_details_() # Use this to see what Python knows about a COM object. + +g_index = 1 +# A procedure, using a global. +def Show(desc, value = None): + global g_index # Need global for g_index, as I locally assign. + # No global needed to "xl" object, as only referenced. + # Also note "xl" is assigned later in the script - ie, Python is very late bound. + xl.Cells(g_index, 1).Value = desc + if value: xl.Cells(g_index, 2).Value = value + g_index = g_index + 1 + +xl = WScript.CreateObject("Excel.Application") +import sys + +xl.Visible = 1 +#xl.Workbooks().Add() # Excel versions before 98 +xl.Workbooks.Add() + +# Show the WScript properties. +Show("Application Friendly Name", WScript.Name) +Show("Application Version", WScript.Version) +Show("Application Context: Fully Qualified Name", WScript.FullName) +Show("Application Context: Path Only", WScript.Path) +Show("State of Interactive Mode", WScript.Interactive) + +Show("All script arguments:") +args = WScript.Arguments + +for i in range(0,args.Count()): + Show("Arg %d" % i, args(i)) + + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/registry.pys b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/registry.pys new file mode 100644 index 0000000000000000000000000000000000000000..2d9d1e7736c715d80dbe69397d93adba8f7563f8 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/registry.pys @@ -0,0 +1,45 @@ +""" Windows Script Host Sample Script +' Ported to Python +' +' ------------------------------------------------------------------------ +' Copyright (C) 1996 Microsoft Corporation +' +' You have a royalty-free right to use, modify, reproduce and distribute +' the Sample Application Files (and/or any modified version) in any way +' you find useful, provided that you agree that Microsoft has no warranty, +' obligations or liability for any Sample Application Files. +' ------------------------------------------------------------------------ +' +' This sample demonstrates how to write/delete from the registry. +""" + +WshShell = WScript.CreateObject("WScript.Shell") + +WshShell.Popup("This script shows how to use registry related methods.", 2) + +WshShell.Popup("Create key HKCU\\Foo with value 'Top level key'") +WshShell.RegWrite("HKCU\\Foo\\", "Top level key") + +WshShell.Popup("Create key HKCU\\Foo\\Bar with value 'Second level key'") +WshShell.RegWrite( "HKCU\\Foo\\Bar\\", "Second level key") + +WshShell.Popup ("Set value HKCU\\Foo\\Value to REG_SZ 1") +WshShell.RegWrite( "HKCU\\Foo\\Value", 1) + +WshShell.Popup ("Set value HKCU\\Foo\\Bar to REG_DWORD 2") +WshShell.RegWrite ("HKCU\\Foo\\Bar", 2, "REG_DWORD") + +WshShell.Popup ("Set value HKCU\\Foo\\Bar to REG_EXPAND_SZ '3'") +WshShell.RegWrite ("HKCU\\Foo\\Bar\\Baz", "%SystemRoot%\\Foo") + +WshShell.Popup ("Delete value HKCU\\Foo\\Bar\\Baz") +WshShell.RegDelete ("HKCU\\Foo\\Bar\\Baz") + +WshShell.Popup ("Delete key HKCU\\Foo\\Bar") +WshShell.RegDelete ("HKCU\\Foo\\Bar\\") + +WshShell.Popup ("Delete key HKCU\\Foo") +WshShell.RegDelete ("HKCU\\Foo\\") + +WScript.Echo ("Done") + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/test.pys b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/test.pys new file mode 100644 index 0000000000000000000000000000000000000000..4038321ed20260b4f4c6513933447889f54c6ca6 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/Demos/client/wsh/test.pys @@ -0,0 +1,15 @@ +# Testall - test core AX support. + +# Test "Restricted Execution" (ie, IObjectSafety). +# This will fail if in a "restricted execution" environment, but +# will silenty do nothing of not restricted. This same line in an MSIE +# script would cause an exception. +print("Importing win32api...") +import win32api +if 1==1: + print("Hi") + +WScript.Echo("Hello from WScript") + +#fail + diff --git a/MLPY/Lib/site-packages/win32comext/axscript/__init__.py b/MLPY/Lib/site-packages/win32comext/axscript/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8d5db8b9375cce5e37b013fc099e1ccc4ba4374e --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/__init__.py @@ -0,0 +1,4 @@ +# See if we have a special directory for the binaries (for developers) +import win32com + +win32com.__PackageSupportBuildPath__(__path__) diff --git a/MLPY/Lib/site-packages/win32comext/axscript/__pycache__/__init__.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36c2416c263f75d01505da77acf0213cae8f1297 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/__pycache__/__init__.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/__pycache__/asputil.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/__pycache__/asputil.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5bb4480b4a5dcf27f3156284a84b9095be6cfc0f Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/__pycache__/asputil.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/asputil.py b/MLPY/Lib/site-packages/win32comext/axscript/asputil.py new file mode 100644 index 0000000000000000000000000000000000000000..b61c35373e81d248235a161e4f5c3c7ee7c0aff8 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/asputil.py @@ -0,0 +1,13 @@ +"""A utility module for ASP (Active Server Pages on MS Internet Info Server. + +Contains: + iif -- A utility function to avoid using "if" statements in ASP <% tags + +""" + + +def iif(cond, t, f): + if cond: + return t + else: + return f diff --git a/MLPY/Lib/site-packages/win32comext/axscript/axscript.pyd b/MLPY/Lib/site-packages/win32comext/axscript/axscript.pyd new file mode 100644 index 0000000000000000000000000000000000000000..a29615a5f4f88f1ea911cc9cc16c0c211953935b Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/axscript.pyd differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__init__.py b/MLPY/Lib/site-packages/win32comext/axscript/client/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7858ad6be04143d2e59d611b3a44cb3b2d9cd0cb --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/client/__init__.py @@ -0,0 +1 @@ +# This is a Python package diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/__init__.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e3c65a8a0d4f6e995992f55c930fcc0da7cfee4 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/__init__.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/debug.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/debug.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42a8dff2198da065aa67df74dae3f017e426cc69 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/debug.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/error.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/error.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d0c22b481fd835c1d89f274e86317587dd2940b Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/error.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/framework.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/framework.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a557efaf9d3b94628275c259d390e96927e9bd38 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/framework.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pydumper.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pydumper.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a298271afb227a6a5a5da56fe41f21ca87f025f Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pydumper.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pyscript.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pyscript.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b6f5dd3c9c174b6e903dc196c1a244e00d145e0 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pyscript.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pyscript_rexec.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pyscript_rexec.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8deccf299fc4d64af6a35634883c951bda70a26 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/pyscript_rexec.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/scriptdispatch.cpython-39.pyc b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/scriptdispatch.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..220a1dc326816882d8d90a5976d1b68b8dfdfc56 Binary files /dev/null and b/MLPY/Lib/site-packages/win32comext/axscript/client/__pycache__/scriptdispatch.cpython-39.pyc differ diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/debug.py b/MLPY/Lib/site-packages/win32comext/axscript/client/debug.py new file mode 100644 index 0000000000000000000000000000000000000000..2e305f0b77d875595326dfbdca9a2ced7a0193ef --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/client/debug.py @@ -0,0 +1,240 @@ +import os +import sys + +import pythoncom +import win32api +import win32com.client.connect +import win32com.server.util +import winerror +from win32com.axdebug import adb, axdebug, contexts, documents, gateways, stackframe +from win32com.axdebug.codecontainer import SourceCodeContainer +from win32com.axdebug.util import _wrap, _wrap_remove +from win32com.client.util import Enumerator +from win32com.server.exception import COMException +from win32com.util import IIDToInterfaceName + +from .framework import trace + +try: + os.environ["DEBUG_AXDEBUG"] + debuggingTrace = 1 # Should we print "trace" output? +except KeyError: + debuggingTrace = 0 + + +def trace(*args): + """A function used instead of "print" for debugging output.""" + if not debuggingTrace: + return + print(win32api.GetCurrentThreadId(), end=" ") + for arg in args: + print(arg, end=" ") + print() + + +# Note that the DebugManager is not a COM gateway class for the +# debugger - but it does create and manage them. +class DebugManager: + _debugger_interfaces_ = [axdebug.IID_IActiveScriptDebug] + + def __init__(self, scriptEngine): + self.scriptEngine = scriptEngine + self.adb = adb.Debugger() + self.rootNode = None + self.debugApplication = None + self.ccProvider = documents.CodeContainerProvider() + try: + self.scriptSiteDebug = scriptEngine.GetScriptSite( + axdebug.IID_IActiveScriptSiteDebug + ) + except pythoncom.com_error: + # No debugger interface (ie, dumb host). Do the extra work. + trace("Scripting site has no debugger interface") + self.scriptSiteDebug = None + # Get the debug application object. + self.debugApplication = None + if self.scriptSiteDebug is not None: + # Spec says that we should test for this, and if it fails revert to + # PDM application. + try: + self.debugApplication = self.scriptSiteDebug.GetApplication() + self.rootNode = self.scriptSiteDebug.GetRootApplicationNode() + except pythoncom.com_error: + self.debugApplication = None + + if self.debugApplication is None: + # Try to get/create the default one + # NOTE - Dont catch exceptions here - let the parent do it, + # so it knows debug support is available. + pdm = pythoncom.CoCreateInstance( + axdebug.CLSID_ProcessDebugManager, + None, + pythoncom.CLSCTX_ALL, + axdebug.IID_IProcessDebugManager, + ) + self.debugApplication = pdm.GetDefaultApplication() + self.rootNode = self.debugApplication.GetRootNode() + + assert ( + self.debugApplication is not None + ), "Need to have a DebugApplication object by now!" + self.activeScriptDebug = None + + if self.debugApplication is not None: + self.adb.AttachApp(self.debugApplication, self.ccProvider) + self.codeContainers = {} + self.activeScriptDebug = _wrap( + ActiveScriptDebug(self, self.codeContainers), axdebug.IID_IActiveScriptDebug + ) + + def Close(self): + # Called by the language engine when it receives a close request + if self.activeScriptDebug is not None: + _wrap_remove(self.activeScriptDebug) + self.activeScriptDebug = None + self.scriptEngine = None + self.rootNode = None + self.debugApplication = None + self.scriptSiteDebug = None + if self.ccProvider is not None: + self.ccProvider.Close() + self.ccProvider = None + self.codeContainers = {} + if self.adb: + self.adb.CloseApp() + self.adb = None + + # print "Close complete" + + def IsAnyHost(self): + "Do we have _any_ debugging interfaces installed?" + return self.debugApplication is not None + + def IsSimpleHost(self): + return self.scriptSiteDebug is None + + def HandleRuntimeError(self): + """Called by the engine when a runtime error occurs. If we have a debugger, + we let it know. + + The result is a boolean which indicates if the error handler should call + IActiveScriptSite::OnScriptError() + """ + # if self.IsAnyHost: + # site = _wrap(self, axdebug.IID_IActiveScriptSite) + # breakResume, errorResume, fCallOnError = self.debugApplication(activeScriptErrorDebug, site) + # Do something with these! + # else: + trace("HandleRuntimeError") + fCallOnError = 1 + return fCallOnError + + def _query_interface_for_debugger_(self, iid): + if iid in self._debugger_interfaces_: + return self.activeScriptDebug + trace("DebugManager QI - unknown IID", iid) + return 0 + + def OnEnterScript(self): + trace("OnEnterScript") + try: + 1 / 0 + except: + # Bit of a hack - reach into engine. + baseFrame = sys.exc_info()[2].tb_frame.f_back + self.adb.SetupAXDebugging(baseFrame) + + def OnLeaveScript(self): + trace("OnLeaveScript") + self.adb.ResetAXDebugging() + + def AddScriptBlock(self, codeBlock): + # If we dont have debugging support, dont bother. + cc = DebugCodeBlockContainer(codeBlock, self.scriptSiteDebug) + if self.IsSimpleHost(): + document = documents.DebugDocumentText(cc) + document = _wrap(document, axdebug.IID_IDebugDocument) + provider = documents.DebugDocumentProvider(document) + provider = _wrap(provider, axdebug.IID_IDebugDocumentProvider) + cc.debugDocument = document + newNode = self.debugApplication.CreateApplicationNode() + newNode.SetDocumentProvider(provider) + newNode.Attach(self.rootNode) + else: + newNode = None # Managed by smart host. + self.codeContainers[cc.sourceContext] = cc + self.ccProvider.AddCodeContainer(cc, newNode) + + +class DebugCodeBlockContainer(SourceCodeContainer): + def __init__(self, codeBlock, site): + self.codeBlock = codeBlock + SourceCodeContainer.__init__( + self, + codeBlock.codeText, + codeBlock.GetFileName(), + codeBlock.sourceContextCookie, + codeBlock.startLineNumber, + site, + ) + + def GetName(self, dnt): + if dnt == axdebug.DOCUMENTNAMETYPE_APPNODE: + return self.codeBlock.GetDisplayName() + elif dnt == axdebug.DOCUMENTNAMETYPE_TITLE: + return self.codeBlock.GetDisplayName() + # elif dnt==axdebug.DOCUMENTNAMETYPE_FILE_TAIL: + # elif dnt==axdebug.DOCUMENTNAMETYPE_URL: + else: + raise COMException(scode=winerror.S_FALSE) + + +class EnumDebugCodeContexts(gateways.EnumDebugCodeContexts): + def _wrap(self, ob): + return ob + + +class ActiveScriptDebug: + """The class which implements the IActiveScriptDebug interface for the Active Script engine. + + Only ever used by smart hosts. + """ + + _public_methods_ = [ + "GetScriptTextAttributes", + "GetScriptletTextAttributes", + "EnumCodeContextsOfPosition", + ] + _com_interfaces_ = [axdebug.IID_IActiveScriptDebug] + + def __init__(self, debugMgr, codeContainers): + self.debugMgr = debugMgr + self.scriptSiteDebug = debugMgr.scriptSiteDebug + self.codeContainers = codeContainers + + def _Close(self): + self.debugMgr = None + self.scriptSiteDebug = None + self.codeContainers = {} + + def _query_interface_(self, iid): + trace("DebuggerQI with", iid) + return _wrap(self.debugMgr.scriptEngine, iid) + + def GetScriptTextAttributes(self, code, delim, flags): + container = SourceCodeContainer(code, "") + return container.GetSyntaxColorAttributes() + + def GetScriptletTextAttributes(self, code, delim, flags): + trace("GetScriptletTextAttributes", code, delim, flags) + container = SourceCodeContainer(code, "") + return container.GetSyntaxColorAttributes() + + def EnumCodeContextsOfPosition(self, context, charOffset, numChars): + trace("EnumCodeContextsOfPosition", context, charOffset, numChars) + try: + context = self.codeContainers[context].GetCodeContextAtPosition(charOffset) + except KeyError: + raise COMException(scode=winerror.E_UNEXPECTED) + enum = EnumDebugCodeContexts([context]) + return _wrap(enum, axdebug.IID_IEnumDebugCodeContexts) diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/error.py b/MLPY/Lib/site-packages/win32comext/axscript/client/error.py new file mode 100644 index 0000000000000000000000000000000000000000..1dfa54fa2fd2d4cdc9dea77c4977026390e238aa --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/client/error.py @@ -0,0 +1,273 @@ +"""Exception and error handling. + + This contains the core exceptions that the implementations should raise + as well as the IActiveScriptError interface code. + +""" + +import re +import sys +import traceback + +import pythoncom +import win32com.server.exception +import win32com.server.util +import winerror +from win32com.axscript import axscript + +debugging = 0 + + +def FormatForAX(text): + """Format a string suitable for an AX Host""" + # Replace all " with ', so it works OK in HTML (ie, ASP) + return ExpandTabs(AddCR(text)) + + +def ExpandTabs(text): + return re.sub("\t", " ", text) + + +def AddCR(text): + return re.sub("\n", "\r\n", text) + + +class IActiveScriptError: + """An implementation of IActiveScriptError + + The ActiveX Scripting host calls this client whenever we report + an exception to it. This interface provides the exception details + for the host to report to the user. + """ + + _com_interfaces_ = [axscript.IID_IActiveScriptError] + _public_methods_ = ["GetSourceLineText", "GetSourcePosition", "GetExceptionInfo"] + + def _query_interface_(self, iid): + print("IActiveScriptError QI - unknown IID", iid) + return 0 + + def _SetExceptionInfo(self, exc): + self.exception = exc + + def GetSourceLineText(self): + return self.exception.linetext + + def GetSourcePosition(self): + ctx = self.exception.sourceContext + # Zero based in the debugger (but our columns are too!) + return ( + ctx, + self.exception.lineno + self.exception.startLineNo - 1, + self.exception.colno, + ) + + def GetExceptionInfo(self): + return self.exception + + +class AXScriptException(win32com.server.exception.COMException): + """A class used as a COM exception. + + Note this has attributes which conform to the standard attributes + for COM exceptions, plus a few others specific to our IActiveScriptError + object. + """ + + def __init__(self, site, codeBlock, exc_type, exc_value, exc_traceback): + # set properties base class shares via base ctor... + win32com.server.exception.COMException.__init__( + self, + description="Unknown Exception", + scode=winerror.DISP_E_EXCEPTION, + source="Python ActiveX Scripting Engine", + ) + + # And my other values... + if codeBlock is None: + self.sourceContext = 0 + self.startLineNo = 0 + else: + self.sourceContext = codeBlock.sourceContextCookie + self.startLineNo = codeBlock.startLineNumber + self.linetext = "" + + self.__BuildFromException(site, exc_type, exc_value, exc_traceback) + + def __BuildFromException(self, site, type, value, tb): + if debugging: + import linecache + + linecache.clearcache() + try: + if issubclass(type, SyntaxError): + self._BuildFromSyntaxError(site, value, tb) + else: + self._BuildFromOther(site, type, value, tb) + except: # Error extracting traceback info!!! + traceback.print_exc() + # re-raise. + raise + + def _BuildFromSyntaxError(self, site, exc, tb): + value = exc.args + # All syntax errors should have a message as element 0 + try: + msg = value[0] + except: + msg = "Unknown Error (%s)" % (value,) + try: + (filename, lineno, offset, line) = value[1] + # Some of these may be None, which upsets us! + if offset is None: + offset = 0 + if line is None: + line = "" + except: + msg = "Unknown" + lineno = 0 + offset = 0 + line = "Unknown" + self.description = FormatForAX(msg) + self.lineno = lineno + self.colno = offset - 1 + self.linetext = ExpandTabs(line.rstrip()) + + def _BuildFromOther(self, site, exc_type, value, tb): + self.colno = -1 + self.lineno = 0 + if debugging: # Full traceback if debugging. + list = traceback.format_exception(exc_type, value, tb) + self.description = ExpandTabs("".join(list)) + return + # Run down the traceback list, looking for the first "" + # Hide traceback above this. In addition, keep going down + # looking for a "_*_" attribute, and below hide these also. + hide_names = [ + "r_import", + "r_reload", + "r_open", + ] # hide from these functions down in the traceback. + depth = None + tb_top = tb + while tb_top: + filename, lineno, name, line = self.ExtractTracebackInfo(tb_top, site) + if filename[:7] == " all items in the list are utf8 courtesy of Python magically + # > converting unicode to utf8 before compilation. + # but that is likely just confusion from early unicode days; + # Python isn't doing it, pywin32 probably was, so 'mbcs' would + # be the default encoding. We should never hit this these days + # anyway, but on py3k, we *never* will, and str objects there + # don't have a decode method... + if sys.version_info < (3,): + for i in range(len(bits)): + if type(bits[i]) is str: + # assert type(bits[i]) is str, type(bits[i]) + bits[i] = bits[i].decode("utf8") + + self.description = ExpandTabs("".join(bits)) + # Clear tracebacks etc. + tb = tb_top = tb_look = None + + def ExtractTracebackInfo(self, tb, site): + import linecache + + f = tb.tb_frame + lineno = tb.tb_lineno + co = f.f_code + filename = co.co_filename + name = co.co_name + line = linecache.getline(filename, lineno) + if not line: + try: + codeBlock = site.scriptCodeBlocks[filename] + except KeyError: + codeBlock = None + if codeBlock: + # Note: 'line' will now be unicode. + line = codeBlock.GetLineNo(lineno) + if line: + line = line.strip() + else: + line = None + return filename, lineno, name, line + + def __repr__(self): + return "AXScriptException Object with description:" + self.description + + +def ProcessAXScriptException(scriptingSite, debugManager, exceptionInstance): + """General function to handle any exception in AX code + + This function creates an instance of our IActiveScriptError interface, and + gives it to the host, along with out exception class. The host will + likely call back on the IActiveScriptError interface to get the source text + and other information not normally in COM exceptions. + """ + # traceback.print_exc() + instance = IActiveScriptError() + instance._SetExceptionInfo(exceptionInstance) + gateway = win32com.server.util.wrap(instance, axscript.IID_IActiveScriptError) + if debugManager: + fCallOnError = debugManager.HandleRuntimeError() + if not fCallOnError: + return None + + try: + result = scriptingSite.OnScriptError(gateway) + except pythoncom.com_error as details: + print("**OnScriptError failed:", details) + print("Exception description:'%s'" % (repr(exceptionInstance.description))) + print("Exception text:'%s'" % (repr(exceptionInstance.linetext))) + result = winerror.S_FALSE + + if result == winerror.S_OK: + # If the above returns NOERROR, it is assumed the error has been + # correctly registered and the value SCRIPT_E_REPORTED is returned. + ret = win32com.server.exception.COMException(scode=axscript.SCRIPT_E_REPORTED) + return ret + else: + # The error is taken to be unreported and is propagated up the call stack + # via the IDispatch::Invoke's EXCEPINFO parameter (hr returned is DISP_E_EXCEPTION. + return exceptionInstance diff --git a/MLPY/Lib/site-packages/win32comext/axscript/client/framework.py b/MLPY/Lib/site-packages/win32comext/axscript/client/framework.py new file mode 100644 index 0000000000000000000000000000000000000000..d7b56a7cbe7e7a28fc94fd6251d66eefa34aebd9 --- /dev/null +++ b/MLPY/Lib/site-packages/win32comext/axscript/client/framework.py @@ -0,0 +1,1270 @@ +"""AXScript Client Framework + + This module provides a core framework for an ActiveX Scripting client. + Derived classes actually implement the AX Client itself, including the + scoping rules, etc. + + There are classes defined for the engine itself, and for ScriptItems +""" +import re +import sys + +import pythoncom # Need simple connection point support +import win32api +import win32com.client.connect +import win32com.server.util +import winerror +from win32com.axscript import axscript + + +def RemoveCR(text): + # No longer just "RemoveCR" - should be renamed to + # FixNewlines, or something. Idea is to fix arbitary newlines into + # something Python can compile... + return re.sub("(\r\n)|\r|(\n\r)", "\n", text) + + +SCRIPTTEXT_FORCEEXECUTION = -2147483648 # 0x80000000 +SCRIPTTEXT_ISEXPRESSION = 0x00000020 +SCRIPTTEXT_ISPERSISTENT = 0x00000040 + +from win32com.server.exception import Exception, IsCOMServerException + +from . import error # ax.client.error + +state_map = { + axscript.SCRIPTSTATE_UNINITIALIZED: "SCRIPTSTATE_UNINITIALIZED", + axscript.SCRIPTSTATE_INITIALIZED: "SCRIPTSTATE_INITIALIZED", + axscript.SCRIPTSTATE_STARTED: "SCRIPTSTATE_STARTED", + axscript.SCRIPTSTATE_CONNECTED: "SCRIPTSTATE_CONNECTED", + axscript.SCRIPTSTATE_DISCONNECTED: "SCRIPTSTATE_DISCONNECTED", + axscript.SCRIPTSTATE_CLOSED: "SCRIPTSTATE_CLOSED", +} + + +def profile(fn, *args): + import profile + + prof = profile.Profile() + try: + # roll on 1.6 :-) + # return prof.runcall(fn, *args) + return prof.runcall(*(fn,) + args) + finally: + import pstats + + # Damn - really want to send this to Excel! + # width, list = pstats.Stats(prof).strip_dirs().get_print_list([]) + pstats.Stats(prof).strip_dirs().sort_stats("time").print_stats() + + +class SafeOutput: + softspace = 1 + + def __init__(self, redir=None): + if redir is None: + redir = sys.stdout + self.redir = redir + + def write(self, message): + try: + self.redir.write(message) + except: + win32api.OutputDebugString(message) + + def flush(self): + pass + + def close(self): + pass + + +# Make sure we have a valid sys.stdout/stderr, otherwise out +# print and trace statements may raise an exception +def MakeValidSysOuts(): + if not isinstance(sys.stdout, SafeOutput): + sys.stdout = sys.stderr = SafeOutput() + # and for the sake of working around something I can't understand... + # prevent keyboard interrupts from killing IIS + import signal + + def noOp(a, b): + # it would be nice to get to the bottom of this, so a warning to + # the debug console can't hurt. + print("WARNING: Ignoring keyboard interrupt from ActiveScripting engine") + + # If someone else has already redirected, then assume they know what they are doing! + if signal.getsignal(signal.SIGINT) == signal.default_int_handler: + try: + signal.signal(signal.SIGINT, noOp) + except ValueError: + # Not the main thread - can't do much. + pass + + +def trace(*args): + """A function used instead of "print" for debugging output.""" + for arg in args: + print(arg, end=" ") + print() + + +def RaiseAssert(scode, desc): + """A debugging function that raises an exception considered an "Assertion".""" + print("**************** ASSERTION FAILED *******************") + print(desc) + raise Exception(desc, scode) + + +class AXScriptCodeBlock: + """An object which represents a chunk of code in an AX Script""" + + def __init__(self, name, codeText, sourceContextCookie, startLineNumber, flags): + self.name = name + self.codeText = codeText + self.codeObject = None + self.sourceContextCookie = sourceContextCookie + self.startLineNumber = startLineNumber + self.flags = flags + self.beenExecuted = 0 + + def GetFileName(self): + # Gets the "file name" for Python - uses <...> so Python doesnt think + # it is a real file. + return "<%s>" % self.name + + def GetDisplayName(self): + return self.name + + def GetLineNo(self, no): + pos = -1 + for i in range(no - 1): + pos = self.codeText.find("\n", pos + 1) + if pos == -1: + pos = len(self.codeText) + epos = self.codeText.find("\n", pos + 1) + if epos == -1: + epos = len(self.codeText) + return self.codeText[pos + 1 : epos].strip() + + +class Event: + """A single event for a ActiveX named object.""" + + def __init__(self): + self.name = "" + + def __repr__(self): + return "<%s at %d: %s>" % (self.__class__.__name__, id(self), self.name) + + def Reset(self): + pass + + def Close(self): + pass + + def Build(self, typeinfo, funcdesc): + self.dispid = funcdesc[0] + self.name = typeinfo.GetNames(self.dispid)[0] + + +# print "Event.Build() - Event Name is ", self.name + + +class EventSink: + """A set of events against an item. Note this is a COM client for connection points.""" + + _public_methods_ = [] + + def __init__(self, myItem, coDispatch): + self.events = {} + self.connection = None + self.coDispatch = coDispatch + self.myScriptItem = myItem + self.myInvokeMethod = myItem.GetEngine().ProcessScriptItemEvent + self.iid = None + + def Reset(self): + self.Disconnect() + + def Close(self): + self.iid = None + self.myScriptItem = None + self.myInvokeMethod = None + self.coDispatch = None + for event in self.events.values(): + event.Reset() + self.events = {} + self.Disconnect() + + # COM Connection point methods. + def _query_interface_(self, iid): + if iid == self.iid: + return win32com.server.util.wrap(self) + + def _invoke_(self, dispid, lcid, wFlags, args): + try: + event = self.events[dispid] + except: + raise Exception(scode=winerror.DISP_E_MEMBERNOTFOUND) + # print "Invoke for ", event, "on", self.myScriptItem, " - calling", self.myInvokeMethod + return self.myInvokeMethod(self.myScriptItem, event, lcid, wFlags, args) + + def GetSourceTypeInfo(self, typeinfo): + """Gets the typeinfo for the Source Events for the passed typeinfo""" + attr = typeinfo.GetTypeAttr() + cFuncs = attr[6] + typeKind = attr[5] + if typeKind not in [pythoncom.TKIND_COCLASS, pythoncom.TKIND_INTERFACE]: + RaiseAssert( + winerror.E_UNEXPECTED, "The typeKind of the object is unexpected" + ) + cImplType = attr[8] + for i in range(cImplType): + # Look for the [source, default] interface on the coclass + # that isn't marked as restricted. + flags = typeinfo.GetImplTypeFlags(i) + flagsNeeded = ( + pythoncom.IMPLTYPEFLAG_FDEFAULT | pythoncom.IMPLTYPEFLAG_FSOURCE + ) + if (flags & (flagsNeeded | pythoncom.IMPLTYPEFLAG_FRESTRICTED)) == ( + flagsNeeded + ): + # Get the handle to the implemented interface. + href = typeinfo.GetRefTypeOfImplType(i) + return typeinfo.GetRefTypeInfo(href) + + def BuildEvents(self): + # See if it is an extender object. + try: + mainTypeInfo = self.coDispatch.QueryInterface( + axscript.IID_IProvideMultipleClassInfo + ) + isMulti = 1 + numTypeInfos = mainTypeInfo.GetMultiTypeInfoCount() + except pythoncom.com_error: + isMulti = 0 + numTypeInfos = 1 + try: + mainTypeInfo = self.coDispatch.QueryInterface( + pythoncom.IID_IProvideClassInfo + ) + except pythoncom.com_error: + numTypeInfos = 0 + # Create an event handler for the item. + for item in range(numTypeInfos): + if isMulti: + typeinfo, flags = mainTypeInfo.GetInfoOfIndex( + item, axscript.MULTICLASSINFO_GETTYPEINFO + ) + else: + typeinfo = mainTypeInfo.GetClassInfo() + sourceType = self.GetSourceTypeInfo(typeinfo) + cFuncs = 0 + if sourceType: + attr = sourceType.GetTypeAttr() + self.iid = attr[0] + cFuncs = attr[6] + for i in range(cFuncs): + funcdesc = sourceType.GetFuncDesc(i) + event = Event() + event.Build(sourceType, funcdesc) + self.events[event.dispid] = event + + def Connect(self): + if self.connection is not None or self.iid is None: + return + # trace("Connect for sink item", self.myScriptItem.name, "with IID",str(self.iid)) + self.connection = win32com.client.connect.SimpleConnection( + self.coDispatch, self, self.iid + ) + + def Disconnect(self): + if self.connection: + try: + self.connection.Disconnect() + except pythoncom.com_error: + pass # Ignore disconnection errors. + self.connection = None + + +class ScriptItem: + """An item (or subitem) that is exposed to the ActiveX script""" + + def __init__(self, parentItem, name, dispatch, flags): + self.parentItem = parentItem + self.dispatch = dispatch + self.name = name + self.flags = flags + self.eventSink = None + self.subItems = {} + self.createdConnections = 0 + self.isRegistered = 0 + + # trace("Creating ScriptItem", name, "of parent", parentItem,"with dispatch", dispatch) + + def __repr__(self): + flagsDesc = "" + if self.flags is not None and self.flags & axscript.SCRIPTITEM_GLOBALMEMBERS: + flagsDesc = "/Global" + return "<%s at %d: %s%s>" % ( + self.__class__.__name__, + id(self), + self.name, + flagsDesc, + ) + + def _dump_(self, level): + flagDescs = [] + if self.flags is not None and self.flags & axscript.SCRIPTITEM_GLOBALMEMBERS: + flagDescs.append("GLOBAL!") + if self.flags is None or self.flags & axscript.SCRIPTITEM_ISVISIBLE == 0: + flagDescs.append("NOT VISIBLE") + if self.flags is not None and self.flags & axscript.SCRIPTITEM_ISSOURCE: + flagDescs.append("EVENT SINK") + if self.flags is not None and self.flags & axscript.SCRIPTITEM_CODEONLY: + flagDescs.append("CODE ONLY") + print(" " * level, "Name=", self.name, ", flags=", "/".join(flagDescs), self) + for subItem in self.subItems.values(): + subItem._dump_(level + 1) + + def Reset(self): + self.Disconnect() + if self.eventSink: + self.eventSink.Reset() + self.isRegistered = 0 + for subItem in self.subItems.values(): + subItem.Reset() + + def Close(self): + self.Reset() + self.dispatch = None + self.parentItem = None + if self.eventSink: + self.eventSink.Close() + self.eventSink = None + for subItem in self.subItems.values(): + subItem.Close() + self.subItems = [] + self.createdConnections = 0 + + def Register(self): + if self.isRegistered: + return + # Get the type info to use to build this item. + # if not self.dispatch: + # id = self.parentItem.dispatch.GetIDsOfNames(self.name) + # print "DispID of me is", id + # result = self.parentItem.dispatch.Invoke(id, 0, pythoncom.DISPATCH_PROPERTYGET,1) + # if type(result)==pythoncom.TypeIIDs[pythoncom.IID_IDispatch]: + # self.dispatch = result + # else: + # print "*** No dispatch" + # return + # print "**** Made dispatch" + self.isRegistered = 1 + # Register the sub-items. + for item in self.subItems.values(): + if not item.isRegistered: + item.Register() + + def IsGlobal(self): + return self.flags & axscript.SCRIPTITEM_GLOBALMEMBERS + + def IsVisible(self): + return ( + self.flags & (axscript.SCRIPTITEM_ISVISIBLE | axscript.SCRIPTITEM_ISSOURCE) + ) != 0 + + def GetEngine(self): + item = self + while item.parentItem.__class__ == self.__class__: + item = item.parentItem + return item.parentItem + + def _GetFullItemName(self): + ret = self.name + if self.parentItem: + try: + ret = self.parentItem._GetFullItemName() + "." + ret + except AttributeError: + pass + return ret + + def GetSubItemClass(self): + return self.__class__ + + def GetSubItem(self, name): + return self.subItems[name.lower()] + + def GetCreateSubItem(self, parentItem, name, dispatch, flags): + keyName = name.lower() + try: + rc = self.subItems[keyName] + # No changes allowed to existing flags. + if not rc.flags is None and not flags is None and rc.flags != flags: + raise Exception(scode=winerror.E_INVALIDARG) + # Existing item must not have a dispatch. + if not rc.dispatch is None and not dispatch is None: + raise Exception(scode=winerror.E_INVALIDARG) + rc.flags = flags # Setup the real flags. + rc.dispatch = dispatch + except KeyError: + rc = self.subItems[keyName] = self.GetSubItemClass()( + parentItem, name, dispatch, flags + ) + return rc + + # if self.dispatch is None: + # RaiseAssert(winerror.E_UNEXPECTED, "??") + + def CreateConnections(self): + # Create (but do not connect to) the connection points. + if self.createdConnections: + return + self.createdConnections = 1 + # Nothing to do unless this is an event source + # This flags means self, _and_ children, are connectable. + if self.flags & axscript.SCRIPTITEM_ISSOURCE: + self.BuildEvents() + self.FindBuildSubItemEvents() + + def Connect(self): + # Connect to the already created connection points. + if self.eventSink: + self.eventSink.Connect() + for subItem in self.subItems.values(): + subItem.Connect() + + def Disconnect(self): + # Disconnect from the connection points. + if self.eventSink: + self.eventSink.Disconnect() + for subItem in self.subItems.values(): + subItem.Disconnect() + + def BuildEvents(self): + if self.eventSink is not None or self.dispatch is None: + RaiseAssert( + winerror.E_UNEXPECTED, + "Item already has built events, or no dispatch available?", + ) + + # trace("BuildEvents for named item", self._GetFullItemName()) + self.eventSink = EventSink(self, self.dispatch) + self.eventSink.BuildEvents() + + def FindBuildSubItemEvents(self): + # Called during connection to event source. Seeks out and connects to + # all children. As per the AX spec, this is not recursive + # (ie, children sub-items are not seeked) + try: + multiTypeInfo = self.dispatch.QueryInterface( + axscript.IID_IProvideMultipleClassInfo + ) + numTypeInfos = multiTypeInfo.GetMultiTypeInfoCount() + except pythoncom.com_error: + return + for item in range(numTypeInfos): + typeinfo, flags = multiTypeInfo.GetInfoOfIndex( + item, axscript.MULTICLASSINFO_GETTYPEINFO + ) + defaultType = self.GetDefaultSourceTypeInfo(typeinfo) + index = 0 + while 1: + try: + fdesc = defaultType.GetFuncDesc(index) + except pythoncom.com_error: + break # No more funcs + index = index + 1 + dispid = fdesc[0] + funckind = fdesc[3] + invkind = fdesc[4] + elemdesc = fdesc[8] + funcflags = fdesc[9] + try: + isSubObject = ( + not (funcflags & pythoncom.FUNCFLAG_FRESTRICTED) + and funckind == pythoncom.FUNC_DISPATCH + and invkind == pythoncom.INVOKE_PROPERTYGET + and elemdesc[0][0] == pythoncom.VT_PTR + and elemdesc[0][1][0] == pythoncom.VT_USERDEFINED + ) + except: + isSubObject = 0 + if isSubObject: + try: + # We found a sub-object. + names = typeinfo.GetNames(dispid) + result = self.dispatch.Invoke( + dispid, 0x0, pythoncom.DISPATCH_PROPERTYGET, 1 + ) + # IE has an interesting problem - there are lots of synonyms for the same object. Eg + # in a simple form, "window.top", "window.window", "window.parent", "window.self" + # all refer to the same object. Our event implementation code does not differentiate + # eg, "window_onload" will fire for *all* objects named "window". Thus, + # "window" and "window.window" will fire the same event handler :( + # One option would be to check if the sub-object is indeed the + # parent object - however, this would stop "top_onload" from firing, + # as no event handler for "top" would work. + # I think we simply need to connect to a *single* event handler. + # As use in IE is deprecated, I am not solving this now. + if type(result) == pythoncom.TypeIIDs[pythoncom.IID_IDispatch]: + name = names[0] + subObj = self.GetCreateSubItem( + self, name, result, axscript.SCRIPTITEM_ISVISIBLE + ) + # print "subobj", name, "flags are", subObj.flags, "mydisp=", self.dispatch, "result disp=", result, "compare=", self.dispatch==result + subObj.BuildEvents() + subObj.Register() + except pythoncom.com_error: + pass + + def GetDefaultSourceTypeInfo(self, typeinfo): + """Gets the typeinfo for the Default Dispatch for the passed typeinfo""" + attr = typeinfo.GetTypeAttr() + cFuncs = attr[6] + typeKind = attr[5] + if typeKind not in [pythoncom.TKIND_COCLASS, pythoncom.TKIND_INTERFACE]: + RaiseAssert( + winerror.E_UNEXPECTED, "The typeKind of the object is unexpected" + ) + cImplType = attr[8] + for i in range(cImplType): + # Look for the [source, default] interface on the coclass + # that isn't marked as restricted. + flags = typeinfo.GetImplTypeFlags(i) + if ( + flags + & ( + pythoncom.IMPLTYPEFLAG_FDEFAULT + | pythoncom.IMPLTYPEFLAG_FSOURCE + | pythoncom.IMPLTYPEFLAG_FRESTRICTED + ) + ) == pythoncom.IMPLTYPEFLAG_FDEFAULT: + # Get the handle to the implemented interface. + href = typeinfo.GetRefTypeOfImplType(i) + defTypeInfo = typeinfo.GetRefTypeInfo(href) + attr = defTypeInfo.GetTypeAttr() + typeKind = attr[5] + typeFlags = attr[11] + if ( + typeKind == pythoncom.TKIND_INTERFACE + and typeFlags & pythoncom.TYPEFLAG_FDUAL + ): + # Get corresponding Disp interface + # -1 is a special value which does this for us. + href = typeinfo.GetRefTypeOfImplType(-1) + return defTypeInfo.GetRefTypeInfo(href) + else: + return defTypeInfo + + +IActiveScriptMethods = [ + "SetScriptSite", + "GetScriptSite", + "SetScriptState", + "GetScriptState", + "Close", + "AddNamedItem", + "AddTypeLib", + "GetScriptDispatch", + "GetCurrentScriptThreadID", + "GetScriptThreadID", + "GetScriptThreadState", + "InterruptScriptThread", + "Clone", +] +IActiveScriptParseMethods = ["InitNew", "AddScriptlet", "ParseScriptText"] +IObjectSafetyMethods = ["GetInterfaceSafetyOptions", "SetInterfaceSafetyOptions"] + +# ActiveScriptParseProcedure is a new interface with IIS4/IE4. +IActiveScriptParseProcedureMethods = ["ParseProcedureText"] + + +class COMScript: + """An ActiveX Scripting engine base class. + + This class implements the required COM interfaces for ActiveX scripting. + """ + + _public_methods_ = ( + IActiveScriptMethods + + IActiveScriptParseMethods + + IObjectSafetyMethods + + IActiveScriptParseProcedureMethods + ) + _com_interfaces_ = [ + axscript.IID_IActiveScript, + axscript.IID_IActiveScriptParse, + axscript.IID_IObjectSafety, + ] # , axscript.IID_IActiveScriptParseProcedure] + + def __init__(self): + # Make sure we can print/trace wihout an exception! + MakeValidSysOuts() + # trace("AXScriptEngine object created", self) + self.baseThreadId = -1 + self.debugManager = None + self.threadState = axscript.SCRIPTTHREADSTATE_NOTINSCRIPT + self.scriptState = axscript.SCRIPTSTATE_UNINITIALIZED + self.scriptSite = None + self.safetyOptions = 0 + self.lcid = 0 + self.subItems = {} + self.scriptCodeBlocks = {} + + def _query_interface_(self, iid): + if self.debugManager: + return self.debugManager._query_interface_for_debugger_(iid) + # trace("ScriptEngine QI - unknown IID", iid) + return 0 + + # IActiveScriptParse + def InitNew(self): + if self.scriptSite is not None: + self.SetScriptState(axscript.SCRIPTSTATE_INITIALIZED) + + def AddScriptlet( + self, + defaultName, + code, + itemName, + subItemName, + eventName, + delimiter, + sourceContextCookie, + startLineNumber, + ): + # trace ("AddScriptlet", defaultName, code, itemName, subItemName, eventName, delimiter, sourceContextCookie, startLineNumber) + self.DoAddScriptlet( + defaultName, + code, + itemName, + subItemName, + eventName, + delimiter, + sourceContextCookie, + startLineNumber, + ) + + def ParseScriptText( + self, + code, + itemName, + context, + delimiter, + sourceContextCookie, + startLineNumber, + flags, + bWantResult, + ): + # trace ("ParseScriptText", code[:20],"...", itemName, context, delimiter, sourceContextCookie, startLineNumber, flags, bWantResult) + if ( + bWantResult + or self.scriptState == axscript.SCRIPTSTATE_STARTED + or self.scriptState == axscript.SCRIPTSTATE_CONNECTED + or self.scriptState == axscript.SCRIPTSTATE_DISCONNECTED + ): + flags = flags | SCRIPTTEXT_FORCEEXECUTION + else: + flags = flags & (~SCRIPTTEXT_FORCEEXECUTION) + + if flags & SCRIPTTEXT_FORCEEXECUTION: + # About to execute the code. + self.RegisterNewNamedItems() + return self.DoParseScriptText( + code, sourceContextCookie, startLineNumber, bWantResult, flags + ) + + # + # IActiveScriptParseProcedure + def ParseProcedureText( + self, + code, + formalParams, + procName, + itemName, + unkContext, + delimiter, + contextCookie, + startingLineNumber, + flags, + ): + trace( + "ParseProcedureText", + code, + formalParams, + procName, + itemName, + unkContext, + delimiter, + contextCookie, + startingLineNumber, + flags, + ) + # NOTE - this is never called, as we have disabled this interface. + # Problem is, once enabled all even code comes via here, rather than AddScriptlet. + # However, the "procName" is always an empty string - ie, itemName is the object whose event we are handling, + # but no idea what the specific event is!? + # Problem is disabling this block is that AddScriptlet is _not_ passed + #