/*
 * MAPISendMail implementation
 *
 * Copyright 2005 Hans Leidekker
 * Copyright 2009 Owen Rudge for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdio.h>
#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winuser.h"
#include "objbase.h"
#include "objidl.h"
#include "mapi.h"
#include "mapix.h"
#include "mapiutil.h"
#include "mapidefs.h"
#include "winreg.h"
#include "shellapi.h"
#include "shlwapi.h"
#include "wine/debug.h"
#include "util.h"
#include "res.h"

WINE_DEFAULT_DEBUG_CHANNEL(mapi);

#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;
}

static LPWSTR convert_to_unicode(LPSTR str)
{
    LPWSTR wstr;
    DWORD len;

    if (!str)
        return NULL;

    len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
    wstr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, len);

    return wstr;
}

/*
   Internal function to send a message via Extended MAPI. Wrapper around the Simple
   MAPI function MAPISendMail.
*/
static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpMapiMessageW message,
    FLAGS flags)
{
    ULONG tags[] = {1, 0};
    char *subjectA = NULL, *bodyA = NULL;
    ULONG retval = MAPI_E_FAILURE;
    IMAPISession *session = NULL;
    BOOL unicode_aware = FALSE;
    IMAPITable* msg_table;
    LPSRowSet rows = NULL;
    IMsgStore* msg_store;
    IMAPIFolder* folder = NULL, *draft_folder = NULL;
    LPENTRYID entry_id;
    LPSPropValue props;
    ULONG entry_len;
    DWORD obj_type;
    IMessage* msg;
    ULONG values;
    HRESULT ret;

    TRACE("Using Extended MAPI wrapper for MAPISendMail\n");

    /* Attempt to log on via Extended MAPI */

    ret = MAPILogonEx(0, NULL, NULL, MAPI_EXTENDED | MAPI_USE_DEFAULT | MAPI_NEW_SESSION, &session);
    TRACE("MAPILogonEx: %x\n", ret);

    if (ret != S_OK)
    {
        retval = MAPI_E_LOGIN_FAILURE;
        goto cleanup;
    }

    /* Open the default message store */

    if (IMAPISession_GetMsgStoresTable(session, 0, &msg_table) == S_OK)
    {
        /* We want the default store */
        SizedSPropTagArray(2, columns) = {2, {PR_ENTRYID, PR_DEFAULT_STORE}};

        /* Set the columns we want */
        if (IMAPITable_SetColumns(msg_table, (LPSPropTagArray) &columns, 0) == S_OK)
        {
            while (1)
            {
                if (IMAPITable_QueryRows(msg_table, 1, 0, &rows) != S_OK)
                {
                    MAPIFreeBuffer(rows);
                    rows = NULL;
                }
                else if (rows->cRows != 1)
                {
                    FreeProws(rows);
                    rows = NULL;
                }
                else
                {
                    /* If it's not the default store, try the next row */
                    if (!rows->aRow[0].lpProps[1].Value.b)
                    {
                        FreeProws(rows);
                        continue;
                    }
                }

                break;
            }
        }

        IMAPITable_Release(msg_table);
    }

    /* Did we manage to get the right store? */
    if (!rows)
        goto logoff;

    /* Open the message store */
    IMAPISession_OpenMsgStore(session, 0, rows->aRow[0].lpProps[0].Value.bin.cb,
                              (ENTRYID *) rows->aRow[0].lpProps[0].Value.bin.lpb, NULL,
                              MDB_NO_DIALOG | MAPI_BEST_ACCESS, &msg_store);

    /* We don't need this any more */
    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 */
    if (IMsgStore_GetReceiveFolder(msg_store, NULL, 0, &entry_len, &entry_id, NULL) == S_OK)
    {
        IMsgStore_OpenEntry(msg_store, entry_len, entry_id, NULL, 0, &obj_type, (LPUNKNOWN*) &folder);
        MAPIFreeBuffer(entry_id);
    }

    tags[1] = PR_IPM_DRAFTS_ENTRYID;

    /* 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))
    {
        TRACE("Unable to open Drafts folder; opening Outbox instead\n");
        tags[1] = PR_IPM_OUTBOX_ENTRYID;
        ret = IMsgStore_GetProps(msg_store, (LPSPropTagArray) tags, 0, &values, &props);
    }

    if (ret != S_OK)
        goto logoff;

    IMsgStore_OpenEntry(msg_store, props[0].Value.bin.cb, (LPENTRYID) props[0].Value.bin.lpb,
        NULL, MAPI_MODIFY, &obj_type, (LPUNKNOWN *) &draft_folder);

    /* Create a new message */
    if (IMAPIFolder_CreateMessage(draft_folder, NULL, 0, &msg) == S_OK)
    {
        ULONG token;
        SPropValue p;

        /* Define message properties */
        p.ulPropTag = PR_MESSAGE_FLAGS;
        p.Value.l = MSGFLAG_FROMME | MSGFLAG_UNSENT;

        IMessage_SetProps(msg, 1, &p, NULL);

        p.ulPropTag = PR_SENTMAIL_ENTRYID;
        p.Value.bin.cb = props[0].Value.bin.cb;
        p.Value.bin.lpb = props[0].Value.bin.lpb;
        IMessage_SetProps(msg, 1,&p, NULL);

        /* Set message subject */
        if (message->lpszSubject)
        {
            if (unicode_aware)
            {
                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);
        }

        /* Set message body */
        if (message->lpszNoteText)
        {
            LPSTREAM stream = NULL;

            if (IMessage_OpenProperty(msg, unicode_aware ? PR_BODY_W : PR_BODY_A, &IID_IStream, 0,
                MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*) &stream) == S_OK)
            {
                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);
            }
        }

        /* Add message attachments */
        if (message->nFileCount > 0)
        {
            ULONG num_attach = 0;
            unsigned int i;

            for (i = 0; i < message->nFileCount; i++)
            {
                IAttach* attachment = NULL;
                char *filenameA = NULL;
                SPropValue prop[4];
                LPCWSTR filename;
                HANDLE file;

                if (!message->lpFiles[i].lpszPathName)
                    continue;

                /* Open the attachment for reading */
                file = CreateFileW(message->lpFiles[i].lpszPathName, GENERIC_READ, FILE_SHARE_READ,
                    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

                if (file == INVALID_HANDLE_VALUE)
                    continue;

                /* Check if a display filename has been given; if not, get one ourselves from path name */
                filename = message->lpFiles[i].lpszFileName;

                if (!filename)
                {
                    int j;

                    filename = message->lpFiles[i].lpszPathName;

                    for (j = lstrlenW(message->lpFiles[i].lpszPathName)-1; j >= 0; j--)
                    {
                        if (message->lpFiles[i].lpszPathName[i] == '\\' ||
                            message->lpFiles[i].lpszPathName[i] == '/')
                        {
                            filename = &message->lpFiles[i].lpszPathName[i+1];
                            break;
                        }
                    }
                }

                TRACE("Attachment %u path: '%s'; filename: '%s'\n", i, debugstr_w(message->lpFiles[i].lpszPathName),
                    debugstr_w(filename));

                /* Create the attachment */
                if (IMessage_CreateAttach(msg, NULL, 0, &num_attach, &attachment) != S_OK)
                {
                    TRACE("Unable to create attachment\n");
                    CloseHandle(file);
                    continue;
                }

                /* Set the attachment properties */
                ZeroMemory(prop, sizeof(prop));

                prop[0].ulPropTag = PR_ATTACH_METHOD;
                prop[0].Value.ul = ATTACH_BY_VALUE;

                if (unicode_aware)
                {
                    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].Value.l = -1;

                if (IAttach_SetProps(attachment, 4, prop, NULL) == S_OK)
                {
                    LPSTREAM stream = NULL;

                    if (IAttach_OpenProperty(attachment, PR_ATTACH_DATA_BIN, &IID_IStream, 0,
                        MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*) &stream) == S_OK)
                    {
                        BYTE data[READ_BUF_SIZE];
                        DWORD size = 0, read, written;

                        while (ReadFile(file, data, READ_BUF_SIZE, &read, NULL) && (read != 0))
                        {
                            IStream_Write(stream, data, read, &written);
                            size += read;
                        }

                        TRACE("%d bytes written of attachment\n", size);

                        IStream_Commit(stream, STGC_DEFAULT);
                        IStream_Release(stream);

                        prop[0].ulPropTag = PR_ATTACH_SIZE;
                        prop[0].Value.ul = size;
                        IAttach_SetProps(attachment, 1, prop, NULL);

                        IAttach_SaveChanges(attachment, KEEP_OPEN_READONLY);
                        num_attach++;
                    }
                }

                CloseHandle(file);
                IAttach_Release(attachment);

                HeapFree(GetProcessHeap(), 0, filenameA);
            }
        }

        IMessage_SaveChanges(msg, KEEP_OPEN_READWRITE);

        /* Prepare the message form */

        if (IMAPISession_PrepareForm(session, NULL, msg, &token) == S_OK)
        {
            ULONG access = 0, status = 0, message_flags = 0, pc = 0;
            ULONG pT[2] = {1, PR_MSG_STATUS};

            /* Retrieve message status, flags, access rights and class */

            if (IMessage_GetProps(msg, (LPSPropTagArray) pT, 0, &pc, &props) == S_OK)
            {
                status = props->Value.ul;
                MAPIFreeBuffer(props);
            }

            pT[1] = PR_MESSAGE_FLAGS;

            if (IMessage_GetProps(msg, (LPSPropTagArray) pT, 0, &pc, &props) == S_OK)
            {
                message_flags = props->Value.ul;
                MAPIFreeBuffer(props);
            }

            pT[1] = PR_ACCESS;

            if (IMessage_GetProps(msg, (LPSPropTagArray) pT, 0, &pc, &props) == S_OK)
            {
                access = props->Value.ul;
                MAPIFreeBuffer(props);
            }

            pT[1] = PR_MESSAGE_CLASS_A;

            if (IMessage_GetProps(msg, (LPSPropTagArray) pT, 0, &pc, &props) == S_OK)
            {
                /* Show the message form (edit window) */

                ret = IMAPISession_ShowForm(session, 0, msg_store, draft_folder, NULL,
                                            token, NULL, 0, status, message_flags, access,
                                            props->Value.lpszA);

                switch (ret)
                {
                    case S_OK:
                        retval = SUCCESS_SUCCESS;
                        break;

                    case MAPI_E_USER_CANCEL:
                        retval = MAPI_E_USER_ABORT;
                        break;

                    default:
                        TRACE("ShowForm failure: %x\n", ret);
                        break;
                }
            }
        }

        IMessage_Release(msg);
    }

    /* Free up the resources we've used */
    IMAPIFolder_Release(draft_folder);
    if (folder) IMAPIFolder_Release(folder);
    IMsgStore_Release(msg_store);

    HeapFree(GetProcessHeap(), 0, subjectA);
    HeapFree(GetProcessHeap(), 0, bodyA);

