Index: src/libexchangemapi/exchange-mapi-utils.c
===================================================================
--- src/libexchangemapi/exchange-mapi-utils.c	(revision 190)
+++ src/libexchangemapi/exchange-mapi-utils.c	(working copy)
@@ -55,6 +55,8 @@ utf8tolinux (const char *wstring)
 
 	if (g_utf8_validate (newstr, -1, NULL)) 
 		retval = g_strdup (newstr);
+	else
+		retval = g_strdup (wstring);
 
 	talloc_free (mem_ctx);
 
Index: src/libexchangemapi/ChangeLog
===================================================================
--- src/libexchangemapi/ChangeLog	(revision 190)
+++ src/libexchangemapi/ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2009-04-06  Milan Crha  <mcrha@redhat.com>
+
+	** Part of fix for bug #569321
+
+	* exchange-mapi-utils.c: (utf8tolinux): Never return NULL, copy
+	original string on error.
+
 2009-03-19  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #574784
Index: src/camel/ChangeLog
===================================================================
--- src/camel/ChangeLog	(revision 190)
+++ src/camel/ChangeLog	(working copy)
@@ -1,3 +1,13 @@
+2009-04-06  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #569321
+
+	* camel-mapi-folder.h: (struct MapiItemHeader):
+	* camel-mapi-folder.c: (fetch_items_cb), (fetch_item_cb),
+	(mapi_populate_msg_body_from_item):
+	Convert strings from windows to utf8 encoding if necessary.
+	Claim the codepage for message body in headers.
+
 2009-03-19  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #574784
Index: src/camel/camel-mapi-folder.c
===================================================================
--- src/camel/camel-mapi-folder.c	(revision 190)
+++ src/camel/camel-mapi-folder.c	(working copy)
@@ -223,22 +223,32 @@ fetch_items_cb (FetchItemsCallbackData *
 		switch (item_data->properties->lpProps[j].ulPropTag) {
 		/* FIXME : Instead of duping. Use talloc_steal to reuse the memory */
 		case PR_NORMALIZED_SUBJECT:
+			item->header.subject = utf8tolinux (prop_data);
+			break;
 		case PR_NORMALIZED_SUBJECT_UNICODE :
 			item->header.subject = g_strdup (prop_data);
 			break;
 		case PR_DISPLAY_TO :
+			item->header.to = utf8tolinux (prop_data);
+			break;
 		case PR_DISPLAY_TO_UNICODE :
 			item->header.to = g_strdup (prop_data);
 			break;
 		case PR_DISPLAY_CC:
+			item->header.cc = utf8tolinux (prop_data);
+			break;
 		case PR_DISPLAY_CC_UNICODE:
 			item->header.cc = g_strdup (prop_data);
 			break;
 		case PR_DISPLAY_BCC:
+			item->header.bcc = utf8tolinux (prop_data);
+			break;
 		case PR_DISPLAY_BCC_UNICODE:
 			item->header.bcc = g_strdup (prop_data);
 			break;
 		case PR_SENT_REPRESENTING_NAME:
+			item->header.from = utf8tolinux (prop_data);
+			break;
 		case PR_SENT_REPRESENTING_NAME_UNICODE:
 			item->header.from = g_strdup (prop_data);
 			break;
@@ -709,6 +719,7 @@ end1:
 static const uint32_t camel_GetPropsList[] = {
 	PR_FID, 
 	PR_MID, 
+	PR_INTERNET_CPID,
 
 	PR_MESSAGE_CLASS, 
 	PR_MESSAGE_CLASS_UNICODE, 
@@ -875,24 +886,39 @@ fetch_item_cb (FetchItemsCallbackData *i
 		gconstpointer prop_data = get_mapi_SPropValue_data(&item_data->properties->lpProps[j]);
 
 		switch (item_data->properties->lpProps[j].ulPropTag) {
+		case PR_INTERNET_CPID: {
+			const uint32_t *ui32 = (const uint32_t *) prop_data;
+			if (ui32)
+				item->header.cpid = *ui32;
+			} break;
 		/*FIXME : Instead of duping. Use talloc_steal to reuse the memory*/
 		case PR_NORMALIZED_SUBJECT:
+			item->header.subject = utf8tolinux (prop_data);
+			break;
 		case PR_NORMALIZED_SUBJECT_UNICODE :
 			item->header.subject = g_strdup (prop_data);
 			break;
 		case PR_DISPLAY_TO :
+			item->header.to = utf8tolinux (prop_data);
+			break;
 		case PR_DISPLAY_TO_UNICODE :
 			item->header.to = g_strdup (prop_data);
 			break;
 		case PR_DISPLAY_CC:
+			item->header.cc = utf8tolinux (prop_data);
+			break;
 		case PR_DISPLAY_CC_UNICODE:
 			item->header.cc = g_strdup (prop_data);
 			break;
 		case PR_DISPLAY_BCC:
+			item->header.bcc = utf8tolinux (prop_data);
+			break;
 		case PR_DISPLAY_BCC_UNICODE:
 			item->header.bcc = g_strdup (prop_data);
 			break;
 		case PR_SENT_REPRESENTING_NAME:
+			item->header.from = utf8tolinux (prop_data);
+			break;
 		case PR_SENT_REPRESENTING_NAME_UNICODE:
 			item->header.from = g_strdup (prop_data);
 			break;
@@ -1048,11 +1074,20 @@ mapi_populate_msg_body_from_item (CamelM
 		if (item->is_cal)
 			camel_mime_part_set_content(part, (const char *) body->value->data, body->value->len, "text/calendar");
 		else {
+			char *buff = NULL;
+
 			type = (body->proptag == PR_BODY || body->proptag == PR_BODY_UNICODE) ? 
 				"text/plain" : "text/html";
 
+			if (item->header.cpid) {
+				buff = g_strdup_printf ("%s; charset=\"CP%d\"", type, item->header.cpid);
+				type = buff;
+			}
+
 			/*NOTE : Last byte null mess up CRLF*. Probably needs a fix in e*fetch_items. */
 			camel_mime_part_set_content (part, (const char *) body->value->data, body->value->len - 1, type );
+			g_free (buff);
+			type = NULL;
 		}
 	} else
 		camel_mime_part_set_content(part, " ", strlen(" "), "text/html");
Index: src/camel/camel-mapi-folder.h
===================================================================
--- src/camel/camel-mapi-folder.h	(revision 190)
+++ src/camel/camel-mapi-folder.h	(working copy)
@@ -70,6 +70,7 @@ typedef struct {
 	glong size;
 	time_t recieved_time;
 	time_t send_time;
+	guint cpid; /* codepage id */
 } MapiItemHeader;
 
 typedef struct {
