def GetMessageStores(self): tab = self.session.GetMsgStoresTable(0) rows = mapi.HrQueryAllRows( tab, (PR_ENTRYID, PR_DISPLAY_NAME_A, PR_DEFAULT_STORE), # columns to retrieve None, # all rows None, # any sort order is fine 0) # any # of results is fine for row in rows: (eid_tag, eid), (name_tag, name), (def_store_tag, def_store) = row # Open the store. try: store = self.session.OpenMsgStore( 0, # no parent window eid, # msg store to open None, # IID; accept default IMsgStore # need write access to add score fields mapi.MDB_WRITE | # we won't send or receive email mapi.MDB_NO_MAIL | mapi.MAPI_DEFERRED_ERRORS) yield store, name, def_store except pythoncom.com_error, details: hr, msg, exc, arg_err = details if hr == mapi.MAPI_E_FAILONEPROVIDER: # not logged on etc. pass else: print "Error opening message store", details, "- ignoring"
def _FindSubfolder(self, store, folder, find_name): find_name = find_name.lower() table = folder.GetHierarchyTable(0) rows = mapi.HrQueryAllRows(table, (PR_ENTRYID, PR_DISPLAY_NAME_A), None, None, 0) for (eid_tag, eid), (name_tag, name), in rows: if name.lower() == find_name: return store.OpenEntry(eid, None, mapi.MAPI_DEFERRED_ERRORS) return None
def DumpTopLevelFolders(self): print "Top-level folder names are:" for store, name, is_default in self.GetMessageStores(): # Find the folder with the content. hr, data = store.GetProps((PR_IPM_SUBTREE_ENTRYID, ), 0) subtree_eid = data[0][1] folder = store.OpenEntry(subtree_eid, None, mapi.MAPI_DEFERRED_ERRORS) # Now the top-level folders in the store. table = folder.GetHierarchyTable(0) rows = mapi.HrQueryAllRows(table, (PR_DISPLAY_NAME_A), None, None, 0) for (name_tag, folder_name), in rows: print " \\%s\\%s" % (name, folder_name)
def _BuildFoldersMAPI(manager, folder_spec): # This is called dynamically as folders are expanded. dlgutils.SetWaitCursor(1) folder = manager.message_store.GetFolder(folder_spec.folder_id).OpenEntry() # Get the hierarchy table for it. table = folder.GetHierarchyTable(0) children = [] order = (((PR_DISPLAY_NAME_A, mapi.TABLE_SORT_ASCEND), ), 0, 0) rows = mapi.HrQueryAllRows( table, (PR_ENTRYID, PR_STORE_ENTRYID, PR_DISPLAY_NAME_A), None, order, 0) if verbose: print "Rows for sub-folder of", folder_spec.name, "-", folder_spec.folder_id pprint(rows) for (eid_tag, eid), (storeeid_tag, store_eid), (name_tag, name) in rows: # Note the eid we get here is short-term - hence we must # re-fetch from the object itself (which is what our manager does, # so no need to do it explicitly - just believe folder.id over eid) ignore = False for check_eid in folder_spec.ignore_eids: if manager.message_store.session.CompareEntryIDs(check_eid, eid): ignore = True break if ignore: continue temp_id = mapi.HexFromBin(store_eid), mapi.HexFromBin(eid) try: # may get MsgStoreException for GetFolder, or # a mapi exception for the underlying MAPI stuff we then call. # Either way, just skip it. child_folder = manager.message_store.GetFolder(temp_id) spec = FolderSpec(child_folder.GetID(), name, folder_spec.ignore_eids) # If we have no children at all, indicate # the item is not expandable. table = child_folder.OpenEntry().GetHierarchyTable(0) if table.GetRowCount(0) == 0: spec.children = [] else: spec.children = None # Flag as "not yet built" children.append(spec) except (pythoncom.com_error, manager.message_store.MsgStoreException), details: # Users have reported failure here - it is not clear if the # entire tree is going to fail, or just this folder print "** Unable to open child folder - ignoring" print details
def FindAndDumpTableUserProps(driver, table, folder, shorten, get_large_props, stream=None): restriction = (mapi.RES_PROPERTY, (mapi.RELOP_EQ, PR_MESSAGE_CLASS_A, (PR_MESSAGE_CLASS_A, 'IPC.MS.REN.USERFIELDS'))) cols = (PR_USERFIELDS, ) table.SetColumns(cols, 0) rows = mapi.HrQueryAllRows(table, cols, restriction, None, 0) assert len(rows) <= 1, "Only expecting 1 (or 0) rows" tag, val = rows[0][0] prop_name = GetPropTagName(folder, tag) prop_repr = FormatPropertyValue(tag, val, folder, shorten, get_large_props) print >> stream, "%-20s: %s" % (prop_name, prop_repr)
def DumpTable(driver, table, name_query_ob, shorten, large_props, stream=None): cols = table.QueryColumns(TBL_ALL_COLUMNS) table.SetColumns(cols, 0) rows = mapi.HrQueryAllRows(table, cols, None, None, 0) print >> stream, \ "Table has %d rows, each with %d columns" % (len(rows), len(cols)) for row in rows: print >> stream, "-- new row --" for col in row: prop_tag, prop_val = col # If we want 'short' variables, drop 'not found' props. if shorten and PROP_TYPE(prop_tag)==PT_ERROR \ and prop_val == mapi.MAPI_E_NOT_FOUND: continue prop_name = GetPropTagName(name_query_ob, prop_tag) prop_repr = FormatPropertyValue(prop_tag, prop_val, name_query_ob, shorten, large_props) print >> stream, "%-20s: %s" % (prop_name, prop_repr)
def BuildFolderTreeMAPI(session, ignore_ids): root = FolderSpec(None, "root") tab = session.GetMsgStoresTable(0) prop_tags = PR_ENTRYID, PR_DISPLAY_NAME_A rows = mapi.HrQueryAllRows(tab, prop_tags, None, None, 0) if verbose: print "message store rows:" pprint(rows) for row in rows: (eid_tag, eid), (name_tag, name) = row hex_eid = mapi.HexFromBin(eid) try: msgstore = session.OpenMsgStore( 0, eid, None, mapi.MDB_NO_MAIL | mapi.MAPI_DEFERRED_ERRORS) hr, data = msgstore.GetProps( (PR_IPM_SUBTREE_ENTRYID, ) + ignore_ids, 0) # It appears that not all stores have a subtree. if PROP_TYPE(data[0][0]) != PT_BINARY: print "FolderSelector dialog found message store without a subtree - ignoring" continue subtree_eid = data[0][1] ignore_eids = [ item[1] for item in data[1:] if PROP_TYPE(item[0]) == PT_BINARY ] except pythoncom.com_error, details: # Handle 'expected' errors. if details[0] == mapi.MAPI_E_FAILONEPROVIDER: print "A message store is temporarily unavailable - " \ "it will not appear in the Folder Selector dialog" else: # Some weird error opening a folder tree # Just print a warning and ignore the tree. print "Failed to open a message store for the FolderSelector dialog" print "Exception details:", details continue folder_id = hex_eid, mapi.HexFromBin(subtree_eid) if verbose: print "message store root folder id is", folder_id spec = FolderSpec(folder_id, name, ignore_eids) spec.children = None root.children.append(spec)
def GetItemsWithValue(self, folder, prop_tag, prop_val, mapi_flags=None): mapi_flags = self._GetMAPIFlags(mapi_flags) tab = folder.GetContentsTable(0) # Restriction for the table: get rows where our prop values match restriction = ( mapi.RES_CONTENT, # a property restriction ( mapi.FL_SUBSTRING | mapi.FL_IGNORECASE | mapi.FL_LOOSE, # fuzz level prop_tag, # of the given prop (prop_tag, prop_val))) # with given val rows = mapi.HrQueryAllRows( tab, (PR_ENTRYID, PR_STORE_ENTRYID), # columns to retrieve restriction, # only these rows None, # any sort order is fine 0) # any # of results is fine for row in rows: (tag, eid), (tag, store_eid) = row store = self.session.OpenMsgStore(0, store_eid, None, mapi_flags) item = store.OpenEntry(eid, None, mapi_flags) yield item
def DumpProps(driver, mapi_folder, subject, include_attach, shorten, get_large, stream=None): hr, data = mapi_folder.GetProps((PR_DISPLAY_NAME_A, ), 0) name = data[0][1] for item in driver.GetItemsWithValue(mapi_folder, PR_SUBJECT_A, subject): DumpItemProps(item, shorten, get_large, stream) if include_attach: print >> stream table = item.GetAttachmentTable(0) rows = mapi.HrQueryAllRows(table, (PR_ATTACH_NUM, ), None, None, 0) for row in rows: attach_num = row[0][1] print >> stream, \ "Dumping attachment (PR_ATTACH_NUM=%d)" % (attach_num,) attach = item.OpenAttach(attach_num, None, mapi.MAPI_DEFERRED_ERRORS) DumpItemProps(attach, shorten, get_large, stream) print >> stream print >> stream
from win32com.client import Dispatch from win32com.mapi import mapi from win32com.mapi.mapitags import * mapi.MAPIInitialize(None) logonFlags = mapi.MAPI_NO_MAIL | mapi.MAPI_EXTENDED session = mapi.MAPILogonEx(0, None, None, logonFlags) MAPI_SUBSYSTEM = 39 restriction = mapi.RES_PROPERTY, (mapi.RELOP_EQ, PR_RESOURCE_TYPE, (PR_RESOURCE_TYPE, MAPI_SUBSYSTEM)) table = session.GetStatusTable(0) rows = mapi.HrQueryAllRows( table, (PR_DISPLAY_NAME_A, ), # columns to retrieve restriction, # only these rows None, # any sort order is fine 0) # any # of results is fine assert len(rows) == 1, "Should be exactly one row" (tag, val), = rows[0] print "Profile name:", val