2 OpenChange MAPI torture suite implementation.
4 Fetch attachments from an Exchange server
6 Copyright (C) Julien Kerihuel 2007.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <libmapi/libmapi.h>
23 #include <gen_ndr/ndr_exchange.h>
25 #include <credentials.h>
26 #include <torture/mapi_torture.h>
28 #include <torture/torture_proto.h>
29 #include <samba/popt.h>
32 static enum MAPISTATUS read_attach_stream(TALLOC_CTX *ctx_mem,
33 mapi_object_t *obj_attach,
34 mapi_object_t *obj_stream,
40 enum MAPISTATUS status;
42 struct SPropTagArray *proptags;
43 struct SPropValue *vals;
53 /* Get Attachment size
55 proptags = set_SPropTagArray(ctx_mem, 0x1, PR_ATTACH_SIZE);
56 status = GetProps(obj_attach, proptags, &vals, &cn_vals);
57 mapi_errstr("GetProps", GetLastError());
58 if (status != MAPI_E_SUCCESS) return status;
62 *sz_data = (uint32_t)vals[0].value.b;
63 *buf_data = talloc_size(ctx_mem, *sz_data);
70 status = ReadStream(obj_stream,
71 (*buf_data) + off_data,
72 (*sz_data) - off_data,
74 mapi_errstr("ReadStream", GetLastError());
75 if ((status != MAPI_E_SUCCESS) || (cn_read == 0)) {
80 if (off_data >= *sz_data)
90 bool torture_rpc_mapi_fetchattach(struct torture_context *torture)
92 enum MAPISTATUS retval;
95 struct mapi_session *session;
96 mapi_object_t obj_store;
97 mapi_object_t obj_inbox;
98 mapi_object_t obj_message;
99 mapi_object_t obj_tb_contents;
100 mapi_object_t obj_tb_attach;
101 mapi_object_t obj_attach;
102 mapi_object_t obj_stream;
105 mapi_id_t id_message;
106 struct SPropTagArray *proptags;
107 struct SRowSet rows_msgs;
108 struct SRowSet rows_attach;
110 uint32_t i_row_attach;
116 mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchattach");
119 if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
122 mapi_object_init(&obj_store);
123 mapi_object_init(&obj_inbox);
124 mapi_object_init(&obj_message);
125 mapi_object_init(&obj_tb_contents);
126 mapi_object_init(&obj_tb_attach);
127 mapi_object_init(&obj_attach);
128 mapi_object_init(&obj_stream);
130 /* session::OpenMsgStore() */
131 retval = OpenMsgStore(session, &obj_store);
132 mapi_errstr("OpenMsgStore", GetLastError());
133 if (retval != MAPI_E_SUCCESS) return false;
135 /* id_inbox = store->GetReceiveFolder */
136 retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
137 mapi_errstr("GetReceiveFolder", GetLastError());
138 if (retval != MAPI_E_SUCCESS) return false;
140 /* inbox = store->OpenFolder() */
141 retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
142 mapi_errstr("OpenFolder", GetLastError());
143 if (retval != MAPI_E_SUCCESS) return false;
145 /* table = inbox->GetContentsTable() */
146 retval = GetContentsTable(&obj_inbox, &obj_tb_contents, 0, NULL);
147 mapi_errstr("GetContentsTable", GetLastError());
148 if (retval != MAPI_E_SUCCESS) return false;
150 proptags = set_SPropTagArray(mem_ctx, 0x5,
156 retval = SetColumns(&obj_tb_contents, proptags);
157 mapi_errstr("SetColumns", GetLastError());
158 if (retval != MAPI_E_SUCCESS) return false;
160 retval = QueryRows(&obj_tb_contents, 0xa, TBL_ADVANCE, &rows_msgs);
161 mapi_errstr("QueryRows", GetLastError());
162 if (retval != MAPI_E_SUCCESS) return false;
164 /* foreach message get attachment table
165 foreach attachment, get PR_NUM
166 foreach PR_NUM, open attachment
169 for (i_msg = 0; i_msg < rows_msgs.cRows; i_msg++) {
173 id_folder = rows_msgs.aRow[i_msg].lpProps[0].value.d;
174 id_message = rows_msgs.aRow[i_msg].lpProps[1].value.d;
175 retval = OpenMessage(&obj_store,
179 mapi_errstr("OpenMessage", GetLastError());
180 if (retval == MAPI_E_SUCCESS) {
182 /* open attachment table */
183 retval = GetAttachmentTable(&obj_message, &obj_tb_attach);
184 mapi_errstr("GetAttachmentTable", GetLastError());
186 /* foreach attachment, open by PR_ATTACH_NUM */
187 if (retval == MAPI_E_SUCCESS) {
188 proptags = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM);
189 retval = SetColumns(&obj_tb_attach, proptags);
190 mapi_errstr("SetColumns", GetLastError());
191 if (retval != MAPI_E_SUCCESS) return false;
193 retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rows_attach);
194 mapi_errstr("QueryRows", GetLastError());
195 if (retval != MAPI_E_SUCCESS) return false;
197 /* get a stream on PR_ATTACH_DATA_BIN */
198 for (i_row_attach = 0; i_row_attach < rows_attach.cRows; i_row_attach++) {
199 num_attach = rows_attach.aRow[i_row_attach].lpProps[0].value.l;
200 retval = OpenAttach(&obj_message, num_attach, &obj_attach);
201 mapi_errstr("OpenAttach", GetLastError());
202 if (retval == MAPI_E_SUCCESS) {
203 retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
204 mapi_errstr("OpenStream", GetLastError());
206 /* read stream content */
207 if (retval == MAPI_E_SUCCESS) {
208 read_attach_stream(mem_ctx,
209 &obj_attach, &obj_stream, &buf_attach,
218 mapi_object_release(&obj_store);
219 mapi_object_release(&obj_inbox);
220 mapi_object_release(&obj_message);
221 mapi_object_release(&obj_tb_contents);
222 mapi_object_release(&obj_tb_attach);
223 mapi_object_release(&obj_attach);
224 mapi_object_release(&obj_stream);
228 talloc_free(mem_ctx);