logoff: ;
    IMAPISession_Logoff(session, 0, 0, 0);
    IMAPISession_Release(session);

cleanup: ;
    MAPIUninitialize();
    return retval;
}

/**************************************************************************
 *  MAPISendMail	(MAPI32.211)
 *
 * Send a mail.
 *
 * PARAMS
 *  session  [I] Handle to a MAPI session.
 *  uiparam  [I] Parent window handle.
 *  message  [I] Pointer to a MAPIMessage structure.
 *  flags    [I] Flags.
 *  reserved [I] Reserved, pass 0.
 *
 * RETURNS
 *  Success: SUCCESS_SUCCESS
 *  Failure: MAPI_E_FAILURE
 *
 */
ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
    lpMapiMessage 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 */
    if (mapiFunctions.MAPISendMail)
        return mapiFunctions.MAPISendMail(session, uiparam, message, flags, reserved);

    /* Check if we have an Extended MAPI provider - if so, use our wrapper */
    if (MAPIInitialize(NULL) == S_OK)
    {
        MapiMessageW messageW;
        ULONG ret;

        ZeroMemory(&messageW, sizeof(MapiMessageW));

        /* Convert the entries we need to Unicode */
        messageW.lpszSubject = convert_to_unicode(message->lpszSubject);
        messageW.lpszNoteText = convert_to_unicode(message->lpszNoteText);
        messageW.nFileCount = message->nFileCount;

        if (message->nFileCount && message->lpFiles)
        {
            lpMapiFileDescW filesW;
            unsigned int i;

            filesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MapiFileDescW) * message->nFileCount);

            for (i = 0; i < message->nFileCount; i++)
            {
                filesW[i].lpszPathName = convert_to_unicode(message->lpFiles[i].lpszPathName);
                filesW[i].lpszFileName = convert_to_unicode(message->lpFiles[i].lpszFileName);
            }

            messageW.lpFiles = filesW;
        }

        ret = sendmail_extended_mapi(session, uiparam, &messageW, flags);

        /* Now free everything we allocated */
        if (message->nFileCount && message->lpFiles)
        {
            unsigned int i;

            for (i = 0; i < message->nFileCount; i++)
            {
                HeapFree(GetProcessHeap(), 0, messageW.lpFiles[i].lpszPathName);
                HeapFree(GetProcessHeap(), 0, messageW.lpFiles[i].lpszFileName);
            }

            HeapFree(GetProcessHeap(), 0, messageW.lpFiles);
        }

        HeapFree(GetProcessHeap(), 0, messageW.lpszSubject);
        HeapFree(GetProcessHeap(), 0, messageW.lpszNoteText);

        return ret;
    }

    /* 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;
}

static lpMapiRecipDesc convert_recipient_from_unicode(lpMapiRecipDescW recipW, lpMapiRecipDesc dest)
{
    lpMapiRecipDesc ret;

    if (!recipW)
        return NULL;

    if (dest)
        ret = dest;
    else
        ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MapiRecipDesc));

    ret->ulRecipClass = recipW->ulRecipClass;
    ret->lpszName = convert_from_unicode(recipW->lpszName);
    ret->lpszAddress = convert_from_unicode(recipW->lpszAddress);
    ret->ulEIDSize = recipW->ulEIDSize;
    ret->lpEntryID = recipW->lpEntryID;

    return ret;
}

/**************************************************************************
 *  MAPISendMailW	(MAPI32.256)
 *
 * Send a mail.
 *
 * PARAMS
 *  session  [I] Handle to a MAPI session.
 *  uiparam  [I] Parent window handle.
 *  message  [I] Pointer to a MAPIMessageW structure.
 *  flags    [I] Flags.
 *  reserved [I] Reserved, pass 0.
 *
 * RETURNS
 *  Success: SUCCESS_SUCCESS
 *  Failure: MAPI_E_FAILURE
 *
 */
