mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-20 13:23:24 -07:00
Bump cherrypy from 18.8.0 to 18.9.0 (#2266)
* Bump cherrypy from 18.8.0 to 18.9.0 Bumps [cherrypy](https://github.com/cherrypy/cherrypy) from 18.8.0 to 18.9.0. - [Changelog](https://github.com/cherrypy/cherrypy/blob/main/CHANGES.rst) - [Commits](https://github.com/cherrypy/cherrypy/compare/v18.8.0...v18.9.0) --- updated-dependencies: - dependency-name: cherrypy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update cherrypy==18.9.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> [skip ci]
This commit is contained in:
parent
cfefa928be
commit
faef9a94c4
673 changed files with 159850 additions and 11583 deletions
122
lib/win32comext/adsi/__init__.py
Normal file
122
lib/win32comext/adsi/__init__.py
Normal file
|
@ -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)
|
BIN
lib/win32comext/adsi/adsi.pyd
Normal file
BIN
lib/win32comext/adsi/adsi.pyd
Normal file
Binary file not shown.
340
lib/win32comext/adsi/adsicon.py
Normal file
340
lib/win32comext/adsi/adsicon.py
Normal file
|
@ -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"
|
68
lib/win32comext/adsi/demos/objectPicker.py
Normal file
68
lib/win32comext/adsi/demos/objectPicker.py
Normal file
|
@ -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()
|
565
lib/win32comext/adsi/demos/scp.py
Normal file
565
lib/win32comext/adsi/demos/scp.py
Normal file
|
@ -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")
|
152
lib/win32comext/adsi/demos/search.py
Normal file
152
lib/win32comext/adsi/demos/search.py
Normal file
|
@ -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()
|
273
lib/win32comext/adsi/demos/test.py
Normal file
273
lib/win32comext/adsi/demos/test.py
Normal file
|
@ -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 = "<Error: %s>" % (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, "<unknown type>")
|
||||
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()
|
6
lib/win32comext/authorization/__init__.py
Normal file
6
lib/win32comext/authorization/__init__.py
Normal file
|
@ -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__)
|
BIN
lib/win32comext/authorization/authorization.pyd
Normal file
BIN
lib/win32comext/authorization/authorization.pyd
Normal file
Binary file not shown.
255
lib/win32comext/authorization/demos/EditSecurity.py
Normal file
255
lib/win32comext/authorization/demos/EditSecurity.py
Normal file
|
@ -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()
|
242
lib/win32comext/authorization/demos/EditServiceSecurity.py
Normal file
242
lib/win32comext/authorization/demos/EditServiceSecurity.py
Normal file
|
@ -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()
|
4
lib/win32comext/axcontrol/__init__.py
Normal file
4
lib/win32comext/axcontrol/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
# See if we have a special directory for the binaries (for developers)
|
||||
import win32com
|
||||
|
||||
win32com.__PackageSupportBuildPath__(__path__)
|
BIN
lib/win32comext/axcontrol/axcontrol.pyd
Normal file
BIN
lib/win32comext/axcontrol/axcontrol.pyd
Normal file
Binary file not shown.
4
lib/win32comext/axdebug/__init__.py
Normal file
4
lib/win32comext/axdebug/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
# See if we have a special directory for the binaries (for developers)
|
||||
import win32com
|
||||
|
||||
win32com.__PackageSupportBuildPath__(__path__)
|
480
lib/win32comext/axdebug/adb.py
Normal file
480
lib/win32comext/axdebug/adb.py
Normal file
|
@ -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 "<None>"
|
||||
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
|
BIN
lib/win32comext/axdebug/axdebug.pyd
Normal file
BIN
lib/win32comext/axdebug/axdebug.pyd
Normal file
Binary file not shown.
278
lib/win32comext/axdebug/codecontainer.py
Normal file
278
lib/win32comext/axdebug/codecontainer.py
Normal file
|
@ -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="<Remove Me!>",
|
||||
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 = "<Unknown!>"
|
||||
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))
|
62
lib/win32comext/axdebug/contexts.py
Normal file
62
lib/win32comext/axdebug/contexts.py
Normal file
|
@ -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)
|
250
lib/win32comext/axdebug/debugger.py
Normal file
250
lib/win32comext/axdebug/debugger.py
Normal file
|
@ -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 "<ModuleTreeNode wrapping %s>" % (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())
|
||||
)
|
140
lib/win32comext/axdebug/documents.py
Normal file
140
lib/win32comext/axdebug/documents.py
Normal file
|
@ -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 = {}
|
61
lib/win32comext/axdebug/dump.py
Normal file
61
lib/win32comext/axdebug/dump.py
Normal file
|
@ -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 = "<N/A>"
|
||||
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, "<No document available>"))
|
||||
|
||||
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()
|
214
lib/win32comext/axdebug/expressions.py
Normal file
214
lib/win32comext/axdebug/expressions.py
Normal file
|
@ -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")
|
583
lib/win32comext/axdebug/gateways.py
Normal file
583
lib/win32comext/axdebug/gateways.py
Normal file
|
@ -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")
|
179
lib/win32comext/axdebug/stackframe.py
Normal file
179
lib/win32comext/axdebug/stackframe.py
Normal file
|
@ -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 + "<lambda>"
|
||||
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")
|
141
lib/win32comext/axdebug/util.py
Normal file
141
lib/win32comext/axdebug/util.py
Normal file
|
@ -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("<error>")
|
||||
|
||||
|
||||
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
|
19
lib/win32comext/axscript/Demos/client/asp/CreateObject.asp
Normal file
19
lib/win32comext/axscript/Demos/client/asp/CreateObject.asp
Normal file
|
@ -0,0 +1,19 @@
|
|||
<HTML>
|
||||
|
||||
<SCRIPT Language="Python" RUNAT=Server>
|
||||
|
||||
# Just for the sake of the demo, our Python script engine
|
||||
# will create a Python.Interpreter COM object, and call that.
|
||||
|
||||
# This is completely useless, as the Python Script Engine is
|
||||
# completely normal Python, and ASP does not impose retrictions, so
|
||||
# there is nothing the COM object can do that we can not do natively.
|
||||
|
||||
o = Server.CreateObject("Python.Interpreter")
|
||||
|
||||
Response.Write("Python says 1+1=" + str(o.Eval("1+1")))
|
||||
|
||||
</SCRIPT>
|
||||
|
||||
</HTML>
|
||||
|
52
lib/win32comext/axscript/Demos/client/asp/caps.asp
Normal file
52
lib/win32comext/axscript/Demos/client/asp/caps.asp
Normal file
|
@ -0,0 +1,52 @@
|
|||
<%@ Language=Python %>
|
||||
<HTML>
|
||||
|
||||
<HEAD>
|
||||
|
||||
<BODY BACKGROUND="/samples/images/backgrnd.gif">
|
||||
|
||||
<TITLE>Python test</TITLE>
|
||||
|
||||
</HEAD>
|
||||
|
||||
<BODY BGCOLOR="FFFFFF">
|
||||
|
||||
<SCRIPT Language="Python" RUNAT=Server>
|
||||
# NOTE that the <% tags below execute _before_ these tags!
|
||||
Response.Write("Hello from Python<P>")
|
||||
Response.Write("Browser is "+bc.browser)
|
||||
import win32api # Should be no problem using win32api in ASP pages.
|
||||
Response.Write("<p>Win32 username is "+win32api.GetUserName())
|
||||
</SCRIPT>
|
||||
|
||||
<BODY BGCOLOR="FFFFFF">
|
||||
|
||||
<%
|
||||
import sys
|
||||
print sys.path
|
||||
from win32com.axscript.asputil import *
|
||||
print "Hello"
|
||||
print "There"
|
||||
print "How are you"
|
||||
%>
|
||||
|
||||
<%bc = Server.CreateObject("MSWC.BrowserType")%>
|
||||
<BODY BGCOLOR="FFFFFF">
|
||||
<table border=1>
|
||||
<tr><td>Browser</td><td> <%=bc.browser %>
|
||||
<tr><td>Version</td><td> <%=bc.version %> </td></TR>
|
||||
<tr><td>Frames</td><td>
|
||||
<%Response.Write( iif(bc.frames, "TRUE", "FALSE")) %></td></TR>
|
||||
<tr><td>Tables</td><td>
|
||||
<%Response.Write( iif (bc.tables, "TRUE", "FALSE")) %></td></TR>
|
||||
<tr><td>BackgroundSounds</td><td>
|
||||
<%Response.Write( iif(bc.BackgroundSounds, "TRUE", "FALSE"))%></td></TR>
|
||||
<tr><td>VBScript</td><td>
|
||||
<%Response.Write( iif(bc.vbscript, "TRUE", "FALSE"))%></td></TR>
|
||||
<tr><td>JavaScript</td><td>
|
||||
<%Response.Write( iif(bc.javascript, "TRUE", "FALSE"))%></td></TR>
|
||||
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
<%@ language=python%>
|
||||
<html>
|
||||
<%Response.Redirect("test1.html")%>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<body>
|
||||
GOT There
|
||||
<script language=javascript>
|
||||
location.href ="http://192.168.0.1/Python/interrupt/test.asp"
|
||||
</script>
|
||||
</body>
|
||||
</head>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
<%@ language =Python%>
|
||||
<html>
|
||||
<head>
|
||||
<%Response.Redirect("test.html")%>
|
||||
</head>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<head>
|
||||
<body>
|
||||
GOT HERE
|
||||
<script language=javascript>
|
||||
location.href ="http://192.168.0.1/Python/interrupt/test1.asp"
|
||||
</script>
|
||||
</body>
|
||||
</head>
|
||||
</html>
|
||||
|
11
lib/win32comext/axscript/Demos/client/asp/tut1.asp
Normal file
11
lib/win32comext/axscript/Demos/client/asp/tut1.asp
Normal file
|
@ -0,0 +1,11 @@
|
|||
<HTML>
|
||||
|
||||
<SCRIPT Language="Python" RUNAT=Server>
|
||||
|
||||
for i in range(3,8):
|
||||
Response.Write("<FONT SIZE=%d>Hello World!!<BR>" % i)
|
||||
|
||||
</SCRIPT>
|
||||
|
||||
</HTML>
|
||||
|
25
lib/win32comext/axscript/Demos/client/ie/MarqueeText1.htm
Normal file
25
lib/win32comext/axscript/Demos/client/ie/MarqueeText1.htm
Normal file
|
@ -0,0 +1,25 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<base target="text">
|
||||
<TITLE> Internet Workshop </TITLE>
|
||||
</HEAD>
|
||||
<BODY leftmargin=8 bgcolor="#FFFFFF" VLINK="#666666" LINK="#FF0000">
|
||||
<FONT FACE="ARIAL,HELVETICA" SIZE="2">
|
||||
|
||||
<P>
|
||||
<BR>
|
||||
<P><FONT FACE="ARIAL,HELVETICA" SIZE="5"><B>Python AX Script Engine</B></FONT>
|
||||
<BR>Demo using the Marquee Control
|
||||
<BR>Mark Hammond.
|
||||
|
||||
<P>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!!!
|
||||
|
||||
<P>For more information on Python as an ActiveX scripting language, see
|
||||
|
||||
<P><B>Python</B>
|
||||
<BR><A HREF="http://www.python.org">http://www.python.org</A>
|
||||
|
||||
</FONT>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
116
lib/win32comext/axscript/Demos/client/ie/calc.htm
Normal file
116
lib/win32comext/axscript/Demos/client/ie/calc.htm
Normal file
|
@ -0,0 +1,116 @@
|
|||
<HTML>
|
||||
<HEAD><TITLE>Python Script sample: Calculator</TITLE></HEAD>
|
||||
<BODY><FONT FACE=ARIAL SIZE=3> <!-- global default -->
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
# globals
|
||||
Accum = 0.0 # Previous number (operand) awaiting operation
|
||||
FlagNewNum = 1 # Flag to indicate a new number (operand) is being entered
|
||||
NullOp = lambda x,y: y
|
||||
PendingOp = NullOp# Pending operation waiting for completion of second operand
|
||||
numberButNames = ['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine']
|
||||
|
||||
def NumPressed(Num):
|
||||
print "NumPressed", Num
|
||||
global FlagNewNum
|
||||
if FlagNewNum:
|
||||
ax.document.Keypad.ReadOut.Value = Num
|
||||
FlagNewNum = None
|
||||
else:
|
||||
if ax.document.Keypad.ReadOut.Value == "0":
|
||||
ax.document.Keypad.ReadOut.Value = str(Num)
|
||||
else:
|
||||
ax.document.Keypad.ReadOut.Value= ax.document.Keypad.ReadOut.Value + str(Num)
|
||||
|
||||
# Dynamically create handlers for all the decimal buttons.
|
||||
# (ie, this will dynamically create "One_OnClick()"... etc handlers
|
||||
for i in range(len(numberButNames)):
|
||||
exec "def %s_OnClick():\tNumPressed(%d)\n" % (numberButNames[i],i)
|
||||
|
||||
def Decimal_OnClick():
|
||||
global curReadOut, FlagNewNum
|
||||
curReadOut = ax.document.Keypad.ReadOut.Value
|
||||
if FlagNewNum:
|
||||
curReadOut = "0."
|
||||
FlagNewNum = None
|
||||
else:
|
||||
if not ("." in curReadOut):
|
||||
curReadOut = curReadOut + "."
|
||||
ax.document.Keypad.ReadOut.Value = curReadOut
|
||||
|
||||
import sys, string
|
||||
|
||||
def Operation(Op, fn):
|
||||
global FlagNewNum, PendingOp, Accum
|
||||
ReadOut = ax.document.Keypad.ReadOut.Value
|
||||
print "Operation", Op, ReadOut, PendingOp, Accum
|
||||
if FlagNewNum:
|
||||
# User is hitting op keys repeatedly, so don't do anything
|
||||
PendingOp = NullOp
|
||||
else:
|
||||
FlagNewNum = 1
|
||||
Accum = PendingOp( Accum, string.atof(ReadOut) )
|
||||
ax.document.Keypad.ReadOut.Value = str(Accum)
|
||||
PendingOp = fn
|
||||
|
||||
def ClearEntry_OnClick():
|
||||
# Remove current number and reset state
|
||||
global FlagNewNum
|
||||
ax.document.Keypad.ReadOut.Value = "0"
|
||||
FlagNewNum = 1
|
||||
|
||||
def Clear_OnClick():
|
||||
global Accum, PendingOp
|
||||
Accum = 0
|
||||
PendingOp = NullOp
|
||||
ClearEntry_OnClick()
|
||||
|
||||
def Neg_OnClick():
|
||||
ax.document.Keypad.ReadOut.Value = str(-string.atof(ax.document.Keypad.ReadOut.Value))
|
||||
</SCRIPT>
|
||||
|
||||
|
||||
<form action="" Name="Keypad">
|
||||
<TABLE>
|
||||
<B>
|
||||
<TABLE BORDER=2 WIDTH=50 HEIGHT=60 CELLPADDING=1 CELLSPACING=5>
|
||||
<CAPTION ALIGN=top> <b>Calculator</b><p> </CAPTION>
|
||||
<TR>
|
||||
<TD COLSPAN=3 ALIGN=MIDDLE><INPUT NAME="ReadOut" TYPE="Text" SIZE=24 VALUE="0" WIDTH=100%></TD>
|
||||
<TD></TD>
|
||||
<TD><INPUT NAME="Clear" TYPE="Button" VALUE=" C " ></TD>
|
||||
<TD><INPUT NAME="ClearEntry" TYPE="Button" VALUE=" CE " ></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD><INPUT NAME="Seven" TYPE="Button" VALUE=" 7 " ></TD>
|
||||
<TD><INPUT NAME="Eight" TYPE="Button" VALUE=" 8 " ></TD>
|
||||
<TD><INPUT NAME="Nine" TYPE="Button" VALUE=" 9 " ></TD>
|
||||
<TD></TD>
|
||||
<TD><INPUT NAME="Neg" TYPE="Button" VALUE=" +/- " ></TD>
|
||||
<TD><INPUT NAME="Percent" TYPE="Button" VALUE=" % " OnClick="Operation('%', lambda x,y: x*y/100.0)"></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><INPUT NAME="Four" TYPE="Button" VALUE=" 4 " ></TD>
|
||||
<TD><INPUT NAME="Five" TYPE="Button" VALUE=" 5 " ></TD>
|
||||
<TD><INPUT NAME="Six" TYPE="Button" VALUE=" 6 " ></TD>
|
||||
<TD></TD>
|
||||
<TD ALIGN=MIDDLE><INPUT NAME="Plus" TYPE="Button" VALUE=" + " OnClick="Operation('+', lambda x,y: x+y)"></TD>
|
||||
<TD ALIGN=MIDDLE><INPUT NAME="Minus" TYPE="Button" VALUE=" - " OnClick="Operation('-', lambda x,y: x-y)"></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD><INPUT NAME="One" TYPE="Button" VALUE=" 1 " ></TD>
|
||||
<TD><INPUT NAME="Two" TYPE="Button" VALUE=" 2 " ></TD>
|
||||
<TD><INPUT NAME="Three" TYPE="Button" VALUE=" 3 " ></TD>
|
||||
<TD></TD>
|
||||
<TD ALIGN=MIDDLE><INPUT NAME="Multiply" TYPE="Button" VALUE=" * " OnClick="Operation('*', lambda x,y: x*y)" ></TD>
|
||||
<TD ALIGN=MIDDLE><INPUT NAME="Divide" TYPE="Button" VALUE=" / " OnClick="Operation('/', lambda x,y: x/y)" ></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD><INPUT NAME="Zero" TYPE="Button" VALUE=" 0 " ></TD>
|
||||
<TD><INPUT NAME="Decimal" TYPE="Button" VALUE=" . " ></TD>
|
||||
<TD COLSPAN=3></TD>
|
||||
<TD><INPUT NAME="Equals" TYPE="Button" VALUE=" = " OnClick="Operation('=', lambda x,y: x)"></TD>
|
||||
</TR></TABLE></TABLE></B>
|
||||
</FORM>
|
||||
</FONT></BODY></HTML>
|
||||
|
16
lib/win32comext/axscript/Demos/client/ie/dbgtest.htm
Normal file
16
lib/win32comext/axscript/Demos/client/ie/dbgtest.htm
Normal file
|
@ -0,0 +1,16 @@
|
|||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<SCRIPT>
|
||||
b="Hello There, how are you"
|
||||
</SCRIPT>
|
||||
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
print "Hello"
|
||||
a="Hi there"
|
||||
document.write("Hello<P>")
|
||||
alert("Hi there")
|
||||
</SCRIPT>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
26
lib/win32comext/axscript/Demos/client/ie/demo.htm
Normal file
26
lib/win32comext/axscript/Demos/client/ie/demo.htm
Normal file
|
@ -0,0 +1,26 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Python AXScript Demos</TITLE>
|
||||
</HEAD>
|
||||
|
||||
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
def Window_OnLoad():
|
||||
pass
|
||||
# import win32traceutil
|
||||
# print "Frames are", ax.window.frames._print_details_()
|
||||
# print "Frame 0 href = ", ax.frames.Item(0).location.href
|
||||
|
||||
def Name_OnLoad():
|
||||
print "Frame loading"
|
||||
|
||||
</SCRIPT>
|
||||
|
||||
<FRAMESET FRAMEBORDER=1 COLS = "250, *">
|
||||
<FRAME SRC="demo_menu.htm">
|
||||
<FRAME SRC="demo_check.htm" NAME="Body">
|
||||
</FRAMESET>
|
||||
|
||||
|
||||
</HTML>
|
||||
|
42
lib/win32comext/axscript/Demos/client/ie/demo_check.htm
Normal file
42
lib/win32comext/axscript/Demos/client/ie/demo_check.htm
Normal file
|
@ -0,0 +1,42 @@
|
|||
<HTML>
|
||||
<H1>Engine Registration</H1>
|
||||
|
||||
<BODY>
|
||||
|
||||
<p>The Python ActiveX Scripting Engine is not currently registered.<p>
|
||||
|
||||
<p>Due to a <a href="http://starship.python.net/crew/mhammond/win32/PrivacyProblem.html">privacy
|
||||
concern</a> discovered in the engine, the use of Python inside IE has been disabled.</p>
|
||||
|
||||
Before any of the supplied demos will work, the engine must be successfully registered.
|
||||
|
||||
<P>To install a version of the engine, that does work with IE, you can execute the Python program
|
||||
<CODE>win32com\axscript\client\pyscript_rexec.py</CODE> must be run. You can either do this manually, or follow the instructions below.</p>
|
||||
|
||||
<H2>Register the engine now!</H2>
|
||||
|
||||
<p>If you have read about the <a href="http://starship.python.net/crew/mhammond/win32/PrivacyProblem.html">privacy
|
||||
concern</a> and still wish to register the engine, just follow the process outlined below:</p>
|
||||
<OL>
|
||||
<LI>Click on the link below
|
||||
<LI><B>A dialog will be presented asking if the file should be opened or saved to disk. Select "Open it".</B>
|
||||
<LI>A Console program will briefly open, while the server is registered.
|
||||
</OL>
|
||||
|
||||
<P><A HREF="..\..\..\client\pyscript_rexec.py">Register the engine now</A>
|
||||
|
||||
<H2>Checking the registration</H2>
|
||||
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.
|
||||
|
||||
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
try:
|
||||
window.open("demo_intro.htm", "Body")
|
||||
except:
|
||||
history.back()
|
||||
</SCRIPT>
|
||||
</BODY></HTML>
|
||||
|
||||
|
||||
|
38
lib/win32comext/axscript/Demos/client/ie/demo_intro.htm
Normal file
38
lib/win32comext/axscript/Demos/client/ie/demo_intro.htm
Normal file
|
@ -0,0 +1,38 @@
|
|||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<H1>
|
||||
<MARQUEE NAME="Marquee1" DIRECTION=LEFT BEHAVIOR=SCROLL SCROLLAMOUNT=10 SCROLLDELAY=200
|
||||
>Python ActiveX Scripting Demonstation
|
||||
</MARQUEE>
|
||||
</H1>
|
||||
|
||||
<p>Congratulations on installing the Python ActiveX Scripting Engine</p>
|
||||
|
||||
<p>Be warned that there is a <a href="http://starship.python.net/crew/mhammond/win32/PrivacyProblem.html">privacy
|
||||
concern</a> with this engine. Please read this information, including how to disable the feature.</p>
|
||||
|
||||
|
||||
<H3>Object model</H3>
|
||||
<P>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".
|
||||
|
||||
<P>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 <code>text="Hi there"</code>, but in Python, you must code
|
||||
<code>MyForm.ThisButton.Text="Hi There"</code>. See the <A HREF="foo2.htm">foo2</A> sample
|
||||
for futher details.
|
||||
|
||||
<H3>Known bugs and problems</H3>
|
||||
<UL>
|
||||
<LI><P>This release seems to have broken Aaron's mouse-trace sample. No idea why, and Im supposed to be looking into it.
|
||||
<LI><P>Builtin objects such as MARQUEE are giving me grief. Objects accessed via forms are generally
|
||||
no problem.
|
||||
<LI><P>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.
|
||||
</UL>
|
||||
|
||||
</BODY></HTML>
|
||||
|
16
lib/win32comext/axscript/Demos/client/ie/demo_menu.htm
Normal file
16
lib/win32comext/axscript/Demos/client/ie/demo_menu.htm
Normal file
|
@ -0,0 +1,16 @@
|
|||
<HTML>
|
||||
<BODY>
|
||||
<H1>Scripting Demos</H1>
|
||||
<P>An <A HREF="demo_check.htm" TARGET=Body>Introduction</A> to the
|
||||
scripting engine.
|
||||
|
||||
<P>The <A HREF="calc.htm" TARGET=Body>Calculator Demo</A> is a very
|
||||
cool sample written by Aaron Watters.
|
||||
|
||||
<P><A HREF="mouseTrack.htm" TARGET=Body>Mouse track</A> is another of
|
||||
Aaron's samples, and shows how fast the Python engine is!
|
||||
|
||||
<P>The <A HREF="foo2.htm" TARGET=Body>foo2 sample</A> is mainly used
|
||||
for debugging and testing, but does show some forms in action.
|
||||
|
||||
|
25
lib/win32comext/axscript/Demos/client/ie/docwrite.htm
Normal file
25
lib/win32comext/axscript/Demos/client/ie/docwrite.htm
Normal file
|
@ -0,0 +1,25 @@
|
|||
<HTML>
|
||||
<BODY>
|
||||
A page generated by Python
|
||||
|
||||
<SCRIPT LANGUAGE="XXXVBScript">
|
||||
document.open()
|
||||
document.writeLn "<P>Hello from VBScript"
|
||||
document.close()
|
||||
</SCRIPT>
|
||||
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
ax.document.write("<P>Hello from Python")
|
||||
ax.document.close()
|
||||
ax.document.open()
|
||||
ax.document.write("<P>Hello again from Python")
|
||||
ax.document.close()
|
||||
|
||||
def Window_OnLoad():
|
||||
pass
|
||||
# ax.document.write("<P>Hello from Load from Python")
|
||||
# ax.document.close()
|
||||
</SCRIPT>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
105
lib/win32comext/axscript/Demos/client/ie/foo2.htm
Normal file
105
lib/win32comext/axscript/Demos/client/ie/foo2.htm
Normal file
|
@ -0,0 +1,105 @@
|
|||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<SCRIPT>
|
||||
b="Hello"
|
||||
</SCRIPT>
|
||||
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
import win32traceutil
|
||||
import sys
|
||||
print "Hello"
|
||||
a="Hi there"
|
||||
print "Location is", document.location
|
||||
document.write("Hello", " from version ", 2, " of the Python AXScript Engine","<P>")
|
||||
document.writeln("This is Python", sys.version)
|
||||
|
||||
</SCRIPT>
|
||||
|
||||
<P>The caption on the first button is set by the Window Load code. Clicking
|
||||
that button changes the text in the first edit box.
|
||||
|
||||
<P>The second button changes its own text when clicked.
|
||||
|
||||
<P>The fourth button calls a global function, defined in the global 'script' scope,
|
||||
rather than the 'MyForm' scope.
|
||||
|
||||
<FORM NAME="MyForm" METHOD="GET">
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
print "Hello from in the form"
|
||||
</SCRIPT>
|
||||
<INPUT NAME="Button1" TYPE="Button" OnClick="MyForm.Text1.value='Hi'" LANGUAGE="Python">
|
||||
<INPUT TYPE="TEXT" SIZE=25 NAME="Text1">
|
||||
<INPUT NAME="Button2" TYPE="Button" VALUE="Click for 'Hi'" OnClick="a='Howdy'; MyForm.Button2.value='Hi'" LANGUAGE="Python">
|
||||
<INPUT NAME="Button3" TYPE="Button" VALUE="Click for URL" OnClick="MyForm.Text2.value=document.location" LANGUAGE="Python">
|
||||
<INPUT TYPE="TEXT" SIZE=25 NAME="Text2">
|
||||
<INPUT NAME="Button4" TYPE="Button" VALUE="Call global fn" OnClick="foo1()" LANGUAGE="Python">
|
||||
<INPUT NAME="Button5" TYPE="Button" VALUE="Script for... Test">
|
||||
<script for="Button5" event="onClick" language="Python">
|
||||
print "HelloThere";
|
||||
window.alert("Hello")
|
||||
def ATest():
|
||||
print "Hello from ATEst"
|
||||
|
||||
ATest()
|
||||
</script>
|
||||
<INPUT NAME="Button6" TYPE="Button" VALUE="Set Other" OnClick="Form2.Text1.Value='Hi from other'" LANGUAGE="Python">
|
||||
|
||||
</FORM><BR>
|
||||
<P>
|
||||
And here is a second form
|
||||
<P>
|
||||
<FORM NAME="Form2" METHOD="GET">
|
||||
<INPUT NAME="Button1" TYPE="Button" OnClick="Form2.Text1.Value='Hi'" LANGUAGE="Python">
|
||||
<INPUT NAME="Button2" TYPE="Button" VALUE="Set Other" OnClick="MyForm.Text1.Value='Hi from other'" LANGUAGE="Python">
|
||||
<INPUT TYPE="TEXT" SIZE=25 NAME="Text1">
|
||||
<INPUT NAME="ButRExec" TYPE="Button" VALUE="RExec fail" OnClick="import win32api;win32api.MessageBox(0,'Oops')" LANGUAGE="Python">
|
||||
<INPUT NAME="ButRExec2" TYPE="Button" VALUE="RExec fail 2" OnClick="import sys,win32traceutil;print sys.modules;from win32com.client import dynamic;import win32com.client.dynamic, pythoncom, win32com.client;o=win32com.client.Dispatch('Word.Application')" LANGUAGE="Python">
|
||||
<INPUT NAME="ButVB" TYPE="Button" VALUE="VBScript Button" OnClick='alert("Hi from VBScript")'>
|
||||
<INPUT NAME="ButCallChain" TYPE="Button" VALUE="Multi-Language call" OnClick='CallPython()'>
|
||||
</FORM><BR>
|
||||
|
||||
<SCRIPT LANGUAGE="VBScript">
|
||||
function CallPython()
|
||||
alert("Hello from VB - Im about to call Python!")
|
||||
PythonGlobalFunction()
|
||||
end function
|
||||
</SCRIPT>
|
||||
|
||||
<SCRIPT LANGUAGE="JScript">
|
||||
function JScriptFunction()
|
||||
{
|
||||
alert("Hello from JScript");
|
||||
}
|
||||
</SCRIPT>
|
||||
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
x=13
|
||||
|
||||
def foo1():
|
||||
y = 14
|
||||
for name, item in globals().items():
|
||||
print name, `item`
|
||||
alert ("Hello from AXCode")
|
||||
print "Y is ",y
|
||||
|
||||
def PythonGlobalFunction():
|
||||
window.alert("Hello from Python - Im about to call JScript!")
|
||||
window.JScriptFunction()
|
||||
|
||||
def Window_OnLoad():
|
||||
print "X is", x
|
||||
print "a is", a
|
||||
# print "------ GLOBALS ----------"
|
||||
# for n,v in globals().items():
|
||||
# print n,'=',v
|
||||
print "MyForm is", MyForm
|
||||
print "MyForm is repr", `MyForm`
|
||||
print "MyForm.Button1 is", `MyForm.Button1`
|
||||
MyForm.Button1.Value = "Python Rules!"
|
||||
Form2.Button1.value = "Form2!"
|
||||
MyForm.Text1.value = document.location
|
||||
</SCRIPT>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
25
lib/win32comext/axscript/Demos/client/ie/form.htm
Normal file
25
lib/win32comext/axscript/Demos/client/ie/form.htm
Normal file
|
@ -0,0 +1,25 @@
|
|||
<HTML>
|
||||
<BODY>
|
||||
|
||||
<FORM NAME="TestForm" METHOD="POST" >
|
||||
<INPUT TYPE="TEXT" SIZE=25 NAME="Name">Name<br>
|
||||
<INPUT TYPE="TEXT" SIZE=25 NAME="Address">Address<br>
|
||||
<INPUT TYPE=SUBMIT
|
||||
</FORM>
|
||||
|
||||
<SCRIPT LANGUAGE="Python" for="TestForm" Event="onSubmit">
|
||||
return Validate()
|
||||
</SCRIPT>
|
||||
|
||||
<SCRIPT LANGUAGE="Python">
|
||||
|
||||
def Validate():
|
||||
if not TestForm.Name.Value or not TestForm.Address.Value:
|
||||
ax.alert("You must enter a name and address.")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
</SCRIPT>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
60
lib/win32comext/axscript/Demos/client/ie/marqueeDemo.htm
Normal file
60
lib/win32comext/axscript/Demos/client/ie/marqueeDemo.htm
Normal file
|
@ -0,0 +1,60 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<base target="text">
|
||||
<TITLE> Internet Workshop </TITLE>
|
||||
</HEAD>
|
||||
<BODY leftmargin=8 bgcolor="#FFFFFF" VLINK="#666666" LINK="#FF0000">
|
||||
<FONT FACE="ARIAL,HELVETICA" SIZE="2">
|
||||
|
||||
<P>
|
||||
<BR>
|
||||
<P><FONT FACE="ARIAL,HELVETICA" SIZE="5"><B>Marquee Demo</B></FONT>
|
||||
|
||||
<P>
|
||||
|
||||
|
||||
<OBJECT
|
||||
ID="Marquee1"
|
||||
CLASSID="CLSID:1A4DA620-6217-11CF-BE62-0080C72EDD2D"
|
||||
CODEBASE="/workshop/activex/gallery/ms/marquee/other/marquee.ocx#Version=4,70,0,1112"
|
||||
TYPE="application/x-oleobject"
|
||||
WIDTH=100%
|
||||
HEIGHT=80
|
||||
>
|
||||
<PARAM NAME="szURL" VALUE="marqueeText1.htm">
|
||||
<PARAM NAME="ScrollPixelsX" VALUE="0">
|
||||
<PARAM NAME="ScrollPixelsY" VALUE="-5">
|
||||
<PARAM NAME="ScrollDelay" VALUE="100">
|
||||
<PARAM NAME="Whitespace" VALUE="0">
|
||||
</OBJECT>
|
||||
|
||||
<br> <br>
|
||||
|
||||
<INPUT TYPE="Button" NAME="btnFaster" VALUE="Faster">
|
||||
<INPUT TYPE="Button" NAME="btnNormal" VALUE="Normal">
|
||||
<INPUT TYPE="Button" NAME="btnSlower" VALUE="Slower">
|
||||
|
||||
<SCRIPT Language="Python">
|
||||
|
||||
def btnFaster_Onclick():
|
||||
ax.Marquee1.ScrollDelay = 0
|
||||
|
||||
def btnNormal_Onclick():
|
||||
ax.Marquee1.ScrollDelay = 50
|
||||
|
||||
def btnSlower_Onclick():
|
||||
ax.Marquee1.ScrollDelay = 300
|
||||
|
||||
</SCRIPT>
|
||||
|
||||
|
||||
<P>
|
||||
<HR>
|
||||
<B>Notes:</B>
|
||||
<P>
|
||||
|
||||
|
||||
</FONT>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
83
lib/win32comext/axscript/Demos/client/ie/mousetrack.htm
Normal file
83
lib/win32comext/axscript/Demos/client/ie/mousetrack.htm
Normal file
|
@ -0,0 +1,83 @@
|
|||
<HTML>
|
||||
|
||||
<HEAD><TITLE>Python Scripting sample: Mouse tracking</TITLE></HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF" TOPMARGIN=8>
|
||||
<FONT SIZE=5>
|
||||
<TABLE Border=0><TR VALIGN=MIDDLE><TD>
|
||||
<A ID="Image"> <IMG
|
||||
SRC="file:..\..\..\..\..\win32com\html\image\pycom_blowing.gif"
|
||||
ALT="Clickable Map Image" HEIGHT=113 WIDTH=624 BORDER=0></A>
|
||||
|
||||
</TD></TR>
|
||||
<TR><TD> </TD></TR>
|
||||
<TR VALIGN=MIDDLE><TD VALIGN=MIDDLE ALIGN=CENTER><FONT SIZE=5><INPUT
|
||||
TYPE="text" NAME="TxtLinkDescription" SIZE=50></FONT></TD></TR></TABLE>
|
||||
</FONT>
|
||||
|
||||
<P>
|
||||
A mouse tracking demo. Move the mouse over the image above...
|
||||
|
||||
<SCRIPT Language="Python">
|
||||
<!--
|
||||
# Remember the last location clicked
|
||||
#print "here we go", 1
|
||||
mx = my = 0
|
||||
|
||||
# class for rectangle testing
|
||||
class rect:
|
||||
def __init__(self, lowx, lowy, upx, upy, desc, url):
|
||||
self.lowx, self.lowy, self.upx, self.upy, self.desc, self.url = \
|
||||
lowx, lowy, upx, upy, desc, url
|
||||
def inside(self, x, y):
|
||||
# print (x,y), "inside", self.desc,
|
||||
result = self.lowx <= x <= self.upx and self.lowy <= y <= self.upy
|
||||
# print result
|
||||
return result
|
||||
def mouse_move(self):
|
||||
# print "move", self.desc
|
||||
ax.TxtLinkDescription.Value = coords + " - " + self.desc
|
||||
def onclick(self):
|
||||
# print "click", self.desc
|
||||
ax.TxtLinkDescription.Value = coords +" click! " + `self.url`
|
||||
if self.url: ax.location = self.url
|
||||
|
||||
blows = "Blows away "
|
||||
rects =[rect(12,48,59,101,blows+"Visual Basic", ""),
|
||||
rect(107,0,172,58,blows+"Internet Explorer", ""),
|
||||
rect(193,0,261,56,blows+"Microsoft Access", ""),
|
||||
rect(332,43,392,93,blows+"Microsoft Word", ""),
|
||||
rect(457,52,521,99,blows+"Microsoft Excel", ""),
|
||||
rect(537,12,613,85,"Python blows them all away!", "http://www.python.org"),
|
||||
]
|
||||
|
||||
default = rect(0,0,0,0,"Click on an icon","")
|
||||
|
||||
def Image_MouseMove(s, b, x, y):
|
||||
global mx, my, coords
|
||||
coords =`(x,y)`
|
||||
# print coords,
|
||||
mx, my = x, y
|
||||
for r in rects:
|
||||
if r.inside(x,y):
|
||||
# print r.desc
|
||||
r.mouse_move()
|
||||
break
|
||||
else:
|
||||
# print default.desc
|
||||
default.mouse_move()
|
||||
|
||||
def Image_OnClick():
|
||||
for r in rects:
|
||||
if r.inside(mx,my):
|
||||
r.onclick()
|
||||
break
|
||||
-->
|
||||
</SCRIPT>
|
||||
|
||||
<P>
|
||||
|
||||
</FONT>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
BIN
lib/win32comext/axscript/Demos/client/ie/pycom_blowing.gif
Normal file
BIN
lib/win32comext/axscript/Demos/client/ie/pycom_blowing.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
0
lib/win32comext/axscript/Demos/client/wsh/blank.pys
Normal file
0
lib/win32comext/axscript/Demos/client/wsh/blank.pys
Normal file
34
lib/win32comext/axscript/Demos/client/wsh/excel.pys
Normal file
34
lib/win32comext/axscript/Demos/client/wsh/excel.pys
Normal file
|
@ -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))
|
||||
|
||||
|
45
lib/win32comext/axscript/Demos/client/wsh/registry.pys
Normal file
45
lib/win32comext/axscript/Demos/client/wsh/registry.pys
Normal file
|
@ -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")
|
||||
|
15
lib/win32comext/axscript/Demos/client/wsh/test.pys
Normal file
15
lib/win32comext/axscript/Demos/client/wsh/test.pys
Normal file
|
@ -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
|
||||
|
4
lib/win32comext/axscript/__init__.py
Normal file
4
lib/win32comext/axscript/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
# See if we have a special directory for the binaries (for developers)
|
||||
import win32com
|
||||
|
||||
win32com.__PackageSupportBuildPath__(__path__)
|
13
lib/win32comext/axscript/asputil.py
Normal file
13
lib/win32comext/axscript/asputil.py
Normal file
|
@ -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
|
BIN
lib/win32comext/axscript/axscript.pyd
Normal file
BIN
lib/win32comext/axscript/axscript.pyd
Normal file
Binary file not shown.
1
lib/win32comext/axscript/client/__init__.py
Normal file
1
lib/win32comext/axscript/client/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
# This is a Python package
|
240
lib/win32comext/axscript/client/debug.py
Normal file
240
lib/win32comext/axscript/client/debug.py
Normal file
|
@ -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, "<Temp Code Block>")
|
||||
return container.GetSyntaxColorAttributes()
|
||||
|
||||
def GetScriptletTextAttributes(self, code, delim, flags):
|
||||
trace("GetScriptletTextAttributes", code, delim, flags)
|
||||
container = SourceCodeContainer(code, "<Temp Code Block>")
|
||||
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)
|
273
lib/win32comext/axscript/client/error.py
Normal file
273
lib/win32comext/axscript/client/error.py
Normal file
|
@ -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 "<Script..>"
|
||||
# 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] == "<Script":
|
||||
break
|
||||
tb_top = tb_top.tb_next
|
||||
format_items = []
|
||||
if tb_top: # found one.
|
||||
depth = 0
|
||||
tb_look = tb_top
|
||||
# Look down for our bottom
|
||||
while tb_look:
|
||||
filename, lineno, name, line = self.ExtractTracebackInfo(tb_look, site)
|
||||
if name in hide_names:
|
||||
break
|
||||
# We can report a line-number, but not a filename. Therefore,
|
||||
# we return the last line-number we find in one of our script
|
||||
# blocks.
|
||||
if filename.startswith("<Script"):
|
||||
self.lineno = lineno
|
||||
self.linetext = line
|
||||
format_items.append((filename, lineno, name, line))
|
||||
depth = depth + 1
|
||||
tb_look = tb_look.tb_next
|
||||
else:
|
||||
depth = None
|
||||
tb_top = tb
|
||||
|
||||
bits = ["Traceback (most recent call last):\n"]
|
||||
bits.extend(traceback.format_list(format_items))
|
||||
if exc_type == pythoncom.com_error:
|
||||
desc = "%s (0x%x)" % (value.strerror, value.hresult)
|
||||
if (
|
||||
value.hresult == winerror.DISP_E_EXCEPTION
|
||||
and value.excepinfo
|
||||
and value.excepinfo[2]
|
||||
):
|
||||
desc = value.excepinfo[2]
|
||||
bits.append("COM Error: " + desc)
|
||||
else:
|
||||
bits.extend(traceback.format_exception_only(exc_type, value))
|
||||
|
||||
# XXX - this utf8 encoding seems bogus. From well before py3k,
|
||||
# we had the comment:
|
||||
# > 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
|
1270
lib/win32comext/axscript/client/framework.py
Normal file
1270
lib/win32comext/axscript/client/framework.py
Normal file
File diff suppressed because it is too large
Load diff
77
lib/win32comext/axscript/client/pydumper.py
Normal file
77
lib/win32comext/axscript/client/pydumper.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
# pydumper.py
|
||||
#
|
||||
# This is being worked on - it does not yet work at all, in ay way
|
||||
# shape or form :-)
|
||||
#
|
||||
# A new script engine, derived from the standard scripting engine,
|
||||
# which dumps information.
|
||||
|
||||
# This generally can be used to grab all sorts of useful details about
|
||||
# an engine - expose bugs in it or Python, dump the object model, etc.
|
||||
|
||||
# As it is derived from the standard engine, it fully supports Python
|
||||
# as a scripting language - meaning the dumps produced can be quite dynamic,
|
||||
# and based on the script code you execute.
|
||||
|
||||
from win32com.axscript import axscript
|
||||
|
||||
from . import pyscript
|
||||
from .pyscript import SCRIPTTEXT_FORCEEXECUTION, Exception, RaiseAssert, trace
|
||||
|
||||
PyDump_CLSID = "{ac527e60-c693-11d0-9c25-00aa00125a98}"
|
||||
|
||||
|
||||
class AXScriptAttribute(pyscript.AXScriptAttribute):
|
||||
pass
|
||||
|
||||
|
||||
class NamedScriptAttribute(pyscript.NamedScriptAttribute):
|
||||
pass
|
||||
|
||||
|
||||
class PyScript(pyscript.PyScript):
|
||||
pass
|
||||
|
||||
|
||||
def Register():
|
||||
import sys
|
||||
|
||||
if "-d" in sys.argv:
|
||||
dispatcher = "DispatcherWin32trace"
|
||||
debug_desc = " (" + dispatcher + ")"
|
||||
debug_option = "Yes"
|
||||
else:
|
||||
dispatcher = None
|
||||
debug_desc = ""
|
||||
debug_option = ""
|
||||
|
||||
categories = [axscript.CATID_ActiveScript, axscript.CATID_ActiveScriptParse]
|
||||
clsid = PyDump_CLSID
|
||||
lcid = 0x0409 # // english
|
||||
policy = None # "win32com.axscript.client.axspolicy.AXScriptPolicy"
|
||||
|
||||
print("Registering COM server%s..." % debug_desc)
|
||||
from win32com.server.register import RegisterServer
|
||||
|
||||
languageName = "PyDump"
|
||||
verProgId = "Python.Dumper.1"
|
||||
RegisterServer(
|
||||
clsid=clsid,
|
||||
pythonInstString="win32com.axscript.client.pyscript.PyDumper",
|
||||
className="Python Debugging/Dumping ActiveX Scripting Engine",
|
||||
progID=languageName,
|
||||
verProgID=verProgId,
|
||||
catids=categories,
|
||||
policy=policy,
|
||||
dispatcher=dispatcher,
|
||||
)
|
||||
|
||||
CreateRegKey(languageName + "\\OLEScript")
|
||||
# Basic Registration for wsh.
|
||||
win32com.server.register._set_string(".pysDump", "pysDumpFile")
|
||||
win32com.server.register._set_string("pysDumpFile\\ScriptEngine", languageName)
|
||||
print("Dumping Server registered.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Register()
|
443
lib/win32comext/axscript/client/pyscript.py
Normal file
443
lib/win32comext/axscript/client/pyscript.py
Normal file
|
@ -0,0 +1,443 @@
|
|||
"""Python ActiveX Scripting Implementation
|
||||
|
||||
This module implements the Python ActiveX Scripting client.
|
||||
|
||||
To register the implementation, simply "run" this Python program - ie
|
||||
either double-click on it, or run "python.exe pyscript.py" from the
|
||||
command line.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
import pythoncom
|
||||
import win32api
|
||||
import win32com
|
||||
import win32com.client.dynamic
|
||||
import win32com.server.register
|
||||
import winerror
|
||||
from win32com.axscript import axscript
|
||||
from win32com.axscript.client import framework, scriptdispatch
|
||||
from win32com.axscript.client.framework import (
|
||||
SCRIPTTEXT_FORCEEXECUTION,
|
||||
SCRIPTTEXT_ISEXPRESSION,
|
||||
SCRIPTTEXT_ISPERSISTENT,
|
||||
Exception,
|
||||
RaiseAssert,
|
||||
trace,
|
||||
)
|
||||
|
||||
PyScript_CLSID = "{DF630910-1C1D-11d0-AE36-8C0F5E000000}"
|
||||
|
||||
debugging_attr = 0
|
||||
|
||||
|
||||
def debug_attr_print(*args):
|
||||
if debugging_attr:
|
||||
trace(*args)
|
||||
|
||||
|
||||
def ExpandTabs(text):
|
||||
return re.sub("\t", " ", text)
|
||||
|
||||
|
||||
def AddCR(text):
|
||||
return re.sub("\n", "\r\n", text)
|
||||
|
||||
|
||||
class AXScriptCodeBlock(framework.AXScriptCodeBlock):
|
||||
def GetDisplayName(self):
|
||||
return "PyScript - " + framework.AXScriptCodeBlock.GetDisplayName(self)
|
||||
|
||||
|
||||
# There is only ever _one_ ax object - it exists in the global namespace
|
||||
# for all script items.
|
||||
# It performs a search from all global/visible objects
|
||||
# down.
|
||||
# This means that if 2 sub-objects of the same name are used
|
||||
# then only one is ever reachable using the ax shortcut.
|
||||
class AXScriptAttribute:
|
||||
"An attribute in a scripts namespace."
|
||||
|
||||
def __init__(self, engine):
|
||||
self.__dict__["_scriptEngine_"] = engine
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr[1] == "_" and attr[:-1] == "_":
|
||||
raise AttributeError(attr)
|
||||
rc = self._FindAttribute_(attr)
|
||||
if rc is None:
|
||||
raise AttributeError(attr)
|
||||
return rc
|
||||
|
||||
def _Close_(self):
|
||||
self.__dict__["_scriptEngine_"] = None
|
||||
|
||||
def _DoFindAttribute_(self, obj, attr):
|
||||
try:
|
||||
return obj.subItems[attr.lower()].attributeObject
|
||||
except KeyError:
|
||||
pass
|
||||
# Check out the sub-items
|
||||
for item in obj.subItems.values():
|
||||
try:
|
||||
return self._DoFindAttribute_(item, attr)
|
||||
except AttributeError:
|
||||
pass
|
||||
raise AttributeError(attr)
|
||||
|
||||
def _FindAttribute_(self, attr):
|
||||
for item in self._scriptEngine_.subItems.values():
|
||||
try:
|
||||
return self._DoFindAttribute_(item, attr)
|
||||
except AttributeError:
|
||||
pass
|
||||
# All else fails, see if it is a global
|
||||
# (mainly b/w compat)
|
||||
return getattr(self._scriptEngine_.globalNameSpaceModule, attr)
|
||||
|
||||
|
||||
# raise AttributeError(attr)
|
||||
|
||||
|
||||
class NamedScriptAttribute:
|
||||
"An explicitely named object in an objects namespace"
|
||||
|
||||
# Each named object holds a reference to one of these.
|
||||
# Whenever a sub-item appears in a namespace, it is really one of these
|
||||
# objects. Has a circular reference back to the item itself, which is
|
||||
# closed via _Close_()
|
||||
def __init__(self, scriptItem):
|
||||
self.__dict__["_scriptItem_"] = scriptItem
|
||||
|
||||
def __repr__(self):
|
||||
return "<NamedItemAttribute" + repr(self._scriptItem_) + ">"
|
||||
|
||||
def __getattr__(self, attr):
|
||||
# If a known subitem, return it.
|
||||
try:
|
||||
return self._scriptItem_.subItems[attr.lower()].attributeObject
|
||||
except KeyError:
|
||||
# Otherwise see if the dispatch can give it to us
|
||||
if self._scriptItem_.dispatchContainer:
|
||||
return getattr(self._scriptItem_.dispatchContainer, attr)
|
||||
raise AttributeError(attr)
|
||||
|
||||
def __setattr__(self, attr, value):
|
||||
# XXX - todo - if a known item, then should call its default
|
||||
# dispatch method.
|
||||
attr = attr.lower()
|
||||
if self._scriptItem_.dispatchContainer:
|
||||
try:
|
||||
return setattr(self._scriptItem_.dispatchContainer, attr, value)
|
||||
except AttributeError:
|
||||
pass
|
||||
raise AttributeError(attr)
|
||||
|
||||
def _Close_(self):
|
||||
self.__dict__["_scriptItem_"] = None
|
||||
|
||||
|
||||
class ScriptItem(framework.ScriptItem):
|
||||
def __init__(self, parentItem, name, dispatch, flags):
|
||||
framework.ScriptItem.__init__(self, parentItem, name, dispatch, flags)
|
||||
self.scriptlets = {}
|
||||
self.attributeObject = None
|
||||
|
||||
def Reset(self):
|
||||
framework.ScriptItem.Reset(self)
|
||||
if self.attributeObject:
|
||||
self.attributeObject._Close_()
|
||||
self.attributeObject = None
|
||||
|
||||
def Close(self):
|
||||
framework.ScriptItem.Close(self) # calls reset.
|
||||
self.dispatchContainer = None
|
||||
self.scriptlets = {}
|
||||
|
||||
def Register(self):
|
||||
framework.ScriptItem.Register(self)
|
||||
self.attributeObject = NamedScriptAttribute(self)
|
||||
if self.dispatch:
|
||||
# Need to avoid the new Python "lazy" dispatch behaviour.
|
||||
try:
|
||||
engine = self.GetEngine()
|
||||
olerepr = clsid = None
|
||||
typeinfo = self.dispatch.GetTypeInfo()
|
||||
clsid = typeinfo.GetTypeAttr()[0]
|
||||
try:
|
||||
olerepr = engine.mapKnownCOMTypes[clsid]
|
||||
except KeyError:
|
||||
pass
|
||||
except pythoncom.com_error:
|
||||
typeinfo = None
|
||||
if olerepr is None:
|
||||
olerepr = win32com.client.dynamic.MakeOleRepr(
|
||||
self.dispatch, typeinfo, None
|
||||
)
|
||||
if clsid is not None:
|
||||
engine.mapKnownCOMTypes[clsid] = olerepr
|
||||
self.dispatchContainer = win32com.client.dynamic.CDispatch(
|
||||
self.dispatch, olerepr, self.name
|
||||
)
|
||||
|
||||
|
||||
# self.dispatchContainer = win32com.client.dynamic.Dispatch(self.dispatch, userName = self.name)
|
||||
# self.dispatchContainer = win32com.client.dynamic.DumbDispatch(self.dispatch, userName = self.name)
|
||||
|
||||
# def Connect(self):
|
||||
# framework.ScriptItem.Connect(self)
|
||||
# def Disconnect(self):
|
||||
# framework.ScriptItem.Disconnect(self)
|
||||
|
||||
|
||||
class PyScript(framework.COMScript):
|
||||
# Setup the auto-registration stuff...
|
||||
_reg_verprogid_ = "Python.AXScript.2"
|
||||
_reg_progid_ = "Python"
|
||||
# _reg_policy_spec_ = default
|
||||
_reg_catids_ = [axscript.CATID_ActiveScript, axscript.CATID_ActiveScriptParse]
|
||||
_reg_desc_ = "Python ActiveX Scripting Engine"
|
||||
_reg_clsid_ = PyScript_CLSID
|
||||
_reg_class_spec_ = "win32com.axscript.client.pyscript.PyScript"
|
||||
_reg_remove_keys_ = [(".pys",), ("pysFile",)]
|
||||
_reg_threading_ = "both"
|
||||
|
||||
def __init__(self):
|
||||
framework.COMScript.__init__(self)
|
||||
self.globalNameSpaceModule = None
|
||||
self.codeBlocks = []
|
||||
self.scriptDispatch = None
|
||||
|
||||
def InitNew(self):
|
||||
framework.COMScript.InitNew(self)
|
||||
import imp
|
||||
|
||||
self.scriptDispatch = None
|
||||
self.globalNameSpaceModule = imp.new_module("__ax_main__")
|
||||
self.globalNameSpaceModule.__dict__["ax"] = AXScriptAttribute(self)
|
||||
|
||||
self.codeBlocks = []
|
||||
self.persistedCodeBlocks = []
|
||||
self.mapKnownCOMTypes = {} # Map of known CLSID to typereprs
|
||||
self.codeBlockCounter = 0
|
||||
|
||||
def Stop(self):
|
||||
# Flag every pending script as already done
|
||||
for b in self.codeBlocks:
|
||||
b.beenExecuted = 1
|
||||
return framework.COMScript.Stop(self)
|
||||
|
||||
def Reset(self):
|
||||
# Reset all code-blocks that are persistent, and discard the rest
|
||||
oldCodeBlocks = self.codeBlocks[:]
|
||||
self.codeBlocks = []
|
||||
for b in oldCodeBlocks:
|
||||
if b.flags & SCRIPTTEXT_ISPERSISTENT:
|
||||
b.beenExecuted = 0
|
||||
self.codeBlocks.append(b)
|
||||
return framework.COMScript.Reset(self)
|
||||
|
||||
def _GetNextCodeBlockNumber(self):
|
||||
self.codeBlockCounter = self.codeBlockCounter + 1
|
||||
return self.codeBlockCounter
|
||||
|
||||
def RegisterNamedItem(self, item):
|
||||
wasReg = item.isRegistered
|
||||
framework.COMScript.RegisterNamedItem(self, item)
|
||||
if not wasReg:
|
||||
# Insert into our namespace.
|
||||
# Add every item by name
|
||||
if item.IsVisible():
|
||||
self.globalNameSpaceModule.__dict__[item.name] = item.attributeObject
|
||||
if item.IsGlobal():
|
||||
# Global items means sub-items are also added...
|
||||
for subitem in item.subItems.values():
|
||||
self.globalNameSpaceModule.__dict__[
|
||||
subitem.name
|
||||
] = subitem.attributeObject
|
||||
# Also add all methods
|
||||
for name, entry in item.dispatchContainer._olerepr_.mapFuncs.items():
|
||||
if not entry.hidden:
|
||||
self.globalNameSpaceModule.__dict__[name] = getattr(
|
||||
item.dispatchContainer, name
|
||||
)
|
||||
|
||||
def DoExecutePendingScripts(self):
|
||||
try:
|
||||
globs = self.globalNameSpaceModule.__dict__
|
||||
for codeBlock in self.codeBlocks:
|
||||
if not codeBlock.beenExecuted:
|
||||
if self.CompileInScriptedSection(codeBlock, "exec"):
|
||||
self.ExecInScriptedSection(codeBlock, globs)
|
||||
finally:
|
||||
pass
|
||||
|
||||
def DoRun(self):
|
||||
pass
|
||||
|
||||
def Close(self):
|
||||
self.ResetNamespace()
|
||||
self.globalNameSpaceModule = None
|
||||
self.codeBlocks = []
|
||||
self.scriptDispatch = None
|
||||
framework.COMScript.Close(self)
|
||||
|
||||
def GetScriptDispatch(self, name):
|
||||
# trace("GetScriptDispatch with", name)
|
||||
# if name is not None: return None
|
||||
if self.scriptDispatch is None:
|
||||
self.scriptDispatch = scriptdispatch.MakeScriptDispatch(
|
||||
self, self.globalNameSpaceModule
|
||||
)
|
||||
return self.scriptDispatch
|
||||
|
||||
def MakeEventMethodName(self, subItemName, eventName):
|
||||
return (
|
||||
subItemName[0].upper()
|
||||
+ subItemName[1:]
|
||||
+ "_"
|
||||
+ eventName[0].upper()
|
||||
+ eventName[1:]
|
||||
)
|
||||
|
||||
def DoAddScriptlet(
|
||||
self,
|
||||
defaultName,
|
||||
code,
|
||||
itemName,
|
||||
subItemName,
|
||||
eventName,
|
||||
delimiter,
|
||||
sourceContextCookie,
|
||||
startLineNumber,
|
||||
):
|
||||
# Just store the code away - compile when called. (JIT :-)
|
||||
item = self.GetNamedItem(itemName)
|
||||
if (
|
||||
itemName == subItemName
|
||||
): # Explicit handlers - eg <SCRIPT LANGUAGE="Python" for="TestForm" Event="onSubmit">
|
||||
subItem = item
|
||||
else:
|
||||
subItem = item.GetCreateSubItem(item, subItemName, None, None)
|
||||
funcName = self.MakeEventMethodName(subItemName, eventName)
|
||||
|
||||
codeBlock = AXScriptCodeBlock(
|
||||
"Script Event %s" % funcName, code, sourceContextCookie, startLineNumber, 0
|
||||
)
|
||||
self._AddScriptCodeBlock(codeBlock)
|
||||
subItem.scriptlets[funcName] = codeBlock
|
||||
|
||||
def DoProcessScriptItemEvent(self, item, event, lcid, wFlags, args):
|
||||
# trace("ScriptItemEvent", self, item, event, event.name, lcid, wFlags, args)
|
||||
funcName = self.MakeEventMethodName(item.name, event.name)
|
||||
codeBlock = function = None
|
||||
try:
|
||||
function = item.scriptlets[funcName]
|
||||
if type(function) == type(self): # ie, is a CodeBlock instance
|
||||
codeBlock = function
|
||||
function = None
|
||||
except KeyError:
|
||||
pass
|
||||
if codeBlock is not None:
|
||||
realCode = "def %s():\n" % funcName
|
||||
for line in framework.RemoveCR(codeBlock.codeText).split("\n"):
|
||||
realCode = realCode + "\t" + line + "\n"
|
||||
realCode = realCode + "\n"
|
||||
if not self.CompileInScriptedSection(codeBlock, "exec", realCode):
|
||||
return
|
||||
dict = {}
|
||||
self.ExecInScriptedSection(
|
||||
codeBlock, self.globalNameSpaceModule.__dict__, dict
|
||||
)
|
||||
function = dict[funcName]
|
||||
# cache back in scriptlets as a function.
|
||||
item.scriptlets[funcName] = function
|
||||
if function is None:
|
||||
# still no function - see if in the global namespace.
|
||||
try:
|
||||
function = self.globalNameSpaceModule.__dict__[funcName]
|
||||
except KeyError:
|
||||
# Not there _exactly_ - do case ins search.
|
||||
funcNameLook = funcName.lower()
|
||||
for attr in self.globalNameSpaceModule.__dict__.keys():
|
||||
if funcNameLook == attr.lower():
|
||||
function = self.globalNameSpaceModule.__dict__[attr]
|
||||
# cache back in scriptlets, to avoid this overhead next time
|
||||
item.scriptlets[funcName] = function
|
||||
|
||||
if function is None:
|
||||
raise Exception(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
return self.ApplyInScriptedSection(codeBlock, function, args)
|
||||
|
||||
def DoParseScriptText(
|
||||
self, code, sourceContextCookie, startLineNumber, bWantResult, flags
|
||||
):
|
||||
code = framework.RemoveCR(code) + "\n"
|
||||
if flags & SCRIPTTEXT_ISEXPRESSION:
|
||||
name = "Script Expression"
|
||||
exec_type = "eval"
|
||||
else:
|
||||
name = "Script Block"
|
||||
exec_type = "exec"
|
||||
num = self._GetNextCodeBlockNumber()
|
||||
if num == 1:
|
||||
num = ""
|
||||
name = "%s %s" % (name, num)
|
||||
codeBlock = AXScriptCodeBlock(
|
||||
name, code, sourceContextCookie, startLineNumber, flags
|
||||
)
|
||||
self._AddScriptCodeBlock(codeBlock)
|
||||
globs = self.globalNameSpaceModule.__dict__
|
||||
if bWantResult: # always immediate.
|
||||
if self.CompileInScriptedSection(codeBlock, exec_type):
|
||||
if flags & SCRIPTTEXT_ISEXPRESSION:
|
||||
return self.EvalInScriptedSection(codeBlock, globs)
|
||||
else:
|
||||
return self.ExecInScriptedSection(codeBlock, globs)
|
||||
|
||||
# else compile failed, but user chose to keep running...
|
||||
else:
|
||||
if flags & SCRIPTTEXT_FORCEEXECUTION:
|
||||
if self.CompileInScriptedSection(codeBlock, exec_type):
|
||||
self.ExecInScriptedSection(codeBlock, globs)
|
||||
else:
|
||||
self.codeBlocks.append(codeBlock)
|
||||
|
||||
def GetNamedItemClass(self):
|
||||
return ScriptItem
|
||||
|
||||
def ResetNamespace(self):
|
||||
if self.globalNameSpaceModule is not None:
|
||||
try:
|
||||
self.globalNameSpaceModule.ax._Reset_()
|
||||
except AttributeError:
|
||||
pass # ???
|
||||
globalNameSpaceModule = None
|
||||
|
||||
|
||||
def DllRegisterServer():
|
||||
klass = PyScript
|
||||
win32com.server.register._set_subkeys(
|
||||
klass._reg_progid_ + "\\OLEScript", {}
|
||||
) # Just a CreateKey
|
||||
# Basic Registration for wsh.
|
||||
win32com.server.register._set_string(".pys", "pysFile")
|
||||
win32com.server.register._set_string("pysFile\\ScriptEngine", klass._reg_progid_)
|
||||
guid_wsh_shellex = "{60254CA5-953B-11CF-8C96-00AA00B8708C}"
|
||||
win32com.server.register._set_string(
|
||||
"pysFile\\ShellEx\\DropHandler", guid_wsh_shellex
|
||||
)
|
||||
win32com.server.register._set_string(
|
||||
"pysFile\\ShellEx\\PropertySheetHandlers\\WSHProps", guid_wsh_shellex
|
||||
)
|
||||
|
||||
|
||||
def Register(klass=PyScript):
|
||||
ret = win32com.server.register.UseCommandLine(
|
||||
klass, finalize_register=DllRegisterServer
|
||||
)
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Register()
|
49
lib/win32comext/axscript/client/pyscript_rexec.py
Normal file
49
lib/win32comext/axscript/client/pyscript_rexec.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
# A version of the ActiveScripting engine that enables rexec support
|
||||
# This version supports hosting by IE - however, due to Python's
|
||||
# rexec module being neither completely trusted nor private, it is
|
||||
# *not* enabled by default.
|
||||
# As of Python 2.2, rexec is simply not available - thus, if you use this,
|
||||
# a HTML page can do almost *anything* at all on your machine.
|
||||
|
||||
# You almost certainly do NOT want to use thus!
|
||||
|
||||
import pythoncom
|
||||
from win32com.axscript import axscript
|
||||
|
||||
from . import pyscript
|
||||
|
||||
INTERFACE_USES_DISPEX = 0x00000004 # Object knows to use IDispatchEx
|
||||
INTERFACE_USES_SECURITY_MANAGER = (
|
||||
0x00000008 # Object knows to use IInternetHostSecurityManager
|
||||
)
|
||||
|
||||
|
||||
class PyScriptRExec(pyscript.PyScript):
|
||||
# Setup the auto-registration stuff...
|
||||
_reg_verprogid_ = "Python.AXScript-rexec.2"
|
||||
_reg_progid_ = "Python" # Same ProgID as the standard engine.
|
||||
# _reg_policy_spec_ = default
|
||||
_reg_catids_ = [axscript.CATID_ActiveScript, axscript.CATID_ActiveScriptParse]
|
||||
_reg_desc_ = "Python ActiveX Scripting Engine (with rexec support)"
|
||||
_reg_clsid_ = "{69c2454b-efa2-455b-988c-c3651c4a2f69}"
|
||||
_reg_class_spec_ = "win32com.axscript.client.pyscript_rexec.PyScriptRExec"
|
||||
_reg_remove_keys_ = [(".pys",), ("pysFile",)]
|
||||
_reg_threading_ = "Apartment"
|
||||
|
||||
def _GetSupportedInterfaceSafetyOptions(self):
|
||||
# print "**** calling", pyscript.PyScript._GetSupportedInterfaceSafetyOptions, "**->", pyscript.PyScript._GetSupportedInterfaceSafetyOptions(self)
|
||||
return (
|
||||
INTERFACE_USES_DISPEX
|
||||
| INTERFACE_USES_SECURITY_MANAGER
|
||||
| axscript.INTERFACESAFE_FOR_UNTRUSTED_DATA
|
||||
| axscript.INTERFACESAFE_FOR_UNTRUSTED_CALLER
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("WARNING: By registering this engine, you are giving remote HTML code")
|
||||
print("the ability to execute *any* code on your system.")
|
||||
print()
|
||||
print("You almost certainly do NOT want to do this.")
|
||||
print("You have been warned, and are doing this at your own (significant) risk")
|
||||
pyscript.Register(PyScriptRExec)
|
115
lib/win32comext/axscript/client/scriptdispatch.py
Normal file
115
lib/win32comext/axscript/client/scriptdispatch.py
Normal file
|
@ -0,0 +1,115 @@
|
|||
"""dynamic dispatch objects for AX Script.
|
||||
|
||||
This is an IDispatch object that a scripting host may use to
|
||||
query and invoke methods on the main script. Not may hosts use
|
||||
this yet, so it is not well tested!
|
||||
"""
|
||||
|
||||
import types
|
||||
|
||||
import pythoncom
|
||||
import win32com.server.policy
|
||||
import win32com.server.util
|
||||
import winerror
|
||||
from win32com.axscript import axscript
|
||||
from win32com.client import Dispatch
|
||||
from win32com.server.exception import COMException
|
||||
|
||||
debugging = 0
|
||||
|
||||
PyIDispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch]
|
||||
|
||||
|
||||
def _is_callable(obj):
|
||||
return type(obj) in [types.FunctionType, types.MethodType]
|
||||
# ignore hasattr(obj, "__call__") as this means all COM objects!
|
||||
|
||||
|
||||
class ScriptDispatch:
|
||||
_public_methods_ = []
|
||||
|
||||
def __init__(self, engine, scriptNamespace):
|
||||
self.engine = engine
|
||||
self.scriptNamespace = scriptNamespace
|
||||
|
||||
def _dynamic_(self, name, lcid, wFlags, args):
|
||||
# Ensure any newly added items are available.
|
||||
self.engine.RegisterNewNamedItems()
|
||||
self.engine.ProcessNewNamedItemsConnections()
|
||||
if wFlags & pythoncom.INVOKE_FUNC:
|
||||
# attempt to call a function
|
||||
try:
|
||||
func = getattr(self.scriptNamespace, name)
|
||||
if not _is_callable(func):
|
||||
raise AttributeError(name) # Not a function.
|
||||
realArgs = []
|
||||
for arg in args:
|
||||
if type(arg) == PyIDispatchType:
|
||||
realArgs.append(Dispatch(arg))
|
||||
else:
|
||||
realArgs.append(arg)
|
||||
# xxx - todo - work out what code block to pass???
|
||||
return self.engine.ApplyInScriptedSection(None, func, tuple(realArgs))
|
||||
|
||||
except AttributeError:
|
||||
if not wFlags & pythoncom.DISPATCH_PROPERTYGET:
|
||||
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
if wFlags & pythoncom.DISPATCH_PROPERTYGET:
|
||||
# attempt to get a property
|
||||
try:
|
||||
ret = getattr(self.scriptNamespace, name)
|
||||
if _is_callable(ret):
|
||||
raise AttributeError(name) # Not a property.
|
||||
except AttributeError:
|
||||
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
except COMException as instance:
|
||||
raise
|
||||
except:
|
||||
ret = self.engine.HandleException()
|
||||
return ret
|
||||
|
||||
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
|
||||
|
||||
class StrictDynamicPolicy(win32com.server.policy.DynamicPolicy):
|
||||
def _wrap_(self, object):
|
||||
win32com.server.policy.DynamicPolicy._wrap_(self, object)
|
||||
if hasattr(self._obj_, "scriptNamespace"):
|
||||
for name in dir(self._obj_.scriptNamespace):
|
||||
self._dyn_dispid_to_name_[self._getdispid_(name, 0)] = name
|
||||
|
||||
def _getmembername_(self, dispid):
|
||||
try:
|
||||
return str(self._dyn_dispid_to_name_[dispid])
|
||||
except KeyError:
|
||||
raise COMException(scode=winerror.DISP_E_UNKNOWNNAME, desc="Name not found")
|
||||
|
||||
def _getdispid_(self, name, fdex):
|
||||
try:
|
||||
func = getattr(self._obj_.scriptNamespace, str(name))
|
||||
except AttributeError:
|
||||
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
# if not _is_callable(func):
|
||||
return win32com.server.policy.DynamicPolicy._getdispid_(self, name, fdex)
|
||||
|
||||
|
||||
def _wrap_debug(obj):
|
||||
return win32com.server.util.wrap(
|
||||
obj,
|
||||
usePolicy=StrictDynamicPolicy,
|
||||
useDispatcher=win32com.server.policy.DispatcherWin32trace,
|
||||
)
|
||||
|
||||
|
||||
def _wrap_nodebug(obj):
|
||||
return win32com.server.util.wrap(obj, usePolicy=StrictDynamicPolicy)
|
||||
|
||||
|
||||
if debugging:
|
||||
_wrap = _wrap_debug
|
||||
else:
|
||||
_wrap = _wrap_nodebug
|
||||
|
||||
|
||||
def MakeScriptDispatch(engine, namespace):
|
||||
return _wrap(ScriptDispatch(engine, namespace))
|
0
lib/win32comext/axscript/server/__init__.py
Normal file
0
lib/win32comext/axscript/server/__init__.py
Normal file
145
lib/win32comext/axscript/server/axsite.py
Normal file
145
lib/win32comext/axscript/server/axsite.py
Normal file
|
@ -0,0 +1,145 @@
|
|||
import pythoncom
|
||||
import win32com.axscript.axscript
|
||||
import winerror
|
||||
from win32com.axscript import axscript
|
||||
from win32com.server import exception, util
|
||||
|
||||
|
||||
class AXEngine:
|
||||
def __init__(self, site, engine):
|
||||
self.eScript = self.eParse = self.eSafety = None
|
||||
if type(engine) == type(""):
|
||||
engine = pythoncom.CoCreateInstance(
|
||||
engine, None, pythoncom.CLSCTX_SERVER, pythoncom.IID_IUnknown
|
||||
)
|
||||
|
||||
self.eScript = engine.QueryInterface(axscript.IID_IActiveScript)
|
||||
self.eParse = engine.QueryInterface(axscript.IID_IActiveScriptParse)
|
||||
self.eSafety = engine.QueryInterface(axscript.IID_IObjectSafety)
|
||||
|
||||
self.eScript.SetScriptSite(site)
|
||||
self.eParse.InitNew()
|
||||
|
||||
def __del__(self):
|
||||
self.Close()
|
||||
|
||||
def GetScriptDispatch(self, name=None):
|
||||
return self.eScript.GetScriptDispatch(name)
|
||||
|
||||
def AddNamedItem(self, item, flags):
|
||||
return self.eScript.AddNamedItem(item, flags)
|
||||
|
||||
# Some helpers.
|
||||
def AddCode(self, code, flags=0):
|
||||
self.eParse.ParseScriptText(code, None, None, None, 0, 0, flags)
|
||||
|
||||
def EvalCode(self, code):
|
||||
return self.eParse.ParseScriptText(
|
||||
code, None, None, None, 0, 0, axscript.SCRIPTTEXT_ISEXPRESSION
|
||||
)
|
||||
|
||||
def Start(self):
|
||||
# Should maybe check state?
|
||||
# Do I need to transition through?
|
||||
self.eScript.SetScriptState(axscript.SCRIPTSTATE_STARTED)
|
||||
|
||||
# self.eScript.SetScriptState(axscript.SCRIPTSTATE_CONNECTED)
|
||||
|
||||
def Close(self):
|
||||
if self.eScript:
|
||||
self.eScript.Close()
|
||||
self.eScript = self.eParse = self.eSafety = None
|
||||
|
||||
def SetScriptState(self, state):
|
||||
self.eScript.SetScriptState(state)
|
||||
|
||||
|
||||
IActiveScriptSite_methods = [
|
||||
"GetLCID",
|
||||
"GetItemInfo",
|
||||
"GetDocVersionString",
|
||||
"OnScriptTerminate",
|
||||
"OnStateChange",
|
||||
"OnScriptError",
|
||||
"OnEnterScript",
|
||||
"OnLeaveScript",
|
||||
]
|
||||
|
||||
|
||||
class AXSite:
|
||||
"""An Active Scripting site. A Site can have exactly one engine."""
|
||||
|
||||
_public_methods_ = IActiveScriptSite_methods
|
||||
_com_interfaces_ = [axscript.IID_IActiveScriptSite]
|
||||
|
||||
def __init__(self, objModel={}, engine=None, lcid=0):
|
||||
self.lcid = lcid
|
||||
self.objModel = {}
|
||||
for name, object in objModel.items():
|
||||
# Gregs code did string.lower this - I think that is callers job if he wants!
|
||||
self.objModel[name] = object
|
||||
|
||||
self.engine = None
|
||||
if engine:
|
||||
self._AddEngine(engine)
|
||||
|
||||
def AddEngine(self, engine):
|
||||
"""Adds a new engine to the site.
|
||||
engine can be a string, or a fully wrapped engine object.
|
||||
"""
|
||||
if type(engine) == type(""):
|
||||
newEngine = AXEngine(util.wrap(self), engine)
|
||||
else:
|
||||
newEngine = engine
|
||||
self.engine = newEngine
|
||||
flags = (
|
||||
axscript.SCRIPTITEM_ISVISIBLE
|
||||
| axscript.SCRIPTITEM_NOCODE
|
||||
| axscript.SCRIPTITEM_GLOBALMEMBERS
|
||||
| axscript.SCRIPTITEM_ISPERSISTENT
|
||||
)
|
||||
for name in self.objModel.keys():
|
||||
newEngine.AddNamedItem(name, flags)
|
||||
newEngine.SetScriptState(axscript.SCRIPTSTATE_INITIALIZED)
|
||||
return newEngine
|
||||
|
||||
# B/W compat
|
||||
_AddEngine = AddEngine
|
||||
|
||||
def _Close(self):
|
||||
self.engine.Close()
|
||||
self.objModel = {}
|
||||
|
||||
def GetLCID(self):
|
||||
return self.lcid
|
||||
|
||||
def GetItemInfo(self, name, returnMask):
|
||||
if name not in self.objModel:
|
||||
raise exception.Exception(
|
||||
scode=winerror.TYPE_E_ELEMENTNOTFOUND, desc="item not found"
|
||||
)
|
||||
|
||||
### for now, we don't have any type information
|
||||
|
||||
if returnMask & axscript.SCRIPTINFO_IUNKNOWN:
|
||||
return (self.objModel[name], None)
|
||||
|
||||
return (None, None)
|
||||
|
||||
def GetDocVersionString(self):
|
||||
return "Python AXHost version 1.0"
|
||||
|
||||
def OnScriptTerminate(self, result, excepInfo):
|
||||
pass
|
||||
|
||||
def OnStateChange(self, state):
|
||||
pass
|
||||
|
||||
def OnScriptError(self, errorInterface):
|
||||
return winerror.S_FALSE
|
||||
|
||||
def OnEnterScript(self):
|
||||
pass
|
||||
|
||||
def OnLeaveScript(self):
|
||||
pass
|
16
lib/win32comext/axscript/server/error.py
Normal file
16
lib/win32comext/axscript/server/error.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
"""Exception instance for AXScript servers.
|
||||
|
||||
This module implements an exception instance that is raised by the core
|
||||
server scripting support.
|
||||
|
||||
When a script error occurs, it wraps the COM object that describes the
|
||||
exception in a Python instance, which can then be raised and caught.
|
||||
"""
|
||||
|
||||
|
||||
class Exception:
|
||||
def __init__(self, activeScriptError):
|
||||
self.activeScriptError = activeScriptError
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return getattr(self.activeScriptError, attr)
|
17
lib/win32comext/axscript/test/debugTest.pys
Normal file
17
lib/win32comext/axscript/test/debugTest.pys
Normal file
|
@ -0,0 +1,17 @@
|
|||
def Function(i):
|
||||
Test.Echo(i)
|
||||
|
||||
print(dir())
|
||||
|
||||
a=1
|
||||
b=a
|
||||
c=b # And here is a comment
|
||||
d="A string"
|
||||
print(a)
|
||||
Test.echo("Hello from Python")
|
||||
for i in range(2):
|
||||
Function(i)
|
||||
a = """\
|
||||
A multi-line string!
|
||||
"""
|
||||
|
7
lib/win32comext/axscript/test/debugTest.vbs
Normal file
7
lib/win32comext/axscript/test/debugTest.vbs
Normal file
|
@ -0,0 +1,7 @@
|
|||
a=1
|
||||
b=a
|
||||
Test.Echo "Hello from VBScript"
|
||||
' Here is a comment
|
||||
for i = 1 to 10
|
||||
|
||||
next
|
188
lib/win32comext/axscript/test/leakTest.py
Normal file
188
lib/win32comext/axscript/test/leakTest.py
Normal file
|
@ -0,0 +1,188 @@
|
|||
import sys
|
||||
|
||||
import pythoncom
|
||||
import win32com.server.policy
|
||||
from win32com.axscript import axscript
|
||||
from win32com.axscript.server import axsite
|
||||
from win32com.axscript.server.error import Exception
|
||||
from win32com.server import connect, util
|
||||
|
||||
|
||||
class MySite(axsite.AXSite):
|
||||
def OnScriptError(self, error):
|
||||
exc = error.GetExceptionInfo()
|
||||
context, line, char = error.GetSourcePosition()
|
||||
print(" >Exception:", exc[1])
|
||||
try:
|
||||
st = error.GetSourceLineText()
|
||||
except pythoncom.com_error:
|
||||
st = None
|
||||
if st is None:
|
||||
st = ""
|
||||
text = st + "\n" + (" " * (char - 1)) + "^" + "\n" + exc[2]
|
||||
for line in text.splitlines():
|
||||
print(" >" + line)
|
||||
|
||||
|
||||
class MyCollection(util.Collection):
|
||||
def _NewEnum(self):
|
||||
print("Making new Enumerator")
|
||||
return util.Collection._NewEnum(self)
|
||||
|
||||
|
||||
class Test:
|
||||
_public_methods_ = ["echo"]
|
||||
_public_attrs_ = ["collection", "verbose"]
|
||||
|
||||
def __init__(self):
|
||||
self.verbose = 0
|
||||
self.collection = util.wrap(MyCollection([1, "Two", 3]))
|
||||
self.last = ""
|
||||
|
||||
# self._connect_server_ = TestConnectServer(self)
|
||||
|
||||
def echo(self, *args):
|
||||
self.last = "".join(map(str, args))
|
||||
if self.verbose:
|
||||
for arg in args:
|
||||
print(arg, end=" ")
|
||||
print()
|
||||
|
||||
|
||||
# self._connect_server_.Broadcast(last)
|
||||
|
||||
|
||||
#### Connections currently wont work, as there is no way for the engine to
|
||||
#### know what events we support. We need typeinfo support.
|
||||
|
||||
IID_ITestEvents = pythoncom.MakeIID("{8EB72F90-0D44-11d1-9C4B-00AA00125A98}")
|
||||
|
||||
|
||||
class TestConnectServer(connect.ConnectableServer):
|
||||
_connect_interfaces_ = [IID_ITestEvents]
|
||||
|
||||
# The single public method that the client can call on us
|
||||
# (ie, as a normal COM server, this exposes just this single method.
|
||||
def __init__(self, object):
|
||||
self.object = object
|
||||
|
||||
def Broadcast(self, arg):
|
||||
# Simply broadcast a notification.
|
||||
self._BroadcastNotify(self.NotifyDoneIt, (arg,))
|
||||
|
||||
def NotifyDoneIt(self, interface, arg):
|
||||
interface.Invoke(1000, 0, pythoncom.DISPATCH_METHOD, 1, arg)
|
||||
|
||||
|
||||
VBScript = """\
|
||||
prop = "Property Value"
|
||||
|
||||
sub hello(arg1)
|
||||
test.echo arg1
|
||||
end sub
|
||||
|
||||
sub testcollection
|
||||
test.verbose = 1
|
||||
for each item in test.collection
|
||||
test.echo "Collection item is", item
|
||||
next
|
||||
end sub
|
||||
"""
|
||||
if sys.version_info < (3,):
|
||||
PyScript = """print "PyScript is being parsed..."\n"""
|
||||
else:
|
||||
PyScript = """print("PyScript is being parsed...")\n"""
|
||||
PyScript += """\
|
||||
prop = "Property Value"
|
||||
def hello(arg1):
|
||||
test.echo(arg1)
|
||||
pass
|
||||
|
||||
def testcollection():
|
||||
test.verbose = 1
|
||||
# test.collection[1] = "New one"
|
||||
for item in test.collection:
|
||||
test.echo("Collection item is", item)
|
||||
pass
|
||||
"""
|
||||
|
||||
ErrScript = """\
|
||||
bad code for everyone!
|
||||
"""
|
||||
|
||||
|
||||
def TestEngine(engineName, code, bShouldWork=1):
|
||||
echoer = Test()
|
||||
model = {
|
||||
"test": util.wrap(echoer),
|
||||
}
|
||||
|
||||
site = MySite(model)
|
||||
engine = site._AddEngine(engineName)
|
||||
engine.AddCode(code, axscript.SCRIPTTEXT_ISPERSISTENT)
|
||||
try:
|
||||
engine.Start()
|
||||
finally:
|
||||
if not bShouldWork:
|
||||
engine.Close()
|
||||
return
|
||||
doTestEngine(engine, echoer)
|
||||
# re-transition the engine back to the UNINITIALIZED state, a-la ASP.
|
||||
engine.eScript.SetScriptState(axscript.SCRIPTSTATE_UNINITIALIZED)
|
||||
engine.eScript.SetScriptSite(util.wrap(site))
|
||||
print("restarting")
|
||||
engine.Start()
|
||||
# all done!
|
||||
engine.Close()
|
||||
|
||||
|
||||
def doTestEngine(engine, echoer):
|
||||
# Now call into the scripts IDispatch
|
||||
from win32com.client.dynamic import Dispatch
|
||||
|
||||
ob = Dispatch(engine.GetScriptDispatch())
|
||||
try:
|
||||
ob.hello("Goober")
|
||||
except pythoncom.com_error as exc:
|
||||
print("***** Calling 'hello' failed", exc)
|
||||
return
|
||||
if echoer.last != "Goober":
|
||||
print("***** Function call didnt set value correctly", repr(echoer.last))
|
||||
|
||||
if str(ob.prop) != "Property Value":
|
||||
print("***** Property Value not correct - ", repr(ob.prop))
|
||||
|
||||
ob.testcollection()
|
||||
|
||||
# Now make sure my engines can evaluate stuff.
|
||||
result = engine.eParse.ParseScriptText(
|
||||
"1+1", None, None, None, 0, 0, axscript.SCRIPTTEXT_ISEXPRESSION
|
||||
)
|
||||
if result != 2:
|
||||
print("Engine could not evaluate '1+1' - said the result was", result)
|
||||
|
||||
|
||||
def dotestall():
|
||||
for i in range(10):
|
||||
TestEngine("Python", PyScript)
|
||||
print(sys.gettotalrefcount())
|
||||
|
||||
|
||||
## print "Testing Exceptions"
|
||||
## try:
|
||||
## TestEngine("Python", ErrScript, 0)
|
||||
## except pythoncom.com_error:
|
||||
## pass
|
||||
|
||||
|
||||
def testall():
|
||||
dotestall()
|
||||
pythoncom.CoUninitialize()
|
||||
print(
|
||||
"AXScript Host worked correctly - %d/%d COM objects left alive."
|
||||
% (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
testall()
|
257
lib/win32comext/axscript/test/testHost.py
Normal file
257
lib/win32comext/axscript/test/testHost.py
Normal file
|
@ -0,0 +1,257 @@
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
import pythoncom
|
||||
import win32com.server.policy
|
||||
import win32com.test.util
|
||||
from win32com.axscript import axscript
|
||||
from win32com.axscript.server import axsite
|
||||
from win32com.axscript.server.error import Exception
|
||||
from win32com.client.dynamic import Dispatch
|
||||
from win32com.server import connect, util
|
||||
from win32com.server.exception import COMException
|
||||
|
||||
verbose = "-v" in sys.argv
|
||||
|
||||
|
||||
class MySite(axsite.AXSite):
|
||||
def __init__(self, *args):
|
||||
self.exception_seen = None
|
||||
axsite.AXSite.__init__(self, *args)
|
||||
|
||||
def OnScriptError(self, error):
|
||||
self.exception_seen = exc = error.GetExceptionInfo()
|
||||
context, line, char = error.GetSourcePosition()
|
||||
if not verbose:
|
||||
return
|
||||
print(" >Exception:", exc[1])
|
||||
try:
|
||||
st = error.GetSourceLineText()
|
||||
except pythoncom.com_error:
|
||||
st = None
|
||||
if st is None:
|
||||
st = ""
|
||||
text = st + "\n" + (" " * (char - 1)) + "^" + "\n" + exc[2]
|
||||
for line in text.splitlines():
|
||||
print(" >" + line)
|
||||
|
||||
|
||||
class MyCollection(util.Collection):
|
||||
def _NewEnum(self):
|
||||
return util.Collection._NewEnum(self)
|
||||
|
||||
|
||||
class Test:
|
||||
_public_methods_ = ["echo", "fail"]
|
||||
_public_attrs_ = ["collection"]
|
||||
|
||||
def __init__(self):
|
||||
self.verbose = verbose
|
||||
self.collection = util.wrap(MyCollection([1, "Two", 3]))
|
||||
self.last = ""
|
||||
self.fail_called = 0
|
||||
|
||||
# self._connect_server_ = TestConnectServer(self)
|
||||
|
||||
def echo(self, *args):
|
||||
self.last = "".join([str(s) for s in args])
|
||||
if self.verbose:
|
||||
for arg in args:
|
||||
print(arg, end=" ")
|
||||
print()
|
||||
|
||||
def fail(self, *args):
|
||||
print("**** fail() called ***")
|
||||
for arg in args:
|
||||
print(arg, end=" ")
|
||||
print()
|
||||
self.fail_called = 1
|
||||
|
||||
|
||||
# self._connect_server_.Broadcast(last)
|
||||
|
||||
|
||||
#### Connections currently wont work, as there is no way for the engine to
|
||||
#### know what events we support. We need typeinfo support.
|
||||
|
||||
IID_ITestEvents = pythoncom.MakeIID("{8EB72F90-0D44-11d1-9C4B-00AA00125A98}")
|
||||
|
||||
|
||||
class TestConnectServer(connect.ConnectableServer):
|
||||
_connect_interfaces_ = [IID_ITestEvents]
|
||||
|
||||
# The single public method that the client can call on us
|
||||
# (ie, as a normal COM server, this exposes just this single method.
|
||||
def __init__(self, object):
|
||||
self.object = object
|
||||
|
||||
def Broadcast(self, arg):
|
||||
# Simply broadcast a notification.
|
||||
self._BroadcastNotify(self.NotifyDoneIt, (arg,))
|
||||
|
||||
def NotifyDoneIt(self, interface, arg):
|
||||
interface.Invoke(1000, 0, pythoncom.DISPATCH_METHOD, 1, arg)
|
||||
|
||||
|
||||
VBScript = """\
|
||||
prop = "Property Value"
|
||||
|
||||
sub hello(arg1)
|
||||
test.echo arg1
|
||||
end sub
|
||||
|
||||
sub testcollection
|
||||
if test.collection.Item(0) <> 1 then
|
||||
test.fail("Index 0 was wrong")
|
||||
end if
|
||||
if test.collection.Item(1) <> "Two" then
|
||||
test.fail("Index 1 was wrong")
|
||||
end if
|
||||
if test.collection.Item(2) <> 3 then
|
||||
test.fail("Index 2 was wrong")
|
||||
end if
|
||||
num = 0
|
||||
for each item in test.collection
|
||||
num = num + 1
|
||||
next
|
||||
if num <> 3 then
|
||||
test.fail("Collection didn't have 3 items")
|
||||
end if
|
||||
end sub
|
||||
"""
|
||||
PyScript = """\
|
||||
# A unicode \xa9omment.
|
||||
prop = "Property Value"
|
||||
def hello(arg1):
|
||||
test.echo(arg1)
|
||||
|
||||
def testcollection():
|
||||
# test.collection[1] = "New one"
|
||||
got = []
|
||||
for item in test.collection:
|
||||
got.append(item)
|
||||
if got != [1, "Two", 3]:
|
||||
test.fail("Didn't get the collection")
|
||||
pass
|
||||
"""
|
||||
|
||||
# XXX - needs py3k work! Throwing a bytes string with an extended char
|
||||
# doesn't make much sense, but py2x allows it. What it gets upset with
|
||||
# is a real unicode arg - which is the only thing py3k allows!
|
||||
PyScript_Exc = """\
|
||||
def hello(arg1):
|
||||
raise RuntimeError("exc with extended \xa9har")
|
||||
"""
|
||||
|
||||
ErrScript = """\
|
||||
bad code for everyone!
|
||||
"""
|
||||
|
||||
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 _CheckEngineState(engine, name, state):
|
||||
got = engine.engine.eScript.GetScriptState()
|
||||
if got != state:
|
||||
got_name = state_map.get(got, str(got))
|
||||
state_name = state_map.get(state, str(state))
|
||||
raise RuntimeError(
|
||||
"Warning - engine %s has state %s, but expected %s"
|
||||
% (name, got_name, state_name)
|
||||
)
|
||||
|
||||
|
||||
class EngineTester(win32com.test.util.TestCase):
|
||||
def _TestEngine(self, engineName, code, expected_exc=None):
|
||||
echoer = Test()
|
||||
model = {
|
||||
"test": util.wrap(echoer),
|
||||
}
|
||||
site = MySite(model)
|
||||
engine = site._AddEngine(engineName)
|
||||
try:
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_INITIALIZED)
|
||||
engine.AddCode(code)
|
||||
engine.Start()
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_STARTED)
|
||||
self.assertTrue(not echoer.fail_called, "Fail should not have been called")
|
||||
# Now call into the scripts IDispatch
|
||||
ob = Dispatch(engine.GetScriptDispatch())
|
||||
try:
|
||||
ob.hello("Goober")
|
||||
self.assertTrue(
|
||||
expected_exc is None,
|
||||
"Expected %r, but no exception seen" % (expected_exc,),
|
||||
)
|
||||
except pythoncom.com_error:
|
||||
if expected_exc is None:
|
||||
self.fail(
|
||||
"Unexpected failure from script code: %s"
|
||||
% (site.exception_seen,)
|
||||
)
|
||||
if expected_exc not in site.exception_seen[2]:
|
||||
self.fail(
|
||||
"Could not find %r in %r"
|
||||
% (expected_exc, site.exception_seen[2])
|
||||
)
|
||||
return
|
||||
self.assertEqual(echoer.last, "Goober")
|
||||
|
||||
self.assertEqual(str(ob.prop), "Property Value")
|
||||
ob.testcollection()
|
||||
self.assertTrue(not echoer.fail_called, "Fail should not have been called")
|
||||
|
||||
# Now make sure my engines can evaluate stuff.
|
||||
result = engine.eParse.ParseScriptText(
|
||||
"1+1", None, None, None, 0, 0, axscript.SCRIPTTEXT_ISEXPRESSION
|
||||
)
|
||||
self.assertEqual(result, 2)
|
||||
# re-initialize to make sure it transitions back to initialized again.
|
||||
engine.SetScriptState(axscript.SCRIPTSTATE_INITIALIZED)
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_INITIALIZED)
|
||||
engine.Start()
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_STARTED)
|
||||
|
||||
# Transition back to initialized, then through connected too.
|
||||
engine.SetScriptState(axscript.SCRIPTSTATE_INITIALIZED)
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_INITIALIZED)
|
||||
engine.SetScriptState(axscript.SCRIPTSTATE_CONNECTED)
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_CONNECTED)
|
||||
engine.SetScriptState(axscript.SCRIPTSTATE_INITIALIZED)
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_INITIALIZED)
|
||||
|
||||
engine.SetScriptState(axscript.SCRIPTSTATE_CONNECTED)
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_CONNECTED)
|
||||
engine.SetScriptState(axscript.SCRIPTSTATE_DISCONNECTED)
|
||||
_CheckEngineState(site, engineName, axscript.SCRIPTSTATE_DISCONNECTED)
|
||||
finally:
|
||||
engine.Close()
|
||||
engine = None
|
||||
site = None
|
||||
|
||||
def testVB(self):
|
||||
self._TestEngine("VBScript", VBScript)
|
||||
|
||||
def testPython(self):
|
||||
self._TestEngine("Python", PyScript)
|
||||
|
||||
def testPythonUnicodeError(self):
|
||||
self._TestEngine("Python", PyScript)
|
||||
|
||||
def testVBExceptions(self):
|
||||
self.assertRaises(pythoncom.com_error, self._TestEngine, "VBScript", ErrScript)
|
||||
|
||||
def testPythonExceptions(self):
|
||||
expected = "RuntimeError: exc with extended \xa9har"
|
||||
self._TestEngine("Python", PyScript_Exc, expected)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
88
lib/win32comext/axscript/test/testHost4Dbg.py
Normal file
88
lib/win32comext/axscript/test/testHost4Dbg.py
Normal file
|
@ -0,0 +1,88 @@
|
|||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import pythoncom
|
||||
import win32ui
|
||||
from win32com.axscript import axscript
|
||||
from win32com.axscript.server import axsite
|
||||
from win32com.axscript.server.error import Exception
|
||||
from win32com.server import util
|
||||
|
||||
version = "0.0.1"
|
||||
|
||||
|
||||
class MySite(axsite.AXSite):
|
||||
def OnScriptError(self, error):
|
||||
print("An error occurred in the Script Code")
|
||||
exc = error.GetExceptionInfo()
|
||||
try:
|
||||
text = error.GetSourceLineText()
|
||||
except:
|
||||
text = "<unknown>"
|
||||
context, line, char = error.GetSourcePosition()
|
||||
print(
|
||||
"Exception: %s (line %d)\n%s\n%s^\n%s"
|
||||
% (exc[1], line, text, " " * (char - 1), exc[2])
|
||||
)
|
||||
|
||||
|
||||
class ObjectModel:
|
||||
_public_methods_ = ["echo", "msgbox"]
|
||||
|
||||
def echo(self, *args):
|
||||
print("".join(map(str, args)))
|
||||
|
||||
def msgbox(self, *args):
|
||||
msg = "".join(map(str, args))
|
||||
win32ui.MessageBox(msg)
|
||||
|
||||
|
||||
def TestEngine():
|
||||
model = {"Test": util.wrap(ObjectModel())}
|
||||
scriptDir = "."
|
||||
site = MySite(model)
|
||||
pyEngine = site._AddEngine("Python")
|
||||
# pyEngine2 = site._AddEngine("Python")
|
||||
vbEngine = site._AddEngine("VBScript")
|
||||
# forthEngine = site._AddEngine("ForthScript")
|
||||
try:
|
||||
# code = open(os.path.join(scriptDir, "debugTest.4ths"),"rb").read()
|
||||
# forthEngine.AddCode(code)
|
||||
code = open(os.path.join(scriptDir, "debugTest.pys"), "rb").read()
|
||||
pyEngine.AddCode(code)
|
||||
code = open(os.path.join(scriptDir, "debugTest.vbs"), "rb").read()
|
||||
vbEngine.AddCode(code)
|
||||
# code = open(os.path.join(scriptDir, "debugTestFail.pys"),"rb").read()
|
||||
# pyEngine2.AddCode(code)
|
||||
|
||||
# from win32com.axdebug import axdebug
|
||||
# sessionProvider=pythoncom.CoCreateInstance(axdebug.CLSID_DefaultDebugSessionProvider,None,pythoncom.CLSCTX_ALL, axdebug.IID_IDebugSessionProvider)
|
||||
# sessionProvider.StartDebugSession(None)
|
||||
|
||||
input("Press enter to continue")
|
||||
# forthEngine.Start()
|
||||
pyEngine.Start() # Actually run the Python code
|
||||
vbEngine.Start() # Actually run the VB code
|
||||
except pythoncom.com_error as details:
|
||||
print("Script failed: %s (0x%x)" % (details[1], details[0]))
|
||||
# Now run the code expected to fail!
|
||||
# try:
|
||||
# pyEngine2.Start() # Actually run the Python code that fails!
|
||||
# print "Script code worked when it should have failed."
|
||||
# except pythoncom.com_error:
|
||||
# pass
|
||||
|
||||
site._Close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import win32com.axdebug.util
|
||||
|
||||
try:
|
||||
TestEngine()
|
||||
except:
|
||||
traceback.print_exc()
|
||||
win32com.axdebug.util._dump_wrapped()
|
||||
sys.exc_type = sys.exc_value = sys.exc_traceback = None
|
||||
print(pythoncom._GetInterfaceCount(), "com objects still alive")
|
6
lib/win32comext/bits/__init__.py
Normal file
6
lib/win32comext/bits/__init__.py
Normal file
|
@ -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__)
|
BIN
lib/win32comext/bits/bits.pyd
Normal file
BIN
lib/win32comext/bits/bits.pyd
Normal file
Binary file not shown.
52
lib/win32comext/bits/test/show_all_jobs.py
Normal file
52
lib/win32comext/bits/test/show_all_jobs.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Dump lots of info about BITS jobs.
|
||||
import pythoncom
|
||||
from win32com.bits import bits
|
||||
|
||||
states = dict(
|
||||
[
|
||||
(val, (name[13:]))
|
||||
for name, val in vars(bits).items()
|
||||
if name.startswith("BG_JOB_STATE_")
|
||||
]
|
||||
)
|
||||
|
||||
job_types = dict(
|
||||
[
|
||||
(val, (name[12:]))
|
||||
for name, val in vars(bits).items()
|
||||
if name.startswith("BG_JOB_TYPE_")
|
||||
]
|
||||
)
|
||||
|
||||
bcm = pythoncom.CoCreateInstance(
|
||||
bits.CLSID_BackgroundCopyManager,
|
||||
None,
|
||||
pythoncom.CLSCTX_LOCAL_SERVER,
|
||||
bits.IID_IBackgroundCopyManager,
|
||||
)
|
||||
|
||||
try:
|
||||
enum = bcm.EnumJobs(bits.BG_JOB_ENUM_ALL_USERS)
|
||||
except pythoncom.error:
|
||||
print("Failed to get jobs for all users - trying for current user")
|
||||
enum = bcm.EnumJobs(0)
|
||||
|
||||
for job in enum:
|
||||
print("Job:", job.GetDisplayName())
|
||||
print("Description:", job.GetDescription())
|
||||
print("Id:", job.GetId())
|
||||
print("State:", states.get(job.GetState()))
|
||||
print("Type:", job_types.get(job.GetType()))
|
||||
print("Owner:", job.GetOwner())
|
||||
print("Errors:", job.GetErrorCount())
|
||||
print("Created/Modified/Finished times:", [str(t) for t in job.GetTimes()])
|
||||
bytes_tot, bytes_xf, files_tot, files_xf = job.GetProgress()
|
||||
print("Bytes: %d complete of %d total" % (bytes_xf, bytes_tot))
|
||||
print("Files: %d complete of %d total" % (files_xf, files_tot))
|
||||
for f in job.EnumFiles():
|
||||
bytes, total, done = f.GetProgress()
|
||||
print(" Remote:", f.GetRemoteName())
|
||||
print(" Local:", f.GetLocalName())
|
||||
print(" Progress: %d of %d bytes - completed=%s)" % (bytes, total, done))
|
||||
print()
|
||||
print()
|
121
lib/win32comext/bits/test/test_bits.py
Normal file
121
lib/win32comext/bits/test/test_bits.py
Normal file
|
@ -0,0 +1,121 @@
|
|||
import os
|
||||
import tempfile
|
||||
|
||||
import pythoncom
|
||||
import win32api
|
||||
import win32event
|
||||
from win32com.bits import bits
|
||||
from win32com.server.util import wrap
|
||||
|
||||
TIMEOUT = 200 # ms
|
||||
StopEvent = win32event.CreateEvent(None, 0, 0, None)
|
||||
|
||||
job_name = "bits-pywin32-test"
|
||||
states = dict(
|
||||
[
|
||||
(val, (name[13:]))
|
||||
for name, val in vars(bits).items()
|
||||
if name.startswith("BG_JOB_STATE_")
|
||||
]
|
||||
)
|
||||
|
||||
bcm = pythoncom.CoCreateInstance(
|
||||
bits.CLSID_BackgroundCopyManager,
|
||||
None,
|
||||
pythoncom.CLSCTX_LOCAL_SERVER,
|
||||
bits.IID_IBackgroundCopyManager,
|
||||
)
|
||||
|
||||
|
||||
class BackgroundJobCallback:
|
||||
_com_interfaces_ = [bits.IID_IBackgroundCopyCallback]
|
||||
_public_methods_ = ["JobTransferred", "JobError", "JobModification"]
|
||||
|
||||
def JobTransferred(self, job):
|
||||
print("Job Transferred", job)
|
||||
job.Complete()
|
||||
win32event.SetEvent(StopEvent) # exit msg pump
|
||||
|
||||
def JobError(self, job, error):
|
||||
print("Job Error", job, error)
|
||||
f = error.GetFile()
|
||||
print("While downloading", f.GetRemoteName())
|
||||
print("To", f.GetLocalName())
|
||||
print("The following error happened:")
|
||||
self._print_error(error)
|
||||
if f.GetRemoteName().endswith("missing-favicon.ico"):
|
||||
print("Changing to point to correct file")
|
||||
f2 = f.QueryInterface(bits.IID_IBackgroundCopyFile2)
|
||||
favicon = "http://www.python.org/favicon.ico"
|
||||
print("Changing RemoteName from", f2.GetRemoteName(), "to", favicon)
|
||||
f2.SetRemoteName(favicon)
|
||||
job.Resume()
|
||||
else:
|
||||
job.Cancel()
|
||||
|
||||
def _print_error(self, err):
|
||||
ctx, hresult = err.GetError()
|
||||
try:
|
||||
hresult_msg = win32api.FormatMessage(hresult)
|
||||
except win32api.error:
|
||||
hresult_msg = ""
|
||||
print("Context=0x%x, hresult=0x%x (%s)" % (ctx, hresult, hresult_msg))
|
||||
print(err.GetErrorDescription())
|
||||
|
||||
def JobModification(self, job, reserved):
|
||||
state = job.GetState()
|
||||
print("Job Modification", job.GetDisplayName(), states.get(state))
|
||||
# Need to catch TRANSIENT_ERROR here, as JobError doesn't get
|
||||
# called (apparently) when the error is transient.
|
||||
if state == bits.BG_JOB_STATE_TRANSIENT_ERROR:
|
||||
print("Error details:")
|
||||
err = job.GetError()
|
||||
self._print_error(err)
|
||||
|
||||
|
||||
job = bcm.CreateJob(job_name, bits.BG_JOB_TYPE_DOWNLOAD)
|
||||
|
||||
job.SetNotifyInterface(wrap(BackgroundJobCallback()))
|
||||
job.SetNotifyFlags(
|
||||
bits.BG_NOTIFY_JOB_TRANSFERRED
|
||||
| bits.BG_NOTIFY_JOB_ERROR
|
||||
| bits.BG_NOTIFY_JOB_MODIFICATION
|
||||
)
|
||||
|
||||
|
||||
# The idea here is to intentionally make one of the files fail to be
|
||||
# downloaded. Then the JobError notification will be triggered, where
|
||||
# we do fix the failing file by calling SetRemoteName to a valid URL
|
||||
# and call Resume() on the job, making the job finish successfully.
|
||||
#
|
||||
# Note to self: A domain that cannot be resolved will cause
|
||||
# TRANSIENT_ERROR instead of ERROR, and the JobError notification will
|
||||
# not be triggered! This can bite you during testing depending on how
|
||||
# your DNS is configured. For example, if you use OpenDNS.org's DNS
|
||||
# servers, an invalid hostname will *always* be resolved (they
|
||||
# redirect you to a search page), so be careful when testing.
|
||||
job.AddFile(
|
||||
"http://www.python.org/favicon.ico",
|
||||
os.path.join(tempfile.gettempdir(), "bits-favicon.ico"),
|
||||
)
|
||||
job.AddFile(
|
||||
"http://www.python.org/missing-favicon.ico",
|
||||
os.path.join(tempfile.gettempdir(), "bits-missing-favicon.ico"),
|
||||
)
|
||||
|
||||
for f in job.EnumFiles():
|
||||
print("Downloading", f.GetRemoteName())
|
||||
print("To", f.GetLocalName())
|
||||
|
||||
job.Resume()
|
||||
|
||||
while True:
|
||||
rc = win32event.MsgWaitForMultipleObjects(
|
||||
(StopEvent,), 0, TIMEOUT, win32event.QS_ALLEVENTS
|
||||
)
|
||||
|
||||
if rc == win32event.WAIT_OBJECT_0:
|
||||
break
|
||||
elif rc == win32event.WAIT_OBJECT_0 + 1:
|
||||
if pythoncom.PumpWaitingMessages():
|
||||
break # wm_quit
|
4
lib/win32comext/directsound/__init__.py
Normal file
4
lib/win32comext/directsound/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
# See if we have a special directory for the binaries (for developers)
|
||||
import win32com
|
||||
|
||||
win32com.__PackageSupportBuildPath__(__path__)
|
BIN
lib/win32comext/directsound/directsound.pyd
Normal file
BIN
lib/win32comext/directsound/directsound.pyd
Normal file
Binary file not shown.
1
lib/win32comext/directsound/test/__init__.py
Normal file
1
lib/win32comext/directsound/test/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
# This is a Python package, imported by the win32com test suite.
|
60
lib/win32comext/directsound/test/ds_record.py
Normal file
60
lib/win32comext/directsound/test/ds_record.py
Normal file
|
@ -0,0 +1,60 @@
|
|||
import os
|
||||
import struct
|
||||
|
||||
import pywintypes
|
||||
import win32api
|
||||
import win32com.directsound.directsound as ds
|
||||
import win32event
|
||||
|
||||
|
||||
def wav_header_pack(wfx, datasize):
|
||||
return struct.pack(
|
||||
"<4sl4s4slhhllhh4sl",
|
||||
"RIFF",
|
||||
36 + datasize,
|
||||
"WAVE",
|
||||
"fmt ",
|
||||
16,
|
||||
wfx.wFormatTag,
|
||||
wfx.nChannels,
|
||||
wfx.nSamplesPerSec,
|
||||
wfx.nAvgBytesPerSec,
|
||||
wfx.nBlockAlign,
|
||||
wfx.wBitsPerSample,
|
||||
"data",
|
||||
datasize,
|
||||
)
|
||||
|
||||
|
||||
d = ds.DirectSoundCaptureCreate(None, None)
|
||||
|
||||
sdesc = ds.DSCBUFFERDESC()
|
||||
sdesc.dwBufferBytes = 352800 # 2 seconds
|
||||
sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX()
|
||||
sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM
|
||||
sdesc.lpwfxFormat.nChannels = 2
|
||||
sdesc.lpwfxFormat.nSamplesPerSec = 44100
|
||||
sdesc.lpwfxFormat.nAvgBytesPerSec = 176400
|
||||
sdesc.lpwfxFormat.nBlockAlign = 4
|
||||
sdesc.lpwfxFormat.wBitsPerSample = 16
|
||||
|
||||
print(sdesc)
|
||||
print(d)
|
||||
buffer = d.CreateCaptureBuffer(sdesc)
|
||||
|
||||
event = win32event.CreateEvent(None, 0, 0, None)
|
||||
notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify)
|
||||
|
||||
notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event))
|
||||
|
||||
buffer.Start(0)
|
||||
|
||||
win32event.WaitForSingleObject(event, -1)
|
||||
|
||||
data = buffer.Update(0, 352800)
|
||||
|
||||
fname = os.path.join(win32api.GetTempPath(), "test_directsound_record.wav")
|
||||
f = open(fname, "wb")
|
||||
f.write(wav_header_pack(sdesc.lpwfxFormat, 352800))
|
||||
f.write(data)
|
||||
f.close()
|
402
lib/win32comext/directsound/test/ds_test.py
Normal file
402
lib/win32comext/directsound/test/ds_test.py
Normal file
|
@ -0,0 +1,402 @@
|
|||
import os
|
||||
import struct
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import pythoncom
|
||||
import pywintypes
|
||||
import win32api
|
||||
import win32com.directsound.directsound as ds
|
||||
import win32event
|
||||
from pywin32_testutil import TestSkipped, find_test_fixture
|
||||
|
||||
# next two lines are for for debugging:
|
||||
# import win32com
|
||||
# import directsound as ds
|
||||
|
||||
WAV_FORMAT_PCM = 1
|
||||
WAV_HEADER_SIZE = struct.calcsize("<4sl4s4slhhllhh4sl")
|
||||
|
||||
|
||||
def wav_header_unpack(data):
|
||||
(
|
||||
riff,
|
||||
riffsize,
|
||||
wave,
|
||||
fmt,
|
||||
fmtsize,
|
||||
format,
|
||||
nchannels,
|
||||
samplespersecond,
|
||||
datarate,
|
||||
blockalign,
|
||||
bitspersample,
|
||||
data,
|
||||
datalength,
|
||||
) = struct.unpack("<4sl4s4slhhllhh4sl", data)
|
||||
|
||||
if riff != b"RIFF":
|
||||
raise ValueError("invalid wav header")
|
||||
|
||||
if fmtsize != 16 or fmt != b"fmt " or data != b"data":
|
||||
# fmt chuck is not first chunk, directly followed by data chuck
|
||||
# It is nowhere required that they are, it is just very common
|
||||
raise ValueError("cannot understand wav header")
|
||||
|
||||
wfx = pywintypes.WAVEFORMATEX()
|
||||
wfx.wFormatTag = format
|
||||
wfx.nChannels = nchannels
|
||||
wfx.nSamplesPerSec = samplespersecond
|
||||
wfx.nAvgBytesPerSec = datarate
|
||||
wfx.nBlockAlign = blockalign
|
||||
wfx.wBitsPerSample = bitspersample
|
||||
|
||||
return wfx, datalength
|
||||
|
||||
|
||||
def wav_header_pack(wfx, datasize):
|
||||
return struct.pack(
|
||||
"<4sl4s4slhhllhh4sl",
|
||||
b"RIFF",
|
||||
36 + datasize,
|
||||
b"WAVE",
|
||||
b"fmt ",
|
||||
16,
|
||||
wfx.wFormatTag,
|
||||
wfx.nChannels,
|
||||
wfx.nSamplesPerSec,
|
||||
wfx.nAvgBytesPerSec,
|
||||
wfx.nBlockAlign,
|
||||
wfx.wBitsPerSample,
|
||||
b"data",
|
||||
datasize,
|
||||
)
|
||||
|
||||
|
||||
class WAVEFORMATTest(unittest.TestCase):
|
||||
def test_1_Type(self):
|
||||
"WAVEFORMATEX type"
|
||||
w = pywintypes.WAVEFORMATEX()
|
||||
self.assertTrue(type(w) == pywintypes.WAVEFORMATEXType)
|
||||
|
||||
def test_2_Attr(self):
|
||||
"WAVEFORMATEX attribute access"
|
||||
# A wav header for a soundfile from a CD should look like this...
|
||||
w = pywintypes.WAVEFORMATEX()
|
||||
w.wFormatTag = pywintypes.WAVE_FORMAT_PCM
|
||||
w.nChannels = 2
|
||||
w.nSamplesPerSec = 44100
|
||||
w.nAvgBytesPerSec = 176400
|
||||
w.nBlockAlign = 4
|
||||
w.wBitsPerSample = 16
|
||||
|
||||
self.assertTrue(w.wFormatTag == 1)
|
||||
self.assertTrue(w.nChannels == 2)
|
||||
self.assertTrue(w.nSamplesPerSec == 44100)
|
||||
self.assertTrue(w.nAvgBytesPerSec == 176400)
|
||||
self.assertTrue(w.nBlockAlign == 4)
|
||||
self.assertTrue(w.wBitsPerSample == 16)
|
||||
|
||||
|
||||
class DSCAPSTest(unittest.TestCase):
|
||||
def test_1_Type(self):
|
||||
"DSCAPS type"
|
||||
c = ds.DSCAPS()
|
||||
self.assertTrue(type(c) == ds.DSCAPSType)
|
||||
|
||||
def test_2_Attr(self):
|
||||
"DSCAPS attribute access"
|
||||
c = ds.DSCAPS()
|
||||
c.dwFlags = 1
|
||||
c.dwMinSecondarySampleRate = 2
|
||||
c.dwMaxSecondarySampleRate = 3
|
||||
c.dwPrimaryBuffers = 4
|
||||
c.dwMaxHwMixingAllBuffers = 5
|
||||
c.dwMaxHwMixingStaticBuffers = 6
|
||||
c.dwMaxHwMixingStreamingBuffers = 7
|
||||
c.dwFreeHwMixingAllBuffers = 8
|
||||
c.dwFreeHwMixingStaticBuffers = 9
|
||||
c.dwFreeHwMixingStreamingBuffers = 10
|
||||
c.dwMaxHw3DAllBuffers = 11
|
||||
c.dwMaxHw3DStaticBuffers = 12
|
||||
c.dwMaxHw3DStreamingBuffers = 13
|
||||
c.dwFreeHw3DAllBuffers = 14
|
||||
c.dwFreeHw3DStaticBuffers = 15
|
||||
c.dwFreeHw3DStreamingBuffers = 16
|
||||
c.dwTotalHwMemBytes = 17
|
||||
c.dwFreeHwMemBytes = 18
|
||||
c.dwMaxContigFreeHwMemBytes = 19
|
||||
c.dwUnlockTransferRateHwBuffers = 20
|
||||
c.dwPlayCpuOverheadSwBuffers = 21
|
||||
|
||||
self.assertTrue(c.dwFlags == 1)
|
||||
self.assertTrue(c.dwMinSecondarySampleRate == 2)
|
||||
self.assertTrue(c.dwMaxSecondarySampleRate == 3)
|
||||
self.assertTrue(c.dwPrimaryBuffers == 4)
|
||||
self.assertTrue(c.dwMaxHwMixingAllBuffers == 5)
|
||||
self.assertTrue(c.dwMaxHwMixingStaticBuffers == 6)
|
||||
self.assertTrue(c.dwMaxHwMixingStreamingBuffers == 7)
|
||||
self.assertTrue(c.dwFreeHwMixingAllBuffers == 8)
|
||||
self.assertTrue(c.dwFreeHwMixingStaticBuffers == 9)
|
||||
self.assertTrue(c.dwFreeHwMixingStreamingBuffers == 10)
|
||||
self.assertTrue(c.dwMaxHw3DAllBuffers == 11)
|
||||
self.assertTrue(c.dwMaxHw3DStaticBuffers == 12)
|
||||
self.assertTrue(c.dwMaxHw3DStreamingBuffers == 13)
|
||||
self.assertTrue(c.dwFreeHw3DAllBuffers == 14)
|
||||
self.assertTrue(c.dwFreeHw3DStaticBuffers == 15)
|
||||
self.assertTrue(c.dwFreeHw3DStreamingBuffers == 16)
|
||||
self.assertTrue(c.dwTotalHwMemBytes == 17)
|
||||
self.assertTrue(c.dwFreeHwMemBytes == 18)
|
||||
self.assertTrue(c.dwMaxContigFreeHwMemBytes == 19)
|
||||
self.assertTrue(c.dwUnlockTransferRateHwBuffers == 20)
|
||||
self.assertTrue(c.dwPlayCpuOverheadSwBuffers == 21)
|
||||
|
||||
|
||||
class DSBCAPSTest(unittest.TestCase):
|
||||
def test_1_Type(self):
|
||||
"DSBCAPS type"
|
||||
c = ds.DSBCAPS()
|
||||
self.assertTrue(type(c) == ds.DSBCAPSType)
|
||||
|
||||
def test_2_Attr(self):
|
||||
"DSBCAPS attribute access"
|
||||
c = ds.DSBCAPS()
|
||||
c.dwFlags = 1
|
||||
c.dwBufferBytes = 2
|
||||
c.dwUnlockTransferRate = 3
|
||||
c.dwPlayCpuOverhead = 4
|
||||
|
||||
self.assertTrue(c.dwFlags == 1)
|
||||
self.assertTrue(c.dwBufferBytes == 2)
|
||||
self.assertTrue(c.dwUnlockTransferRate == 3)
|
||||
self.assertTrue(c.dwPlayCpuOverhead == 4)
|
||||
|
||||
|
||||
class DSCCAPSTest(unittest.TestCase):
|
||||
def test_1_Type(self):
|
||||
"DSCCAPS type"
|
||||
c = ds.DSCCAPS()
|
||||
self.assertTrue(type(c) == ds.DSCCAPSType)
|
||||
|
||||
def test_2_Attr(self):
|
||||
"DSCCAPS attribute access"
|
||||
c = ds.DSCCAPS()
|
||||
c.dwFlags = 1
|
||||
c.dwFormats = 2
|
||||
c.dwChannels = 4
|
||||
|
||||
self.assertTrue(c.dwFlags == 1)
|
||||
self.assertTrue(c.dwFormats == 2)
|
||||
self.assertTrue(c.dwChannels == 4)
|
||||
|
||||
|
||||
class DSCBCAPSTest(unittest.TestCase):
|
||||
def test_1_Type(self):
|
||||
"DSCBCAPS type"
|
||||
c = ds.DSCBCAPS()
|
||||
self.assertTrue(type(c) == ds.DSCBCAPSType)
|
||||
|
||||
def test_2_Attr(self):
|
||||
"DSCBCAPS attribute access"
|
||||
c = ds.DSCBCAPS()
|
||||
c.dwFlags = 1
|
||||
c.dwBufferBytes = 2
|
||||
|
||||
self.assertTrue(c.dwFlags == 1)
|
||||
self.assertTrue(c.dwBufferBytes == 2)
|
||||
|
||||
|
||||
class DSBUFFERDESCTest(unittest.TestCase):
|
||||
def test_1_Type(self):
|
||||
"DSBUFFERDESC type"
|
||||
c = ds.DSBUFFERDESC()
|
||||
self.assertTrue(type(c) == ds.DSBUFFERDESCType)
|
||||
|
||||
def test_2_Attr(self):
|
||||
"DSBUFFERDESC attribute access"
|
||||
c = ds.DSBUFFERDESC()
|
||||
c.dwFlags = 1
|
||||
c.dwBufferBytes = 2
|
||||
c.lpwfxFormat = pywintypes.WAVEFORMATEX()
|
||||
c.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM
|
||||
c.lpwfxFormat.nChannels = 2
|
||||
c.lpwfxFormat.nSamplesPerSec = 44100
|
||||
c.lpwfxFormat.nAvgBytesPerSec = 176400
|
||||
c.lpwfxFormat.nBlockAlign = 4
|
||||
c.lpwfxFormat.wBitsPerSample = 16
|
||||
|
||||
self.assertTrue(c.dwFlags == 1)
|
||||
self.assertTrue(c.dwBufferBytes == 2)
|
||||
self.assertTrue(c.lpwfxFormat.wFormatTag == 1)
|
||||
self.assertTrue(c.lpwfxFormat.nChannels == 2)
|
||||
self.assertTrue(c.lpwfxFormat.nSamplesPerSec == 44100)
|
||||
self.assertTrue(c.lpwfxFormat.nAvgBytesPerSec == 176400)
|
||||
self.assertTrue(c.lpwfxFormat.nBlockAlign == 4)
|
||||
self.assertTrue(c.lpwfxFormat.wBitsPerSample == 16)
|
||||
|
||||
def invalid_format(self, c):
|
||||
c.lpwfxFormat = 17
|
||||
|
||||
def test_3_invalid_format(self):
|
||||
"DSBUFFERDESC invalid lpwfxFormat assignment"
|
||||
c = ds.DSBUFFERDESC()
|
||||
self.assertRaises(ValueError, self.invalid_format, c)
|
||||
|
||||
|
||||
class DSCBUFFERDESCTest(unittest.TestCase):
|
||||
def test_1_Type(self):
|
||||
"DSCBUFFERDESC type"
|
||||
c = ds.DSCBUFFERDESC()
|
||||
self.assertTrue(type(c) == ds.DSCBUFFERDESCType)
|
||||
|
||||
def test_2_Attr(self):
|
||||
"DSCBUFFERDESC attribute access"
|
||||
c = ds.DSCBUFFERDESC()
|
||||
c.dwFlags = 1
|
||||
c.dwBufferBytes = 2
|
||||
c.lpwfxFormat = pywintypes.WAVEFORMATEX()
|
||||
c.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM
|
||||
c.lpwfxFormat.nChannels = 2
|
||||
c.lpwfxFormat.nSamplesPerSec = 44100
|
||||
c.lpwfxFormat.nAvgBytesPerSec = 176400
|
||||
c.lpwfxFormat.nBlockAlign = 4
|
||||
c.lpwfxFormat.wBitsPerSample = 16
|
||||
|
||||
self.assertTrue(c.dwFlags == 1)
|
||||
self.assertTrue(c.dwBufferBytes == 2)
|
||||
self.assertTrue(c.lpwfxFormat.wFormatTag == 1)
|
||||
self.assertTrue(c.lpwfxFormat.nChannels == 2)
|
||||
self.assertTrue(c.lpwfxFormat.nSamplesPerSec == 44100)
|
||||
self.assertTrue(c.lpwfxFormat.nAvgBytesPerSec == 176400)
|
||||
self.assertTrue(c.lpwfxFormat.nBlockAlign == 4)
|
||||
self.assertTrue(c.lpwfxFormat.wBitsPerSample == 16)
|
||||
|
||||
def invalid_format(self, c):
|
||||
c.lpwfxFormat = 17
|
||||
|
||||
def test_3_invalid_format(self):
|
||||
"DSCBUFFERDESC invalid lpwfxFormat assignment"
|
||||
c = ds.DSCBUFFERDESC()
|
||||
self.assertRaises(ValueError, self.invalid_format, c)
|
||||
|
||||
|
||||
class DirectSoundTest(unittest.TestCase):
|
||||
# basic tests - mostly just exercise the functions
|
||||
def testEnumerate(self):
|
||||
"""DirectSoundEnumerate() sanity tests"""
|
||||
|
||||
devices = ds.DirectSoundEnumerate()
|
||||
# this might fail on machines without a sound card
|
||||
self.assertTrue(len(devices))
|
||||
# if we have an entry, it must be a tuple of size 3
|
||||
self.assertTrue(len(devices[0]) == 3)
|
||||
|
||||
def testCreate(self):
|
||||
"""DirectSoundCreate()"""
|
||||
try:
|
||||
d = ds.DirectSoundCreate(None, None)
|
||||
except pythoncom.com_error as exc:
|
||||
if exc.hresult != ds.DSERR_NODRIVER:
|
||||
raise
|
||||
raise TestSkipped(exc)
|
||||
|
||||
def testPlay(self):
|
||||
"""Mesdames et Messieurs, la cour de Devin Dazzle"""
|
||||
# relative to 'testall.py' in the win32com test suite.
|
||||
extra = os.path.join(
|
||||
os.path.dirname(sys.argv[0]), "../../win32comext/directsound/test"
|
||||
)
|
||||
|
||||
fname = find_test_fixture("01-Intro.wav", extra)
|
||||
|
||||
with open(fname, "rb") as f:
|
||||
hdr = f.read(WAV_HEADER_SIZE)
|
||||
wfx, size = wav_header_unpack(hdr)
|
||||
|
||||
try:
|
||||
d = ds.DirectSoundCreate(None, None)
|
||||
except pythoncom.com_error as exc:
|
||||
if exc.hresult != ds.DSERR_NODRIVER:
|
||||
raise
|
||||
raise TestSkipped(exc)
|
||||
d.SetCooperativeLevel(None, ds.DSSCL_PRIORITY)
|
||||
|
||||
sdesc = ds.DSBUFFERDESC()
|
||||
sdesc.dwFlags = ds.DSBCAPS_STICKYFOCUS | ds.DSBCAPS_CTRLPOSITIONNOTIFY
|
||||
sdesc.dwBufferBytes = size
|
||||
sdesc.lpwfxFormat = wfx
|
||||
|
||||
buffer = d.CreateSoundBuffer(sdesc, None)
|
||||
|
||||
event = win32event.CreateEvent(None, 0, 0, None)
|
||||
notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify)
|
||||
|
||||
notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event))
|
||||
|
||||
buffer.Update(0, f.read(size))
|
||||
|
||||
buffer.Play(0)
|
||||
|
||||
win32event.WaitForSingleObject(event, -1)
|
||||
|
||||
|
||||
class DirectSoundCaptureTest(unittest.TestCase):
|
||||
# basic tests - mostly just exercise the functions
|
||||
def testEnumerate(self):
|
||||
"""DirectSoundCaptureEnumerate() sanity tests"""
|
||||
|
||||
devices = ds.DirectSoundCaptureEnumerate()
|
||||
# this might fail on machines without a sound card
|
||||
self.assertTrue(len(devices))
|
||||
# if we have an entry, it must be a tuple of size 3
|
||||
self.assertTrue(len(devices[0]) == 3)
|
||||
|
||||
def testCreate(self):
|
||||
"""DirectSoundCreate()"""
|
||||
try:
|
||||
d = ds.DirectSoundCaptureCreate(None, None)
|
||||
except pythoncom.com_error as exc:
|
||||
if exc.hresult != ds.DSERR_NODRIVER:
|
||||
raise
|
||||
raise TestSkipped(exc)
|
||||
|
||||
def testRecord(self):
|
||||
try:
|
||||
d = ds.DirectSoundCaptureCreate(None, None)
|
||||
except pythoncom.com_error as exc:
|
||||
if exc.hresult != ds.DSERR_NODRIVER:
|
||||
raise
|
||||
raise TestSkipped(exc)
|
||||
|
||||
sdesc = ds.DSCBUFFERDESC()
|
||||
sdesc.dwBufferBytes = 352800 # 2 seconds
|
||||
sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX()
|
||||
sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM
|
||||
sdesc.lpwfxFormat.nChannels = 2
|
||||
sdesc.lpwfxFormat.nSamplesPerSec = 44100
|
||||
sdesc.lpwfxFormat.nAvgBytesPerSec = 176400
|
||||
sdesc.lpwfxFormat.nBlockAlign = 4
|
||||
sdesc.lpwfxFormat.wBitsPerSample = 16
|
||||
|
||||
buffer = d.CreateCaptureBuffer(sdesc)
|
||||
|
||||
event = win32event.CreateEvent(None, 0, 0, None)
|
||||
notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify)
|
||||
|
||||
notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event))
|
||||
|
||||
buffer.Start(0)
|
||||
|
||||
win32event.WaitForSingleObject(event, -1)
|
||||
event.Close()
|
||||
|
||||
data = buffer.Update(0, 352800)
|
||||
fname = os.path.join(win32api.GetTempPath(), "test_directsound_record.wav")
|
||||
f = open(fname, "wb")
|
||||
f.write(wav_header_pack(sdesc.lpwfxFormat, 352800))
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
1
lib/win32comext/ifilter/__init__.py
Normal file
1
lib/win32comext/ifilter/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
# empty file to designate as a package.
|
300
lib/win32comext/ifilter/demo/filterDemo.py
Normal file
300
lib/win32comext/ifilter/demo/filterDemo.py
Normal file
|
@ -0,0 +1,300 @@
|
|||
import pythoncom
|
||||
import pywintypes
|
||||
from win32com import storagecon
|
||||
from win32com.ifilter import ifilter
|
||||
from win32com.ifilter.ifiltercon import *
|
||||
|
||||
|
||||
class FileParser:
|
||||
# Property IDs for the Storage Property Set
|
||||
PIDS_BODY = 0x00000013
|
||||
|
||||
# property IDs for HTML Storage Property Set
|
||||
PIDH_DESCRIPTION = "DESCRIPTION"
|
||||
PIDH_HREF = "A.HREF"
|
||||
PIDH_IMGSRC = "IMG.SRC"
|
||||
|
||||
# conversion map to convert ifilter properties to more user friendly names
|
||||
propertyToName = {
|
||||
PSGUID_STORAGE: {PIDS_BODY: "body"},
|
||||
PSGUID_SUMMARYINFORMATION: {
|
||||
PIDSI_TITLE: "title",
|
||||
PIDSI_SUBJECT: "description",
|
||||
PIDSI_AUTHOR: "author",
|
||||
PIDSI_KEYWORDS: "keywords",
|
||||
PIDSI_COMMENTS: "comments",
|
||||
},
|
||||
PSGUID_HTMLINFORMATION: {PIDH_DESCRIPTION: "description"},
|
||||
PSGUID_HTML2_INFORMATION: {PIDH_HREF: "href", PIDH_IMGSRC: "img"},
|
||||
}
|
||||
|
||||
def __init__(self, verbose=False):
|
||||
self.f = None
|
||||
self.stg = None
|
||||
self.verbose = verbose
|
||||
|
||||
def Close(self):
|
||||
self.f = None
|
||||
self.stg = None
|
||||
|
||||
def Parse(self, fileName, maxErrors=10):
|
||||
properties = {}
|
||||
|
||||
try:
|
||||
self._bind_to_filter(fileName)
|
||||
try:
|
||||
flags = self.f.Init(
|
||||
IFILTER_INIT_APPLY_INDEX_ATTRIBUTES
|
||||
| IFILTER_INIT_APPLY_OTHER_ATTRIBUTES
|
||||
)
|
||||
if flags == IFILTER_FLAGS_OLE_PROPERTIES and self.stg is not None:
|
||||
self._trace("filter requires to get properities via ole")
|
||||
self._get_properties(properties)
|
||||
|
||||
errCnt = 0
|
||||
while True:
|
||||
try:
|
||||
# each chunk returns a tuple with the following:-
|
||||
# idChunk = The chunk identifier. each chunk has a unique identifier
|
||||
# breakType = The type of break that separates the previous chunk from the current chunk. Values are:-
|
||||
# CHUNK_NO_BREAK=0,CHUNK_EOW=1,CHUNK_EOS= 2,CHUNK_EOP= 3,CHUNK_EOC= 4
|
||||
# flags = Flags indicate whether this chunk contains a text-type or a value-type property
|
||||
# locale = The language and sublanguage associated with a chunk of text
|
||||
# attr = A tuple containing the property to be applied to the chunk. Tuple is (propertyset GUID, property ID)
|
||||
# Property ID can be a number or string
|
||||
# idChunkSource = The ID of the source of a chunk. The value of the idChunkSource member depends on the nature of the chunk
|
||||
# startSource = The offset from which the source text for a derived chunk starts in the source chunk
|
||||
# lenSource = The length in characters of the source text from which the current chunk was derived.
|
||||
# A zero value signifies character-by-character correspondence between the source text and the derived text.
|
||||
|
||||
(
|
||||
idChunk,
|
||||
breakType,
|
||||
flags,
|
||||
locale,
|
||||
attr,
|
||||
idChunkSource,
|
||||
startSource,
|
||||
lenSource,
|
||||
) = self.f.GetChunk()
|
||||
self._trace(
|
||||
"Chunk details:",
|
||||
idChunk,
|
||||
breakType,
|
||||
flags,
|
||||
locale,
|
||||
attr,
|
||||
idChunkSource,
|
||||
startSource,
|
||||
lenSource,
|
||||
)
|
||||
|
||||
# attempt to map each property to a more user friendly name. If we don't know what it is just return
|
||||
# the set guid and property id. (note: the id can be a number or a string.
|
||||
propSet = self.propertyToName.get(attr[0])
|
||||
if propSet:
|
||||
propName = propSet.get(attr[1], "%s:%s" % attr)
|
||||
else:
|
||||
propName = "%s:%s" % attr
|
||||
|
||||
except pythoncom.com_error as e:
|
||||
if e[0] == FILTER_E_END_OF_CHUNKS:
|
||||
# we have read all the chunks
|
||||
break
|
||||
elif e[0] in [
|
||||
FILTER_E_EMBEDDING_UNAVAILABLE,
|
||||
FILTER_E_LINK_UNAVAILABLE,
|
||||
]:
|
||||
# the next chunk can't be read. Also keep track of the number of times we
|
||||
# fail as some filters (ie. the Msoft office ones can get stuck here)
|
||||
errCnt += 1
|
||||
if errCnt > maxErrors:
|
||||
raise
|
||||
else:
|
||||
continue
|
||||
elif e[0] == FILTER_E_ACCESS:
|
||||
self._trace("Access denied")
|
||||
raise
|
||||
elif e[0] == FILTER_E_PASSWORD:
|
||||
self._trace("Password required")
|
||||
raise
|
||||
else:
|
||||
# any other type of error really can't be recovered from
|
||||
raise
|
||||
|
||||
# reset consecutive errors (some filters may get stuck in a lopp if embedding or link failures occurs
|
||||
errCnt = 0
|
||||
|
||||
if flags == CHUNK_TEXT:
|
||||
# its a text segment - get all available text for this chunk.
|
||||
body_chunks = properties.setdefault(propName, [])
|
||||
self._get_text(body_chunks)
|
||||
elif flags == CHUNK_VALUE:
|
||||
# its a data segment - get the value
|
||||
properties[propName] = self.f.GetValue()
|
||||
else:
|
||||
self._trace("Unknown flag returned by GetChunk:", flags)
|
||||
finally:
|
||||
self.Close()
|
||||
|
||||
except pythoncom.com_error as e:
|
||||
self._trace("ERROR processing file", e)
|
||||
raise
|
||||
|
||||
return properties
|
||||
|
||||
def _bind_to_filter(self, fileName):
|
||||
"""
|
||||
See if the file is a structured storage file or a normal file
|
||||
and then return an ifilter interface by calling the appropriate bind/load function
|
||||
"""
|
||||
if pythoncom.StgIsStorageFile(fileName):
|
||||
self.stg = pythoncom.StgOpenStorage(
|
||||
fileName, None, storagecon.STGM_READ | storagecon.STGM_SHARE_DENY_WRITE
|
||||
)
|
||||
try:
|
||||
self.f = ifilter.BindIFilterFromStorage(self.stg)
|
||||
except pythoncom.com_error as e:
|
||||
if (
|
||||
e[0] == -2147467262
|
||||
): # 0x80004002: # no interface, try the load interface (this happens for some MSoft files)
|
||||
self.f = ifilter.LoadIFilter(fileName)
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
self.f = ifilter.LoadIFilter(fileName)
|
||||
self.stg = None
|
||||
|
||||
def _get_text(self, body_chunks):
|
||||
"""
|
||||
Gets all the text for a particular chunk. We need to keep calling get text till all the
|
||||
segments for this chunk are retrieved
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
body_chunks.append(self.f.GetText())
|
||||
except pythoncom.com_error as e:
|
||||
if e[0] in [
|
||||
FILTER_E_NO_MORE_TEXT,
|
||||
FILTER_E_NO_MORE_TEXT,
|
||||
FILTER_E_NO_TEXT,
|
||||
]:
|
||||
break
|
||||
else:
|
||||
raise # not one of the values we were expecting
|
||||
|
||||
def _get_properties(self, properties):
|
||||
"""
|
||||
Use OLE property sets to get base properties
|
||||
"""
|
||||
try:
|
||||
pss = self.stg.QueryInterface(pythoncom.IID_IPropertySetStorage)
|
||||
except pythoncom.com_error as e:
|
||||
self._trace("No Property information could be retrieved", e)
|
||||
return
|
||||
|
||||
ps = pss.Open(PSGUID_SUMMARYINFORMATION)
|
||||
|
||||
props = (
|
||||
PIDSI_TITLE,
|
||||
PIDSI_SUBJECT,
|
||||
PIDSI_AUTHOR,
|
||||
PIDSI_KEYWORDS,
|
||||
PIDSI_COMMENTS,
|
||||
)
|
||||
|
||||
title, subject, author, keywords, comments = ps.ReadMultiple(props)
|
||||
if title is not None:
|
||||
properties["title"] = title
|
||||
if subject is not None:
|
||||
properties["description"] = subject
|
||||
if author is not None:
|
||||
properties["author"] = author
|
||||
if keywords is not None:
|
||||
properties["keywords"] = keywords
|
||||
if comments is not None:
|
||||
properties["comments"] = comments
|
||||
|
||||
def _trace(self, *args):
|
||||
if self.verbose:
|
||||
ret = " ".join([str(arg) for arg in args])
|
||||
try:
|
||||
print(ret)
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
|
||||
def _usage():
|
||||
import os
|
||||
|
||||
print("Usage: %s filename [verbose [dumpbody]]" % (os.path.basename(sys.argv[0]),))
|
||||
print()
|
||||
print("Where:-")
|
||||
print("filename = name of the file to extract text & properties from")
|
||||
print("verbose = 1=debug output, 0=no debug output (default=0)")
|
||||
print("dumpbody = 1=print text content, 0=don't print content (default=1)")
|
||||
print()
|
||||
print("e.g. to dump a word file called spam.doc go:- filterDemo.py spam.doc")
|
||||
print()
|
||||
print("by default .htm, .txt, .doc, .dot, .xls, .xlt, .ppt are supported")
|
||||
print("you can filter .pdf's by downloading adobes ifilter component. ")
|
||||
print(
|
||||
"(currently found at http://download.adobe.com/pub/adobe/acrobat/win/all/ifilter50.exe)."
|
||||
)
|
||||
print("ifilters for other filetypes are also available.")
|
||||
print()
|
||||
print(
|
||||
"This extension is only supported on win2000 & winXP - because thats the only"
|
||||
)
|
||||
print("place the ifilter stuff is supported. For more info on the API check out ")
|
||||
print("MSDN under ifilters")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import operator
|
||||
import sys
|
||||
|
||||
fName = ""
|
||||
verbose = False
|
||||
bDumpBody = True
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
_usage()
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
fName = sys.argv[1]
|
||||
verbose = sys.argv[2] != "0"
|
||||
bDumpBody = sys.argv[3] != "0"
|
||||
except:
|
||||
pass
|
||||
|
||||
p = FileParser(verbose)
|
||||
propMap = p.Parse(fName)
|
||||
|
||||
if bDumpBody:
|
||||
print("Body")
|
||||
ch = " ".join(propMap.get("body", []))
|
||||
try:
|
||||
print(ch)
|
||||
except UnicodeError:
|
||||
print(ch.encode("iso8859-1", "ignore"))
|
||||
|
||||
print("Properties")
|
||||
for propName, propValue in propMap.items():
|
||||
print(propName, ":", end=" ")
|
||||
if propName == "body":
|
||||
print(
|
||||
"<%s length: %d>"
|
||||
% (
|
||||
propName,
|
||||
reduce(operator.add, [len(p) for p in propValue]),
|
||||
)
|
||||
)
|
||||
elif type(propValue) == type([]):
|
||||
print()
|
||||
for pv in propValue:
|
||||
print(pv)
|
||||
else:
|
||||
print(propValue)
|
||||
print()
|
BIN
lib/win32comext/ifilter/ifilter.pyd
Normal file
BIN
lib/win32comext/ifilter/ifilter.pyd
Normal file
Binary file not shown.
110
lib/win32comext/ifilter/ifiltercon.py
Normal file
110
lib/win32comext/ifilter/ifiltercon.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
# manual stuff
|
||||
from pywintypes import IID
|
||||
|
||||
PSGUID_STORAGE = IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}")
|
||||
PSGUID_SUMMARYINFORMATION = IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}")
|
||||
PSGUID_HTMLINFORMATION = IID("{D1B5D3F0-C0B3-11CF-9A92-00A0C908DBF1}")
|
||||
PSGUID_HTML2_INFORMATION = IID("{C82BF597-B831-11D0-B733-00AA00A1EBD2}")
|
||||
|
||||
IFILTER_INIT_CANON_PARAGRAPHS = 1
|
||||
IFILTER_INIT_HARD_LINE_BREAKS = 2
|
||||
IFILTER_INIT_CANON_HYPHENS = 4
|
||||
IFILTER_INIT_CANON_SPACES = 8
|
||||
IFILTER_INIT_APPLY_INDEX_ATTRIBUTES = 16
|
||||
IFILTER_INIT_APPLY_CRAWL_ATTRIBUTES = 256
|
||||
IFILTER_INIT_APPLY_OTHER_ATTRIBUTES = 32
|
||||
IFILTER_INIT_INDEXING_ONLY = 64
|
||||
IFILTER_INIT_SEARCH_LINKS = 128
|
||||
IFILTER_INIT_FILTER_OWNED_VALUE_OK = 512
|
||||
|
||||
IFILTER_FLAGS_OLE_PROPERTIES = 1
|
||||
|
||||
CHUNK_TEXT = 0x1
|
||||
CHUNK_VALUE = 0x2
|
||||
CHUNK_NO_BREAK = 0
|
||||
CHUNK_EOW = 1
|
||||
CHUNK_EOS = 2
|
||||
CHUNK_EOP = 3
|
||||
CHUNK_EOC = 4
|
||||
|
||||
NOT_AN_ERROR = 0x00080000
|
||||
FILTER_E_END_OF_CHUNKS = -2147215616
|
||||
FILTER_E_NO_MORE_TEXT = -2147215615
|
||||
FILTER_E_NO_MORE_VALUES = -2147215614
|
||||
FILTER_E_ACCESS = -2147215613
|
||||
FILTER_W_MONIKER_CLIPPED = 0x00041704
|
||||
FILTER_E_NO_TEXT = -2147215611
|
||||
FILTER_E_NO_VALUES = -2147215610
|
||||
FILTER_E_EMBEDDING_UNAVAILABLE = -2147215609
|
||||
FILTER_E_LINK_UNAVAILABLE = -2147215608
|
||||
FILTER_S_LAST_TEXT = 0x00041709
|
||||
FILTER_S_LAST_VALUES = 0x0004170A
|
||||
FILTER_E_PASSWORD = -2147215605
|
||||
FILTER_E_UNKNOWNFORMAT = -2147215604
|
||||
|
||||
# Generated by h2py from PropIdl.h
|
||||
PROPSETFLAG_DEFAULT = 0
|
||||
PROPSETFLAG_NONSIMPLE = 1
|
||||
PROPSETFLAG_ANSI = 2
|
||||
PROPSETFLAG_UNBUFFERED = 4
|
||||
PROPSETFLAG_CASE_SENSITIVE = 8
|
||||
PROPSET_BEHAVIOR_CASE_SENSITIVE = 1
|
||||
PID_DICTIONARY = 0
|
||||
PID_CODEPAGE = 0x1
|
||||
PID_FIRST_USABLE = 0x2
|
||||
PID_FIRST_NAME_DEFAULT = 0xFFF
|
||||
PID_LOCALE = -2147483648
|
||||
PID_MODIFY_TIME = -2147483647
|
||||
PID_SECURITY = -2147483646
|
||||
PID_BEHAVIOR = -2147483645
|
||||
PID_ILLEGAL = -1
|
||||
PID_MIN_READONLY = -2147483648
|
||||
PID_MAX_READONLY = -1073741825
|
||||
PIDDI_THUMBNAIL = 0x00000002
|
||||
PIDSI_TITLE = 0x00000002
|
||||
PIDSI_SUBJECT = 0x00000003
|
||||
PIDSI_AUTHOR = 0x00000004
|
||||
PIDSI_KEYWORDS = 0x00000005
|
||||
PIDSI_COMMENTS = 0x00000006
|
||||
PIDSI_TEMPLATE = 0x00000007
|
||||
PIDSI_LASTAUTHOR = 0x00000008
|
||||
PIDSI_REVNUMBER = 0x00000009
|
||||
PIDSI_EDITTIME = 0x0000000A
|
||||
PIDSI_LASTPRINTED = 0x0000000B
|
||||
PIDSI_CREATE_DTM = 0x0000000C
|
||||
PIDSI_LASTSAVE_DTM = 0x0000000D
|
||||
PIDSI_PAGECOUNT = 0x0000000E
|
||||
PIDSI_WORDCOUNT = 0x0000000F
|
||||
PIDSI_CHARCOUNT = 0x00000010
|
||||
PIDSI_THUMBNAIL = 0x00000011
|
||||
PIDSI_APPNAME = 0x00000012
|
||||
PIDSI_DOC_SECURITY = 0x00000013
|
||||
PIDDSI_CATEGORY = 0x00000002
|
||||
PIDDSI_PRESFORMAT = 0x00000003
|
||||
PIDDSI_BYTECOUNT = 0x00000004
|
||||
PIDDSI_LINECOUNT = 0x00000005
|
||||
PIDDSI_PARCOUNT = 0x00000006
|
||||
PIDDSI_SLIDECOUNT = 0x00000007
|
||||
PIDDSI_NOTECOUNT = 0x00000008
|
||||
PIDDSI_HIDDENCOUNT = 0x00000009
|
||||
PIDDSI_MMCLIPCOUNT = 0x0000000A
|
||||
PIDDSI_SCALE = 0x0000000B
|
||||
PIDDSI_HEADINGPAIR = 0x0000000C
|
||||
PIDDSI_DOCPARTS = 0x0000000D
|
||||
PIDDSI_MANAGER = 0x0000000E
|
||||
PIDDSI_COMPANY = 0x0000000F
|
||||
PIDDSI_LINKSDIRTY = 0x00000010
|
||||
PIDMSI_EDITOR = 0x00000002
|
||||
PIDMSI_SUPPLIER = 0x00000003
|
||||
PIDMSI_SOURCE = 0x00000004
|
||||
PIDMSI_SEQUENCE_NO = 0x00000005
|
||||
PIDMSI_PROJECT = 0x00000006
|
||||
PIDMSI_STATUS = 0x00000007
|
||||
PIDMSI_OWNER = 0x00000008
|
||||
PIDMSI_RATING = 0x00000009
|
||||
PIDMSI_PRODUCTION = 0x0000000A
|
||||
PIDMSI_COPYRIGHT = 0x0000000B
|
||||
PRSPEC_INVALID = -1
|
||||
PRSPEC_LPWSTR = 0
|
||||
PRSPEC_PROPID = 1
|
||||
CCH_MAX_PROPSTG_NAME = 31
|
4
lib/win32comext/internet/__init__.py
Normal file
4
lib/win32comext/internet/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
# See if we have a special directory for the binaries (for developers)
|
||||
import win32com
|
||||
|
||||
win32com.__PackageSupportBuildPath__(__path__)
|
261
lib/win32comext/internet/inetcon.py
Normal file
261
lib/win32comext/internet/inetcon.py
Normal file
|
@ -0,0 +1,261 @@
|
|||
INET_E_USE_DEFAULT_PROTOCOLHANDLER = -2146697199 # _HRESULT_TYPEDEF_(0x800C0011L)
|
||||
INET_E_USE_DEFAULT_SETTING = -2146697198 # _HRESULT_TYPEDEF_(0x800C0012L)
|
||||
INET_E_DEFAULT_ACTION = INET_E_USE_DEFAULT_PROTOCOLHANDLER
|
||||
INET_E_QUERYOPTION_UNKNOWN = -2146697197 # _HRESULT_TYPEDEF_(0x800C0013L)
|
||||
INET_E_REDIRECTING = -2146697196 # _HRESULT_TYPEDEF_(0x800C0014L)
|
||||
|
||||
INET_E_INVALID_URL = -2146697214 # _HRESULT_TYPEDEF_(0x800C0002L)
|
||||
INET_E_NO_SESSION = -2146697213 # _HRESULT_TYPEDEF_(0x800C0003L)
|
||||
INET_E_CANNOT_CONNECT = -2146697212 # _HRESULT_TYPEDEF_(0x800C0004L)
|
||||
INET_E_RESOURCE_NOT_FOUND = -2146697211 # _HRESULT_TYPEDEF_(0x800C0005L)
|
||||
INET_E_OBJECT_NOT_FOUND = -2146697210 # _HRESULT_TYPEDEF_(0x800C0006L)
|
||||
INET_E_DATA_NOT_AVAILABLE = -2146697209 # _HRESULT_TYPEDEF_(0x800C0007L)
|
||||
INET_E_DOWNLOAD_FAILURE = -2146697208 # _HRESULT_TYPEDEF_(0x800C0008L)
|
||||
INET_E_AUTHENTICATION_REQUIRED = -2146697207 # _HRESULT_TYPEDEF_(0x800C0009L)
|
||||
INET_E_NO_VALID_MEDIA = -2146697206 # _HRESULT_TYPEDEF_(0x800C000AL)
|
||||
INET_E_CONNECTION_TIMEOUT = -2146697205 # _HRESULT_TYPEDEF_(0x800C000BL)
|
||||
INET_E_INVALID_REQUEST = -2146697204 # _HRESULT_TYPEDEF_(0x800C000CL)
|
||||
INET_E_UNKNOWN_PROTOCOL = -2146697203 # _HRESULT_TYPEDEF_(0x800C000DL)
|
||||
INET_E_SECURITY_PROBLEM = -2146697202 # _HRESULT_TYPEDEF_(0x800C000EL)
|
||||
INET_E_CANNOT_LOAD_DATA = -2146697201 # _HRESULT_TYPEDEF_(0x800C000FL)
|
||||
INET_E_CANNOT_INSTANTIATE_OBJECT = -2146697200 # _HRESULT_TYPEDEF_(0x800C0010L)
|
||||
INET_E_INVALID_CERTIFICATE = -2146697191 # _HRESULT_TYPEDEF_(0x800C0019L)
|
||||
INET_E_REDIRECT_FAILED = -2146697196 # _HRESULT_TYPEDEF_(0x800C0014L)
|
||||
INET_E_REDIRECT_TO_DIR = -2146697195 # _HRESULT_TYPEDEF_(0x800C0015L)
|
||||
INET_E_CANNOT_LOCK_REQUEST = -2146697194 # _HRESULT_TYPEDEF_(0x800C0016L)
|
||||
INET_E_USE_EXTEND_BINDING = -2146697193 # _HRESULT_TYPEDEF_(0x800C0017L)
|
||||
INET_E_TERMINATED_BIND = -2146697192 # _HRESULT_TYPEDEF_(0x800C0018L)
|
||||
INET_E_CODE_DOWNLOAD_DECLINED = -2146696960 # _HRESULT_TYPEDEF_(0x800C0100L)
|
||||
INET_E_RESULT_DISPATCHED = -2146696704 # _HRESULT_TYPEDEF_(0x800C0200L)
|
||||
INET_E_CANNOT_REPLACE_SFP_FILE = -2146696448 # _HRESULT_TYPEDEF_(0x800C0300L)
|
||||
INET_E_CODE_INSTALL_SUPPRESSED = -2146696192 # _HRESULT_TYPEDEF_(0x800C0400L)
|
||||
INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY = (
|
||||
-2146695936
|
||||
) # _HRESULT_TYPEDEF_(0x800C0500L)
|
||||
|
||||
# Generated by h2py from UrlMon.h
|
||||
MKSYS_URLMONIKER = 6
|
||||
URL_MK_LEGACY = 0
|
||||
URL_MK_UNIFORM = 1
|
||||
URL_MK_NO_CANONICALIZE = 2
|
||||
FIEF_FLAG_FORCE_JITUI = 0x1
|
||||
FIEF_FLAG_PEEK = 0x2
|
||||
FIEF_FLAG_SKIP_INSTALLED_VERSION_CHECK = 0x4
|
||||
FMFD_DEFAULT = 0x00000000
|
||||
FMFD_URLASFILENAME = 0x00000001
|
||||
FMFD_ENABLEMIMESNIFFING = 0x00000002
|
||||
FMFD_IGNOREMIMETEXTPLAIN = 0x00000004
|
||||
URLMON_OPTION_USERAGENT = 0x10000001
|
||||
URLMON_OPTION_USERAGENT_REFRESH = 0x10000002
|
||||
URLMON_OPTION_URL_ENCODING = 0x10000004
|
||||
URLMON_OPTION_USE_BINDSTRINGCREDS = 0x10000008
|
||||
URLMON_OPTION_USE_BROWSERAPPSDOCUMENTS = 0x10000010
|
||||
CF_NULL = 0
|
||||
Uri_CREATE_ALLOW_RELATIVE = 0x00000001
|
||||
Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME = 0x00000002
|
||||
Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME = 0x00000004
|
||||
Uri_CREATE_NOFRAG = 0x00000008
|
||||
Uri_CREATE_NO_CANONICALIZE = 0x00000010
|
||||
Uri_CREATE_CANONICALIZE = 0x00000100
|
||||
Uri_CREATE_FILE_USE_DOS_PATH = 0x00000020
|
||||
Uri_CREATE_DECODE_EXTRA_INFO = 0x00000040
|
||||
Uri_CREATE_NO_DECODE_EXTRA_INFO = 0x00000080
|
||||
Uri_CREATE_CRACK_UNKNOWN_SCHEMES = 0x00000200
|
||||
Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES = 0x00000400
|
||||
Uri_CREATE_PRE_PROCESS_HTML_URI = 0x00000800
|
||||
Uri_CREATE_NO_PRE_PROCESS_HTML_URI = 0x00001000
|
||||
Uri_CREATE_IE_SETTINGS = 0x00002000
|
||||
Uri_CREATE_NO_IE_SETTINGS = 0x00004000
|
||||
Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS = 0x00008000
|
||||
Uri_DISPLAY_NO_FRAGMENT = 0x00000001
|
||||
Uri_PUNYCODE_IDN_HOST = 0x00000002
|
||||
Uri_DISPLAY_IDN_HOST = 0x00000004
|
||||
Uri_ENCODING_USER_INFO_AND_PATH_IS_PERCENT_ENCODED_UTF8 = 0x00000001
|
||||
Uri_ENCODING_USER_INFO_AND_PATH_IS_CP = 0x00000002
|
||||
Uri_ENCODING_HOST_IS_IDN = 0x00000004
|
||||
Uri_ENCODING_HOST_IS_PERCENT_ENCODED_UTF8 = 0x00000008
|
||||
Uri_ENCODING_HOST_IS_PERCENT_ENCODED_CP = 0x00000010
|
||||
Uri_ENCODING_QUERY_AND_FRAGMENT_IS_PERCENT_ENCODED_UTF8 = 0x00000020
|
||||
Uri_ENCODING_QUERY_AND_FRAGMENT_IS_CP = 0x00000040
|
||||
Uri_ENCODING_RFC = (
|
||||
Uri_ENCODING_USER_INFO_AND_PATH_IS_PERCENT_ENCODED_UTF8
|
||||
| Uri_ENCODING_HOST_IS_PERCENT_ENCODED_UTF8
|
||||
| Uri_ENCODING_QUERY_AND_FRAGMENT_IS_PERCENT_ENCODED_UTF8
|
||||
)
|
||||
UriBuilder_USE_ORIGINAL_FLAGS = 0x00000001
|
||||
WININETINFO_OPTION_LOCK_HANDLE = 65534
|
||||
URLOSTRM_USECACHEDCOPY_ONLY = 0x1
|
||||
URLOSTRM_USECACHEDCOPY = 0x2
|
||||
URLOSTRM_GETNEWESTVERSION = 0x3
|
||||
SET_FEATURE_ON_THREAD = 0x00000001
|
||||
SET_FEATURE_ON_PROCESS = 0x00000002
|
||||
SET_FEATURE_IN_REGISTRY = 0x00000004
|
||||
SET_FEATURE_ON_THREAD_LOCALMACHINE = 0x00000008
|
||||
SET_FEATURE_ON_THREAD_INTRANET = 0x00000010
|
||||
SET_FEATURE_ON_THREAD_TRUSTED = 0x00000020
|
||||
SET_FEATURE_ON_THREAD_INTERNET = 0x00000040
|
||||
SET_FEATURE_ON_THREAD_RESTRICTED = 0x00000080
|
||||
GET_FEATURE_FROM_THREAD = 0x00000001
|
||||
GET_FEATURE_FROM_PROCESS = 0x00000002
|
||||
GET_FEATURE_FROM_REGISTRY = 0x00000004
|
||||
GET_FEATURE_FROM_THREAD_LOCALMACHINE = 0x00000008
|
||||
GET_FEATURE_FROM_THREAD_INTRANET = 0x00000010
|
||||
GET_FEATURE_FROM_THREAD_TRUSTED = 0x00000020
|
||||
GET_FEATURE_FROM_THREAD_INTERNET = 0x00000040
|
||||
GET_FEATURE_FROM_THREAD_RESTRICTED = 0x00000080
|
||||
PROTOCOLFLAG_NO_PICS_CHECK = 0x00000001
|
||||
MUTZ_NOSAVEDFILECHECK = 0x00000001
|
||||
MUTZ_ISFILE = 0x00000002
|
||||
MUTZ_ACCEPT_WILDCARD_SCHEME = 0x00000080
|
||||
MUTZ_ENFORCERESTRICTED = 0x00000100
|
||||
MUTZ_RESERVED = 0x00000200
|
||||
MUTZ_REQUIRESAVEDFILECHECK = 0x00000400
|
||||
MUTZ_DONT_UNESCAPE = 0x00000800
|
||||
MUTZ_DONT_USE_CACHE = 0x00001000
|
||||
MUTZ_FORCE_INTRANET_FLAGS = 0x00002000
|
||||
MUTZ_IGNORE_ZONE_MAPPINGS = 0x00004000
|
||||
MAX_SIZE_SECURITY_ID = 512
|
||||
URLACTION_MIN = 0x00001000
|
||||
URLACTION_DOWNLOAD_MIN = 0x00001000
|
||||
URLACTION_DOWNLOAD_SIGNED_ACTIVEX = 0x00001001
|
||||
URLACTION_DOWNLOAD_UNSIGNED_ACTIVEX = 0x00001004
|
||||
URLACTION_DOWNLOAD_CURR_MAX = 0x00001004
|
||||
URLACTION_DOWNLOAD_MAX = 0x000011FF
|
||||
URLACTION_ACTIVEX_MIN = 0x00001200
|
||||
URLACTION_ACTIVEX_RUN = 0x00001200
|
||||
URLPOLICY_ACTIVEX_CHECK_LIST = 0x00010000
|
||||
URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY = 0x00001201
|
||||
URLACTION_ACTIVEX_OVERRIDE_DATA_SAFETY = 0x00001202
|
||||
URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY = 0x00001203
|
||||
URLACTION_SCRIPT_OVERRIDE_SAFETY = 0x00001401
|
||||
URLACTION_ACTIVEX_CONFIRM_NOOBJECTSAFETY = 0x00001204
|
||||
URLACTION_ACTIVEX_TREATASUNTRUSTED = 0x00001205
|
||||
URLACTION_ACTIVEX_NO_WEBOC_SCRIPT = 0x00001206
|
||||
URLACTION_ACTIVEX_OVERRIDE_REPURPOSEDETECTION = 0x00001207
|
||||
URLACTION_ACTIVEX_OVERRIDE_OPTIN = 0x00001208
|
||||
URLACTION_ACTIVEX_SCRIPTLET_RUN = 0x00001209
|
||||
URLACTION_ACTIVEX_DYNSRC_VIDEO_AND_ANIMATION = 0x0000120A
|
||||
URLACTION_ACTIVEX_CURR_MAX = 0x0000120A
|
||||
URLACTION_ACTIVEX_MAX = 0x000013FF
|
||||
URLACTION_SCRIPT_MIN = 0x00001400
|
||||
URLACTION_SCRIPT_RUN = 0x00001400
|
||||
URLACTION_SCRIPT_JAVA_USE = 0x00001402
|
||||
URLACTION_SCRIPT_SAFE_ACTIVEX = 0x00001405
|
||||
URLACTION_CROSS_DOMAIN_DATA = 0x00001406
|
||||
URLACTION_SCRIPT_PASTE = 0x00001407
|
||||
URLACTION_ALLOW_XDOMAIN_SUBFRAME_RESIZE = 0x00001408
|
||||
URLACTION_SCRIPT_CURR_MAX = 0x00001408
|
||||
URLACTION_SCRIPT_MAX = 0x000015FF
|
||||
URLACTION_HTML_MIN = 0x00001600
|
||||
URLACTION_HTML_SUBMIT_FORMS = 0x00001601
|
||||
URLACTION_HTML_SUBMIT_FORMS_FROM = 0x00001602
|
||||
URLACTION_HTML_SUBMIT_FORMS_TO = 0x00001603
|
||||
URLACTION_HTML_FONT_DOWNLOAD = 0x00001604
|
||||
URLACTION_HTML_JAVA_RUN = 0x00001605
|
||||
URLACTION_HTML_USERDATA_SAVE = 0x00001606
|
||||
URLACTION_HTML_SUBFRAME_NAVIGATE = 0x00001607
|
||||
URLACTION_HTML_META_REFRESH = 0x00001608
|
||||
URLACTION_HTML_MIXED_CONTENT = 0x00001609
|
||||
URLACTION_HTML_INCLUDE_FILE_PATH = 0x0000160A
|
||||
URLACTION_HTML_MAX = 0x000017FF
|
||||
URLACTION_SHELL_MIN = 0x00001800
|
||||
URLACTION_SHELL_INSTALL_DTITEMS = 0x00001800
|
||||
URLACTION_SHELL_MOVE_OR_COPY = 0x00001802
|
||||
URLACTION_SHELL_FILE_DOWNLOAD = 0x00001803
|
||||
URLACTION_SHELL_VERB = 0x00001804
|
||||
URLACTION_SHELL_WEBVIEW_VERB = 0x00001805
|
||||
URLACTION_SHELL_SHELLEXECUTE = 0x00001806
|
||||
URLACTION_SHELL_EXECUTE_HIGHRISK = 0x00001806
|
||||
URLACTION_SHELL_EXECUTE_MODRISK = 0x00001807
|
||||
URLACTION_SHELL_EXECUTE_LOWRISK = 0x00001808
|
||||
URLACTION_SHELL_POPUPMGR = 0x00001809
|
||||
URLACTION_SHELL_RTF_OBJECTS_LOAD = 0x0000180A
|
||||
URLACTION_SHELL_ENHANCED_DRAGDROP_SECURITY = 0x0000180B
|
||||
URLACTION_SHELL_EXTENSIONSECURITY = 0x0000180C
|
||||
URLACTION_SHELL_SECURE_DRAGSOURCE = 0x0000180D
|
||||
URLACTION_SHELL_CURR_MAX = 0x0000180D
|
||||
URLACTION_SHELL_MAX = 0x000019FF
|
||||
URLACTION_NETWORK_MIN = 0x00001A00
|
||||
URLACTION_CREDENTIALS_USE = 0x00001A00
|
||||
URLPOLICY_CREDENTIALS_SILENT_LOGON_OK = 0x00000000
|
||||
URLPOLICY_CREDENTIALS_MUST_PROMPT_USER = 0x00010000
|
||||
URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT = 0x00020000
|
||||
URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY = 0x00030000
|
||||
URLACTION_AUTHENTICATE_CLIENT = 0x00001A01
|
||||
URLPOLICY_AUTHENTICATE_CLEARTEXT_OK = 0x00000000
|
||||
URLPOLICY_AUTHENTICATE_CHALLENGE_RESPONSE = 0x00010000
|
||||
URLPOLICY_AUTHENTICATE_MUTUAL_ONLY = 0x00030000
|
||||
URLACTION_COOKIES = 0x00001A02
|
||||
URLACTION_COOKIES_SESSION = 0x00001A03
|
||||
URLACTION_CLIENT_CERT_PROMPT = 0x00001A04
|
||||
URLACTION_COOKIES_THIRD_PARTY = 0x00001A05
|
||||
URLACTION_COOKIES_SESSION_THIRD_PARTY = 0x00001A06
|
||||
URLACTION_COOKIES_ENABLED = 0x00001A10
|
||||
URLACTION_NETWORK_CURR_MAX = 0x00001A10
|
||||
URLACTION_NETWORK_MAX = 0x00001BFF
|
||||
URLACTION_JAVA_MIN = 0x00001C00
|
||||
URLACTION_JAVA_PERMISSIONS = 0x00001C00
|
||||
URLPOLICY_JAVA_PROHIBIT = 0x00000000
|
||||
URLPOLICY_JAVA_HIGH = 0x00010000
|
||||
URLPOLICY_JAVA_MEDIUM = 0x00020000
|
||||
URLPOLICY_JAVA_LOW = 0x00030000
|
||||
URLPOLICY_JAVA_CUSTOM = 0x00800000
|
||||
URLACTION_JAVA_CURR_MAX = 0x00001C00
|
||||
URLACTION_JAVA_MAX = 0x00001CFF
|
||||
URLACTION_INFODELIVERY_MIN = 0x00001D00
|
||||
URLACTION_INFODELIVERY_NO_ADDING_CHANNELS = 0x00001D00
|
||||
URLACTION_INFODELIVERY_NO_EDITING_CHANNELS = 0x00001D01
|
||||
URLACTION_INFODELIVERY_NO_REMOVING_CHANNELS = 0x00001D02
|
||||
URLACTION_INFODELIVERY_NO_ADDING_SUBSCRIPTIONS = 0x00001D03
|
||||
URLACTION_INFODELIVERY_NO_EDITING_SUBSCRIPTIONS = 0x00001D04
|
||||
URLACTION_INFODELIVERY_NO_REMOVING_SUBSCRIPTIONS = 0x00001D05
|
||||
URLACTION_INFODELIVERY_NO_CHANNEL_LOGGING = 0x00001D06
|
||||
URLACTION_INFODELIVERY_CURR_MAX = 0x00001D06
|
||||
URLACTION_INFODELIVERY_MAX = 0x00001DFF
|
||||
URLACTION_CHANNEL_SOFTDIST_MIN = 0x00001E00
|
||||
URLACTION_CHANNEL_SOFTDIST_PERMISSIONS = 0x00001E05
|
||||
URLPOLICY_CHANNEL_SOFTDIST_PROHIBIT = 0x00010000
|
||||
URLPOLICY_CHANNEL_SOFTDIST_PRECACHE = 0x00020000
|
||||
URLPOLICY_CHANNEL_SOFTDIST_AUTOINSTALL = 0x00030000
|
||||
URLACTION_CHANNEL_SOFTDIST_MAX = 0x00001EFF
|
||||
URLACTION_BEHAVIOR_MIN = 0x00002000
|
||||
URLACTION_BEHAVIOR_RUN = 0x00002000
|
||||
URLPOLICY_BEHAVIOR_CHECK_LIST = 0x00010000
|
||||
URLACTION_FEATURE_MIN = 0x00002100
|
||||
URLACTION_FEATURE_MIME_SNIFFING = 0x00002100
|
||||
URLACTION_FEATURE_ZONE_ELEVATION = 0x00002101
|
||||
URLACTION_FEATURE_WINDOW_RESTRICTIONS = 0x00002102
|
||||
URLACTION_FEATURE_SCRIPT_STATUS_BAR = 0x00002103
|
||||
URLACTION_FEATURE_FORCE_ADDR_AND_STATUS = 0x00002104
|
||||
URLACTION_FEATURE_BLOCK_INPUT_PROMPTS = 0x00002105
|
||||
URLACTION_AUTOMATIC_DOWNLOAD_UI_MIN = 0x00002200
|
||||
URLACTION_AUTOMATIC_DOWNLOAD_UI = 0x00002200
|
||||
URLACTION_AUTOMATIC_ACTIVEX_UI = 0x00002201
|
||||
URLACTION_ALLOW_RESTRICTEDPROTOCOLS = 0x00002300
|
||||
URLACTION_ALLOW_APEVALUATION = 0x00002301
|
||||
URLACTION_WINDOWS_BROWSER_APPLICATIONS = 0x00002400
|
||||
URLACTION_XPS_DOCUMENTS = 0x00002401
|
||||
URLACTION_LOOSE_XAML = 0x00002402
|
||||
URLACTION_LOWRIGHTS = 0x00002500
|
||||
URLACTION_WINFX_SETUP = 0x00002600
|
||||
URLPOLICY_ALLOW = 0x00
|
||||
URLPOLICY_QUERY = 0x01
|
||||
URLPOLICY_DISALLOW = 0x03
|
||||
URLPOLICY_NOTIFY_ON_ALLOW = 0x10
|
||||
URLPOLICY_NOTIFY_ON_DISALLOW = 0x20
|
||||
URLPOLICY_LOG_ON_ALLOW = 0x40
|
||||
URLPOLICY_LOG_ON_DISALLOW = 0x80
|
||||
URLPOLICY_MASK_PERMISSIONS = 0x0F
|
||||
URLPOLICY_DONTCHECKDLGBOX = 0x100
|
||||
URLZONE_ESC_FLAG = 0x100
|
||||
SECURITY_IE_STATE_GREEN = 0x00000000
|
||||
SECURITY_IE_STATE_RED = 0x00000001
|
||||
SOFTDIST_FLAG_USAGE_EMAIL = 0x00000001
|
||||
SOFTDIST_FLAG_USAGE_PRECACHE = 0x00000002
|
||||
SOFTDIST_FLAG_USAGE_AUTOINSTALL = 0x00000004
|
||||
SOFTDIST_FLAG_DELETE_SUBSCRIPTION = 0x00000008
|
||||
SOFTDIST_ADSTATE_NONE = 0x00000000
|
||||
SOFTDIST_ADSTATE_AVAILABLE = 0x00000001
|
||||
SOFTDIST_ADSTATE_DOWNLOADED = 0x00000002
|
||||
SOFTDIST_ADSTATE_INSTALLED = 0x00000003
|
||||
CONFIRMSAFETYACTION_LOADOBJECT = 0x00000001
|
BIN
lib/win32comext/internet/internet.pyd
Normal file
BIN
lib/win32comext/internet/internet.pyd
Normal file
Binary file not shown.
27
lib/win32comext/mapi/__init__.py
Normal file
27
lib/win32comext/mapi/__init__.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
if type(__path__) == type(""):
|
||||
# For freeze to work!
|
||||
import sys
|
||||
|
||||
try:
|
||||
import mapi
|
||||
|
||||
sys.modules["win32com.mapi.mapi"] = mapi
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import exchange
|
||||
|
||||
sys.modules["win32com.mapi.exchange"] = exchange
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import exchdapi
|
||||
|
||||
sys.modules["win32com.mapi.exchdapi"] = exchdapi
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
import win32com
|
||||
|
||||
# See if we have a special directory for the binaries (for developers)
|
||||
win32com.__PackageSupportBuildPath__(__path__)
|
98
lib/win32comext/mapi/demos/mapisend.py
Normal file
98
lib/win32comext/mapi/demos/mapisend.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""module to send mail with Extended MAPI using the pywin32 mapi wrappers..."""
|
||||
|
||||
# this was based on Jason Hattingh's C++ code at http://www.codeproject.com/internet/mapadmin.asp
|
||||
# written by David Fraser <davidf at sjsoft.com> and Stephen Emslie <stephene at sjsoft.com>
|
||||
# you can test this by changing the variables at the bottom and running from the command line
|
||||
|
||||
from win32com.mapi import mapi, mapitags
|
||||
|
||||
|
||||
def SendEMAPIMail(
|
||||
Subject="", Message="", SendTo=None, SendCC=None, SendBCC=None, MAPIProfile=None
|
||||
):
|
||||
"""Sends an email to the recipient using the extended MAPI interface
|
||||
Subject and Message are strings
|
||||
Send{To,CC,BCC} are comma-separated address lists
|
||||
MAPIProfile is the name of the MAPI profile"""
|
||||
|
||||
# initialize and log on
|
||||
mapi.MAPIInitialize(None)
|
||||
session = mapi.MAPILogonEx(
|
||||
0, MAPIProfile, None, mapi.MAPI_EXTENDED | mapi.MAPI_USE_DEFAULT
|
||||
)
|
||||
messagestorestable = session.GetMsgStoresTable(0)
|
||||
messagestorestable.SetColumns(
|
||||
(mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME_A, mapitags.PR_DEFAULT_STORE), 0
|
||||
)
|
||||
|
||||
while True:
|
||||
rows = messagestorestable.QueryRows(1, 0)
|
||||
# if this is the last row then stop
|
||||
if len(rows) != 1:
|
||||
break
|
||||
row = rows[0]
|
||||
# if this is the default store then stop
|
||||
if (mapitags.PR_DEFAULT_STORE, True) in row:
|
||||
break
|
||||
|
||||
# unpack the row and open the message store
|
||||
(eid_tag, eid), (name_tag, name), (def_store_tag, def_store) = row
|
||||
msgstore = session.OpenMsgStore(
|
||||
0, eid, None, mapi.MDB_NO_DIALOG | mapi.MAPI_BEST_ACCESS
|
||||
)
|
||||
|
||||
# get the outbox
|
||||
hr, props = msgstore.GetProps((mapitags.PR_IPM_OUTBOX_ENTRYID), 0)
|
||||
(tag, eid) = props[0]
|
||||
# check for errors
|
||||
if mapitags.PROP_TYPE(tag) == mapitags.PT_ERROR:
|
||||
raise TypeError("got PT_ERROR instead of PT_BINARY: %s" % eid)
|
||||
outboxfolder = msgstore.OpenEntry(eid, None, mapi.MAPI_BEST_ACCESS)
|
||||
|
||||
# create the message and the addrlist
|
||||
message = outboxfolder.CreateMessage(None, 0)
|
||||
# note: you can use the resolveaddress functions for this. but you may get headaches
|
||||
pal = []
|
||||
|
||||
def makeentry(recipient, recipienttype):
|
||||
return (
|
||||
(mapitags.PR_RECIPIENT_TYPE, recipienttype),
|
||||
(mapitags.PR_SEND_RICH_INFO, False),
|
||||
(mapitags.PR_DISPLAY_TYPE, 0),
|
||||
(mapitags.PR_OBJECT_TYPE, 6),
|
||||
(mapitags.PR_EMAIL_ADDRESS_A, recipient),
|
||||
(mapitags.PR_ADDRTYPE_A, "SMTP"),
|
||||
(mapitags.PR_DISPLAY_NAME_A, recipient),
|
||||
)
|
||||
|
||||
if SendTo:
|
||||
pal.extend(
|
||||
[makeentry(recipient, mapi.MAPI_TO) for recipient in SendTo.split(",")]
|
||||
)
|
||||
if SendCC:
|
||||
pal.extend(
|
||||
[makeentry(recipient, mapi.MAPI_CC) for recipient in SendCC.split(",")]
|
||||
)
|
||||
if SendBCC:
|
||||
pal.extend(
|
||||
[makeentry(recipient, mapi.MAPI_BCC) for recipient in SendBCC.split(",")]
|
||||
)
|
||||
|
||||
# add the resolved recipients to the message
|
||||
message.ModifyRecipients(mapi.MODRECIP_ADD, pal)
|
||||
message.SetProps([(mapitags.PR_BODY_A, Message), (mapitags.PR_SUBJECT_A, Subject)])
|
||||
|
||||
# save changes and submit
|
||||
outboxfolder.SaveChanges(0)
|
||||
message.SubmitMessage(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
MAPIProfile = ""
|
||||
# Change this to a valid email address to test
|
||||
SendTo = "an.invalid at address"
|
||||
SendMessage = "testing one two three"
|
||||
SendSubject = "Testing Extended MAPI!!"
|
||||
SendEMAPIMail(SendSubject, SendMessage, SendTo, MAPIProfile=MAPIProfile)
|
874
lib/win32comext/mapi/emsabtags.py
Normal file
874
lib/win32comext/mapi/emsabtags.py
Normal file
|
@ -0,0 +1,874 @@
|
|||
# Converted "manually" from EMSABTAG.H
|
||||
from .mapitags import (
|
||||
PROP_TAG,
|
||||
PT_APPTIME,
|
||||
PT_BINARY,
|
||||
PT_BOOLEAN,
|
||||
PT_CLSID,
|
||||
PT_CURRENCY,
|
||||
PT_DOUBLE,
|
||||
PT_ERROR,
|
||||
PT_FLOAT,
|
||||
PT_I2,
|
||||
PT_I4,
|
||||
PT_I8,
|
||||
PT_LONG,
|
||||
PT_LONGLONG,
|
||||
PT_MV_APPTIME,
|
||||
PT_MV_BINARY,
|
||||
PT_MV_CLSID,
|
||||
PT_MV_CURRENCY,
|
||||
PT_MV_DOUBLE,
|
||||
PT_MV_FLOAT,
|
||||
PT_MV_I2,
|
||||
PT_MV_I4,
|
||||
PT_MV_I8,
|
||||
PT_MV_LONG,
|
||||
PT_MV_LONGLONG,
|
||||
PT_MV_R4,
|
||||
PT_MV_R8,
|
||||
PT_MV_SHORT,
|
||||
PT_MV_STRING8,
|
||||
PT_MV_SYSTIME,
|
||||
PT_MV_TSTRING,
|
||||
PT_MV_UNICODE,
|
||||
PT_NULL,
|
||||
PT_OBJECT,
|
||||
PT_R4,
|
||||
PT_SHORT,
|
||||
PT_STRING8,
|
||||
PT_SYSTIME,
|
||||
PT_TSTRING,
|
||||
PT_UNICODE,
|
||||
PT_UNSPECIFIED,
|
||||
)
|
||||
|
||||
AB_SHOW_PHANTOMS = 2
|
||||
AB_SHOW_OTHERS = 4
|
||||
|
||||
# Flags for ulFlag on ResolveNames
|
||||
EMS_AB_ADDRESS_LOOKUP = 1
|
||||
|
||||
|
||||
# Constructed, but externally visible.
|
||||
PR_EMS_AB_SERVER = PROP_TAG(PT_TSTRING, 65534)
|
||||
PR_EMS_AB_SERVER_A = PROP_TAG(PT_STRING8, 65534)
|
||||
PR_EMS_AB_SERVER_W = PROP_TAG(PT_UNICODE, 65534)
|
||||
PR_EMS_AB_CONTAINERID = PROP_TAG(PT_LONG, 65533)
|
||||
PR_EMS_AB_DOS_ENTRYID = PR_EMS_AB_CONTAINERID
|
||||
PR_EMS_AB_PARENT_ENTRYID = PROP_TAG(PT_BINARY, 65532)
|
||||
PR_EMS_AB_IS_MASTER = PROP_TAG(PT_BOOLEAN, 65531)
|
||||
PR_EMS_AB_OBJECT_OID = PROP_TAG(PT_BINARY, 65530)
|
||||
PR_EMS_AB_HIERARCHY_PATH = PROP_TAG(PT_TSTRING, 65529)
|
||||
PR_EMS_AB_HIERARCHY_PATH_A = PROP_TAG(PT_STRING8, 65529)
|
||||
PR_EMS_AB_HIERARCHY_PATH_W = PROP_TAG(PT_UNICODE, 65529)
|
||||
PR_EMS_AB_CHILD_RDNS = PROP_TAG(PT_MV_STRING8, 65528)
|
||||
|
||||
MIN_EMS_AB_CONSTRUCTED_PROP_ID = 65528
|
||||
|
||||
PR_EMS_AB_OTHER_RECIPS = PROP_TAG(PT_OBJECT, 61440)
|
||||
|
||||
# Prop tags defined in the schema.
|
||||
PR_EMS_AB_DISPLAY_NAME_PRINTABLE = PROP_TAG(PT_TSTRING, 14847)
|
||||
PR_EMS_AB_DISPLAY_NAME_PRINTABLE_A = PROP_TAG(PT_STRING8, 14847)
|
||||
PR_EMS_AB_DISPLAY_NAME_PRINTABLE_W = PROP_TAG(PT_UNICODE, 14847)
|
||||
|
||||
PR_EMS_AB_ACCESS_CATEGORY = PROP_TAG(PT_LONG, 32836)
|
||||
PR_EMS_AB_ACTIVATION_SCHEDULE = PROP_TAG(PT_BINARY, 32837)
|
||||
PR_EMS_AB_ACTIVATION_STYLE = PROP_TAG(PT_LONG, 32838)
|
||||
PR_EMS_AB_ADDRESS_ENTRY_DISPLAY_TABLE = PROP_TAG(PT_BINARY, 32791)
|
||||
PR_EMS_AB_ADDRESS_ENTRY_DISPLAY_TABLE_MSDOS = PROP_TAG(PT_BINARY, 32839)
|
||||
PR_EMS_AB_ADDRESS_SYNTAX = PROP_TAG(PT_BINARY, 32792)
|
||||
PR_EMS_AB_ADDRESS_TYPE = PROP_TAG(PT_TSTRING, 32840)
|
||||
PR_EMS_AB_ADDRESS_TYPE_A = PROP_TAG(PT_STRING8, 32840)
|
||||
PR_EMS_AB_ADDRESS_TYPE_W = PROP_TAG(PT_UNICODE, 32840)
|
||||
PR_EMS_AB_ADMD = PROP_TAG(PT_TSTRING, 32841)
|
||||
PR_EMS_AB_ADMD_A = PROP_TAG(PT_STRING8, 32841)
|
||||
PR_EMS_AB_ADMD_W = PROP_TAG(PT_UNICODE, 32841)
|
||||
PR_EMS_AB_ADMIN_DESCRIPTION = PROP_TAG(PT_TSTRING, 32842)
|
||||
PR_EMS_AB_ADMIN_DESCRIPTION_A = PROP_TAG(PT_STRING8, 32842)
|
||||
PR_EMS_AB_ADMIN_DESCRIPTION_W = PROP_TAG(PT_UNICODE, 32842)
|
||||
PR_EMS_AB_ADMIN_DISPLAY_NAME = PROP_TAG(PT_TSTRING, 32843)
|
||||
PR_EMS_AB_ADMIN_DISPLAY_NAME_A = PROP_TAG(PT_STRING8, 32843)
|
||||
PR_EMS_AB_ADMIN_DISPLAY_NAME_W = PROP_TAG(PT_UNICODE, 32843)
|
||||
PR_EMS_AB_ADMIN_EXTENSION_DLL = PROP_TAG(PT_TSTRING, 32844)
|
||||
PR_EMS_AB_ADMIN_EXTENSION_DLL_A = PROP_TAG(PT_STRING8, 32844)
|
||||
PR_EMS_AB_ADMIN_EXTENSION_DLL_W = PROP_TAG(PT_UNICODE, 32844)
|
||||
PR_EMS_AB_ALIASED_OBJECT_NAME = PROP_TAG(PT_TSTRING, 32845)
|
||||
PR_EMS_AB_ALIASED_OBJECT_NAME_A = PROP_TAG(PT_STRING8, 32845)
|
||||
PR_EMS_AB_ALIASED_OBJECT_NAME_W = PROP_TAG(PT_UNICODE, 32845)
|
||||
PR_EMS_AB_ALIASED_OBJECT_NAME_O = PROP_TAG(PT_OBJECT, 32845)
|
||||
PR_EMS_AB_ALIASED_OBJECT_NAME_T = PROP_TAG(PT_TSTRING, 32845)
|
||||
PR_EMS_AB_ALT_RECIPIENT = PROP_TAG(PT_TSTRING, 32846)
|
||||
PR_EMS_AB_ALT_RECIPIENT_A = PROP_TAG(PT_STRING8, 32846)
|
||||
PR_EMS_AB_ALT_RECIPIENT_W = PROP_TAG(PT_UNICODE, 32846)
|
||||
PR_EMS_AB_ALT_RECIPIENT_O = PROP_TAG(PT_OBJECT, 32846)
|
||||
PR_EMS_AB_ALT_RECIPIENT_T = PROP_TAG(PT_TSTRING, 32846)
|
||||
PR_EMS_AB_ALT_RECIPIENT_BL = PROP_TAG(PT_MV_TSTRING, 32847)
|
||||
PR_EMS_AB_ALT_RECIPIENT_BL_A = PROP_TAG(PT_MV_STRING8, 32847)
|
||||
PR_EMS_AB_ALT_RECIPIENT_BL_W = PROP_TAG(PT_MV_UNICODE, 32847)
|
||||
PR_EMS_AB_ALT_RECIPIENT_BL_O = PROP_TAG(PT_OBJECT, 32847)
|
||||
PR_EMS_AB_ALT_RECIPIENT_BL_T = PROP_TAG(PT_MV_TSTRING, 32847)
|
||||
PR_EMS_AB_ANCESTOR_ID = PROP_TAG(PT_BINARY, 32848)
|
||||
PR_EMS_AB_ASSOC_NT_ACCOUNT = PROP_TAG(PT_BINARY, 32807)
|
||||
PR_EMS_AB_ASSOC_REMOTE_DXA = PROP_TAG(PT_MV_TSTRING, 32849)
|
||||
PR_EMS_AB_ASSOC_REMOTE_DXA_A = PROP_TAG(PT_MV_STRING8, 32849)
|
||||
PR_EMS_AB_ASSOC_REMOTE_DXA_W = PROP_TAG(PT_MV_UNICODE, 32849)
|
||||
PR_EMS_AB_ASSOC_REMOTE_DXA_O = PROP_TAG(PT_OBJECT, 32849)
|
||||
PR_EMS_AB_ASSOC_REMOTE_DXA_T = PROP_TAG(PT_MV_TSTRING, 32849)
|
||||
PR_EMS_AB_ASSOCIATION_LIFETIME = PROP_TAG(PT_LONG, 32850)
|
||||
PR_EMS_AB_AUTH_ORIG_BL = PROP_TAG(PT_MV_TSTRING, 32851)
|
||||
PR_EMS_AB_AUTH_ORIG_BL_A = PROP_TAG(PT_MV_STRING8, 32851)
|
||||
PR_EMS_AB_AUTH_ORIG_BL_W = PROP_TAG(PT_MV_UNICODE, 32851)
|
||||
PR_EMS_AB_AUTH_ORIG_BL_O = PROP_TAG(PT_OBJECT, 32851)
|
||||
PR_EMS_AB_AUTH_ORIG_BL_T = PROP_TAG(PT_MV_TSTRING, 32851)
|
||||
PR_EMS_AB_AUTHORITY_REVOCATION_LIST = PROP_TAG(PT_MV_BINARY, 32806)
|
||||
PR_EMS_AB_AUTHORIZED_DOMAIN = PROP_TAG(PT_TSTRING, 32852)
|
||||
PR_EMS_AB_AUTHORIZED_DOMAIN_A = PROP_TAG(PT_STRING8, 32852)
|
||||
PR_EMS_AB_AUTHORIZED_DOMAIN_W = PROP_TAG(PT_UNICODE, 32852)
|
||||
PR_EMS_AB_AUTHORIZED_PASSWORD = PROP_TAG(PT_BINARY, 32853)
|
||||
PR_EMS_AB_AUTHORIZED_USER = PROP_TAG(PT_TSTRING, 32854)
|
||||
PR_EMS_AB_AUTHORIZED_USER_A = PROP_TAG(PT_STRING8, 32854)
|
||||
PR_EMS_AB_AUTHORIZED_USER_W = PROP_TAG(PT_UNICODE, 32854)
|
||||
PR_EMS_AB_AUTOREPLY = PROP_TAG(PT_BOOLEAN, 32779)
|
||||
PR_EMS_AB_AUTOREPLY_MESSAGE = PROP_TAG(PT_TSTRING, 32778)
|
||||
PR_EMS_AB_AUTOREPLY_MESSAGE_A = PROP_TAG(PT_STRING8, 32778)
|
||||
PR_EMS_AB_AUTOREPLY_MESSAGE_W = PROP_TAG(PT_UNICODE, 32778)
|
||||
PR_EMS_AB_AUTOREPLY_SUBJECT = PROP_TAG(PT_TSTRING, 32830)
|
||||
PR_EMS_AB_AUTOREPLY_SUBJECT_A = PROP_TAG(PT_STRING8, 32830)
|
||||
PR_EMS_AB_AUTOREPLY_SUBJECT_W = PROP_TAG(PT_UNICODE, 32830)
|
||||
PR_EMS_AB_BRIDGEHEAD_SERVERS = PROP_TAG(PT_MV_TSTRING, 33140)
|
||||
PR_EMS_AB_BRIDGEHEAD_SERVERS_A = PROP_TAG(PT_MV_STRING8, 33140)
|
||||
PR_EMS_AB_BRIDGEHEAD_SERVERS_W = PROP_TAG(PT_MV_UNICODE, 33140)
|
||||
PR_EMS_AB_BRIDGEHEAD_SERVERS_O = PROP_TAG(PT_OBJECT, 33140)
|
||||
PR_EMS_AB_BRIDGEHEAD_SERVERS_T = PROP_TAG(PT_MV_TSTRING, 33140)
|
||||
PR_EMS_AB_BUSINESS_CATEGORY = PROP_TAG(PT_MV_TSTRING, 32855)
|
||||
PR_EMS_AB_BUSINESS_CATEGORY_A = PROP_TAG(PT_MV_STRING8, 32855)
|
||||
PR_EMS_AB_BUSINESS_CATEGORY_W = PROP_TAG(PT_MV_UNICODE, 32855)
|
||||
PR_EMS_AB_BUSINESS_ROLES = PROP_TAG(PT_BINARY, 32803)
|
||||
PR_EMS_AB_CA_CERTIFICATE = PROP_TAG(PT_MV_BINARY, 32771)
|
||||
PR_EMS_AB_CAN_CREATE_PF = PROP_TAG(PT_MV_TSTRING, 32856)
|
||||
PR_EMS_AB_CAN_CREATE_PF_A = PROP_TAG(PT_MV_STRING8, 32856)
|
||||
PR_EMS_AB_CAN_CREATE_PF_W = PROP_TAG(PT_MV_UNICODE, 32856)
|
||||
PR_EMS_AB_CAN_CREATE_PF_O = PROP_TAG(PT_OBJECT, 32856)
|
||||
PR_EMS_AB_CAN_CREATE_PF_T = PROP_TAG(PT_MV_TSTRING, 32856)
|
||||
PR_EMS_AB_CAN_CREATE_PF_BL = PROP_TAG(PT_MV_TSTRING, 32857)
|
||||
PR_EMS_AB_CAN_CREATE_PF_BL_A = PROP_TAG(PT_MV_STRING8, 32857)
|
||||
PR_EMS_AB_CAN_CREATE_PF_BL_W = PROP_TAG(PT_MV_UNICODE, 32857)
|
||||
PR_EMS_AB_CAN_CREATE_PF_BL_O = PROP_TAG(PT_OBJECT, 32857)
|
||||
PR_EMS_AB_CAN_CREATE_PF_BL_T = PROP_TAG(PT_MV_TSTRING, 32857)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL = PROP_TAG(PT_MV_TSTRING, 32858)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_A = PROP_TAG(PT_MV_STRING8, 32858)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_W = PROP_TAG(PT_MV_UNICODE, 32858)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_O = PROP_TAG(PT_OBJECT, 32858)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_T = PROP_TAG(PT_MV_TSTRING, 32858)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_BL = PROP_TAG(PT_MV_TSTRING, 32859)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_BL_A = PROP_TAG(PT_MV_STRING8, 32859)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_BL_W = PROP_TAG(PT_MV_UNICODE, 32859)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_BL_O = PROP_TAG(PT_OBJECT, 32859)
|
||||
PR_EMS_AB_CAN_CREATE_PF_DL_BL_T = PROP_TAG(PT_MV_TSTRING, 32859)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF = PROP_TAG(PT_MV_TSTRING, 32860)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_A = PROP_TAG(PT_MV_STRING8, 32860)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_W = PROP_TAG(PT_MV_UNICODE, 32860)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_O = PROP_TAG(PT_OBJECT, 32860)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_T = PROP_TAG(PT_MV_TSTRING, 32860)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_BL = PROP_TAG(PT_MV_TSTRING, 32861)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_BL_A = PROP_TAG(PT_MV_STRING8, 32861)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_BL_W = PROP_TAG(PT_MV_UNICODE, 32861)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_BL_O = PROP_TAG(PT_OBJECT, 32861)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_BL_T = PROP_TAG(PT_MV_TSTRING, 32861)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL = PROP_TAG(PT_MV_TSTRING, 32862)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_A = PROP_TAG(PT_MV_STRING8, 32862)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_W = PROP_TAG(PT_MV_UNICODE, 32862)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_O = PROP_TAG(PT_OBJECT, 32862)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_T = PROP_TAG(PT_MV_TSTRING, 32862)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL = PROP_TAG(PT_MV_TSTRING, 32863)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL_A = PROP_TAG(PT_MV_STRING8, 32863)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL_W = PROP_TAG(PT_MV_UNICODE, 32863)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL_O = PROP_TAG(PT_OBJECT, 32863)
|
||||
PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL_T = PROP_TAG(PT_MV_TSTRING, 32863)
|
||||
PR_EMS_AB_CAN_PRESERVE_DNS = PROP_TAG(PT_BOOLEAN, 32864)
|
||||
PR_EMS_AB_CERTIFICATE_REVOCATION_LIST = PROP_TAG(PT_BINARY, 32790)
|
||||
PR_EMS_AB_CLOCK_ALERT_OFFSET = PROP_TAG(PT_LONG, 32865)
|
||||
PR_EMS_AB_CLOCK_ALERT_REPAIR = PROP_TAG(PT_BOOLEAN, 32866)
|
||||
PR_EMS_AB_CLOCK_WARNING_OFFSET = PROP_TAG(PT_LONG, 32867)
|
||||
PR_EMS_AB_CLOCK_WARNING_REPAIR = PROP_TAG(PT_BOOLEAN, 32868)
|
||||
PR_EMS_AB_COMPUTER_NAME = PROP_TAG(PT_TSTRING, 32869)
|
||||
PR_EMS_AB_COMPUTER_NAME_A = PROP_TAG(PT_STRING8, 32869)
|
||||
PR_EMS_AB_COMPUTER_NAME_W = PROP_TAG(PT_UNICODE, 32869)
|
||||
PR_EMS_AB_CONNECTED_DOMAINS = PROP_TAG(PT_MV_TSTRING, 32870)
|
||||
PR_EMS_AB_CONNECTED_DOMAINS_A = PROP_TAG(PT_MV_STRING8, 32870)
|
||||
PR_EMS_AB_CONNECTED_DOMAINS_W = PROP_TAG(PT_MV_UNICODE, 32870)
|
||||
PR_EMS_AB_CONTAINER_INFO = PROP_TAG(PT_LONG, 32871)
|
||||
PR_EMS_AB_COST = PROP_TAG(PT_LONG, 32872)
|
||||
PR_EMS_AB_COUNTRY_NAME = PROP_TAG(PT_TSTRING, 32873)
|
||||
PR_EMS_AB_COUNTRY_NAME_A = PROP_TAG(PT_STRING8, 32873)
|
||||
PR_EMS_AB_COUNTRY_NAME_W = PROP_TAG(PT_UNICODE, 32873)
|
||||
PR_EMS_AB_CROSS_CERTIFICATE_PAIR = PROP_TAG(PT_MV_BINARY, 32805)
|
||||
PR_EMS_AB_DELIV_CONT_LENGTH = PROP_TAG(PT_LONG, 32874)
|
||||
PR_EMS_AB_DELIV_EITS = PROP_TAG(PT_MV_BINARY, 32875)
|
||||
PR_EMS_AB_DELIV_EXT_CONT_TYPES = PROP_TAG(PT_MV_BINARY, 32876)
|
||||
PR_EMS_AB_DELIVER_AND_REDIRECT = PROP_TAG(PT_BOOLEAN, 32877)
|
||||
PR_EMS_AB_DELIVERY_MECHANISM = PROP_TAG(PT_LONG, 32878)
|
||||
PR_EMS_AB_DESCRIPTION = PROP_TAG(PT_MV_TSTRING, 32879)
|
||||
PR_EMS_AB_DESCRIPTION_A = PROP_TAG(PT_MV_STRING8, 32879)
|
||||
PR_EMS_AB_DESCRIPTION_W = PROP_TAG(PT_MV_UNICODE, 32879)
|
||||
PR_EMS_AB_DESTINATION_INDICATOR = PROP_TAG(PT_MV_TSTRING, 32880)
|
||||
PR_EMS_AB_DESTINATION_INDICATOR_A = PROP_TAG(PT_MV_STRING8, 32880)
|
||||
PR_EMS_AB_DESTINATION_INDICATOR_W = PROP_TAG(PT_MV_UNICODE, 32880)
|
||||
PR_EMS_AB_DIAGNOSTIC_REG_KEY = PROP_TAG(PT_TSTRING, 32881)
|
||||
PR_EMS_AB_DIAGNOSTIC_REG_KEY_A = PROP_TAG(PT_STRING8, 32881)
|
||||
PR_EMS_AB_DIAGNOSTIC_REG_KEY_W = PROP_TAG(PT_UNICODE, 32881)
|
||||
PR_EMS_AB_DISPLAY_NAME_OVERRIDE = PROP_TAG(PT_BOOLEAN, 32769)
|
||||
PR_EMS_AB_DL_MEM_REJECT_PERMS_BL = PROP_TAG(PT_MV_TSTRING, 32882)
|
||||
PR_EMS_AB_DL_MEM_REJECT_PERMS_BL_A = PROP_TAG(PT_MV_STRING8, 32882)
|
||||
PR_EMS_AB_DL_MEM_REJECT_PERMS_BL_W = PROP_TAG(PT_MV_UNICODE, 32882)
|
||||
PR_EMS_AB_DL_MEM_REJECT_PERMS_BL_O = PROP_TAG(PT_OBJECT, 32882)
|
||||
PR_EMS_AB_DL_MEM_REJECT_PERMS_BL_T = PROP_TAG(PT_MV_TSTRING, 32882)
|
||||
PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL = PROP_TAG(PT_MV_TSTRING, 32883)
|
||||
PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL_A = PROP_TAG(PT_MV_STRING8, 32883)
|
||||
PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL_W = PROP_TAG(PT_MV_UNICODE, 32883)
|
||||
PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL_O = PROP_TAG(PT_OBJECT, 32883)
|
||||
PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL_T = PROP_TAG(PT_MV_TSTRING, 32883)
|
||||
PR_EMS_AB_DL_MEMBER_RULE = PROP_TAG(PT_MV_BINARY, 32884)
|
||||
PR_EMS_AB_DOMAIN_DEF_ALT_RECIP = PROP_TAG(PT_TSTRING, 32885)
|
||||
PR_EMS_AB_DOMAIN_DEF_ALT_RECIP_A = PROP_TAG(PT_STRING8, 32885)
|
||||
PR_EMS_AB_DOMAIN_DEF_ALT_RECIP_W = PROP_TAG(PT_UNICODE, 32885)
|
||||
PR_EMS_AB_DOMAIN_DEF_ALT_RECIP_O = PROP_TAG(PT_OBJECT, 32885)
|
||||
PR_EMS_AB_DOMAIN_DEF_ALT_RECIP_T = PROP_TAG(PT_TSTRING, 32885)
|
||||
PR_EMS_AB_DOMAIN_NAME = PROP_TAG(PT_TSTRING, 32886)
|
||||
PR_EMS_AB_DOMAIN_NAME_A = PROP_TAG(PT_STRING8, 32886)
|
||||
PR_EMS_AB_DOMAIN_NAME_W = PROP_TAG(PT_UNICODE, 32886)
|
||||
PR_EMS_AB_DSA_SIGNATURE = PROP_TAG(PT_BINARY, 32887)
|
||||
PR_EMS_AB_DXA_ADMIN_COPY = PROP_TAG(PT_BOOLEAN, 32888)
|
||||
PR_EMS_AB_DXA_ADMIN_FORWARD = PROP_TAG(PT_BOOLEAN, 32889)
|
||||
PR_EMS_AB_DXA_ADMIN_UPDATE = PROP_TAG(PT_LONG, 32890)
|
||||
PR_EMS_AB_DXA_APPEND_REQCN = PROP_TAG(PT_BOOLEAN, 32891)
|
||||
PR_EMS_AB_DXA_CONF_CONTAINER_LIST = PROP_TAG(PT_MV_TSTRING, 32892)
|
||||
PR_EMS_AB_DXA_CONF_CONTAINER_LIST_A = PROP_TAG(PT_MV_STRING8, 32892)
|
||||
PR_EMS_AB_DXA_CONF_CONTAINER_LIST_W = PROP_TAG(PT_MV_UNICODE, 32892)
|
||||
PR_EMS_AB_DXA_CONF_CONTAINER_LIST_O = PROP_TAG(PT_OBJECT, 32892)
|
||||
PR_EMS_AB_DXA_CONF_CONTAINER_LIST_T = PROP_TAG(PT_MV_TSTRING, 32892)
|
||||
PR_EMS_AB_DXA_CONF_REQ_TIME = PROP_TAG(PT_SYSTIME, 32893)
|
||||
PR_EMS_AB_DXA_CONF_SEQ = PROP_TAG(PT_TSTRING, 32894)
|
||||
PR_EMS_AB_DXA_CONF_SEQ_A = PROP_TAG(PT_STRING8, 32894)
|
||||
PR_EMS_AB_DXA_CONF_SEQ_W = PROP_TAG(PT_UNICODE, 32894)
|
||||
PR_EMS_AB_DXA_CONF_SEQ_USN = PROP_TAG(PT_LONG, 32895)
|
||||
PR_EMS_AB_DXA_EXCHANGE_OPTIONS = PROP_TAG(PT_LONG, 32896)
|
||||
PR_EMS_AB_DXA_EXPORT_NOW = PROP_TAG(PT_BOOLEAN, 32897)
|
||||
PR_EMS_AB_DXA_FLAGS = PROP_TAG(PT_LONG, 32898)
|
||||
PR_EMS_AB_DXA_IMP_SEQ = PROP_TAG(PT_TSTRING, 32899)
|
||||
PR_EMS_AB_DXA_IMP_SEQ_A = PROP_TAG(PT_STRING8, 32899)
|
||||
PR_EMS_AB_DXA_IMP_SEQ_W = PROP_TAG(PT_UNICODE, 32899)
|
||||
PR_EMS_AB_DXA_IMP_SEQ_TIME = PROP_TAG(PT_SYSTIME, 32900)
|
||||
PR_EMS_AB_DXA_IMP_SEQ_USN = PROP_TAG(PT_LONG, 32901)
|
||||
PR_EMS_AB_DXA_IMPORT_NOW = PROP_TAG(PT_BOOLEAN, 32902)
|
||||
PR_EMS_AB_DXA_IN_TEMPLATE_MAP = PROP_TAG(PT_MV_TSTRING, 32903)
|
||||
PR_EMS_AB_DXA_IN_TEMPLATE_MAP_A = PROP_TAG(PT_MV_STRING8, 32903)
|
||||
PR_EMS_AB_DXA_IN_TEMPLATE_MAP_W = PROP_TAG(PT_MV_UNICODE, 32903)
|
||||
PR_EMS_AB_DXA_LOCAL_ADMIN = PROP_TAG(PT_TSTRING, 32904)
|
||||
PR_EMS_AB_DXA_LOCAL_ADMIN_A = PROP_TAG(PT_STRING8, 32904)
|
||||
PR_EMS_AB_DXA_LOCAL_ADMIN_W = PROP_TAG(PT_UNICODE, 32904)
|
||||
PR_EMS_AB_DXA_LOCAL_ADMIN_O = PROP_TAG(PT_OBJECT, 32904)
|
||||
PR_EMS_AB_DXA_LOCAL_ADMIN_T = PROP_TAG(PT_TSTRING, 32904)
|
||||
PR_EMS_AB_DXA_LOGGING_LEVEL = PROP_TAG(PT_LONG, 32905)
|
||||
PR_EMS_AB_DXA_NATIVE_ADDRESS_TYPE = PROP_TAG(PT_TSTRING, 32906)
|
||||
PR_EMS_AB_DXA_NATIVE_ADDRESS_TYPE_A = PROP_TAG(PT_STRING8, 32906)
|
||||
PR_EMS_AB_DXA_NATIVE_ADDRESS_TYPE_W = PROP_TAG(PT_UNICODE, 32906)
|
||||
PR_EMS_AB_DXA_OUT_TEMPLATE_MAP = PROP_TAG(PT_MV_TSTRING, 32907)
|
||||
PR_EMS_AB_DXA_OUT_TEMPLATE_MAP_A = PROP_TAG(PT_MV_STRING8, 32907)
|
||||
PR_EMS_AB_DXA_OUT_TEMPLATE_MAP_W = PROP_TAG(PT_MV_UNICODE, 32907)
|
||||
PR_EMS_AB_DXA_PASSWORD = PROP_TAG(PT_TSTRING, 32908)
|
||||
PR_EMS_AB_DXA_PASSWORD_A = PROP_TAG(PT_STRING8, 32908)
|
||||
PR_EMS_AB_DXA_PASSWORD_W = PROP_TAG(PT_UNICODE, 32908)
|
||||
PR_EMS_AB_DXA_PREV_EXCHANGE_OPTIONS = PROP_TAG(PT_LONG, 32909)
|
||||
PR_EMS_AB_DXA_PREV_EXPORT_NATIVE_ONLY = PROP_TAG(PT_BOOLEAN, 32910)
|
||||
PR_EMS_AB_DXA_PREV_IN_EXCHANGE_SENSITIVITY = PROP_TAG(PT_LONG, 32911)
|
||||
PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES = PROP_TAG(PT_TSTRING, 32912)
|
||||
PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES_A = PROP_TAG(PT_STRING8, 32912)
|
||||
PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES_W = PROP_TAG(PT_UNICODE, 32912)
|
||||
PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES_O = PROP_TAG(PT_OBJECT, 32912)
|
||||
PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES_T = PROP_TAG(PT_TSTRING, 32912)
|
||||
PR_EMS_AB_DXA_PREV_REPLICATION_SENSITIVITY = PROP_TAG(PT_LONG, 32913)
|
||||
PR_EMS_AB_DXA_PREV_TEMPLATE_OPTIONS = PROP_TAG(PT_LONG, 32914)
|
||||
PR_EMS_AB_DXA_PREV_TYPES = PROP_TAG(PT_LONG, 32915)
|
||||
PR_EMS_AB_DXA_RECIPIENT_CP = PROP_TAG(PT_TSTRING, 32916)
|
||||
PR_EMS_AB_DXA_RECIPIENT_CP_A = PROP_TAG(PT_STRING8, 32916)
|
||||
PR_EMS_AB_DXA_RECIPIENT_CP_W = PROP_TAG(PT_UNICODE, 32916)
|
||||
PR_EMS_AB_DXA_REMOTE_CLIENT = PROP_TAG(PT_TSTRING, 32917)
|
||||
PR_EMS_AB_DXA_REMOTE_CLIENT_A = PROP_TAG(PT_STRING8, 32917)
|
||||
PR_EMS_AB_DXA_REMOTE_CLIENT_W = PROP_TAG(PT_UNICODE, 32917)
|
||||
PR_EMS_AB_DXA_REMOTE_CLIENT_O = PROP_TAG(PT_OBJECT, 32917)
|
||||
PR_EMS_AB_DXA_REMOTE_CLIENT_T = PROP_TAG(PT_TSTRING, 32917)
|
||||
PR_EMS_AB_DXA_REQ_SEQ = PROP_TAG(PT_TSTRING, 32918)
|
||||
PR_EMS_AB_DXA_REQ_SEQ_A = PROP_TAG(PT_STRING8, 32918)
|
||||
PR_EMS_AB_DXA_REQ_SEQ_W = PROP_TAG(PT_UNICODE, 32918)
|
||||
PR_EMS_AB_DXA_REQ_SEQ_TIME = PROP_TAG(PT_SYSTIME, 32919)
|
||||
PR_EMS_AB_DXA_REQ_SEQ_USN = PROP_TAG(PT_LONG, 32920)
|
||||
PR_EMS_AB_DXA_REQNAME = PROP_TAG(PT_TSTRING, 32921)
|
||||
PR_EMS_AB_DXA_REQNAME_A = PROP_TAG(PT_STRING8, 32921)
|
||||
PR_EMS_AB_DXA_REQNAME_W = PROP_TAG(PT_UNICODE, 32921)
|
||||
PR_EMS_AB_DXA_SVR_SEQ = PROP_TAG(PT_TSTRING, 32922)
|
||||
PR_EMS_AB_DXA_SVR_SEQ_A = PROP_TAG(PT_STRING8, 32922)
|
||||
PR_EMS_AB_DXA_SVR_SEQ_W = PROP_TAG(PT_UNICODE, 32922)
|
||||
PR_EMS_AB_DXA_SVR_SEQ_TIME = PROP_TAG(PT_SYSTIME, 32923)
|
||||
PR_EMS_AB_DXA_SVR_SEQ_USN = PROP_TAG(PT_LONG, 32924)
|
||||
PR_EMS_AB_DXA_TASK = PROP_TAG(PT_LONG, 32925)
|
||||
PR_EMS_AB_DXA_TEMPLATE_OPTIONS = PROP_TAG(PT_LONG, 32926)
|
||||
PR_EMS_AB_DXA_TEMPLATE_TIMESTAMP = PROP_TAG(PT_SYSTIME, 32927)
|
||||
PR_EMS_AB_DXA_TYPES = PROP_TAG(PT_LONG, 32928)
|
||||
PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST = PROP_TAG(PT_MV_TSTRING, 32929)
|
||||
PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST_A = PROP_TAG(PT_MV_STRING8, 32929)
|
||||
PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST_W = PROP_TAG(PT_MV_UNICODE, 32929)
|
||||
PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST_O = PROP_TAG(PT_OBJECT, 32929)
|
||||
PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST_T = PROP_TAG(PT_MV_TSTRING, 32929)
|
||||
PR_EMS_AB_ENABLED_PROTOCOLS = PROP_TAG(PT_LONG, 33151)
|
||||
PR_EMS_AB_ENCAPSULATION_METHOD = PROP_TAG(PT_LONG, 32930)
|
||||
PR_EMS_AB_ENCRYPT = PROP_TAG(PT_BOOLEAN, 32931)
|
||||
PR_EMS_AB_ENCRYPT_ALG_LIST_NA = PROP_TAG(PT_MV_TSTRING, 32832)
|
||||
PR_EMS_AB_ENCRYPT_ALG_LIST_NA_A = PROP_TAG(PT_MV_STRING8, 32832)
|
||||
PR_EMS_AB_ENCRYPT_ALG_LIST_NA_W = PROP_TAG(PT_MV_UNICODE, 32832)
|
||||
PR_EMS_AB_ENCRYPT_ALG_LIST_OTHER = PROP_TAG(PT_MV_TSTRING, 32833)
|
||||
PR_EMS_AB_ENCRYPT_ALG_LIST_OTHER_A = PROP_TAG(PT_MV_STRING8, 32833)
|
||||
PR_EMS_AB_ENCRYPT_ALG_LIST_OTHER_W = PROP_TAG(PT_MV_UNICODE, 32833)
|
||||
PR_EMS_AB_ENCRYPT_ALG_SELECTED_NA = PROP_TAG(PT_TSTRING, 32835)
|
||||
PR_EMS_AB_ENCRYPT_ALG_SELECTED_NA_A = PROP_TAG(PT_STRING8, 32835)
|
||||
PR_EMS_AB_ENCRYPT_ALG_SELECTED_NA_W = PROP_TAG(PT_UNICODE, 32835)
|
||||
PR_EMS_AB_ENCRYPT_ALG_SELECTED_OTHER = PROP_TAG(PT_TSTRING, 32829)
|
||||
PR_EMS_AB_ENCRYPT_ALG_SELECTED_OTHER_A = PROP_TAG(PT_STRING8, 32829)
|
||||
PR_EMS_AB_ENCRYPT_ALG_SELECTED_OTHER_W = PROP_TAG(PT_UNICODE, 32829)
|
||||
PR_EMS_AB_EXPAND_DLS_LOCALLY = PROP_TAG(PT_BOOLEAN, 32932)
|
||||
PR_EMS_AB_EXPIRATION_TIME = PROP_TAG(PT_SYSTIME, 32808)
|
||||
PR_EMS_AB_EXPORT_CONTAINERS = PROP_TAG(PT_MV_TSTRING, 32933)
|
||||
PR_EMS_AB_EXPORT_CONTAINERS_A = PROP_TAG(PT_MV_STRING8, 32933)
|
||||
PR_EMS_AB_EXPORT_CONTAINERS_W = PROP_TAG(PT_MV_UNICODE, 32933)
|
||||
PR_EMS_AB_EXPORT_CONTAINERS_O = PROP_TAG(PT_OBJECT, 32933)
|
||||
PR_EMS_AB_EXPORT_CONTAINERS_T = PROP_TAG(PT_MV_TSTRING, 32933)
|
||||
PR_EMS_AB_EXPORT_CUSTOM_RECIPIENTS = PROP_TAG(PT_BOOLEAN, 32934)
|
||||
PR_EMS_AB_EXTENDED_CHARS_ALLOWED = PROP_TAG(PT_BOOLEAN, 32935)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_1 = PROP_TAG(PT_TSTRING, 32813)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_1_A = PROP_TAG(PT_STRING8, 32813)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_1_W = PROP_TAG(PT_UNICODE, 32813)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_10 = PROP_TAG(PT_TSTRING, 32822)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_10_A = PROP_TAG(PT_STRING8, 32822)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_10_W = PROP_TAG(PT_UNICODE, 32822)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_2 = PROP_TAG(PT_TSTRING, 32814)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_2_A = PROP_TAG(PT_STRING8, 32814)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_2_W = PROP_TAG(PT_UNICODE, 32814)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_3 = PROP_TAG(PT_TSTRING, 32815)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_3_A = PROP_TAG(PT_STRING8, 32815)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_3_W = PROP_TAG(PT_UNICODE, 32815)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_4 = PROP_TAG(PT_TSTRING, 32816)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_4_A = PROP_TAG(PT_STRING8, 32816)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_4_W = PROP_TAG(PT_UNICODE, 32816)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_5 = PROP_TAG(PT_TSTRING, 32817)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_5_A = PROP_TAG(PT_STRING8, 32817)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_5_W = PROP_TAG(PT_UNICODE, 32817)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_6 = PROP_TAG(PT_TSTRING, 32818)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_6_A = PROP_TAG(PT_STRING8, 32818)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_6_W = PROP_TAG(PT_UNICODE, 32818)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_7 = PROP_TAG(PT_TSTRING, 32819)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_7_A = PROP_TAG(PT_STRING8, 32819)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_7_W = PROP_TAG(PT_UNICODE, 32819)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_8 = PROP_TAG(PT_TSTRING, 32820)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_8_A = PROP_TAG(PT_STRING8, 32820)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_8_W = PROP_TAG(PT_UNICODE, 32820)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_9 = PROP_TAG(PT_TSTRING, 32821)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_9_A = PROP_TAG(PT_STRING8, 32821)
|
||||
PR_EMS_AB_EXTENSION_ATTRIBUTE_9_W = PROP_TAG(PT_UNICODE, 32821)
|
||||
PR_EMS_AB_EXTENSION_DATA = PROP_TAG(PT_MV_BINARY, 32936)
|
||||
PR_EMS_AB_EXTENSION_NAME = PROP_TAG(PT_MV_TSTRING, 32937)
|
||||
PR_EMS_AB_EXTENSION_NAME_A = PROP_TAG(PT_MV_STRING8, 32937)
|
||||
PR_EMS_AB_EXTENSION_NAME_W = PROP_TAG(PT_MV_UNICODE, 32937)
|
||||
PR_EMS_AB_EXTENSION_NAME_INHERITED = PROP_TAG(PT_MV_TSTRING, 32938)
|
||||
PR_EMS_AB_EXTENSION_NAME_INHERITED_A = PROP_TAG(PT_MV_STRING8, 32938)
|
||||
PR_EMS_AB_EXTENSION_NAME_INHERITED_W = PROP_TAG(PT_MV_UNICODE, 32938)
|
||||
PR_EMS_AB_FACSIMILE_TELEPHONE_NUMBER = PROP_TAG(PT_MV_BINARY, 32939)
|
||||
PR_EMS_AB_FILE_VERSION = PROP_TAG(PT_BINARY, 32940)
|
||||
PR_EMS_AB_FILTER_LOCAL_ADDRESSES = PROP_TAG(PT_BOOLEAN, 32941)
|
||||
PR_EMS_AB_FOLDER_PATHNAME = PROP_TAG(PT_TSTRING, 32772)
|
||||
PR_EMS_AB_FOLDER_PATHNAME_A = PROP_TAG(PT_STRING8, 32772)
|
||||
PR_EMS_AB_FOLDER_PATHNAME_W = PROP_TAG(PT_UNICODE, 32772)
|
||||
PR_EMS_AB_FOLDERS_CONTAINER = PROP_TAG(PT_TSTRING, 32942)
|
||||
PR_EMS_AB_FOLDERS_CONTAINER_A = PROP_TAG(PT_STRING8, 32942)
|
||||
PR_EMS_AB_FOLDERS_CONTAINER_W = PROP_TAG(PT_UNICODE, 32942)
|
||||
PR_EMS_AB_FOLDERS_CONTAINER_O = PROP_TAG(PT_OBJECT, 32942)
|
||||
PR_EMS_AB_FOLDERS_CONTAINER_T = PROP_TAG(PT_TSTRING, 32942)
|
||||
PR_EMS_AB_GARBAGE_COLL_PERIOD = PROP_TAG(PT_LONG, 32943)
|
||||
PR_EMS_AB_GATEWAY_LOCAL_CRED = PROP_TAG(PT_TSTRING, 32944)
|
||||
PR_EMS_AB_GATEWAY_LOCAL_CRED_A = PROP_TAG(PT_STRING8, 32944)
|
||||
PR_EMS_AB_GATEWAY_LOCAL_CRED_W = PROP_TAG(PT_UNICODE, 32944)
|
||||
PR_EMS_AB_GATEWAY_LOCAL_DESIG = PROP_TAG(PT_TSTRING, 32945)
|
||||
PR_EMS_AB_GATEWAY_LOCAL_DESIG_A = PROP_TAG(PT_STRING8, 32945)
|
||||
PR_EMS_AB_GATEWAY_LOCAL_DESIG_W = PROP_TAG(PT_UNICODE, 32945)
|
||||
PR_EMS_AB_GATEWAY_PROXY = PROP_TAG(PT_MV_TSTRING, 32946)
|
||||
PR_EMS_AB_GATEWAY_PROXY_A = PROP_TAG(PT_MV_STRING8, 32946)
|
||||
PR_EMS_AB_GATEWAY_PROXY_W = PROP_TAG(PT_MV_UNICODE, 32946)
|
||||
PR_EMS_AB_GATEWAY_ROUTING_TREE = PROP_TAG(PT_BINARY, 32947)
|
||||
PR_EMS_AB_GWART_LAST_MODIFIED = PROP_TAG(PT_SYSTIME, 32948)
|
||||
PR_EMS_AB_HAS_FULL_REPLICA_NCS = PROP_TAG(PT_MV_TSTRING, 32949)
|
||||
PR_EMS_AB_HAS_FULL_REPLICA_NCS_A = PROP_TAG(PT_MV_STRING8, 32949)
|
||||
PR_EMS_AB_HAS_FULL_REPLICA_NCS_W = PROP_TAG(PT_MV_UNICODE, 32949)
|
||||
PR_EMS_AB_HAS_FULL_REPLICA_NCS_O = PROP_TAG(PT_OBJECT, 32949)
|
||||
PR_EMS_AB_HAS_FULL_REPLICA_NCS_T = PROP_TAG(PT_MV_TSTRING, 32949)
|
||||
PR_EMS_AB_HAS_MASTER_NCS = PROP_TAG(PT_MV_TSTRING, 32950)
|
||||
PR_EMS_AB_HAS_MASTER_NCS_A = PROP_TAG(PT_MV_STRING8, 32950)
|
||||
PR_EMS_AB_HAS_MASTER_NCS_W = PROP_TAG(PT_MV_UNICODE, 32950)
|
||||
PR_EMS_AB_HAS_MASTER_NCS_O = PROP_TAG(PT_OBJECT, 32950)
|
||||
PR_EMS_AB_HAS_MASTER_NCS_T = PROP_TAG(PT_MV_TSTRING, 32950)
|
||||
PR_EMS_AB_HELP_DATA16 = PROP_TAG(PT_BINARY, 32826)
|
||||
PR_EMS_AB_HELP_DATA32 = PROP_TAG(PT_BINARY, 32784)
|
||||
PR_EMS_AB_HELP_FILE_NAME = PROP_TAG(PT_TSTRING, 32827)
|
||||
PR_EMS_AB_HELP_FILE_NAME_A = PROP_TAG(PT_STRING8, 32827)
|
||||
PR_EMS_AB_HELP_FILE_NAME_W = PROP_TAG(PT_UNICODE, 32827)
|
||||
PR_EMS_AB_HEURISTICS = PROP_TAG(PT_LONG, 32951)
|
||||
PR_EMS_AB_HIDE_DL_MEMBERSHIP = PROP_TAG(PT_BOOLEAN, 32952)
|
||||
PR_EMS_AB_HIDE_FROM_ADDRESS_BOOK = PROP_TAG(PT_BOOLEAN, 32953)
|
||||
PR_EMS_AB_HOME_MDB = PROP_TAG(PT_TSTRING, 32774)
|
||||
PR_EMS_AB_HOME_MDB_A = PROP_TAG(PT_STRING8, 32774)
|
||||
PR_EMS_AB_HOME_MDB_W = PROP_TAG(PT_UNICODE, 32774)
|
||||
PR_EMS_AB_HOME_MDB_O = PROP_TAG(PT_OBJECT, 32774)
|
||||
PR_EMS_AB_HOME_MDB_T = PROP_TAG(PT_TSTRING, 32774)
|
||||
PR_EMS_AB_HOME_MDB_BL = PROP_TAG(PT_MV_TSTRING, 32788)
|
||||
PR_EMS_AB_HOME_MDB_BL_A = PROP_TAG(PT_MV_STRING8, 32788)
|
||||
PR_EMS_AB_HOME_MDB_BL_W = PROP_TAG(PT_MV_UNICODE, 32788)
|
||||
PR_EMS_AB_HOME_MDB_BL_O = PROP_TAG(PT_OBJECT, 32788)
|
||||
PR_EMS_AB_HOME_MDB_BL_T = PROP_TAG(PT_MV_TSTRING, 32788)
|
||||
PR_EMS_AB_HOME_MTA = PROP_TAG(PT_TSTRING, 32775)
|
||||
PR_EMS_AB_HOME_MTA_A = PROP_TAG(PT_STRING8, 32775)
|
||||
PR_EMS_AB_HOME_MTA_W = PROP_TAG(PT_UNICODE, 32775)
|
||||
PR_EMS_AB_HOME_MTA_O = PROP_TAG(PT_OBJECT, 32775)
|
||||
PR_EMS_AB_HOME_MTA_T = PROP_TAG(PT_TSTRING, 32775)
|
||||
PR_EMS_AB_HOME_PUBLIC_SERVER = PROP_TAG(PT_TSTRING, 32831)
|
||||
PR_EMS_AB_HOME_PUBLIC_SERVER_A = PROP_TAG(PT_STRING8, 32831)
|
||||
PR_EMS_AB_HOME_PUBLIC_SERVER_W = PROP_TAG(PT_UNICODE, 32831)
|
||||
PR_EMS_AB_HOME_PUBLIC_SERVER_O = PROP_TAG(PT_OBJECT, 32831)
|
||||
PR_EMS_AB_HOME_PUBLIC_SERVER_T = PROP_TAG(PT_TSTRING, 32831)
|
||||
PR_EMS_AB_IMPORT_CONTAINER = PROP_TAG(PT_TSTRING, 32954)
|
||||
PR_EMS_AB_IMPORT_CONTAINER_A = PROP_TAG(PT_STRING8, 32954)
|
||||
PR_EMS_AB_IMPORT_CONTAINER_W = PROP_TAG(PT_UNICODE, 32954)
|
||||
PR_EMS_AB_IMPORT_CONTAINER_O = PROP_TAG(PT_OBJECT, 32954)
|
||||
PR_EMS_AB_IMPORT_CONTAINER_T = PROP_TAG(PT_TSTRING, 32954)
|
||||
PR_EMS_AB_IMPORT_SENSITIVITY = PROP_TAG(PT_LONG, 32955)
|
||||
PR_EMS_AB_IMPORTED_FROM = PROP_TAG(PT_TSTRING, 32834)
|
||||
PR_EMS_AB_IMPORTED_FROM_A = PROP_TAG(PT_STRING8, 32834)
|
||||
PR_EMS_AB_IMPORTED_FROM_W = PROP_TAG(PT_UNICODE, 32834)
|
||||
PR_EMS_AB_INBOUND_SITES = PROP_TAG(PT_MV_TSTRING, 32956)
|
||||
PR_EMS_AB_INBOUND_SITES_A = PROP_TAG(PT_MV_STRING8, 32956)
|
||||
PR_EMS_AB_INBOUND_SITES_W = PROP_TAG(PT_MV_UNICODE, 32956)
|
||||
PR_EMS_AB_INBOUND_SITES_O = PROP_TAG(PT_OBJECT, 32956)
|
||||
PR_EMS_AB_INBOUND_SITES_T = PROP_TAG(PT_MV_TSTRING, 32956)
|
||||
PR_EMS_AB_INSTANCE_TYPE = PROP_TAG(PT_LONG, 32957)
|
||||
PR_EMS_AB_INTERNATIONAL_ISDN_NUMBER = PROP_TAG(PT_MV_TSTRING, 32958)
|
||||
PR_EMS_AB_INTERNATIONAL_ISDN_NUMBER_A = PROP_TAG(PT_MV_STRING8, 32958)
|
||||
PR_EMS_AB_INTERNATIONAL_ISDN_NUMBER_W = PROP_TAG(PT_MV_UNICODE, 32958)
|
||||
PR_EMS_AB_INVOCATION_ID = PROP_TAG(PT_BINARY, 32959)
|
||||
PR_EMS_AB_IS_DELETED = PROP_TAG(PT_BOOLEAN, 32960)
|
||||
PR_EMS_AB_IS_MEMBER_OF_DL = PROP_TAG(PT_OBJECT, 32776)
|
||||
PR_EMS_AB_IS_MEMBER_OF_DL_A = PROP_TAG(PT_MV_STRING8, 32776)
|
||||
PR_EMS_AB_IS_MEMBER_OF_DL_W = PROP_TAG(PT_MV_UNICODE, 32776)
|
||||
PR_EMS_AB_IS_MEMBER_OF_DL_O = PROP_TAG(PT_OBJECT, 32776)
|
||||
PR_EMS_AB_IS_MEMBER_OF_DL_T = PROP_TAG(PT_MV_TSTRING, 32776)
|
||||
PR_EMS_AB_IS_SINGLE_VALUED = PROP_TAG(PT_BOOLEAN, 32961)
|
||||
PR_EMS_AB_KCC_STATUS = PROP_TAG(PT_MV_BINARY, 32962)
|
||||
PR_EMS_AB_KM_SERVER = PROP_TAG(PT_TSTRING, 32781)
|
||||
PR_EMS_AB_KM_SERVER_A = PROP_TAG(PT_STRING8, 32781)
|
||||
PR_EMS_AB_KM_SERVER_W = PROP_TAG(PT_UNICODE, 32781)
|
||||
PR_EMS_AB_KM_SERVER_O = PROP_TAG(PT_OBJECT, 32781)
|
||||
PR_EMS_AB_KM_SERVER_T = PROP_TAG(PT_TSTRING, 32781)
|
||||
PR_EMS_AB_KNOWLEDGE_INFORMATION = PROP_TAG(PT_MV_TSTRING, 32963)
|
||||
PR_EMS_AB_KNOWLEDGE_INFORMATION_A = PROP_TAG(PT_MV_STRING8, 32963)
|
||||
PR_EMS_AB_KNOWLEDGE_INFORMATION_W = PROP_TAG(PT_MV_UNICODE, 32963)
|
||||
PR_EMS_AB_LANGUAGE = PROP_TAG(PT_LONG, 33144)
|
||||
PR_EMS_AB_LDAP_DISPLAY_NAME = PROP_TAG(PT_MV_TSTRING, 33137)
|
||||
PR_EMS_AB_LDAP_DISPLAY_NAME_A = PROP_TAG(PT_MV_STRING8, 33137)
|
||||
PR_EMS_AB_LDAP_DISPLAY_NAME_W = PROP_TAG(PT_MV_UNICODE, 33137)
|
||||
PR_EMS_AB_LINE_WRAP = PROP_TAG(PT_LONG, 32964)
|
||||
PR_EMS_AB_LINK_ID = PROP_TAG(PT_LONG, 32965)
|
||||
PR_EMS_AB_LOCAL_BRIDGE_HEAD = PROP_TAG(PT_TSTRING, 32966)
|
||||
PR_EMS_AB_LOCAL_BRIDGE_HEAD_A = PROP_TAG(PT_STRING8, 32966)
|
||||
PR_EMS_AB_LOCAL_BRIDGE_HEAD_W = PROP_TAG(PT_UNICODE, 32966)
|
||||
PR_EMS_AB_LOCAL_BRIDGE_HEAD_ADDRESS = PROP_TAG(PT_TSTRING, 32967)
|
||||
PR_EMS_AB_LOCAL_BRIDGE_HEAD_ADDRESS_A = PROP_TAG(PT_STRING8, 32967)
|
||||
PR_EMS_AB_LOCAL_BRIDGE_HEAD_ADDRESS_W = PROP_TAG(PT_UNICODE, 32967)
|
||||
PR_EMS_AB_LOCAL_INITIAL_TURN = PROP_TAG(PT_BOOLEAN, 32968)
|
||||
PR_EMS_AB_LOCAL_SCOPE = PROP_TAG(PT_MV_TSTRING, 32969)
|
||||
PR_EMS_AB_LOCAL_SCOPE_A = PROP_TAG(PT_MV_STRING8, 32969)
|
||||
PR_EMS_AB_LOCAL_SCOPE_W = PROP_TAG(PT_MV_UNICODE, 32969)
|
||||
PR_EMS_AB_LOCAL_SCOPE_O = PROP_TAG(PT_OBJECT, 32969)
|
||||
PR_EMS_AB_LOCAL_SCOPE_T = PROP_TAG(PT_MV_TSTRING, 32969)
|
||||
PR_EMS_AB_LOG_FILENAME = PROP_TAG(PT_TSTRING, 32970)
|
||||
PR_EMS_AB_LOG_FILENAME_A = PROP_TAG(PT_STRING8, 32970)
|
||||
PR_EMS_AB_LOG_FILENAME_W = PROP_TAG(PT_UNICODE, 32970)
|
||||
PR_EMS_AB_LOG_ROLLOVER_INTERVAL = PROP_TAG(PT_LONG, 32971)
|
||||
PR_EMS_AB_MAINTAIN_AUTOREPLY_HISTORY = PROP_TAG(PT_BOOLEAN, 32972)
|
||||
PR_EMS_AB_MANAGER = PROP_TAG(PT_OBJECT, 32773)
|
||||
PR_EMS_AB_MANAGER_A = PROP_TAG(PT_STRING8, 32773)
|
||||
PR_EMS_AB_MANAGER_W = PROP_TAG(PT_UNICODE, 32773)
|
||||
PR_EMS_AB_MANAGER_O = PROP_TAG(PT_OBJECT, 32773)
|
||||
PR_EMS_AB_MANAGER_T = PROP_TAG(PT_TSTRING, 32773)
|
||||
PR_EMS_AB_MAPI_DISPLAY_TYPE = PROP_TAG(PT_LONG, 32973)
|
||||
PR_EMS_AB_MAPI_ID = PROP_TAG(PT_LONG, 32974)
|
||||
PR_EMS_AB_MAXIMUM_OBJECT_ID = PROP_TAG(PT_BINARY, 33129)
|
||||
PR_EMS_AB_MDB_BACKOFF_INTERVAL = PROP_TAG(PT_LONG, 32975)
|
||||
PR_EMS_AB_MDB_MSG_TIME_OUT_PERIOD = PROP_TAG(PT_LONG, 32976)
|
||||
PR_EMS_AB_MDB_OVER_QUOTA_LIMIT = PROP_TAG(PT_LONG, 32977)
|
||||
PR_EMS_AB_MDB_STORAGE_QUOTA = PROP_TAG(PT_LONG, 32978)
|
||||
PR_EMS_AB_MDB_UNREAD_LIMIT = PROP_TAG(PT_LONG, 32979)
|
||||
PR_EMS_AB_MDB_USE_DEFAULTS = PROP_TAG(PT_BOOLEAN, 32980)
|
||||
PR_EMS_AB_MEMBER = PROP_TAG(PT_OBJECT, 32777)
|
||||
PR_EMS_AB_MEMBER_A = PROP_TAG(PT_MV_STRING8, 32777)
|
||||
PR_EMS_AB_MEMBER_W = PROP_TAG(PT_MV_UNICODE, 32777)
|
||||
PR_EMS_AB_MEMBER_O = PROP_TAG(PT_OBJECT, 32777)
|
||||
PR_EMS_AB_MEMBER_T = PROP_TAG(PT_MV_TSTRING, 32777)
|
||||
PR_EMS_AB_MESSAGE_TRACKING_ENABLED = PROP_TAG(PT_BOOLEAN, 32981)
|
||||
PR_EMS_AB_MONITOR_CLOCK = PROP_TAG(PT_BOOLEAN, 32982)
|
||||
PR_EMS_AB_MONITOR_SERVERS = PROP_TAG(PT_BOOLEAN, 32983)
|
||||
PR_EMS_AB_MONITOR_SERVICES = PROP_TAG(PT_BOOLEAN, 32984)
|
||||
PR_EMS_AB_MONITORED_CONFIGURATIONS = PROP_TAG(PT_MV_TSTRING, 32985)
|
||||
PR_EMS_AB_MONITORED_CONFIGURATIONS_A = PROP_TAG(PT_MV_STRING8, 32985)
|
||||
PR_EMS_AB_MONITORED_CONFIGURATIONS_W = PROP_TAG(PT_MV_UNICODE, 32985)
|
||||
PR_EMS_AB_MONITORED_CONFIGURATIONS_O = PROP_TAG(PT_OBJECT, 32985)
|
||||
PR_EMS_AB_MONITORED_CONFIGURATIONS_T = PROP_TAG(PT_MV_TSTRING, 32985)
|
||||
PR_EMS_AB_MONITORED_SERVERS = PROP_TAG(PT_MV_TSTRING, 32986)
|
||||
PR_EMS_AB_MONITORED_SERVERS_A = PROP_TAG(PT_MV_STRING8, 32986)
|
||||
PR_EMS_AB_MONITORED_SERVERS_W = PROP_TAG(PT_MV_UNICODE, 32986)
|
||||
PR_EMS_AB_MONITORED_SERVERS_O = PROP_TAG(PT_OBJECT, 32986)
|
||||
PR_EMS_AB_MONITORED_SERVERS_T = PROP_TAG(PT_MV_TSTRING, 32986)
|
||||
PR_EMS_AB_MONITORED_SERVICES = PROP_TAG(PT_MV_TSTRING, 32987)
|
||||
PR_EMS_AB_MONITORED_SERVICES_A = PROP_TAG(PT_MV_STRING8, 32987)
|
||||
PR_EMS_AB_MONITORED_SERVICES_W = PROP_TAG(PT_MV_UNICODE, 32987)
|
||||
PR_EMS_AB_MONITORING_ALERT_DELAY = PROP_TAG(PT_LONG, 32988)
|
||||
PR_EMS_AB_MONITORING_ALERT_UNITS = PROP_TAG(PT_LONG, 32989)
|
||||
PR_EMS_AB_MONITORING_AVAILABILITY_STYLE = PROP_TAG(PT_LONG, 32990)
|
||||
PR_EMS_AB_MONITORING_AVAILABILITY_WINDOW = PROP_TAG(PT_BINARY, 32991)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_MAIL = PROP_TAG(PT_MV_TSTRING, 32992)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_MAIL_A = PROP_TAG(PT_MV_STRING8, 32992)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_MAIL_W = PROP_TAG(PT_MV_UNICODE, 32992)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_MAIL_O = PROP_TAG(PT_OBJECT, 32992)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_MAIL_T = PROP_TAG(PT_MV_TSTRING, 32992)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_RPC = PROP_TAG(PT_MV_TSTRING, 32993)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_RPC_A = PROP_TAG(PT_MV_STRING8, 32993)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_RPC_W = PROP_TAG(PT_MV_UNICODE, 32993)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_RPC_O = PROP_TAG(PT_OBJECT, 32993)
|
||||
PR_EMS_AB_MONITORING_CACHED_VIA_RPC_T = PROP_TAG(PT_MV_TSTRING, 32993)
|
||||
PR_EMS_AB_MONITORING_ESCALATION_PROCEDURE = PROP_TAG(PT_MV_BINARY, 32994)
|
||||
PR_EMS_AB_MONITORING_HOTSITE_POLL_INTERVAL = PROP_TAG(PT_LONG, 32995)
|
||||
PR_EMS_AB_MONITORING_HOTSITE_POLL_UNITS = PROP_TAG(PT_LONG, 32996)
|
||||
PR_EMS_AB_MONITORING_MAIL_UPDATE_INTERVAL = PROP_TAG(PT_LONG, 32997)
|
||||
PR_EMS_AB_MONITORING_MAIL_UPDATE_UNITS = PROP_TAG(PT_LONG, 32998)
|
||||
PR_EMS_AB_MONITORING_NORMAL_POLL_INTERVAL = PROP_TAG(PT_LONG, 32999)
|
||||
PR_EMS_AB_MONITORING_NORMAL_POLL_UNITS = PROP_TAG(PT_LONG, 33000)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS = PROP_TAG(PT_MV_TSTRING, 33001)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_A = PROP_TAG(PT_MV_STRING8, 33001)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_W = PROP_TAG(PT_MV_UNICODE, 33001)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_O = PROP_TAG(PT_OBJECT, 33001)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_T = PROP_TAG(PT_MV_TSTRING, 33001)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_NDR = PROP_TAG(PT_MV_TSTRING, 33002)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_NDR_A = PROP_TAG(PT_MV_STRING8, 33002)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_NDR_W = PROP_TAG(PT_MV_UNICODE, 33002)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_NDR_O = PROP_TAG(PT_OBJECT, 33002)
|
||||
PR_EMS_AB_MONITORING_RECIPIENTS_NDR_T = PROP_TAG(PT_MV_TSTRING, 33002)
|
||||
PR_EMS_AB_MONITORING_RPC_UPDATE_INTERVAL = PROP_TAG(PT_LONG, 33003)
|
||||
PR_EMS_AB_MONITORING_RPC_UPDATE_UNITS = PROP_TAG(PT_LONG, 33004)
|
||||
PR_EMS_AB_MONITORING_WARNING_DELAY = PROP_TAG(PT_LONG, 33005)
|
||||
PR_EMS_AB_MONITORING_WARNING_UNITS = PROP_TAG(PT_LONG, 33006)
|
||||
PR_EMS_AB_MTA_LOCAL_CRED = PROP_TAG(PT_TSTRING, 33007)
|
||||
PR_EMS_AB_MTA_LOCAL_CRED_A = PROP_TAG(PT_STRING8, 33007)
|
||||
PR_EMS_AB_MTA_LOCAL_CRED_W = PROP_TAG(PT_UNICODE, 33007)
|
||||
PR_EMS_AB_MTA_LOCAL_DESIG = PROP_TAG(PT_TSTRING, 33008)
|
||||
PR_EMS_AB_MTA_LOCAL_DESIG_A = PROP_TAG(PT_STRING8, 33008)
|
||||
PR_EMS_AB_MTA_LOCAL_DESIG_W = PROP_TAG(PT_UNICODE, 33008)
|
||||
PR_EMS_AB_N_ADDRESS = PROP_TAG(PT_BINARY, 33009)
|
||||
PR_EMS_AB_N_ADDRESS_TYPE = PROP_TAG(PT_LONG, 33010)
|
||||
PR_EMS_AB_NETWORK_ADDRESS = PROP_TAG(PT_MV_TSTRING, 33136)
|
||||
PR_EMS_AB_NETWORK_ADDRESS_A = PROP_TAG(PT_MV_STRING8, 33136)
|
||||
PR_EMS_AB_NETWORK_ADDRESS_W = PROP_TAG(PT_MV_UNICODE, 33136)
|
||||
PR_EMS_AB_NNTP_CHARACTER_SET = PROP_TAG(PT_TSTRING, 33149)
|
||||
PR_EMS_AB_NNTP_CHARACTER_SET_A = PROP_TAG(PT_STRING8, 33149)
|
||||
PR_EMS_AB_NNTP_CHARACTER_SET_W = PROP_TAG(PT_UNICODE, 33149)
|
||||
PR_EMS_AB_NNTP_CONTENT_FORMAT = PROP_TAG(PT_TSTRING, 33142)
|
||||
PR_EMS_AB_NNTP_CONTENT_FORMAT_A = PROP_TAG(PT_STRING8, 33142)
|
||||
PR_EMS_AB_NNTP_CONTENT_FORMAT_W = PROP_TAG(PT_UNICODE, 33142)
|
||||
PR_EMS_AB_NT_MACHINE_NAME = PROP_TAG(PT_TSTRING, 33011)
|
||||
PR_EMS_AB_NT_MACHINE_NAME_A = PROP_TAG(PT_STRING8, 33011)
|
||||
PR_EMS_AB_NT_MACHINE_NAME_W = PROP_TAG(PT_UNICODE, 33011)
|
||||
PR_EMS_AB_NT_SECURITY_DESCRIPTOR = PROP_TAG(PT_BINARY, 32787)
|
||||
PR_EMS_AB_NUM_OF_OPEN_RETRIES = PROP_TAG(PT_LONG, 33012)
|
||||
PR_EMS_AB_NUM_OF_TRANSFER_RETRIES = PROP_TAG(PT_LONG, 33013)
|
||||
PR_EMS_AB_OBJ_DIST_NAME = PROP_TAG(PT_TSTRING, 32828)
|
||||
PR_EMS_AB_OBJ_DIST_NAME_A = PROP_TAG(PT_STRING8, 32828)
|
||||
PR_EMS_AB_OBJ_DIST_NAME_W = PROP_TAG(PT_UNICODE, 32828)
|
||||
PR_EMS_AB_OBJ_DIST_NAME_O = PROP_TAG(PT_OBJECT, 32828)
|
||||
PR_EMS_AB_OBJ_DIST_NAME_T = PROP_TAG(PT_TSTRING, 32828)
|
||||
PR_EMS_AB_OBJECT_CLASS_CATEGORY = PROP_TAG(PT_LONG, 33014)
|
||||
PR_EMS_AB_OBJECT_VERSION = PROP_TAG(PT_LONG, 33015)
|
||||
PR_EMS_AB_OFF_LINE_AB_CONTAINERS = PROP_TAG(PT_MV_TSTRING, 33016)
|
||||
PR_EMS_AB_OFF_LINE_AB_CONTAINERS_A = PROP_TAG(PT_MV_STRING8, 33016)
|
||||
PR_EMS_AB_OFF_LINE_AB_CONTAINERS_W = PROP_TAG(PT_MV_UNICODE, 33016)
|
||||
PR_EMS_AB_OFF_LINE_AB_CONTAINERS_O = PROP_TAG(PT_OBJECT, 33016)
|
||||
PR_EMS_AB_OFF_LINE_AB_CONTAINERS_T = PROP_TAG(PT_MV_TSTRING, 33016)
|
||||
PR_EMS_AB_OFF_LINE_AB_SCHEDULE = PROP_TAG(PT_BINARY, 33017)
|
||||
PR_EMS_AB_OFF_LINE_AB_SERVER = PROP_TAG(PT_TSTRING, 33018)
|
||||
PR_EMS_AB_OFF_LINE_AB_SERVER_A = PROP_TAG(PT_STRING8, 33018)
|
||||
PR_EMS_AB_OFF_LINE_AB_SERVER_W = PROP_TAG(PT_UNICODE, 33018)
|
||||
PR_EMS_AB_OFF_LINE_AB_SERVER_O = PROP_TAG(PT_OBJECT, 33018)
|
||||
PR_EMS_AB_OFF_LINE_AB_SERVER_T = PROP_TAG(PT_TSTRING, 33018)
|
||||
PR_EMS_AB_OFF_LINE_AB_STYLE = PROP_TAG(PT_LONG, 33019)
|
||||
PR_EMS_AB_OID_TYPE = PROP_TAG(PT_LONG, 33020)
|
||||
PR_EMS_AB_OM_OBJECT_CLASS = PROP_TAG(PT_BINARY, 33021)
|
||||
PR_EMS_AB_OM_SYNTAX = PROP_TAG(PT_LONG, 33022)
|
||||
PR_EMS_AB_OOF_REPLY_TO_ORIGINATOR = PROP_TAG(PT_BOOLEAN, 33023)
|
||||
PR_EMS_AB_OPEN_RETRY_INTERVAL = PROP_TAG(PT_LONG, 33024)
|
||||
PR_EMS_AB_ORGANIZATION_NAME = PROP_TAG(PT_MV_TSTRING, 33025)
|
||||
PR_EMS_AB_ORGANIZATION_NAME_A = PROP_TAG(PT_MV_STRING8, 33025)
|
||||
PR_EMS_AB_ORGANIZATION_NAME_W = PROP_TAG(PT_MV_UNICODE, 33025)
|
||||
PR_EMS_AB_ORGANIZATIONAL_UNIT_NAME = PROP_TAG(PT_MV_TSTRING, 33026)
|
||||
PR_EMS_AB_ORGANIZATIONAL_UNIT_NAME_A = PROP_TAG(PT_MV_STRING8, 33026)
|
||||
PR_EMS_AB_ORGANIZATIONAL_UNIT_NAME_W = PROP_TAG(PT_MV_UNICODE, 33026)
|
||||
PR_EMS_AB_ORIGINAL_DISPLAY_TABLE = PROP_TAG(PT_BINARY, 33027)
|
||||
PR_EMS_AB_ORIGINAL_DISPLAY_TABLE_MSDOS = PROP_TAG(PT_BINARY, 33028)
|
||||
PR_EMS_AB_OUTBOUND_SITES = PROP_TAG(PT_MV_TSTRING, 33029)
|
||||
PR_EMS_AB_OUTBOUND_SITES_A = PROP_TAG(PT_MV_STRING8, 33029)
|
||||
PR_EMS_AB_OUTBOUND_SITES_W = PROP_TAG(PT_MV_UNICODE, 33029)
|
||||
PR_EMS_AB_OUTBOUND_SITES_O = PROP_TAG(PT_OBJECT, 33029)
|
||||
PR_EMS_AB_OUTBOUND_SITES_T = PROP_TAG(PT_MV_TSTRING, 33029)
|
||||
PR_EMS_AB_OWNER = PROP_TAG(PT_TSTRING, 32780)
|
||||
PR_EMS_AB_OWNER_A = PROP_TAG(PT_STRING8, 32780)
|
||||
PR_EMS_AB_OWNER_W = PROP_TAG(PT_UNICODE, 32780)
|
||||
PR_EMS_AB_OWNER_O = PROP_TAG(PT_OBJECT, 32780)
|
||||
PR_EMS_AB_OWNER_T = PROP_TAG(PT_TSTRING, 32780)
|
||||
PR_EMS_AB_OWNER_BL = PROP_TAG(PT_TSTRING, 32804)
|
||||
PR_EMS_AB_OWNER_BL_A = PROP_TAG(PT_STRING8, 32804)
|
||||
PR_EMS_AB_OWNER_BL_W = PROP_TAG(PT_UNICODE, 32804)
|
||||
PR_EMS_AB_OWNER_BL_O = PROP_TAG(PT_OBJECT, 32804)
|
||||
PR_EMS_AB_OWNER_BL_T = PROP_TAG(PT_TSTRING, 32804)
|
||||
PR_EMS_AB_P_SELECTOR = PROP_TAG(PT_BINARY, 33030)
|
||||
PR_EMS_AB_P_SELECTOR_INBOUND = PROP_TAG(PT_BINARY, 33031)
|
||||
PR_EMS_AB_PER_MSG_DIALOG_DISPLAY_TABLE = PROP_TAG(PT_BINARY, 33032)
|
||||
PR_EMS_AB_PER_RECIP_DIALOG_DISPLAY_TABLE = PROP_TAG(PT_BINARY, 33033)
|
||||
PR_EMS_AB_PERIOD_REP_SYNC_TIMES = PROP_TAG(PT_BINARY, 33034)
|
||||
PR_EMS_AB_PERIOD_REPL_STAGGER = PROP_TAG(PT_LONG, 33035)
|
||||
PR_EMS_AB_PF_CONTACTS = PROP_TAG(PT_MV_TSTRING, 32824)
|
||||
PR_EMS_AB_PF_CONTACTS_A = PROP_TAG(PT_MV_STRING8, 32824)
|
||||
PR_EMS_AB_PF_CONTACTS_W = PROP_TAG(PT_MV_UNICODE, 32824)
|
||||
PR_EMS_AB_PF_CONTACTS_O = PROP_TAG(PT_OBJECT, 32824)
|
||||
PR_EMS_AB_PF_CONTACTS_T = PROP_TAG(PT_MV_TSTRING, 32824)
|
||||
PR_EMS_AB_POP_CHARACTER_SET = PROP_TAG(PT_TSTRING, 33145)
|
||||
PR_EMS_AB_POP_CHARACTER_SET_A = PROP_TAG(PT_STRING8, 33145)
|
||||
PR_EMS_AB_POP_CHARACTER_SET_W = PROP_TAG(PT_UNICODE, 33145)
|
||||
PR_EMS_AB_POP_CONTENT_FORMAT = PROP_TAG(PT_TSTRING, 33143)
|
||||
PR_EMS_AB_POP_CONTENT_FORMAT_A = PROP_TAG(PT_STRING8, 33143)
|
||||
PR_EMS_AB_POP_CONTENT_FORMAT_W = PROP_TAG(PT_UNICODE, 33143)
|
||||
PR_EMS_AB_POSTAL_ADDRESS = PROP_TAG(PT_MV_BINARY, 33036)
|
||||
PR_EMS_AB_PREFERRED_DELIVERY_METHOD = PROP_TAG(PT_MV_LONG, 33037)
|
||||
PR_EMS_AB_PRMD = PROP_TAG(PT_TSTRING, 33038)
|
||||
PR_EMS_AB_PRMD_A = PROP_TAG(PT_STRING8, 33038)
|
||||
PR_EMS_AB_PRMD_W = PROP_TAG(PT_UNICODE, 33038)
|
||||
PR_EMS_AB_PROXY_ADDRESSES = PROP_TAG(PT_MV_TSTRING, 32783)
|
||||
PR_EMS_AB_PROXY_ADDRESSES_A = PROP_TAG(PT_MV_STRING8, 32783)
|
||||
PR_EMS_AB_PROXY_ADDRESSES_W = PROP_TAG(PT_MV_UNICODE, 32783)
|
||||
PR_EMS_AB_PROXY_GENERATOR_DLL = PROP_TAG(PT_TSTRING, 33039)
|
||||
PR_EMS_AB_PROXY_GENERATOR_DLL_A = PROP_TAG(PT_STRING8, 33039)
|
||||
PR_EMS_AB_PROXY_GENERATOR_DLL_W = PROP_TAG(PT_UNICODE, 33039)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES = PROP_TAG(PT_OBJECT, 32789)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_A = PROP_TAG(PT_MV_STRING8, 32789)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_W = PROP_TAG(PT_MV_UNICODE, 32789)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_O = PROP_TAG(PT_OBJECT, 32789)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_T = PROP_TAG(PT_MV_TSTRING, 32789)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_BL = PROP_TAG(PT_MV_TSTRING, 33040)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_BL_A = PROP_TAG(PT_MV_STRING8, 33040)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_BL_W = PROP_TAG(PT_MV_UNICODE, 33040)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_BL_O = PROP_TAG(PT_OBJECT, 33040)
|
||||
PR_EMS_AB_PUBLIC_DELEGATES_BL_T = PROP_TAG(PT_MV_TSTRING, 33040)
|
||||
PR_EMS_AB_QUOTA_NOTIFICATION_SCHEDULE = PROP_TAG(PT_BINARY, 33041)
|
||||
PR_EMS_AB_QUOTA_NOTIFICATION_STYLE = PROP_TAG(PT_LONG, 33042)
|
||||
PR_EMS_AB_RANGE_LOWER = PROP_TAG(PT_LONG, 33043)
|
||||
PR_EMS_AB_RANGE_UPPER = PROP_TAG(PT_LONG, 33044)
|
||||
PR_EMS_AB_RAS_CALLBACK_NUMBER = PROP_TAG(PT_TSTRING, 33045)
|
||||
PR_EMS_AB_RAS_CALLBACK_NUMBER_A = PROP_TAG(PT_STRING8, 33045)
|
||||
PR_EMS_AB_RAS_CALLBACK_NUMBER_W = PROP_TAG(PT_UNICODE, 33045)
|
||||
PR_EMS_AB_RAS_PHONE_NUMBER = PROP_TAG(PT_TSTRING, 33046)
|
||||
PR_EMS_AB_RAS_PHONE_NUMBER_A = PROP_TAG(PT_STRING8, 33046)
|
||||
PR_EMS_AB_RAS_PHONE_NUMBER_W = PROP_TAG(PT_UNICODE, 33046)
|
||||
PR_EMS_AB_RAS_PHONEBOOK_ENTRY_NAME = PROP_TAG(PT_TSTRING, 33047)
|
||||
PR_EMS_AB_RAS_PHONEBOOK_ENTRY_NAME_A = PROP_TAG(PT_STRING8, 33047)
|
||||
PR_EMS_AB_RAS_PHONEBOOK_ENTRY_NAME_W = PROP_TAG(PT_UNICODE, 33047)
|
||||
PR_EMS_AB_RAS_REMOTE_SRVR_NAME = PROP_TAG(PT_TSTRING, 33048)
|
||||
PR_EMS_AB_RAS_REMOTE_SRVR_NAME_A = PROP_TAG(PT_STRING8, 33048)
|
||||
PR_EMS_AB_RAS_REMOTE_SRVR_NAME_W = PROP_TAG(PT_UNICODE, 33048)
|
||||
PR_EMS_AB_REGISTERED_ADDRESS = PROP_TAG(PT_MV_BINARY, 33049)
|
||||
PR_EMS_AB_REMOTE_BRIDGE_HEAD = PROP_TAG(PT_TSTRING, 33050)
|
||||
PR_EMS_AB_REMOTE_BRIDGE_HEAD_A = PROP_TAG(PT_STRING8, 33050)
|
||||
PR_EMS_AB_REMOTE_BRIDGE_HEAD_W = PROP_TAG(PT_UNICODE, 33050)
|
||||
PR_EMS_AB_REMOTE_BRIDGE_HEAD_ADDRESS = PROP_TAG(PT_TSTRING, 33051)
|
||||
PR_EMS_AB_REMOTE_BRIDGE_HEAD_ADDRESS_A = PROP_TAG(PT_STRING8, 33051)
|
||||
PR_EMS_AB_REMOTE_BRIDGE_HEAD_ADDRESS_W = PROP_TAG(PT_UNICODE, 33051)
|
||||
PR_EMS_AB_REMOTE_OUT_BH_SERVER = PROP_TAG(PT_TSTRING, 33052)
|
||||
PR_EMS_AB_REMOTE_OUT_BH_SERVER_A = PROP_TAG(PT_STRING8, 33052)
|
||||
PR_EMS_AB_REMOTE_OUT_BH_SERVER_W = PROP_TAG(PT_UNICODE, 33052)
|
||||
PR_EMS_AB_REMOTE_OUT_BH_SERVER_O = PROP_TAG(PT_OBJECT, 33052)
|
||||
PR_EMS_AB_REMOTE_OUT_BH_SERVER_T = PROP_TAG(PT_TSTRING, 33052)
|
||||
PR_EMS_AB_REMOTE_SITE = PROP_TAG(PT_TSTRING, 33053)
|
||||
PR_EMS_AB_REMOTE_SITE_A = PROP_TAG(PT_STRING8, 33053)
|
||||
PR_EMS_AB_REMOTE_SITE_W = PROP_TAG(PT_UNICODE, 33053)
|
||||
PR_EMS_AB_REMOTE_SITE_O = PROP_TAG(PT_OBJECT, 33053)
|
||||
PR_EMS_AB_REMOTE_SITE_T = PROP_TAG(PT_TSTRING, 33053)
|
||||
PR_EMS_AB_REPLICATION_MAIL_MSG_SIZE = PROP_TAG(PT_LONG, 33128)
|
||||
PR_EMS_AB_REPLICATION_SENSITIVITY = PROP_TAG(PT_LONG, 33054)
|
||||
PR_EMS_AB_REPLICATION_STAGGER = PROP_TAG(PT_LONG, 33055)
|
||||
PR_EMS_AB_REPORT_TO_ORIGINATOR = PROP_TAG(PT_BOOLEAN, 33056)
|
||||
PR_EMS_AB_REPORT_TO_OWNER = PROP_TAG(PT_BOOLEAN, 33057)
|
||||
PR_EMS_AB_REPORTS = PROP_TAG(PT_OBJECT, 32782)
|
||||
PR_EMS_AB_REPORTS_A = PROP_TAG(PT_MV_STRING8, 32782)
|
||||
PR_EMS_AB_REPORTS_W = PROP_TAG(PT_MV_UNICODE, 32782)
|
||||
PR_EMS_AB_REPORTS_O = PROP_TAG(PT_OBJECT, 32782)
|
||||
PR_EMS_AB_REPORTS_T = PROP_TAG(PT_MV_TSTRING, 32782)
|
||||
PR_EMS_AB_REQ_SEQ = PROP_TAG(PT_LONG, 33058)
|
||||
PR_EMS_AB_RESPONSIBLE_LOCAL_DXA = PROP_TAG(PT_TSTRING, 33059)
|
||||
PR_EMS_AB_RESPONSIBLE_LOCAL_DXA_A = PROP_TAG(PT_STRING8, 33059)
|
||||
PR_EMS_AB_RESPONSIBLE_LOCAL_DXA_W = PROP_TAG(PT_UNICODE, 33059)
|
||||
PR_EMS_AB_RESPONSIBLE_LOCAL_DXA_O = PROP_TAG(PT_OBJECT, 33059)
|
||||
PR_EMS_AB_RESPONSIBLE_LOCAL_DXA_T = PROP_TAG(PT_TSTRING, 33059)
|
||||
PR_EMS_AB_RID_SERVER = PROP_TAG(PT_TSTRING, 33060)
|
||||
PR_EMS_AB_RID_SERVER_A = PROP_TAG(PT_STRING8, 33060)
|
||||
PR_EMS_AB_RID_SERVER_W = PROP_TAG(PT_UNICODE, 33060)
|
||||
PR_EMS_AB_RID_SERVER_O = PROP_TAG(PT_OBJECT, 33060)
|
||||
PR_EMS_AB_RID_SERVER_T = PROP_TAG(PT_TSTRING, 33060)
|
||||
PR_EMS_AB_ROLE_OCCUPANT = PROP_TAG(PT_MV_TSTRING, 33061)
|
||||
PR_EMS_AB_ROLE_OCCUPANT_A = PROP_TAG(PT_MV_STRING8, 33061)
|
||||
PR_EMS_AB_ROLE_OCCUPANT_W = PROP_TAG(PT_MV_UNICODE, 33061)
|
||||
PR_EMS_AB_ROLE_OCCUPANT_O = PROP_TAG(PT_OBJECT, 33061)
|
||||
PR_EMS_AB_ROLE_OCCUPANT_T = PROP_TAG(PT_MV_TSTRING, 33061)
|
||||
PR_EMS_AB_ROUTING_LIST = PROP_TAG(PT_MV_TSTRING, 33062)
|
||||
PR_EMS_AB_ROUTING_LIST_A = PROP_TAG(PT_MV_STRING8, 33062)
|
||||
PR_EMS_AB_ROUTING_LIST_W = PROP_TAG(PT_MV_UNICODE, 33062)
|
||||
PR_EMS_AB_RTS_CHECKPOINT_SIZE = PROP_TAG(PT_LONG, 33063)
|
||||
PR_EMS_AB_RTS_RECOVERY_TIMEOUT = PROP_TAG(PT_LONG, 33064)
|
||||
PR_EMS_AB_RTS_WINDOW_SIZE = PROP_TAG(PT_LONG, 33065)
|
||||
PR_EMS_AB_RUNS_ON = PROP_TAG(PT_MV_TSTRING, 33066)
|
||||
PR_EMS_AB_RUNS_ON_A = PROP_TAG(PT_MV_STRING8, 33066)
|
||||
PR_EMS_AB_RUNS_ON_W = PROP_TAG(PT_MV_UNICODE, 33066)
|
||||
PR_EMS_AB_RUNS_ON_O = PROP_TAG(PT_OBJECT, 33066)
|
||||
PR_EMS_AB_RUNS_ON_T = PROP_TAG(PT_MV_TSTRING, 33066)
|
||||
PR_EMS_AB_S_SELECTOR = PROP_TAG(PT_BINARY, 33067)
|
||||
PR_EMS_AB_S_SELECTOR_INBOUND = PROP_TAG(PT_BINARY, 33068)
|
||||
PR_EMS_AB_SCHEMA_FLAGS = PROP_TAG(PT_LONG, 33139)
|
||||
PR_EMS_AB_SCHEMA_VERSION = PROP_TAG(PT_MV_LONG, 33148)
|
||||
PR_EMS_AB_SEARCH_FLAGS = PROP_TAG(PT_LONG, 33069)
|
||||
PR_EMS_AB_SEARCH_GUIDE = PROP_TAG(PT_MV_BINARY, 33070)
|
||||
PR_EMS_AB_SECURITY_PROTOCOL = PROP_TAG(PT_MV_BINARY, 32823)
|
||||
PR_EMS_AB_SEE_ALSO = PROP_TAG(PT_MV_TSTRING, 33071)
|
||||
PR_EMS_AB_SEE_ALSO_A = PROP_TAG(PT_MV_STRING8, 33071)
|
||||
PR_EMS_AB_SEE_ALSO_W = PROP_TAG(PT_MV_UNICODE, 33071)
|
||||
PR_EMS_AB_SEE_ALSO_O = PROP_TAG(PT_OBJECT, 33071)
|
||||
PR_EMS_AB_SEE_ALSO_T = PROP_TAG(PT_MV_TSTRING, 33071)
|
||||
PR_EMS_AB_SERIAL_NUMBER = PROP_TAG(PT_MV_TSTRING, 33072)
|
||||
PR_EMS_AB_SERIAL_NUMBER_A = PROP_TAG(PT_MV_STRING8, 33072)
|
||||
PR_EMS_AB_SERIAL_NUMBER_W = PROP_TAG(PT_MV_UNICODE, 33072)
|
||||
PR_EMS_AB_SERVICE_ACTION_FIRST = PROP_TAG(PT_LONG, 33073)
|
||||
PR_EMS_AB_SERVICE_ACTION_OTHER = PROP_TAG(PT_LONG, 33074)
|
||||
PR_EMS_AB_SERVICE_ACTION_SECOND = PROP_TAG(PT_LONG, 33075)
|
||||
PR_EMS_AB_SERVICE_RESTART_DELAY = PROP_TAG(PT_LONG, 33076)
|
||||
PR_EMS_AB_SERVICE_RESTART_MESSAGE = PROP_TAG(PT_TSTRING, 33077)
|
||||
PR_EMS_AB_SERVICE_RESTART_MESSAGE_A = PROP_TAG(PT_STRING8, 33077)
|
||||
PR_EMS_AB_SERVICE_RESTART_MESSAGE_W = PROP_TAG(PT_UNICODE, 33077)
|
||||
PR_EMS_AB_SESSION_DISCONNECT_TIMER = PROP_TAG(PT_LONG, 33078)
|
||||
PR_EMS_AB_SITE_AFFINITY = PROP_TAG(PT_MV_TSTRING, 33079)
|
||||
PR_EMS_AB_SITE_AFFINITY_A = PROP_TAG(PT_MV_STRING8, 33079)
|
||||
PR_EMS_AB_SITE_AFFINITY_W = PROP_TAG(PT_MV_UNICODE, 33079)
|
||||
PR_EMS_AB_SITE_FOLDER_GUID = PROP_TAG(PT_BINARY, 33126)
|
||||
PR_EMS_AB_SITE_FOLDER_SERVER = PROP_TAG(PT_TSTRING, 33127)
|
||||
PR_EMS_AB_SITE_FOLDER_SERVER_A = PROP_TAG(PT_STRING8, 33127)
|
||||
PR_EMS_AB_SITE_FOLDER_SERVER_W = PROP_TAG(PT_UNICODE, 33127)
|
||||
PR_EMS_AB_SITE_FOLDER_SERVER_O = PROP_TAG(PT_OBJECT, 33127)
|
||||
PR_EMS_AB_SITE_FOLDER_SERVER_T = PROP_TAG(PT_TSTRING, 33127)
|
||||
PR_EMS_AB_SITE_PROXY_SPACE = PROP_TAG(PT_MV_TSTRING, 33080)
|
||||
PR_EMS_AB_SITE_PROXY_SPACE_A = PROP_TAG(PT_MV_STRING8, 33080)
|
||||
PR_EMS_AB_SITE_PROXY_SPACE_W = PROP_TAG(PT_MV_UNICODE, 33080)
|
||||
PR_EMS_AB_SPACE_LAST_COMPUTED = PROP_TAG(PT_SYSTIME, 33081)
|
||||
PR_EMS_AB_STREET_ADDRESS = PROP_TAG(PT_TSTRING, 33082)
|
||||
PR_EMS_AB_STREET_ADDRESS_A = PROP_TAG(PT_STRING8, 33082)
|
||||
PR_EMS_AB_STREET_ADDRESS_W = PROP_TAG(PT_UNICODE, 33082)
|
||||
PR_EMS_AB_SUB_REFS = PROP_TAG(PT_MV_TSTRING, 33083)
|
||||
PR_EMS_AB_SUB_REFS_A = PROP_TAG(PT_MV_STRING8, 33083)
|
||||
PR_EMS_AB_SUB_REFS_W = PROP_TAG(PT_MV_UNICODE, 33083)
|
||||
PR_EMS_AB_SUB_REFS_O = PROP_TAG(PT_OBJECT, 33083)
|
||||
PR_EMS_AB_SUB_REFS_T = PROP_TAG(PT_MV_TSTRING, 33083)
|
||||
PR_EMS_AB_SUB_SITE = PROP_TAG(PT_TSTRING, 33147)
|
||||
PR_EMS_AB_SUB_SITE_A = PROP_TAG(PT_STRING8, 33147)
|
||||
PR_EMS_AB_SUB_SITE_W = PROP_TAG(PT_UNICODE, 33147)
|
||||
PR_EMS_AB_SUBMISSION_CONT_LENGTH = PROP_TAG(PT_LONG, 33084)
|
||||
PR_EMS_AB_SUPPORTED_APPLICATION_CONTEXT = PROP_TAG(PT_MV_BINARY, 33085)
|
||||
PR_EMS_AB_SUPPORTING_STACK = PROP_TAG(PT_MV_TSTRING, 33086)
|
||||
PR_EMS_AB_SUPPORTING_STACK_A = PROP_TAG(PT_MV_STRING8, 33086)
|
||||
PR_EMS_AB_SUPPORTING_STACK_W = PROP_TAG(PT_MV_UNICODE, 33086)
|
||||
PR_EMS_AB_SUPPORTING_STACK_O = PROP_TAG(PT_OBJECT, 33086)
|
||||
PR_EMS_AB_SUPPORTING_STACK_T = PROP_TAG(PT_MV_TSTRING, 33086)
|
||||
PR_EMS_AB_SUPPORTING_STACK_BL = PROP_TAG(PT_MV_TSTRING, 33087)
|
||||
PR_EMS_AB_SUPPORTING_STACK_BL_A = PROP_TAG(PT_MV_STRING8, 33087)
|
||||
PR_EMS_AB_SUPPORTING_STACK_BL_W = PROP_TAG(PT_MV_UNICODE, 33087)
|
||||
PR_EMS_AB_SUPPORTING_STACK_BL_O = PROP_TAG(PT_OBJECT, 33087)
|
||||
PR_EMS_AB_SUPPORTING_STACK_BL_T = PROP_TAG(PT_MV_TSTRING, 33087)
|
||||
PR_EMS_AB_T_SELECTOR = PROP_TAG(PT_BINARY, 33088)
|
||||
PR_EMS_AB_T_SELECTOR_INBOUND = PROP_TAG(PT_BINARY, 33089)
|
||||
PR_EMS_AB_TARGET_ADDRESS = PROP_TAG(PT_TSTRING, 32785)
|
||||
PR_EMS_AB_TARGET_ADDRESS_A = PROP_TAG(PT_STRING8, 32785)
|
||||
PR_EMS_AB_TARGET_ADDRESS_W = PROP_TAG(PT_UNICODE, 32785)
|
||||
PR_EMS_AB_TARGET_MTAS = PROP_TAG(PT_MV_TSTRING, 33090)
|
||||
PR_EMS_AB_TARGET_MTAS_A = PROP_TAG(PT_MV_STRING8, 33090)
|
||||
PR_EMS_AB_TARGET_MTAS_W = PROP_TAG(PT_MV_UNICODE, 33090)
|
||||
PR_EMS_AB_TELEPHONE_NUMBER = PROP_TAG(PT_MV_TSTRING, 32786)
|
||||
PR_EMS_AB_TELEPHONE_NUMBER_A = PROP_TAG(PT_MV_STRING8, 32786)
|
||||
PR_EMS_AB_TELEPHONE_NUMBER_W = PROP_TAG(PT_MV_UNICODE, 32786)
|
||||
PR_EMS_AB_TELETEX_TERMINAL_IDENTIFIER = PROP_TAG(PT_MV_BINARY, 33091)
|
||||
PR_EMS_AB_TEMP_ASSOC_THRESHOLD = PROP_TAG(PT_LONG, 33092)
|
||||
PR_EMS_AB_TOMBSTONE_LIFETIME = PROP_TAG(PT_LONG, 33093)
|
||||
PR_EMS_AB_TRACKING_LOG_PATH_NAME = PROP_TAG(PT_TSTRING, 33094)
|
||||
PR_EMS_AB_TRACKING_LOG_PATH_NAME_A = PROP_TAG(PT_STRING8, 33094)
|
||||
PR_EMS_AB_TRACKING_LOG_PATH_NAME_W = PROP_TAG(PT_UNICODE, 33094)
|
||||
PR_EMS_AB_TRANS_RETRY_MINS = PROP_TAG(PT_LONG, 33095)
|
||||
PR_EMS_AB_TRANS_TIMEOUT_MINS = PROP_TAG(PT_LONG, 33096)
|
||||
PR_EMS_AB_TRANSFER_RETRY_INTERVAL = PROP_TAG(PT_LONG, 33097)
|
||||
PR_EMS_AB_TRANSFER_TIMEOUT_NON_URGENT = PROP_TAG(PT_LONG, 33098)
|
||||
PR_EMS_AB_TRANSFER_TIMEOUT_NORMAL = PROP_TAG(PT_LONG, 33099)
|
||||
PR_EMS_AB_TRANSFER_TIMEOUT_URGENT = PROP_TAG(PT_LONG, 33100)
|
||||
PR_EMS_AB_TRANSLATION_TABLE_USED = PROP_TAG(PT_LONG, 33101)
|
||||
PR_EMS_AB_TRANSPORT_EXPEDITED_DATA = PROP_TAG(PT_BOOLEAN, 33102)
|
||||
PR_EMS_AB_TRUST_LEVEL = PROP_TAG(PT_LONG, 33103)
|
||||
PR_EMS_AB_TURN_REQUEST_THRESHOLD = PROP_TAG(PT_LONG, 33104)
|
||||
PR_EMS_AB_TWO_WAY_ALTERNATE_FACILITY = PROP_TAG(PT_BOOLEAN, 33105)
|
||||
PR_EMS_AB_UNAUTH_ORIG_BL = PROP_TAG(PT_MV_TSTRING, 33106)
|
||||
PR_EMS_AB_UNAUTH_ORIG_BL_A = PROP_TAG(PT_MV_STRING8, 33106)
|
||||
PR_EMS_AB_UNAUTH_ORIG_BL_W = PROP_TAG(PT_MV_UNICODE, 33106)
|
||||
PR_EMS_AB_UNAUTH_ORIG_BL_O = PROP_TAG(PT_OBJECT, 33106)
|
||||
PR_EMS_AB_UNAUTH_ORIG_BL_T = PROP_TAG(PT_MV_TSTRING, 33106)
|
||||
PR_EMS_AB_USE_SERVER_VALUES = PROP_TAG(PT_BOOLEAN, 33150)
|
||||
PR_EMS_AB_USER_PASSWORD = PROP_TAG(PT_MV_BINARY, 33107)
|
||||
PR_EMS_AB_USN_CHANGED = PROP_TAG(PT_LONG, 32809)
|
||||
PR_EMS_AB_USN_CREATED = PROP_TAG(PT_LONG, 33108)
|
||||
PR_EMS_AB_USN_DSA_LAST_OBJ_REMOVED = PROP_TAG(PT_LONG, 33109)
|
||||
PR_EMS_AB_USN_INTERSITE = PROP_TAG(PT_LONG, 33146)
|
||||
PR_EMS_AB_USN_LAST_OBJ_REM = PROP_TAG(PT_LONG, 33110)
|
||||
PR_EMS_AB_USN_SOURCE = PROP_TAG(PT_LONG, 33111)
|
||||
PR_EMS_AB_WWW_HOME_PAGE = PROP_TAG(PT_TSTRING, 33141)
|
||||
PR_EMS_AB_WWW_HOME_PAGE_A = PROP_TAG(PT_STRING8, 33141)
|
||||
PR_EMS_AB_WWW_HOME_PAGE_W = PROP_TAG(PT_UNICODE, 33141)
|
||||
PR_EMS_AB_X121_ADDRESS = PROP_TAG(PT_MV_TSTRING, 33112)
|
||||
PR_EMS_AB_X121_ADDRESS_A = PROP_TAG(PT_MV_STRING8, 33112)
|
||||
PR_EMS_AB_X121_ADDRESS_W = PROP_TAG(PT_MV_UNICODE, 33112)
|
||||
PR_EMS_AB_X25_CALL_USER_DATA_INCOMING = PROP_TAG(PT_BINARY, 33113)
|
||||
PR_EMS_AB_X25_CALL_USER_DATA_OUTGOING = PROP_TAG(PT_BINARY, 33114)
|
||||
PR_EMS_AB_X25_FACILITIES_DATA_INCOMING = PROP_TAG(PT_BINARY, 33115)
|
||||
PR_EMS_AB_X25_FACILITIES_DATA_OUTGOING = PROP_TAG(PT_BINARY, 33116)
|
||||
PR_EMS_AB_X25_LEASED_LINE_PORT = PROP_TAG(PT_BINARY, 33117)
|
||||
PR_EMS_AB_X25_LEASED_OR_SWITCHED = PROP_TAG(PT_BOOLEAN, 33118)
|
||||
PR_EMS_AB_X25_REMOTE_MTA_PHONE = PROP_TAG(PT_TSTRING, 33119)
|
||||
PR_EMS_AB_X25_REMOTE_MTA_PHONE_A = PROP_TAG(PT_STRING8, 33119)
|
||||
PR_EMS_AB_X25_REMOTE_MTA_PHONE_W = PROP_TAG(PT_UNICODE, 33119)
|
||||
PR_EMS_AB_X400_ATTACHMENT_TYPE = PROP_TAG(PT_BINARY, 33120)
|
||||
PR_EMS_AB_X400_SELECTOR_SYNTAX = PROP_TAG(PT_LONG, 33121)
|
||||
PR_EMS_AB_X500_ACCESS_CONTROL_LIST = PROP_TAG(PT_BINARY, 33122)
|
||||
PR_EMS_AB_XMIT_TIMEOUT_NON_URGENT = PROP_TAG(PT_LONG, 33123)
|
||||
PR_EMS_AB_XMIT_TIMEOUT_NORMAL = PROP_TAG(PT_LONG, 33124)
|
||||
PR_EMS_AB_XMIT_TIMEOUT_URGENT = PROP_TAG(PT_LONG, 33125)
|
BIN
lib/win32comext/mapi/exchange.pyd
Normal file
BIN
lib/win32comext/mapi/exchange.pyd
Normal file
Binary file not shown.
BIN
lib/win32comext/mapi/mapi.pyd
Normal file
BIN
lib/win32comext/mapi/mapi.pyd
Normal file
Binary file not shown.
1025
lib/win32comext/mapi/mapitags.py
Normal file
1025
lib/win32comext/mapi/mapitags.py
Normal file
File diff suppressed because it is too large
Load diff
217
lib/win32comext/mapi/mapiutil.py
Normal file
217
lib/win32comext/mapi/mapiutil.py
Normal file
|
@ -0,0 +1,217 @@
|
|||
# General utilities for MAPI and MAPI objects.
|
||||
# We used to use these old names from the 'types' module...
|
||||
TupleType = tuple
|
||||
ListType = list
|
||||
IntType = int
|
||||
import pythoncom
|
||||
from pywintypes import TimeType
|
||||
|
||||
from . import mapi, mapitags
|
||||
|
||||
prTable = {}
|
||||
|
||||
|
||||
def GetPropTagName(pt):
|
||||
if not prTable:
|
||||
for name, value in mapitags.__dict__.items():
|
||||
if name[:3] == "PR_":
|
||||
# Store both the full ID (including type) and just the ID.
|
||||
# This is so PR_FOO_A and PR_FOO_W are still differentiated,
|
||||
# but should we get a PT_FOO with PT_ERROR set, we fallback
|
||||
# to the ID.
|
||||
|
||||
# String types should have 3 definitions in mapitags.py
|
||||
# PR_BODY = PROP_TAG( PT_TSTRING, 4096)
|
||||
# PR_BODY_W = PROP_TAG( PT_UNICODE, 4096)
|
||||
# PR_BODY_A = PROP_TAG( PT_STRING8, 4096)
|
||||
# The following change ensures a lookup using only the the
|
||||
# property id returns the conditional default.
|
||||
|
||||
# PT_TSTRING is a conditional assignment for either PT_UNICODE or
|
||||
# PT_STRING8 and should not be returned during a lookup.
|
||||
|
||||
if (
|
||||
mapitags.PROP_TYPE(value) == mapitags.PT_UNICODE
|
||||
or mapitags.PROP_TYPE(value) == mapitags.PT_STRING8
|
||||
):
|
||||
if name[-2:] == "_A" or name[-2:] == "_W":
|
||||
prTable[value] = name
|
||||
else:
|
||||
prTable[mapitags.PROP_ID(value)] = name
|
||||
|
||||
else:
|
||||
prTable[value] = name
|
||||
prTable[mapitags.PROP_ID(value)] = name
|
||||
|
||||
try:
|
||||
try:
|
||||
return prTable[pt]
|
||||
except KeyError:
|
||||
# Can't find it exactly - see if the raw ID exists.
|
||||
return prTable[mapitags.PROP_ID(pt)]
|
||||
except KeyError:
|
||||
# god-damn bullshit hex() warnings: I don't see a way to get the
|
||||
# old behaviour without a warning!!
|
||||
ret = hex(int(pt))
|
||||
# -0x8000000L -> 0x80000000
|
||||
if ret[0] == "-":
|
||||
ret = ret[1:]
|
||||
if ret[-1] == "L":
|
||||
ret = ret[:-1]
|
||||
return ret
|
||||
|
||||
|
||||
mapiErrorTable = {}
|
||||
|
||||
|
||||
def GetScodeString(hr):
|
||||
if not mapiErrorTable:
|
||||
for name, value in mapi.__dict__.items():
|
||||
if name[:7] in ["MAPI_E_", "MAPI_W_"]:
|
||||
mapiErrorTable[value] = name
|
||||
return mapiErrorTable.get(hr, pythoncom.GetScodeString(hr))
|
||||
|
||||
|
||||
ptTable = {}
|
||||
|
||||
|
||||
def GetMapiTypeName(propType, rawType=True):
|
||||
"""Given a mapi type flag, return a string description of the type"""
|
||||
if not ptTable:
|
||||
for name, value in mapitags.__dict__.items():
|
||||
if name[:3] == "PT_":
|
||||
# PT_TSTRING is a conditional assignment
|
||||
# for either PT_UNICODE or PT_STRING8 and
|
||||
# should not be returned during a lookup.
|
||||
if name in ["PT_TSTRING", "PT_MV_TSTRING"]:
|
||||
continue
|
||||
ptTable[value] = name
|
||||
|
||||
if rawType:
|
||||
propType = propType & ~mapitags.MV_FLAG
|
||||
return ptTable.get(propType, str(hex(propType)))
|
||||
|
||||
|
||||
def GetProperties(obj, propList):
|
||||
"""Given a MAPI object and a list of properties, return a list of property values.
|
||||
|
||||
Allows a single property to be passed, and the result is a single object.
|
||||
|
||||
Each request property can be an integer or a string. Of a string, it is
|
||||
automatically converted to an integer via the GetIdsFromNames function.
|
||||
|
||||
If the property fetch fails, the result is None.
|
||||
"""
|
||||
bRetList = 1
|
||||
if type(propList) not in [TupleType, ListType]:
|
||||
bRetList = 0
|
||||
propList = (propList,)
|
||||
realPropList = []
|
||||
rc = []
|
||||
for prop in propList:
|
||||
if type(prop) != IntType: # Integer
|
||||
props = ((mapi.PS_PUBLIC_STRINGS, prop),)
|
||||
propIds = obj.GetIDsFromNames(props, 0)
|
||||
prop = mapitags.PROP_TAG(
|
||||
mapitags.PT_UNSPECIFIED, mapitags.PROP_ID(propIds[0])
|
||||
)
|
||||
realPropList.append(prop)
|
||||
|
||||
hr, data = obj.GetProps(realPropList, 0)
|
||||
if hr != 0:
|
||||
data = None
|
||||
return None
|
||||
if bRetList:
|
||||
return [v[1] for v in data]
|
||||
else:
|
||||
return data[0][1]
|
||||
|
||||
|
||||
def GetAllProperties(obj, make_tag_names=True):
|
||||
tags = obj.GetPropList(0)
|
||||
hr, data = obj.GetProps(tags)
|
||||
ret = []
|
||||
for tag, val in data:
|
||||
if make_tag_names:
|
||||
hr, tags, array = obj.GetNamesFromIDs((tag,))
|
||||
if type(array[0][1]) == type(""):
|
||||
name = array[0][1]
|
||||
else:
|
||||
name = GetPropTagName(tag)
|
||||
else:
|
||||
name = tag
|
||||
ret.append((name, val))
|
||||
return ret
|
||||
|
||||
|
||||
_MapiTypeMap = {
|
||||
type(0.0): mapitags.PT_DOUBLE,
|
||||
type(0): mapitags.PT_I4,
|
||||
type("".encode("ascii")): mapitags.PT_STRING8, # bytes
|
||||
type(""): mapitags.PT_UNICODE, # str
|
||||
type(None): mapitags.PT_UNSPECIFIED,
|
||||
# In Python 2.2.2, bool isn't a distinct type (type(1==1) is type(0)).
|
||||
# (markh thinks the above is trying to say that in 2020, we probably *do*
|
||||
# want bool in this map? :)
|
||||
}
|
||||
|
||||
|
||||
def SetPropertyValue(obj, prop, val):
|
||||
if type(prop) != IntType:
|
||||
props = ((mapi.PS_PUBLIC_STRINGS, prop),)
|
||||
propIds = obj.GetIDsFromNames(props, mapi.MAPI_CREATE)
|
||||
if val == (1 == 1) or val == (1 == 0):
|
||||
type_tag = mapitags.PT_BOOLEAN
|
||||
else:
|
||||
type_tag = _MapiTypeMap.get(type(val))
|
||||
if type_tag is None:
|
||||
raise ValueError(
|
||||
"Don't know what to do with '%r' ('%s')" % (val, type(val))
|
||||
)
|
||||
prop = mapitags.PROP_TAG(type_tag, mapitags.PROP_ID(propIds[0]))
|
||||
if val is None:
|
||||
# Delete the property
|
||||
obj.DeleteProps((prop,))
|
||||
else:
|
||||
obj.SetProps(((prop, val),))
|
||||
|
||||
|
||||
def SetProperties(msg, propDict):
|
||||
"""Given a Python dictionary, set the objects properties.
|
||||
|
||||
If the dictionary key is a string, then a property ID is queried
|
||||
otherwise the ID is assumed native.
|
||||
|
||||
Coded for maximum efficiency wrt server calls - ie, maximum of
|
||||
2 calls made to the object, regardless of the dictionary contents
|
||||
(only 1 if dictionary full of int keys)
|
||||
"""
|
||||
|
||||
newProps = []
|
||||
# First pass over the properties we should get IDs for.
|
||||
for key, val in propDict.items():
|
||||
if type(key) == str:
|
||||
newProps.append((mapi.PS_PUBLIC_STRINGS, key))
|
||||
# Query for the new IDs
|
||||
if newProps:
|
||||
newIds = msg.GetIDsFromNames(newProps, mapi.MAPI_CREATE)
|
||||
newIdNo = 0
|
||||
newProps = []
|
||||
for key, val in propDict.items():
|
||||
if type(key) == str:
|
||||
type_val = type(val)
|
||||
if type_val == str:
|
||||
tagType = mapitags.PT_UNICODE
|
||||
elif type_val == IntType:
|
||||
tagType = mapitags.PT_I4
|
||||
elif type_val == TimeType:
|
||||
tagType = mapitags.PT_SYSTIME
|
||||
else:
|
||||
raise ValueError(
|
||||
"The type of object %s(%s) can not be written"
|
||||
% (repr(val), type_val)
|
||||
)
|
||||
key = mapitags.PROP_TAG(tagType, mapitags.PROP_ID(newIds[newIdNo]))
|
||||
newIdNo = newIdNo + 1
|
||||
newProps.append((key, val))
|
||||
msg.SetProps(newProps)
|
1
lib/win32comext/propsys/__init__.py
Normal file
1
lib/win32comext/propsys/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
# this is a python package
|
BIN
lib/win32comext/propsys/propsys.pyd
Normal file
BIN
lib/win32comext/propsys/propsys.pyd
Normal file
Binary file not shown.
838
lib/win32comext/propsys/pscon.py
Normal file
838
lib/win32comext/propsys/pscon.py
Normal file
|
@ -0,0 +1,838 @@
|
|||
# hand generated from propsys.h
|
||||
|
||||
## PROPENUMTYPE, used with IPropertyEnumType
|
||||
PET_DISCRETEVALUE = 0
|
||||
PET_RANGEDVALUE = 1
|
||||
PET_DEFAULTVALUE = 2
|
||||
PET_ENDRANGE = 3
|
||||
|
||||
PDTF_DEFAULT = 0
|
||||
PDTF_MULTIPLEVALUES = 0x1
|
||||
PDTF_ISINNATE = 0x2
|
||||
PDTF_ISGROUP = 0x4
|
||||
PDTF_CANGROUPBY = 0x8
|
||||
PDTF_CANSTACKBY = 0x10
|
||||
PDTF_ISTREEPROPERTY = 0x20
|
||||
PDTF_INCLUDEINFULLTEXTQUERY = 0x40
|
||||
PDTF_ISVIEWABLE = 0x80
|
||||
PDTF_ISQUERYABLE = 0x100
|
||||
PDTF_ISSYSTEMPROPERTY = 0x80000000
|
||||
PDTF_MASK_ALL = 0x800001FF
|
||||
|
||||
PDVF_DEFAULT = 0
|
||||
PDVF_CENTERALIGN = 0x1
|
||||
PDVF_RIGHTALIGN = 0x2
|
||||
PDVF_BEGINNEWGROUP = 0x4
|
||||
PDVF_FILLAREA = 0x8
|
||||
PDVF_SORTDESCENDING = 0x10
|
||||
PDVF_SHOWONLYIFPRESENT = 0x20
|
||||
PDVF_SHOWBYDEFAULT = 0x40
|
||||
PDVF_SHOWINPRIMARYLIST = 0x80
|
||||
PDVF_SHOWINSECONDARYLIST = 0x100
|
||||
PDVF_HIDELABEL = 0x200
|
||||
PDVF_HIDDEN = 0x800
|
||||
PDVF_CANWRAP = 0x1000
|
||||
PDVF_MASK_ALL = 0x1BFF
|
||||
|
||||
PDDT_STRING = 0
|
||||
PDDT_NUMBER = 1
|
||||
PDDT_BOOLEAN = 2
|
||||
PDDT_DATETIME = 3
|
||||
PDDT_ENUMERATED = 4
|
||||
|
||||
PDGR_DISCRETE = 0
|
||||
PDGR_ALPHANUMERIC = 1
|
||||
PDGR_SIZE = 2
|
||||
PDGR_DYNAMIC = 3
|
||||
PDGR_DATE = 4
|
||||
PDGR_PERCENT = 5
|
||||
PDGR_ENUMERATED = 6
|
||||
|
||||
## PROPDESC_FORMAT_FLAGS
|
||||
PDFF_DEFAULT = 0
|
||||
PDFF_PREFIXNAME = 0x1
|
||||
PDFF_FILENAME = 0x2
|
||||
PDFF_ALWAYSKB = 0x4
|
||||
PDFF_RESERVED_RIGHTTOLEFT = 0x8
|
||||
PDFF_SHORTTIME = 0x10
|
||||
PDFF_LONGTIME = 0x20
|
||||
PDFF_HIDETIME = 0x40
|
||||
PDFF_SHORTDATE = 0x80
|
||||
PDFF_LONGDATE = 0x100
|
||||
PDFF_HIDEDATE = 0x200
|
||||
PDFF_RELATIVEDATE = 0x400
|
||||
PDFF_USEEDITINVITATION = 0x800
|
||||
PDFF_READONLY = 0x1000
|
||||
PDFF_NOAUTOREADINGORDER = 0x2000
|
||||
|
||||
PDSD_GENERAL = 0
|
||||
PDSD_A_Z = 1
|
||||
PDSD_LOWEST_HIGHEST = 2
|
||||
PDSD_SMALLEST_BIGGEST = 3
|
||||
PDSD_OLDEST_NEWEST = 4
|
||||
|
||||
PDRDT_GENERAL = 0
|
||||
PDRDT_DATE = 1
|
||||
PDRDT_SIZE = 2
|
||||
PDRDT_COUNT = 3
|
||||
PDRDT_REVISION = 4
|
||||
PDRDT_LENGTH = 5
|
||||
PDRDT_DURATION = 6
|
||||
PDRDT_SPEED = 7
|
||||
PDRDT_RATE = 8
|
||||
PDRDT_RATING = 9
|
||||
PDRDT_PRIORITY = 10
|
||||
|
||||
PDAT_DEFAULT = 0
|
||||
PDAT_FIRST = 1
|
||||
PDAT_SUM = 2
|
||||
PDAT_AVERAGE = 3
|
||||
PDAT_DATERANGE = 4
|
||||
PDAT_UNION = 5
|
||||
PDAT_MAX = 6
|
||||
PDAT_MIN = 7
|
||||
|
||||
PDCOT_NONE = 0
|
||||
PDCOT_STRING = 1
|
||||
PDCOT_SIZE = 2
|
||||
PDCOT_DATETIME = 3
|
||||
PDCOT_BOOLEAN = 4
|
||||
PDCOT_NUMBER = 5
|
||||
|
||||
PDSIF_DEFAULT = 0
|
||||
PDSIF_ININVERTEDINDEX = 0x1
|
||||
PDSIF_ISCOLUMN = 0x2
|
||||
PDSIF_ISCOLUMNSPARSE = 0x4
|
||||
PDCIT_NONE = 0
|
||||
PDCIT_ONDISK = 1
|
||||
PDCIT_INMEMORY = 2
|
||||
|
||||
## PROPDESC_ENUMFILTER, used with IPropertySystem::EnumeratePropertyDescriptions
|
||||
PDEF_ALL = 0
|
||||
PDEF_SYSTEM = 1
|
||||
PDEF_NONSYSTEM = 2
|
||||
PDEF_VIEWABLE = 3
|
||||
PDEF_QUERYABLE = 4
|
||||
PDEF_INFULLTEXTQUERY = 5
|
||||
PDEF_COLUMN = 6
|
||||
|
||||
## PSC_STATE, used with IPropertyStoreCache
|
||||
PSC_NORMAL = 0
|
||||
PSC_NOTINSOURCE = 1
|
||||
PSC_DIRTY = 2
|
||||
|
||||
## CONDITION_OPERATION
|
||||
COP_IMPLICIT = 0
|
||||
COP_EQUAL = 1
|
||||
COP_NOTEQUAL = 2
|
||||
COP_LESSTHAN = 3
|
||||
COP_GREATERTHAN = 4
|
||||
COP_LESSTHANOREQUAL = 5
|
||||
COP_GREATERTHANOREQUAL = 6
|
||||
COP_VALUE_STARTSWITH = 7
|
||||
COP_VALUE_ENDSWITH = 8
|
||||
COP_VALUE_CONTAINS = 9
|
||||
COP_VALUE_NOTCONTAINS = 10
|
||||
COP_DOSWILDCARDS = 11
|
||||
COP_WORD_EQUAL = 12
|
||||
COP_WORD_STARTSWITH = 13
|
||||
COP_APPLICATION_SPECIFIC = 14
|
||||
|
||||
## PERSIST_SPROPSTORE_FLAGS, used with IPersistSerializedPropStorage
|
||||
FPSPS_READONLY = 1
|
||||
|
||||
PKEY_PIDSTR_MAX = 10 # will take care of any long integer value
|
||||
# define GUIDSTRING_MAX (1 + 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1) // "{12345678-1234-1234-1234-123456789012}"
|
||||
GUIDSTRING_MAX = 1 + 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1 # hrm ???
|
||||
# define PKEYSTR_MAX (GUIDSTRING_MAX + 1 + PKEY_PIDSTR_MAX)
|
||||
PKEYSTR_MAX = GUIDSTRING_MAX + 1 + PKEY_PIDSTR_MAX
|
||||
|
||||
## Property keys from propkey.h
|
||||
from pywintypes import IID
|
||||
|
||||
PKEY_Audio_ChannelCount = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 7)
|
||||
PKEY_Audio_Compression = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 10)
|
||||
PKEY_Audio_EncodingBitrate = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 4)
|
||||
PKEY_Audio_Format = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 2)
|
||||
PKEY_Audio_IsVariableBitRate = (IID("{E6822FEE-8C17-4D62-823C-8E9CFCBD1D5C}"), 100)
|
||||
PKEY_Audio_PeakValue = (IID("{2579E5D0-1116-4084-BD9A-9B4F7CB4DF5E}"), 100)
|
||||
PKEY_Audio_SampleRate = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 5)
|
||||
PKEY_Audio_SampleSize = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 6)
|
||||
PKEY_Audio_StreamName = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 9)
|
||||
PKEY_Audio_StreamNumber = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 8)
|
||||
PKEY_Calendar_Duration = (IID("{293CA35A-09AA-4DD2-B180-1FE245728A52}"), 100)
|
||||
PKEY_Calendar_IsOnline = (IID("{BFEE9149-E3E2-49A7-A862-C05988145CEC}"), 100)
|
||||
PKEY_Calendar_IsRecurring = (IID("{315B9C8D-80A9-4EF9-AE16-8E746DA51D70}"), 100)
|
||||
PKEY_Calendar_Location = (IID("{F6272D18-CECC-40B1-B26A-3911717AA7BD}"), 100)
|
||||
PKEY_Calendar_OptionalAttendeeAddresses = (
|
||||
IID("{D55BAE5A-3892-417A-A649-C6AC5AAAEAB3}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Calendar_OptionalAttendeeNames = (
|
||||
IID("{09429607-582D-437F-84C3-DE93A2B24C3C}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Calendar_OrganizerAddress = (IID("{744C8242-4DF5-456C-AB9E-014EFB9021E3}"), 100)
|
||||
PKEY_Calendar_OrganizerName = (IID("{AAA660F9-9865-458E-B484-01BC7FE3973E}"), 100)
|
||||
PKEY_Calendar_ReminderTime = (IID("{72FC5BA4-24F9-4011-9F3F-ADD27AFAD818}"), 100)
|
||||
PKEY_Calendar_RequiredAttendeeAddresses = (
|
||||
IID("{0BA7D6C3-568D-4159-AB91-781A91FB71E5}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Calendar_RequiredAttendeeNames = (
|
||||
IID("{B33AF30B-F552-4584-936C-CB93E5CDA29F}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Calendar_Resources = (IID("{00F58A38-C54B-4C40-8696-97235980EAE1}"), 100)
|
||||
PKEY_Calendar_ShowTimeAs = (IID("{5BF396D4-5EB2-466F-BDE9-2FB3F2361D6E}"), 100)
|
||||
PKEY_Calendar_ShowTimeAsText = (IID("{53DA57CF-62C0-45C4-81DE-7610BCEFD7F5}"), 100)
|
||||
PKEY_Communication_AccountName = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 9)
|
||||
PKEY_Communication_Suffix = (IID("{807B653A-9E91-43EF-8F97-11CE04EE20C5}"), 100)
|
||||
PKEY_Communication_TaskStatus = (IID("{BE1A72C6-9A1D-46B7-AFE7-AFAF8CEF4999}"), 100)
|
||||
PKEY_Communication_TaskStatusText = (IID("{A6744477-C237-475B-A075-54F34498292A}"), 100)
|
||||
PKEY_Computer_DecoratedFreeSpace = (IID("{9B174B35-40FF-11D2-A27E-00C04FC30871}"), 7)
|
||||
PKEY_Contact_Anniversary = (IID("{9AD5BADB-CEA7-4470-A03D-B84E51B9949E}"), 100)
|
||||
PKEY_Contact_AssistantName = (IID("{CD102C9C-5540-4A88-A6F6-64E4981C8CD1}"), 100)
|
||||
PKEY_Contact_AssistantTelephone = (IID("{9A93244D-A7AD-4FF8-9B99-45EE4CC09AF6}"), 100)
|
||||
PKEY_Contact_Birthday = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 47)
|
||||
PKEY_Contact_BusinessAddress = (IID("{730FB6DD-CF7C-426B-A03F-BD166CC9EE24}"), 100)
|
||||
PKEY_Contact_BusinessAddressCity = (IID("{402B5934-EC5A-48C3-93E6-85E86A2D934E}"), 100)
|
||||
PKEY_Contact_BusinessAddressCountry = (
|
||||
IID("{B0B87314-FCF6-4FEB-8DFF-A50DA6AF561C}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_BusinessAddressPostalCode = (
|
||||
IID("{E1D4A09E-D758-4CD1-B6EC-34A8B5A73F80}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_BusinessAddressPostOfficeBox = (
|
||||
IID("{BC4E71CE-17F9-48D5-BEE9-021DF0EA5409}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_BusinessAddressState = (IID("{446F787F-10C4-41CB-A6C4-4D0343551597}"), 100)
|
||||
PKEY_Contact_BusinessAddressStreet = (
|
||||
IID("{DDD1460F-C0BF-4553-8CE4-10433C908FB0}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_BusinessFaxNumber = (IID("{91EFF6F3-2E27-42CA-933E-7C999FBE310B}"), 100)
|
||||
PKEY_Contact_BusinessHomePage = (IID("{56310920-2491-4919-99CE-EADB06FAFDB2}"), 100)
|
||||
PKEY_Contact_BusinessTelephone = (IID("{6A15E5A0-0A1E-4CD7-BB8C-D2F1B0C929BC}"), 100)
|
||||
PKEY_Contact_CallbackTelephone = (IID("{BF53D1C3-49E0-4F7F-8567-5A821D8AC542}"), 100)
|
||||
PKEY_Contact_CarTelephone = (IID("{8FDC6DEA-B929-412B-BA90-397A257465FE}"), 100)
|
||||
PKEY_Contact_Children = (IID("{D4729704-8EF1-43EF-9024-2BD381187FD5}"), 100)
|
||||
PKEY_Contact_CompanyMainTelephone = (IID("{8589E481-6040-473D-B171-7FA89C2708ED}"), 100)
|
||||
PKEY_Contact_Department = (IID("{FC9F7306-FF8F-4D49-9FB6-3FFE5C0951EC}"), 100)
|
||||
PKEY_Contact_EmailAddress = (IID("{F8FA7FA3-D12B-4785-8A4E-691A94F7A3E7}"), 100)
|
||||
PKEY_Contact_EmailAddress2 = (IID("{38965063-EDC8-4268-8491-B7723172CF29}"), 100)
|
||||
PKEY_Contact_EmailAddress3 = (IID("{644D37B4-E1B3-4BAD-B099-7E7C04966ACA}"), 100)
|
||||
PKEY_Contact_EmailAddresses = (IID("{84D8F337-981D-44B3-9615-C7596DBA17E3}"), 100)
|
||||
PKEY_Contact_EmailName = (IID("{CC6F4F24-6083-4BD4-8754-674D0DE87AB8}"), 100)
|
||||
PKEY_Contact_FileAsName = (IID("{F1A24AA7-9CA7-40F6-89EC-97DEF9FFE8DB}"), 100)
|
||||
PKEY_Contact_FirstName = (IID("{14977844-6B49-4AAD-A714-A4513BF60460}"), 100)
|
||||
PKEY_Contact_FullName = (IID("{635E9051-50A5-4BA2-B9DB-4ED056C77296}"), 100)
|
||||
PKEY_Contact_Gender = (IID("{3C8CEE58-D4F0-4CF9-B756-4E5D24447BCD}"), 100)
|
||||
PKEY_Contact_Hobbies = (IID("{5DC2253F-5E11-4ADF-9CFE-910DD01E3E70}"), 100)
|
||||
PKEY_Contact_HomeAddress = (IID("{98F98354-617A-46B8-8560-5B1B64BF1F89}"), 100)
|
||||
PKEY_Contact_HomeAddressCity = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 65)
|
||||
PKEY_Contact_HomeAddressCountry = (IID("{08A65AA1-F4C9-43DD-9DDF-A33D8E7EAD85}"), 100)
|
||||
PKEY_Contact_HomeAddressPostalCode = (
|
||||
IID("{8AFCC170-8A46-4B53-9EEE-90BAE7151E62}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_HomeAddressPostOfficeBox = (
|
||||
IID("{7B9F6399-0A3F-4B12-89BD-4ADC51C918AF}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_HomeAddressState = (IID("{C89A23D0-7D6D-4EB8-87D4-776A82D493E5}"), 100)
|
||||
PKEY_Contact_HomeAddressStreet = (IID("{0ADEF160-DB3F-4308-9A21-06237B16FA2A}"), 100)
|
||||
PKEY_Contact_HomeFaxNumber = (IID("{660E04D6-81AB-4977-A09F-82313113AB26}"), 100)
|
||||
PKEY_Contact_HomeTelephone = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 20)
|
||||
PKEY_Contact_IMAddress = (IID("{D68DBD8A-3374-4B81-9972-3EC30682DB3D}"), 100)
|
||||
PKEY_Contact_Initials = (IID("{F3D8F40D-50CB-44A2-9718-40CB9119495D}"), 100)
|
||||
PKEY_Contact_JA_CompanyNamePhonetic = (IID("{897B3694-FE9E-43E6-8066-260F590C0100}"), 2)
|
||||
PKEY_Contact_JA_FirstNamePhonetic = (IID("{897B3694-FE9E-43E6-8066-260F590C0100}"), 3)
|
||||
PKEY_Contact_JA_LastNamePhonetic = (IID("{897B3694-FE9E-43E6-8066-260F590C0100}"), 4)
|
||||
PKEY_Contact_JobTitle = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 6)
|
||||
PKEY_Contact_Label = (IID("{97B0AD89-DF49-49CC-834E-660974FD755B}"), 100)
|
||||
PKEY_Contact_LastName = (IID("{8F367200-C270-457C-B1D4-E07C5BCD90C7}"), 100)
|
||||
PKEY_Contact_MailingAddress = (IID("{C0AC206A-827E-4650-95AE-77E2BB74FCC9}"), 100)
|
||||
PKEY_Contact_MiddleName = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 71)
|
||||
PKEY_Contact_MobileTelephone = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 35)
|
||||
PKEY_Contact_NickName = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 74)
|
||||
PKEY_Contact_OfficeLocation = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 7)
|
||||
PKEY_Contact_OtherAddress = (IID("{508161FA-313B-43D5-83A1-C1ACCF68622C}"), 100)
|
||||
PKEY_Contact_OtherAddressCity = (IID("{6E682923-7F7B-4F0C-A337-CFCA296687BF}"), 100)
|
||||
PKEY_Contact_OtherAddressCountry = (IID("{8F167568-0AAE-4322-8ED9-6055B7B0E398}"), 100)
|
||||
PKEY_Contact_OtherAddressPostalCode = (
|
||||
IID("{95C656C1-2ABF-4148-9ED3-9EC602E3B7CD}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_OtherAddressPostOfficeBox = (
|
||||
IID("{8B26EA41-058F-43F6-AECC-4035681CE977}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_OtherAddressState = (IID("{71B377D6-E570-425F-A170-809FAE73E54E}"), 100)
|
||||
PKEY_Contact_OtherAddressStreet = (IID("{FF962609-B7D6-4999-862D-95180D529AEA}"), 100)
|
||||
PKEY_Contact_PagerTelephone = (IID("{D6304E01-F8F5-4F45-8B15-D024A6296789}"), 100)
|
||||
PKEY_Contact_PersonalTitle = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 69)
|
||||
PKEY_Contact_PrimaryAddressCity = (IID("{C8EA94F0-A9E3-4969-A94B-9C62A95324E0}"), 100)
|
||||
PKEY_Contact_PrimaryAddressCountry = (
|
||||
IID("{E53D799D-0F3F-466E-B2FF-74634A3CB7A4}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_PrimaryAddressPostalCode = (
|
||||
IID("{18BBD425-ECFD-46EF-B612-7B4A6034EDA0}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_PrimaryAddressPostOfficeBox = (
|
||||
IID("{DE5EF3C7-46E1-484E-9999-62C5308394C1}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Contact_PrimaryAddressState = (IID("{F1176DFE-7138-4640-8B4C-AE375DC70A6D}"), 100)
|
||||
PKEY_Contact_PrimaryAddressStreet = (IID("{63C25B20-96BE-488F-8788-C09C407AD812}"), 100)
|
||||
PKEY_Contact_PrimaryEmailAddress = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 48)
|
||||
PKEY_Contact_PrimaryTelephone = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 25)
|
||||
PKEY_Contact_Profession = (IID("{7268AF55-1CE4-4F6E-A41F-B6E4EF10E4A9}"), 100)
|
||||
PKEY_Contact_SpouseName = (IID("{9D2408B6-3167-422B-82B0-F583B7A7CFE3}"), 100)
|
||||
PKEY_Contact_Suffix = (IID("{176DC63C-2688-4E89-8143-A347800F25E9}"), 73)
|
||||
PKEY_Contact_TelexNumber = (IID("{C554493C-C1F7-40C1-A76C-EF8C0614003E}"), 100)
|
||||
PKEY_Contact_TTYTDDTelephone = (IID("{AAF16BAC-2B55-45E6-9F6D-415EB94910DF}"), 100)
|
||||
PKEY_Contact_WebPage = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 18)
|
||||
PKEY_AcquisitionID = (IID("{65A98875-3C80-40AB-ABBC-EFDAF77DBEE2}"), 100)
|
||||
PKEY_ApplicationName = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 18)
|
||||
PKEY_Author = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 4)
|
||||
PKEY_Capacity = (IID("{9B174B35-40FF-11D2-A27E-00C04FC30871}"), 3)
|
||||
PKEY_Category = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 2)
|
||||
PKEY_Comment = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 6)
|
||||
PKEY_Company = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 15)
|
||||
PKEY_ComputerName = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 5)
|
||||
PKEY_ContainedItems = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 29)
|
||||
PKEY_ContentStatus = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 27)
|
||||
PKEY_ContentType = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 26)
|
||||
PKEY_Copyright = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 11)
|
||||
PKEY_DateAccessed = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 16)
|
||||
PKEY_DateAcquired = (IID("{2CBAA8F5-D81F-47CA-B17A-F8D822300131}"), 100)
|
||||
PKEY_DateArchived = (IID("{43F8D7B7-A444-4F87-9383-52271C9B915C}"), 100)
|
||||
PKEY_DateCompleted = (IID("{72FAB781-ACDA-43E5-B155-B2434F85E678}"), 100)
|
||||
PKEY_DateCreated = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 15)
|
||||
PKEY_DateImported = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 18258)
|
||||
PKEY_DateModified = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 14)
|
||||
PKEY_DueDate = (IID("{3F8472B5-E0AF-4DB2-8071-C53FE76AE7CE}"), 100)
|
||||
PKEY_EndDate = (IID("{C75FAA05-96FD-49E7-9CB4-9F601082D553}"), 100)
|
||||
PKEY_FileAllocationSize = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 18)
|
||||
PKEY_FileAttributes = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 13)
|
||||
PKEY_FileCount = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 12)
|
||||
PKEY_FileDescription = (IID("{0CEF7D53-FA64-11D1-A203-0000F81FEDEE}"), 3)
|
||||
PKEY_FileExtension = (IID("{E4F10A3C-49E6-405D-8288-A23BD4EEAA6C}"), 100)
|
||||
PKEY_FileFRN = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 21)
|
||||
PKEY_FileName = (IID("{41CF5AE0-F75A-4806-BD87-59C7D9248EB9}"), 100)
|
||||
PKEY_FileOwner = (IID("{9B174B34-40FF-11D2-A27E-00C04FC30871}"), 4)
|
||||
PKEY_FileVersion = (IID("{0CEF7D53-FA64-11D1-A203-0000F81FEDEE}"), 4)
|
||||
PKEY_FindData = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 0)
|
||||
PKEY_FlagColor = (IID("{67DF94DE-0CA7-4D6F-B792-053A3E4F03CF}"), 100)
|
||||
PKEY_FlagColorText = (IID("{45EAE747-8E2A-40AE-8CBF-CA52ABA6152A}"), 100)
|
||||
PKEY_FlagStatus = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 12)
|
||||
PKEY_FlagStatusText = (IID("{DC54FD2E-189D-4871-AA01-08C2F57A4ABC}"), 100)
|
||||
PKEY_FreeSpace = (IID("{9B174B35-40FF-11D2-A27E-00C04FC30871}"), 2)
|
||||
PKEY_Identity = (IID("{A26F4AFC-7346-4299-BE47-EB1AE613139F}"), 100)
|
||||
PKEY_Importance = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 11)
|
||||
PKEY_ImportanceText = (IID("{A3B29791-7713-4E1D-BB40-17DB85F01831}"), 100)
|
||||
PKEY_IsAttachment = (IID("{F23F425C-71A1-4FA8-922F-678EA4A60408}"), 100)
|
||||
PKEY_IsDeleted = (IID("{5CDA5FC8-33EE-4FF3-9094-AE7BD8868C4D}"), 100)
|
||||
PKEY_IsFlagged = (IID("{5DA84765-E3FF-4278-86B0-A27967FBDD03}"), 100)
|
||||
PKEY_IsFlaggedComplete = (IID("{A6F360D2-55F9-48DE-B909-620E090A647C}"), 100)
|
||||
PKEY_IsIncomplete = (IID("{346C8BD1-2E6A-4C45-89A4-61B78E8E700F}"), 100)
|
||||
PKEY_IsRead = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 10)
|
||||
PKEY_IsSendToTarget = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 33)
|
||||
PKEY_IsShared = (IID("{EF884C5B-2BFE-41BB-AAE5-76EEDF4F9902}"), 100)
|
||||
PKEY_ItemAuthors = (IID("{D0A04F0A-462A-48A4-BB2F-3706E88DBD7D}"), 100)
|
||||
PKEY_ItemDate = (IID("{F7DB74B4-4287-4103-AFBA-F1B13DCD75CF}"), 100)
|
||||
PKEY_ItemFolderNameDisplay = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 2)
|
||||
PKEY_ItemFolderPathDisplay = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 6)
|
||||
PKEY_ItemFolderPathDisplayNarrow = (IID("{DABD30ED-0043-4789-A7F8-D013A4736622}"), 100)
|
||||
PKEY_ItemName = (IID("{6B8DA074-3B5C-43BC-886F-0A2CDCE00B6F}"), 100)
|
||||
PKEY_ItemNameDisplay = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 10)
|
||||
PKEY_ItemNamePrefix = (IID("{D7313FF1-A77A-401C-8C99-3DBDD68ADD36}"), 100)
|
||||
PKEY_ItemParticipants = (IID("{D4D0AA16-9948-41A4-AA85-D97FF9646993}"), 100)
|
||||
PKEY_ItemPathDisplay = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 7)
|
||||
PKEY_ItemPathDisplayNarrow = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 8)
|
||||
PKEY_ItemType = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 11)
|
||||
PKEY_ItemTypeText = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 4)
|
||||
PKEY_ItemUrl = (IID("{49691C90-7E17-101A-A91C-08002B2ECDA9}"), 9)
|
||||
PKEY_Keywords = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 5)
|
||||
PKEY_Kind = (IID("{1E3EE840-BC2B-476C-8237-2ACD1A839B22}"), 3)
|
||||
PKEY_KindText = (IID("{F04BEF95-C585-4197-A2B7-DF46FDC9EE6D}"), 100)
|
||||
PKEY_Language = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 28)
|
||||
PKEY_MileageInformation = (IID("{FDF84370-031A-4ADD-9E91-0D775F1C6605}"), 100)
|
||||
PKEY_MIMEType = (IID("{0B63E350-9CCC-11D0-BCDB-00805FCCCE04}"), 5)
|
||||
PKEY_Null = (IID("{00000000-0000-0000-0000-000000000000}"), 0)
|
||||
PKEY_OfflineAvailability = (IID("{A94688B6-7D9F-4570-A648-E3DFC0AB2B3F}"), 100)
|
||||
PKEY_OfflineStatus = (IID("{6D24888F-4718-4BDA-AFED-EA0FB4386CD8}"), 100)
|
||||
PKEY_OriginalFileName = (IID("{0CEF7D53-FA64-11D1-A203-0000F81FEDEE}"), 6)
|
||||
PKEY_ParentalRating = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 21)
|
||||
PKEY_ParentalRatingReason = (IID("{10984E0A-F9F2-4321-B7EF-BAF195AF4319}"), 100)
|
||||
PKEY_ParentalRatingsOrganization = (IID("{A7FE0840-1344-46F0-8D37-52ED712A4BF9}"), 100)
|
||||
PKEY_ParsingBindContext = (IID("{DFB9A04D-362F-4CA3-B30B-0254B17B5B84}"), 100)
|
||||
PKEY_ParsingName = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 24)
|
||||
PKEY_ParsingPath = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 30)
|
||||
PKEY_PerceivedType = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 9)
|
||||
PKEY_PercentFull = (IID("{9B174B35-40FF-11D2-A27E-00C04FC30871}"), 5)
|
||||
PKEY_Priority = (IID("{9C1FCF74-2D97-41BA-B4AE-CB2E3661A6E4}"), 5)
|
||||
PKEY_PriorityText = (IID("{D98BE98B-B86B-4095-BF52-9D23B2E0A752}"), 100)
|
||||
PKEY_Project = (IID("{39A7F922-477C-48DE-8BC8-B28441E342E3}"), 100)
|
||||
PKEY_ProviderItemID = (IID("{F21D9941-81F0-471A-ADEE-4E74B49217ED}"), 100)
|
||||
PKEY_Rating = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 9)
|
||||
PKEY_RatingText = (IID("{90197CA7-FD8F-4E8C-9DA3-B57E1E609295}"), 100)
|
||||
PKEY_Sensitivity = (IID("{F8D3F6AC-4874-42CB-BE59-AB454B30716A}"), 100)
|
||||
PKEY_SensitivityText = (IID("{D0C7F054-3F72-4725-8527-129A577CB269}"), 100)
|
||||
PKEY_SFGAOFlags = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 25)
|
||||
PKEY_SharedWith = (IID("{EF884C5B-2BFE-41BB-AAE5-76EEDF4F9902}"), 200)
|
||||
PKEY_ShareUserRating = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 12)
|
||||
PKEY_Shell_OmitFromView = (IID("{DE35258C-C695-4CBC-B982-38B0AD24CED0}"), 2)
|
||||
PKEY_SimpleRating = (IID("{A09F084E-AD41-489F-8076-AA5BE3082BCA}"), 100)
|
||||
PKEY_Size = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 12)
|
||||
PKEY_SoftwareUsed = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 305)
|
||||
PKEY_SourceItem = (IID("{668CDFA5-7A1B-4323-AE4B-E527393A1D81}"), 100)
|
||||
PKEY_StartDate = (IID("{48FD6EC8-8A12-4CDF-A03E-4EC5A511EDDE}"), 100)
|
||||
PKEY_Status = (IID("{000214A1-0000-0000-C000-000000000046}"), 9)
|
||||
PKEY_Subject = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 3)
|
||||
PKEY_Thumbnail = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 17)
|
||||
PKEY_ThumbnailCacheId = (IID("{446D16B1-8DAD-4870-A748-402EA43D788C}"), 100)
|
||||
PKEY_ThumbnailStream = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 27)
|
||||
PKEY_Title = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 2)
|
||||
PKEY_TotalFileSize = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 14)
|
||||
PKEY_Trademarks = (IID("{0CEF7D53-FA64-11D1-A203-0000F81FEDEE}"), 9)
|
||||
PKEY_Document_ByteCount = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 4)
|
||||
PKEY_Document_CharacterCount = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 16)
|
||||
PKEY_Document_ClientID = (IID("{276D7BB0-5B34-4FB0-AA4B-158ED12A1809}"), 100)
|
||||
PKEY_Document_Contributor = (IID("{F334115E-DA1B-4509-9B3D-119504DC7ABB}"), 100)
|
||||
PKEY_Document_DateCreated = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 12)
|
||||
PKEY_Document_DatePrinted = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 11)
|
||||
PKEY_Document_DateSaved = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 13)
|
||||
PKEY_Document_Division = (IID("{1E005EE6-BF27-428B-B01C-79676ACD2870}"), 100)
|
||||
PKEY_Document_DocumentID = (IID("{E08805C8-E395-40DF-80D2-54F0D6C43154}"), 100)
|
||||
PKEY_Document_HiddenSlideCount = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 9)
|
||||
PKEY_Document_LastAuthor = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 8)
|
||||
PKEY_Document_LineCount = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 5)
|
||||
PKEY_Document_Manager = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 14)
|
||||
PKEY_Document_MultimediaClipCount = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 10)
|
||||
PKEY_Document_NoteCount = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 8)
|
||||
PKEY_Document_PageCount = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 14)
|
||||
PKEY_Document_ParagraphCount = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 6)
|
||||
PKEY_Document_PresentationFormat = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 3)
|
||||
PKEY_Document_RevisionNumber = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 9)
|
||||
PKEY_Document_Security = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 19)
|
||||
PKEY_Document_SlideCount = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 7)
|
||||
PKEY_Document_Template = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 7)
|
||||
PKEY_Document_TotalEditingTime = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 10)
|
||||
PKEY_Document_Version = (IID("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"), 29)
|
||||
PKEY_Document_WordCount = (IID("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"), 15)
|
||||
PKEY_DRM_DatePlayExpires = (IID("{AEAC19E4-89AE-4508-B9B7-BB867ABEE2ED}"), 6)
|
||||
PKEY_DRM_DatePlayStarts = (IID("{AEAC19E4-89AE-4508-B9B7-BB867ABEE2ED}"), 5)
|
||||
PKEY_DRM_Description = (IID("{AEAC19E4-89AE-4508-B9B7-BB867ABEE2ED}"), 3)
|
||||
PKEY_DRM_IsProtected = (IID("{AEAC19E4-89AE-4508-B9B7-BB867ABEE2ED}"), 2)
|
||||
PKEY_DRM_PlayCount = (IID("{AEAC19E4-89AE-4508-B9B7-BB867ABEE2ED}"), 4)
|
||||
PKEY_GPS_Altitude = (IID("{827EDB4F-5B73-44A7-891D-FDFFABEA35CA}"), 100)
|
||||
PKEY_GPS_AltitudeDenominator = (IID("{78342DCB-E358-4145-AE9A-6BFE4E0F9F51}"), 100)
|
||||
PKEY_GPS_AltitudeNumerator = (IID("{2DAD1EB7-816D-40D3-9EC3-C9773BE2AADE}"), 100)
|
||||
PKEY_GPS_AltitudeRef = (IID("{46AC629D-75EA-4515-867F-6DC4321C5844}"), 100)
|
||||
PKEY_GPS_AreaInformation = (IID("{972E333E-AC7E-49F1-8ADF-A70D07A9BCAB}"), 100)
|
||||
PKEY_GPS_Date = (IID("{3602C812-0F3B-45F0-85AD-603468D69423}"), 100)
|
||||
PKEY_GPS_DestBearing = (IID("{C66D4B3C-E888-47CC-B99F-9DCA3EE34DEA}"), 100)
|
||||
PKEY_GPS_DestBearingDenominator = (IID("{7ABCF4F8-7C3F-4988-AC91-8D2C2E97ECA5}"), 100)
|
||||
PKEY_GPS_DestBearingNumerator = (IID("{BA3B1DA9-86EE-4B5D-A2A4-A271A429F0CF}"), 100)
|
||||
PKEY_GPS_DestBearingRef = (IID("{9AB84393-2A0F-4B75-BB22-7279786977CB}"), 100)
|
||||
PKEY_GPS_DestDistance = (IID("{A93EAE04-6804-4F24-AC81-09B266452118}"), 100)
|
||||
PKEY_GPS_DestDistanceDenominator = (IID("{9BC2C99B-AC71-4127-9D1C-2596D0D7DCB7}"), 100)
|
||||
PKEY_GPS_DestDistanceNumerator = (IID("{2BDA47DA-08C6-4FE1-80BC-A72FC517C5D0}"), 100)
|
||||
PKEY_GPS_DestDistanceRef = (IID("{ED4DF2D3-8695-450B-856F-F5C1C53ACB66}"), 100)
|
||||
PKEY_GPS_DestLatitude = (IID("{9D1D7CC5-5C39-451C-86B3-928E2D18CC47}"), 100)
|
||||
PKEY_GPS_DestLatitudeDenominator = (IID("{3A372292-7FCA-49A7-99D5-E47BB2D4E7AB}"), 100)
|
||||
PKEY_GPS_DestLatitudeNumerator = (IID("{ECF4B6F6-D5A6-433C-BB92-4076650FC890}"), 100)
|
||||
PKEY_GPS_DestLatitudeRef = (IID("{CEA820B9-CE61-4885-A128-005D9087C192}"), 100)
|
||||
PKEY_GPS_DestLongitude = (IID("{47A96261-CB4C-4807-8AD3-40B9D9DBC6BC}"), 100)
|
||||
PKEY_GPS_DestLongitudeDenominator = (IID("{425D69E5-48AD-4900-8D80-6EB6B8D0AC86}"), 100)
|
||||
PKEY_GPS_DestLongitudeNumerator = (IID("{A3250282-FB6D-48D5-9A89-DBCACE75CCCF}"), 100)
|
||||
PKEY_GPS_DestLongitudeRef = (IID("{182C1EA6-7C1C-4083-AB4B-AC6C9F4ED128}"), 100)
|
||||
PKEY_GPS_Differential = (IID("{AAF4EE25-BD3B-4DD7-BFC4-47F77BB00F6D}"), 100)
|
||||
PKEY_GPS_DOP = (IID("{0CF8FB02-1837-42F1-A697-A7017AA289B9}"), 100)
|
||||
PKEY_GPS_DOPDenominator = (IID("{A0BE94C5-50BA-487B-BD35-0654BE8881ED}"), 100)
|
||||
PKEY_GPS_DOPNumerator = (IID("{47166B16-364F-4AA0-9F31-E2AB3DF449C3}"), 100)
|
||||
PKEY_GPS_ImgDirection = (IID("{16473C91-D017-4ED9-BA4D-B6BAA55DBCF8}"), 100)
|
||||
PKEY_GPS_ImgDirectionDenominator = (IID("{10B24595-41A2-4E20-93C2-5761C1395F32}"), 100)
|
||||
PKEY_GPS_ImgDirectionNumerator = (IID("{DC5877C7-225F-45F7-BAC7-E81334B6130A}"), 100)
|
||||
PKEY_GPS_ImgDirectionRef = (IID("{A4AAA5B7-1AD0-445F-811A-0F8F6E67F6B5}"), 100)
|
||||
PKEY_GPS_Latitude = (IID("{8727CFFF-4868-4EC6-AD5B-81B98521D1AB}"), 100)
|
||||
PKEY_GPS_LatitudeDenominator = (IID("{16E634EE-2BFF-497B-BD8A-4341AD39EEB9}"), 100)
|
||||
PKEY_GPS_LatitudeNumerator = (IID("{7DDAAAD1-CCC8-41AE-B750-B2CB8031AEA2}"), 100)
|
||||
PKEY_GPS_LatitudeRef = (IID("{029C0252-5B86-46C7-ACA0-2769FFC8E3D4}"), 100)
|
||||
PKEY_GPS_Longitude = (IID("{C4C4DBB2-B593-466B-BBDA-D03D27D5E43A}"), 100)
|
||||
PKEY_GPS_LongitudeDenominator = (IID("{BE6E176C-4534-4D2C-ACE5-31DEDAC1606B}"), 100)
|
||||
PKEY_GPS_LongitudeNumerator = (IID("{02B0F689-A914-4E45-821D-1DDA452ED2C4}"), 100)
|
||||
PKEY_GPS_LongitudeRef = (IID("{33DCF22B-28D5-464C-8035-1EE9EFD25278}"), 100)
|
||||
PKEY_GPS_MapDatum = (IID("{2CA2DAE6-EDDC-407D-BEF1-773942ABFA95}"), 100)
|
||||
PKEY_GPS_MeasureMode = (IID("{A015ED5D-AAEA-4D58-8A86-3C586920EA0B}"), 100)
|
||||
PKEY_GPS_ProcessingMethod = (IID("{59D49E61-840F-4AA9-A939-E2099B7F6399}"), 100)
|
||||
PKEY_GPS_Satellites = (IID("{467EE575-1F25-4557-AD4E-B8B58B0D9C15}"), 100)
|
||||
PKEY_GPS_Speed = (IID("{DA5D0862-6E76-4E1B-BABD-70021BD25494}"), 100)
|
||||
PKEY_GPS_SpeedDenominator = (IID("{7D122D5A-AE5E-4335-8841-D71E7CE72F53}"), 100)
|
||||
PKEY_GPS_SpeedNumerator = (IID("{ACC9CE3D-C213-4942-8B48-6D0820F21C6D}"), 100)
|
||||
PKEY_GPS_SpeedRef = (IID("{ECF7F4C9-544F-4D6D-9D98-8AD79ADAF453}"), 100)
|
||||
PKEY_GPS_Status = (IID("{125491F4-818F-46B2-91B5-D537753617B2}"), 100)
|
||||
PKEY_GPS_Track = (IID("{76C09943-7C33-49E3-9E7E-CDBA872CFADA}"), 100)
|
||||
PKEY_GPS_TrackDenominator = (IID("{C8D1920C-01F6-40C0-AC86-2F3A4AD00770}"), 100)
|
||||
PKEY_GPS_TrackNumerator = (IID("{702926F4-44A6-43E1-AE71-45627116893B}"), 100)
|
||||
PKEY_GPS_TrackRef = (IID("{35DBE6FE-44C3-4400-AAAE-D2C799C407E8}"), 100)
|
||||
PKEY_GPS_VersionID = (IID("{22704DA4-C6B2-4A99-8E56-F16DF8C92599}"), 100)
|
||||
PKEY_Image_BitDepth = (IID("{6444048F-4C8B-11D1-8B70-080036B11A03}"), 7)
|
||||
PKEY_Image_ColorSpace = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 40961)
|
||||
PKEY_Image_CompressedBitsPerPixel = (IID("{364B6FA9-37AB-482A-BE2B-AE02F60D4318}"), 100)
|
||||
PKEY_Image_CompressedBitsPerPixelDenominator = (
|
||||
IID("{1F8844E1-24AD-4508-9DFD-5326A415CE02}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Image_CompressedBitsPerPixelNumerator = (
|
||||
IID("{D21A7148-D32C-4624-8900-277210F79C0F}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Image_Compression = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 259)
|
||||
PKEY_Image_CompressionText = (IID("{3F08E66F-2F44-4BB9-A682-AC35D2562322}"), 100)
|
||||
PKEY_Image_Dimensions = (IID("{6444048F-4C8B-11D1-8B70-080036B11A03}"), 13)
|
||||
PKEY_Image_HorizontalResolution = (IID("{6444048F-4C8B-11D1-8B70-080036B11A03}"), 5)
|
||||
PKEY_Image_HorizontalSize = (IID("{6444048F-4C8B-11D1-8B70-080036B11A03}"), 3)
|
||||
PKEY_Image_ImageID = (IID("{10DABE05-32AA-4C29-BF1A-63E2D220587F}"), 100)
|
||||
PKEY_Image_ResolutionUnit = (IID("{19B51FA6-1F92-4A5C-AB48-7DF0ABD67444}"), 100)
|
||||
PKEY_Image_VerticalResolution = (IID("{6444048F-4C8B-11D1-8B70-080036B11A03}"), 6)
|
||||
PKEY_Image_VerticalSize = (IID("{6444048F-4C8B-11D1-8B70-080036B11A03}"), 4)
|
||||
PKEY_Journal_Contacts = (IID("{DEA7C82C-1D89-4A66-9427-A4E3DEBABCB1}"), 100)
|
||||
PKEY_Journal_EntryType = (IID("{95BEB1FC-326D-4644-B396-CD3ED90E6DDF}"), 100)
|
||||
PKEY_Link_Comment = (IID("{B9B4B3FC-2B51-4A42-B5D8-324146AFCF25}"), 5)
|
||||
PKEY_Link_DateVisited = (IID("{5CBF2787-48CF-4208-B90E-EE5E5D420294}"), 23)
|
||||
PKEY_Link_Description = (IID("{5CBF2787-48CF-4208-B90E-EE5E5D420294}"), 21)
|
||||
PKEY_Link_Status = (IID("{B9B4B3FC-2B51-4A42-B5D8-324146AFCF25}"), 3)
|
||||
PKEY_Link_TargetExtension = (IID("{7A7D76F4-B630-4BD7-95FF-37CC51A975C9}"), 2)
|
||||
PKEY_Link_TargetParsingPath = (IID("{B9B4B3FC-2B51-4A42-B5D8-324146AFCF25}"), 2)
|
||||
PKEY_Link_TargetSFGAOFlags = (IID("{B9B4B3FC-2B51-4A42-B5D8-324146AFCF25}"), 8)
|
||||
PKEY_Media_AuthorUrl = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 32)
|
||||
PKEY_Media_AverageLevel = (IID("{09EDD5B6-B301-43C5-9990-D00302EFFD46}"), 100)
|
||||
PKEY_Media_ClassPrimaryID = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 13)
|
||||
PKEY_Media_ClassSecondaryID = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 14)
|
||||
PKEY_Media_CollectionGroupID = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 24)
|
||||
PKEY_Media_CollectionID = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 25)
|
||||
PKEY_Media_ContentDistributor = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 18)
|
||||
PKEY_Media_ContentID = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 26)
|
||||
PKEY_Media_CreatorApplication = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 27)
|
||||
PKEY_Media_CreatorApplicationVersion = (
|
||||
IID("{64440492-4C8B-11D1-8B70-080036B11A03}"),
|
||||
28,
|
||||
)
|
||||
PKEY_Media_DateEncoded = (IID("{2E4B640D-5019-46D8-8881-55414CC5CAA0}"), 100)
|
||||
PKEY_Media_DateReleased = (IID("{DE41CC29-6971-4290-B472-F59F2E2F31E2}"), 100)
|
||||
PKEY_Media_Duration = (IID("{64440490-4C8B-11D1-8B70-080036B11A03}"), 3)
|
||||
PKEY_Media_DVDID = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 15)
|
||||
PKEY_Media_EncodedBy = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 36)
|
||||
PKEY_Media_EncodingSettings = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 37)
|
||||
PKEY_Media_FrameCount = (IID("{6444048F-4C8B-11D1-8B70-080036B11A03}"), 12)
|
||||
PKEY_Media_MCDI = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 16)
|
||||
PKEY_Media_MetadataContentProvider = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 17)
|
||||
PKEY_Media_Producer = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 22)
|
||||
PKEY_Media_PromotionUrl = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 33)
|
||||
PKEY_Media_ProtectionType = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 38)
|
||||
PKEY_Media_ProviderRating = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 39)
|
||||
PKEY_Media_ProviderStyle = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 40)
|
||||
PKEY_Media_Publisher = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 30)
|
||||
PKEY_Media_SubscriptionContentId = (IID("{9AEBAE7A-9644-487D-A92C-657585ED751A}"), 100)
|
||||
PKEY_Media_SubTitle = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 38)
|
||||
PKEY_Media_UniqueFileIdentifier = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 35)
|
||||
PKEY_Media_UserNoAutoInfo = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 41)
|
||||
PKEY_Media_UserWebUrl = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 34)
|
||||
PKEY_Media_Writer = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 23)
|
||||
PKEY_Media_Year = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 5)
|
||||
PKEY_Message_AttachmentContents = (IID("{3143BF7C-80A8-4854-8880-E2E40189BDD0}"), 100)
|
||||
PKEY_Message_AttachmentNames = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 21)
|
||||
PKEY_Message_BccAddress = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 2)
|
||||
PKEY_Message_BccName = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 3)
|
||||
PKEY_Message_CcAddress = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 4)
|
||||
PKEY_Message_CcName = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 5)
|
||||
PKEY_Message_ConversationID = (IID("{DC8F80BD-AF1E-4289-85B6-3DFC1B493992}"), 100)
|
||||
PKEY_Message_ConversationIndex = (IID("{DC8F80BD-AF1E-4289-85B6-3DFC1B493992}"), 101)
|
||||
PKEY_Message_DateReceived = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 20)
|
||||
PKEY_Message_DateSent = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 19)
|
||||
PKEY_Message_FromAddress = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 13)
|
||||
PKEY_Message_FromName = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 14)
|
||||
PKEY_Message_HasAttachments = (IID("{9C1FCF74-2D97-41BA-B4AE-CB2E3661A6E4}"), 8)
|
||||
PKEY_Message_IsFwdOrReply = (IID("{9A9BC088-4F6D-469E-9919-E705412040F9}"), 100)
|
||||
PKEY_Message_MessageClass = (IID("{CD9ED458-08CE-418F-A70E-F912C7BB9C5C}"), 103)
|
||||
PKEY_Message_SenderAddress = (IID("{0BE1C8E7-1981-4676-AE14-FDD78F05A6E7}"), 100)
|
||||
PKEY_Message_SenderName = (IID("{0DA41CFA-D224-4A18-AE2F-596158DB4B3A}"), 100)
|
||||
PKEY_Message_Store = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 15)
|
||||
PKEY_Message_ToAddress = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 16)
|
||||
PKEY_Message_ToDoTitle = (IID("{BCCC8A3C-8CEF-42E5-9B1C-C69079398BC7}"), 100)
|
||||
PKEY_Message_ToName = (IID("{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD}"), 17)
|
||||
PKEY_Music_AlbumArtist = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 13)
|
||||
PKEY_Music_AlbumTitle = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 4)
|
||||
PKEY_Music_Artist = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 2)
|
||||
PKEY_Music_BeatsPerMinute = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 35)
|
||||
PKEY_Music_Composer = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 19)
|
||||
PKEY_Music_Conductor = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 36)
|
||||
PKEY_Music_ContentGroupDescription = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 33)
|
||||
PKEY_Music_Genre = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 11)
|
||||
PKEY_Music_InitialKey = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 34)
|
||||
PKEY_Music_Lyrics = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 12)
|
||||
PKEY_Music_Mood = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 39)
|
||||
PKEY_Music_PartOfSet = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 37)
|
||||
PKEY_Music_Period = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 31)
|
||||
PKEY_Music_SynchronizedLyrics = (IID("{6B223B6A-162E-4AA9-B39F-05D678FC6D77}"), 100)
|
||||
PKEY_Music_TrackNumber = (IID("{56A3372E-CE9C-11D2-9F0E-006097C686F6}"), 7)
|
||||
PKEY_Note_Color = (IID("{4776CAFA-BCE4-4CB1-A23E-265E76D8EB11}"), 100)
|
||||
PKEY_Note_ColorText = (IID("{46B4E8DE-CDB2-440D-885C-1658EB65B914}"), 100)
|
||||
PKEY_Photo_Aperture = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 37378)
|
||||
PKEY_Photo_ApertureDenominator = (IID("{E1A9A38B-6685-46BD-875E-570DC7AD7320}"), 100)
|
||||
PKEY_Photo_ApertureNumerator = (IID("{0337ECEC-39FB-4581-A0BD-4C4CC51E9914}"), 100)
|
||||
PKEY_Photo_Brightness = (IID("{1A701BF6-478C-4361-83AB-3701BB053C58}"), 100)
|
||||
PKEY_Photo_BrightnessDenominator = (IID("{6EBE6946-2321-440A-90F0-C043EFD32476}"), 100)
|
||||
PKEY_Photo_BrightnessNumerator = (IID("{9E7D118F-B314-45A0-8CFB-D654B917C9E9}"), 100)
|
||||
PKEY_Photo_CameraManufacturer = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 271)
|
||||
PKEY_Photo_CameraModel = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 272)
|
||||
PKEY_Photo_CameraSerialNumber = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 273)
|
||||
PKEY_Photo_Contrast = (IID("{2A785BA9-8D23-4DED-82E6-60A350C86A10}"), 100)
|
||||
PKEY_Photo_ContrastText = (IID("{59DDE9F2-5253-40EA-9A8B-479E96C6249A}"), 100)
|
||||
PKEY_Photo_DateTaken = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 36867)
|
||||
PKEY_Photo_DigitalZoom = (IID("{F85BF840-A925-4BC2-B0C4-8E36B598679E}"), 100)
|
||||
PKEY_Photo_DigitalZoomDenominator = (IID("{745BAF0E-E5C1-4CFB-8A1B-D031A0A52393}"), 100)
|
||||
PKEY_Photo_DigitalZoomNumerator = (IID("{16CBB924-6500-473B-A5BE-F1599BCBE413}"), 100)
|
||||
PKEY_Photo_Event = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 18248)
|
||||
PKEY_Photo_EXIFVersion = (IID("{D35F743A-EB2E-47F2-A286-844132CB1427}"), 100)
|
||||
PKEY_Photo_ExposureBias = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 37380)
|
||||
PKEY_Photo_ExposureBiasDenominator = (
|
||||
IID("{AB205E50-04B7-461C-A18C-2F233836E627}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_ExposureBiasNumerator = (IID("{738BF284-1D87-420B-92CF-5834BF6EF9ED}"), 100)
|
||||
PKEY_Photo_ExposureIndex = (IID("{967B5AF8-995A-46ED-9E11-35B3C5B9782D}"), 100)
|
||||
PKEY_Photo_ExposureIndexDenominator = (
|
||||
IID("{93112F89-C28B-492F-8A9D-4BE2062CEE8A}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_ExposureIndexNumerator = (IID("{CDEDCF30-8919-44DF-8F4C-4EB2FFDB8D89}"), 100)
|
||||
PKEY_Photo_ExposureProgram = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 34850)
|
||||
PKEY_Photo_ExposureProgramText = (IID("{FEC690B7-5F30-4646-AE47-4CAAFBA884A3}"), 100)
|
||||
PKEY_Photo_ExposureTime = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 33434)
|
||||
PKEY_Photo_ExposureTimeDenominator = (
|
||||
IID("{55E98597-AD16-42E0-B624-21599A199838}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_ExposureTimeNumerator = (IID("{257E44E2-9031-4323-AC38-85C552871B2E}"), 100)
|
||||
PKEY_Photo_Flash = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 37385)
|
||||
PKEY_Photo_FlashEnergy = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 41483)
|
||||
PKEY_Photo_FlashEnergyDenominator = (IID("{D7B61C70-6323-49CD-A5FC-C84277162C97}"), 100)
|
||||
PKEY_Photo_FlashEnergyNumerator = (IID("{FCAD3D3D-0858-400F-AAA3-2F66CCE2A6BC}"), 100)
|
||||
PKEY_Photo_FlashManufacturer = (IID("{AABAF6C9-E0C5-4719-8585-57B103E584FE}"), 100)
|
||||
PKEY_Photo_FlashModel = (IID("{FE83BB35-4D1A-42E2-916B-06F3E1AF719E}"), 100)
|
||||
PKEY_Photo_FlashText = (IID("{6B8B68F6-200B-47EA-8D25-D8050F57339F}"), 100)
|
||||
PKEY_Photo_FNumber = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 33437)
|
||||
PKEY_Photo_FNumberDenominator = (IID("{E92A2496-223B-4463-A4E3-30EABBA79D80}"), 100)
|
||||
PKEY_Photo_FNumberNumerator = (IID("{1B97738A-FDFC-462F-9D93-1957E08BE90C}"), 100)
|
||||
PKEY_Photo_FocalLength = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 37386)
|
||||
PKEY_Photo_FocalLengthDenominator = (IID("{305BC615-DCA1-44A5-9FD4-10C0BA79412E}"), 100)
|
||||
PKEY_Photo_FocalLengthInFilm = (IID("{A0E74609-B84D-4F49-B860-462BD9971F98}"), 100)
|
||||
PKEY_Photo_FocalLengthNumerator = (IID("{776B6B3B-1E3D-4B0C-9A0E-8FBAF2A8492A}"), 100)
|
||||
PKEY_Photo_FocalPlaneXResolution = (IID("{CFC08D97-C6F7-4484-89DD-EBEF4356FE76}"), 100)
|
||||
PKEY_Photo_FocalPlaneXResolutionDenominator = (
|
||||
IID("{0933F3F5-4786-4F46-A8E8-D64DD37FA521}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_FocalPlaneXResolutionNumerator = (
|
||||
IID("{DCCB10AF-B4E2-4B88-95F9-031B4D5AB490}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_FocalPlaneYResolution = (IID("{4FFFE4D0-914F-4AC4-8D6F-C9C61DE169B1}"), 100)
|
||||
PKEY_Photo_FocalPlaneYResolutionDenominator = (
|
||||
IID("{1D6179A6-A876-4031-B013-3347B2B64DC8}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_FocalPlaneYResolutionNumerator = (
|
||||
IID("{A2E541C5-4440-4BA8-867E-75CFC06828CD}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_GainControl = (IID("{FA304789-00C7-4D80-904A-1E4DCC7265AA}"), 100)
|
||||
PKEY_Photo_GainControlDenominator = (IID("{42864DFD-9DA4-4F77-BDED-4AAD7B256735}"), 100)
|
||||
PKEY_Photo_GainControlNumerator = (IID("{8E8ECF7C-B7B8-4EB8-A63F-0EE715C96F9E}"), 100)
|
||||
PKEY_Photo_GainControlText = (IID("{C06238B2-0BF9-4279-A723-25856715CB9D}"), 100)
|
||||
PKEY_Photo_ISOSpeed = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 34855)
|
||||
PKEY_Photo_LensManufacturer = (IID("{E6DDCAF7-29C5-4F0A-9A68-D19412EC7090}"), 100)
|
||||
PKEY_Photo_LensModel = (IID("{E1277516-2B5F-4869-89B1-2E585BD38B7A}"), 100)
|
||||
PKEY_Photo_LightSource = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 37384)
|
||||
PKEY_Photo_MakerNote = (IID("{FA303353-B659-4052-85E9-BCAC79549B84}"), 100)
|
||||
PKEY_Photo_MakerNoteOffset = (IID("{813F4124-34E6-4D17-AB3E-6B1F3C2247A1}"), 100)
|
||||
PKEY_Photo_MaxAperture = (IID("{08F6D7C2-E3F2-44FC-AF1E-5AA5C81A2D3E}"), 100)
|
||||
PKEY_Photo_MaxApertureDenominator = (IID("{C77724D4-601F-46C5-9B89-C53F93BCEB77}"), 100)
|
||||
PKEY_Photo_MaxApertureNumerator = (IID("{C107E191-A459-44C5-9AE6-B952AD4B906D}"), 100)
|
||||
PKEY_Photo_MeteringMode = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 37383)
|
||||
PKEY_Photo_MeteringModeText = (IID("{F628FD8C-7BA8-465A-A65B-C5AA79263A9E}"), 100)
|
||||
PKEY_Photo_Orientation = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 274)
|
||||
PKEY_Photo_OrientationText = (IID("{A9EA193C-C511-498A-A06B-58E2776DCC28}"), 100)
|
||||
PKEY_Photo_PhotometricInterpretation = (
|
||||
IID("{341796F1-1DF9-4B1C-A564-91BDEFA43877}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_PhotometricInterpretationText = (
|
||||
IID("{821437D6-9EAB-4765-A589-3B1CBBD22A61}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_ProgramMode = (IID("{6D217F6D-3F6A-4825-B470-5F03CA2FBE9B}"), 100)
|
||||
PKEY_Photo_ProgramModeText = (IID("{7FE3AA27-2648-42F3-89B0-454E5CB150C3}"), 100)
|
||||
PKEY_Photo_RelatedSoundFile = (IID("{318A6B45-087F-4DC2-B8CC-05359551FC9E}"), 100)
|
||||
PKEY_Photo_Saturation = (IID("{49237325-A95A-4F67-B211-816B2D45D2E0}"), 100)
|
||||
PKEY_Photo_SaturationText = (IID("{61478C08-B600-4A84-BBE4-E99C45F0A072}"), 100)
|
||||
PKEY_Photo_Sharpness = (IID("{FC6976DB-8349-4970-AE97-B3C5316A08F0}"), 100)
|
||||
PKEY_Photo_SharpnessText = (IID("{51EC3F47-DD50-421D-8769-334F50424B1E}"), 100)
|
||||
PKEY_Photo_ShutterSpeed = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 37377)
|
||||
PKEY_Photo_ShutterSpeedDenominator = (
|
||||
IID("{E13D8975-81C7-4948-AE3F-37CAE11E8FF7}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_ShutterSpeedNumerator = (IID("{16EA4042-D6F4-4BCA-8349-7C78D30FB333}"), 100)
|
||||
PKEY_Photo_SubjectDistance = (IID("{14B81DA1-0135-4D31-96D9-6CBFC9671A99}"), 37382)
|
||||
PKEY_Photo_SubjectDistanceDenominator = (
|
||||
IID("{0C840A88-B043-466D-9766-D4B26DA3FA77}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_SubjectDistanceNumerator = (
|
||||
IID("{8AF4961C-F526-43E5-AA81-DB768219178D}"),
|
||||
100,
|
||||
)
|
||||
PKEY_Photo_TranscodedForSync = (IID("{9A8EBB75-6458-4E82-BACB-35C0095B03BB}"), 100)
|
||||
PKEY_Photo_WhiteBalance = (IID("{EE3D3D8A-5381-4CFA-B13B-AAF66B5F4EC9}"), 100)
|
||||
PKEY_Photo_WhiteBalanceText = (IID("{6336B95E-C7A7-426D-86FD-7AE3D39C84B4}"), 100)
|
||||
PKEY_PropGroup_Advanced = (IID("{900A403B-097B-4B95-8AE2-071FDAEEB118}"), 100)
|
||||
PKEY_PropGroup_Audio = (IID("{2804D469-788F-48AA-8570-71B9C187E138}"), 100)
|
||||
PKEY_PropGroup_Calendar = (IID("{9973D2B5-BFD8-438A-BA94-5349B293181A}"), 100)
|
||||
PKEY_PropGroup_Camera = (IID("{DE00DE32-547E-4981-AD4B-542F2E9007D8}"), 100)
|
||||
PKEY_PropGroup_Contact = (IID("{DF975FD3-250A-4004-858F-34E29A3E37AA}"), 100)
|
||||
PKEY_PropGroup_Content = (IID("{D0DAB0BA-368A-4050-A882-6C010FD19A4F}"), 100)
|
||||
PKEY_PropGroup_Description = (IID("{8969B275-9475-4E00-A887-FF93B8B41E44}"), 100)
|
||||
PKEY_PropGroup_FileSystem = (IID("{E3A7D2C1-80FC-4B40-8F34-30EA111BDC2E}"), 100)
|
||||
PKEY_PropGroup_General = (IID("{CC301630-B192-4C22-B372-9F4C6D338E07}"), 100)
|
||||
PKEY_PropGroup_GPS = (IID("{F3713ADA-90E3-4E11-AAE5-FDC17685B9BE}"), 100)
|
||||
PKEY_PropGroup_Image = (IID("{E3690A87-0FA8-4A2A-9A9F-FCE8827055AC}"), 100)
|
||||
PKEY_PropGroup_Media = (IID("{61872CF7-6B5E-4B4B-AC2D-59DA84459248}"), 100)
|
||||
PKEY_PropGroup_MediaAdvanced = (IID("{8859A284-DE7E-4642-99BA-D431D044B1EC}"), 100)
|
||||
PKEY_PropGroup_Message = (IID("{7FD7259D-16B4-4135-9F97-7C96ECD2FA9E}"), 100)
|
||||
PKEY_PropGroup_Music = (IID("{68DD6094-7216-40F1-A029-43FE7127043F}"), 100)
|
||||
PKEY_PropGroup_Origin = (IID("{2598D2FB-5569-4367-95DF-5CD3A177E1A5}"), 100)
|
||||
PKEY_PropGroup_PhotoAdvanced = (IID("{0CB2BF5A-9EE7-4A86-8222-F01E07FDADAF}"), 100)
|
||||
PKEY_PropGroup_RecordedTV = (IID("{E7B33238-6584-4170-A5C0-AC25EFD9DA56}"), 100)
|
||||
PKEY_PropGroup_Video = (IID("{BEBE0920-7671-4C54-A3EB-49FDDFC191EE}"), 100)
|
||||
PKEY_PropList_ConflictPrompt = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 11)
|
||||
PKEY_PropList_ExtendedTileInfo = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 9)
|
||||
PKEY_PropList_FileOperationPrompt = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 10)
|
||||
PKEY_PropList_FullDetails = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 2)
|
||||
PKEY_PropList_InfoTip = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 4)
|
||||
PKEY_PropList_NonPersonal = (IID("{49D1091F-082E-493F-B23F-D2308AA9668C}"), 100)
|
||||
PKEY_PropList_PreviewDetails = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 8)
|
||||
PKEY_PropList_PreviewTitle = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 6)
|
||||
PKEY_PropList_QuickTip = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 5)
|
||||
PKEY_PropList_TileInfo = (IID("{C9944A21-A406-48FE-8225-AEC7E24C211B}"), 3)
|
||||
PKEY_PropList_XPDetailsPanel = (IID("{F2275480-F782-4291-BD94-F13693513AEC}"), 0)
|
||||
PKEY_RecordedTV_ChannelNumber = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 7)
|
||||
PKEY_RecordedTV_Credits = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 4)
|
||||
PKEY_RecordedTV_DateContentExpires = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 15)
|
||||
PKEY_RecordedTV_EpisodeName = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 2)
|
||||
PKEY_RecordedTV_IsATSCContent = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 16)
|
||||
PKEY_RecordedTV_IsClosedCaptioningAvailable = (
|
||||
IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"),
|
||||
12,
|
||||
)
|
||||
PKEY_RecordedTV_IsDTVContent = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 17)
|
||||
PKEY_RecordedTV_IsHDContent = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 18)
|
||||
PKEY_RecordedTV_IsRepeatBroadcast = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 13)
|
||||
PKEY_RecordedTV_IsSAP = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 14)
|
||||
PKEY_RecordedTV_NetworkAffiliation = (
|
||||
IID("{2C53C813-FB63-4E22-A1AB-0B331CA1E273}"),
|
||||
100,
|
||||
)
|
||||
PKEY_RecordedTV_OriginalBroadcastDate = (
|
||||
IID("{4684FE97-8765-4842-9C13-F006447B178C}"),
|
||||
100,
|
||||
)
|
||||
PKEY_RecordedTV_ProgramDescription = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 3)
|
||||
PKEY_RecordedTV_RecordingTime = (IID("{A5477F61-7A82-4ECA-9DDE-98B69B2479B3}"), 100)
|
||||
PKEY_RecordedTV_StationCallSign = (IID("{6D748DE2-8D38-4CC3-AC60-F009B057C557}"), 5)
|
||||
PKEY_RecordedTV_StationName = (IID("{1B5439E7-EBA1-4AF8-BDD7-7AF1D4549493}"), 100)
|
||||
PKEY_Search_AutoSummary = (IID("{560C36C0-503A-11CF-BAA1-00004C752A9A}"), 2)
|
||||
PKEY_Search_ContainerHash = (IID("{BCEEE283-35DF-4D53-826A-F36A3EEFC6BE}"), 100)
|
||||
PKEY_Search_Contents = (IID("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"), 19)
|
||||
PKEY_Search_EntryID = (IID("{49691C90-7E17-101A-A91C-08002B2ECDA9}"), 5)
|
||||
PKEY_Search_GatherTime = (IID("{0B63E350-9CCC-11D0-BCDB-00805FCCCE04}"), 8)
|
||||
PKEY_Search_IsClosedDirectory = (IID("{0B63E343-9CCC-11D0-BCDB-00805FCCCE04}"), 23)
|
||||
PKEY_Search_IsFullyContained = (IID("{0B63E343-9CCC-11D0-BCDB-00805FCCCE04}"), 24)
|
||||
PKEY_Search_QueryFocusedSummary = (IID("{560C36C0-503A-11CF-BAA1-00004C752A9A}"), 3)
|
||||
PKEY_Search_Rank = (IID("{49691C90-7E17-101A-A91C-08002B2ECDA9}"), 3)
|
||||
PKEY_Search_Store = (IID("{A06992B3-8CAF-4ED7-A547-B259E32AC9FC}"), 100)
|
||||
PKEY_Search_UrlToIndex = (IID("{0B63E343-9CCC-11D0-BCDB-00805FCCCE04}"), 2)
|
||||
PKEY_Search_UrlToIndexWithModificationTime = (
|
||||
IID("{0B63E343-9CCC-11D0-BCDB-00805FCCCE04}"),
|
||||
12,
|
||||
)
|
||||
PKEY_DescriptionID = (IID("{28636AA6-953D-11D2-B5D6-00C04FD918D0}"), 2)
|
||||
PKEY_Link_TargetSFGAOFlagsStrings = (IID("{D6942081-D53B-443D-AD47-5E059D9CD27A}"), 3)
|
||||
PKEY_Link_TargetUrl = (IID("{5CBF2787-48CF-4208-B90E-EE5E5D420294}"), 2)
|
||||
PKEY_Shell_SFGAOFlagsStrings = (IID("{D6942081-D53B-443D-AD47-5E059D9CD27A}"), 2)
|
||||
PKEY_Software_DateLastUsed = (IID("{841E4F90-FF59-4D16-8947-E81BBFFAB36D}"), 16)
|
||||
PKEY_Software_ProductName = (IID("{0CEF7D53-FA64-11D1-A203-0000F81FEDEE}"), 7)
|
||||
PKEY_Sync_Comments = (IID("{7BD5533E-AF15-44DB-B8C8-BD6624E1D032}"), 13)
|
||||
PKEY_Sync_ConflictDescription = (IID("{CE50C159-2FB8-41FD-BE68-D3E042E274BC}"), 4)
|
||||
PKEY_Sync_ConflictFirstLocation = (IID("{CE50C159-2FB8-41FD-BE68-D3E042E274BC}"), 6)
|
||||
PKEY_Sync_ConflictSecondLocation = (IID("{CE50C159-2FB8-41FD-BE68-D3E042E274BC}"), 7)
|
||||
PKEY_Sync_HandlerCollectionID = (IID("{7BD5533E-AF15-44DB-B8C8-BD6624E1D032}"), 2)
|
||||
PKEY_Sync_HandlerID = (IID("{7BD5533E-AF15-44DB-B8C8-BD6624E1D032}"), 3)
|
||||
PKEY_Sync_HandlerName = (IID("{CE50C159-2FB8-41FD-BE68-D3E042E274BC}"), 2)
|
||||
PKEY_Sync_HandlerType = (IID("{7BD5533E-AF15-44DB-B8C8-BD6624E1D032}"), 8)
|
||||
PKEY_Sync_HandlerTypeLabel = (IID("{7BD5533E-AF15-44DB-B8C8-BD6624E1D032}"), 9)
|
||||
PKEY_Sync_ItemID = (IID("{7BD5533E-AF15-44DB-B8C8-BD6624E1D032}"), 6)
|
||||
PKEY_Sync_ItemName = (IID("{CE50C159-2FB8-41FD-BE68-D3E042E274BC}"), 3)
|
||||
PKEY_Task_BillingInformation = (IID("{D37D52C6-261C-4303-82B3-08B926AC6F12}"), 100)
|
||||
PKEY_Task_CompletionStatus = (IID("{084D8A0A-E6D5-40DE-BF1F-C8820E7C877C}"), 100)
|
||||
PKEY_Task_Owner = (IID("{08C7CC5F-60F2-4494-AD75-55E3E0B5ADD0}"), 100)
|
||||
PKEY_Video_Compression = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 10)
|
||||
PKEY_Video_Director = (IID("{64440492-4C8B-11D1-8B70-080036B11A03}"), 20)
|
||||
PKEY_Video_EncodingBitrate = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 8)
|
||||
PKEY_Video_FourCC = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 44)
|
||||
PKEY_Video_FrameHeight = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 4)
|
||||
PKEY_Video_FrameRate = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 6)
|
||||
PKEY_Video_FrameWidth = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 3)
|
||||
PKEY_Video_HorizontalAspectRatio = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 42)
|
||||
PKEY_Video_SampleSize = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 9)
|
||||
PKEY_Video_StreamName = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 2)
|
||||
PKEY_Video_StreamNumber = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 11)
|
||||
PKEY_Video_TotalBitrate = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 43)
|
||||
PKEY_Video_VerticalAspectRatio = (IID("{64440491-4C8B-11D1-8B70-080036B11A03}"), 45)
|
||||
PKEY_Volume_FileSystem = (IID("{9B174B35-40FF-11D2-A27E-00C04FC30871}"), 4)
|
||||
PKEY_Volume_IsMappedDrive = (IID("{149C0B69-2C2D-48FC-808F-D318D78C4636}"), 2)
|
||||
PKEY_Volume_IsRoot = (IID("{9B174B35-40FF-11D2-A27E-00C04FC30871}"), 10)
|
||||
|
||||
PKEY_AppUserModel_RelaunchCommand = (IID("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"), 2)
|
||||
PKEY_AppUserModel_RelaunchIconResource = (
|
||||
IID("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"),
|
||||
3,
|
||||
)
|
||||
PKEY_AppUserModel_RelaunchDisplayNameResource = (
|
||||
IID("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"),
|
||||
4,
|
||||
)
|
||||
PKEY_AppUserModel_ID = (IID("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"), 5)
|
||||
PKEY_AppUserModel_IsDestListSeparator = (
|
||||
IID("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"),
|
||||
6,
|
||||
)
|
||||
PKEY_AppUserModel_ExcludeFromShowInNewInstall = (
|
||||
IID("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"),
|
||||
8,
|
||||
)
|
||||
PKEY_AppUserModel_PreventPinning = (IID("{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"), 9)
|
||||
|
||||
# PKA_FLAGS, used with IPropertyChange
|
||||
PKA_SET = 0
|
||||
PKA_APPEND = 1
|
||||
PKA_DELETE = 2
|
5
lib/win32comext/propsys/test/testpropsys.py
Normal file
5
lib/win32comext/propsys/test/testpropsys.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from win32com.propsys import propsys, pscon
|
||||
|
||||
print("propsys was imported (sorry - that is the extent of the tests,")
|
||||
print("but see the shell folder_view demo, which uses this module)")
|
||||
# that's all folks!
|
4
lib/win32comext/shell/__init__.py
Normal file
4
lib/win32comext/shell/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
# See if we have a special directory for the binaries (for developers)
|
||||
import win32com
|
||||
|
||||
win32com.__PackageSupportBuildPath__(__path__)
|
83
lib/win32comext/shell/demos/IActiveDesktop.py
Normal file
83
lib/win32comext/shell/demos/IActiveDesktop.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
import time
|
||||
|
||||
import pythoncom
|
||||
from win32com.shell import shell, shellcon
|
||||
|
||||
website = "https://github.com/mhammond/pywin32/"
|
||||
iad = pythoncom.CoCreateInstance(
|
||||
shell.CLSID_ActiveDesktop,
|
||||
None,
|
||||
pythoncom.CLSCTX_INPROC_SERVER,
|
||||
shell.IID_IActiveDesktop,
|
||||
)
|
||||
opts = iad.GetDesktopItemOptions()
|
||||
if not (opts["ActiveDesktop"] and opts["EnableComponents"]):
|
||||
print("Warning: Enabling Active Desktop")
|
||||
opts["ActiveDesktop"] = True
|
||||
opts["EnableComponents"] = True
|
||||
iad.SetDesktopItemOptions(opts)
|
||||
iad.ApplyChanges(0xFFFF)
|
||||
iad = None
|
||||
## apparently takes a short while for it to become active
|
||||
time.sleep(2)
|
||||
iad = pythoncom.CoCreateInstance(
|
||||
shell.CLSID_ActiveDesktop,
|
||||
None,
|
||||
pythoncom.CLSCTX_INPROC_SERVER,
|
||||
shell.IID_IActiveDesktop,
|
||||
)
|
||||
|
||||
cnt = iad.GetDesktopItemCount()
|
||||
print("Count:", cnt)
|
||||
for i in range(cnt):
|
||||
print(iad.GetDesktopItem(i))
|
||||
|
||||
component = {
|
||||
"ID": cnt + 1,
|
||||
"ComponentType": shellcon.COMP_TYPE_WEBSITE,
|
||||
"CurItemState": shellcon.IS_NORMAL,
|
||||
"SubscribedURL": website,
|
||||
"Source": website,
|
||||
"FriendlyName": "Pywin32 on SF",
|
||||
"Checked": True, ## this controls whether item is currently displayed
|
||||
"NoScroll": False,
|
||||
"Dirty": False,
|
||||
"Pos": {
|
||||
"Top": 69,
|
||||
"Left": 69,
|
||||
"Height": 400,
|
||||
"Width": 400,
|
||||
"zIndex": 1002,
|
||||
"CanResize": True,
|
||||
"CanResizeX": True,
|
||||
"CanResizeY": True,
|
||||
"PreferredLeftPercent": 0,
|
||||
"PreferredTopPercent": 0,
|
||||
},
|
||||
"Original": {
|
||||
"Top": 33,
|
||||
"Left": 304,
|
||||
"Height": 362,
|
||||
"Width": 372,
|
||||
"ItemState": shellcon.IS_NORMAL,
|
||||
},
|
||||
"Restored": {
|
||||
"Top": 33,
|
||||
"Left": 304,
|
||||
"Height": 362,
|
||||
"Width": 372,
|
||||
"ItemState": shellcon.IS_NORMAL,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
try:
|
||||
existing_item = iad.GetDesktopItemBySource(website)
|
||||
except pythoncom.com_error:
|
||||
pass
|
||||
else:
|
||||
iad.RemoveDesktopItem(existing_item)
|
||||
iad.ApplyChanges(0xFFFF)
|
||||
|
||||
iad.AddDesktopItem(component)
|
||||
iad.ApplyChanges(0xFFFF) ## need to check which AD_APPLY constants are actually needed
|
181
lib/win32comext/shell/demos/IFileOperationProgressSink.py
Normal file
181
lib/win32comext/shell/demos/IFileOperationProgressSink.py
Normal file
|
@ -0,0 +1,181 @@
|
|||
# Sample implementation of IFileOperationProgressSink that just prints
|
||||
# some basic info
|
||||
|
||||
import pythoncom
|
||||
from win32com.server.policy import DesignatedWrapPolicy
|
||||
from win32com.shell import shell, shellcon
|
||||
|
||||
tsf_flags = list(
|
||||
(k, v) for k, v in list(shellcon.__dict__.items()) if k.startswith("TSF_")
|
||||
)
|
||||
|
||||
|
||||
def decode_flags(flags):
|
||||
if flags == 0:
|
||||
return "TSF_NORMAL"
|
||||
flag_txt = ""
|
||||
for k, v in tsf_flags:
|
||||
if flags & v:
|
||||
if flag_txt:
|
||||
flag_txt = flag_txt + "|" + k
|
||||
else:
|
||||
flag_txt = k
|
||||
return flag_txt
|
||||
|
||||
|
||||
class FileOperationProgressSink(DesignatedWrapPolicy):
|
||||
_com_interfaces_ = [shell.IID_IFileOperationProgressSink]
|
||||
_public_methods_ = [
|
||||
"StartOperations",
|
||||
"FinishOperations",
|
||||
"PreRenameItem",
|
||||
"PostRenameItem",
|
||||
"PreMoveItem",
|
||||
"PostMoveItem",
|
||||
"PreCopyItem",
|
||||
"PostCopyItem",
|
||||
"PreDeleteItem",
|
||||
"PostDeleteItem",
|
||||
"PreNewItem",
|
||||
"PostNewItem",
|
||||
"UpdateProgress",
|
||||
"ResetTimer",
|
||||
"PauseTimer",
|
||||
"ResumeTimer",
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
self._wrap_(self)
|
||||
|
||||
def StartOperations(self):
|
||||
print("StartOperations")
|
||||
|
||||
def FinishOperations(self, Result):
|
||||
print("FinishOperations: HRESULT ", Result)
|
||||
|
||||
def PreRenameItem(self, Flags, Item, NewName):
|
||||
print(
|
||||
"PreRenameItem: Renaming "
|
||||
+ Item.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ " to "
|
||||
+ NewName
|
||||
)
|
||||
|
||||
def PostRenameItem(self, Flags, Item, NewName, hrRename, NewlyCreated):
|
||||
if NewlyCreated is not None:
|
||||
newfile = NewlyCreated.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
else:
|
||||
newfile = "not renamed, HRESULT " + str(hrRename)
|
||||
print(
|
||||
"PostRenameItem: renamed "
|
||||
+ Item.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ " to "
|
||||
+ newfile
|
||||
)
|
||||
|
||||
def PreMoveItem(self, Flags, Item, DestinationFolder, NewName):
|
||||
print(
|
||||
"PreMoveItem: Moving "
|
||||
+ Item.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ " to "
|
||||
+ DestinationFolder.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ "\\"
|
||||
+ str(NewName)
|
||||
)
|
||||
|
||||
def PostMoveItem(
|
||||
self, Flags, Item, DestinationFolder, NewName, hrMove, NewlyCreated
|
||||
):
|
||||
if NewlyCreated is not None:
|
||||
newfile = NewlyCreated.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
else:
|
||||
newfile = "not copied, HRESULT " + str(hrMove)
|
||||
print(
|
||||
"PostMoveItem: Moved "
|
||||
+ Item.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ " to "
|
||||
+ newfile
|
||||
)
|
||||
|
||||
def PreCopyItem(self, Flags, Item, DestinationFolder, NewName):
|
||||
if not NewName:
|
||||
NewName = ""
|
||||
print(
|
||||
"PreCopyItem: Copying "
|
||||
+ Item.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ " to "
|
||||
+ DestinationFolder.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ "\\"
|
||||
+ NewName
|
||||
)
|
||||
print("Flags: ", decode_flags(Flags))
|
||||
|
||||
def PostCopyItem(
|
||||
self, Flags, Item, DestinationFolder, NewName, hrCopy, NewlyCreated
|
||||
):
|
||||
if NewlyCreated is not None:
|
||||
newfile = NewlyCreated.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
else:
|
||||
newfile = "not copied, HRESULT " + str(hrCopy)
|
||||
print(
|
||||
"PostCopyItem: Copied "
|
||||
+ Item.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ " to "
|
||||
+ newfile
|
||||
)
|
||||
print("Flags: ", decode_flags(Flags))
|
||||
|
||||
def PreDeleteItem(self, Flags, Item):
|
||||
print(
|
||||
"PreDeleteItem: Deleting " + Item.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
)
|
||||
|
||||
def PostDeleteItem(self, Flags, Item, hrDelete, NewlyCreated):
|
||||
print(
|
||||
"PostDeleteItem: Deleted " + Item.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
)
|
||||
if NewlyCreated:
|
||||
print(
|
||||
" Moved to recycle bin - "
|
||||
+ NewlyCreated.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
)
|
||||
|
||||
def PreNewItem(self, Flags, DestinationFolder, NewName):
|
||||
print(
|
||||
"PreNewItem: Creating "
|
||||
+ DestinationFolder.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
+ "\\"
|
||||
+ NewName
|
||||
)
|
||||
|
||||
def PostNewItem(
|
||||
self,
|
||||
Flags,
|
||||
DestinationFolder,
|
||||
NewName,
|
||||
TemplateName,
|
||||
FileAttributes,
|
||||
hrNew,
|
||||
NewItem,
|
||||
):
|
||||
print(
|
||||
"PostNewItem: Created " + NewItem.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
)
|
||||
|
||||
def UpdateProgress(self, WorkTotal, WorkSoFar):
|
||||
print("UpdateProgress: ", WorkSoFar, WorkTotal)
|
||||
|
||||
def ResetTimer(self):
|
||||
print("ResetTimer")
|
||||
|
||||
def PauseTimer(self):
|
||||
print("PauseTimer")
|
||||
|
||||
def ResumeTimer(self):
|
||||
print("ResumeTimer")
|
||||
|
||||
|
||||
def CreateSink():
|
||||
return pythoncom.WrapObject(
|
||||
FileOperationProgressSink(), shell.IID_IFileOperationProgressSink
|
||||
)
|
67
lib/win32comext/shell/demos/IShellLinkDataList.py
Normal file
67
lib/win32comext/shell/demos/IShellLinkDataList.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
import pythoncom
|
||||
import win32api
|
||||
from win32com.shell import shell, shellcon
|
||||
|
||||
temp_dir = win32api.GetTempPath()
|
||||
linkname = win32api.GetTempFileName(temp_dir, "cmd")[0]
|
||||
os.remove(linkname)
|
||||
linkname += ".lnk"
|
||||
print("Link name:", linkname)
|
||||
ish = pythoncom.CoCreateInstance(
|
||||
shell.CLSID_ShellLink, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink
|
||||
)
|
||||
ish.SetPath(os.environ["cOMSPEC"])
|
||||
ish.SetWorkingDirectory(os.path.split(sys.executable)[0])
|
||||
ish.SetDescription("shortcut made by python")
|
||||
|
||||
console_props = {
|
||||
"Signature": shellcon.NT_CONSOLE_PROPS_SIG,
|
||||
"InsertMode": True,
|
||||
"FullScreen": False, ## True looks like "DOS Mode" from win98!
|
||||
"FontFamily": 54,
|
||||
"CursorSize": 75, ## pct of character size
|
||||
"ScreenBufferSize": (152, 256),
|
||||
"AutoPosition": False,
|
||||
"FontSize": (4, 5),
|
||||
"FaceName": "",
|
||||
"HistoryBufferSize": 32,
|
||||
"InputBufferSize": 0,
|
||||
"QuickEdit": True,
|
||||
"Font": 0, ## 0 should always be present, use win32console.GetNumberOfConsoleFonts() to find how many available
|
||||
"FillAttribute": 7,
|
||||
"PopupFillAttribute": 245,
|
||||
"WindowSize": (128, 32),
|
||||
"WindowOrigin": (0, 0),
|
||||
"FontWeight": 400,
|
||||
"HistoryNoDup": False,
|
||||
"NumberOfHistoryBuffers": 32,
|
||||
## ColorTable copied from a 'normal' console shortcut, with some obvious changes
|
||||
## These do not appear to be documented. From experimentation, [0] is background, [7] is foreground text
|
||||
"ColorTable": (
|
||||
255,
|
||||
8388608,
|
||||
32768,
|
||||
8421376,
|
||||
128,
|
||||
8388736,
|
||||
32896,
|
||||
12582912,
|
||||
8421504,
|
||||
16711680,
|
||||
65280,
|
||||
16776960,
|
||||
255,
|
||||
16711935,
|
||||
65535,
|
||||
16777215,
|
||||
),
|
||||
}
|
||||
|
||||
ishdl = ish.QueryInterface(shell.IID_IShellLinkDataList)
|
||||
ishdl.AddDataBlock(console_props)
|
||||
ipf = ish.QueryInterface(pythoncom.IID_IPersistFile)
|
||||
ipf.Save(linkname, 1)
|
||||
os.startfile(linkname)
|
107
lib/win32comext/shell/demos/ITransferAdviseSink.py
Normal file
107
lib/win32comext/shell/demos/ITransferAdviseSink.py
Normal file
|
@ -0,0 +1,107 @@
|
|||
# ITransferAdviseSink implementation template
|
||||
|
||||
import pythoncom
|
||||
from win32com.server.policy import DesignatedWrapPolicy
|
||||
from win32com.shell import shell, shellcon
|
||||
|
||||
tsf_flags = list(
|
||||
(k, v) for k, v in list(shellcon.__dict__.items()) if k.startswith("TSF_")
|
||||
)
|
||||
|
||||
|
||||
def decode_flags(flags):
|
||||
if flags == 0:
|
||||
return "TSF_NORMAL"
|
||||
flag_txt = ""
|
||||
for k, v in tsf_flags:
|
||||
if flags & v:
|
||||
if flag_txt:
|
||||
flag_txt = flag_txt + "|" + k
|
||||
else:
|
||||
flag_txt = k
|
||||
return flag_txt
|
||||
|
||||
|
||||
TRANSFER_ADVISE_STATES = {}
|
||||
for k, v in list(shellcon.__dict__.items()):
|
||||
if k.startswith("TS_"):
|
||||
TRANSFER_ADVISE_STATES[v] = k
|
||||
|
||||
|
||||
def decode_flags(flags):
|
||||
if flags == 0:
|
||||
return "TSF_NORMAL"
|
||||
flag_txt = ""
|
||||
for k, v in tsf_flags:
|
||||
if flags & v:
|
||||
if flag_txt:
|
||||
flag_txt = flag_txt + "|" + k
|
||||
else:
|
||||
flag_txt = k
|
||||
return flag_txt
|
||||
|
||||
|
||||
class TransferAdviseSink(DesignatedWrapPolicy):
|
||||
_com_interfaces_ = [shell.IID_ITransferAdviseSink]
|
||||
_public_methods_ = [
|
||||
"UpdateProgress",
|
||||
"UpdateTransferState",
|
||||
"ConfirmOverwrite",
|
||||
"ConfirmEncryptionLoss",
|
||||
"FileFailure",
|
||||
"SubStreamFailure",
|
||||
"PropertyFailure",
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
self._wrap_(self)
|
||||
|
||||
def UpdateProgress(
|
||||
self,
|
||||
SizeCurrent,
|
||||
SizeTotal,
|
||||
FilesCurrent,
|
||||
FilesTotal,
|
||||
FoldersCurrent,
|
||||
FoldersTotal,
|
||||
):
|
||||
print("UpdateProgress - processed so far:")
|
||||
print("\t %s out of %s bytes" % (SizeCurrent, SizeTotal))
|
||||
print("\t %s out of %s files" % (FilesCurrent, FilesTotal))
|
||||
print("\t %s out of %s folders" % (FoldersCurrent, FoldersTotal))
|
||||
|
||||
def UpdateTransferState(self, State):
|
||||
print(
|
||||
"Current state: ",
|
||||
TRANSFER_ADVISE_STATES.get(State, "??? Unknown state %s ???" % State),
|
||||
)
|
||||
|
||||
def ConfirmOverwrite(self, Source, DestParent, Name):
|
||||
print(
|
||||
"ConfirmOverwrite: ",
|
||||
Source.GetDisplayName(shellcon.SHGDN_FORPARSING),
|
||||
DestParent.GetDisplayName(shellcon.SHGDN_FORPARSING),
|
||||
Name,
|
||||
)
|
||||
|
||||
def ConfirmEncryptionLoss(self, Source):
|
||||
print(
|
||||
"ConfirmEncryptionLoss:", Source.GetDisplayName(shellcon.SHGDN_FORPARSING)
|
||||
)
|
||||
|
||||
def FileFailure(self, Item, ItemName, Error):
|
||||
print("FileFailure:", Item.GetDisplayName(shellcon.SHGDN_FORPARSING), ItemName)
|
||||
|
||||
def SubStreamFailure(self, Item, StreamName, Error):
|
||||
print("SubStreamFailure:\n")
|
||||
|
||||
def PropertyFailure(self, Item, key, Error):
|
||||
print("PropertyFailure:\n")
|
||||
|
||||
|
||||
def CreateSink():
|
||||
return pythoncom.WrapObject(
|
||||
TransferAdviseSink(),
|
||||
shell.IID_ITransferAdviseSink,
|
||||
shell.IID_ITransferAdviseSink,
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue