/** \details EcDoRpc GetHierarchyTable (0x04) Rop. This operation gets the subfolder hierarchy table for a folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetHierarchyTable EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetHierarchyTable EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetHierarchyTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL, *parent_object = NULL; void *data; uint32_t handle; uint32_t count = 0; OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] GetHierarchyTable (0x04)\n"); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Initialize default empty GetHierarchyTable reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_GetHierarchyTable.handle_idx; /* GetHierarchyTable can only be called for mailbox/folder objects */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { OC_DEBUG(5, " handle (%x) not found: %x\n", handle, mapi_req->handle_idx); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(parent, &data); parent_object = (struct emsmdbp_object *)data; if (!parent_object) { OC_DEBUG(5, " no object found\n"); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } if ((parent_object->type != EMSMDBP_OBJECT_MAILBOX) && (parent_object->type != EMSMDBP_OBJECT_FOLDER)) { OC_DEBUG(5, "unsupported object type"); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } /* Initialize Table object */ retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec); handles[mapi_repl->handle_idx] = rec->handle; object = emsmdbp_folder_open_table(rec, parent_object, MAPISTORE_FOLDER_TABLE, rec->handle); if (!object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } object->object.table->flags = mapi_req->u.mapi_GetHierarchyTable.TableFlags; mapi_handles_set_private_data(rec, object); if (object->object.table->flags & TableFlags_Depth) { retval = emsmdbp_folder_get_recursive_folder_count(emsmdbp_ctx, parent_object, &count); if (retval != MAPI_E_SUCCESS) { mapi_repl->error_code = MAPI_E_CALL_FAILED; goto end; } object->object.table->denominator = count; } mapi_repl->u.mapi_GetHierarchyTable.RowCount = object->object.table->denominator; /* notifications */ if ((mapi_req->u.mapi_GetHierarchyTable.TableFlags & TableFlags_NoNotifications)) { OC_DEBUG(5, " notifications skipped\n"); } end: *size += libmapiserver_RopGetHierarchyTable_size(mapi_repl); return MAPI_E_SUCCESS; }
/** \details EcDoRpc GetHierarchyTable (0x04) Rop. This operation gets the subfolder hierarchy table for a folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetHierarchyTable EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetHierarchyTable EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetHierarchyTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL, *parent_object = NULL; struct mapistore_subscription_list *subscription_list; struct mapistore_subscription *subscription; struct mapistore_table_subscription_parameters subscription_parameters; void *data; uint64_t folderID; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] GetHierarchyTable (0x04)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Initialize default empty GetHierarchyTable reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_GetHierarchyTable.handle_idx; /* GetHierarchyTable can only be called for mailbox/folder objects */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(parent, &data); parent_object = (struct emsmdbp_object *)data; if (!parent_object) { DEBUG(5, (" no object found\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } switch (parent_object->type) { case EMSMDBP_OBJECT_MAILBOX: folderID = parent_object->object.mailbox->folderID; break; case EMSMDBP_OBJECT_FOLDER: folderID = parent_object->object.folder->folderID; break; default: DEBUG(5, (" unsupported object type\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } /* Initialize Table object */ retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec); handles[mapi_repl->handle_idx] = rec->handle; object = emsmdbp_folder_open_table(rec, parent_object, MAPISTORE_FOLDER_TABLE, rec->handle); if (!object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_set_private_data(rec, object); mapi_repl->u.mapi_GetHierarchyTable.RowCount = object->object.table->denominator; /* notifications */ if ((mapi_req->u.mapi_GetHierarchyTable.TableFlags & TableFlags_NoNotifications)) { DEBUG(5, (" notifications skipped\n")); } else { /* we attach the subscription to the session object */ subscription_list = talloc_zero(emsmdbp_ctx->mstore_ctx, struct mapistore_subscription_list); DLIST_ADD(emsmdbp_ctx->mstore_ctx->subscriptions, subscription_list); subscription_parameters.table_type = MAPISTORE_FOLDER_TABLE; subscription_parameters.folder_id = folderID; /* note that a mapistore_subscription can exist without a corresponding emsmdbp_object (tables) */ subscription = mapistore_new_subscription(subscription_list, emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, rec->handle, fnevTableModified, &subscription_parameters); subscription_list->subscription = subscription; object->object.table->subscription_list = subscription_list; } end: *size += libmapiserver_RopGetHierarchyTable_size(mapi_repl); return MAPI_E_SUCCESS; }