Commit 7877e657 authored by Owen Rudge's avatar Owen Rudge Committed by Alexandre Julliard

mapi32: Convert sendmail_extended_mapi to Unicode.

parent cc6205f1
...@@ -48,16 +48,35 @@ WINE_DEFAULT_DEBUG_CHANNEL(mapi); ...@@ -48,16 +48,35 @@ WINE_DEFAULT_DEBUG_CHANNEL(mapi);
#define READ_BUF_SIZE 4096 #define READ_BUF_SIZE 4096
#define STORE_UNICODE_OK 0x00040000
static LPSTR convert_from_unicode(LPCWSTR wstr)
{
LPSTR str;
DWORD len;
if (!wstr)
return NULL;
len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
str = HeapAlloc(GetProcessHeap(), 0, len);
WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
return str;
}
/* /*
Internal function to send a message via Extended MAPI. Wrapper around the Simple Internal function to send a message via Extended MAPI. Wrapper around the Simple
MAPI function MAPISendMail. MAPI function MAPISendMail.
*/ */
static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpMapiMessage message, static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpMapiMessageW message,
FLAGS flags, ULONG reserved) FLAGS flags)
{ {
ULONG tags[] = {1, PR_IPM_DRAFTS_ENTRYID}; ULONG tags[] = {1, 0};
char *subjectA = NULL, *bodyA = NULL;
ULONG retval = MAPI_E_FAILURE; ULONG retval = MAPI_E_FAILURE;
IMAPISession *session = NULL; IMAPISession *session = NULL;
BOOL unicode_aware = FALSE;
IMAPITable* msg_table; IMAPITable* msg_table;
LPSRowSet rows = NULL; LPSRowSet rows = NULL;
IMsgStore* msg_store; IMsgStore* msg_store;
...@@ -134,6 +153,24 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -134,6 +153,24 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
/* We don't need this any more */ /* We don't need this any more */
FreeProws(rows); FreeProws(rows);
/* Check if the message store supports Unicode */
tags[1] = PR_STORE_SUPPORT_MASK;
ret = IMsgStore_GetProps(msg_store, (LPSPropTagArray) tags, 0, &values, &props);
if ((ret == S_OK) && (props[0].Value.l & STORE_UNICODE_OK))
unicode_aware = TRUE;
else
{
/* Don't convert to ANSI */
if (flags & MAPI_FORCE_UNICODE)
{
WARN("No Unicode-capable mail client, and MAPI_FORCE_UNICODE is specified. MAPISendMail failed.\n");
retval = MAPI_E_UNICODE_NOT_SUPPORTED;
IMsgStore_Release(msg_store);
goto logoff;
}
}
/* First open the inbox, from which the drafts folder can be opened */ /* First open the inbox, from which the drafts folder can be opened */
if (IMsgStore_GetReceiveFolder(msg_store, NULL, 0, &entry_len, &entry_id, NULL) == S_OK) if (IMsgStore_GetReceiveFolder(msg_store, NULL, 0, &entry_len, &entry_id, NULL) == S_OK)
{ {
...@@ -141,6 +178,8 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -141,6 +178,8 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
MAPIFreeBuffer(entry_id); MAPIFreeBuffer(entry_id);
} }
tags[1] = PR_IPM_DRAFTS_ENTRYID;
/* Open the drafts folder, or failing that, try asking the message store for the outbox */ /* Open the drafts folder, or failing that, try asking the message store for the outbox */
if ((folder == NULL) || ((ret = IMAPIFolder_GetProps(folder, (LPSPropTagArray) tags, 0, &values, &props)) != S_OK)) if ((folder == NULL) || ((ret = IMAPIFolder_GetProps(folder, (LPSPropTagArray) tags, 0, &values, &props)) != S_OK))
{ {
...@@ -175,8 +214,19 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -175,8 +214,19 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
/* Set message subject */ /* Set message subject */
if (message->lpszSubject) if (message->lpszSubject)
{ {
p.ulPropTag = PR_SUBJECT_A; if (unicode_aware)
p.Value.lpszA = message->lpszSubject; {
p.ulPropTag = PR_SUBJECT_W;
p.Value.lpszW = message->lpszSubject;
}
else
{
subjectA = convert_from_unicode(message->lpszSubject);
p.ulPropTag = PR_SUBJECT_A;
p.Value.lpszA = subjectA;
}
IMessage_SetProps(msg, 1, &p, NULL); IMessage_SetProps(msg, 1, &p, NULL);
} }
...@@ -185,10 +235,17 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -185,10 +235,17 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
{ {
LPSTREAM stream = NULL; LPSTREAM stream = NULL;
if (IMessage_OpenProperty(msg, PR_BODY_A, &IID_IStream, 0, if (IMessage_OpenProperty(msg, unicode_aware ? PR_BODY_W : PR_BODY_A, &IID_IStream, 0,
MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*) &stream) == S_OK) MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*) &stream) == S_OK)
{ {
IStream_Write(stream, message->lpszNoteText, strlen(message->lpszNoteText)+1, NULL); if (unicode_aware)
IStream_Write(stream, message->lpszNoteText, (lstrlenW(message->lpszNoteText)+1) * sizeof(WCHAR), NULL);
else
{
bodyA = convert_from_unicode(message->lpszNoteText);
IStream_Write(stream, bodyA, strlen(bodyA)+1, NULL);
}
IStream_Release(stream); IStream_Release(stream);
} }
} }
...@@ -202,15 +259,16 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -202,15 +259,16 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
for (i = 0; i < message->nFileCount; i++) for (i = 0; i < message->nFileCount; i++)
{ {
IAttach* attachment = NULL; IAttach* attachment = NULL;
char *filenameA = NULL;
SPropValue prop[4]; SPropValue prop[4];
LPCSTR filename; LPCWSTR filename;
HANDLE file; HANDLE file;
if (!message->lpFiles[i].lpszPathName) if (!message->lpFiles[i].lpszPathName)
continue; continue;
/* Open the attachment for reading */ /* Open the attachment for reading */
file = CreateFileA(message->lpFiles[i].lpszPathName, GENERIC_READ, FILE_SHARE_READ, file = CreateFileW(message->lpFiles[i].lpszPathName, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) if (file == INVALID_HANDLE_VALUE)
...@@ -223,7 +281,7 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -223,7 +281,7 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
{ {
filename = message->lpFiles[i].lpszPathName; filename = message->lpFiles[i].lpszPathName;
for (j = strlen(message->lpFiles[i].lpszPathName)-1; j >= 0; j--) for (j = lstrlenW(message->lpFiles[i].lpszPathName)-1; j >= 0; j--)
{ {
if (message->lpFiles[i].lpszPathName[i] == '\\' || if (message->lpFiles[i].lpszPathName[i] == '\\' ||
message->lpFiles[i].lpszPathName[i] == '/') message->lpFiles[i].lpszPathName[i] == '/')
...@@ -234,8 +292,8 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -234,8 +292,8 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
} }
} }
TRACE("Attachment %d path: '%s'; filename: '%s'\n", i, debugstr_a(message->lpFiles[i].lpszPathName), TRACE("Attachment %d path: '%s'; filename: '%s'\n", i, debugstr_w(message->lpFiles[i].lpszPathName),
debugstr_a(filename)); debugstr_w(filename));
/* Create the attachment */ /* Create the attachment */
if (IMessage_CreateAttach(msg, NULL, 0, &num_attach, &attachment) != S_OK) if (IMessage_CreateAttach(msg, NULL, 0, &num_attach, &attachment) != S_OK)
...@@ -250,10 +308,25 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -250,10 +308,25 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
prop[0].ulPropTag = PR_ATTACH_METHOD; prop[0].ulPropTag = PR_ATTACH_METHOD;
prop[0].Value.ul = ATTACH_BY_VALUE; prop[0].Value.ul = ATTACH_BY_VALUE;
prop[1].ulPropTag = PR_ATTACH_LONG_FILENAME_A;
prop[1].Value.lpszA = (LPSTR) filename; if (unicode_aware)
prop[2].ulPropTag = PR_ATTACH_FILENAME_A; {
prop[2].Value.lpszA = (LPSTR) filename; prop[1].ulPropTag = PR_ATTACH_LONG_FILENAME_W;
prop[1].Value.lpszW = (LPWSTR) filename;
prop[2].ulPropTag = PR_ATTACH_FILENAME_W;
prop[2].Value.lpszW = (LPWSTR) filename;
}
else
{
filenameA = convert_from_unicode(filename);
prop[1].ulPropTag = PR_ATTACH_LONG_FILENAME_A;
prop[1].Value.lpszA = (LPSTR) filenameA;
prop[2].ulPropTag = PR_ATTACH_FILENAME_A;
prop[2].Value.lpszA = (LPSTR) filenameA;
}
prop[3].ulPropTag = PR_RENDERING_POSITION; prop[3].ulPropTag = PR_RENDERING_POSITION;
prop[3].Value.l = -1; prop[3].Value.l = -1;
...@@ -273,7 +346,7 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -273,7 +346,7 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
size += read; size += read;
} }
TRACE("%d bytes read, %d bytes written of attachment\n", read, written); TRACE("%d bytes written of attachment\n", size);
IStream_Commit(stream, STGC_DEFAULT); IStream_Commit(stream, STGC_DEFAULT);
IStream_Release(stream); IStream_Release(stream);
...@@ -289,6 +362,8 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -289,6 +362,8 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
CloseHandle(file); CloseHandle(file);
IAttach_Release(attachment); IAttach_Release(attachment);
HeapFree(GetProcessHeap(), 0, filenameA);
} }
} }
...@@ -360,6 +435,9 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM ...@@ -360,6 +435,9 @@ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpM
if (folder) IMAPIFolder_Release(folder); if (folder) IMAPIFolder_Release(folder);
IMsgStore_Release(msg_store); IMsgStore_Release(msg_store);
HeapFree(GetProcessHeap(), 0, subjectA);
HeapFree(GetProcessHeap(), 0, bodyA);
logoff: ; logoff: ;
IMAPISession_Logoff(session, 0, 0, 0); IMAPISession_Logoff(session, 0, 0, 0);
IMAPISession_Release(session); IMAPISession_Release(session);
...@@ -396,8 +474,10 @@ ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam, ...@@ -396,8 +474,10 @@ ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
return mapiFunctions.MAPISendMail(session, uiparam, message, flags, reserved); return mapiFunctions.MAPISendMail(session, uiparam, message, flags, reserved);
/* Check if we have an Extended MAPI provider - if so, use our wrapper */ /* Check if we have an Extended MAPI provider - if so, use our wrapper */
#if 0
if (MAPIInitialize(NULL) == S_OK) if (MAPIInitialize(NULL) == S_OK)
return sendmail_extended_mapi(session, uiparam, message, flags, reserved); return sendmail_extended_mapi(session, uiparam, message, flags);
#endif
/* Display an error message since we apparently have no mail clients */ /* Display an error message since we apparently have no mail clients */
LoadStringW(hInstMAPI32, IDS_NO_MAPI_CLIENT, error_msg, sizeof(error_msg) / sizeof(WCHAR)); LoadStringW(hInstMAPI32, IDS_NO_MAPI_CLIENT, error_msg, sizeof(error_msg) / sizeof(WCHAR));
...@@ -428,11 +508,22 @@ ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam, ...@@ -428,11 +508,22 @@ ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
ULONG WINAPI MAPISendMailW(LHANDLE session, ULONG_PTR uiparam, ULONG WINAPI MAPISendMailW(LHANDLE session, ULONG_PTR uiparam,
lpMapiMessageW message, FLAGS flags, ULONG reserved) lpMapiMessageW message, FLAGS flags, ULONG reserved)
{ {
WCHAR msg_title[READ_BUF_SIZE], error_msg[READ_BUF_SIZE];
/* Check to see if we have a Simple MAPI provider loaded */ /* Check to see if we have a Simple MAPI provider loaded */
if (mapiFunctions.MAPISendMailW) if (mapiFunctions.MAPISendMailW)
return mapiFunctions.MAPISendMailW(session, uiparam, message, flags, reserved); return mapiFunctions.MAPISendMailW(session, uiparam, message, flags, reserved);
WARN("STUB\n"); /* Check if we have an Extended MAPI provider - if so, use our wrapper */
if (MAPIInitialize(NULL) == S_OK)
return sendmail_extended_mapi(session, uiparam, message, flags);
/* Display an error message since we apparently have no mail clients */
LoadStringW(hInstMAPI32, IDS_NO_MAPI_CLIENT, error_msg, sizeof(error_msg) / sizeof(WCHAR));
LoadStringW(hInstMAPI32, IDS_SEND_MAIL, msg_title, sizeof(msg_title) / sizeof(WCHAR));
MessageBoxW((HWND) uiparam, error_msg, msg_title, MB_ICONEXCLAMATION);
return MAPI_E_NOT_SUPPORTED; return MAPI_E_NOT_SUPPORTED;
} }
......
...@@ -150,6 +150,7 @@ typedef struct ...@@ -150,6 +150,7 @@ typedef struct
#define MAPI_E_INVALID_EDITFIELDS 24 #define MAPI_E_INVALID_EDITFIELDS 24
#define MAPI_E_INVALID_RECIPS 25 #define MAPI_E_INVALID_RECIPS 25
#define MAPI_E_NOT_SUPPORTED 26 #define MAPI_E_NOT_SUPPORTED 26
#define MAPI_E_UNICODE_NOT_SUPPORTED 27
/* MAPILogon */ /* MAPILogon */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment