Click here to Skip to main content
15,883,705 members
Articles / Desktop Programming / ATL

En/Decode MIME-Content with MimeSniffer

Rate me:
Please Sign up or sign in to vote.
4.88/5 (26 votes)
2 Dec 20022 min read 372.9K   7K   74  
RFC-compliant Mime-En/Decoder
// MimeDecoder.h : Declaration of the CMimeDecoder

#ifndef __MIMEDECODER_H_
#define __MIMEDECODER_H_

#include "resource.h"       // main symbols
#include "MimeSnifferCP.h"
#include "yystype.h"
#include "MyMutex.h"

class IPersistBaseImpl :
	public IPersistStream,
	public IPersistStreamInit
{
protected:
	IPersistBaseImpl()
	{
		m_bModified = false;
	}
public:
	STDMETHOD(IsDirty)(void)
	{
		return m_bModified ? S_OK : S_FALSE;
	}       
	STDMETHOD(GetSizeMax)(ULARGE_INTEGER __RPC_FAR *pCbSize)
	{
		return E_NOTIMPL;
	}       
protected:	
	bool	m_bModified;
};

/////////////////////////////////////////////////////////////////////////////
// CMimeDecoder
class ATL_NO_VTABLE CMimeDecoder : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CMimeDecoder, &CLSID_MimeDecoder>,
	public IConnectionPointContainerImpl<CMimeDecoder>,
	public IPersistBaseImpl,
	public IDispatchImpl<IMimeDecoder, &IID_IMimeDecoder, &LIBID_MIMESNIFFERLib>,
	public CProxy_IMimeDecoderEvents< CMimeDecoder >
{
public:
	CMimeDecoder();
	virtual ~CMimeDecoder();

DECLARE_REGISTRY_RESOURCEID(IDR_MIMEDECODER)
DECLARE_NOT_AGGREGATABLE(CMimeDecoder)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CMimeDecoder)
	COM_INTERFACE_ENTRY(IMimeDecoder)
	COM_INTERFACE_ENTRY(IDispatch)
	COM_INTERFACE_ENTRY(IConnectionPointContainer)
	COM_INTERFACE_ENTRY(IPersistStream)
	COM_INTERFACE_ENTRY(IPersistStreamInit)
	COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(CMimeDecoder)
CONNECTION_POINT_ENTRY(DIID__IMimeDecoderEvents)
END_CONNECTION_POINT_MAP()

public:
// Slots
static	CMutex								s_Mutex;
static	CMimeDecoder*						s_pCurrentMimeDec;	
		
		IStreamPtr							m_pStream;
		IStreamPtr							m_pRawCopy;

		list<pair<CYYSType, CYYSType> >		m_listReceived;
		CYYSType							m_ReturnPath;

		CYYSType							m_Date;
		CYYSType							m_ResentDate;

		CYYSType							m_Sender;
		CYYSType							m_From;
		CYYSType							m_ReplyTo;
											
		CYYSType							m_ResentSender;
		CYYSType							m_ResentFrom;
		CYYSType							m_ResentReplyTo;
								
		CYYSType							m_To;
		CYYSType							m_ResentTo;
		CYYSType							m_CC;
		CYYSType							m_ResentCC;
		CYYSType							m_BCC;
		CYYSType							m_ResentBCC;
											
		long								m_nVersionMajor;
		long								m_nVersionMinor;
											
		CYYSType							m_MessageID;
		CYYSType							m_Subject;

		CYYSType							m_ReturnReceiptTo;

		bool								m_bInterpretReceivedAsRaw;
		bool								m_bInterpretEmbeddedMails;
		bool								m_bErrorOccured;
		CMimeDecoder*						m_pParent;
		IStreamPtr							m_pCommit;

		CYYSType							m_Body;

// Enums
		typedef enum {	atype_unknown		= -1l, 
						atype_ftp,
						atype_anon_ftp,
						atype_tftp,
						atype_local_file,
						atype_afs,
						atype_mail_server
					 } ATYPE;

		typedef enum {	mimetype_unknown		= -1l, 
						mimetype_multipart,
						mimetype_text,
						mimetype_image,
						mimetype_application,
						mimetype_audio,
						mimetype_video,
						mimetype_message
					} MIMETYPE;


		typedef enum {	charset_unknown		= -1l, 
						charset_us_ascii
					} CHARSETTYPE;

		typedef enum {	multipart_subtype_unknown		= -1l, 
						multipart_subtype_mixed,
						multipart_subtype_parallel,
						multipart_subtype_digest,	
						multipart_subtype_alternative
					} MULTIPARTSUBTYPE;

		typedef enum {	text_subtype_unknown		= -1l, 
						text_subtype_plain,
						text_subtype_html
					} TEXTSUBTYPE;

		typedef enum {	mechanism_unknown		= -1l, 
						mechanism_7bit,
						mechanism_quoted_printable,
						mechanism_base64,	
						mechanism_8bit,		
						mechanism_binary
					} MECHANISMTYPE;

		typedef enum {	image_subtype_unknown		= -1l, 
						image_subtype_gif,
						image_subtype_jpg
					} IMAGESUBTYPE;

		typedef enum {	application_subtype_unknown		= -1l, 
						application_subtype_octet_stream,
						application_subtype_postscript
					} APPLICATIONSUBTYPE;

		typedef enum {	audio_subtype_unknown		= -1l, 
						audio_subtype_basic
					} AUDIOSUBTYPE;

		typedef enum {	video_subtype_unknown		= -1l, 
						video_subtype_mpeg
					} VIDEOSUBTYPE;

		typedef enum {	msg_subtype_unknown		= -1l, 
						msg_subtype_rfc822,
						msg_subtype_partial,
						msg_subtype_external_body
					} MESSAGESUBTYPE;
