[evolution-mapi] Cannot read/write large attachments
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Cannot read/write large attachments
- Date: Thu, 2 Feb 2012 14:45:22 +0000 (UTC)
commit ec8c9ac9870dbf3007684155ebb50162fa8f4612
Author: Milan Crha <mcrha redhat com>
Date: Thu Feb 2 15:44:22 2012 +0100
Cannot read/write large attachments
src/libexchangemapi/e-mapi-cal-utils.c | 30 ++--
src/libexchangemapi/e-mapi-connection.c | 297 ++++++++++++++++++++++------
src/libexchangemapi/e-mapi-connection.h | 42 ++++-
src/libexchangemapi/e-mapi-debug.c | 52 +++++-
src/libexchangemapi/e-mapi-fast-transfer.c | 56 +++++-
src/libexchangemapi/e-mapi-mail-utils.c | 120 +++++++-----
6 files changed, 463 insertions(+), 134 deletions(-)
---
diff --git a/src/libexchangemapi/e-mapi-cal-utils.c b/src/libexchangemapi/e-mapi-cal-utils.c
index a2eb8f3..1344a51 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-utils.c
@@ -792,14 +792,14 @@ set_attachments_to_comp (EMapiConnection *conn,
e_cal_component_get_uid (comp, &uid);
for (attach = attachments; attach; attach = attach->next) {
- const struct SBinary_short *data_bin;
+ uint64_t data_cb = 0;
+ const uint8_t *data_lpb = NULL;
const gchar *filename;
const uint32_t *ui32;
gchar *path, *attach_uri;
GError *error = NULL;
- data_bin = e_mapi_util_find_array_propval (&attach->properties, PidTagAttachDataBinary);
- if (!data_bin) {
+ if (!e_mapi_attachment_get_bin_prop (attach, PidTagAttachDataBinary, &data_cb, &data_lpb)) {
g_debug ("%s: Skipping calendar attachment without data", G_STRFUNC);
continue;
}
@@ -819,7 +819,7 @@ set_attachments_to_comp (EMapiConnection *conn,
continue;
}
- if (!g_file_set_contents (path, (const gchar *) data_bin->lpb, data_bin->cb, &error)) {
+ if (!g_file_set_contents (path, (const gchar *) data_lpb, data_cb, &error)) {
g_debug ("%s: Failed to write attachment content to '%s': %s", G_STRFUNC, path, error ? error->message : "Unknown error");
g_free (attach_uri);
g_clear_error (&error);
@@ -900,12 +900,13 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
g_free (utf8_str);
} else {
- const struct SBinary_short *html_bin = e_mapi_util_find_array_propval (&object->properties, PidTagHtml);
+ uint64_t html_cb = 0;
+ const uint8_t *html_lpb = NULL;
- if (html_bin) {
+ if (e_mapi_object_get_bin_prop (object, PidTagHtml, &html_cb, &html_lpb)) {
gchar *utf8_str = NULL;
- if (e_mapi_utils_ensure_utf8_string (PidTagHtml, ui32, html_bin->lpb, html_bin->cb, &utf8_str))
+ if (e_mapi_utils_ensure_utf8_string (PidTagHtml, ui32, html_lpb, html_cb, &utf8_str))
icalcomponent_set_description (ical_comp, utf8_str);
g_free (utf8_str);
@@ -1471,7 +1472,8 @@ e_mapi_cal_utils_add_attachments (EMapiObject *object,
guint filelength = g_mapped_file_get_length (mapped_file);
const gchar *split_name;
uint32_t ui32;
- struct SBinary_short bin;
+ uint64_t data_cb;
+ uint8_t *data_lpb;
if (g_str_has_prefix (filename, safeuid)) {
split_name = (filename + strlen (safeuid) + strlen ("-"));
@@ -1504,9 +1506,9 @@ e_mapi_cal_utils_add_attachments (EMapiObject *object,
set_value (PidTagAttachFilename, split_name);
set_value (PidTagAttachLongFilename, split_name);
- bin.cb = filelength;
- bin.lpb = talloc_memdup (attachment, attach, bin.cb);
- set_value (PidTagAttachDataBinary, &bin);
+ data_cb = filelength;
+ data_lpb = talloc_memdup (attachment, attach, data_cb);
+ e_mapi_attachment_add_streamed (attachment, PidTagAttachDataBinary, data_cb, data_lpb);
#undef set_value
@@ -2080,10 +2082,10 @@ e_mapi_cal_utils_comp_to_object (EMapiConnection *conn,
set_value (PidLidIsRecurring, &b);
if (b) {
- struct SBinary_short bin;
+ struct SBinary_short recur_bin;
- if (e_mapi_cal_util_rrule_to_bin (comp, &bin, object)) {
- set_value (PidLidAppointmentRecur, &bin);
+ if (e_mapi_cal_util_rrule_to_bin (comp, &recur_bin, object)) {
+ set_value (PidLidAppointmentRecur, &recur_bin);
}
}
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index 6311b19..32ddd16 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -2296,7 +2296,8 @@ fetch_object_property_as_stream (EMapiConnection *conn,
TALLOC_CTX *mem_ctx,
mapi_object_t *obj_message,
uint32_t proptag,
- struct SBinary_short *bin,
+ uint64_t *pcb,
+ uint8_t **plpb,
GCancellable *cancellable,
GError **perror)
{
@@ -2304,12 +2305,15 @@ fetch_object_property_as_stream (EMapiConnection *conn,
mapi_object_t obj_stream;
uint32_t buf_size, max_read;
uint16_t off_data, cn_read;
+ uint64_t cb = 0;
+ uint8_t *lpb = NULL;
gboolean done = FALSE;
g_return_val_if_fail (conn != NULL, MAPI_E_INVALID_PARAMETER);
g_return_val_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER);
g_return_val_if_fail (obj_message != NULL, MAPI_E_INVALID_PARAMETER);
- g_return_val_if_fail (bin != NULL, MAPI_E_INVALID_PARAMETER);
+ g_return_val_if_fail (pcb != NULL, MAPI_E_INVALID_PARAMETER);
+ g_return_val_if_fail (plpb != NULL, MAPI_E_INVALID_PARAMETER);
mapi_object_init (&obj_stream);
@@ -2319,7 +2323,7 @@ fetch_object_property_as_stream (EMapiConnection *conn,
goto cleanup;
}
- bin->cb = 0;
+ cb = 0;
ms = GetStreamSize (&obj_stream, &buf_size);
if (ms != MAPI_E_SUCCESS) {
@@ -2327,16 +2331,16 @@ fetch_object_property_as_stream (EMapiConnection *conn,
goto cleanup;
}
- bin->cb = buf_size;
- bin->lpb = talloc_size (mem_ctx, bin->cb + 1);
- if (!bin->lpb || !bin->cb)
+ cb = buf_size;
+ lpb = talloc_size (mem_ctx, cb + 1);
+ if (!lpb || !cb)
goto cleanup;
/* determine max_read first, to read by chunks as long as possible */
off_data = 0;
max_read = buf_size > STREAM_MAX_READ_SIZE ? STREAM_MAX_READ_SIZE : buf_size;
do {
- ms = ReadStream (&obj_stream, (bin->lpb) + off_data, max_read, &cn_read);
+ ms = ReadStream (&obj_stream, lpb + off_data, max_read, &cn_read);
if (ms == MAPI_E_SUCCESS) {
if (cn_read == 0) {
done = TRUE;
@@ -2358,7 +2362,7 @@ fetch_object_property_as_stream (EMapiConnection *conn,
} while (ms == 0x2c80); /* an error when max_read is too large? */
while (!done) {
- ms = ReadStream (&obj_stream, bin->lpb + off_data, max_read, &cn_read);
+ ms = ReadStream (&obj_stream, lpb + off_data, max_read, &cn_read);
if (ms != MAPI_E_SUCCESS) {
make_mapi_error (perror, "ReadStream", ms);
done = TRUE;
@@ -2374,6 +2378,9 @@ fetch_object_property_as_stream (EMapiConnection *conn,
cleanup:
mapi_object_release (&obj_stream);
+ *pcb = cb;
+ *plpb = lpb;
+
return ms;
}
@@ -2439,22 +2446,16 @@ fetch_object_attachment_cb (EMapiConnection *conn,
attach_method = e_mapi_util_find_row_propval (srow, PidTagAttachMethod);
if (attach_method && *attach_method == ATTACH_BY_VALUE) {
if (!e_mapi_util_find_array_propval (&attachment->properties, PidTagAttachDataBinary)) {
- struct SBinary_short bin;
+ uint64_t cb = 0;
+ uint8_t *lpb = NULL;
- ms = fetch_object_property_as_stream (conn, mem_ctx, &obj_attach, PidTagAttachDataBinary, &bin, cancellable, perror);
+ ms = fetch_object_property_as_stream (conn, mem_ctx, &obj_attach, PidTagAttachDataBinary, &cb, &lpb, cancellable, perror);
if (ms != MAPI_E_SUCCESS) {
make_mapi_error (perror, "Attachment::fetch PidTagAttachDataBinary", ms);
goto cleanup;
}
- attachment->properties.cValues++;
- attachment->properties.lpProps = talloc_realloc (mem_ctx,
- attachment->properties.lpProps,
- struct mapi_SPropValue,
- attachment->properties.cValues + 1);
- attachment->properties.lpProps[attachment->properties.cValues - 1].ulPropTag = PidTagAttachDataBinary;
- attachment->properties.lpProps[attachment->properties.cValues - 1].value.bin = bin;
- attachment->properties.lpProps[attachment->properties.cValues].ulPropTag = 0;
+ e_mapi_attachment_add_streamed (attachment, PidTagAttachDataBinary, cb, lpb);
}
} else if (attach_method && *attach_method == ATTACH_EMBEDDED_MSG) {
mapi_object_t obj_emb_msg;
@@ -2568,39 +2569,34 @@ e_mapi_connection_fetch_object_internal (EMapiConnection *conn,
uint8_t best_body = 0;
if (GetBestBody (obj_message, &best_body) == MAPI_E_SUCCESS && best_body == olEditorHTML) {
- struct SBinary_short bin;
+ uint64_t cb = 0;
+ uint8_t *lpb = NULL;
- ms = fetch_object_property_as_stream (conn, mem_ctx, obj_message, PidTagHtml, &bin, cancellable, perror);
+ ms = fetch_object_property_as_stream (conn, mem_ctx, obj_message, PidTagHtml, &cb, &lpb, cancellable, perror);
if (ms != MAPI_E_SUCCESS) {
make_mapi_error (perror, "Object::fetch PidTagHtml", ms);
goto cleanup;
}
- object->properties.cValues++;
- object->properties.lpProps = talloc_realloc (mem_ctx,
- object->properties.lpProps,
- struct mapi_SPropValue,
- object->properties.cValues + 1);
- object->properties.lpProps[object->properties.cValues - 1].ulPropTag = PidTagHtml;
- object->properties.lpProps[object->properties.cValues - 1].value.bin = bin;
- object->properties.lpProps[object->properties.cValues].ulPropTag = 0;
+ e_mapi_object_add_streamed (object, PidTagHtml, cb, lpb);
}
}
if (!e_mapi_util_find_array_propval (&object->properties, PidTagBody)) {
- struct SBinary_short bin;
+ uint64_t cb = 0;
+ uint8_t *lpb = NULL;
- if (fetch_object_property_as_stream (conn, mem_ctx, obj_message, PidTagBody, &bin, cancellable, NULL) == MAPI_E_SUCCESS) {
+ if (fetch_object_property_as_stream (conn, mem_ctx, obj_message, PidTagBody, &cb, &lpb, cancellable, NULL) == MAPI_E_SUCCESS) {
object->properties.cValues++;
object->properties.lpProps = talloc_realloc (mem_ctx,
object->properties.lpProps,
struct mapi_SPropValue,
object->properties.cValues + 1);
object->properties.lpProps[object->properties.cValues - 1].ulPropTag = PidTagBody;
- if (bin.cb > 0 && bin.lpb[bin.cb - 1] == 0)
- object->properties.lpProps[object->properties.cValues - 1].value.lpszW = (const char *) talloc_steal (object, bin.lpb);
+ if (cb > 0 && lpb[cb - 1] == 0)
+ object->properties.lpProps[object->properties.cValues - 1].value.lpszW = (const char *) talloc_steal (object, lpb);
else
- object->properties.lpProps[object->properties.cValues - 1].value.lpszW = talloc_strndup (object, (char *) bin.lpb, bin.cb);
+ object->properties.lpProps[object->properties.cValues - 1].value.lpszW = talloc_strndup (object, (char *) lpb, cb);
object->properties.lpProps[object->properties.cValues].ulPropTag = 0;
}
}
@@ -3048,16 +3044,12 @@ e_mapi_connection_transfer_summary (EMapiConnection *conn,
return ms == MAPI_E_SUCCESS;
}
-typedef struct {
- uint32_t proptag;
- uint32_t cb;
- const uint8_t *lpb; /* taken from the original mapi prop, no need to copy the memory */
-} EMapiStreamedProp;
-
static gboolean
convert_mapi_props_to_props (EMapiConnection *conn,
mapi_object_t *obj_folder,
const struct mapi_SPropValue_array *mapi_props,
+ const EMapiStreamedProp *known_streams,
+ guint known_streams_count,
struct SPropValue **props,
uint32_t *propslen,
EMapiStreamedProp **streams, /* can be NULL for no streaming */
@@ -3078,8 +3070,24 @@ convert_mapi_props_to_props (EMapiConnection *conn,
e_return_val_mapi_error_if_fail (mem_ctx != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
if (streams) {
e_return_val_mapi_error_if_fail (streamslen != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
+ } else {
+ e_return_val_mapi_error_if_fail (known_streams == NULL, MAPI_E_INVALID_PARAMETER, FALSE);
}
+ #define addstream() { \
+ if (!*streams) { \
+ *streams = g_new0 (EMapiStreamedProp, 1); \
+ *streamslen = 0; \
+ } else { \
+ *streams = g_renew (EMapiStreamedProp, *streams, *streamslen + 1); \
+ } \
+ \
+ (*streams)[*streamslen].proptag = proptag; \
+ (*streams)[*streamslen].cb = 0; \
+ (*streams)[*streamslen].lpb = NULL; \
+ (*streamslen) += 1; \
+ }
+
for (ii = 0; ii < mapi_props->cValues; ii++) {
gboolean processed = FALSE;
uint32_t proptag = mapi_props->lpProps[ii].ulPropTag;
@@ -3097,20 +3105,6 @@ convert_mapi_props_to_props (EMapiConnection *conn,
const gchar *str;
const struct SBinary_short *bin;
- #define addstream() { \
- if (!*streams) { \
- *streams = g_new0 (EMapiStreamedProp, 1); \
- *streamslen = 0; \
- } else { \
- *streams = g_renew (EMapiStreamedProp, *streams, *streamslen + 1); \
- } \
- \
- (*streams)[*streamslen].proptag = proptag; \
- (*streams)[*streamslen].cb = 0; \
- (*streams)[*streamslen].lpb = NULL; \
- (*streamslen) += 1; \
- }
-
switch (proptag & 0xFFFF) {
case PT_BINARY:
bin = propdata;
@@ -3160,14 +3154,25 @@ convert_mapi_props_to_props (EMapiConnection *conn,
}
break;
}
-
- #undef addstream
}
if (!processed)
e_mapi_utils_add_spropvalue (mem_ctx, props, propslen, proptag, propdata);
}
+ if (known_streams && known_streams_count > 0 && streams) {
+ for (ii = 0; ii < known_streams_count; ii++) {
+ uint32_t proptag = known_streams[ii].proptag;
+
+ maybe_add_named_id_tag (proptag, &named_ids_list, &named_ids_len);
+
+ addstream ();
+ (*streams)[(*streamslen) - 1].cb = known_streams[ii].cb;
+ (*streams)[(*streamslen) - 1].lpb = known_streams[ii].lpb;
+ }
+ }
+ #undef addstream
+
if (named_ids_list) {
GHashTable *replace_hash = NULL;
@@ -3209,7 +3214,7 @@ write_streamed_prop (EMapiConnection *conn,
GError **perror)
{
enum MAPISTATUS ms;
- uint32_t total_written;
+ uint64_t total_written;
gboolean done = FALSE;
mapi_object_t obj_stream;
@@ -3291,6 +3296,8 @@ update_props_on_object (EMapiConnection *conn,
mapi_object_t *obj_folder,
mapi_object_t *obj_object,
const struct mapi_SPropValue_array *properties,
+ const EMapiStreamedProp *known_streams,
+ guint known_streams_count,
TALLOC_CTX *mem_ctx,
GCancellable *cancellable,
GError **perror)
@@ -3306,7 +3313,7 @@ update_props_on_object (EMapiConnection *conn,
LOCK ();
- if (!convert_mapi_props_to_props (conn, obj_folder, properties, &props, &propslen, &streams, &streamslen, mem_ctx, cancellable, perror)) {
+ if (!convert_mapi_props_to_props (conn, obj_folder, properties, known_streams, known_streams_count, &props, &propslen, &streams, &streamslen, mem_ctx, cancellable, perror)) {
ms = MAPI_E_CALL_FAILED;
make_mapi_error (perror, "convert_mapi_props_to_props", ms);
goto cleanup;
@@ -3373,7 +3380,7 @@ update_recipient_properties (EMapiConnection *conn,
g_return_val_if_fail (recipient != NULL, FALSE);
- if (!convert_mapi_props_to_props (conn, obj_folder, &recipient->properties, &props, &propslen, NULL, NULL, mem_ctx, cancellable, perror))
+ if (!convert_mapi_props_to_props (conn, obj_folder, &recipient->properties, NULL, 0, &props, &propslen, NULL, NULL, mem_ctx, cancellable, perror))
return FALSE;
for (ii = 0; ii < propslen; ii++) {
@@ -3703,7 +3710,10 @@ add_object_attachments (EMapiConnection *conn,
goto cleanup;
}
- if (!update_props_on_object (conn, obj_folder, &obj_attach, &attachment->properties, mem_ctx, cancellable, perror)) {
+ if (!update_props_on_object (conn, obj_folder, &obj_attach,
+ &attachment->properties,
+ attachment->streamed_properties, attachment->streamed_properties_count,
+ mem_ctx, cancellable, perror)) {
ms = MAPI_E_CALL_FAILED;
make_mapi_error (perror, "update_props_on_object", ms);
goto cleanup;
@@ -3767,7 +3777,10 @@ update_message_with_object (EMapiConnection *conn,
e_return_val_mapi_error_if_fail (obj_message != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
e_return_val_mapi_error_if_fail (object != NULL, MAPI_E_INVALID_PARAMETER, FALSE);
- if (!update_props_on_object (conn, obj_folder, obj_message, &object->properties, mem_ctx, cancellable, perror))
+ if (!update_props_on_object (conn, obj_folder, obj_message,
+ &object->properties,
+ object->streamed_properties, object->streamed_properties_count,
+ mem_ctx, cancellable, perror))
return FALSE;
if (g_cancellable_set_error_if_cancelled (cancellable, perror))
@@ -6824,6 +6837,8 @@ e_mapi_attachment_new (TALLOC_CTX *mem_ctx)
attachment->properties.cValues = 0;
attachment->properties.lpProps = talloc_zero_array (mem_ctx, struct mapi_SPropValue, 1);
+ attachment->streamed_properties = NULL;
+ attachment->streamed_properties_count = 0;
attachment->embedded_object = NULL;
attachment->next = NULL;
@@ -6840,9 +6855,89 @@ e_mapi_attachment_free (EMapiAttachment *attachment)
e_mapi_object_free (attachment->embedded_object);
talloc_free (attachment->properties.lpProps);
+ talloc_free (attachment->streamed_properties);
talloc_free (attachment);
}
+void
+e_mapi_attachment_add_streamed (EMapiAttachment *attachment,
+ uint32_t proptag,
+ uint64_t cb,
+ const uint8_t *lpb)
+{
+ guint32 index;
+
+ g_return_if_fail (attachment != NULL);
+ g_return_if_fail (proptag != 0);
+ g_return_if_fail (e_mapi_attachment_get_streamed (attachment, proptag) == NULL);
+
+ attachment->streamed_properties = talloc_realloc (attachment,
+ attachment->streamed_properties,
+ EMapiStreamedProp,
+ attachment->streamed_properties_count + 1);
+ g_return_if_fail (attachment->streamed_properties != NULL);
+
+ index = attachment->streamed_properties_count;
+ attachment->streamed_properties_count++;
+ attachment->streamed_properties[index].proptag = proptag;
+ attachment->streamed_properties[index].cb = cb;
+ attachment->streamed_properties[index].lpb = lpb;
+}
+
+EMapiStreamedProp *
+e_mapi_attachment_get_streamed (EMapiAttachment *attachment,
+ uint32_t proptag)
+{
+ guint32 ii;
+
+ g_return_val_if_fail (attachment != NULL, NULL);
+
+ if (!attachment->streamed_properties_count || !attachment->streamed_properties)
+ return NULL;
+
+ for (ii = 0; ii < attachment->streamed_properties_count; ii++) {
+ if (attachment->streamed_properties[ii].proptag == proptag)
+ return &attachment->streamed_properties[ii];
+ }
+
+ return NULL;
+}
+
+gboolean
+e_mapi_attachment_get_bin_prop (EMapiAttachment *attachment,
+ uint32_t proptag,
+ uint64_t *cb,
+ const uint8_t **lpb)
+{
+ EMapiStreamedProp *streamed;
+ const struct SBinary_short *bin;
+
+ g_return_val_if_fail (attachment != NULL, FALSE);
+ g_return_val_if_fail (cb != NULL, FALSE);
+ g_return_val_if_fail (lpb != NULL, FALSE);
+
+ *cb = 0;
+ *lpb = NULL;
+
+ streamed = e_mapi_attachment_get_streamed (attachment, proptag);
+ if (streamed) {
+ *cb = streamed->cb;
+ *lpb = streamed->lpb;
+
+ return TRUE;
+ }
+
+ bin = e_mapi_util_find_array_propval (&attachment->properties, proptag);
+ if (bin) {
+ *cb = bin->cb;
+ *lpb = bin->lpb;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
EMapiObject *
e_mapi_object_new (TALLOC_CTX *mem_ctx)
{
@@ -6853,6 +6948,8 @@ e_mapi_object_new (TALLOC_CTX *mem_ctx)
object->properties.cValues = 0;
object->properties.lpProps = talloc_zero_array (mem_ctx, struct mapi_SPropValue, 1);
+ object->streamed_properties = NULL;
+ object->streamed_properties_count = 0;
object->recipients = NULL;
object->attachments = NULL;
object->parent = NULL;
@@ -6887,6 +6984,7 @@ e_mapi_object_free (EMapiObject *object)
e_mapi_attachment_free (a);
}
+ talloc_free (object->streamed_properties);
talloc_free (object->properties.lpProps);
talloc_free (object);
}
@@ -6933,6 +7031,85 @@ e_mapi_object_add_attachment (EMapiObject *object,
}
}
+void
+e_mapi_object_add_streamed (EMapiObject *object,
+ uint32_t proptag,
+ uint64_t cb,
+ const uint8_t *lpb)
+{
+ guint32 index;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (proptag != 0);
+ g_return_if_fail (e_mapi_object_get_streamed (object, proptag) == NULL);
+
+ object->streamed_properties = talloc_realloc (object,
+ object->streamed_properties,
+ EMapiStreamedProp,
+ object->streamed_properties_count + 1);
+ g_return_if_fail (object->streamed_properties != NULL);
+
+ index = object->streamed_properties_count;
+ object->streamed_properties_count++;
+ object->streamed_properties[index].proptag = proptag;
+ object->streamed_properties[index].cb = cb;
+ object->streamed_properties[index].lpb = lpb;
+}
+
+EMapiStreamedProp *
+e_mapi_object_get_streamed (EMapiObject *object,
+ uint32_t proptag)
+{
+ guint32 ii;
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ if (!object->streamed_properties_count || !object->streamed_properties)
+ return NULL;
+
+ for (ii = 0; ii < object->streamed_properties_count; ii++) {
+ if (object->streamed_properties[ii].proptag == proptag)
+ return &object->streamed_properties[ii];
+ }
+
+ return NULL;
+}
+
+gboolean
+e_mapi_object_get_bin_prop (EMapiObject *object,
+ uint32_t proptag,
+ uint64_t *cb,
+ const uint8_t **lpb)
+{
+ EMapiStreamedProp *streamed;
+ const struct SBinary_short *bin;
+
+ g_return_val_if_fail (object != NULL, FALSE);
+ g_return_val_if_fail (cb != NULL, FALSE);
+ g_return_val_if_fail (lpb != NULL, FALSE);
+
+ *cb = 0;
+ *lpb = NULL;
+
+ streamed = e_mapi_object_get_streamed (object, proptag);
+ if (streamed) {
+ *cb = streamed->cb;
+ *lpb = streamed->lpb;
+
+ return TRUE;
+ }
+
+ bin = e_mapi_util_find_array_propval (&object->properties, proptag);
+ if (bin) {
+ *cb = bin->cb;
+ *lpb = bin->lpb;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
EMapiPermissionEntry *
e_mapi_permission_entry_new (const gchar *username,
const struct SBinary_short *entry_id,
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index a32e2e7..8889c55 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -61,24 +61,27 @@ typedef struct {
time_t last_modified; /* PidTagLastModificationTime as UTC */
} ListObjectsData;
-struct _EMapiObject;
-struct _EMapiRecipient;
-struct _EMapiAttachment;
+typedef struct _EMapiStreamedProp {
+ uint32_t proptag;
+ uint64_t cb;
+ const uint8_t *lpb; /* taken from the original mapi prop, no need to copy the memory */
+} EMapiStreamedProp;
-typedef struct _EMapiObject EMapiObject;
typedef struct _EMapiRecipient EMapiRecipient;
typedef struct _EMapiAttachment EMapiAttachment;
+typedef struct _EMapiObject EMapiObject;
-struct _EMapiRecipient
-{
+struct _EMapiRecipient {
struct mapi_SPropValue_array properties;
EMapiRecipient *next;
};
-struct _EMapiAttachment
-{
+struct _EMapiAttachment {
struct mapi_SPropValue_array properties;
+ EMapiStreamedProp *streamed_properties; /* use get/add functions for these */
+ guint32 streamed_properties_count;
+
EMapiObject *embedded_object;
EMapiAttachment *next;
@@ -86,6 +89,9 @@ struct _EMapiAttachment
struct _EMapiObject {
struct mapi_SPropValue_array properties;
+ EMapiStreamedProp *streamed_properties; /* use get/add functions for these */
+ guint32 streamed_properties_count;
+
EMapiRecipient *recipients; /* NULL when none */
EMapiAttachment *attachments; /* NULL when none */
@@ -97,6 +103,16 @@ void e_mapi_recipient_free (EMapiRecipient *recipient);
EMapiAttachment * e_mapi_attachment_new (TALLOC_CTX *mem_ctx);
void e_mapi_attachment_free (EMapiAttachment *attachment);
+void e_mapi_attachment_add_streamed (EMapiAttachment *attachment,
+ uint32_t proptag,
+ uint64_t cb,
+ const uint8_t *lpb); /* this might be created inside the attachment TALLOC_CTX */
+EMapiStreamedProp * e_mapi_attachment_get_streamed (EMapiAttachment *attachment,
+ uint32_t proptag);
+gboolean e_mapi_attachment_get_bin_prop (EMapiAttachment *attachment,
+ uint32_t proptag,
+ uint64_t *cb,
+ const uint8_t **lpb);
EMapiObject * e_mapi_object_new (TALLOC_CTX *mem_ctx);
void e_mapi_object_free (EMapiObject *object);
@@ -104,6 +120,16 @@ void e_mapi_object_add_recipient (EMapiObject *object,
EMapiRecipient *recipient);
void e_mapi_object_add_attachment (EMapiObject *object,
EMapiAttachment *attachment);
+void e_mapi_object_add_streamed (EMapiObject *object,
+ uint32_t proptag,
+ uint64_t cb,
+ const uint8_t *lpb); /* this might be created inside the attachment TALLOC_CTX */
+EMapiStreamedProp * e_mapi_object_get_streamed (EMapiObject *object,
+ uint32_t proptag);
+gboolean e_mapi_object_get_bin_prop (EMapiObject *object,
+ uint32_t proptag,
+ uint64_t *cb,
+ const uint8_t **lpb);
#define E_MAPI_PERMISSION_MEMBER_ID_ANONYMOUS_CLIENT (~((uint64_t) 0))
#define E_MAPI_PERMISSION_MEMBER_ID_DEFAULT_USER ((uint64_t) 0)
diff --git a/src/libexchangemapi/e-mapi-debug.c b/src/libexchangemapi/e-mapi-debug.c
index 994ed32..835a8e1 100644
--- a/src/libexchangemapi/e-mapi-debug.c
+++ b/src/libexchangemapi/e-mapi-debug.c
@@ -867,6 +867,49 @@ e_mapi_debug_dump_properties (struct mapi_SPropValue_array *properties,
}
}
+static void
+e_mapi_debug_dump_streamed_properties (guint32 streamed_properties_count,
+ const EMapiStreamedProp *streamed_properties,
+ gint indent)
+{
+ guint32 ii;
+
+ if (!streamed_properties || streamed_properties_count <= 0)
+ return;
+
+ for (ii = 0; ii < streamed_properties_count; ii++) {
+ const gchar *tmp;
+
+ tmp = get_proptag_name (streamed_properties[ii].proptag);
+ if (!tmp || !*tmp)
+ tmp = get_namedid_name (streamed_properties[ii].proptag);
+
+ if (tmp && *tmp)
+ g_print ("%*s%s ", indent, "", tmp);
+ else
+ g_print ("%*s0x%08X ", indent, "", streamed_properties[ii].proptag);
+
+ switch (streamed_properties[ii].proptag & 0xFFFF) {
+ case PT_STRING8:
+ g_print (" (streamed string) - '%s'", streamed_properties[ii].cb == 0 ? "" : streamed_properties[ii].lpb ? (const gchar *) streamed_properties[ii].lpb : "null");
+ break;
+ case PT_UNICODE:
+ g_print (" (streamed unicodestring) - '%s'", streamed_properties[ii].cb == 0 ? "" : streamed_properties[ii].lpb ? (const gchar *) streamed_properties[ii].lpb : "null");
+ break;
+ case PT_BINARY:
+ g_print (" (streamed Binary %p, size %" G_GINT64_MODIFIER "d): %s", streamed_properties[ii].lpb, streamed_properties[ii].cb, streamed_properties[ii].cb > 0 ? "\n" : "");
+ e_mapi_debug_dump_bin (streamed_properties[ii].lpb, streamed_properties[ii].cb, indent + 3);
+ break;
+ default:
+ g_print (" (other streamed type %p, size %" G_GINT64_MODIFIER "d): %s", streamed_properties[ii].lpb, streamed_properties[ii].cb, streamed_properties[ii].cb > 0 ? "\n" : "");
+ e_mapi_debug_dump_bin (streamed_properties[ii].lpb, streamed_properties[ii].cb, indent + 3);
+ break;
+ }
+
+ g_print ("\n");
+ }
+}
+
void
e_mapi_debug_dump_object (EMapiObject *object, gboolean with_properties, gint indent)
{
@@ -879,8 +922,10 @@ e_mapi_debug_dump_object (EMapiObject *object, gboolean with_properties, gint in
if (!object)
return;
- if (with_properties)
+ if (with_properties) {
e_mapi_debug_dump_properties (&object->properties, indent + 3);
+ e_mapi_debug_dump_streamed_properties (object->streamed_properties_count, object->streamed_properties, indent + 3);
+ }
for (index = 0, recipient = object->recipients; recipient; index++, recipient = recipient->next) {
g_print ("%*sRecipient[%d]:\n", indent + 2, "", index);
@@ -890,8 +935,11 @@ e_mapi_debug_dump_object (EMapiObject *object, gboolean with_properties, gint in
for (index = 0, attachment = object->attachments; attachment; index++, attachment = attachment->next) {
g_print ("%*sAttachment[%d]:\n", indent + 2, "", index);
- if (with_properties)
+ if (with_properties) {
e_mapi_debug_dump_properties (&attachment->properties, indent + 3);
+ e_mapi_debug_dump_streamed_properties (attachment->streamed_properties_count, attachment->streamed_properties, indent + 3);
+ }
+
if (attachment->embedded_object) {
g_print ("%*sEmbedded object:\n", indent + 3, "");
e_mapi_debug_dump_object (attachment->embedded_object, with_properties, indent + 5);
diff --git a/src/libexchangemapi/e-mapi-fast-transfer.c b/src/libexchangemapi/e-mapi-fast-transfer.c
index 30ba551..1d36496 100644
--- a/src/libexchangemapi/e-mapi-fast-transfer.c
+++ b/src/libexchangemapi/e-mapi-fast-transfer.c
@@ -51,6 +51,10 @@ struct _EMapiFXParserClosure {
uint32_t marker;
/* where to store read properties */
struct mapi_SPropValue_array *current_properties;
+ TALLOC_CTX *current_streamed_mem_ctx;
+ EMapiStreamedProp **current_streamed_properties;
+ guint32 *current_streamed_properties_count;
+
/* what object is currently read (can be embeded object or the below object */
EMapiObject *current_object;
@@ -113,6 +117,9 @@ parse_marker_cb (uint32_t marker, void *closure)
data->object = NULL;
data->current_object = NULL;
data->current_properties = NULL;
+ data->current_streamed_mem_ctx = NULL;
+ data->current_streamed_properties = NULL;
+ data->current_streamed_properties_count = NULL;
}
if (stop)
@@ -123,6 +130,9 @@ parse_marker_cb (uint32_t marker, void *closure)
data->object = e_mapi_object_new (data->mem_ctx);
data->current_object = data->object;
data->current_properties = &data->object->properties;
+ data->current_streamed_mem_ctx = data->object;
+ data->current_streamed_properties = &data->object->streamed_properties;
+ data->current_streamed_properties_count = &data->object->streamed_properties_count;
data->marker = marker;
break;
case PidTagEndMessage:
@@ -136,6 +146,9 @@ parse_marker_cb (uint32_t marker, void *closure)
data->object = NULL;
data->current_object = NULL;
data->current_properties = NULL;
+ data->current_streamed_mem_ctx = NULL;
+ data->current_streamed_properties = NULL;
+ data->current_streamed_properties_count = NULL;
if (stop)
return MAPI_E_USER_CANCEL;
@@ -155,11 +168,17 @@ parse_marker_cb (uint32_t marker, void *closure)
data->current_object->recipients = recipient;
data->current_properties = &recipient->properties;
+ data->current_streamed_mem_ctx = NULL;
+ data->current_streamed_properties = NULL;
+ data->current_streamed_properties_count = NULL;
}
data->marker = marker;
break;
case PidTagEndToRecip:
data->current_properties = NULL;
+ data->current_streamed_mem_ctx = NULL;
+ data->current_streamed_properties = NULL;
+ data->current_streamed_properties_count = NULL;
data->marker = 0;
break;
case PidTagNewAttach:
@@ -175,11 +194,17 @@ parse_marker_cb (uint32_t marker, void *closure)
data->current_object->attachments = attachment;
data->current_properties = &attachment->properties;
+ data->current_streamed_mem_ctx = attachment;
+ data->current_streamed_properties = &attachment->streamed_properties;
+ data->current_streamed_properties_count = &attachment->streamed_properties_count;
}
data->marker = marker;
break;
case PidTagEndAttach:
data->current_properties = NULL;
+ data->current_streamed_mem_ctx = NULL;
+ data->current_streamed_properties = NULL;
+ data->current_streamed_properties_count = NULL;
data->marker = 0;
break;
case PidTagStartEmbed:
@@ -198,6 +223,9 @@ parse_marker_cb (uint32_t marker, void *closure)
data->current_object->attachments->embedded_object = object;
data->current_object = object;
data->current_properties = &object->properties;
+ data->current_streamed_mem_ctx = object;
+ data->current_streamed_properties = &object->streamed_properties;
+ data->current_streamed_properties_count = &object->streamed_properties_count;
}
data->marker = marker;
break;
@@ -210,6 +238,9 @@ parse_marker_cb (uint32_t marker, void *closure)
e_mapi_object_finish_read (data->current_object);
data->current_object = data->current_object->parent;
data->current_properties = NULL;
+ data->current_streamed_mem_ctx = NULL;
+ data->current_streamed_properties = NULL;
+ data->current_streamed_properties_count = NULL;
}
data->marker = 0;
break;
@@ -274,6 +305,24 @@ parse_property_cb (struct SPropValue prop, void *closure)
}
switch (prop.ulPropTag & 0xFFFF) {
+ case PT_BINARY:
+ if (data->current_streamed_properties && data->current_streamed_properties_count &&
+ prop.value.bin.cb > 65535) {
+ guint32 index;
+
+ (*data->current_streamed_properties) = talloc_realloc (data->current_streamed_mem_ctx,
+ (*data->current_streamed_properties),
+ EMapiStreamedProp,
+ (*data->current_streamed_properties_count) + 1);
+ index = (*data->current_streamed_properties_count);
+ (*data->current_streamed_properties_count)++;
+ (*data->current_streamed_properties)[index].proptag = prop.ulPropTag;
+ (*data->current_streamed_properties)[index].cb = prop.value.bin.cb;
+ (*data->current_streamed_properties)[index].lpb = prop.value.bin.lpb;
+ break;
+ } else if (prop.value.bin.cb > 65535) {
+ g_debug ("%s: PT_BINARY property 0x%X larger than 64KB (%d), will be truncated", G_STRFUNC, prop.ulPropTag, prop.value.bin.cb);
+ }
case PT_BOOLEAN:
case PT_I2:
case PT_LONG:
@@ -282,7 +331,6 @@ parse_property_cb (struct SPropValue prop, void *closure)
case PT_STRING8:
case PT_UNICODE:
case PT_SYSTIME:
- case PT_BINARY:
case PT_ERROR:
case PT_CLSID:
case PT_SVREID:
@@ -336,6 +384,9 @@ e_mapi_fast_transfer_internal (EMapiConnection *conn,
data.objects_total = objects_total;
data.marker = 0;
data.current_properties = NULL;
+ data.current_streamed_mem_ctx = NULL;
+ data.current_streamed_properties = NULL;
+ data.current_streamed_properties_count = NULL;
data.current_object = NULL;
data.object = NULL;
@@ -344,6 +395,9 @@ e_mapi_fast_transfer_internal (EMapiConnection *conn,
data.object = e_mapi_object_new (data.mem_ctx);
data.current_object = data.object;
data.current_properties = &data.object->properties;
+ data.current_streamed_mem_ctx = data.object;
+ data.current_streamed_properties = &data.object->streamed_properties;
+ data.current_streamed_properties_count = &data.object->streamed_properties_count;
data.marker = PidTagStartMessage;
}
diff --git a/src/libexchangemapi/e-mapi-mail-utils.c b/src/libexchangemapi/e-mapi-mail-utils.c
index b931247..bf0e650 100644
--- a/src/libexchangemapi/e-mapi-mail-utils.c
+++ b/src/libexchangemapi/e-mapi-mail-utils.c
@@ -177,7 +177,7 @@ build_body_part_content (CamelMimePart *part, EMapiObject *object, uint32_t prop
camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_8BIT);
value = e_mapi_util_find_array_propval (&object->properties, proptag);
- if (value) {
+ if (value || (proptag == PidTagHtml && e_mapi_object_get_streamed (object, proptag))) {
const gchar *type = NULL;
gchar *buff = NULL, *in_utf8;
const uint32_t *pcpid = e_mapi_util_find_array_propval (&object->properties, PidTagInternetCodepage);
@@ -214,12 +214,19 @@ build_body_part_content (CamelMimePart *part, EMapiObject *object, uint32_t prop
in_utf8 = NULL;
if (proptag == PidTagHtml) {
- const struct SBinary_short *html_bin = value;
+ uint64_t cb = 0;
+ const uint8_t *lpb = NULL;
- if (e_mapi_utils_ensure_utf8_string (proptag, pcpid, html_bin->lpb, html_bin->cb, &in_utf8))
+ if (!e_mapi_object_get_bin_prop (object, proptag, &cb, &lpb)) {
+ g_warn_if_reached ();
+ cb = 0;
+ lpb = (const uint8_t *) "";
+ }
+
+ if (e_mapi_utils_ensure_utf8_string (proptag, pcpid, lpb, cb, &in_utf8))
camel_mime_part_set_content (part, in_utf8, strlen (in_utf8), type);
else
- camel_mime_part_set_content (part, (const gchar *) html_bin->lpb, html_bin->cb, type);
+ camel_mime_part_set_content (part, (const gchar *) lpb, cb, type);
} else {
const gchar *str = value;
@@ -240,33 +247,35 @@ static gboolean
is_apple_attach (EMapiAttachment *attach, guint32 *data_len, guint32 *resource_len)
{
gboolean is_apple = FALSE;
- const struct SBinary_short *encoding_bin = e_mapi_util_find_array_propval (&attach->properties, PidTagAttachEncoding);
+ uint64_t enc_cb = 0;
+ const uint8_t *enc_lpb = NULL;
guint8 apple_enc_magic[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x14, 0x03, 0x0B, 0x01 };
- if (encoding_bin && encoding_bin->lpb && encoding_bin->cb == G_N_ELEMENTS (apple_enc_magic)) {
+ if (e_mapi_attachment_get_bin_prop (attach, PidTagAttachEncoding, &enc_cb, &enc_lpb) && enc_cb == G_N_ELEMENTS (apple_enc_magic)) {
gint idx;
is_apple = TRUE;
- for (idx = 0; idx < encoding_bin->cb && is_apple; idx++) {
- is_apple = apple_enc_magic[idx] == encoding_bin->lpb[idx];
+ for (idx = 0; idx < enc_cb && is_apple; idx++) {
+ is_apple = apple_enc_magic[idx] == enc_lpb[idx];
}
}
if (is_apple) {
/* check boundaries too */
- const struct SBinary_short *data_bin = e_mapi_util_find_array_propval (&attach->properties, PidTagAttachDataBinary);
+ uint64_t data_cb = 0;
+ const uint8_t *data_lpb = NULL;
- is_apple = data_bin && data_bin->lpb && data_bin->cb > 128;
+ is_apple = e_mapi_attachment_get_bin_prop (attach, PidTagAttachDataBinary, &data_cb, &data_lpb) && data_lpb && data_cb > 128;
if (is_apple) {
- const guint8 *bin = data_bin->lpb;
+ const guint8 *bin = data_lpb;
/* in big-endian format */
*data_len = (bin[83] << 24) | (bin[84] << 16) | (bin[85] << 8) | (bin[86]);
*resource_len = (bin[87] << 24) | (bin[88] << 16) | (bin[89] << 8) | (bin[90]);
/* +/- mod 128 (but the first 128 is a header length) */
- is_apple = 128 + *data_len + *resource_len <= data_bin->cb && bin[1] < 64;
+ is_apple = 128 + *data_len + *resource_len <= data_cb && bin[1] < 64;
}
}
@@ -364,12 +373,12 @@ classify_attachments (EMapiConnection *conn, EMapiAttachment *attachments, const
CamelContentType *content_type;
CamelMimePart *part;
const uint32_t *ui32;
- const struct SBinary_short *data_bin;
+ uint64_t data_cb = 0;
+ const uint8_t *data_lpb = NULL;
gboolean is_apple;
guint32 apple_data_len = 0, apple_resource_len = 0;
- data_bin = e_mapi_util_find_array_propval (&attach->properties, PidTagAttachDataBinary);
- if (!data_bin && !attach->embedded_object) {
+ if (!e_mapi_attachment_get_bin_prop (attach, PidTagAttachDataBinary, &data_cb, &data_lpb) && !attach->embedded_object) {
g_debug ("%s: Skipping attachment without data and without embedded object", G_STRFUNC);
continue;
}
@@ -403,7 +412,8 @@ classify_attachments (EMapiConnection *conn, EMapiAttachment *attachments, const
if (is_apple) {
CamelMultipart *mp;
gchar *apple_filename;
- const struct SBinary_short *mac_info_bin;
+ uint64_t mac_info_cb = 0;
+ const uint8_t *mac_info_lpb = NULL;
mp = camel_multipart_new ();
camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (mp), "multipart/appledouble");
@@ -411,9 +421,8 @@ classify_attachments (EMapiConnection *conn, EMapiAttachment *attachments, const
camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BASE64);
- mac_info_bin = e_mapi_util_find_array_propval (&attach->properties, PidNameAttachmentMacInfo);
- if (mac_info_bin && mac_info_bin->lpb && mac_info_bin->cb > 0) {
- camel_mime_part_set_content (part, (const gchar *) mac_info_bin->lpb, mac_info_bin->cb, mime_type);
+ if (e_mapi_attachment_get_bin_prop (attach, PidNameAttachmentMacInfo, &mac_info_cb, &mac_info_lpb) && mac_info_lpb && mac_info_cb > 0) {
+ camel_mime_part_set_content (part, (const gchar *) mac_info_lpb, mac_info_cb, mime_type);
} else {
/* RFC 1740 */
guint8 header[] = {
@@ -434,7 +443,7 @@ classify_attachments (EMapiConnection *conn, EMapiAttachment *attachments, const
header[37] = (apple_resource_len ) & 0xFF;
g_byte_array_append (arr, header, G_N_ELEMENTS (header));
- g_byte_array_append (arr, data_bin->lpb + 128 + apple_data_len + (apple_data_len % 128), apple_resource_len);
+ g_byte_array_append (arr, data_lpb + 128 + apple_data_len + (apple_data_len % 128), apple_resource_len);
camel_mime_part_set_content (part, (const gchar *) arr->data, arr->len, mime_type);
@@ -446,7 +455,7 @@ classify_attachments (EMapiConnection *conn, EMapiAttachment *attachments, const
part = camel_mime_part_new ();
- apple_filename = g_strndup ((const gchar *) data_bin->lpb + 2, data_bin->lpb[1]);
+ apple_filename = g_strndup ((const gchar *) data_lpb + 2, data_lpb[1]);
camel_mime_part_set_filename (part, (apple_filename && *apple_filename) ? apple_filename : filename);
g_free (apple_filename);
@@ -454,7 +463,7 @@ classify_attachments (EMapiConnection *conn, EMapiAttachment *attachments, const
if (!mime_type)
mime_type = "application/octet-stream";
- camel_mime_part_set_content (part, (const gchar *) data_bin->lpb + 128, apple_data_len, mime_type);
+ camel_mime_part_set_content (part, (const gchar *) data_lpb + 128, apple_data_len, mime_type);
camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BASE64);
camel_multipart_add_part (mp, part);
g_object_unref (part);
@@ -467,7 +476,7 @@ classify_attachments (EMapiConnection *conn, EMapiAttachment *attachments, const
CamelStream *mem;
mem = camel_stream_mem_new ();
- camel_stream_write (mem, (const gchar *) data_bin->lpb, data_bin->cb, NULL, NULL);
+ camel_stream_write (mem, (const gchar *) data_lpb, data_cb, NULL, NULL);
g_seekable_seek (G_SEEKABLE (mem), 0, G_SEEK_SET, NULL, NULL);
parser = camel_mime_parser_new ();
@@ -558,11 +567,11 @@ classify_attachments (EMapiConnection *conn, EMapiAttachment *attachments, const
g_byte_array_free (data, TRUE);
} else {
- camel_mime_part_set_content (part, (const gchar *) data_bin->lpb, data_bin->cb, mime_type);
+ camel_mime_part_set_content (part, (const gchar *) data_lpb, data_cb, mime_type);
}
}
} else {
- camel_mime_part_set_content (part, (const gchar *) data_bin->lpb, data_bin->cb, mime_type);
+ camel_mime_part_set_content (part, (const gchar *) data_lpb, data_cb, mime_type);
}
content_type = camel_mime_part_get_content_type (part);
@@ -1060,30 +1069,37 @@ get_content_stream (CamelMimePart *part, GCancellable *cancellable)
static void
e_mapi_mail_content_stream_to_bin (CamelStream *content_stream,
- struct SBinary_short *bin,
+ uint64_t *pcb,
+ uint8_t **plpb,
TALLOC_CTX *mem_ctx,
GCancellable *cancellable)
{
guint8 *buf;
guint32 read_size;
+ uint64_t cb;
+ uint8_t *lpb;
g_return_if_fail (content_stream != NULL);
- g_return_if_fail (bin != NULL);
+ g_return_if_fail (pcb != NULL);
+ g_return_if_fail (plpb != NULL);
g_return_if_fail (mem_ctx != NULL);
buf = g_new0 (guint8 , STREAM_SIZE);
- bin->cb = 0;
- bin->lpb = NULL;
+ cb = 0;
+ lpb = NULL;
g_seekable_seek (G_SEEKABLE (content_stream), 0, G_SEEK_SET, NULL, NULL);
while (read_size = camel_stream_read (content_stream, (gchar *) buf, STREAM_SIZE, cancellable, NULL), read_size > 0) {
- bin->lpb = talloc_realloc (mem_ctx, bin->lpb, uint8_t, bin->cb + read_size);
- memcpy (bin->lpb + bin->cb, buf, read_size);
- bin->cb += read_size;
+ lpb = talloc_realloc (mem_ctx, lpb, uint8_t, cb + read_size);
+ memcpy (lpb + cb, buf, read_size);
+ cb += read_size;
}
g_free (buf);
+
+ *pcb = cb;
+ *plpb = lpb;
}
#define set_attach_value(pt,vl) { \
@@ -1103,7 +1119,8 @@ e_mapi_mail_add_attach (EMapiObject *object,
CamelContentType *content_type;
const gchar *content_id;
const gchar *filename;
- struct SBinary_short bin;
+ uint64_t data_cb = 0;
+ uint8_t *data_lpb = NULL;
uint32_t ui32;
g_return_val_if_fail (object != NULL, FALSE);
@@ -1136,8 +1153,8 @@ e_mapi_mail_add_attach (EMapiObject *object,
g_free (ct);
}
- e_mapi_mail_content_stream_to_bin (content_stream, &bin, attach, cancellable);
- set_attach_value (PidTagAttachDataBinary, &bin);
+ e_mapi_mail_content_stream_to_bin (content_stream, &data_cb, &data_lpb, attach, cancellable);
+ e_mapi_attachment_add_streamed (attach, PidTagAttachDataBinary, data_cb, data_lpb);
return TRUE;
}
@@ -1148,19 +1165,22 @@ e_mapi_mail_add_body (EMapiObject *object,
uint32_t proptag,
GCancellable *cancellable)
{
- struct SBinary_short bin = { 0 };
+ uint64_t data_cb = 0;
+ uint8_t *data_lpb = NULL;
gchar *str;
- e_mapi_mail_content_stream_to_bin (content_stream, &bin, object, cancellable);
- str = talloc_strndup (object, (const gchar *) bin.lpb, bin.cb);
- talloc_free (bin.lpb);
+ e_mapi_mail_content_stream_to_bin (content_stream, &data_cb, &data_lpb, object, cancellable);
+ str = talloc_strndup (object, (const gchar *) data_lpb, data_cb);
+ talloc_free (data_lpb);
if ((proptag & 0xFFFF) == PT_BINARY) {
- bin.lpb = (uint8_t *) (str ? str : "");
- bin.cb = strlen ((const gchar *) bin.lpb) + 1;
- /* include trailing zero ................ ^^^ */
+ data_lpb = (uint8_t *) (str ? str : "");
+ data_cb = strlen ((const gchar *) data_lpb) + 1;
+ /* include trailing zero .................. ^^^ */
+
+ e_mapi_object_add_streamed (object, proptag, data_cb, data_lpb);
- return e_mapi_utils_add_property (&object->properties, proptag, &bin, object);
+ return TRUE;
} else if (str) {
if (!e_mapi_utils_add_property (&object->properties, proptag, str, object)) {
talloc_free (str);
@@ -1187,7 +1207,8 @@ e_mapi_mail_do_smime_encrypted (EMapiObject *object,
CamelDataWrapper *dw;
CamelContentType *type;
uint32_t ui32;
- struct SBinary_short bin;
+ uint64_t data_cb = 0;
+ uint8_t *data_lpb = NULL;
gchar *content_type_str;
g_return_val_if_fail (object != NULL, FALSE);
@@ -1220,8 +1241,8 @@ e_mapi_mail_do_smime_encrypted (EMapiObject *object,
set_attach_value (PidTagAttachLongFilename, "SMIME.txt");
set_attach_value (PidTagDisplayName, "SMIME.txt");
- e_mapi_mail_content_stream_to_bin (content_stream, &bin, attach, cancellable);
- set_attach_value (PidTagAttachDataBinary, &bin);
+ e_mapi_mail_content_stream_to_bin (content_stream, &data_cb, &data_lpb, attach, cancellable);
+ e_mapi_attachment_add_streamed (attach, PidTagAttachDataBinary, data_cb, data_lpb);
g_object_unref (content_stream);
@@ -1240,7 +1261,8 @@ e_mapi_mail_do_smime_signed (EMapiObject *object,
CamelContentType *type;
CamelDataWrapper *dw;
uint32_t ui32;
- struct SBinary_short bin;
+ uint64_t data_cb = 0;
+ uint8_t *data_lpb = NULL;
gchar *content_type_str;
g_free (*pmsg_class);
@@ -1293,8 +1315,8 @@ e_mapi_mail_do_smime_signed (EMapiObject *object,
set_attach_value (PidTagAttachLongFilename, "SMIME.txt");
set_attach_value (PidTagDisplayName, "SMIME.txt");
- e_mapi_mail_content_stream_to_bin (content_stream, &bin, attach, cancellable);
- set_attach_value (PidTagAttachDataBinary, &bin);
+ e_mapi_mail_content_stream_to_bin (content_stream, &data_cb, &data_lpb, attach, cancellable);
+ e_mapi_attachment_add_streamed (attach, PidTagAttachDataBinary, data_cb, data_lpb);
g_object_unref (content_stream);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]