Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1656 lines
52 KiB

// --------------------------------------------------------------------------------
// Mimetest.cpp
//
// This is a console app that has various types of functions that highlight the
// most typical ways to use mimeole. This console app also acts as a test program
// for mimeole, but does not actually do anything.
//
// Here are the files you need to use mimeole:
//
// mimeole.h - This is the main header file. It is generated from mimeole.idl.
// mimeole.idl - This is the interface definition file. It has a little bit of
// documentation. A client should use this file to find out info
// about mimeole interfaces, data types, utility functions, etc.
// inetcomm.dll - This is the DLL that contains the implementation of everything
// in mimeole.h. You should run regsvr32.exe on inetcomm.dll.
// msoert2.dll - inetcomm.dll statically links to this dll. msoert2 is the Microsoft
// Outlook Express runtime library. msoert2.dll is part of the Outlook
// Express installation. This DLL does not require any registration.
// shlwapi.dll - inetcomm.dll statically links to this dll. shlwapi is part of the
// Internet Explorer installation. shlwapi does not require any
// registration.
// mlang.dll - inetcomm.dll will dynamically load this dll. mlang is used to support
// various character set translations. mlang stands for multi-language.
// This DLL is part of the Internet Explorer installation. You should
// run regsvr32.exe on mlang.dll to register it.
// urlmon.dll - inetcomm.dll will dynamically load this dll. urlmon is used by
// inetcomm to support various parts of MHTML as well as rendering
// MHTML inside of the IE browser.
// SMIME - SMIME support in mimeole requires the crypto API, which is part of
// the IE installation.
// Notes: shlwapi and msoert2, as well as any other DLLs that inetcomm.dll statically
// links to must be either in the same directory as inetcomm.dll, or be located
// in a directory that is in the system path.
//
// The DLLs that inetcomm dynamically load are not required. Inetcomm will still
// work, although certain functionality will be disabled.
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// To use mimeole objects, per COM rules, you must have one file in your project that
// has the #define INITGUID line, and then include mimeole.h. This will cause all of
// the CLSIDs and IIDs to be defined.
// --------------------------------------------------------------------------------
#define INITGUID
// --------------------------------------------------------------------------------
// This is simply my precompiled header
// --------------------------------------------------------------------------------
#include "pch.h"
#include <shlwapi.h>
#include <shlwapip.h>
// --------------------------------------------------------------------------------
// Part of the initguid process
// --------------------------------------------------------------------------------
#include <initguid.h>
// --------------------------------------------------------------------------------
// Primary mimeole header file
// --------------------------------------------------------------------------------
#include <mimeole.h>
#define DEFINE_HOTSTORE
// --------------------------------------------------------------------------------
// I'm disable various parts of MOSERT so that I can use it from within this test
// program.
// --------------------------------------------------------------------------------
#define MSOERT_NO_PROTSTOR
#define MSOERT_NO_BYTESTM
#define MSOERT_NO_STRPARSE
#define MSOERT_NO_ENUMFMT
#define MSOERT_NO_CLOGFILE
#define MSOERT_NO_DATAOBJ
// --------------------------------------------------------------------------------
// I know you don't have this, but you can if you want it. This header has a bunch
// of slick macros. I will try not to use too many of them.
// --------------------------------------------------------------------------------
#include "d:\\athena\\inc\\msoert.h"
// --------------------------------------------------------------------------------
// Test function Prototypes
// --------------------------------------------------------------------------------
HRESULT MimeTestAppendRfc822(IMimeMessage **ppMessage);
HRESULT MimeTestSettingContentLocation(IMimeMessage **ppMessage);
HRESULT MimeTestGetMultiValueAddressProp(IMimeMessage **ppMessage);
HRESULT MimeTestLookupCharsetHandle(LPCSTR pszCharset, LPHCHARSET phCharset);
HRESULT MimeTestSettingReplyTo(IMimeMessage **ppMessage);
HRESULT MimeTestSplitMessageIntoParts(void);
HRESULT MimeTestRecombineMessageParts(LPWSTR *prgpszFile, ULONG cFiles);
HRESULT MimeTestIsContentType(IMimeMessage **ppMessage);
HRESULT MimeTestBodyStream(IMimeMessage **ppMessage);
HRESULT MimeTestDeleteBody(IMimeMessage **ppMessage);
HRESULT MimeTestEnumHeaderTable(IMimeMessage **ppMessage);
HRESULT MimeTestCDO(IMimeMessage **ppMessage);
// --------------------------------------------------------------------------------
// Utility functions used by mimetest
// --------------------------------------------------------------------------------
HRESULT DumpStreamToConsole(IStream *pStream);
HRESULT ReportError(LPCSTR pszFunction, INT nLine, LPCSTR pszErrorText, HRESULT hrResult);
HRESULT ReportStatus(LPCSTR pszStatusText);
HRESULT CreateMimeMessage(IMimeMessage **ppMessage);
HRESULT SaveMimeMessage(IMimeMessage *pMessage, MIMESAVETYPE savetype, IStream **ppStream);
// --------------------------------------------------------------------------------
// Testing Switches
// --------------------------------------------------------------------------------
// #define TEST_MimeTestAppendRfc822
// #define TEST_MimeTestSettingContentLocation
// #define TEST_MimeTestGetMultiValueAddressProp
// #define TEST_MimeTestSettingReplyTo
// #define TEST_MimeTestSplitMessageIntoParts
// #define TEST_MimeTestIsContentType
// #define TEST_MimeTestBodyStream
// #define TEST_MimeTestDeleteBody
// #define TEST_MimeTestEnumHeaderTable
#define TEST_MimeTestCDO
// --------------------------------------------------------------------------------
// MimeTest Entry Point
// --------------------------------------------------------------------------------
void __cdecl main(int argc, char *argv[])
{
// Locals
HRESULT hr;
IMimeMessage *pMessage=NULL;
// You must always call this if you are going to use COM
hr = CoInitialize(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "CoInitialize failed.", hr);
exit(1);
}
IDatabaseTable *pTable;
HROWSET hRowset;
MESSAGEINFO Message;
CoCreateInstance(CLSID_DatabaseTable, NULL, CLSCTX_INPROC_SERVER, IID_IDatabaseTable, (LPVOID *)&pTable);
pTable->Open("d:\\store\\00000004.dbx", 0, &g_MessageTableSchema, NULL);
pTable->CreateRowset(IINDEX_SUBJECT, 0, &hRowset);
while (S_OK == pTable->QueryRowset(hRowset, 1, (LPVOID *)&Message, NULL))
{
printf("%08d: %s\n", Message.idMessage, Message.pszSubject);
pTable->FreeRecord(&Message);
}
pTable->CloseRowset(&hRowset);
pTable->Release();
exit(1);
// ----------------------------------------------------------------------------
// TEST_MimeTestCDO
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestCDO
MimeTestCDO(NULL);
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestEnumHeaderTable
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestEnumHeaderTable
hr = MimeTestEnumHeaderTable(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestEnumHeaderTable failed.", hr);
goto exit;
}
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestDeleteBody
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestDeleteBody
hr = MimeTestDeleteBody(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestDeleteBody failed.", hr);
goto exit;
}
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestBodyStream
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestBodyStream
hr = MimeTestBodyStream(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestBodyStream failed.", hr);
goto exit;
}
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestIsContentType
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestIsContentType
hr = MimeTestIsContentType(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestIsContentType failed.", hr);
goto exit;
}
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestAppendRfc822
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestAppendRfc822
hr = MimeTestAppendRfc822(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestAppendRfc822 failed.", hr);
goto exit;
}
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestGetMultiValueAddressProp
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestGetMultiValueAddressProp
hr = MimeTestGetMultiValueAddressProp(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestAppendRfc822 failed.", hr);
goto exit;
}
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestSettingContentLocation
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestSettingContentLocation
hr = MimeTestSettingContentLocation(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestSettingContentLocation failed.", hr);
goto exit;
}
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestSettingReplyTo
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestSettingReplyTo
hr = MimeTestSettingReplyTo(NULL);
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestSettingReplyTo failed.", hr);
goto exit;
}
#endif
// ----------------------------------------------------------------------------
// TEST_MimeTestSplitMessageIntoParts
// ----------------------------------------------------------------------------
#ifdef TEST_MimeTestSplitMessageIntoParts
hr = MimeTestSplitMessageIntoParts();
if (FAILED(hr))
{
ReportError("main", __LINE__, "MimeTestSplitMessageIntoParts failed.", hr);
goto exit;
}
#endif
exit:
// Cleanup
if (pMessage)
pMessage->Release();
// I called CoInitialize, so lets call this...
CoUninitialize();
// Done
exit(1);
}
// --------------------------------------------------------------------------------
// MimeTestCDO
// --------------------------------------------------------------------------------
//#define RAID_17675
#define RAID_20406
//#define RAID_29961
HRESULT MimeTestCDO(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
IMimeMessage *pMessage=NULL;
IPersistFile *pPersistFile=NULL;
PROPVARIANT Variant;
LPSTR psz;
FINDBODY FindBody={0};
HBODY hBody;
HCHARSET hCharset;
IMimeBody *pBody=NULL;
IMimeInternational *pInternat=NULL;
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
goto exit;
#ifdef RAID_29961
hr = CoCreateInstance(CLSID_IMimeInternational, NULL, CLSCTX_INPROC_SERVER, IID_IMimeInternational, (LPVOID *)&pInternat);
if (FAILED(hr))
goto exit;
hr = pMessage->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
goto exit;
hr = pPersistFile->Load(L"j:\\test\\raid29961.eml", STGM_READ | STGM_SHARE_DENY_NONE);
if (FAILED(hr))
goto exit;
FindBody.pszPriType = "text";
FindBody.pszSubType = "plain";
hr = pMessage->FindFirst(&FindBody, &hBody);
if (FAILED(hr))
goto exit;
hr = pMessage->BindToObject(hBody, IID_IMimeBody, (LPVOID *)&pBody);
if (FAILED(hr))
goto exit;
hr = pInternat->FindCharset("iso-8859-7", &hCharset);
if (FAILED(hr))
goto exit;
hr = pBody->SetCharset(hCharset, CSET_APPLY_ALL);
if (FAILED(hr))
goto exit;
pBody->Release();
pBody = NULL;
hr = pMessage->FindNext(&FindBody, &hBody);
if (FAILED(hr))
goto exit;
hr = pMessage->BindToObject(hBody, IID_IMimeBody, (LPVOID *)&pBody);
if (FAILED(hr))
goto exit;
hr = pInternat->FindCharset("iso-8859-4", &hCharset);
if (FAILED(hr))
goto exit;
hr = pBody->SetCharset(hCharset, CSET_APPLY_ALL);
if (FAILED(hr))
goto exit;
pBody->Release();
pBody = NULL;
hr = pInternat->FindCharset("iso-8859-3", &hCharset);
if (FAILED(hr))
goto exit;
hr = pMessage->SetCharset(hCharset, CSET_APPLY_UNTAGGED);
if (FAILED(hr))
goto exit;
hr = pPersistFile->Save(L"j:\\test\\raid29961_saved.eml", FALSE);
if (FAILED(hr))
goto exit;
#endif
#ifdef RAID_17675
// Get an IPersistFile
hr = pMessage->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
goto exit;
// Load
hr = pPersistFile->Load(L"c:\\test\\cdo.eml", STGM_READ | STGM_SHARE_DENY_NONE);
if (FAILED(hr))
goto exit;
ZeroMemory(&Variant, sizeof(PROPVARIANT));
Variant.vt = VT_EMPTY;
hr = pMessage->SetProp("par:content-type:charset", 0, &Variant);
// if (FAILED(hr))
// goto exit;
Variant.vt = VT_LPSTR;
hr = pMessage->GetProp("par:content-type:charset", 0, &Variant);
if (FAILED(hr))
goto exit;
#endif // RAID_17675
#ifdef RAID_20406
// Get an IPersistFile
hr = pMessage->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
goto exit;
// Load
hr = pPersistFile->Load(L"c:\\test\\address.eml", STGM_READ | STGM_SHARE_DENY_NONE);
if (FAILED(hr))
goto exit;
pMessage->GetAddressFormat(IAT_TO, AFT_DISPLAY_FRIENDLY, &psz);
printf("AFT_DISPLAY_FRIENDLY: %s\n", psz);
CoTaskMemFree(psz);
pMessage->GetAddressFormat(IAT_TO, AFT_DISPLAY_EMAIL, &psz);
printf("AFT_DISPLAY_EMAIL: %s\n", psz);
CoTaskMemFree(psz);
pMessage->GetAddressFormat(IAT_TO, AFT_DISPLAY_BOTH, &psz);
printf("AFT_DISPLAY_BOTH: %s\n", psz);
CoTaskMemFree(psz);
pMessage->GetAddressFormat(IAT_TO, AFT_RFC822_DECODED, &psz);
printf("AFT_RFC822_DECODED: %s\n", psz);
CoTaskMemFree(psz);
pMessage->GetAddressFormat(IAT_TO, AFT_RFC822_ENCODED, &psz);
printf("AFT_RFC822_ENCODED: %s\n", psz);
CoTaskMemFree(psz);
pMessage->GetAddressFormat(IAT_TO, AFT_RFC822_TRANSMIT, &psz);
printf("AFT_RFC822_TRANSMIT: %s\n", psz);
CoTaskMemFree(psz);
#endif // RAID_20406
exit:
// Cleanup
if (pMessage)
pMessage->Release();
if (pPersistFile)
pPersistFile->Release();
if (pInternat)
pInternat->Release();
// Done
return(hr);
}
// --------------------------------------------------------------------------------
// MimeTestEnumHeaderTable
// --------------------------------------------------------------------------------
HRESULT MimeTestEnumHeaderTable(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
IMimeMessage *pMessage=NULL;
IPersistFile *pPersistFile=NULL;
IMimeHeaderTable *pTable=NULL;
IMimeEnumHeaderRows *pEnum=NULL;
ENUMHEADERROW Row;
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestEnumHeaderTable", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Get an IPersistFile
hr = pMessage->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
{
ReportError("MimeTestEnumHeaderTable", __LINE__, "IMimeMessage::QueryInterface(IID_IPersistFile) failed.", hr);
goto exit;
}
// Load
hr = pPersistFile->Load(L"c:\\test\\multiadd.eml", STGM_READ | STGM_SHARE_DENY_NONE);
if (FAILED(hr))
{
ReportError("MimeTestEnumHeaderTable", __LINE__, "IPersistFile::Load failed.", hr);
goto exit;
}
// Get Enumerator
hr = pMessage->BindToObject(HBODY_ROOT, IID_IMimeHeaderTable, (LPVOID *)&pTable);
if (FAILED(hr))
{
ReportError("MimeTestEnumHeaderTable", __LINE__, "pMessage->BindToObject(HBODY_ROOT, IID_IMimeHeaderTable, ...) failed.", hr);
goto exit;
}
// EnumRows
hr = pTable->EnumRows(NULL, 0, &pEnum);
if (FAILED(hr))
{
ReportError("MimeTestEnumHeaderTable", __LINE__, "pTable->EnumRows failed.", hr);
goto exit;
}
// Loop
while (S_OK == pEnum->Next(1, &Row, NULL))
{
printf("%s: %s\n", Row.pszHeader, Row.pszData);
CoTaskMemFree(Row.pszHeader);
CoTaskMemFree(Row.pszData);
}
// Return a message object
if (ppMessage)
{
(*ppMessage) = pMessage;
(*ppMessage)->AddRef();
}
exit:
// Cleanup
if (pPersistFile)
pPersistFile->Release();
if (pMessage)
pMessage->Release();
if (pTable)
pTable->Release();
if (pEnum)
pEnum->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestDeleteBody
// --------------------------------------------------------------------------------
HRESULT MimeTestDeleteBody(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
IMimeMessage *pMessage=NULL;
IPersistFile *pPersistFile=NULL;
HBODY hBody;
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Get an IPersistFile
hr = pMessage->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "IMimeMessage::QueryInterface(IID_IPersistFile) failed.", hr);
goto exit;
}
// Load
hr = pPersistFile->Load(L"d:\\test\\delbody.eml", STGM_READ | STGM_SHARE_DENY_NONE);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "IPersistFile::Load failed.", hr);
goto exit;
}
// Load
hr = pPersistFile->Load(L"d:\\test\\delbody.eml", STGM_READ | STGM_SHARE_DENY_NONE);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "IPersistFile::Load failed.", hr);
goto exit;
}
goto exit;
// Get the root body
hr = pMessage->GetBody(IBL_ROOT, NULL, &hBody);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "pMessage->GetBody failed.", hr);
goto exit;
}
// Get the root body
hr = pMessage->GetBody(IBL_FIRST, hBody, &hBody);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "pMessage->GetBody failed.", hr);
goto exit;
}
// Delete the Root
hr = pMessage->DeleteBody(hBody, DELETE_PROMOTE_CHILDREN);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "pMessage->DeleteBody failed.", hr);
goto exit;
}
// Get the root body
hr = pMessage->GetBody(IBL_ROOT, NULL, &hBody);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "pMessage->GetBody failed.", hr);
goto exit;
}
// Delete the Root
hr = pMessage->DeleteBody(hBody, 0);
if (FAILED(hr))
{
ReportError("MimeTestDeleteBody", __LINE__, "pMessage->DeleteBody failed.", hr);
goto exit;
}
// Return a message object
if (ppMessage)
{
(*ppMessage) = pMessage;
(*ppMessage)->AddRef();
}
exit:
// Cleanup
if (pPersistFile)
pPersistFile->Release();
if (pMessage)
pMessage->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestBodyStream
// --------------------------------------------------------------------------------
#if 0
HRESULT MimeTestBodyStream(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
IMimeMessage *pMessage=NULL;
IStream *pStmSave=NULL;
IStream *pStmBody=NULL;
IStream *pStmText=NULL;
IStream *pStmTxtOut=NULL;
IMimeBody *pBody=NULL;
PROPVARIANT rVariant;
IWaveAudio *pWave=NULL;
IWaveStream *pStmWave=NULL;
DWORD cAttach;
HBODY hBody;
HBODY *prghAttach=NULL;
DWORD cb;
DWORD dw;
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Create a stream in which to save the message...
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStmText);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "CreateStreamOnHGlobal failed", hr);
goto exit;
}
// Write some text into pStmText
hr = pStmText->Write("Testing BodyStream.", lstrlen("Testing BodyStream."), NULL);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "pStmText->Write failed", hr);
goto exit;
}
// Commit
pStmText->Commit(STGC_DEFAULT);
// Rewind it
HrRewindStream(pStmText);
// Set the text body
hr = pMessage->SetTextBody(TXT_PLAIN, IET_BINARY, NULL, pStmText, NULL);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "pMessage->SetTextBody failed", hr);
goto exit;
}
// Attach a file
hr = pMessage->AttachFile("d:\\waveedit\\test.wav", NULL, NULL);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "IMimeMessage::AttachFile failed.", hr);
goto exit;
}
// Save that bad boy to a stream
hr = CreateTempFileStream(&pStmSave);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "CreateTempFileStream failed.", hr);
goto exit;
}
// Save the message
hr = pMessage->Save(pStmSave, TRUE);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "pMessage->Save failed.", hr);
goto exit;
}
// Commit
pStmSave->Commit(STGC_DEFAULT);
// Release pMessage
pMessage->Release();
pMessage = NULL;
// Rewind pStmSave
HrRewindStream(pStmSave);
// Create a new message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Load that message object
hr = pMessage->Load(pStmSave);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "IMimeMessage::Load failed.", hr);
goto exit;
}
// Get the text body
hr = pMessage->GetTextBody(TXT_PLAIN, IET_BINARY, &pStmTxtOut, &hBody);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "pMessage->GetTextBody failed.", hr);
goto exit;
}
// Get the attachment, should be the wave file
hr = pMessage->GetAttachments(&cAttach, &prghAttach);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "pMessage->GetAttachments failed.", hr);
goto exit;
}
// Get the root body
hr = pMessage->BindToObject(prghAttach[0], IID_IMimeBody, (LPVOID *)&pBody);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "IMimeMessage::BindToObject failed.", hr);
goto exit;
}
// Get the data stream
hr = pBody->SaveToFile(IET_BINARY, "d:\\waveedit\\test.new");
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "IMimeBody::GetData failed.", hr);
goto exit;
}
// Get the data stream
hr = pBody->GetData(IET_BINARY, &pStmBody);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "IMimeBody::GetData failed.", hr);
goto exit;
}
// Feed this into waveedit
#if 0
hr = CreateWaveEditObject(IID_IWaveAudio, (LPVOID *)&pWave);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "CreateWaveEditObject failed.", hr);
goto exit;
}
// Get pStmWave
hr = pWave->QueryInterface(IID_IWaveStream, (LPVOID *)&pStmWave);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "pWave->QueryInterface(IID_IWaveStream...) failed.", hr);
goto exit;
}
// Open the stream
hr = pStmWave->StreamOpen(pStmBody);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "pStmWave->StreamOpen failed.", hr);
goto exit;
}
pWave->GetNumSamples(&dw);
// Play it
hr = pWave->Play(WAVE_MAPPER, 0, dw);
if (FAILED(hr))
{
ReportError("MimeTestBodyStream", __LINE__, "pStmWave->Play failed.", hr);
goto exit;
}
#endif
Sleep(8000);
exit:
// Cleanup
if (pMessage)
pMessage->Release();
if (pBody)
pBody->Release();
if (pStmBody)
pStmBody->Release();
if (pStmSave)
pStmSave->Release();
if (pWave)
pWave->Release();
if (pStmWave)
pStmWave->Release();
if (pStmText)
pStmText->Release();
if (pStmTxtOut)
pStmTxtOut->Release();
if (prghAttach)
CoTaskMemFree(prghAttach);
// Done
return hr;
}
#endif
// --------------------------------------------------------------------------------
// MimeTestIsContentType
// --------------------------------------------------------------------------------
HRESULT MimeTestIsContentType(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
IMimeMessage *pMessage=NULL;
IPersistFile *pPersistFile=NULL;
HBODY hBody;
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestIsContentType", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Get an IPersistFile
hr = pMessage->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
{
ReportError("MimeTestIsContentType", __LINE__, "IMimeMessage::QueryInterface(IID_IPersistFile) failed.", hr);
goto exit;
}
// Load
hr = pPersistFile->Load(L"d:\\test\\vlad.eml", STGM_READ | STGM_SHARE_DENY_NONE);
if (FAILED(hr))
{
ReportError("MimeTestIsContentType", __LINE__, "IPersistFile::Load failed.", hr);
goto exit;
}
// Get the root body
hr = pMessage->GetBody(IBL_ROOT, NULL, &hBody);
// Test for content-Type
hr = pMessage->IsContentType(hBody, "multipart", NULL);
if (S_OK == hr)
printf("The root body of the message is a multipart.");
else if (S_FALSE == hr)
printf("The root body of the message is NOT a multipart.");
// Return a message object
if (ppMessage)
{
(*ppMessage) = pMessage;
(*ppMessage)->AddRef();
}
exit:
// Cleanup
if (pPersistFile)
pPersistFile->Release();
if (pMessage)
pMessage->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestSplitMessageIntoParts - How to split a large message into smaller parts
// --------------------------------------------------------------------------------
HRESULT MimeTestSplitMessageIntoParts(void)
{
// Locals
HRESULT hr=S_OK;
IMimeMessageParts *pParts=NULL;
IMimeEnumMessageParts *pEnumParts=NULL;
IMimeMessage *pMessage=NULL;
IMimeMessage *pMsgPart=NULL;
IStream *pStream=NULL;
IPersistFile *pPersistFile=NULL;
ULONG c;
ULONG cFiles=0;
ULONG i;
LPWSTR *prgpszFile=NULL;
PROPVARIANT rVariant;
// Init the variant
ZeroMemory(&rVariant, sizeof(PROPVARIANT));
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Attach a large file
hr = pMessage->AttachFile("c:\\winnt\\winnt256.bmp", NULL, NULL);
if (FAILED(hr))
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "IMimeMessage::AttachFile(...) failed.", hr);
goto exit;
}
// Split the message into parts
hr = pMessage->SplitMessage(65536, &pParts);
if (FAILED(hr))
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "IMimeMessage::SplitMessage(...) failed.", hr);
goto exit;
}
// Get the number of parts
hr = pParts->CountParts(&cFiles);
if (FAILED(hr))
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "IMimeMessageParts::EnumParts(...) failed.", hr);
goto exit;
}
// Allocate an array
prgpszFile = (LPWSTR *)CoTaskMemAlloc(sizeof(LPWSTR) * cFiles);
if (NULL == prgpszFile)
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "CoTaskMemAlloc Failed.", hr);
goto exit;
}
// Init
ZeroMemory(prgpszFile, sizeof(LPWSTR) * cFiles);
// Enumerate the parts
hr = pParts->EnumParts(&pEnumParts);
if (FAILED(hr))
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "IMimeMessageParts::EnumParts(...) failed.", hr);
goto exit;
}
// INit loop var
i = 0;
// Enumerate the parts
while (SUCCEEDED(pEnumParts->Next(1, &pMsgPart, &c)) && 1 == c)
{
// Setup the variant
rVariant.vt = VT_LPWSTR;
// Get a filename, in unicode
hr = pMsgPart->GetBodyProp(HBODY_ROOT, PIDTOSTR(PID_ATT_GENFNAME), 0, &rVariant);
if (FAILED(hr))
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "IMimeMessage::GetBodyProp(HBODY_ROOT, PID_ATT_GENFNAME (Unicode), ...) failed.", hr);
goto exit;
}
// QI for IPersistFile
hr = pMsgPart->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "IMimeMessage::QueryInterface(IID_IPersistFile, ...) failed.", hr);
goto exit;
}
// Get the message source and dump to file...
hr = pPersistFile->Save(rVariant.pwszVal, FALSE);
if (FAILED(hr))
{
ReportError("MimeTestSplitMessageIntoParts", __LINE__, "IPersistFile::Save(...) failed.", hr);
goto exit;
}
// Save the filename
prgpszFile[i++] = rVariant.pwszVal;
rVariant.pwszVal = NULL;
// Release the message
pMsgPart->Release();
pMsgPart = NULL;
pPersistFile->Release();
pPersistFile = NULL;
}
// Lets recombine those message parts
MimeTestRecombineMessageParts(prgpszFile, cFiles);
exit:
// Cleanup
if (pStream)
pStream->Release();
if (pMessage)
pMessage->Release();
if (pParts)
pParts->Release();
if (pEnumParts)
pEnumParts->Release();
if (pMsgPart)
pMsgPart->Release();
if (pPersistFile)
pPersistFile->Release();
if (rVariant.pwszVal)
CoTaskMemFree(rVariant.pwszVal);
if (prgpszFile)
{
for (i=0; i<cFiles; i++)
if (prgpszFile[i])
CoTaskMemFree(prgpszFile[i]);
CoTaskMemFree(prgpszFile);
}
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestRecombineMessageParts
// --------------------------------------------------------------------------------
HRESULT MimeTestRecombineMessageParts(LPWSTR *prgpszFile, ULONG cFiles)
{
// Locals
HRESULT hr=S_OK;
ULONG i=0;
IMimeMessageParts *pParts=NULL;
IMimeMessage *pMsgPart=NULL;
IMimeMessage *pMessage=NULL;
IPersistFile *pPersistFile=NULL;
// Create a message object
hr = CoCreateInstance(CLSID_IMimeMessageParts, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessageParts, (LPVOID *)&pParts);
if (FAILED(hr))
{
ReportError("MimeTestRecombineMessageParts", __LINE__, "CoCreateInstance(CLSID_IMimeMessageParts, ...) failed.", hr);
goto exit;
}
// Loop through the files
for (i=0; i<cFiles; i++)
{
// Create a mime message object
hr = CreateMimeMessage(&pMsgPart);
if (FAILED(hr))
{
ReportError("MimeTestRecombineMessageParts", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Get an IPersistFile
hr = pMsgPart->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
{
ReportError("MimeTestRecombineMessageParts", __LINE__, "IMimeMessage::QueryInterface(IID_IPersistFile, ...) failed.", hr);
goto exit;
}
// Get the message source and dump to file...
hr = pPersistFile->Load(prgpszFile[i], STGM_READ | STGM_SHARE_DENY_NONE);
if (FAILED(hr))
{
ReportError("MimeTestRecombineMessageParts", __LINE__, "IPersistFile::Load(...) failed.", hr);
goto exit;
}
// Add the message into the parts list
hr = pParts->AddPart(pMsgPart);
if (FAILED(hr))
{
ReportError("MimeTestRecombineMessageParts", __LINE__, "IMimeMessageParts::AddPart(...) failed.", hr);
goto exit;
}
// Cleanup
pMsgPart->Release();
pMsgPart = NULL;
pPersistFile->Release();
pPersistFile = NULL;
}
// Combine all the parts into a new message
hr = pParts->CombineParts(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestRecombineMessageParts", __LINE__, "IMimeMessageParts::CombineParts(...) failed.", hr);
goto exit;
}
// Get an IPersistFile
hr = pMessage->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (FAILED(hr))
{
ReportError("MimeTestRecombineMessageParts", __LINE__, "IMimeMessage::QueryInterface(IID_IPersistFile, ...) failed.", hr);
goto exit;
}
// Get the message source and dump to file...
hr = pPersistFile->Save(L"combined.eml", FALSE);
if (FAILED(hr))
{
ReportError("MimeTestRecombineMessageParts", __LINE__, "IPersistFile::Save(...) failed.", hr);
goto exit;
}
exit:
// Cleanup
if (pParts)
pParts->Release();
if (pMsgPart)
pMsgPart->Release();
if (pMessage)
pMessage->Release();
if (pPersistFile)
pPersistFile->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestLookupCharsetHandle
// --------------------------------------------------------------------------------
HRESULT MimeTestLookupCharsetHandle(LPCSTR pszCharset, LPHCHARSET phCharset)
{
// Locals
HRESULT hr=S_OK;
INETCSETINFO rCharset;
IMimeInternational *pInternat=NULL;
// Create a message object
hr = CoCreateInstance(CLSID_IMimeInternational, NULL, CLSCTX_INPROC_SERVER, IID_IMimeInternational, (LPVOID *)&pInternat);
if (FAILED(hr))
{
ReportError("MimeTestLookupCharsetHandle", __LINE__, "CoCreateInstance(CLSID_IMimeInternational, ...) failed.", hr);
goto exit;
}
// Look for character set
hr = pInternat->FindCharset(pszCharset, phCharset);
if (FAILED(hr))
{
ReportError("MimeTestLookupCharsetHandle", __LINE__, "IMimeInternational::FindCharset(...) failed.", hr);
goto exit;
}
// Lets lookup some character set information
hr = pInternat->GetCharsetInfo(*phCharset, &rCharset);
if (FAILED(hr))
{
ReportError("MimeTestLookupCharsetHandle", __LINE__, "IMimeInternational::GetCharsetInfo(...) failed.", hr);
goto exit;
}
// Print some stuff
printf("Charset Name: %s, Windows Codepage: %d, Internet Codepage: %d\n", rCharset.szName, rCharset.cpiWindows, rCharset.cpiInternet);
exit:
// Clenaup
if (pInternat)
pInternat->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestSettingContentLocation - How to set the Content-Location header
// --------------------------------------------------------------------------------
HRESULT MimeTestSettingContentLocation(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
IMimeMessage *pMessage=NULL;
IStream *pStream=NULL;
PROPVARIANT rVariant;
HCHARSET hCharset;
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestSettingContentLocation", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Setup a variant, I can pass in unicode or ansi
rVariant.vt = VT_LPWSTR;
rVariant.pwszVal = L"http://www.microsoft.com";
// Set the Content-Location of the message
hr = pMessage->SetProp(PIDTOSTR(PID_HDR_CNTLOC), 0, &rVariant);
if (FAILED(hr))
{
ReportError("MimeTestSettingContentLocation", __LINE__, "IMimeMessage::SetProp(PIDTOSTR(PID_HDR_CNTLOC), 0, ...) failed.", hr);
goto exit;
}
// Setup a variant, I can pass in unicode or ansi
rVariant.vt = VT_LPSTR;
rVariant.pszVal = "\"Ken Dacey\" <postmaster>";
// Set the Content-Location of the message
hr = pMessage->SetProp(PIDTOSTR(PID_HDR_FROM), 0, &rVariant);
if (FAILED(hr))
{
ReportError("MimeTestSettingContentLocation", __LINE__, "IMimeMessage::SetProp(PIDTOSTR(PID_HDR_FROM), 0, ...) failed.", hr);
goto exit;
}
// I could also set the content-location like this:
//
// 1) pMessage->SetBodyProp(HBODY_ROOT, PIDTOSTR(PID_HDR_CNTLOC), 0, &rVariant);
//
// 2) pMessage->BindToObject(HBODY_ROOT, IID_IMimePropertySet, (LPVOID *)&pProps);
// pProps->SetProp(PIDTOSTR(PID_HDR_CNTLOC), 0, &rVariant);
// Lets save the message in UTF-7
#if 0
hr = MimeTestLookupCharsetHandle("utf-8", &hCharset);
if (FAILED(hr))
{
ReportError("MimeTestSettingContentLocation", __LINE__, "MimeTestLookupCharsetHandle(\"utf-7\", ...) failed.", hr);
goto exit;
}
// Set the charset onto the message
hr = pMessage->SetCharset(hCharset, CSET_APPLY_ALL);
if (FAILED(hr))
{
ReportError("MimeTestSettingContentLocation", __LINE__, "IMimeMessage::SetCharset(\"utf-7\", CSET_APPLY_ALL) failed.", hr);
goto exit;
}
#endif
// Save the mime message to a stream
hr = SaveMimeMessage(pMessage, SAVE_RFC1521, &pStream);
if (FAILED(hr))
{
ReportError("MimeTestSettingContentLocation", __LINE__, "SaveMimeMessage(...) failed.", hr);
goto exit;
}
// Dump the stream to the console, and then wait for input so that the user can view it...
ReportStatus("\n");
DumpStreamToConsole(pStream);
// Return a message object
if (ppMessage)
{
(*ppMessage) = pMessage;
(*ppMessage)->AddRef();
}
exit:
// Cleanup
if (pStream)
pStream->Release();
if (pMessage)
pMessage->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestSettingReplyTo - How to set the Reply-To header
// --------------------------------------------------------------------------------
HRESULT MimeTestSettingReplyTo(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
IMimeMessage *pMessage=NULL;
IStream *pStream=NULL;
PROPVARIANT rVariant;
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestSettingReplyTo", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Setup a variant, I can pass in unicode or ansi
rVariant.vt = VT_LPWSTR;
rVariant.pwszVal = L"Steven Bailey <[email protected]>";
// Set the Content-Location of the message
hr = pMessage->SetProp(PIDTOSTR(PID_HDR_REPLYTO), 0, &rVariant);
if (FAILED(hr))
{
ReportError("MimeTestSettingReplyTo", __LINE__, "IMimeMessage::SetProp(PIDTOSTR(PID_HDR_REPLYTO), 0, ...) failed.", hr);
goto exit;
}
// Save the mime message to a stream
hr = SaveMimeMessage(pMessage, SAVE_RFC1521, &pStream);
if (FAILED(hr))
{
ReportError("MimeTestSettingContentLocation", __LINE__, "SaveMimeMessage(...) failed.", hr);
goto exit;
}
// Dump the stream to the console, and then wait for input so that the user can view it...
ReportStatus("\n");
DumpStreamToConsole(pStream);
// Return a message object
if (ppMessage)
{
(*ppMessage) = pMessage;
(*ppMessage)->AddRef();
}
exit:
// Cleanup
if (pStream)
pStream->Release();
if (pMessage)
pMessage->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestGetMultiValueAddressProp
// --------------------------------------------------------------------------------
HRESULT MimeTestGetMultiValueAddressProp(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
PROPVARIANT rVariant;
IMimeMessage *pMessage=NULL;
// Create a message with some addresses in it
hr = MimeTestAppendRfc822(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestGetMultiValueAddressProp", __LINE__, "MimeTestAppendRfc822 failed.", hr);
goto exit;
}
// Setup the Variant
rVariant.vt = VT_LPSTR;
// Get PID_HDR_TO
hr = pMessage->GetProp(PIDTOSTR(PID_HDR_TO), 0, &rVariant);
if (FAILED(hr))
{
ReportError("MimeTestGetMultiValueAddressProp", __LINE__, "IMimeMessage::GetProp(PIDTOSTR(PID_HDR_TO), ...) failed.", hr);
goto exit;
}
// Printf It
printf("PID_HDR_TO = %s\n", rVariant.pszVal);
// Free it
CoTaskMemFree(rVariant.pszVal);
exit:
// Cleanup
if (pMessage)
pMessage->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// MimeTestAppendRfc822 - Test IMimeAddressTable::AppendRfc822
// --------------------------------------------------------------------------------
HRESULT MimeTestAppendRfc822(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr=S_OK;
IMimeMessage *pMessage=NULL;
IMimeAddressTable *pAdrTable=NULL;
IStream *pStream=NULL;
// Create a message object
hr = CreateMimeMessage(&pMessage);
if (FAILED(hr))
{
ReportError("MimeTestAppendRfc822", __LINE__, "CreateMimeMessage failed.", hr);
goto exit;
}
// Get the address table for the message. The address table should only be used on the root body object.
hr = pMessage->BindToObject(HBODY_ROOT, IID_IMimeAddressTable, (LPVOID *)&pAdrTable);
if (FAILED(hr))
{
ReportError("MimeTestAppendRfc822", __LINE__, "IMimeMessage::BindToObject(HBDOY_ROOT, IID_IMimeAddressTable, ...) failed.", hr);
goto exit;
}
// Append an RFC 822 formatted addresses
hr = pAdrTable->AppendRfc822(IAT_TO, IET_DECODED, "test1 <[email protected]>");
if (FAILED(hr))
{
ReportError("MimeTestAppendRfc822", __LINE__, "IMimeAddressTable::AppendRfc822(...) failed.", hr);
goto exit;
}
// Append an RFC 822 formatted addresses
hr = pAdrTable->AppendRfc822(IAT_TO, IET_DECODED, "to2 <[email protected]>");
if (FAILED(hr))
{
ReportError("MimeTestAppendRfc822", __LINE__, "IMimeAddressTable::AppendRfc822(...) failed.", hr);
goto exit;
}
// Append an RFC 822 formatted addresses
hr = pAdrTable->AppendRfc822(IAT_TO, IET_DECODED, "to3 <[email protected]>");
if (FAILED(hr))
{
ReportError("MimeTestAppendRfc822", __LINE__, "IMimeAddressTable::AppendRfc822(...) failed.", hr);
goto exit;
}
// Save the mime message to a stream
hr = SaveMimeMessage(pMessage, SAVE_RFC1521, &pStream);
if (FAILED(hr))
{
ReportError("MimeTestAppendRfc822", __LINE__, "SaveMimeMessage(...) failed.", hr);
goto exit;
}
// Dump the stream to the console, and then wait for input so that the user can view it...
ReportStatus("\n");
DumpStreamToConsole(pStream);
// Return a message object
if (ppMessage)
{
(*ppMessage) = pMessage;
(*ppMessage)->AddRef();
}
exit:
// Cleanup
if (pStream)
pStream->Release();
if (pAdrTable)
pAdrTable->Release();
if (pMessage)
pMessage->Release();
// Done
return hr;
}
// --------------------------------------------------------------------------------
// CreateMimeMessage - Basic way of creating a COM object.
// --------------------------------------------------------------------------------
HRESULT CreateMimeMessage(IMimeMessage **ppMessage)
{
// Locals
HRESULT hr;
// Create a message object
hr = CoCreateInstance(CLSID_IMimeMessage, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)ppMessage);
if (FAILED(hr))
{
ReportError("CreateMimeMessage", __LINE__, "CoCreateInstance(CLSID_IMimeMessage, ...) failed.", hr);
goto exit;
}
// You must always initnew the message object
hr = (*ppMessage)->InitNew();
if (FAILED(hr))
{
ReportError("CreateMimeMessage", __LINE__, "IMimeMessage::InitNew() failed.", hr);
goto exit;
}
exit:
// Done
return hr;
}
// --------------------------------------------------------------------------------
// Saves a MIME message
// --------------------------------------------------------------------------------
HRESULT SaveMimeMessage(IMimeMessage *pMessage, MIMESAVETYPE savetype, IStream **ppStream)
{
// Locals
HRESULT hr;
PROPVARIANT rOption;
// Set the save format option into the message object. The OID_xxx types are defined
// in mimeole.idl. Go to that file for more information.
rOption.vt = VT_UI4;
rOption.ulVal = savetype;
hr = pMessage->SetOption(OID_SAVE_FORMAT, &rOption);
if (FAILED(hr))
{
ReportError("SaveMimeMessage", __LINE__, "IMimeMessage::SetOption(OID_SAVE_FORMAT, ...) failed", hr);
goto exit;
}
// Create a stream in which to save the message...
hr = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
if (FAILED(hr))
{
ReportError("SaveMimeMessage", __LINE__, "CreateStreamOnHGlobal failed", hr);
goto exit;
}
// Call the save method on IMimeMessage. Mimeole will call commit on the stream object.
// After this call, the stream will be positioned at the end.
hr = pMessage->Save(*ppStream, TRUE);
if (FAILED(hr))
{
ReportError("SaveMimeMessage", __LINE__, "IMimeMessage::Save(...) failed", hr);
goto exit;
}
exit:
// Done
return hr;
}
// --------------------------------------------------------------------------------
// ReportError - Simple function to report an error that has an HRESULT
// --------------------------------------------------------------------------------
HRESULT ReportError(LPCSTR pszFunction, INT nLine, LPCSTR pszErrorText, HRESULT hrResult)
{
printf("Error(HR = 0x%08X) in %s on line %d - %s\n", hrResult, pszFunction, nLine, pszErrorText);
return hrResult;
}
// --------------------------------------------------------------------------------
// ReportStatus - Simple function to report a string to the user
// --------------------------------------------------------------------------------
HRESULT ReportStatus(LPCSTR pszStatusText)
{
printf("Status: %s\n", pszStatusText);
return S_OK;
}
// --------------------------------------------------------------------------------
// DumpStreamToConsole
// --------------------------------------------------------------------------------
HRESULT DumpStreamToConsole(IStream *pStream)
{
// Locals
HRESULT hr=S_OK;
BYTE rgbBuffer[2048];
ULONG cbRead;
// This is an msoert function
HrStreamSeekSet(pStream, 0);
while(1)
{
// Read a block from the stream
hr = pStream->Read(rgbBuffer, sizeof(rgbBuffer), &cbRead);
if (FAILED(hr))
{
ReportError("DumpStreamToConsole", __LINE__, "DumpStreamToConsole - IStream::Read failed.", hr);
break;
}
// If nothing read, then were done
if (0 == cbRead)
break;
// Print it
printf("%s", (LPSTR)rgbBuffer);
}
// Finaly LF
printf("\n");
// Done
return hr;
}
/*
DWORD i=1;
DWORD dw;
CHAR szDate[255];
HROWSET hRowset;
FOLDERINFO Folder;
MESSAGEINFO Message;
IMessageStore *pStore;
IMessageFolder *pFolder;
CoCreateInstance(CLSID_MessageStore, NULL, CLSCTX_INPROC_SERVER, IID_IMessageStore, (LPVOID *)&pStore);
pStore->Initialize("d:\\storetest");
pStore->OpenSpecialFolder(FOLDERID_LOCAL_STORE, FOLDER_INBOX, &pFolder);
pFolder->CreateRowset(IINDEX_SUBJECT, 0, &hRowset);
while(S_OK == pFolder->QueryRowset(hRowset, 1, (LPVOID *)&Message, NULL))
{
dw = FDTF_DEFAULT;
SHFormatDateTimeA(&Message.ftReceived, &dw, szDate, 255);
if (Message.pszNormalSubj)
printf("%05d: %s, %s, %d\n", i, Message.pszNormalSubj, szDate, Message.idMessage);
else
printf("%05d: <Empty>, %s, %d\n", i, szDate, Message.idMessage);
pFolder->FreeRecord(&Message);
i++;
}
pFolder->CloseRowset(&hRowset);
pFolder->Release();
pStore->Release();
exit(1);
*/