ULONG WINAPI MAPISendMailW(LHANDLE session, ULONG_PTR uiparam,
    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 */
    if (mapiFunctions.MAPISendMailW)
        return mapiFunctions.MAPISendMailW(session, uiparam, message, flags, reserved);

    /* 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);

    if (mapiFunctions.MAPISendMail)
    {
        MapiMessage messageA;
        ULONG ret;

        if (flags & MAPI_FORCE_UNICODE)
            return MAPI_E_UNICODE_NOT_SUPPORTED;

        /* Convert to ANSI and send to MAPISendMail */
        ZeroMemory(&messageA, sizeof(MapiMessage));

        messageA.lpszSubject = convert_from_unicode(message->lpszSubject);
        messageA.lpszNoteText = convert_from_unicode(message->lpszNoteText);
        messageA.lpszMessageType = convert_from_unicode(message->lpszMessageType);
        messageA.lpszDateReceived = convert_from_unicode(message->lpszDateReceived);
        messageA.lpszConversationID = convert_from_unicode(message->lpszConversationID);
        messageA.flFlags = message->flFlags;
        messageA.lpOriginator = convert_recipient_from_unicode(message->lpOriginator, NULL);
        messageA.nRecipCount = message->nRecipCount;
        messageA.nFileCount = message->nFileCount;

        if (message->nRecipCount && message->lpRecips)
        {
            lpMapiRecipDesc recipsA;
            unsigned int i;

            recipsA = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MapiRecipDesc) * message->nRecipCount);

            for (i = 0; i < message->nRecipCount; i++)
            {
                convert_recipient_from_unicode(&message->lpRecips[i], &recipsA[i]);
            }

            messageA.lpRecips = recipsA;
        }

        if (message->nFileCount && message->lpFiles)
        {
            lpMapiFileDesc filesA;
            unsigned int i;

            filesA = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MapiFileDesc) * message->nFileCount);

            for (i = 0; i < message->nFileCount; i++)
            {
                filesA[i].flFlags = message->lpFiles[i].flFlags;
                filesA[i].nPosition = message->lpFiles[i].nPosition;
                filesA[i].lpszPathName = convert_from_unicode(message->lpFiles[i].lpszPathName);
                filesA[i].lpszFileName = convert_from_unicode(message->lpFiles[i].lpszFileName);
                filesA[i].lpFileType = message->lpFiles[i].lpFileType;
            }

            messageA.lpFiles = filesA;
        }

        ret = mapiFunctions.MAPISendMail(session, uiparam, &messageA, flags, reserved);

        /* Now free everything we allocated */
        if (message->lpOriginator)
        {
            HeapFree(GetProcessHeap(), 0, messageA.lpOriginator->lpszName);
            HeapFree(GetProcessHeap(), 0, messageA.lpOriginator->lpszAddress);
            HeapFree(GetProcessHeap(), 0, messageA.lpOriginator);
        }

        if (message->nRecipCount && message->lpRecips)
        {
            unsigned int i;

            for (i = 0; i < message->nRecipCount; i++)
            {
                HeapFree(GetProcessHeap(), 0, messageA.lpRecips[i].lpszName);
                HeapFree(GetProcessHeap(), 0, messageA.lpRecips[i].lpszAddress);
            }

            HeapFree(GetProcessHeap(), 0, messageA.lpRecips);
        }

        if (message->nFileCount && message->lpFiles)
        {
            unsigned int i;

            for (i = 0; i < message->nFileCount; i++)
            {
                HeapFree(GetProcessHeap(), 0, messageA.lpFiles[i].lpszPathName);
                HeapFree(GetProcessHeap(), 0, messageA.lpFiles[i].lpszFileName);
            }

            HeapFree(GetProcessHeap(), 0, messageA.lpFiles);
        }

        HeapFree(GetProcessHeap(), 0, messageA.lpszSubject);
        HeapFree(GetProcessHeap(), 0, messageA.lpszNoteText);
        HeapFree(GetProcessHeap(), 0, messageA.lpszDateReceived);
        HeapFree(GetProcessHeap(), 0, messageA.lpszConversationID);

        return ret;
    }

    /* 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;
}

ULONG WINAPI MAPISendDocuments(ULONG_PTR uiparam, LPSTR delim, LPSTR paths,
    LPSTR filenames, ULONG reserved)
{
    if (mapiFunctions.MAPISendDocuments)
        return mapiFunctions.MAPISendDocuments(uiparam, delim, paths, filenames, reserved);

    return MAPI_E_NOT_SUPPORTED;
}
