evolution-data-server r9428 - in branches/EXCHANGE_MAPI_BRANCH: camel/providers/mapi servers/mapi



Author: msuman
Date: Fri Aug 22 09:18:54 2008
New Revision: 9428
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9428&view=rev

Log:
Extensive rewrite of ExchangeMAPIAttachment handling. It provides infrastructure for having various modes of attachment. Also, re-uses a lot of existing code and pushes setting the attachment-specific details to the backends, thereby making it extremely flexible.

Modified:
   branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c
   branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-transport.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/ChangeLog
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-folder.c
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-folder.h
   branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-utils.c

Modified: branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c	Fri Aug 22 09:18:54 2008
@@ -924,22 +924,32 @@
 		GSList *al = attach_list;
 		for (al = attach_list; al != NULL; al = al->next) {
 			ExchangeMAPIAttachment *attach = (ExchangeMAPIAttachment *)al->data;
+			ExchangeMAPIStream *stream = NULL;
+			const char *filename, *mime_type; 
 			CamelMimePart *part;
 
+			filename = (const char *) exchange_mapi_util_find_SPropVal_array_propval(attach->lpProps, PR_ATTACH_LONG_FILENAME);
+			if (!(filename && *filename))
+				filename = (const char *) exchange_mapi_util_find_SPropVal_array_propval(attach->lpProps, PR_ATTACH_FILENAME);
+
+			mime_type = (const char *) exchange_mapi_util_find_SPropVal_array_propval(attach->lpProps, PR_ATTACH_MIME_TAG);
+
+			stream = exchange_mapi_util_find_stream (attach->streams, PR_ATTACH_DATA_BIN);
+
 			printf("%s(%d):%s:Attachment --\n\tFileName : %s \n\tMIME Tag : %s\n\tLength : %d\n",
 			       __FILE__, __LINE__, __PRETTY_FUNCTION__, 
-				 attach->filename, attach->mime_type, attach->value->len );
+				 filename, mime_type, stream ? stream->value->len : 0);
 
