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:
dependabot[bot] 2024-03-24 15:25:44 -07:00 committed by GitHub
commit faef9a94c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
673 changed files with 159850 additions and 11583 deletions

View 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)

Binary file not shown.

View 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"

View 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()

View 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")

View 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()

View 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()

View 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__)

Binary file not shown.

View 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()

View 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()

View file

@ -0,0 +1,4 @@
# See if we have a special directory for the binaries (for developers)
import win32com
win32com.__PackageSupportBuildPath__(__path__)

Binary file not shown.

View file

@ -0,0 +1,4 @@
# See if we have a special directory for the binaries (for developers)
import win32com
win32com.__PackageSupportBuildPath__(__path__)

View 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

Binary file not shown.

View 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))

View 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)

View 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())
)

View 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 = {}

View 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()

View 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")

View 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")

View 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")

View 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

View 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>

View 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>

View file

@ -0,0 +1,4 @@
<%@ language=python%>
<html>
<%Response.Redirect("test1.html")%>
</html>

View file

@ -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>

View file

@ -0,0 +1,6 @@
<%@ language =Python%>
<html>
<head>
<%Response.Redirect("test.html")%>
</head>
</html>

View file

@ -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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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.

View 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>

View 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>

View 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>

View 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>&nbsp;
<HR>
<B>Notes:</B>
<P>
</FONT>
</BODY>
</HTML>

View 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>&nbsp;</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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View 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))

View 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")

View 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

View file

@ -0,0 +1,4 @@
# See if we have a special directory for the binaries (for developers)
import win32com
win32com.__PackageSupportBuildPath__(__path__)

View 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

Binary file not shown.

View file

@ -0,0 +1 @@
# This is a Python package

View 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)

View 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

File diff suppressed because it is too large Load diff

View 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()

View 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()

View 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)

View 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))

View 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

View 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)

View 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!
"""

View file

@ -0,0 +1,7 @@
a=1
b=a
Test.Echo "Hello from VBScript"
' Here is a comment
for i = 1 to 10
next

View 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()

View 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()

View 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")

View 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__)

Binary file not shown.

View 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()

View 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

View file

@ -0,0 +1,4 @@
# See if we have a special directory for the binaries (for developers)
import win32com
win32com.__PackageSupportBuildPath__(__path__)

Binary file not shown.

View file

@ -0,0 +1 @@
# This is a Python package, imported by the win32com test suite.

View 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()

View 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()

View file

@ -0,0 +1 @@
# empty file to designate as a package.

View 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()

Binary file not shown.

View 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

View file

@ -0,0 +1,4 @@
# See if we have a special directory for the binaries (for developers)
import win32com
win32com.__PackageSupportBuildPath__(__path__)

View 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

Binary file not shown.

View 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__)

View 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)

View 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)

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

View 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)

View file

@ -0,0 +1 @@
# this is a python package

Binary file not shown.

View 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

View 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!

View file

@ -0,0 +1,4 @@
# See if we have a special directory for the binaries (for developers)
import win32com
win32com.__PackageSupportBuildPath__(__path__)

View 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

View 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
)

View 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)

View 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