Home | Info | Community | Development | myReactOS | Contact Us
[static]
Definition at line 55 of file sendmail.c.
Referenced by MAPISendMail().
{ ULONG tags[] = {1, PR_IPM_DRAFTS_ENTRYID}; ULONG retval = MAPI_E_FAILURE; IMAPISession *session = NULL; 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); /* 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); } /* 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) { p.ulPropTag = PR_SUBJECT_A; p.Value.lpszA = message->lpszSubject; IMessage_SetProps(msg, 1, &p, NULL); } /* Set message body */ if (message->lpszNoteText) { LPSTREAM stream = NULL; if (IMessage_OpenProperty(msg, PR_BODY_A, &IID_IStream, 0, MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*) &stream) == S_OK) { IStream_Write(stream, message->lpszNoteText, strlen(message->lpszNoteText)+1, NULL); IStream_Release(stream); } } /* Add message attachments */ if (message->nFileCount > 0) { ULONG num_attach = 0; int i, j; for (i = 0; i < message->nFileCount; i++) { IAttach* attachment = NULL; SPropValue prop[4]; LPCSTR filename; HANDLE file; if (!message->lpFiles[i].lpszPathName) continue; /* Open the attachment for reading */ file = CreateFileA(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) { filename = message->lpFiles[i].lpszPathName; for (j = strlen(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 %d path: '%s'; filename: '%s'\n", i, debugstr_a(message->lpFiles[i].lpszPathName), debugstr_a(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; prop[1].ulPropTag = PR_ATTACH_LONG_FILENAME_A; prop[1].Value.lpszA = (LPSTR) filename; prop[2].ulPropTag = PR_ATTACH_FILENAME_A; prop[2].Value.lpszA = (LPSTR) filename; 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 read, %d bytes written of attachment\n", read, written); 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); } } IMessage_SaveChanges(msg, KEEP_OPEN_READWRITE); /* Prepare the message form */ if (IMAPISession_PrepareForm(session, NULL, msg, &token) == S_OK) { ULONG access = 0, status = 0, 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) { 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, 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); logoff: ; IMAPISession_Logoff(session, 0, 0, 0); IMAPISession_Release(session); cleanup: ; MAPIUninitialize(); return retval; }