-			if (attach->value->len <= 0) {
+			if (!stream || stream->value->len <= 0) {
 				continue;
 			}
 			part = camel_mime_part_new ();
 
-			camel_mime_part_set_filename(part, g_strdup(attach->filename));
+			camel_mime_part_set_filename(part, g_strdup(filename));
 			//Auto generate content-id
 			camel_mime_part_set_content_id (part, NULL);
-			camel_mime_part_set_content(part, attach->value->data, attach->value->len, attach->mime_type);
-			camel_content_type_set_param (((CamelDataWrapper *) part)->mime_type, "name", attach->filename);
+			camel_mime_part_set_content(part, stream->value->data, stream->value->len, mime_type);
+			camel_content_type_set_param (((CamelDataWrapper *) part)->mime_type, "name", filename);
 
 			camel_multipart_set_boundary(multipart, NULL);
 			camel_multipart_add_part (multipart, part);

Modified: branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-transport.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-transport.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-transport.c	Fri Aug 22 09:18:54 2008
@@ -149,21 +149,39 @@
 		     CamelStream *content_stream, int content_size)
 {
 	guint8 *buf = g_new0 (guint8 , STREAM_SIZE);
-	guint32	read_size;
+	guint32	read_size, flag;
 	ExchangeMAPIAttachment *item_attach;
+	ExchangeMAPIStream *stream; 
+
 	item_attach = g_new0 (ExchangeMAPIAttachment, 1);
 
-	//?? :	attach->id = contents->n_attach;
+	item_attach->cValues = 4; 
+	item_attach->lpProps = g_new0 (struct SPropValue, 4); 
+
+	flag = ATTACH_BY_VALUE; 
+	set_SPropValue_proptag(&(item_attach->lpProps[0]), PR_ATTACH_METHOD, (const void *) (&flag));
+
+	/* MSDN Documentation: When the supplied offset is -1 (0xFFFFFFFF), the 
+	 * attachment is not rendered using the PR_RENDERING_POSITION property. 
+	 * All values other than -1 indicate the position within PR_BODY at which 
+	 * the attachment is to be rendered. 
+	 */
+	flag = 0xFFFFFFFF;
+	set_SPropValue_proptag(&(item_attach->lpProps[1]), PR_RENDERING_POSITION, (const void *) (&flag));
+
 	if (filename) {
-		item_attach->filename = g_strdup(filename);
+		set_SPropValue_proptag(&(item_attach->lpProps[2]), PR_ATTACH_FILENAME, (const void *) g_strdup(filename));
+		set_SPropValue_proptag(&(item_attach->lpProps[3]), PR_ATTACH_LONG_FILENAME, (const void *) g_strdup(filename));
 	}
 
-	item_attach->value = g_byte_array_new ();
-
+	stream = g_new0 (ExchangeMAPIStream, 1);
+	stream->proptag = PR_ATTACH_DATA_BIN; 
+	stream->value = g_byte_array_new ();
 	camel_seekable_stream_seek((CamelSeekableStream *)content_stream, 0, CAMEL_STREAM_SET);
 	while((read_size = camel_stream_read(content_stream, (char *)buf, STREAM_SIZE))){
-		item_attach->value = g_byte_array_append (item_attach->value, buf, read_size);
+		stream->value = g_byte_array_append (stream->value, buf, read_size);
 	}
+	item_attach->streams = g_slist_append (item_attach->streams, stream); 
 
 	item->attachments = g_slist_append(item->attachments, item_attach);
 

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c	Fri Aug 22 09:18:54 2008
@@ -205,16 +205,39 @@
 
 		if (mapped_file && g_str_has_prefix (filename, uid)) {
 			ExchangeMAPIAttachment *attach_item;
+			ExchangeMAPIStream *stream; 
 			gchar *attach = g_mapped_file_get_contents (mapped_file);
 			guint filelength = g_mapped_file_get_length (mapped_file);
 			const gchar *split_name = (filename + strlen (uid) + strlen ("-"));
+			uint32_t flag; 
 
 			new_attach_list = g_slist_append (new_attach_list, g_strdup (sfname_uri));
 
 			attach_item = g_new0 (ExchangeMAPIAttachment, 1);
-			attach_item->filename = g_strdup(split_name);
-			attach_item->value = g_byte_array_sized_new (filelength);
-			attach_item->value = g_byte_array_append (attach_item->value, attach, filelength);
+
+			attach_item->cValues = 4; 
+			attach_item->lpProps = g_new0 (struct SPropValue, 4); 
+
+			flag = ATTACH_BY_VALUE; 
+			set_SPropValue_proptag(&(attach_item->lpProps[0]), PR_ATTACH_METHOD, (const void *) (&flag));
+
+			/* MSDN Documentation: When the supplied offset is -1 (0xFFFFFFFF), the 
+			 * attachment is not rendered using the PR_RENDERING_POSITION property. 
+			 * All values other than -1 indicate the position within PR_BODY at which 
+			 * the attachment is to be rendered. 
+			 */
+			flag = 0xFFFFFFFF;
+			set_SPropValue_proptag(&(attach_item->lpProps[1]), PR_RENDERING_POSITION, (const void *) (&flag));
+
+			set_SPropValue_proptag(&(attach_item->lpProps[2]), PR_ATTACH_FILENAME, (const void *) g_strdup(split_name));
+			set_SPropValue_proptag(&(attach_item->lpProps[3]), PR_ATTACH_LONG_FILENAME, (const void *) g_strdup(split_name));
+
+			stream = g_new0 (ExchangeMAPIStream, 1);
+			stream->proptag = PR_ATTACH_DATA_BIN; 
+			stream->value = g_byte_array_sized_new (filelength);
+			stream->value = g_byte_array_append (stream->value, attach, filelength);
+			attach_item->streams = g_slist_append (attach_item->streams, stream); 
+
 			*attach_list = g_slist_append (*attach_list, attach_item);
 
 			g_mapped_file_free (mapped_file);
@@ -390,14 +413,23 @@
 	e_cal_component_get_uid (comp, &uid);
 	for (l = attach_list; l ; l = l->next) {
 		ExchangeMAPIAttachment *attach_item = (ExchangeMAPIAttachment *) (l->data);
-		gchar *attach_file_url, *filename;
+		ExchangeMAPIStream *stream; 
+		gchar *attach_file_url, *filename; 
+		const char *str, *attach;
 		guint len;
 		int fd = -1;
 
-		gchar *attach = (const char *)attach_item->value->data;
-		len = attach_item->value->len;
+		stream = exchange_mapi_util_find_stream (attach_item->streams, PR_ATTACH_DATA_BIN);
+		if (!stream)
+			continue;
+
+		attach = (const char *)stream->value->data;
+		len = stream->value->len;
 
-		attach_file_url = g_strconcat (local_store_uri, G_DIR_SEPARATOR_S, uid, "-", attach_item->filename, NULL);
+		str = (const char *) exchange_mapi_util_find_SPropVal_array_propval(attach_item->lpProps, PR_ATTACH_LONG_FILENAME);
+		if (!(str && *str))
+			str = (const char *) exchange_mapi_util_find_SPropVal_array_propval(attach_item->lpProps, PR_ATTACH_FILENAME);
+		attach_file_url = g_strconcat (local_store_uri, G_DIR_SEPARATOR_S, uid, "-", str, NULL);
 		filename = g_filename_from_uri (attach_file_url, NULL, NULL);
 
 		fd = g_open (filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c	Fri Aug 22 09:18:54 2008
@@ -55,13 +55,12 @@
 #define DISABLE_VERBOSE_LOG()
 //#endif 
 
-/* Specifies READ/WRITE sizes to be used while handling attachment streams */
-#define ATTACH_MAX_READ_SIZE  0x1000
-#define ATTACH_MAX_WRITE_SIZE 0x1000
-
-/* Specifies READ/WRITE sizes to be used while handling normal streams (struct SBinary_short) */
-#define STREAM_MAX_READ_SIZE  0x1000
-#define STREAM_MAX_WRITE_SIZE 0x1000
+/* Specifies READ/WRITE sizes to be used while handling normal streams */
+#define STREAM_MAX_READ_SIZE    0x1000
+#define STREAM_MAX_WRITE_SIZE   0x1000
+#define STREAM_ACCESS_READ      0x0000
+#define STREAM_ACCESS_WRITE     0x0001
+#define STREAM_ACCESS_READWRITE 0x0002
 
 static struct mapi_session *
 mapi_profile_load (const char *profname, const char *password)
@@ -73,7 +72,7 @@
 
 	d(g_print("\n%s(%d): Entering %s ", __FILE__, __LINE__, __PRETTY_FUNCTION__));
 
-	profpath = g_build_filename (g_getenv("HOME"), DEFAULT_PROF_PATH, NULL);
+	profpath = g_build_filename (g_get_home_dir(), DEFAULT_PROF_PATH, NULL);
 	if (!g_file_test (profpath, G_FILE_TEST_EXISTS)) {
 		g_warning ("\nMAPI profile database @ %s not found ", profpath);
 		goto cleanup;
@@ -149,14 +148,14 @@
 static gboolean 
 exchange_mapi_util_read_generic_stream (mapi_object_t *obj_message, uint32_t proptag, GSList **stream_list)
 {
-	enum MAPISTATUS			retval;
-	TALLOC_CTX 			*mem_ctx;
-	DATA_BLOB 			body;
-	struct SPropTagArray 		*SPropTagArray;
-	struct SPropValue 		*lpProps;
-	uint32_t			count, i;
-	const struct SBinary_short 	*bin;
-	struct mapi_SPropValue_array 	properties_array;
+	enum MAPISTATUS	retval;
+	TALLOC_CTX 	*mem_ctx;
+	mapi_object_t 	obj_stream;
+	uint32_t 	cn_read = 0;
+	uint32_t 	off_data = 0;
+	uint8_t		*buf_data = NULL;
+	uint32_t 	buf_size = 0;
+	gboolean 	done = FALSE;
 
 	/* sanity */
 	g_return_val_if_fail (obj_message, FALSE);
@@ -169,77 +168,68 @@
 	d(g_print("\nAttempt to read stream for proptag 0x%08X ", proptag));
 
 	mem_ctx = talloc_init ("ExchangeMAPI_ReadGenericStream");
+	mapi_object_init(&obj_stream);
 
-	/* initialize body DATA_BLOB */
-	body.length = 0;
-	body.data = talloc_zero(mem_ctx, uint8_t);
-
-	/* Build the array of properties we want to fetch */
-	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, proptag);
-	retval = GetProps(obj_message, SPropTagArray, &lpProps, &count);
-	MAPIFreeBuffer(SPropTagArray);
-
-	if (retval != MAPI_E_SUCCESS || count != 0x1) {
-		mapi_errstr("GetProps", GetLastError());
-		return FALSE;
+	/* get a stream on specified proptag */
+	retval = OpenStream(obj_message, proptag, STREAM_ACCESS_READ, &obj_stream);
+	if (retval != MAPI_E_SUCCESS) {
+	/* If OpenStream failed, should we attempt any other call(s) to fetch the blob? */
+		mapi_errstr("OpenStream", GetLastError());
+		goto cleanup;
 	}
 
-	/* Build a mapi_SPropValue_array structure */
-	properties_array.cValues = count;
-	properties_array.lpProps = talloc_array (mem_ctx, struct mapi_SPropValue, count);
-	for (i=0; i < count; i++)
-		cast_mapi_SPropValue(&properties_array.lpProps[i], &lpProps[i]);
-
-	bin = (const struct SBinary_short *) find_mapi_SPropValue_data(&properties_array, proptag);
-	if (bin && bin->lpb) {
-		body.data = talloc_memdup(mem_ctx, bin->lpb, bin->cb);
-		body.length = bin->cb;
-	} else {
-		mapi_object_t 	obj_stream;
-		uint32_t 	cn_read;
-		uint8_t		buf[STREAM_MAX_READ_SIZE];
+	/* NOTE: This may prove unreliable for streams larger than 4GB length */
+	retval = GetStreamSize(&obj_stream, &buf_size);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("GetStreamSize", GetLastError());
+		goto cleanup;
+	}
 
-		mapi_object_init(&obj_stream);
+	buf_data = talloc_size (mem_ctx, buf_size);
+	if (!buf_data)
+		goto cleanup; 
 
-		/* get a stream on specified proptag */
-		retval = OpenStream(obj_message, proptag, 0, &obj_stream);
-		if (retval != MAPI_E_SUCCESS) {
-			mapi_errstr("OpenStream", GetLastError());
-			goto cleanup;
+	/* Read from the stream */
+	while (!done) {
+		retval = ReadStream(&obj_stream,
+				    (buf_data) + off_data,
+				    STREAM_MAX_READ_SIZE,
+				    &cn_read);
+		if (retval != MAPI_E_SUCCESS) { 
+			mapi_errstr("ReadStream", GetLastError());
+			done = TRUE; 
+		} else if (cn_read == 0) {
+			done = TRUE; 
+		} else {
+			off_data += cn_read;
+			if (off_data >= buf_size)
+				done = TRUE;
 		}
+	};
 
-		/* read from the stream */
-		do {
-			retval = ReadStream(&obj_stream, buf, STREAM_MAX_READ_SIZE, &cn_read);
-			if (retval != MAPI_E_SUCCESS) {
-				cn_read = 0;
-				mapi_errstr("ReadStream", GetLastError());
-			} else if (cn_read) {
-				body.data = talloc_realloc(mem_ctx, body.data, uint8_t,
-							    body.length + cn_read);
-				memcpy(&(body.data[body.length]), buf, cn_read);
-				body.length += cn_read;
-			}
-		} while (cn_read);
-	cleanup: 
-		mapi_object_release(&obj_stream);
-	}
+	if (retval == MAPI_E_SUCCESS) {
+		ExchangeMAPIStream 		*stream = g_new0 (ExchangeMAPIStream, 1);
+		struct mapi_SPropValue_array 	properties_array;
 
-	if (retval == MAPI_E_SUCCESS && body.length) {
-		ExchangeMAPIStream 	*stream = g_new0 (ExchangeMAPIStream, 1);
+		stream->value = g_byte_array_sized_new (off_data);
+		stream->value = g_byte_array_append (stream->value, buf_data, off_data);
 
+		/* Build a mapi_SPropValue_array structure */
+		properties_array.cValues = 1; 
+		properties_array.lpProps = talloc_array (mem_ctx, struct mapi_SPropValue, properties_array.cValues);
+		properties_array.lpProps[0].ulPropTag = proptag; 
 		/* This call is needed in case the read stream was a named prop. */
 		mapi_SPropValue_array_named (obj_message, &properties_array);
 
-		stream->value = g_byte_array_sized_new (body.length);
-		stream->value = g_byte_array_append (stream->value, body.data, body.length);
-
 		stream->proptag = properties_array.lpProps[0].ulPropTag;
+
 		d(g_print("\nAttempt succeeded for proptag 0x%08X (after name conversion) ", stream->proptag));
 
 		*stream_list = g_slist_append (*stream_list, stream);
 	}
 
+cleanup: 
+	mapi_object_release(&obj_stream);
 	talloc_free (mem_ctx);
 
 	d(g_print("\n%s(%d): Leaving %s ", __FILE__, __LINE__, __PRETTY_FUNCTION__));
@@ -352,7 +342,7 @@
 //			if (!(rtf_in_sync && *rtf_in_sync)) {
 				mapi_object_init(&obj_stream);
 
-				retval = OpenStream(obj_message, PR_RTF_COMPRESSED, 0, &obj_stream);
+				retval = OpenStream(obj_message, PR_RTF_COMPRESSED, STREAM_ACCESS_READ, &obj_stream);
 				if (retval != MAPI_E_SUCCESS) {
 					mapi_errstr("OpenStream", GetLastError());
 					mapi_object_release(&obj_stream);
@@ -390,73 +380,82 @@
 	return (retval == MAPI_E_SUCCESS);
 }
 
-/* Returns TRUE if all attachments were written succcesfully, else returns FALSE */
-#define	MAX_READ_SIZE	0x1000
-
+/* Returns TRUE if all streams were written succcesfully, else returns FALSE */
 static gboolean
-exchange_mapi_util_set_generic_streams (mapi_object_t *obj_message, GSList *stream_list) 
+exchange_mapi_util_write_generic_streams (mapi_object_t *obj_message, GSList *stream_list) 
 {
 
-	TALLOC_CTX 	*mem_ctx;
+//	TALLOC_CTX 	*mem_ctx;
 	GSList 		*l;
+	enum MAPISTATUS	retval;
 	gboolean 	status = TRUE;
 
 	d(g_print("\n%s(%d): Entering %s ", __FILE__, __LINE__, __PRETTY_FUNCTION__));
 
-	mem_ctx = talloc_init ("ExchangeMAPI_Set_GenericStreams");
+//	mem_ctx = talloc_init ("ExchangeMAPI_WriteGenericStreams");
 
 	for (l = stream_list; l; l = l->next) {
-		ExchangeMAPIStream *generic_stream = (ExchangeMAPIStream *) (l->data);
-
-		enum MAPISTATUS	retval;
-		DATA_BLOB	stream;
-		uint32_t	size;
-		uint32_t	offset;
-		uint16_t	read_size;
+		ExchangeMAPIStream 	*stream = (ExchangeMAPIStream *) (l->data);
+		uint32_t 		total_written;
+		gboolean 		done = FALSE;
 		mapi_object_t		obj_stream;
 
-		uint32_t mapitag = generic_stream->proptag;
-		uint32_t access_flags = 2; //TODO : Figure out what this is ?
-
 		mapi_object_init(&obj_stream);
-		retval = OpenStream(obj_message, mapitag, access_flags, &obj_stream);
-		if (retval != MAPI_E_SUCCESS) 
-			return false;
 
-		size = MAX_READ_SIZE;
-		offset = 0;
-		while (offset <= generic_stream->value->len) {
-			stream.length = size;
-			stream.data = talloc_size(mem_ctx, size);
-			memcpy(stream.data, generic_stream->value->data + offset, size);
-			retval = WriteStream(&obj_stream, &stream, &read_size);
-			talloc_free(stream.data);
+		/* OpenStream on required proptag */
+		retval = OpenStream(obj_message, stream->proptag, STREAM_ACCESS_READWRITE, &obj_stream);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("OpenStream", GetLastError());
+			goto cleanup;
+		}
+
+		/* Set the stream size */
+		retval = SetStreamSize(&obj_stream, stream->value->len);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("SetStreamSize", GetLastError());
+			goto cleanup;
+		}
+
+		total_written = 0;
+		/* Write attachment */
+		while (!done) {
+			uint16_t 	cn_written = 0;
+			DATA_BLOB 	blob;
+
+			blob.length = (stream->value->len - total_written) < STREAM_MAX_WRITE_SIZE ? 
+					(stream->value->len - total_written) : STREAM_MAX_WRITE_SIZE;
+			blob.data = (stream->value->data) + total_written;
+
+			retval = WriteStream(&obj_stream,
+					     &blob,
+					     &cn_written);
+
 			if (retval != MAPI_E_SUCCESS) {
-				status = FALSE;
-				goto cleanup;
+				mapi_errstr("WriteStream", GetLastError());
+				done = TRUE;
+			} else if (cn_written == 0) {
+				done = TRUE; 
+			} else {
+				total_written += cn_written;
+				if (total_written >= stream->value->len)
+					done = TRUE;
 			}
-			printf(".");
-			fflush(0);
+		}
 
-			/* Exit when there is nothing left to write */
-			if (!read_size) 
-				break;
-		
-			offset += read_size;
-			
-			if ((offset + size) > generic_stream->value->len) {
-				size = generic_stream->value->len - offset;
-			}
+		/* Commit the stream */
+		retval = CommitStream(&obj_stream);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("CommitStream", GetLastError());
+			goto cleanup;
 		}
 
 	cleanup:
 		if (retval != MAPI_E_SUCCESS) 
 			status = FALSE;
-
-		//mapi_object_release(&obj_stream);
+		mapi_object_release(&obj_stream);
 	}
 
-	talloc_free (mem_ctx);
+//	talloc_free (mem_ctx);
 
 	d(g_print("\n%s(%d): Leaving %s ", __FILE__, __LINE__, __PRETTY_FUNCTION__));
 
@@ -479,14 +478,11 @@
 
 	mem_ctx = talloc_init ("ExchangeMAPI_DeleteAttachments");
 
-	proptags = set_SPropTagArray(mem_ctx, 0x7, 
+	proptags = set_SPropTagArray(mem_ctx, 0x4, 
 				     PR_ATTACH_NUM, 
 				     PR_INSTANCE_KEY, 
 				     PR_RECORD_KEY, 
-				     PR_RENDERING_POSITION,
-				     PR_ATTACH_FILENAME, 
-				     PR_ATTACH_LONG_FILENAME,  
-				     PR_ATTACH_SIZE);
+				     PR_RENDERING_POSITION);
 
 	mapi_object_init(&obj_tb_attach);
 
@@ -543,8 +539,7 @@
 static gboolean
 exchange_mapi_util_set_attachments (mapi_object_t *obj_message, GSList *attach_list, gboolean remove_existing)
 {
-	TALLOC_CTX 	*mem_ctx;
-	const uint32_t 	cn_props_attach = 4;
+//	TALLOC_CTX 	*mem_ctx;
 	GSList 		*l;
 	enum MAPISTATUS	retval;
 	gboolean 	status = TRUE;
@@ -554,20 +549,13 @@
 	if (remove_existing)
 		exchange_mapi_util_delete_attachments (obj_message);
 
-	mem_ctx = talloc_init ("ExchangeMAPI_SetAttachments");
+//	mem_ctx = talloc_init ("ExchangeMAPI_SetAttachments");
 
 	for (l = attach_list; l; l = l->next) {
 		ExchangeMAPIAttachment 	*attachment = (ExchangeMAPIAttachment *) (l->data);
-		uint32_t 		flag;
-		uint32_t 		total_written;
-		gboolean 		done = FALSE;
-		struct SPropValue 	*props_attach;
 		mapi_object_t		obj_attach;
-		mapi_object_t		obj_stream;
 
-		props_attach = talloc_array (mem_ctx, struct SPropValue, cn_props_attach);
 		mapi_object_init(&obj_attach);
-		mapi_object_init(&obj_stream);
 
 		/* CreateAttach */
 		retval = CreateAttach(obj_message, &obj_attach);
@@ -576,57 +564,15 @@
 			goto cleanup;
 		}
 
-		flag = ATTACH_BY_VALUE; 
-		set_SPropValue_proptag(&props_attach[0], PR_ATTACH_METHOD, (const void *) (&flag));
-
-		/* MSDN Documentation: When the supplied offset is -1 (0xFFFFFFFF), the 
-		 * attachment is not rendered using the PR_RENDERING_POSITION property. 
-		 * All values other than -1 indicate the position within PR_BODY at which 
-		 * the attachment is to be rendered. 
-		 */
-		flag = 0xFFFFFFFF;
-		set_SPropValue_proptag(&props_attach[1], PR_RENDERING_POSITION, (const void *) (&flag));
-
-		set_SPropValue_proptag(&props_attach[2], PR_ATTACH_FILENAME, (const void *) attachment->filename);
-		set_SPropValue_proptag(&props_attach[3], PR_ATTACH_LONG_FILENAME, (const void *) attachment->filename);
-
 		/* SetProps */
-		retval = SetProps(&obj_attach, props_attach, cn_props_attach);
+		retval = SetProps(&obj_attach, attachment->lpProps, attachment->cValues);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("SetProps", GetLastError());
 			goto cleanup;
 		}
 
-		/* OpenStream on CreateAttach handle */
-		retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
-		if (retval != MAPI_E_SUCCESS) {
-			mapi_errstr("OpenStream", GetLastError());
-			goto cleanup;
-		}
-
-		total_written = 0;
-		/* Write attachment */
-		while (!done) {
-			uint16_t 	cn_written = 0;
-			DATA_BLOB 	blob;
-
-			blob.length = (attachment->value->len - total_written) < ATTACH_MAX_WRITE_SIZE ? 
-					(attachment->value->len - total_written) : ATTACH_MAX_WRITE_SIZE;
-			blob.data = (attachment->value->data) + total_written;
-
-			retval = WriteStream(&obj_stream,
-					     &blob,
-					     &cn_written);
-
-			if ((retval != MAPI_E_SUCCESS) || (cn_written == 0)) {
-				mapi_errstr("WriteStream", GetLastError());
-				done = TRUE;
-			} else {
-				total_written += cn_written;
-				if (total_written >= attachment->value->len)
-					done = TRUE;
-			}
-		}
+		/* If there are any streams to be set, write them. */
+		exchange_mapi_util_write_generic_streams (&obj_attach, attachment->streams);
 
 		/* message->SaveChanges() */
 		retval = SaveChanges(obj_message, &obj_attach, KEEP_OPEN_READWRITE);
@@ -638,12 +584,10 @@
 	cleanup:
 		if (retval != MAPI_E_SUCCESS) 
 			status = FALSE;
-		mapi_object_release(&obj_stream);
 		mapi_object_release(&obj_attach);
-		talloc_free (props_attach);
 	}
 
-	talloc_free (mem_ctx);
+//	talloc_free (mem_ctx);
 
 	d(g_print("\n%s(%d): Leaving %s ", __FILE__, __LINE__, __PRETTY_FUNCTION__));
 
@@ -667,16 +611,12 @@
 
 	mem_ctx = talloc_init ("ExchangeMAPI_GetAttachments");
 
-	/* do we need MIME tag, MIME sequence etc ? */
-	proptags = set_SPropTagArray(mem_ctx, 0x8, 
+	proptags = set_SPropTagArray(mem_ctx, 0x5, 
 				     PR_ATTACH_NUM, 
 				     PR_INSTANCE_KEY, 
 				     PR_RECORD_KEY, 
-				     PR_RENDERING_POSITION,
-				     PR_ATTACH_FILENAME, 
-				     PR_ATTACH_LONG_FILENAME,  
-				     PR_ATTACH_MIME_TAG,
-				     PR_ATTACH_SIZE);
+				     PR_RENDERING_POSITION, 
+				     PR_ATTACH_METHOD);
 
 	mapi_object_init(&obj_tb_attach);
 
@@ -707,76 +647,50 @@
 
 	/* foreach attachment, open by PR_ATTACH_NUM */
 	for (i_row_attach = 0; i_row_attach < rows_attach.cRows; i_row_attach++) {
-		const uint32_t	*num_attach;
+		ExchangeMAPIAttachment 	*attachment;
+		struct mapi_SPropValue_array properties;
+		const uint32_t	*ui32;
 		mapi_object_t	obj_attach;
-		mapi_object_t 	obj_stream;
-		uint32_t 	cn_read = 0;
-		uint32_t 	off_data = 0;
-		gboolean 	done = FALSE;
-		uint8_t 	*buf_data = NULL;
-		const uint32_t 	*sz_data;
+		uint32_t 	z;
 
 		mapi_object_init(&obj_attach);
-		mapi_object_init(&obj_stream);
 
-		num_attach = (const uint32_t *) get_SPropValue_SRow_data(&rows_attach.aRow[i_row_attach], PR_ATTACH_NUM);
+		ui32 = (const uint32_t *) get_SPropValue_SRow_data(&rows_attach.aRow[i_row_attach], PR_ATTACH_NUM);
 
-		retval = OpenAttach(obj_message, *num_attach, &obj_attach);
+		retval = OpenAttach(obj_message, *ui32, &obj_attach);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("OpenAttach", GetLastError());
 			goto loop_cleanup;
 		}
 
-		/* get a stream on PR_ATTACH_DATA_BIN */
-		retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
+		retval = GetPropsAll (&obj_attach, &properties);
 		if (retval != MAPI_E_SUCCESS) {
-			mapi_errstr("OpenStream", GetLastError());
+			mapi_errstr("GetPropsAll", GetLastError());
 			goto loop_cleanup;
 		}
 
-		/* Alloc buffer */
-		sz_data = (const uint32_t *) get_SPropValue_SRow_data(&rows_attach.aRow[i_row_attach], PR_ATTACH_SIZE);
-		buf_data = talloc_size(mem_ctx, *sz_data);
-
-		if (buf_data == 0)
-			goto loop_cleanup;
+		attachment = g_new0 (ExchangeMAPIAttachment, 1);
+		attachment->cValues = properties.cValues; 
+		attachment->lpProps = g_new0 (struct SPropValue, attachment->cValues);
+		for (z=0; z < properties.cValues; z++) 
+			cast_SPropValue (&properties.lpProps[z], &(attachment->lpProps[z]));
 
-		/* Read attachment from stream */
-		while (!done) {
-			retval = ReadStream(&obj_stream,
-					    (buf_data) + off_data,
-					    ATTACH_MAX_READ_SIZE,
-					    &cn_read);
-			if ((retval != MAPI_E_SUCCESS) || (cn_read == 0)) {
-				mapi_errstr("ReadStream", GetLastError());
-				done = TRUE;
-			} else {
-				off_data += cn_read;
-				if (off_data >= *sz_data)
-					done = TRUE;
-			}
+		/* just to get all the other streams */
+		for (z=0; z < properties.cValues; z++) {
+			if ((properties.lpProps[z].ulPropTag & 0xFFFF) == PT_BINARY) 
+				exchange_mapi_util_read_generic_stream (&obj_attach, properties.lpProps[z].ulPropTag, &(attachment->streams));
 		}
 
-		if (retval == MAPI_E_SUCCESS) {
-			ExchangeMAPIAttachment 	*attachment = g_new0 (ExchangeMAPIAttachment, 1);
-
-			attachment->value = g_byte_array_sized_new (off_data);
-			attachment->value = g_byte_array_append (attachment->value, buf_data, off_data);
+		/* HACK */
+		ui32 = (const uint32_t *) get_SPropValue_SRow_data(&rows_attach.aRow[i_row_attach], PR_ATTACH_METHOD);
+		if (ui32 && *ui32 == ATTACH_BY_VALUE)
+			exchange_mapi_util_read_generic_stream (&obj_attach, PR_ATTACH_DATA_BIN, &(attachment->streams));
 
-			attachment->filename = (const char *) get_SPropValue_SRow_data(&rows_attach.aRow[i_row_attach], PR_ATTACH_LONG_FILENAME);
-			if (!(attachment->filename && *attachment->filename))
-				attachment->filename = (const char *) get_SPropValue_SRow_data(&rows_attach.aRow[i_row_attach], PR_ATTACH_FILENAME);
-
-			attachment->mime_type = (const char *) find_SPropValue_data (&rows_attach.aRow[i_row_attach], PR_ATTACH_MIME_TAG);
-
-			*attach_list = g_slist_append (*attach_list, attachment);
-		}
-		talloc_free (buf_data);
+		*attach_list = g_slist_append (*attach_list, attachment);
 
 	loop_cleanup:
 		if (retval != MAPI_E_SUCCESS)
 			status = FALSE;
-		mapi_object_release(&obj_stream);
 		mapi_object_release(&obj_attach);
 	}
 
@@ -814,27 +728,25 @@
 	}
 
 	for (i_row_recip = 0; i_row_recip < rows_recip.cRows; i_row_recip++) {
-		if (retval == MAPI_E_SUCCESS) {
-			ExchangeMAPIRecipient 	*recipient = g_new0 (ExchangeMAPIRecipient, 1);
+		ExchangeMAPIRecipient 	*recipient = g_new0 (ExchangeMAPIRecipient, 1);
 
-			recipient->email_id = (const char *) exchange_mapi_util_find_row_propval (&(rows_recip.aRow[i_row_recip]), PR_SMTP_ADDRESS);
-			/* fallback */
-			if (!recipient->email_id) {
-				const char *addrtype = (const char *) exchange_mapi_util_find_row_propval (&(rows_recip.aRow[i_row_recip]), PR_ADDRTYPE);
-				if (addrtype && !g_ascii_strcasecmp(addrtype, "SMTP"))
-					recipient->email_id = (const char *) exchange_mapi_util_find_row_propval (&(rows_recip.aRow[i_row_recip]), PR_EMAIL_ADDRESS);
-			}
-			/* fail */
-			if (!recipient->email_id) {
-				g_warning ("\n%s:%d %s() - object has a recipient without a PR_SMTP_ADDRESS ", __FILE__, __LINE__, __PRETTY_FUNCTION__);
-				mapidump_SRow (&(rows_recip.aRow[i_row_recip]), " ");
-			}
+		recipient->email_id = (const char *) exchange_mapi_util_find_row_propval (&(rows_recip.aRow[i_row_recip]), PR_SMTP_ADDRESS);
+		/* fallback */
+		if (!recipient->email_id) {
+			const char *addrtype = (const char *) exchange_mapi_util_find_row_propval (&(rows_recip.aRow[i_row_recip]), PR_ADDRTYPE);
+			if (addrtype && !g_ascii_strcasecmp(addrtype, "SMTP"))
+				recipient->email_id = (const char *) exchange_mapi_util_find_row_propval (&(rows_recip.aRow[i_row_recip]), PR_EMAIL_ADDRESS);
+		}
+		/* fail */
+		if (!recipient->email_id) {
+			g_warning ("\n%s:%d %s() - object has a recipient without a PR_SMTP_ADDRESS ", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+			mapidump_SRow (&(rows_recip.aRow[i_row_recip]), " ");
+		}
 
-			recipient->out.all_lpProps = rows_recip.aRow[i_row_recip].lpProps;
-			recipient->out.all_cValues = rows_recip.aRow[i_row_recip].cValues;
+		recipient->out.all_lpProps = rows_recip.aRow[i_row_recip].lpProps;
+		recipient->out.all_cValues = rows_recip.aRow[i_row_recip].cValues;
 
-			*recip_list = g_slist_append (*recip_list, recipient);
-		}
+		*recip_list = g_slist_append (*recip_list, recipient);
 	}
 
 cleanup:
@@ -867,7 +779,7 @@
 		if (!email)
 			email = "";
 		oneoff_eid = exchange_mapi_util_entryid_generate_oneoff (mem_ctx, dn, email, FALSE);
-		set_SPropValue_proptag (&sprop,  PR_ENTRYID, (const void *)(oneoff_eid));
+		set_SPropValue_proptag (&sprop, PR_ENTRYID, (const void *)(oneoff_eid));
 		SRow_addprop (aRow, sprop);
 	}
 
@@ -2075,7 +1987,7 @@
 	}
 
 	if (generic_streams) {
-		exchange_mapi_util_set_generic_streams (&obj_message, generic_streams);
+		exchange_mapi_util_write_generic_streams (&obj_message, generic_streams);
 	}
 
 	/* Set attachments if any */
@@ -2313,7 +2225,7 @@
 static gboolean
 mapi_move_items ( mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mid_list, gboolean do_copy)
 {
-	gboolean ret = true;
+	gboolean ret = TRUE;
 	mapi_object_t obj_store;
 	mapi_object_t obj_folder_src;
 	mapi_object_t obj_folder_dst;
@@ -2333,31 +2245,31 @@
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(&obj_store);
 	if (GetLastError() != MAPI_E_SUCCESS) {
-		ret = false;
+		ret = FALSE;
 		goto cleanup;
 	}
 
 	mapi_object_init(&obj_folder_src);
 	retval = OpenFolder(&obj_store, src_fid, &obj_folder_src);
 	if (GetLastError() != MAPI_E_SUCCESS) {
-		ret = false;
+		ret = FALSE;
 		goto cleanup;
 	}
 		
 	mapi_object_init(&obj_folder_dst);
 	retval = OpenFolder(&obj_store, dest_fid, &obj_folder_dst);
 	if (GetLastError() != MAPI_E_SUCCESS) {
-		ret = false;
+		ret = FALSE;
 		goto cleanup;
 	}
 
 	retval = MoveCopyMessages(&obj_folder_src, &obj_folder_dst, &msg_id_array, do_copy);
 	if (retval != MAPI_E_SUCCESS) {
-		ret = false;
+		ret = FALSE;
 		goto cleanup;
 	}
 
-	ret = true;
+	ret = TRUE;
 
 cleanup:
 	UNLOCK();

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h	Fri Aug 22 09:18:54 2008
@@ -37,20 +37,13 @@
 	MAPI_OPTIONS_DONT_SUBMIT = 1<<4, 
 	MAPI_OPTIONS_GETBESTBODY = 1<<5,
 	MAPI_OPTIONS_USE_PFSTORE = 1<<6
-} ExchangeMapiOptions;
+} ExchangeMAPIOptions;
 
 #define MAPI_OPTIONS_FETCH_ALL MAPI_OPTIONS_FETCH_ATTACHMENTS | \
 	                       MAPI_OPTIONS_FETCH_RECIPIENTS | \
 	                       MAPI_OPTIONS_FETCH_BODY_STREAM | \
 	                       MAPI_OPTIONS_FETCH_GENERIC_STREAMS
 
-/* FIXME: need to accomodate rendering position */
-typedef struct {
-	GByteArray *value;
-	const gchar *filename;
-	const gchar *mime_type;
-} ExchangeMAPIAttachment;
-
 typedef struct {
 	GByteArray *value;
 	uint32_t proptag;
@@ -88,6 +81,13 @@
 	} out; 
 } ExchangeMAPIRecipient;
 
+typedef struct {
+	uint32_t cValues; 
+	struct SPropValue *lpProps; 
+	GSList *streams; 
+	GSList *objects; 
+} ExchangeMAPIAttachment;
+
 struct id_list {
 	mapi_id_t id;
 };

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-folder.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-folder.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-folder.c	Fri Aug 22 09:18:54 2008
@@ -59,7 +59,7 @@
 }
 
 ExchangeMAPIFolder *