public:
		void SetReturnPath(const CYYSType& addr);
		void AddReceived(const CYYSType& received, const CYYSType& dt);
		void AddReceivedRaw(const CYYSType& field);
		
		void SetVersion(const CYYSType& nMajor, const CYYSType& nMinor);

		void SetReplyTo(const CYYSType& addr);
		void SetFrom(const CYYSType& addr);
		void SetSender(const CYYSType& addr);

		void SetResentReplyTo(const CYYSType& addr);
		void SetResentFrom(const CYYSType& addr);
		void SetResentSender(const CYYSType& addr);

		void SetDate(const CYYSType& dt);
		void SetResentDate(const CYYSType& dt);

		void SetTo(const CYYSType& addr);
		void SetResentTo(const CYYSType& addr);
		void SetCC(const CYYSType& addr);
		void SetResentCC(const CYYSType& addr);
		void SetBCC(const CYYSType& addr);
		void SetResentBCC(const CYYSType& addr);

		void SetSubject(const CYYSType& str);
		void SetMessageID(const CYYSType& id);

		void SetReturnReceiptTo(const CYYSType& addr);

		void SetBody(const CYYSType& body);

		void Modified();
		void IsProxy(LPSTREAM pStream, CMimeDecoder* pParent);

public:
		void OnError(const char* strError, long nLine);

protected:
		void SaveMailboxes(LPSTREAM pStm, const char* Intro, CYYSType& addr);
		
		string	m_strPath;

public:
	// IPersistStream
	STDMETHOD(GetClassID)(CLSID* pClassID)
	{
		*pClassID = CLSID_MimeDecoder;
		return S_OK;
	}
	STDMETHOD(Load)(LPSTREAM pStm);
	STDMETHOD(Save)(LPSTREAM pStm, BOOL fClearDirty);

	// IPersistStreamInit
	STDMETHOD(InitNew)(void);

// IMimeDecoder
public:
	STDMETHOD(get_InterpretEmbeddedMails)(/*[out, retval]*/ VARIANT_BOOL *pVal);
	STDMETHOD(put_InterpretEmbeddedMails)(/*[in]*/ VARIANT_BOOL newVal);
	STDMETHOD(get_Body)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_Body)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_SubjectRaw)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_SubjectRaw)(/*[in]*/ VARIANT newVal);
	STDMETHOD(Save)(/*[in]*/ LPDISPATCH StreamObject, /*[out,retval]*/ VARIANT_BOOL* pbvarRestult);
	STDMETHOD(Load)(/*[in]*/ LPDISPATCH StreamObject, /*[out,retval]*/ VARIANT_BOOL* pbvarRestult);
	STDMETHOD(get_ReturnReceiptTo)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_ReturnReceiptTo)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_ReceivedFieldAsRaw)(/*[out, retval]*/ VARIANT_BOOL *pVal);
	STDMETHOD(put_ReceivedFieldAsRaw)(/*[in]*/ VARIANT_BOOL newVal);
	STDMETHOD(get_MessageID)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_MessageID)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_Subject)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_Subject)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_BCC)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_BCC)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_CC)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_CC)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_To)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_To)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_ResentDate)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_ResentDate)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_Date)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_Date)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_ResentSender)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_ResentSender)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_ResentFrom)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_ResentFrom)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_ResentReplyTo)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_ResentReplyTo)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_Sender)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_Sender)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_From)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_From)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_ReplyTo)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_ReplyTo)(/*[in]*/ VARIANT newVal);
	STDMETHOD(get_MinorMimeVersion)(/*[out, retval]*/ long *pVal);
	STDMETHOD(put_MinorMimeVersion)(/*[in]*/ long newVal);
	STDMETHOD(get_MajorMimeVersion)(/*[out, retval]*/ long *pVal);
	STDMETHOD(put_MajorMimeVersion)(/*[in]*/ long newVal);
	STDMETHOD(get_ReturnPath)(/*[out, retval]*/ VARIANT *pVal);
	STDMETHOD(put_ReturnPath)(/*[in]*/ VARIANT newVal);
	STDMETHOD(put_UpdateName)(/*[in]*/ BSTR newVal);
	STDMETHOD(get_CanUpdateName)(/*[out, retval]*/ VARIANT_BOOL *pVal);
	STDMETHOD(SaveToFile)(/*[in]*/ BSTR Path, /*[out,retval]*/ VARIANT_BOOL* pbvarResult);
	STDMETHOD(LoadFromFile)(/*[in]*/ BSTR Path, /*[out,retval]*/ VARIANT_BOOL* pbvarResult);
};

#endif //__MIMEDECODER_H_

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions