/** \details Test the RegisterNotification (0x29) operation This function: -# \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcnotif_RegisterNotification(struct mapitest *mt) { enum MAPISTATUS retval; bool ret; mapi_object_t obj_store; mapi_object_t obj_folder; struct mapi_session *session; uint32_t tcon; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Inbox folder */ mapi_object_init(&obj_folder); ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox); if (!ret) { return ret; } /* Step 3. Register notification */ session = mapi_object_get_session(&obj_store); retval = RegisterNotification(session); mapitest_print_retval(mt, "RegisterNotification"); if ( retval != MAPI_E_SUCCESS) { return false; } /* Step 4. Subscribe for notifications */ retval = Subscribe(&obj_store, &tcon, fnevObjectCopied, true, cb, NULL); mapitest_print_retval(mt, "Subscribe"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 5. Unsubscribe for notifications */ retval = Unsubscribe(mt->session, tcon); mapitest_print_retval(mt, "Unsubscribe"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 6. Cleanup */ mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; }
/** \details Test the QueryColumns (0x37) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Calls the QueryColumn operation -# Calls SetColumns on the test folder -# Checks that QueryColumns on the test folder is correct -# Cleans up \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_QueryColumns(struct mapitest *mt) { mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct SPropTagArray columns; struct mt_common_tf_ctx *context; uint32_t count; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. QueryColumns */ QueryColumns(&obj_htable, &columns); mapitest_print_retval(mt, "QueryColumns"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Get the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &count); mapitest_print_retval(mt, "GetContentsTable"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } if (count != 10) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count); /* This isn't a hard error for this test though, because it might be from a previous test failure. Clean up and try again */ } /* Step 4. QueryColumns on a contents folder */ QueryColumns(&(obj_test_folder), &columns); mapitest_print_retval(mt, "QueryColumns"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* TODO: check the return count against something */ mapitest_print(mt, "column count: %i\n", columns.cValues); /* Step 6. Release */ mapi_object_release(&obj_htable); mapi_object_release(&(obj_test_folder)); mapitest_common_cleanup(mt); return true; }
/** \details Logoff an Exchange store This function uninitializes the MAPI session associated to the object. \param obj_store pointer to the store object \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS Logoff(mapi_object_t *obj_store) { struct mapi_context *mapi_ctx; struct mapi_session *session; struct mapi_session *el; bool found = false; /* Sanity checks */ session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); for (el = mapi_ctx->session; el; el = el->next) { if (session == el) { found = true; mapi_object_release(obj_store); DLIST_REMOVE(mapi_ctx->session, el); MAPIFreeBuffer(session); break; } } return (found == true) ? MAPI_E_SUCCESS : MAPI_E_NOT_FOUND; }
/** \details Test the GetStatus (0x16) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Call GetStatus -# Cleans up */ _PUBLIC_ bool mapitest_oxctable_GetStatus(struct mapitest *mt) { bool ret = true; mapi_object_t obj_htable; uint8_t TableStatus; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. GetStatus */ GetStatus(&obj_htable, &TableStatus); mapitest_print_retval(mt, "GetStatus"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } else { mapitest_print(mt, "* %-35s: TableStatus: %d\n", "GetStatus", TableStatus); } /* Step 3. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; }
enum MAPISTATUS e_mapi_fast_transfer_properties (EMapiConnection *conn, TALLOC_CTX *mem_ctx, mapi_object_t *object, struct SPropTagArray *tags, TransferObjectCB cb, gpointer cb_user_data, GCancellable *cancellable, GError **perror) { enum MAPISTATUS ms; mapi_object_t fasttransfer_ctx; g_return_val_if_fail (tags != NULL, MAPI_E_INVALID_PARAMETER); g_return_val_if_fail (tags->cValues > 0, MAPI_E_INVALID_PARAMETER); mapi_object_init (&fasttransfer_ctx); ms = FXCopyProperties (object, 0, 0, FastTransfer_Unicode, tags, &fasttransfer_ctx); if (ms == MAPI_E_SUCCESS) ms = e_mapi_fast_transfer_internal (conn, mem_ctx, cb, cb_user_data, 1, FALSE, &fasttransfer_ctx, cancellable, perror); mapi_object_release (&fasttransfer_ctx); if (perror && !*perror && ms != MAPI_E_SUCCESS) make_mapi_error (perror, G_STRFUNC, ms); return ms; }
/** \details Test the SetColumns (0x12) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Calls the SetColumns operation -# Cleans up \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_SetColumns(struct mapitest *mt) { mapi_object_t obj_htable; struct SPropTagArray *SPropTagArray; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. SetColumns */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_FID, PR_FOLDER_CHILD_COUNT); SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval(mt, "SetColumns"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return true; }
/** \details Test the SeekRow (0x18) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# SeekRow with BOOKMARK_BEGINNING -# SeekRow with BOOKMARK_END -# SeekRow with BOOKMARK_CURRENT -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_SeekRow(struct mapitest *mt) { mapi_object_t obj_htable; uint32_t count; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. SeekRow */ SeekRow(&obj_htable, BOOKMARK_BEGINNING, 0, &count); mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_BEGINNING)"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SeekRow(&obj_htable, BOOKMARK_END, 0, &count); mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_END)"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SeekRow(&obj_htable, BOOKMARK_CURRENT, 0, &count); mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_CURRENT)"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return true; }
/** \details Test the SeekRowApprox (0x1a) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# SeekRowApprox with 0/1, 1/1 and 1/2 fractional values -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_SeekRowApprox(struct mapitest *mt) { mapi_object_t obj_htable; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. SeekRowApprox */ SeekRowApprox(&obj_htable, 0, 1); mapitest_print_retval_fmt(mt, "SeekRowApprox", "0/1"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SeekRowApprox(&obj_htable, 1, 1); mapitest_print_retval_fmt(mt, "SeekRowApprox", "1/1"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SeekRowApprox(&obj_htable, 1, 2); mapitest_print_retval_fmt(mt, "SeekRowApprox", "1/2"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return true; }
enum MAPISTATUS e_mapi_fast_transfer_objects (EMapiConnection *conn, TALLOC_CTX *mem_ctx, mapi_object_t *obj_folder, mapi_id_array_t *ids, TransferObjectCB cb, gpointer cb_user_data, GCancellable *cancellable, GError **perror) { enum MAPISTATUS ms; mapi_object_t fasttransfer_ctx; mapi_object_init (&fasttransfer_ctx); ms = FXCopyMessages (obj_folder, ids, FastTransferCopyMessage_BestBody, FastTransfer_Unicode, &fasttransfer_ctx); if (ms == MAPI_E_SUCCESS) ms = e_mapi_fast_transfer_internal (conn, mem_ctx, cb, cb_user_data, ids->count, TRUE, &fasttransfer_ctx, cancellable, perror); mapi_object_release (&fasttransfer_ctx); if (perror && !*perror && ms != MAPI_E_SUCCESS) make_mapi_error (perror, G_STRFUNC, ms); return ms; }
folder::message_container_type folder::fetch_messages() throw(mapi_exception) { uint32_t contents_table_row_count = 0; mapi_object_t contents_table; mapi_object_init(&contents_table); if (GetContentsTable(&m_object, &contents_table, 0, &contents_table_row_count) != MAPI_E_SUCCESS) { mapi_object_release(&contents_table); throw mapi_exception(GetLastError(), "folder::fetch_messages : GetContentsTable"); } SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x2, PR_FID, PR_MID); if (SetColumns(&contents_table, property_tag_array) != MAPI_E_SUCCESS) { MAPIFreeBuffer(property_tag_array); mapi_object_release(&contents_table); throw mapi_exception(GetLastError(), "folder::fetch_messages : SetColumns"); } MAPIFreeBuffer(property_tag_array); uint32_t rows_to_read = contents_table_row_count; SRowSet row_set; message_container_type message_container; message_container.reserve(contents_table_row_count); while( (QueryRows(&contents_table, rows_to_read, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) { rows_to_read -= row_set.cRows; for (unsigned int i = 0; i < row_set.cRows; ++i) { try { message_container.push_back(message_shared_ptr(new message(m_session, m_id, row_set.aRow[i].lpProps[1].value.d))); } catch(mapi_exception e) { mapi_object_release(&contents_table); throw; } } } mapi_object_release(&contents_table); return message_container; }
/** \details Test the CreateBookmark (0x1b) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Customize the MAPI table view -# CreateBookmark for each table's row -# Free Bookmark for each created bookmark -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_CreateBookmark(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_htable; uint32_t *bkPosition; uint32_t count; uint32_t i; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Customize the table view */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_FID, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3. Create Bookmarks */ bkPosition = talloc_array(mt->mem_ctx, uint32_t, 1); retval = QueryRows(&obj_htable, 100, TBL_ADVANCE, &SRowSet); for (i = 0; i < SRowSet.cRows; i++) { bkPosition = talloc_realloc(mt->mem_ctx, bkPosition, uint32_t, i + 2); retval = CreateBookmark(&obj_htable, &(bkPosition[i])); mapitest_print_retval_fmt_clean(mt, "CreateBookmark", retval, "(%.2d)", i); if (retval != MAPI_E_SUCCESS) { return false; } } retval = mapi_object_bookmark_get_count(&obj_htable, &count); /* Step 4. Free Bookmarks */ for (i = 0; i < count; i++) { retval = FreeBookmark(&obj_htable, bkPosition[i]); mapitest_print_retval_fmt_clean(mt, "FreeBookmark", retval, "(%.2d)", i); if (retval != MAPI_E_SUCCESS) { return false; } } /* Step 5. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); talloc_free(bkPosition); return true; }
attachment::attachment(message& mapi_message, const uint32_t attach_num) throw(mapi_exception) : object(mapi_message.get_session(), "attachment"), m_attach_num(attach_num), m_bin_data(NULL), m_data_size(0), m_filename("") { if (OpenAttach(&mapi_message.data(), attach_num, &m_object) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "attachment::attachment : OpenAttach"); property_container properties = get_property_container(); properties << PR_ATTACH_FILENAME << PR_ATTACH_LONG_FILENAME << PR_ATTACH_SIZE << PR_ATTACH_DATA_BIN << PR_ATTACH_METHOD; properties.fetch(); const char* filename = static_cast<const char*>(properties[PR_ATTACH_LONG_FILENAME]); if (!filename) { filename = static_cast<const char*>(properties[PR_ATTACH_FILENAME]); } if (filename) m_filename = filename; m_data_size = *(static_cast<const uint32_t*>(properties[PR_ATTACH_SIZE])); const Binary_r* attachment_data = static_cast<const Binary_r*>(properties[PR_ATTACH_DATA_BIN]); // Don't load PR_ATTACH_DATA_BIN if it's embedded in message. // NOTE: Use RopOpenEmbeddedMessage when it is implemented. const uint32_t attach_method = *static_cast<const uint32_t*>(properties[PR_ATTACH_METHOD]); if (attach_method != ATTACH_BY_VALUE) return; // Get Binary Data. if (attachment_data) { m_data_size = attachment_data->cb; m_bin_data = new uint8_t[m_data_size]; memcpy(m_bin_data, attachment_data->lpb, attachment_data->cb); } else { mapi_object_t obj_stream; mapi_object_init(&obj_stream); if (OpenStream(&m_object, (enum MAPITAGS)PidTagAttachDataBinary, OpenStream_ReadOnly, &obj_stream) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "attachment::attachment : OpenStream"); if (GetStreamSize(&obj_stream, &m_data_size) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "attachment::attachment : GetStreamSize"); m_bin_data = new uint8_t[m_data_size]; uint32_t pos = 0; uint16_t bytes_read = 0; do { if (ReadStream(&obj_stream, m_bin_data+pos, 1024, &bytes_read) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "attachment::attachment : ReadStream"); pos += bytes_read; } while (bytes_read && pos < m_data_size); mapi_object_release(&obj_stream); } }
folder::hierarchy_container_type folder::fetch_hierarchy() throw(mapi_exception) { mapi_object_t hierarchy_table; uint32_t hierarchy_table_row_count = 0; mapi_object_init(&hierarchy_table); if (GetHierarchyTable(&m_object, &hierarchy_table, 0, &hierarchy_table_row_count) != MAPI_E_SUCCESS) { mapi_object_release(&hierarchy_table); throw mapi_exception(GetLastError(), "folder::fetch_hierarchy : GetHierarchyTable"); } SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x1, PR_FID); if (SetColumns(&hierarchy_table, property_tag_array)) { MAPIFreeBuffer(property_tag_array); mapi_object_release(&hierarchy_table); throw mapi_exception(GetLastError(), "folder::fetch_hierarchy : SetColumns"); } MAPIFreeBuffer(property_tag_array); uint32_t rows_to_read = hierarchy_table_row_count; SRowSet row_set; hierarchy_container_type hierarchy_container; hierarchy_container.reserve(hierarchy_table_row_count); while( (QueryRows(&hierarchy_table, rows_to_read, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) { rows_to_read -= row_set.cRows; for (unsigned int i = 0; i < row_set.cRows; ++i) { try { hierarchy_container.push_back(folder_shared_ptr(new folder(*this, row_set.aRow[i].lpProps[0].value.d))); } catch(mapi_exception e) { mapi_object_release(&hierarchy_table); throw; } } } mapi_object_release(&hierarchy_table); return hierarchy_container; }
/** \details Test the SyncOpenAdvisor (0x83) and SetSyncNotificationGuid (0x88) operations This function: -# logs on -# creates a notification advisor -# sets a GUID on the advisor -# cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcnotif_SyncOpenAdvisor(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_notifier; mapi_object_init(&obj_store); mapi_object_init(&obj_notifier); /* Logon */ retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_clean(mt, "OpenMsgStore", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Create advisor */ retval = SyncOpenAdvisor(&obj_store, &obj_notifier); mapitest_print_retval_clean(mt, "SyncOpenAdvisor", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Set GUID */ retval = SetSyncNotificationGuid(&obj_notifier, GUID_random()); mapitest_print_retval_clean(mt, "SetSyncNotificationGuid", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Cleanup */ cleanup: mapi_object_release(&obj_notifier); mapi_object_release(&obj_store); return ret; }
message::attachment_container_type message::fetch_attachments() { mapi_object_t attachment_table; mapi_object_init(&attachment_table); if (GetAttachmentTable(&m_object, &attachment_table) != MAPI_E_SUCCESS) { mapi_object_release(&attachment_table); throw mapi_exception(GetLastError(), "message::fetch_attachments : GetAttachmentTable"); } SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x1, PR_ATTACH_NUM); if (SetColumns(&attachment_table, property_tag_array) != MAPI_E_SUCCESS) { MAPIFreeBuffer(property_tag_array); mapi_object_release(&attachment_table); throw mapi_exception(GetLastError(), "message::fetch_attachments : SetColumns"); } MAPIFreeBuffer(property_tag_array); SRowSet row_set; attachment_container_type attachment_container; while( (QueryRows(&attachment_table, 0x32, TBL_ADVANCE, TBL_FORWARD_READ, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) { for (unsigned int i = 0; i < row_set.cRows; ++i) { try { attachment_container.push_back(attachment_shared_ptr(new attachment(*this, row_set.aRow[i].lpProps[0].value.l))); } catch(mapi_exception e) { mapi_object_release(&attachment_table); throw; } } } mapi_object_release(&attachment_table); return attachment_container; }
enum MAPISTATUS e_mapi_fast_transfer_object (EMapiConnection *conn, TALLOC_CTX *mem_ctx, mapi_object_t *object, guint32 transfer_flags, /* bit or of EMapiFastTransferFlags */ TransferObjectCB cb, gpointer cb_user_data, GCancellable *cancellable, GError **perror) { enum MAPISTATUS ms; mapi_object_t fasttransfer_ctx; struct SPropTagArray *excludes = NULL; mapi_object_init (&fasttransfer_ctx); #define add(x) { \ if (!excludes) \ excludes = set_SPropTagArray (mem_ctx, 0x1, x); \ else \ SPropTagArray_add (mem_ctx, excludes, x); \ } if (!(transfer_flags & E_MAPI_FAST_TRANSFER_FLAG_ATTACHMENTS)) add (PidTagMessageAttachments); if (!(transfer_flags & E_MAPI_FAST_TRANSFER_FLAG_RECIPIENTS)) add (PidTagMessageRecipients); #undef add if (!excludes) excludes = talloc_zero (mem_ctx, struct SPropTagArray); ms = FXCopyTo (object, 0, FastTransferCopyTo_BestBody, FastTransfer_Unicode, excludes, &fasttransfer_ctx); if (ms == MAPI_E_SUCCESS) ms = e_mapi_fast_transfer_internal (conn, mem_ctx, cb, cb_user_data, 1, FALSE, &fasttransfer_ctx, cancellable, perror); mapi_object_release (&fasttransfer_ctx); talloc_free (excludes); if (perror && !*perror && ms != MAPI_E_SUCCESS) make_mapi_error (perror, G_STRFUNC, ms); return ms; }
int main(int argc, char *argv[]) { enum MAPISTATUS retval; struct mapi_context *mapi_ctx; TALLOC_CTX *mem_ctx; struct mapi_session *session = NULL; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_table; mapi_object_t obj_message; struct mapi_SPropValue_array props_all; struct SRowSet rowset; struct SPropTagArray *SPropTagArray; mapi_id_t id_inbox; mapi_id_t *fid, *mid; char *profname; char *profdb; uint32_t Numerator; uint32_t Denominator; uint32_t i; mem_ctx = talloc_named(NULL, 0, "fetchmail"); /* Initialize MAPI */ profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); retval = MAPIInitialize(&mapi_ctx, profdb); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Find Default Profile */ retval = GetDefaultProfile(mapi_ctx, &profname); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Log on EMSMDB and NSPI */ retval = MapiLogonEx(mapi_ctx, &session, profname, NULL); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Open Message Store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Find Inbox default folder */ retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Open Inbox folder */ mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_inbox, &obj_folder); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Retrieve Inbox content table */ mapi_object_init(&obj_table); retval = GetContentsTable(&obj_folder, &obj_table, 0x0, NULL); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Create the MAPI table view */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); /* Get current cursor position */ retval = QueryPosition(&obj_table, &Numerator, &Denominator); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Iterate through rows */ while ((retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset)) != -1 && rowset.cRows) { for (i = 0; i < rowset.cRows; i++) { fid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_FID); mid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_MID); mapi_object_init(&obj_message); retval = OpenMessage(&obj_store, *fid, *mid, &obj_message, 0x0); if (retval != MAPI_E_NOT_FOUND) { retval = GetPropsAll(&obj_message, MAPI_UNICODE, &props_all); mapidump_message(&props_all, NULL, &obj_message); mapi_object_release(&obj_message); } } } /* Release MAPI objects */ mapi_object_release(&obj_table); mapi_object_release(&obj_folder); Logoff(&obj_store); /* Uninitialize MAPI */ MAPIUninitialize(mapi_ctx); return (0); }
static enum MAPISTATUS import_ocpf_file(TALLOC_CTX *mem_ctx, const struct mbox_data *mdata, mapi_object_t *obj_store, mapi_object_t *obj_folder, const char *base_path) { int ret; enum MAPISTATUS retval; mapi_object_t obj_message; uint32_t context_id; mapi_id_t folder_id; uint32_t cValues = 0; struct SPropValue *lpProps; DEBUG(4, ("[*] Importing OCPF file '%s'\n", base_path)); /* Initialize OCPF context */ ret = ocpf_init(); if (ret == -1) { DEBUG(0, ("[!] ocpf_init\n")); return MAPI_E_CALL_FAILED; } folder_id = mapi_object_get_id(obj_folder); if (folder_id == -1) { retval = MAPI_E_CALL_FAILED; DEBUG(0, ("[!] mapi_object_get_id: %s\n", mapi_get_errstr(retval))); return retval; } ret = ocpf_new_context(base_path, &context_id, OCPF_FLAGS_READ); if (ret == -1) { retval = MAPI_E_CALL_FAILED; DEBUG(0, ("[!] ocpf_new_context: %s\n", mapi_get_errstr(retval))); return retval; } ret = ocpf_parse(context_id); if (ret == -1) { retval = MAPI_E_CALL_FAILED; DEBUG(0, ("[!] ocpf_parse: %s\n", mapi_get_errstr(retval))); return retval; } /* Create the object */ mapi_object_init(&obj_message); retval = CreateMessage(obj_folder, &obj_message); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] CreateMessage: %s\n", mapi_get_errstr(retval))); mapi_object_release(&obj_message); return retval; } /* Set message recipients */ //retval = ocpf_set_Recipients(mem_ctx, context_id, &obj_message); //if (retval != MAPI_E_SUCCESS && GetLastError() != MAPI_E_NOT_FOUND) return false; //errno = MAPI_E_SUCCESS; /* Set message properties */ retval = ocpf_set_SPropValue(mem_ctx, context_id, obj_folder, &obj_message); if (retval == MAPI_W_ERRORS_RETURNED) { DEBUG(0, ("[!] ocpf_set_SPropValue: %s\n", mapi_get_errstr(retval))); } else if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] ocpf_set_SPropValue: %s\n", mapi_get_errstr(retval))); mapi_object_release(&obj_message); return retval; } /* Set message properties */ lpProps = ocpf_get_SPropValue(context_id, &cValues); retval = SetProps(&obj_message, 0, lpProps, cValues); MAPIFreeBuffer(lpProps); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] ocpf_get_SPropValue: %s\n", mapi_get_errstr(retval))); mapi_object_release(&obj_message); return retval; } retval = ocpf_server_set_folderID(context_id, folder_id); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] ocpf_server_set_folderIF: %s\n", mapi_get_errstr(retval))); mapi_object_release(&obj_message); return retval; } /* Save message */ retval = SaveChangesMessage(obj_folder, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] SaveChangesMessage: %s\n", mapi_get_errstr(retval))); return retval; } mapi_object_release(&obj_message); ocpf_del_context(context_id); ocpf_release(); return MAPI_E_SUCCESS; }
static enum MAPISTATUS import_directory(TALLOC_CTX *mem_ctx, const struct mbox_data *mdata, mapi_object_t *obj_store, mapi_object_t *obj_parent, const char *base_path) { enum MAPISTATUS retval; DIR *dirp; struct dirent *direntp; mapi_object_t obj_folder; mapi_object_t obj_inbox; mapi_object_t obj_child; mapi_id_t id_folder; char *folder_id; char *olFolderSrc; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t cValues = 0; struct SRow aRow; DEBUG(5,("[*] Importing directory %s\n", base_path)); /* Open the filesystem folder */ dirp = opendir(base_path); if (!dirp) { DEBUG(0, ("[!] Error opening directory %s: %s (%d)\n", base_path, strerror(errno), errno)); return MAPI_E_NOT_FOUND; // TODO map to proper code } mapi_object_init(&obj_folder); mapi_object_init(&obj_child); mapi_object_init(&obj_inbox); /* I want to get the folder ID from the remote Exchange server and check in the systemfolder database if it matches with something. we can get the remote folder ID from the directory name */ folder_id = import_get_folder_id(base_path); if (!folder_id) { DEBUG(0, ("[!] Error getting folder ID from directory name\n")); return MAPI_E_NOT_FOUND; // TODO map to proper code } if (!obj_parent) { DEBUG(5, ("parent is null\n")); retval = GetDefaultFolder(obj_store, &id_folder, olFolderInbox); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] GetDefaultFolder: %s\n", mapi_get_errstr(GetLastError()))); return retval; } DEBUG(4, ("[*] Opening folder %u\n", olFolderInbox)); retval = OpenFolder(obj_store, id_folder, &obj_inbox); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] OpenFolder: %s\n", mapi_get_errstr(GetLastError()))); return retval; } obj_parent = &obj_inbox; } /* XXX Begin of hack */ #if 0 olFolderSrc = import_is_system_folder(mdata, folder_id); if (!olFolderSrc) { DEBUG(5, ("[*] Not system folder, skip\n")); talloc_free(olFolderSrc); return MAPI_E_SUCCESS; } uint32_t olFolder = atoi(olFolderSrc); talloc_free(olFolderSrc); retval = MAPI_E_SUCCESS; if (olFolder == olFolderContacts) { retval = GetDefaultFolder(obj_store, &id_folder, olFolderContacts); } else if (olFolder == olFolderCalendar) { retval = GetDefaultFolder(obj_store, &id_folder, olFolderCalendar); } else if (olFolder == olFolderTopInformationStore) { retval = GetDefaultFolder(obj_store, &id_folder, olFolderInbox); } if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] GetDefaultFolder: %s\n", mapi_get_errstr(GetLastError()))); return retval; } DEBUG(4, ("Opening folder %u\n", olFolder)); retval = OpenFolder(obj_store, id_folder, &obj_folder); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] OpenFolder: %s\n", mapi_get_errstr(GetLastError()))); return retval; } #endif /* XXX end of hack */ #if 1 olFolderSrc = import_is_system_folder(mdata, folder_id); if (olFolderSrc) { char *folder_name = import_get_folder_name(mdata, folder_id); if (folder_name) { DEBUG(5, ("[*] Origin Folder '%s' mapped to name '%s'\n", folder_id, folder_name)); talloc_free(folder_name); folder_name = NULL; } /* This is a system folder, then I am calling GetDefaultFolder to retrieve the id then I open the folder */ uint32_t olFolder = atoi(olFolderSrc); talloc_free(olFolderSrc); retval = GetDefaultFolder(obj_store, &id_folder, olFolder); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] GetDefaultFolder: %s\n", mapi_get_errstr(GetLastError()))); return retval; } DEBUG(4, ("[*] Opening folder %u\n", olFolder)); retval = OpenFolder(obj_store, id_folder, &obj_folder); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] OpenFolder: %s\n", mapi_get_errstr(GetLastError()))); return retval; } SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PidTagDisplayName); retval = GetProps(&obj_folder, MAPI_UNICODE, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRow.cValues = cValues; aRow.lpProps = lpProps; folder_name = (char *) find_SPropValue_data(&aRow, PidTagDisplayName); if (folder_name) { DEBUG(5, ("[*] Destination Folder: '%s'\n", folder_name)); } } } else { /* this is not a system folder, I know what is the root base where need to create it i and open it */ char *folder_name = import_get_folder_name(mdata, folder_id); if (!folder_name) { DEBUG(0, ("[!] Invalid Folder Name\n")); return MAPI_E_INVALID_PARAMETER; } DEBUG(4, ("[*] Creating folder %s\n", folder_name)); retval = CreateFolder(obj_parent, FOLDER_GENERIC, folder_name, NULL, OPEN_IF_EXISTS|MAPI_UNICODE, &obj_folder); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("[!] CreateFolder: %s\n", mapi_get_errstr(GetLastError()))); talloc_free(folder_name); return retval; } talloc_free(folder_name); return MAPI_E_SUCCESS; } #endif /* Import the files and clildren folders */ while ((direntp = readdir(dirp)) != NULL) { if (strcmp(direntp->d_name, ".") == 0) { continue; } if (strcmp(direntp->d_name, "..") == 0) { continue; } char *ext = strrchr(direntp->d_name, '.'); if (!ext) { if (strncasecmp(direntp->d_name, "0x", 2) == 0) { char *child_path = talloc_asprintf(mem_ctx, "%s/%s", base_path, direntp->d_name); retval = import_directory(mem_ctx, mdata, obj_store, &obj_folder, child_path); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("import_directory failed with %s\n", mapi_get_errstr(GetLastError()))); talloc_free(child_path); return retval; } talloc_free(child_path); } continue; } if (strncasecmp(ext, ".ocpf", 5) == 0) { char *child_path = talloc_asprintf(mem_ctx, "%s/%s", base_path, direntp->d_name); import_ocpf_file(mem_ctx, mdata, obj_store, &obj_folder, child_path); talloc_free(child_path); } } mapi_object_release(&obj_folder); mapi_object_release(&obj_inbox); /* Close directory */ closedir(dirp); return retval; }
/** \details Test the QueryRows (0x15) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Set the required columns -# Calls QueryRows until the end of the table -# Open the test folder, and get its contents -# Calls QueryRows until the end of the test folder -# Checks the results are as expected. -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_QueryRows(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct SRowSet SRowSet; struct SPropTagArray *SPropTagArray; struct SPropValue lpProp; struct mt_common_tf_ctx *context; uint32_t idx = 0; uint32_t count = 0; const char* data; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Set Table Columns */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_FID, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "SetColumns"); return false; } /* Step 3. QueryRows */ do { retval = QueryRows(&obj_htable, 0x2, TBL_ADVANCE, &SRowSet); if (SRowSet.cRows > 0) { idx += SRowSet.cRows; if (retval == MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: %.2d/%.2d [PASSED]\n", "QueryRows", idx, count); } else { mapitest_print(mt, "* %-35s: %.2d/%.2d [FAILED]\n", "QueryRows", idx, count); } } } while (retval == MAPI_E_SUCCESS && SRowSet.cRows > 0); /* Step 4. Get the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &count); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "GetContentsTable"); return false; } if (count != 10) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count); /* This isn't a hard error for this test though, because it might be from a previous test failure. Clean up and try again */ } /* Step 5. Set Table Columns on the test folder */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_BODY, PR_MESSAGE_CLASS); retval = SetColumns(&obj_test_folder, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "SetColumns"); return false; } /* Step 6. QueryRows on test folder contents */ idx = 0; do { retval = QueryRows(&(obj_test_folder), 0x2, TBL_ADVANCE, &SRowSet); if (SRowSet.cRows > 0) { idx += SRowSet.cRows; if (retval == MAPI_E_SUCCESS) { uint32_t i; mapitest_print(mt, "* %-35s: %.2d/%.2d [PASSED]\n", "QueryRows", idx, count); for (i = 0; i < SRowSet.cRows; ++i) { lpProp = SRowSet.aRow[i].lpProps[0]; if (lpProp.ulPropTag != PR_BODY) { mapitest_print(mt, "* %-35s: Bad proptag0 (0x%x)\n", "QueryRows", lpProp.ulPropTag); return false; } data = get_SPropValue_data(&lpProp); if (0 != strncmp(data, "Body of message", 15)) { mapitest_print(mt, "* %-35s: Bad propval0 (%s)\n", "QueryRows", data); return false; } lpProp = SRowSet.aRow[i].lpProps[1]; if (lpProp.ulPropTag != PR_MESSAGE_CLASS) { mapitest_print(mt, "* %-35s: Bad proptag1 (0x%x)\n", "QueryRows", lpProp.ulPropTag); return false; } data = get_SPropValue_data(&lpProp); if (0 != strncmp(data, "IPM.Note", 8)) { mapitest_print(mt, "* %-35s: Bad propval1 (%s)\n", "QueryRows", data); return false; } } } else { mapitest_print(mt, "* %-35s: %.2d/%.2d [FAILED]\n", "QueryRows", idx, count); } } } while (retval == MAPI_E_SUCCESS && SRowSet.cRows > 0); /* Release */ mapi_object_release(&obj_htable); mapi_object_release(&(obj_test_folder)); mapitest_common_cleanup(mt); return true; }
/** \details Test the Restrict (0x14) operation This function: -# Opens the Inbox folder and creates some test content -# Checks that the content is OK -# Applies a filter -# Checks the results are as expected. -# Resets the table -# Checks the results are as expected. -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_Restrict(struct mapitest *mt) { mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct mt_common_tf_ctx *context; uint32_t count = 0; uint32_t origcount = 0; uint32_t Numerator = 0; uint32_t Denominator = 0; struct mapi_SRestriction res; bool ret = true; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Get the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &origcount); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "GetContentsTable"); ret = false; goto cleanup; } if (origcount != 10) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count); /* This isn't a hard error for this test though, because it might be from a previous test failure. Clean up and try again */ } /* Apply a filter */ res.rt = RES_PROPERTY; res.res.resProperty.relop = RES_PROPERTY; res.res.resProperty.ulPropTag = PR_SUBJECT; res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT; res.res.resProperty.lpProp.value.lpszA = MT_MAIL_SUBJECT; Restrict(&(obj_test_folder), &res, NULL); mapitest_print_retval(mt, "Restrict"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ context = mt->priv; QueryPosition(&(obj_test_folder), &Numerator, &Denominator); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "QueryPosition"); ret = false; goto cleanup; } if (Denominator != origcount/2) { mapitest_print(mt, "* %-35s: unexpected filtered count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } /* Resets the table */ Reset(&(obj_test_folder)); mapitest_print_retval(mt, "Reset"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ context = mt->priv; QueryPosition(&(obj_test_folder), &Numerator, &Denominator); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "QueryPosition"); ret = false; goto cleanup; } if (Denominator != origcount) { mapitest_print(mt, "* %-35s: unexpected reset count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_htable); mapi_object_release(&(obj_test_folder)); mapitest_common_cleanup(mt); return ret; }
void import_mailbox(TALLOC_CTX *mem_ctx, struct mapi_session *session, struct mbox_data *mdata) { enum MAPISTATUS retval; struct dirent *direntp; DIR *dirp; mapi_object_t obj_store; char *base_path; mdata->start_time = time(NULL); base_path = talloc_asprintf(mem_ctx, "%s/%s", DEFAULT_EXPORT_PATH, mdata->username); if (!base_path) { goto fail; } /* Open systemfolder database */ mdata->tdb_sysfolder = tdb_open_database(mdata, base_path, TDB_SYSFOLDER); if (!mdata->tdb_sysfolder) { DEBUG(0, ("[!] Error opening system folder db\n")); goto fail; } /* Open PidTagFolderID to FolderName database */ mdata->tdb_foldermap = tdb_open_database(mdata, base_path, TDB_FOLDERMAP); if (!mdata->tdb_foldermap) { DEBUG(0, ("[!] Error opening id mapping db\n")); goto fail; } /* Open the folder */ dirp = opendir(base_path); if (!dirp) { DEBUG(0, ("[!] Error opening directory %s: %s (%d)\n", base_path, strerror(errno), errno)); goto fail; } /* Open the root folder */ mapi_object_init(&obj_store); retval = OpenUserMailbox(session, mdata->username, &obj_store); if (retval != MAPI_E_SUCCESS) { const char *error = mapi_get_errstr(GetLastError()); DEBUG(0, ("[!] OpenUserMailbox: %s\n", error)); goto fail; } /* Import the directory */ while ((direntp = readdir(dirp)) != NULL) { if (strncasecmp(direntp->d_name, "0x", 2) == 0) { /* This is the root folder */ char *path = talloc_asprintf(mem_ctx, "%s/%s", base_path, direntp->d_name); retval = import_directory(mem_ctx, mdata, &obj_store, NULL, path); if (retval != MAPI_E_SUCCESS) { DEBUG(0, ("import_directory failed with %s\n", mapi_get_errstr(GetLastError()))); break; } talloc_free(path); break; } } fail: mapi_object_release(&obj_store); if (dirp) closedir(dirp); if (mdata->tdb_foldermap) { tdb_close(mdata->tdb_foldermap); mdata->tdb_foldermap = NULL; } if (mdata->tdb_sysfolder) { tdb_close(mdata->tdb_sysfolder); mdata->tdb_sysfolder = NULL; } if (base_path) talloc_free(base_path); mdata->end_time = time(NULL); return; }
/** \details Test the SortTable (0x13), ExpandRow (0x59), CollapseRow(0x5a), GetCollapseState(0x6b) and SetCollapseState (0x6c) operations This function: -# Opens the Inbox folder and creates some test content -# Checks that the content is OK -# Applies a sort and categorisation -# Checks the results are as expected. -# Save away the Row ID and Insatnce Number for the first header -# Collapse the first category -# Checks the results are as expected. -# Save the "collapse state" -# Expand the first category again -# Checks the results are as expected -# Restore the saved "collapse state" -# Checks the results are as expected -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_Category(struct mapitest *mt) { mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct mt_common_tf_ctx *context; uint32_t count = 0; uint32_t origcount = 0; bool ret = true; struct SSortOrderSet criteria; uint64_t inst_id = 0; uint64_t inst_num = 0; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t rowcount = 0; uint32_t Numerator = 0; uint32_t Denominator = 0; struct SBinary_short collapseState; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Get the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &origcount); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "GetContentsTable"); ret = false; goto cleanup; } if (origcount != 10) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count); /* This isn't a hard error for this test though, because it might be from a previous test failure. Clean up and try again */ } /* We need the header row InstanceId to fold/unfold the headers */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6, PR_SENDER_NAME, PR_BODY, PR_LAST_MODIFICATION_TIME, PR_SUBJECT, PR_INST_ID, PR_INSTANCE_NUM); SetColumns(&(obj_test_folder), SPropTagArray); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval(mt, "SetColumns"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Apply a categorised sort */ memset(&criteria, 0x0, sizeof (struct SSortOrderSet)); criteria.cSorts = 1; criteria.cCategories = 1; criteria.cExpanded = 1; criteria.aSort = talloc_array(mt->mem_ctx, struct SSortOrder, criteria.cSorts); criteria.aSort[0].ulPropTag = PR_SENDER_NAME; criteria.aSort[0].ulOrder = TABLE_SORT_ASCEND; SortTable(&(obj_test_folder), &criteria); mapitest_print_retval(mt, "SortTable"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } rowcount = 2 * origcount; QueryRows(&(obj_test_folder), rowcount, TBL_ADVANCE, &SRowSet); mapitest_print_retval(mt, "QueryRows"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ QueryPosition(&(obj_test_folder), &Numerator, &Denominator); mapitest_print_retval(mt, "QueryPosition"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* the categories are expanded, and there are six unique senders, so there are six extra rows - one for each header row */ if (Denominator != origcount + 6) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Numerator); ret = false; goto cleanup; } /* save away ID/instance values for first row header */ inst_id = (*(const uint64_t *)get_SPropValue_data(&(SRowSet.aRow[0].lpProps[4]))); inst_num = (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[0].lpProps[5]))); /* Collapse a row header */ CollapseRow(&(obj_test_folder), inst_id, &rowcount); mapitest_print_retval(mt, "CollapseRow"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ QueryPosition(&(obj_test_folder), &Numerator, &Denominator); mapitest_print_retval(mt, "QueryPosition"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* there are still six unique headers, but half of the real entries are under the first header (usually 10, unless we have some other rubbish hanging around), and when we collapse the first header row, that half disappear */ if (Denominator != origcount/2 + 6) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } /* Save the table collapse state */ GetCollapseState(&(obj_test_folder), inst_id, inst_num, &collapseState); mapitest_print_retval(mt, "GetCollapseState"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Expand a category */ ExpandRow(&(obj_test_folder), inst_id, 20, &SRowSet, &rowcount); mapitest_print_retval(mt, "ExpandRow"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ QueryPosition(&(obj_test_folder), &Numerator, &Denominator); mapitest_print_retval(mt, "QueryPosition"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* we've expanded the first header row, so we now get all the entries plus the 6 headers */ if (Denominator != origcount + 6) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } /* Restore the collapse state */ SetCollapseState(&(obj_test_folder), &collapseState); mapitest_print_retval(mt, "SetCollapseState"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ QueryPosition(&(obj_test_folder), &Numerator, &Denominator); mapitest_print_retval(mt, "QueryPosition"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* back to the situation with the first heading collapsed */ if (Denominator != origcount/2 + 6) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_htable); mapi_object_release(&(obj_test_folder)); mapitest_common_cleanup(mt); return ret; }
void ical_property_ATTACH(struct exchange2ical *exchange2ical) { mapi_object_t obj_tb_attach; mapi_object_t obj_attach; mapi_object_t obj_stream; struct SRowSet rowset_attach; struct SPropTagArray *SPropTagArray = NULL; const uint32_t *attach_num = NULL; struct SPropValue *lpProps; enum MAPISTATUS retval; unsigned int i; uint32_t count; struct SRow aRow2; mapi_object_init(&obj_tb_attach); retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_tb_attach, SPropTagArray); MAPIFreeBuffer(SPropTagArray); retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach); for (i = 0; i < rowset_attach.cRows; i++) { attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM); retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x7, PR_ATTACH_FILENAME, PR_ATTACH_LONG_FILENAME, PR_ATTACH_METHOD, PR_ATTACHMENT_FLAGS, PR_ATTACHMENT_HIDDEN, PR_ATTACH_MIME_TAG, PR_ATTACH_DATA_BIN ); lpProps = NULL; retval = GetProps(&obj_attach, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { uint32_t *attachmentFlags = NULL; uint32_t *attachMethod = NULL; uint8_t *attachmentHidden = NULL; const char *data = NULL; const char *fmttype = NULL; const char *attach_filename = NULL; DATA_BLOB body; icalattach *icalattach = NULL; icalproperty *prop = NULL; icalparameter *param = NULL; aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; attachmentFlags = octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS); attachMethod = octool_get_propval(&aRow2, PR_ATTACH_METHOD); attachmentHidden = octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN); if(attachmentFlags && !(*attachmentFlags & 0x00000007) && (*attachMethod == 0x00000001) && (!attachmentHidden || !(*attachmentHidden))) { /* Get data of attachment */ retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream); retval = octool_get_stream(exchange2ical->mem_ctx, &obj_stream, &body); data=ldb_base64_encode(exchange2ical->mem_ctx, (const char *)body.data, body.length); /*Create a new icalattach from above data*/ #if HAVE_ICAL_0_46 /* the function signature for icalattach_new_from_data() changed in 0.46, released 2010-08-30 */ /* we can switch to just using the new signature after everyone has had a reasonable chance to update (say end of 2011) */ icalattach = icalattach_new_from_data(data, 0, 0); #else icalattach = icalattach_new_from_data((unsigned char *)data,0,0); #endif /*Add attach property to vevent component*/ prop = icalproperty_new_attach(icalattach); icalcomponent_add_property(exchange2ical->vevent, prop); /* Attachment filename for X-FILENAME parameter*/ attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_LONG_FILENAME)); if (!attach_filename || (attach_filename && !strcmp(attach_filename, ""))) { attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_FILENAME)); } /* fmttype parameter */ fmttype = (const char *) octool_get_propval(&aRow2, PR_ATTACH_MIME_TAG); if(fmttype) { param = icalparameter_new_fmttype(fmttype); icalproperty_add_parameter(prop, param); } /* ENCODING parameter */ param =icalparameter_new_encoding(ICAL_ENCODING_BASE64); icalproperty_add_parameter(prop,param); /* VALUE parameter */ param=icalparameter_new_value(ICAL_VALUE_BINARY); icalproperty_add_parameter(prop,param); /* X-FILENAME parameter */ param = icalparameter_new_x(attach_filename); icalparameter_set_xname(param,"X-FILENAME"); icalproperty_add_parameter(prop,param); } MAPIFreeBuffer(lpProps); } } } } mapi_object_release(&obj_tb_attach); }
static uint32_t _module_fetchmail_run(TALLOC_CTX *mem_ctx, struct mapi_session *session) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_inbox; mapi_object_t obj_table; mapi_object_t obj_message; mapi_object_t obj_table_attach; mapi_object_t obj_attach; mapi_object_t obj_stream; uint64_t id_inbox = 0; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; struct SRowSet SRowSet_attach; uint32_t i, j; uint32_t count; const uint8_t *has_attach; const uint32_t *attach_num; uint16_t read_size; unsigned char buf[MAX_READ_SIZE]; /* Log onto the store */ memset(&obj_store, 0, sizeof(mapi_object_t)); memset(&obj_inbox, 0, sizeof(mapi_object_t)); memset(&obj_table, 0, sizeof(mapi_object_t)); memset(&obj_message, 0, sizeof(mapi_object_t)); memset(&obj_table_attach, 0, sizeof(mapi_object_t)); memset(&obj_attach, 0, sizeof(mapi_object_t)); memset(&obj_stream, 0, sizeof(mapi_object_t)); mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); if (retval) { mapi_errstr("OpenMsgStore", GetLastError()); return OCSIM_ERROR; } /* Open default receive folder (Inbox) */ retval = GetReceiveFolder(&obj_store, &id_inbox, NULL); if (retval) { mapi_errstr("GetReceiveFolder", GetLastError()); return OCSIM_ERROR; } retval = OpenFolder(&obj_store, id_inbox, &obj_inbox); if (retval) { mapi_errstr("OpenFolder", GetLastError()); return OCSIM_ERROR; } /* Open the contents table and customize the view */ mapi_object_init(&obj_table); retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count); if (retval) { mapi_errstr("GetContentsTable", GetLastError()); return OCSIM_ERROR; } SPropTagArray = set_SPropTagArray(mem_ctx, 0x5, PR_FID, PR_MID, PR_INST_ID, PR_INSTANCE_NUM, PR_SUBJECT); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval) { mapi_errstr("SetColumns", GetLastError()); return OCSIM_ERROR; } /* Retrieve the messages and attachments */ while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) { count -= SRowSet.cRows; for (i = 0; i < SRowSet.cRows; i++) { mapi_object_init(&obj_message); retval = OpenMessage(&obj_store, SRowSet.aRow[i].lpProps[0].value.d, SRowSet.aRow[i].lpProps[0].value.d, &obj_message, 0); if (GetLastError() == MAPI_E_SUCCESS) { struct SPropValue *lpProps; struct SRow aRow; SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_HASATTACH); lpProps = talloc_zero(mem_ctx, struct SPropValue); retval = GetProps(&obj_message, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval) { mapi_errstr("GetProps", GetLastError()); return OCSIM_ERROR; } aRow.ulAdrEntryPad = 0; aRow.cValues = count; aRow.lpProps = lpProps; retval = fetchmail_get_contents(mem_ctx, &obj_message); has_attach = (const uint8_t *) get_SPropValue_SRow_data(&aRow, PR_HASATTACH); if (has_attach && *has_attach) { mapi_object_init(&obj_table_attach); retval = GetAttachmentTable(&obj_message, &obj_table_attach); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_table_attach, SPropTagArray); if (retval != MAPI_E_SUCCESS) return retval; MAPIFreeBuffer(SPropTagArray); retval = QueryRows(&obj_table_attach, 0xA, TBL_ADVANCE, &SRowSet_attach); if (retval != MAPI_E_SUCCESS) return retval; for (j = 0; j < SRowSet_attach.cRows; j++) { attach_num = (const uint32_t *) find_SPropValue_data(&(SRowSet_attach.aRow[j]), PR_ATTACH_NUM); mapi_object_init(&obj_attach); retval = OpenAttach(&obj_message, *attach_num, &obj_attach); if (retval == MAPI_E_SUCCESS) { struct SPropValue *lpProps2; uint32_t count2; SPropTagArray = set_SPropTagArray(mem_ctx, 0x3, PR_ATTACH_FILENAME, PR_ATTACH_LONG_FILENAME, PR_ATTACH_SIZE); lpProps2 = talloc_zero(mem_ctx, struct SPropValue); retval = GetProps(&obj_attach, 0, SPropTagArray, &lpProps2, &count2); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(lpProps2); return retval; } MAPIFreeBuffer(lpProps2); mapi_object_init(&obj_stream); retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream); if (retval != MAPI_E_SUCCESS) return retval; read_size = 0; do { retval = ReadStream(&obj_stream, buf, MAX_READ_SIZE, &read_size); if (retval != MAPI_E_SUCCESS) break; } while (read_size); mapi_object_release(&obj_stream); mapi_object_release(&obj_attach); } } } } MAPIFreeBuffer(lpProps); } mapi_object_release(&obj_message); }
icalcomponent * _Exchange2Ical(mapi_object_t *obj_folder, struct exchange2ical_check *exchange2ical_check) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; int ret; struct SRowSet SRowSet; struct SRow aRow; struct SRow aRowT; struct SPropValue *lpProps; struct SPropTagArray *SPropTagArray = NULL; struct exchange2ical exchange2ical; mapi_object_t obj_table; uint32_t count; int i; mem_ctx = talloc_named(mapi_object_get_session(obj_folder), 0, "exchange2ical"); exchange2ical_init(mem_ctx, &exchange2ical); /* Open the contents table */ mapi_object_init(&obj_table); retval = GetContentsTable(obj_folder, &obj_table, 0, &count); if (retval != MAPI_E_SUCCESS){ talloc_free(mem_ctx); return NULL; } OC_DEBUG(0, "MAILBOX (%d appointments)", count); if (count == 0) { talloc_free(mem_ctx); return NULL; } SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapi_errstr("SetColumns", retval); talloc_free(mem_ctx); return NULL; } while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, TBL_FORWARD_READ, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) { count -= SRowSet.cRows; for (i = (SRowSet.cRows-1); i >= 0; i--) { mapi_object_init(&exchange2ical.obj_message); retval = OpenMessage(obj_folder, SRowSet.aRow[i].lpProps[0].value.d, SRowSet.aRow[i].lpProps[1].value.d, &exchange2ical.obj_message, 0); if (retval != MAPI_E_NOT_FOUND) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x30, PidLidGlobalObjectId, PidNameKeywords, PidLidRecurring, PidLidAppointmentRecur, PidLidAppointmentStateFlags, PidLidTimeZoneDescription, PidLidTimeZoneStruct, PidLidContacts, PidLidAppointmentStartWhole, PidLidAppointmentEndWhole, PidLidAppointmentSubType, PidLidOwnerCriticalChange, PidLidLocation, PidLidNonSendableBcc, PidLidAppointmentSequence, PidLidBusyStatus, PidLidIntendedBusyStatus, PidLidAttendeeCriticalChange, PidLidAppointmentReplyTime, PidLidAppointmentNotAllowPropose, PidLidAllowExternalCheck, PidLidAppointmentLastSequence, PidLidAppointmentSequenceTime, PidLidAutoFillLocation, PidLidAutoStartCheck, PidLidCollaborateDoc, PidLidConferencingCheck, PidLidConferencingType, PidLidDirectory, PidLidMeetingWorkspaceUrl, PidLidNetShowUrl, PidLidOnlinePassword, PidLidOrganizerAlias, PidLidReminderSet, PidLidReminderDelta, PidLidResponseStatus, PR_MESSAGE_CLASS_UNICODE, PR_SENSITIVITY, PR_BODY_UNICODE, PR_CREATION_TIME, PR_LAST_MODIFICATION_TIME, PR_IMPORTANCE, PR_RESPONSE_REQUESTED, PR_SUBJECT_UNICODE, PR_OWNER_APPT_ID, PR_SENDER_NAME, PR_SENDER_EMAIL_ADDRESS, PR_MESSAGE_LOCALE_ID ); retval = GetProps(&exchange2ical.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRow.ulAdrEntryPad = 0; aRow.cValues = count; aRow.lpProps = lpProps; /*Get Vcal info if first event*/ if(i==(SRowSet.cRows-1)){ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, VcalFlag); /*TODO: exit nicely*/ ical_component_VCALENDAR(&exchange2ical); } /*Get required properties to check if right event*/ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, exchange2ical_check->eFlags); /*Check to see if event is acceptable*/ if (!checkEvent(&exchange2ical, exchange2ical_check, get_tm_from_FILETIME(exchange2ical.apptStartWhole))){ continue; } /*Set RecipientTable*/ retval = GetRecipientTable(&exchange2ical.obj_message, &exchange2ical.Recipients.SRowSet, &exchange2ical.Recipients.SPropTagArray); /*Set PR_BODY_HTML for x_alt_desc property*/ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_BODY_HTML_UNICODE); retval = GetProps(&exchange2ical.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRowT.ulAdrEntryPad = 0; aRowT.cValues = count; aRowT.lpProps = lpProps; exchange2ical.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE); } /*Get rest of properties*/ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, (exchange2ical_check->eFlags | EntireFlag)); /*add new vevent*/ ical_component_VEVENT(&exchange2ical); /*Exceptions to event*/ if(exchange2ical_check->eFlags != EventFlag){ ret = exchange2ical_exception_from_EmbeddedObj(&exchange2ical, exchange2ical_check); if (ret){ ret=exchange2ical_exception_from_ExceptionInfo(&exchange2ical, exchange2ical_check); } } /*REMOVE once globalobjid is fixed*/ exchange2ical.idx++; MAPIFreeBuffer(lpProps); exchange2ical_reset(&exchange2ical); } } mapi_object_release(&exchange2ical.obj_message); } } icalcomponent *icalendar = exchange2ical.vcalendar; exchange2ical_clear(&exchange2ical); /* Uninitialize MAPI subsystem */ mapi_object_release(&obj_table); talloc_free(mem_ctx); return icalendar; }
static uint8_t exchange2ical_exception_from_EmbeddedObj(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check) { mapi_object_t obj_tb_attach; mapi_object_t obj_attach; struct SRowSet rowset_attach; struct SPropTagArray *SPropTagArray; const uint32_t *attach_num; struct SPropValue *lpProps; enum MAPISTATUS retval; unsigned int i; uint32_t count; struct SRow aRow2; struct SRow aRowT; mapi_object_init(&obj_tb_attach); retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_tb_attach, SPropTagArray); MAPIFreeBuffer(SPropTagArray); retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, TBL_FORWARD_READ, &rowset_attach); for (i = 0; i < rowset_attach.cRows; i++) { attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM); retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x3, PR_ATTACH_METHOD, PR_ATTACHMENT_FLAGS, PR_ATTACHMENT_HIDDEN ); lpProps = NULL; retval = GetProps(&obj_attach, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { return 1; }else { aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; uint32_t *attachmentFlags; uint32_t *attachMethod; uint8_t *attachmentHidden; attachmentFlags = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS); attachMethod = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACH_METHOD); attachmentHidden = (uint8_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN); if(attachmentFlags && (*attachmentFlags & 0x00000002) && (*attachMethod == 0x00000005) && (attachmentHidden && (*attachmentHidden))) { struct exchange2ical exception; exchange2ical_init(exchange2ical->mem_ctx,&exception); mapi_object_init(&exception.obj_message); retval = OpenEmbeddedMessage(&obj_attach, &exception.obj_message, MAPI_READONLY); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x2d, PidLidFExceptionalBody, PidLidRecurring, PidLidAppointmentRecur, PidLidAppointmentStateFlags, PidLidTimeZoneDescription, PidLidTimeZoneStruct, PidLidAppointmentStartWhole, PidLidAppointmentEndWhole, PidLidAppointmentSubType, PidLidOwnerCriticalChange, PidLidLocation, PidLidExceptionReplaceTime, PidLidNonSendableBcc, PidLidAppointmentSequence, PidLidBusyStatus, PidLidIntendedBusyStatus, PidLidCleanGlobalObjectId, PidLidAttendeeCriticalChange, PidLidAppointmentReplyTime, PidLidAppointmentNotAllowPropose, PidLidAllowExternalCheck, PidLidAppointmentLastSequence, PidLidAppointmentSequenceTime, PidLidAutoFillLocation, PidLidAutoStartCheck, PidLidCollaborateDoc, PidLidConferencingCheck, PidLidConferencingType, PidLidDirectory, PidLidNetShowUrl, PidLidOnlinePassword, PidLidOrganizerAlias, PidLidReminderSet, PidLidReminderDelta, PR_MESSAGE_CLASS_UNICODE, PR_BODY_UNICODE, PR_CREATION_TIME, PR_LAST_MODIFICATION_TIME, PR_IMPORTANCE, PR_RESPONSE_REQUESTED, PR_SUBJECT_UNICODE, PR_OWNER_APPT_ID, PR_SENDER_NAME, PR_SENDER_EMAIL_ADDRESS, PR_MESSAGE_LOCALE_ID ); retval = GetProps(&exception.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); if (retval == MAPI_E_SUCCESS) { aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; /*Get required properties to check if right event*/ exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags); /*Check to see if event is acceptable*/ if (!checkEvent(&exception, exchange2ical_check, get_tm_from_FILETIME(exception.apptStartWhole))){ break; } /*Grab Rest of Properties*/ exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags | EntireFlag); uint8_t *dBody = (uint8_t *) octool_get_propval(&aRow2, PidLidFExceptionalBody); retval = GetRecipientTable(&exception.obj_message, &exception.Recipients.SRowSet, &exception.Recipients.SPropTagArray); /*Check for set subject*/ if (!exception.Subject){ exception.Subject=exchange2ical->Subject; } /*Check for a set apptSubType*/ if (!exception.apptSubType){ exception.apptSubType=exchange2ical->apptSubType; } /*check for a set Location*/ if (!exception.Location){ exception.Location=exchange2ical->Location; } /*check for set valarm info*/ if(!exception.ReminderSet){ exception.ReminderSet=exchange2ical->ReminderSet; } if(!exception.ReminderDelta){ exception.ReminderDelta=exchange2ical->ReminderDelta; } /*Set to same vcalendar as parent*/ exception.vcalendar=exchange2ical->vcalendar; /*Set to same uid fallback in case GlobalObjId is missing*/ exception.idx=exchange2ical->idx; /*has a modified summary*/ if(dBody && *dBody){ SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_BODY_HTML_UNICODE); retval = GetProps(&exception.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRowT.ulAdrEntryPad = 0; aRowT.cValues = count; aRowT.lpProps = lpProps; exception.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE); } /* has the same summary as parent*/ } else{ exception.body=exchange2ical->body; exception.bodyHTML=exchange2ical->bodyHTML; } ical_component_VEVENT(&exception); exception.vcalendar=NULL; exchange2ical_clear(&exception); } } mapi_object_release(&exception.obj_message); } MAPIFreeBuffer(lpProps); } } } } mapi_object_release(&obj_tb_attach); return 0; }
/* * Fetch the body given PR_MSG_EDITOR_FORMAT property value */ static enum MAPISTATUS fetchmail_get_body(TALLOC_CTX *mem_ctx, mapi_object_t *obj_message, struct SRow *aRow, DATA_BLOB *body) { enum MAPISTATUS retval; const struct SBinary_short *bin; mapi_object_t obj_stream; char *data; uint8_t format; /* Sanity checks */ MAPI_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); /* initialize body DATA_BLOB */ body->data = NULL; body->length = 0; retval = GetBestBody(obj_message, &format); MAPI_RETVAL_IF(retval, retval, NULL); switch (format) { case olEditorText: data = fetchmail_get_propval(aRow, PR_BODY_UNICODE); if (data) { body->data = talloc_memdup(mem_ctx, data, strlen(data)); body->length = strlen(data); } else { mapi_object_init(&obj_stream); retval = OpenStream(obj_message, PR_BODY_UNICODE, 0, &obj_stream); MAPI_RETVAL_IF(retval, GetLastError(), NULL); retval = fetchmail_get_stream(mem_ctx, &obj_stream, body); MAPI_RETVAL_IF(retval, GetLastError(), NULL); mapi_object_release(&obj_stream); } break; case olEditorHTML: bin = (const struct SBinary_short *) fetchmail_get_propval(aRow, PR_HTML); if (bin) { body->data = talloc_memdup(mem_ctx, bin->lpb, bin->cb); body->length = bin->cb; } else { mapi_object_init(&obj_stream); retval = OpenStream(obj_message, PR_HTML, 0, &obj_stream); MAPI_RETVAL_IF(retval, GetLastError(), NULL); retval = fetchmail_get_stream(mem_ctx, &obj_stream, body); MAPI_RETVAL_IF(retval, GetLastError(), NULL); mapi_object_release(&obj_stream); } break; case olEditorRTF: mapi_object_init(&obj_stream); retval = OpenStream(obj_message, PR_RTF_COMPRESSED, 0, &obj_stream); MAPI_RETVAL_IF(retval, GetLastError(), NULL); retval = WrapCompressedRTFStream(&obj_stream, body); MAPI_RETVAL_IF(retval, GetLastError(), NULL); mapi_object_release(&obj_stream); break; default: DEBUG(0, ("Undefined Body\n")); break; } return MAPI_E_SUCCESS; }
/** \details Test #1804 ModifyRecipients and try to build RecipientRow with multi-value properties (e.g. PidTagUserX509Certificate) \param mt pointer to the top level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_zentyal_1804(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_folder; char **username = NULL; struct SPropTagArray *SPropTagArray = NULL; struct PropertyValue_r value; struct PropertyRowSet_r *RowSet = NULL; struct SRowSet *SRowSet = NULL; struct PropertyTagArray_r *flaglist = NULL; mapi_id_t id_msgs[1]; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_folder, &obj_message); mapitest_print_retval(mt, "CreateMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Resolve the recipients and call ModifyRecipients */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_ADDRTYPE_UNICODE, PR_SEND_RICH_INFO, PR_7BIT_DISPLAY_NAME_UNICODE, PR_SMTP_ADDRESS_UNICODE); username = talloc_array(mt->mem_ctx, char *, 2); username[0] = (char *)mt->profile->username; username[1] = NULL; retval = ResolveNames(mapi_object_get_session(&obj_message), (const char **)username, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); mapitest_print_retval_clean(mt, "ResolveNames", retval); if (retval != MAPI_E_SUCCESS) { return false; } if (!RowSet) { mapitest_print(mt, "Null RowSet\n"); return false; } if (!RowSet->cRows) { mapitest_print(mt, "No values in RowSet\n"); MAPIFreeBuffer(RowSet); return false; } value.ulPropTag = PR_SEND_INTERNET_ENCODING; value.value.l = 0; PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value); /* Fake multi-value property on RecipientRow */ /* PT_MV_STRING8 */ value.ulPropTag = PR_EMS_AB_PROXY_ADDRESSES; value.value.MVszA.cValues = 2; value.value.MVszA.lppszA = talloc_array(mt->mem_ctx, const char *, value.value.MVszA.cValues); value.value.MVszA.lppszA[0] = "smtp:[email protected]"; value.value.MVszA.lppszA[1] = "X400:c=US;a= ;p=First Organizati;o=Exchange;s=test"; PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value); /* PT_MV_UNICODE - same layout as PT_MV_STRING8 */ value.ulPropTag = PR_EMS_AB_PROXY_ADDRESSES_UNICODE; PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value); /* PT_MV_BINARY */ value.ulPropTag = PidTagUserX509Certificate; value.value.MVbin.cValues = 2; value.value.MVbin.lpbin = talloc_array(mt->mem_ctx, struct Binary_r, value.value.MVbin.cValues); value.value.MVbin.lpbin[0].cb = 9; value.value.MVbin.lpbin[0].lpb = (uint8_t *)"string 1"; value.value.MVbin.lpbin[1].cb = 9; value.value.MVbin.lpbin[1].lpb = (uint8_t *)"string 2"; PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value); SRowSet = talloc_zero(RowSet, struct SRowSet); cast_PropertyRowSet_to_SRowSet(SRowSet, RowSet, SRowSet); SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO); mapitest_print_retval(mt, "SetRecipientType"); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Step 5. Delete the message */ id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Release */ MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; }