-exchange_mapi_folder_new (const char *folder_name, const char *parent_folder_name, const char *container_class, ExchangeMAPIFolderCategory category, uint64_t folder_id, uint64_t parent_folder_id, uint32_t child_count, uint32_t unread_count, uint32_t total)
+exchange_mapi_folder_new (const char *folder_name, const char *parent_folder_name, const char *container_class, ExchangeMAPIFolderCategory category, mapi_id_t folder_id, mapi_id_t parent_folder_id, uint32_t child_count, uint32_t unread_count, uint32_t total)
 {
 	ExchangeMAPIFolder *folder;
 
@@ -138,7 +138,7 @@
 }
 
 ExchangeMAPIFolder *
-exchange_mapi_folder_get_folder (uint64_t fid)
+exchange_mapi_folder_get_folder (mapi_id_t fid)
 {
 	GSList *tmp = folder_list;
 

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-folder.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-folder.h	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-folder.h	Fri Aug 22 09:18:54 2008
@@ -26,6 +26,8 @@
 
 #include <glib.h>
 
+#include <libmapi/libmapi.h>
+
 typedef enum  {
 	MAPI_FOLDER_TYPE_MAIL=1,
 	MAPI_FOLDER_TYPE_APPOINTMENT,
@@ -57,8 +59,8 @@
 	gchar *parent_folder_name;
 	ExchangeMAPIFolderType container_class;
 	ExchangeMAPIFolderCategory category;
-	guint64 folder_id;
-	guint64 parent_folder_id;
+	mapi_id_t folder_id;
+	mapi_id_t parent_folder_id;
 	guint32 child_count;
 	guint32 unread_count;
 	guint32 total;
@@ -72,7 +74,7 @@
 ExchangeMAPIFolder *
 exchange_mapi_folder_new (const char *folder_name, const char *parent_folder_name, const char *container_class, 
 			  ExchangeMAPIFolderCategory catgory, 
-			  uint64_t folder_id, uint64_t parent_folder_id, 
+			  mapi_id_t folder_id, mapi_id_t parent_folder_id, 
 			  uint32_t child_count, uint32_t unread_count, uint32_t total);
 ExchangeMAPIFolderType exchange_mapi_container_class (char *type);
 
@@ -86,7 +88,7 @@
 gboolean exchange_mapi_folder_is_root (ExchangeMAPIFolder *folder);
 GSList * exchange_mapi_peek_folder_list (void);
 void exchange_mapi_folder_list_free (void);
-ExchangeMAPIFolder * exchange_mapi_folder_get_folder (uint64_t fid);
+ExchangeMAPIFolder * exchange_mapi_folder_get_folder (mapi_id_t fid);
 void exchange_mapi_folder_list_add (ExchangeMAPIFolder *folder);
 
 #endif

Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-utils.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-utils.c	(original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-utils.c	Fri Aug 22 09:18:54 2008
@@ -240,8 +240,9 @@
 
 	for (; l != NULL; l = l->next) {
 		ExchangeMAPIAttachment *attachment = (ExchangeMAPIAttachment *) (l->data);
-		g_byte_array_free (attachment->value, TRUE);
-		attachment->value = NULL;
+		/* FIXME: more stuff here */
+		g_free (attachment->lpProps);
+		exchange_mapi_util_free_stream_list (&(attachment->streams)); 
 		g_free (attachment);
 		attachment = NULL;
 	}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]