mapi32: Convert sendmail_extended_mapi to Unicode.
This commit is contained in:
parent
cc6205f10c
commit
7877e657de
|
@ -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
|
||||||
/* 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
|
||||||
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
|
||||||
/* 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
|
||||||
{
|
{
|
||||||
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
|
||||||
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
|
||||||
{
|
{
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
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,
|
||||||
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,
|
||||||
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
|
||||||
#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 */
|
||||||
|
|
Loading…
Reference in New Issue