// --------------------------------------------------------------------------------
// IMNXPORT.IDL
// Copyright (c)1993-1998 Microsoft Corporation, All Rights Reserved
//
// Authors:
// Steven J. Bailey (sbailey)
// Steve Serdy (steveser)
// Raymond Cheng (raych)
// Greg Friedman (gregfrie)
//
// Date: 11/12/96
// --------------------------------------------------------------------------------
import "imnact.idl";
interface IInternetTransport;
interface ISMTPTransport;
interface IPOP3Transport;
interface INNTPTransport;
interface IRASTransport;
interface IIMAPTransport;
interface IHTTPMailTransport;
interface IPropFindResponse;

cpp_quote("#if 0")
typedef HANDLE HDPA;
cpp_quote("#endif")

cpp_quote("//--------------------------------------------------------------------------------")
cpp_quote("// IMNXPORT.H")
cpp_quote("//--------------------------------------------------------------------------------")
cpp_quote("// (C) Copyright 1995-1998 Microsoft Corporation.  All Rights Reserved.")
cpp_quote("//")
cpp_quote("// THIS CODE AND INFORMATION IS PROVIDED \"AS IS\" WITHOUT WARRANTY OF")
cpp_quote("// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO")
cpp_quote("// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A")
cpp_quote("// PARTICULAR PURPOSE.")
cpp_quote("//--------------------------------------------------------------------------------")
cpp_quote("")
cpp_quote("#pragma comment(lib,\"uuid.lib\")")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// Dependencies")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#include <ras.h>")
cpp_quote("#include <raserror.h>")
cpp_quote("#include <commctrl.h>")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// GUIDS")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// {CA30CC91-B1B3-11d0-85D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(CLSID_IInternetMessageUrl, 0xca30cc91, 0xb1b3, 0x11d0, 0x85, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {0DF2C7E1-3435-11d0-81D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_ITransportCallback, 0xdf2c7e1, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {1F636C01-364E-11d0-81D3-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_IInternetTransport, 0x1f636c01, 0x364e, 0x11d0, 0x81, 0xd3, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {1F636C02-364E-11d0-81D3-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_ISMTPCallback, 0x1f636c02, 0x364e, 0x11d0, 0x81, 0xd3, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {FD853CE6-7F86-11d0-8252-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(CLSID_ISMTPTransport, 0xfd853ce6, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("// {0DF2C7E2-3435-11d0-81D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_ISMTPTransport, 0xdf2c7e2, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("// {0DF2C7EC-3435-11d0-81D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_ISMTPTransport2, 0xdf2c7eC, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {0DF2C7E3-3435-11d0-81D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_IPOP3Callback, 0xdf2c7e3, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {FD853CE7-7F86-11d0-8252-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(CLSID_IPOP3Transport, 0xfd853ce7, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("// {0DF2C7E4-3435-11d0-81D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_IPOP3Transport, 0xdf2c7e4, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {0DF2C7E5-3435-11d0-81D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_INNTPCallback, 0xdf2c7e5, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {FD853CE8-7F86-11d0-8252-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(CLSID_INNTPTransport, 0xfd853ce8, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("// {0DF2C7E6-3435-11d0-81D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_INNTPTransport, 0xdf2c7e6, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("// {0DF2C7ED-3435-11d0-81D0-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_INNTPTransport2, 0xdf2c7eD, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {36D88911-3CD6-11d0-81DF-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_IRASCallback, 0x36d88911, 0x3cd6, 0x11d0, 0x81, 0xdf, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {FD853CE9-7F86-11d0-8252-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(CLSID_IRASTransport, 0xfd853ce9, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("// {8A950001-3CCF-11d0-81DF-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_IRASTransport, 0x8a950001, 0x3ccf, 0x11d0, 0x81, 0xdf, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {FD853CEA-7F86-11d0-8252-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(CLSID_IRangeList, 0xfd853cea, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("// {8C438160-4EF6-11d0-874F-00AA00530EE9}")
cpp_quote("DEFINE_GUID(IID_IRangeList, 0x8c438160, 0x4ef6, 0x11d0, 0x87, 0x4f, 0x0, 0xaa, 0x0, 0x53, 0xe, 0xe9);")
cpp_quote("")
cpp_quote("// {E9E9D8A3-4EDD-11d0-874F-00AA00530EE9}")
cpp_quote("DEFINE_GUID(IID_IIMAPCallback, 0xe9e9d8a3, 0x4edd, 0x11d0, 0x87, 0x4f, 0x0, 0xaa, 0x0, 0x53, 0xe, 0xe9);")
cpp_quote("")
cpp_quote("// {FD853CEB-7F86-11d0-8252-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(CLSID_IIMAPTransport, 0xfd853ceb, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("// {E9E9D8A8-4EDD-11d0-874F-00AA00530EE9}")
cpp_quote("DEFINE_GUID(IID_IIMAPTransport, 0xe9e9d8a8, 0x4edd, 0x11d0, 0x87, 0x4f, 0x0, 0xaa, 0x0, 0x53, 0xe, 0xe9);")
cpp_quote("")
cpp_quote("// {DA8283C0-37C5-11d2-ACD9-0080C7B6E3C5}")
cpp_quote("DEFINE_GUID(IID_IIMAPTransport2, 0xda8283c0, 0x37c5, 0x11d2, 0xac, 0xd9, 0x0, 0x80, 0xc7, 0xb6, 0xe3, 0xc5);")
cpp_quote("")
cpp_quote("// {07849A11-B520-11d0-85D5-00C04FD85AB4}")
cpp_quote("DEFINE_GUID(IID_IBindMessageStream, 0x7849a11, 0xb520, 0x11d0, 0x85, 0xd5, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);")
cpp_quote("")
cpp_quote("// {CA30F3FF-C9AC-11d1-9A3A-00C04FA309D4}")
cpp_quote("DEFINE_GUID(IID_ITransportCallbackService, 0xca30f3ff, 0xc9ac, 0x11d1, 0x9a, 0x3a, 0x0, 0xc0, 0x4f, 0xa3, 0x9, 0xd4);")
cpp_quote("")
cpp_quote("// {19F6481C-E5F0-11d1-A86E-0000F8084F96}")
cpp_quote("DEFINE_GUID(IID_IHTTPMailCallback, 0x19f6481c, 0xe5f0, 0x11d1, 0xa8, 0x6e, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("")
cpp_quote("// {5A580C11-E5EB-11d1-A86E-0000F8084F96}")
cpp_quote("DEFINE_GUID(CLSID_IHTTPMailTransport,0x5a580c11, 0xe5eb, 0x11d1, 0xa8, 0x6e, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("// {B8BDE03C-E548-11d1-A86E-0000F8084F96}")
cpp_quote("DEFINE_GUID(IID_IHTTPMailTransport, 0xb8bde03c, 0xe548, 0x11d1, 0xa8, 0x6e, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("")
cpp_quote("// {82758005-D38A-11d3-8E81-00C04F79E13B}")
cpp_quote("DEFINE_GUID(IID_IHTTPMailTransport2, 0x82758005, 0xd38a, 0x11d3, 0x8e, 0x81, 0x0, 0xc0, 0x4f, 0x79, 0xe1, 0x3b);")
cpp_quote("")
cpp_quote("// {BB847B8A-054A-11d2-A894-0000F8084F96}")
cpp_quote("DEFINE_GUID(CLSID_IPropFindRequest, 0xbb847b8a, 0x54a, 0x11d2, 0xa8, 0x94, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("// {5CFC6308-0544-11d2-A894-0000F8084F96}")
cpp_quote("DEFINE_GUID(IID_IPropFindRequest, 0x5cfc6308, 0x544, 0x11d2, 0xa8, 0x94, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("")
cpp_quote("// {0DEE87DE-0547-11d2-A894-0000F8084F96}")
cpp_quote("DEFINE_GUID(IID_IPropFindMultiResponse, 0xdee87de, 0x547, 0x11d2, 0xa8, 0x94, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("")
cpp_quote("// {8A523716-0548-11d2-A894-0000F8084F96}")
cpp_quote("DEFINE_GUID(IID_IPropFindResponse, 0x8a523716, 0x548, 0x11d2, 0xa8, 0x94, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("")
cpp_quote("// {72A58FF8-227D-11d2-A8B5-0000F8084F96}")
cpp_quote("DEFINE_GUID(IID_IDAVNamespaceArbiter, 0x72a58ff8, 0x227d, 0x11d2, 0xa8, 0xb5, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("")
cpp_quote("// {EA678830-235D-11d2-A8B6-0000F8084F96}")
cpp_quote("DEFINE_GUID(CLSID_IPropPatchRequest, 0xea678830, 0x235d, 0x11d2, 0xa8, 0xb6, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("// {AB8B8D2A-227F-11d2-A8B5-0000F8084F96}")
cpp_quote("DEFINE_GUID(IID_IPropPatchRequest, 0xab8b8d2a, 0x227f, 0x11d2, 0xa8, 0xb5, 0x0, 0x0, 0xf8, 0x8, 0x4f, 0x96);")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// Errors")
cpp_quote("// --------------------------------------------------------------------------------")
//;begin_internal
//
//  NOTE:  All inetcomm error codes must reside between CC00 and CFFF (a 1k block).
//  This has been approved by Johann Posch (johannp)
//  We further subdivide this range as follows:
//      CC00-CCFF   IMNXPORT results
//      CD00-CDFF   IMNACCT results
//      CE00-CEFF   MIMEOLE results
//      CF00-CFFF   undefined, do not use
//  (t-erikne 03/24/97)
//
//;end_internal
cpp_quote("#ifndef FACILITY_INTERNET")
cpp_quote("#define FACILITY_INTERNET 12")
cpp_quote("#endif")
cpp_quote("#ifndef HR_E")
cpp_quote("#define HR_E(n) MAKE_SCODE(SEVERITY_ERROR, FACILITY_INTERNET, n)")
cpp_quote("#endif")
cpp_quote("#ifndef HR_S")
cpp_quote("#define HR_S(n) MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_INTERNET, n)")
cpp_quote("#endif")
cpp_quote("#ifndef HR_CODE")
cpp_quote("#define HR_CODE(hr) (INT)(hr & 0xffff)")
cpp_quote("#endif")
cpp_quote("")
//;begin_internal
//  HRESULTS are even further subdivided in this file
//  NOTE: you should never progammatically rely on this ordering
//  it simply gives you a visual cue in the DOUTs
//      CC00-CC2F   General
//      CC30-CC3F   HTTPMail (first range)
//      CC40-CC5F   WINSOCK
//      CC60-CC8F   SMTP
//      CC90-CC9F   POP3
//      CCA0-CCBF   NNTP
//      CCC0-CCCF   RAS
//      CCD0-CCEF   IMAP
//      CCF0-CCFF   HTTPMail (second range)
//;end_internal
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// General Imnxport Return Values")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#define IXP_E_LOAD_SICILY_FAILED             HR_E(0xCC00)")  // hrFailedToLoadSicily
cpp_quote("#define IXP_E_INVALID_CERT_CN                HR_E(0xCC01)")  // hrInvalidCertCN
cpp_quote("#define IXP_E_INVALID_CERT_DATE              HR_E(0xCC02)")  // hrInvalidCertDate
cpp_quote("#define IXP_E_ALREADY_CONNECTED              HR_E(0xCC03)")  // hrAlreadyConnected
cpp_quote("#define IXP_E_CONN                           HR_E(0xCC04)")  // hrConn
cpp_quote("#define IXP_E_NOT_CONNECTED                  HR_E(0xCC05)")  // hrNotConnected
cpp_quote("#define IXP_E_CONN_SEND                      HR_E(0xCC06)")  // hrConnSend
cpp_quote("#define IXP_E_WOULD_BLOCK                    HR_E(0xCC07)")  // hrWouldBlock
cpp_quote("#define IXP_E_INVALID_STATE                  HR_E(0xCC08)")  // hrInvalidState
cpp_quote("#define IXP_E_CONN_RECV                      HR_E(0xCC09)")  // hrConnRecv
cpp_quote("#define IXP_E_INCOMPLETE                     HR_E(0xCC0A)")  // hrIncomplete
cpp_quote("#define IXP_E_BUSY                           HR_E(0xCC0B)")
cpp_quote("#define IXP_E_NOT_INIT                       HR_E(0xCC0C)")
cpp_quote("#define IXP_E_CANT_FIND_HOST                 HR_E(0xCC0D)")
cpp_quote("#define IXP_E_FAILED_TO_CONNECT              HR_E(0xCC0E)")
cpp_quote("#define IXP_E_CONNECTION_DROPPED             HR_E(0xCC0F)")
cpp_quote("#define IXP_E_INVALID_ADDRESS                HR_E(0xCC10)")
cpp_quote("#define IXP_E_INVALID_ADDRESS_LIST           HR_E(0xCC11)")
cpp_quote("#define IXP_E_SOCKET_READ_ERROR              HR_E(0xCC12)")
cpp_quote("#define IXP_E_SOCKET_WRITE_ERROR             HR_E(0xCC13)")
cpp_quote("#define IXP_E_SOCKET_INIT_ERROR              HR_E(0xCC14)")
cpp_quote("#define IXP_E_SOCKET_CONNECT_ERROR           HR_E(0xCC15)")
cpp_quote("#define IXP_E_INVALID_ACCOUNT                HR_E(0xCC16)")
cpp_quote("#define IXP_E_USER_CANCEL                    HR_E(0xCC17)")
cpp_quote("#define IXP_E_SICILY_LOGON_FAILED            HR_E(0xCC18)")  // hrSicilyLogonFailed
cpp_quote("#define IXP_E_TIMEOUT                        HR_E(0xCC19)")
cpp_quote("#define IXP_E_SECURE_CONNECT_FAILED			HR_E(0xCC1A)")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// WINSOCK Errors")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#define IXP_E_WINSOCK_WSASYSNOTREADY         HR_E(0xCC40)")
cpp_quote("#define IXP_E_WINSOCK_WSAVERNOTSUPPORTED     HR_E(0xCC41)")
cpp_quote("#define IXP_E_WINSOCK_WSAEPROCLIM            HR_E(0xCC42)")
cpp_quote("#define IXP_E_WINSOCK_WSAEFAULT              HR_E(0xCC43)")
cpp_quote("#define IXP_E_WINSOCK_FAILED_WSASTARTUP      HR_E(0xCC44)")
cpp_quote("#define IXP_E_WINSOCK_WSAEINPROGRESS         HR_E(0xCC45)")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// SMTP Command Response Values")
cpp_quote("//--------------------------------------------------------------------------------")
cpp_quote("#define IXP_E_SMTP_RESPONSE_ERROR            HR_E(0xCC60)")
cpp_quote("#define IXP_E_SMTP_UNKNOWN_RESPONSE_CODE     HR_E(0xCC61)")
cpp_quote("#define IXP_E_SMTP_500_SYNTAX_ERROR          HR_E(0xCC62)")
cpp_quote("#define IXP_E_SMTP_501_PARAM_SYNTAX          HR_E(0xCC63)")
cpp_quote("#define IXP_E_SMTP_502_COMMAND_NOTIMPL       HR_E(0xCC64)")
cpp_quote("#define IXP_E_SMTP_503_COMMAND_SEQ           HR_E(0xCC65)")
cpp_quote("#define IXP_E_SMTP_504_COMMAND_PARAM_NOTIMPL HR_E(0xCC66)")
cpp_quote("#define IXP_E_SMTP_421_NOT_AVAILABLE         HR_E(0xCC67)")
cpp_quote("#define IXP_E_SMTP_450_MAILBOX_BUSY          HR_E(0xCC68)")
cpp_quote("#define IXP_E_SMTP_550_MAILBOX_NOT_FOUND     HR_E(0xCC69)")
cpp_quote("#define IXP_E_SMTP_451_ERROR_PROCESSING      HR_E(0xCC6A)")
cpp_quote("#define IXP_E_SMTP_551_USER_NOT_LOCAL        HR_E(0xCC6B)")
cpp_quote("#define IXP_E_SMTP_452_NO_SYSTEM_STORAGE     HR_E(0xCC6C)")
cpp_quote("#define IXP_E_SMTP_552_STORAGE_OVERFLOW      HR_E(0xCC6D)")
cpp_quote("#define IXP_E_SMTP_553_MAILBOX_NAME_SYNTAX   HR_E(0xCC6E)")
cpp_quote("#define IXP_E_SMTP_554_TRANSACT_FAILED       HR_E(0xCC6F)")
cpp_quote("")
cpp_quote("#define IXP_S_SMTP_211_SYSTEM_STATUS         HR_S(0xCC70)")
cpp_quote("#define IXP_S_SMTP_214_HELP_MESSAGE          HR_S(0xCC71)")
cpp_quote("#define IXP_S_SMTP_220_READY                 HR_S(0xCC72)")
cpp_quote("#define IXP_S_SMTP_221_CLOSING               HR_S(0xCC73)")
cpp_quote("#define IXP_S_SMTP_250_MAIL_ACTION_OKAY      HR_S(0xCC74)")
cpp_quote("#define IXP_S_SMTP_251_FORWARDING_MAIL       HR_S(0xCC75)")
cpp_quote("#define IXP_S_SMTP_354_START_MAIL_INPUT      HR_S(0xCC76)")
cpp_quote("#define IXP_S_SMTP_CONTINUE                  HR_S(0xCC77)")
cpp_quote("#define IXP_S_SMTP_334_AUTH_READY_RESPONSE   HR_S(0xCC78)")
cpp_quote("#define IXP_S_SMTP_245_AUTH_SUCCESS          HR_S(0xCC79)")
cpp_quote("")
cpp_quote("#define IXP_E_SMTP_REJECTED_SENDER           HR_E(0xCC78)")
cpp_quote("#define IXP_E_SMTP_REJECTED_RECIPIENTS       HR_E(0xCC79)")
cpp_quote("#define IXP_E_SMTP_NO_SENDER                 HR_E(0xCC7A)")
cpp_quote("#define IXP_E_SMTP_NO_RECIPIENTS             HR_E(0xCC7B)")
cpp_quote("#define IXP_E_SMTP_530_STARTTLS_REQUIRED      HR_E(0xCC7C)")
cpp_quote("#define IXP_E_SMTP_NO_STARTTLS_SUPPORT       HR_E(0xCC7D)")
cpp_quote("#define IXP_S_SMTP_NO_DSN_SUPPORT            HR_E(0xCC7E)")
cpp_quote("#define IXP_E_SMTP_454_STARTTLS_FAILED       HR_E(0xCC7F)")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// POP3 Command Response Values")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#define IXP_E_POP3_RESPONSE_ERROR            HR_E(0xCC90)")
cpp_quote("#define IXP_E_POP3_INVALID_USER_NAME         HR_E(0xCC91)") // hrPOP3BadUserName
cpp_quote("#define IXP_E_POP3_INVALID_PASSWORD          HR_E(0xCC92)") // hrPOP3BadPassword
cpp_quote("#define IXP_E_POP3_PARSE_FAILURE             HR_E(0xCC93)")
cpp_quote("#define IXP_E_POP3_NEED_STAT                 HR_E(0xCC94)")
cpp_quote("#define IXP_E_POP3_NO_MESSAGES               HR_E(0xCC95)")
cpp_quote("#define IXP_E_POP3_NO_MARKED_MESSAGES        HR_E(0xCC96)")
cpp_quote("#define IXP_E_POP3_POPID_OUT_OF_RANGE        HR_E(0xCC97)")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// NNTP Command Response Values")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#define IXP_E_NNTP_RESPONSE_ERROR            HR_E(0xCCA0)")   // hrInvalidResponse
cpp_quote("#define IXP_E_NNTP_NEWGROUPS_FAILED          HR_E(0xCCA1)")
cpp_quote("#define IXP_E_NNTP_LIST_FAILED               HR_E(0xCCA2)")
cpp_quote("#define IXP_E_NNTP_LISTGROUP_FAILED          HR_E(0xCCA3)")
cpp_quote("#define IXP_E_NNTP_GROUP_FAILED              HR_E(0xCCA4)")
cpp_quote("#define IXP_E_NNTP_GROUP_NOTFOUND            HR_E(0xCCA5)")
cpp_quote("#define IXP_E_NNTP_ARTICLE_FAILED            HR_E(0xCCA6)")
cpp_quote("#define IXP_E_NNTP_HEAD_FAILED               HR_E(0xCCA7)")
cpp_quote("#define IXP_E_NNTP_BODY_FAILED               HR_E(0xCCA8)")
cpp_quote("#define IXP_E_NNTP_POST_FAILED               HR_E(0xCCA9)")
cpp_quote("#define IXP_E_NNTP_NEXT_FAILED               HR_E(0xCCAA)")
cpp_quote("#define IXP_E_NNTP_DATE_FAILED               HR_E(0xCCAB)")
cpp_quote("#define IXP_E_NNTP_HEADERS_FAILED            HR_E(0xCCAC)")
cpp_quote("#define IXP_E_NNTP_XHDR_FAILED               HR_E(0xCCAD)")
cpp_quote("#define IXP_E_NNTP_INVALID_USERPASS          HR_E(0xCCAE)")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// NNTP Server Response Values")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#define IXP_NNTP_DATE_RESPONSE               111")
cpp_quote("#define IXP_NNTP_POST_ALLOWED                200")
cpp_quote("#define IXP_NNTP_POST_NOTALLOWED             201")
cpp_quote("#define IXP_NNTP_GROUP_SELECTED              211")
cpp_quote("#define IXP_NNTP_LIST_DATA_FOLLOWS           215")
cpp_quote("#define IXP_NNTP_ARTICLE_FOLLOWS             220")
cpp_quote("#define IXP_NNTP_HEAD_FOLLOWS                221")
cpp_quote("#define IXP_NNTP_BODY_FOLLOWS                222")
cpp_quote("#define IXP_NNTP_ARTICLE_RETRIEVED           223")
cpp_quote("#define IXP_NNTP_OVERVIEW_FOLLOWS            224")
cpp_quote("#define IXP_NNTP_NEWNEWSGROUPS_FOLLOWS       231")
cpp_quote("#define IXP_NNTP_ARTICLE_POSTED_OK           240")
cpp_quote("#define IXP_NNTP_AUTHORIZATION_ACCEPTED      250")
cpp_quote("#define IXP_NNTP_AUTH_OK                     281")
cpp_quote("#define IXP_NNTP_SEND_ARTICLE_TO_POST        340")
cpp_quote("#define IXP_NNTP_CONTINUE_AUTHORIZATION      350")
cpp_quote("#define IXP_NNTP_PASSWORD_REQUIRED           381")
cpp_quote("#define IXP_NNTP_NO_SUCH_NEWSGROUP           411")
cpp_quote("#define IXP_NNTP_NO_NEXT_ARTICLE             421")
cpp_quote("#define IXP_NNTP_NO_PREV_ARTICLE             422")
cpp_quote("#define IXP_NNTP_NO_SUCH_ARTICLE_NUM         423")
cpp_quote("#define IXP_NNTP_NO_SUCH_ARTICLE_FOUND       430")
cpp_quote("#define IXP_NNTP_POSTING_NOT_ALLOWED         441")
cpp_quote("#define IXP_NNTP_PROTOCOLS_SUPPORTED         485")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// RAS Errors")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#define IXP_S_RAS_NOT_NEEDED                 HR_S(0xCCC0)")
cpp_quote("#define IXP_S_RAS_USING_CURRENT              HR_S(0xCCC1)")
cpp_quote("#define IXP_E_RAS_NOT_INSTALLED              HR_E(0xCCC2)")
cpp_quote("#define IXP_E_RAS_PROCS_NOT_FOUND            HR_E(0xCCC3)")
cpp_quote("#define IXP_E_RAS_ERROR                      HR_E(0xCCC4)")
cpp_quote("#define IXP_E_RAS_INVALID_CONNECTOID         HR_E(0xCCC5)")
cpp_quote("#define IXP_E_RAS_GET_DIAL_PARAMS            HR_E(0xCCC6)")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// IMAP Return Codes")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#define IXP_S_IMAP_UNRECOGNIZED_RESP         HR_S(0xCCD0) // Did not recognize IMAP response CODE")
cpp_quote("#define IXP_S_IMAP_VERBATIM_MBOX             HR_S(0xCCE1) // Could not xlate mbox to target CP (or it's disabled): copying verbatim")
cpp_quote("")
cpp_quote("#define IXP_E_IMAP_LOGINFAILURE              HR_E(0xCCD1) // LOGIN cmd failed")
cpp_quote("#define IXP_E_IMAP_TAGGED_NO_RESPONSE        HR_E(0xCCD2) // Received tagged NO response")
cpp_quote("#define IXP_E_IMAP_BAD_RESPONSE              HR_E(0xCCD3) // Received tagged BAD response")
cpp_quote("#define IXP_E_IMAP_SVR_SYNTAXERR             HR_E(0xCCD4) // Syntax error in svr response")
cpp_quote("#define IXP_E_IMAP_NOTIMAPSERVER             HR_E(0xCCD5) // This is not an IMAP server")
cpp_quote("#define IXP_E_IMAP_BUFFER_OVERFLOW           HR_E(0xCCD6) // Buffer overflow occurred")
cpp_quote("#define IXP_E_IMAP_RECVR_ERROR               HR_E(0xCCD7) // An error occurred in the recvr code")
cpp_quote("#define IXP_E_IMAP_INCOMPLETE_LINE           HR_E(0xCCD8) // Received incomplete line")
cpp_quote("#define IXP_E_IMAP_CONNECTION_REFUSED        HR_E(0xCCD9) // Received BYE on greeting")
cpp_quote("#define IXP_E_IMAP_UNRECOGNIZED_RESP         HR_E(0xCCDA) // Did not recognize IMAP response")
cpp_quote("#define IXP_E_IMAP_CHANGEDUID                HR_E(0xCCDB) // UID changed unexpectedly!")
cpp_quote("#define IXP_E_IMAP_UIDORDER                  HR_E(0xCCDC) // UIDs not strictly ascending!")
cpp_quote("#define IXP_E_IMAP_UNSOLICITED_BYE           HR_E(0xCCDD) // Server issued UNSOLICITED BYE")
cpp_quote("#define IXP_E_IMAP_IMPROPER_SVRSTATE			HR_E(0xCCDE) // eg, Attempt to send FETCH before SELECT finishes")
cpp_quote("#define IXP_E_IMAP_AUTH_NOT_POSSIBLE			HR_E(0xCCDF) // No common authentication methods btwn client/svr")
cpp_quote("#define IXP_E_IMAP_OUT_OF_AUTH_METHODS		HR_E(0xCCE0) // We tried >= 1 auth method, no more left to try")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// HTTPMail Return Codes")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// http errors are discontiguous.")
cpp_quote("#define IXP_E_HTTP_USE_PROXY                 HR_E(0xCC30) // http status 305")
cpp_quote("#define IXP_E_HTTP_BAD_REQUEST               HR_E(0xCC31) // http status 400")
cpp_quote("#define IXP_E_HTTP_UNAUTHORIZED              HR_E(0xCC32) // http status 401")
cpp_quote("#define IXP_E_HTTP_FORBIDDEN                 HR_E(0xCC33) // http status 403")
cpp_quote("#define IXP_E_HTTP_NOT_FOUND                 HR_E(0xCC34) // http status 404")
cpp_quote("#define IXP_E_HTTP_METHOD_NOT_ALLOW          HR_E(0xCC35) // http status 405")
cpp_quote("#define IXP_E_HTTP_NOT_ACCEPTABLE            HR_E(0xCC36) // http status 406")
cpp_quote("#define IXP_E_HTTP_PROXY_AUTH_REQ            HR_E(0xCC37) // http status 407")
cpp_quote("#define IXP_E_HTTP_REQUEST_TIMEOUT           HR_E(0xCC38) // http status 408")
cpp_quote("#define IXP_E_HTTP_CONFLICT                  HR_E(0xCC39) // http status 409")
cpp_quote("#define IXP_E_HTTP_GONE                      HR_E(0xCC3A) // http status 410")
cpp_quote("#define IXP_E_HTTP_LENGTH_REQUIRED           HR_E(0xCC3B) // http status 411")
cpp_quote("#define IXP_E_HTTP_PRECOND_FAILED            HR_E(0xCC3C) // http status 412")
cpp_quote("#define IXP_E_HTTP_INTERNAL_ERROR            HR_E(0xCC3D) // http status 500")
cpp_quote("#define IXP_E_HTTP_NOT_IMPLEMENTED           HR_E(0xCC3E) // http status 501")
cpp_quote("#define IXP_E_HTTP_BAD_GATEWAY               HR_E(0xCC3F) // http status 502")
cpp_quote("// begin second range")
cpp_quote("#define IXP_E_HTTP_SERVICE_UNAVAIL           HR_E(0xCCF0) // http status 503")
cpp_quote("#define IXP_E_HTTP_GATEWAY_TIMEOUT           HR_E(0xCCF1) // http status 504")
cpp_quote("#define IXP_E_HTTP_VERS_NOT_SUP              HR_E(0xCCF2) // http status 505")
cpp_quote("#define IXP_E_HTTP_INSUFFICIENT_STORAGE      HR_E(0xCCF3) // http status 425 or 507")
cpp_quote("#define IXP_E_HTTP_ROOT_PROP_NOT_FOUND       HR_E(0xCCF4) // see IHTTPMailTransport::GetProperty")
cpp_quote("#define IXP_E_HTTP_NOT_MODIFIED              HR_E(0xCCF5) // http status 304")
cpp_quote("#define IXP_E_HTTP_PAYMENT_REQUIRED          HR_E(0xCCF6) // http status 402")
cpp_quote("#define IXP_E_HTTP_DAV_ACCESS_TURNED_OFF     HR_E(0xCCF7) // http status 404 + x-dav-errror 1204")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// String Length Constants")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("")

    // ---------------------------------------------------------------------------------------
    // All of the transports in this file work in an asyncronous mode. It is assumed that
    // the client application has a message pump on the thread in which a transport object
    // is created.
    // ---------------------------------------------------------------------------------------

    // ---------------------------------------------------------------------------------------
    // String Lengths
    // ---------------------------------------------------------------------------------------
    const SHORT CCHMAX_DOMAIN = 256;
    const SHORT CCHMAX_PHONE_NUMBER = 128; // RAS_MaxPhoneNumber

    // ---------------------------------------------------------------------------------------
    // Default Port Numbers
    // ---------------------------------------------------------------------------------------
    const DWORD DEFAULT_IMAP_PORT = 143;
    const DWORD DEFAULT_POP3_PORT = 110;
    const DWORD DEFAULT_SMTP_PORT = 25;
    const DWORD DEFAULT_NNTP_PORT = 119;

    // ---------------------------------------------------------------------------------------
    // Internet Address Type
    //
    // There are only two address types because the SMTP protocol only distinguishes
    // between a sender (ADDR_FROM) and recipients. ADDR_TO should include all Bcc, Cc and
    // To recipients.
    //
    // additional DSN flags may be anded in and will result in a DSN request only if the
    // SMTP server supports DSNs (rfc1891) and the transport connected with an EHLO command
    // ---------------------------------------------------------------------------------------
    typedef enum tagINETADDRTYPE {
        ADDR_TO,                            // Recipient of the message (To, CC, Bcc, etc)
        ADDR_FROM,                          // Sender of the message
        ADDR_DSN_NEVER = 16,                // suppress all delivery status notification
        ADDR_DSN_SUCCESS = 32,              // request DSN on successful delivery
        ADDR_DSN_FAILURE = 64,              // request DSN on delivery failure
        ADDR_DSN_DELAY   = 128              // request DSN if delivery is delayed
    } INETADDRTYPE;

    const DWORD ADDR_TOFROM_MASK = 0x1;        // INETADDRTYPE & ADDR_TOFROM_MASK gives raw type
    const DWORD ADDR_DSN_MASK = 0xf0;

    // ---------------------------------------------------------------------------------------
    // DSNRET
    // controls what whether full message or headers only will be returned with DSNs
    // ---------------------------------------------------------------------------------------
	typedef enum tagDSNRET {
		DSNRET_DEFAULT,                     // use SMTP server default
		DSNRET_HDRS,                        // return 822 headers only
		DSNRET_FULL,                        // return full message - headers + body
	} DSNRET;

    // ---------------------------------------------------------------------------------------
    // Internet Address
    // ---------------------------------------------------------------------------------------
    typedef struct tagINETADDR {
	INETADDRTYPE        addrtype;
	CHAR                szEmail[CCHMAX_EMAIL_ADDRESS]; // A person's e-mail address
    } INETADDR, *LPINETADDR;

    // ---------------------------------------------------------------------------------------
    // Internet Address List
    // ---------------------------------------------------------------------------------------
    typedef struct tagINETADDRLIST   {
	ULONG               cAddress;      // Number of elements in prgInetAddr
	LPINETADDR          prgAddress;    // Array of internet addresses
    } INETADDRLIST, *LPINETADDRLIST;

    // -----------------------------------------------------------------------------------
    // RAS Connection Type
    // -----------------------------------------------------------------------------------
    typedef enum tagRASCONNTYPE {
	RAS_CONNECT_LAN,
	RAS_CONNECT_MANUAL,
	RAS_CONNECT_RAS
    } RASCONNTYPE;

    // -----------------------------------------------------------------------------------
    // HTTPMAIL Root Property Types
    // -----------------------------------------------------------------------------------
	typedef enum tagHTTPMAILPROPTYPE {
        HTTPMAIL_PROP_INVALID,
        HTTPMAIL_PROP_ADBAR,
        HTTPMAIL_PROP_CONTACTS,
        HTTPMAIL_PROP_INBOX,
        HTTPMAIL_PROP_OUTBOX,
        HTTPMAIL_PROP_SENDMSG,
        HTTPMAIL_PROP_SENTITEMS,
        HTTPMAIL_PROP_DELETEDITEMS,
        HTTPMAIL_PROP_DRAFTS,
        HTTPMAIL_PROP_MSGFOLDERROOT,
        HTTPMAIL_PROP_SIG,
        HTTPMAIL_PROP_MAXPOLLINGINTERVAL,
        HTTPMAIL_PROP_LAST
	} HTTPMAILPROPTYPE;

    // -----------------------------------------------------------------------------------
    // HTTPMAIL Special Folder Types
    // -----------------------------------------------------------------------------------
    typedef enum tagHTTPMAILSPECIALFOLDER {
        HTTPMAIL_SF_NONE = 0,
        HTTPMAIL_SF_UNRECOGNIZED,
        HTTPMAIL_SF_INBOX,
        HTTPMAIL_SF_DELETEDITEMS,
        HTTPMAIL_SF_DRAFTS,
        HTTPMAIL_SF_OUTBOX,
        HTTPMAIL_SF_SENTITEMS,
        HTTPMAIL_SF_CONTACTS,
        HTTPMAIL_SF_CALENDAR,
        HTTPMAIL_SF_MSNPROMO,
        HTTPMAIL_SF_BULKMAIL,
        HTTPMAIL_SF_LAST
    } HTTPMAILSPECIALFOLDER;

    // -----------------------------------------------------------------------------------
    // HTTPMAIL Contact Types
    // -----------------------------------------------------------------------------------
    typedef enum tagHTTPMAILCONTACTTYPE {
	HTTPMAIL_CT_CONTACT = 0,    // default
	HTTPMAIL_CT_GROUP,
	HTTPMAIL_CT_LAST
    } HTTPMAILCONTACTTYPE;

    // -----------------------------------------------------------------------------------
    // DAV Namespaces
    // -----------------------------------------------------------------------------------
    const DWORD DAVNAMESPACE_UNKNOWN    = 0xFFFFFFFF;
    const DWORD DAVNAMESPACE_DAV        = 0;
    const DWORD DAVNAMESPACE_HOTMAIL    = 1;
    const DWORD DAVNAMESPACE_HTTPMAIL   = 2;
    const DWORD DAVNAMESPACE_MAIL       = 3;
    const DWORD DAVNAMESPACE_CONTACTS   = 4;

    // ---------------------------------------------------------------------------------------
    // Internet Server Flags...
    // ---------------------------------------------------------------------------------------
    cpp_quote("#define      ISF_SMTP_USEIPFORHELO           0x00000001 // For HELO or EHLO Command")
    cpp_quote("#define      ISF_ALWAYSPROMPTFORPASSWORD     0x00000002 // For HELO or EHLO Command")            // Never save password (boolean)
    cpp_quote("#define      ISF_SSLONSAMEPORT               0x00000004 // For SMTP Only - use STARTTLS")        // For STARTTLS Support
    cpp_quote("#define      ISF_QUERYDSNSUPPORT             0x00000008 // For SMTP Only - issue EHLO on connect and check for DSN")
    cpp_quote("#define      ISF_QUERYAUTHSUPPORT            0x00000010 // For SMTP Only - issue EHLO on connect and check for AUTH")

    // ---------------------------------------------------------------------------------------
    // Internet Server Information...
    // ---------------------------------------------------------------------------------------
    typedef struct INETSERVER {
    CHAR                szAccount[CCHMAX_ACCOUNT_NAME];    // IMN Account Name
    CHAR                szUserName[CCHMAX_USERNAME];       // User's connection name
    CHAR                szPassword[CCHMAX_PASSWORD];       // User's password
    CHAR                szServerName[CCHMAX_SERVER_NAME];  // Server name (or IP address string)
    CHAR                szConnectoid[CCHMAX_CONNECTOID];   // RAS Connection Name
    RASCONNTYPE         rasconntype;    // RAS connection type
    DWORD               dwPort;         // Port name
    BOOL                fSSL;           // Using SSL
    BOOL                fTrySicily;     // Try using sicily authentication
    DWORD               dwTimeout;      // Timeout in seconds
    DWORD               dwFlags;        // ISF_xxx Flags (above)
    } INETSERVER, *LPINETSERVER;

    // -----------------------------------------------------------------------------------
    // Internet Transport Types
    // -----------------------------------------------------------------------------------
    typedef enum tagIXPTYPE {
    IXP_NNTP,       // NNTP (News)
    IXP_SMTP,       // SMTP (Send)
    IXP_POP3,       // POP3 (Recv)
    IXP_IMAP,       // IMAP (Recv / remote store)
    IXP_RAS,
    IXP_HTTPMail,   // HTTPMail (Recv / remote store)
    IXP_HTTP        // Community News
    } IXPTYPE;

    // -----------------------------------------------------------------------------------
    // IXPSTATUS - Transport Status Types
    //
    // These values are returned in the ITransportCallback::OnStatus callback method
    // and in the IInternetTransport::GetStatus member.
    // -----------------------------------------------------------------------------------
    typedef enum tagIXPSTATUS
    {
        IXP_FINDINGHOST,    // Attempting to find host (IP/host name resolution)
        IXP_CONNECTING,     // TCP/IP connection is in progress
        IXP_SECURING,       // TCP/IP socket connection has been established, securing an SSL connection
        IXP_CONNECTED,      // TCP/IP socket connection has been established, waiting for protcol response
        IXP_AUTHORIZING,    // Performing authorization with the server
        IXP_AUTHRETRY,      // Retrying authorization
        IXP_AUTHORIZED,     // Authorization successful (transient state, heads directly to IXP_CONNECTED after)
        IXP_DISCONNECTING,  // The connection is being closed
        IXP_DISCONNECTED,   // The transport has been disconnected from the server
        IXP_SENDING,        // (Wininet) Sending data to the server
        IXP_SENT,           // (Wininet) The data has been sent to the server
        IXP_RECEIVING,      // (Wininet) Receiving the server's response
        IXP_RECEIVED,       // (Wininet) The server's response has been received
        IXP_COMPLETE,       // (Wininet) The asynchronous operation is complete
        IXP_LAST            // Last status value (for boundschecking purposes)
    } IXPSTATUS;


    // DEPTH_INFINITY : this constant can be passed to any member of IHTTPMailTransport
    // that takes a DWORD parameter to specify depth in a propfind request.

    const DWORD DEPTH_INFINITY          = 0xFFFFFFFE;

    // IHTTPMailTransport::MemberInfo Flags.

    typedef DWORD MEMBERINFOFLAGS;
    const MEMBERINFOFLAGS  HTTP_MEMBERINFO_COMMONPROPS      = 0x00000000;
    const MEMBERINFOFLAGS  HTTP_MEMBERINFO_FOLDERPROPS      = 0x00000001;   // common props and folder props
    const MEMBERINFOFLAGS  HTTP_MEMBERINFO_MESSAGEPROPS     = 0x00000002;   // common props and message props

    const MEMBERINFOFLAGS HTTP_MEMBERINFO_ALLPROPS          = (HTTP_MEMBERINFO_FOLDERPROPS | HTTP_MEMBERINFO_MESSAGEPROPS);

    // ***NB: You have to be careful when changing IMAP_MSGFLAGS.
    // The function, IMAPMsgFlagsToARF in imapfldr.cpp will have to be updated.
    typedef DWORD IMAP_MSGFLAGS;    // Message flags returned by FLAGS response,
                                    // PERMANENTFLAGS response code and FETCH
    const IMAP_MSGFLAGS IMAP_MSG_NOFLAGS         = 0x00000000;
    const IMAP_MSGFLAGS IMAP_MSG_ANSWERED        = 0x00000001;
    const IMAP_MSGFLAGS IMAP_MSG_FLAGGED         = 0x00000002;
    const IMAP_MSGFLAGS IMAP_MSG_DELETED         = 0x00000004;
    const IMAP_MSGFLAGS IMAP_MSG_SEEN            = 0x00000008;
    const IMAP_MSGFLAGS IMAP_MSG_DRAFT           = 0x00000010;
    const IMAP_MSGFLAGS IMAP_MSG_ALLFLAGS        = 0x0000001F; // Keep this updated

    // ---------------------------------------------------------------------------------------
    // IID_ITransportCallbackService
    // ---------------------------------------------------------------------------------------
    [
    uuid(CA30F3FF-C9AC-11d1-9A3A-00C04FA309D4),
    local,
    ]
    interface ITransportCallbackService : IUnknown
    {
    HRESULT GetParentWindow(
        [in]            DWORD               dwReserved,
        [out]           HWND               *phwndParent);

    HRESULT GetAccount(
        [out]           LPDWORD             pdwServerType, // SRV_xxx Bit
        [out]           IImnAccount       **ppAccount);
    }

    // ---------------------------------------------------------------------------------------
    // IID_ITransportCallback
    // ---------------------------------------------------------------------------------------
    [
    uuid(0DF2C7E1-3435-11d0-81D0-00C04FD85AB4),
    helpstring("Base Transport Callback Interface"),
    local,
    ]
    interface ITransportCallback : IUnknown
    {
    // -----------------------------------------------------------------------------------
    // IXPRESULT
    //
    // This structure holds information about a server response or a transport result /
    // error.
    // -----------------------------------------------------------------------------------
    typedef struct tagIXPRESULT {
        HRESULT         hrResult;         // Error Code
        LPSTR           pszResponse;      // Last server response
        UINT            uiServerError;    // Server generated error number
        HRESULT         hrServerError;    // Associated HRESULT of server error
        DWORD           dwSocketError;    // Socket error as defined in winsock.h
        LPSTR           pszProblem;       // Additional information
    } IXPRESULT, *LPIXPRESULT;

    // -----------------------------------------------------------------------------------
    //  OnTimeout
    //
    //  Description:
    //  This method is called by a transport when a timeout period has expired. A timeout
    //  is defined as a period of time in which no activity has occurred. A client
    //  can specify a timeout in the INETSERVER structure that is passed to the
    //  IInternetTransport::Connect method.
    //
    //  When this method is called, the client MUST return a value that indicates
    //  whether the transport should wait another dwTimeout (seconds), or should
    //  terminate the connection to the server.
    //
    //  Parameters:
    //  pdwTimeout                  Specifies the current timeout value in seconds. A
    //                              client can reset this value to a new timeout value,
    //                              and return S_OK in which case the client will
    //                              continue waiting for the new timeout period.
    //  pTransport                  The transport that generated the timeout
    //
    //  Returns:
    //  S_OK                        Tells the transport to wait another timeout period
    //                              as specified by the value of *pdwTimeout (seconds).
    //  S_FALSE                     Tells the transport to terminate it's connection and
    //                              return to the disconnected state.
    //
    // -----------------------------------------------------------------------------------
    HRESULT OnTimeout(
	[in,out]
	DWORD                  *pdwTimeout,
	[in]
	IInternetTransport     *pTransport);

    // -----------------------------------------------------------------------------------
    //  OnLogonPrompt
    //
    //  Description:
    //  This method is called when the transport requires logon information. The client
    //  is expected to prompt the user and fill the szUserName, szPassword fields of
    //  the INETSERVER structure passed in. The client should not attempt to change
    //  any other fields in this structure, they should be used only for display.
    //
    //  Parameters:
    //  pInetServer                 Information about the current internet server.
    //  pTransport                  The transport that generated the timeout
    //
    //  Returns:
    //  S_OK                        The user entered new logon information and the
    //                              transport should try to re-connect.
    //  S_FALSE                     The user wants to cancel the current logon attempt.
    //                              If this value is returned, the transport returns
    //                              to the disconnected state.
    //
    // -----------------------------------------------------------------------------------
    HRESULT OnLogonPrompt(
	    [in,out]
	    LPINETSERVER            pInetServer,
	    [in]
	    IInternetTransport     *pTransport);

    // -----------------------------------------------------------------------------------
    //  OnPrompt
    //
    //  Description:
    //  This method is called when the transport requires user input. This method is called
    //  in the following cases:
    //
    //  1) hrError == IXP_E_INVALID_CERT_CN, Invalid certificate, SSL error
    //  2) hrError == IXP_E_INVALID_CERT_DATE, Invalid certificate date, SSL error
    //
    //  Parameters:
    //  hrError                     HRESULT of reason for user prompt, usually an error
    //  pszText                     Suggested text of question to be displayed
    //  pszCaption                  Suggested caption of messagebox
    //  uType                       Same parameter as passed into MessageBox (Yes, no, etc)
    //  pTransport                  The transport object that generated the OnPrompt
    //
    //  Returns
    //  INT                         This method should return the same value as the
    //                              standard windows MessageBox API function.
    //
    // -----------------------------------------------------------------------------------
    INT     OnPrompt(
	    [in]
	    HRESULT                 hrError,
	    [in]
	    LPCTSTR                 pszText,
	    [in]
	    LPCTSTR                 pszCaption,
	    [in]
	    UINT                    uType,
	    [in]
	    IInternetTransport     *pTransport);

    // -----------------------------------------------------------------------------------
    //  OnStatus
    //
    //  Description:
    //  This method is called to allow the client to provide a user with a high level
    //  progress indicator.
    //
    //  Parameters:
    //  ixpstatus                   Current status of the transport, described above
    //  pTransport                  Transport object that generated the OnStatus call
    //
    //  Returns:
    //  HRESULT                     A client should always return S_OK
    //
    // -----------------------------------------------------------------------------------
    HRESULT OnStatus(
	    [in]
	    IXPSTATUS               ixpstatus,
	    [in]
	    IInternetTransport     *pTransport);

    // -----------------------------------------------------------------------------------
    //  OnError
    //
    //  Description:
    //  This method is called when a transport encounters a fatal error that will most
    //  likely result is a disconnection from the server. Normal protocol errors are
    //  returned through each transports OnResponse metho. This method is used to handle
    //  high-level errors such eas TCP/IP and connection failures.
    //
    //  Parameters:
    //  ixpstatus                   Current status of the transport (described above)
    //  pResult                     Error information
    //  pTransport                  Transport object that generated the OnError call
    //
    //  Return Values:
    //  HRESULT                     A client should always return S_OK
    //
    // -----------------------------------------------------------------------------------
    HRESULT OnError(
	    [in]
	    IXPSTATUS               ixpstatus,
	    [in]
	    LPIXPRESULT             pResult,
	    [in]
	    IInternetTransport     *pTransport);

    // -----------------------------------------------------------------------------------
    //  OnCommand
    //
    //  Description:
    //  This method is called for every command send to the server and for every respsonse
    //  received from the server. This method is provided ONLY for logging and debugging
    //  purposes. If you pass FALSE for fCommandLogging in the call to
    //  IInternetTransport::Connect, this method will not be called. There is a small
    //  amount of overhead when this function is called.
    //
    //  Parameters:
    //  cmdtype                     Is this a Send Line or a Response Line
    //  pszLine                     Data send to or received from the server
    //  hrResponse                  HRESULT of response code (see codes above). If this
    //                              is a failure code, then it indicates that the
    //                              transport just received an error from the server
    //                              and the current operation is going to fail, possible.
    //  pTransport                  Transport that generated the call to OnCommand
    //
    //  Returns:
    //  S_OK                        The client should always return S_OK
    //
    // -----------------------------------------------------------------------------------
    typedef enum tagCMDTYPE {
	CMD_SEND,
	CMD_RESP
    } CMDTYPE;

    HRESULT OnCommand(
	    [in]
	    CMDTYPE                 cmdtype,
	    [in]
	    LPSTR                   pszLine,
	    [in]
	    HRESULT                 hrResponse,
	    [in]
	    IInternetTransport     *pTransport);
    }

    // ---------------------------------------------------------------------------------------
    // IID_IInternetTransport
    // ---------------------------------------------------------------------------------------
    [
	uuid(1F636C01-364E-11d0-81D3-00C04FD85AB4),
	helpstring("Internet Transport Interface"),
    local,
    ]
    interface IInternetTransport : IUnknown
    {

	// Interface Constants
	const boolean iitAUTHENTICATE = TRUE;
	const boolean iitDONT_AUTHENTICATE = FALSE;
	const boolean iitENABLE_ONCOMMAND = TRUE;
	const boolean iitDISABLE_ONCOMMAND = FALSE;


	// -----------------------------------------------------------------------------------
	//  GetServerInfo
	//
	//  Description:
	//  Allows the client to retreive server information for the transport. The data in
	//  this structure is valid only after a call to IInternetTransport::Connect.
	//
	//  Parameters:
	//  pInetServer                 Current server information for the transport
	//
	//  Returns:
	//  E_INVALIDARG                pInetServer is NULL
	//
	// -----------------------------------------------------------------------------------
	HRESULT GetServerInfo(
		[in,out]
		LPINETSERVER            pInetServer);

	// -----------------------------------------------------------------------------------
	//  GetIXPType
	//
	//  Description:
	//  This method returns the IXPTYPE of the transport.
	//
	//  Parameters:
	//  None
	//
	//  Returns:
	//  IXPTYPE                     Internet Transport Type
	//
	// -----------------------------------------------------------------------------------
	IXPTYPE GetIXPType(void);

	// -----------------------------------------------------------------------------------
	//  IsState
	//
	//  Description:
	//  This method allows a client to query the transport for validity of different states.
	//
	//  Parameters:
	//  isstate                     The State in which to query
	//
	//  Returns:
	//  IXP_E_NOT_INIT              The transport has not been initialized
	//  IXP_E_NOT_CONNECTED         The transport is not connected (return if isstate != IXP_IS_CONNECTED)
	//  S_OK                        The IXP_IS_xxx state is true
	//  S_FALSE                     The IXP_IS_xxx state is false
	//
	// -----------------------------------------------------------------------------------
	typedef enum tagIXPISSTATE {
	    IXP_IS_CONNECTED,           // Is the transport currently connected
	    IXP_IS_BUSY,                // Is the transport currently processing a command
	    IXP_IS_READY,               // Is the transport ready for input
	    IXP_IS_AUTHENTICATED,       // Has the transport performed authentication
	} IXPISSTATE;

	HRESULT IsState(
	    [in]
	    IXPISSTATE              isstate);

	// -----------------------------------------------------------------------------------
	//  InetServerFromAccount
	//
	//  Description:
	//  This method takes an Internet Mail and News Account object and returns a filled
	//  INETSERVER structure.
	//
	//  Parameters:
	//  pAccount                    Internet Mail and News Account
	//  pInetServer                 Upon successful return contains server information
	//                              required to call IInternetTransport::Connect.
	//
	//  Return Values:
	//  E_INVALIDARG                pAccount is NULL or pInetServer is NULL
	//
	// -----------------------------------------------------------------------------------
	HRESULT InetServerFromAccount(
	    [in]
	    IImnAccount            *pAccount,
	    [in,out]
	    LPINETSERVER            pInetServer);

	// -----------------------------------------------------------------------------------
	//  Connect
	//
	//  Description:
	//  Connects the transport to the server specified in pInetServer struct. This call
	//  is asyncronous. Each transport defines that terminal connect state. For example,
	//  for SMTP, the connect state (::Connect is done) is defined by the SMTP_CONNECTED,
	//  state.
	//
	//  Parameters:
	//  pInetServer                 Internet Server connection information.
	//  fAuthenticate               Tells the transport whether of or not to perform
	//                              authentication with the server. If you client
	//                              passes FALSE, it is responsible for authentication.
	//  fCommandLogging             If you pass FALSE, the ITransportCallback::OnCommand
	//                              method will never be called.
	//
	//  Returns:
	//  E_INVALIDARG                pInetServer is NULL, or a member of it is invalid
	//  E_OUTOFMEMORY               An memory allocation failed
	//  E_FAIL                      Socket initialization or connection failed.
	//  IXP_E_ALREADY_CONNECTED     The transport is currently connected and busy
	//  IXP_E_NOT_INIT              The transport has not been Initialized
	//  IXP_E_SOCKET_INIT_ERROR     Unable to initilize the TCP/IP socket connection
	//  IXP_E_SOCKET_CONNECT_ERROR  Unable to connect the TCP/IP socket
	//
	//  In general this function succeeds, even if the server does not exist. If the
	//  server can not be found, the client will receive error information through
	//  ITransportCallback::OnError, and the terminal connection state can be detected
	//  when ITransportCallback::OnStatus(IXP_DISCONNECTED) is called.
	//
	// -----------------------------------------------------------------------------------
	HRESULT Connect(
	    [in]
	    LPINETSERVER            pInetServer,
	    [in]
	    boolean                 fAuthenticate,
	    [in]
	    boolean                 fCommandLogging);

	// -----------------------------------------------------------------------------------
	//  HandsOffCallback
	//
	//  Description:
	//  This method forces the Transport to release the callback interface that was
	//  passed into the InitNew method of the transport. After this method is called,
	//  no more calls will be made to the callback function. This method is provided
	//  so that clients can resolve possible circurlar references.
	//
	//  Parameters:
	//  None
	//
	//  Returns:
	//  S_OK                        The callback was release
	//  S_FALSE                     There is currently no callback registered
	//
	// -----------------------------------------------------------------------------------
	HRESULT HandsOffCallback(void);

	// -----------------------------------------------------------------------------------
	//  Disconnect
	//
	//  Description:
	//  This method disconnects the transport. This method may cause the transport to
	//  send a command, such as the QUIT command, to the server. This is the clean
	//  method of terminating the connection to the server, as opposed to DropConnection.
	//
	//  Parameters:
	//  None
	//
	//  Returns:
	//  S_OK                        The connection has been dropped.
	//  IXP_E_NOT_INIT              The transport has not been Initialized
	//  IXP_E_NOT_CONNECTED         The transport is not connected.
	//
	// -----------------------------------------------------------------------------------
	HRESULT Disconnect(void);

	// -----------------------------------------------------------------------------------
	//  DropConnection
	//
	//  Description:
	//  This method disconnects the transport. This is an un-clean way, but guaranteed
	//  method of dropping the connection between the client and the server. To allow
	//  the protocol to shutdown in a normal fashion, call Disconnect.
	//
	//  Parameters:
	//  None
	//
	//  Returns:
	//  S_OK                        The connection has been dropped.
	//  IXP_E_NOT_INIT              The transport has not been Initialized
	//  IXP_E_NOT_CONNECTED         The transport is not connected.
	//
	// -----------------------------------------------------------------------------------
	HRESULT DropConnection(void);


	// -----------------------------------------------------------------------------------
	//  GetStatus
	//
	//  Description:
	//  This function returns the current status of the transport.
	//
	//  Parameters:
	//  IXPSTATUS *pCurrentStatus [out] - current status of the transport is returned here.
	//
	//  Returns:
	//  HRESULT indicating success or failure.
	// -----------------------------------------------------------------------------------
	HRESULT GetStatus([out]IXPSTATUS *pCurrentStatus);
    }

    // ---------------------------------------------------------------------------------------
    // IID_ISMTPCallback
    // ---------------------------------------------------------------------------------------
    [
    uuid(1F636C02-364E-11d0-81D3-00C04FD85AB4),
    helpstring("SMTP Callback Interface"),
    local,
    ]
    interface ISMTPCallback : ITransportCallback
    {
	// -----------------------------------------------------------------------------------
	// SMTPCOMMAND
	// -----------------------------------------------------------------------------------
	typedef enum tagSMTPCOMMAND {
	    SMTP_NONE,
	    SMTP_BANNER,
	    SMTP_CONNECTED,
	    SMTP_SEND_MESSAGE,
	    SMTP_AUTH,
	    SMTP_EHLO,
	    SMTP_HELO,
	    SMTP_MAIL,
	    SMTP_RCPT,
	    SMTP_RSET,
	    SMTP_QUIT,
	    SMTP_DATA,
	    SMTP_DOT,
	    SMTP_SEND_STREAM,
	    SMTP_CUSTOM
	} SMTPCOMMAND;

	// -----------------------------------------------------------------------------------
	// SMTPSTREAM return OnResponse - command == SMTP_SEND_STREAM
	// -----------------------------------------------------------------------------------
	typedef struct tagSMTPSTREAM {
	    DWORD           cbIncrement;
	    DWORD           cbCurrent;
	    DWORD           cbTotal;
	} SMTPSTREAM, *LPSMTPSTREAM;

	// -----------------------------------------------------------------------------------
	//  SMTPRESPONSE
	//
	//  Description:
	//  command                         SMTPCOMMAND that generated the response
	//  fDone                           Is the command finished. If TRUE, the client
	//                                  can issue another command through ISMTPTransport,
	//                                  otherwise, the client should continue to pump
	//                                  messages until fDone = TRUE is received.
	//  rIxpResult                      Result Information for the response. If
	//                                  rIxpResult::hrResult specifies a FAILED result,
	//                                  the structure contains other information.
	//  pTransport                      Transport that generated the OnResponse call.
	//
	// -----------------------------------------------------------------------------------
	typedef struct tagSMTPRESPONSE {
	    SMTPCOMMAND     command;        // Command in which the response was generated for
	    BOOL            fDone;          // Is this an SMTP continuation response?
	    IXPRESULT       rIxpResult;     // Result Information
	    ISMTPTransport *pTransport;     // Pointer to the SMTP transport that generated the response

	    // This is a union of response information based on the command
	    [switch_type(SMTPCOMMAND), switch_is((SMTPCOMMAND)command)]
	    union {
	    [case(SMTP_SEND_STREAM)]  SMTPSTREAM    rStreamInfo;
	    [default];
	    };
	} SMTPRESPONSE, *LPSMTPRESPONSE;

	// -----------------------------------------------------------------------------------
	//  OnResponse
	//
	//  Description:
	//  Called by ISMTPTransport when a command response is received from the SMTP server.
	//
	//  Parameters:
	//  pResponse                       Response information
	//
	//  Return Values:
	//  S_OK                            The client should always return S_OK
	//
	// -----------------------------------------------------------------------------------
	HRESULT OnResponse(
	    [in]
	    LPSMTPRESPONSE              pResponse);
    }

    // ---------------------------------------------------------------------------------------
    // IID_ISMTPTransport
    // ---------------------------------------------------------------------------------------
    [
	uuid(0DF2C7E2-3435-11d0-81D0-00C04FD85AB4),
	helpstring("SMTP Transport Interface"),
    local,
    ]
    interface ISMTPTransport : IInternetTransport
    {
	// -----------------------------------------------------------------------------------
	// SMTPMESSAGE
	// -----------------------------------------------------------------------------------
	typedef struct tagSMTPMESSAGE {
	    ULONG           cbSize;         // Size of the message in bytes
	    LPSTREAM        pstmMsg;        // Stream containing ANSI MIME/rfc822 message stream
	    INETADDRLIST    rAddressList;   // Internet Address List containing sender and recipients
	} SMTPMESSAGE, *LPSMTPMESSAGE;

	// -----------------------------------------------------------------------------------
	//  InitNew
	//
	//  Description:
	//  This method Initializes the internet transport. This method be called before
	//  the transport can doing anything.
	//
	//  Parameters:
	//  pszLogFilePath              Full file path in which to log the protocol commands.
	//                              NULL is a valid value (no logging)
	//  pCallback(required)         Specifies the Transport callback interface.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT InitNew(
	    [in]
	    LPSTR                   pszLogFilePath,
	    [in]
	    ISMTPCallback          *pCallback);

	// -----------------------------------------------------------------------------------
	//  SendMessage
	//
	//  Description:
	//  This method initiates the sending process. IInternetTransport::Connect must have
	//  been called before this method is called (i.e. the transport must be in the
	//  ready state). This method calls OnProgress throughout the transmission of
	//  pMessage->pstmMsg so that the client can display progress. When the message is
	//  fisnished, or if an error ocurrs, ITransportCallback::OnComplete is called.
	//
	//  Parameters:
	//  pMessage(required)          Contains the information for the message to send. This
	//                              method duplicates the contents of pMessage and AddRefs,
	//                              pMessage->pstmMsg so that the client can free pMessage
	//                              immediately after calling this method.
	//
	//  Returns:
	//  E_INVALIDARG                pMessage is invalid or one of its members is invalid
	//  E_OUTOFMEMORY               A memory allocation failed
	//  IXP_E_BUSY                  The transport is busy
	//  IXP_E_INVALID_ADDRESS_LIST  SMTPMESSAGE::rInetAddrList contains invalid entries
	//  IXP_E_NOT_CONNECTED         IInternetTransport::Connect has not been called, or
	//                              the current connection has been lost. The transport
	//                              will not automatically re-connect.
	//
	// -----------------------------------------------------------------------------------
	HRESULT SendMessage(
	    [in]
	    LPSMTPMESSAGE           pMessage);

	// -----------------------------------------------------------------------------------
	// CommandMAIL
	// -----------------------------------------------------------------------------------
	HRESULT CommandMAIL(
	    [in]
	    LPSTR                   pszEmailFrom);

	// -----------------------------------------------------------------------------------
	// CommandRCPT
	// -----------------------------------------------------------------------------------
	HRESULT CommandRCPT(
	    [in]
	    LPSTR                   pszEmailTo);

	// -----------------------------------------------------------------------------------
	// CommandEHLO
	// -----------------------------------------------------------------------------------
	HRESULT CommandEHLO(void);

	// -----------------------------------------------------------------------------------
	// CommandHELO
	// -----------------------------------------------------------------------------------
	HRESULT CommandHELO(void);

	// -----------------------------------------------------------------------------------
	// CommandHELO
	// -----------------------------------------------------------------------------------
	HRESULT CommandAUTH(
	    [in]
	    LPSTR                   pszAuthType);

	// -----------------------------------------------------------------------------------
	// CommandQUIT
	// -----------------------------------------------------------------------------------
	HRESULT CommandQUIT(void);

	// -----------------------------------------------------------------------------------
	// CommandRSET
	// -----------------------------------------------------------------------------------
	HRESULT CommandRSET(void);

	// -----------------------------------------------------------------------------------
	// CommandDATA
	// -----------------------------------------------------------------------------------
	HRESULT CommandDATA(void);

	// -----------------------------------------------------------------------------------
	// CommandDOT
	// -----------------------------------------------------------------------------------
	HRESULT CommandDOT(void);

	// -----------------------------------------------------------------------------------
	// SendDataStream - This method does a CommandDOT when it is finished.
	// -----------------------------------------------------------------------------------
	HRESULT SendDataStream(
	    [in]
	    IStream                *pStream,
	    [in]
	    ULONG                   cbSize);
    }

    // ---------------------------------------------------------------------------------------
    // IID_ISMTPTransport2
    // ---------------------------------------------------------------------------------------
    [
	uuid(0DF2C7EC-3435-11d0-81D0-00C04FD85AB4),
	helpstring("SMTP Transport Interface"),
    local,
    ]
    interface ISMTPTransport2 : ISMTPTransport
    {

    // -----------------------------------------------------------------------------------
    // SMTPMESSAGE2
    //
    // Adds DSN (rfc1891) support.  To receive DSNs the SMTP server must implement rfc1891
    // and the SMTP transport must be initialized with an EHLO command
    // -----------------------------------------------------------------------------------
    typedef struct tagSMTPMESSAGE2 {
        SMTPMESSAGE     smtpMsg;        // SMTPMESSAGE structure
        LPSTR           pszDSNENVID;    // value for MAIL ENVID paramter
        DSNRET          dsnRet;         // value for MAIL RET parameter
        DWORD           dwReserved;
        DWORD           dwReserved2;
    } SMTPMESSAGE2, *LPSMTPMESSAGE2;

    //***************************************************************************
    // Function: SetWindow
    //
    // Purpose:
    //   This function creates a new window for async winsock processing
    //
    // Returns:
    //   HRESULT indicating success or failure.
    //***************************************************************************
    HRESULT SetWindow(void);

	//***************************************************************************
	// Function: ResetWindow
	//
	// Purpose:
	//   This function closes a window for async winsock processing
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT ResetWindow(void);

    // -----------------------------------------------------------------------------------
    //  SendMessage2
    //
    //  Description:
    //  This method initiates the sending process. IInternetTransport::Connect must have
    //  been called before this method is called (i.e. the transport must be in the
    //  ready state). This method calls OnProgress throughout the transmission of
    //  pMessage->pstmMsg so that the client can display progress. When the message is
    //  fisnished, or if an error ocurrs, ITransportCallback::OnComplete is called.
    //
    //  Parameters:
    //  pMessage(required)          Contains the information for the message to send. This
    //                              method duplicates the contents of pMessage and AddRefs,
    //                              pMessage->pstmMsg so that the client can free pMessage
    //                              immediately after calling this method.
    //
    //  Returns:
    //  E_INVALIDARG                pMessage is invalid or one of its members is invalid
    //  E_OUTOFMEMORY               A memory allocation failed
    //  IXP_E_BUSY                  The transport is busy
    //  IXP_E_INVALID_ADDRESS_LIST  SMTPMESSAGE::rInetAddrList contains invalid entries
    //  IXP_E_NOT_CONNECTED         IInternetTransport::Connect has not been called, or
    //                              the current connection has been lost. The transport
    //                              will not automatically re-connect.
    //
    // -----------------------------------------------------------------------------------
    HRESULT SendMessage2(
        [in]
        LPSMTPMESSAGE2          pMessage);

    // -----------------------------------------------------------------------------------
    // CommandRCPT2
    // -----------------------------------------------------------------------------------
    HRESULT CommandRCPT2(
        [in]
        LPSTR                   pszEmailTo,
        [in]
        INETADDRTYPE            atDSN);
	}

	// ---------------------------------------------------------------------------------------
    // IID_IDAVNamespaceArbiter
    // ---------------------------------------------------------------------------------------
    [
	uuid(72A58FF8-227D-11d2-A8B5-0000F8084F96),
	helpstring("DAV Namespace Arbiter"),
    local,
    ]
    interface IDAVNamespaceArbiter : IUnknown
    {
	HRESULT AddNamespace(
	    [in]
	    LPCSTR                  pszNamespace,
	    [out]
	    DWORD                   *pdwNamespaceID);

	HRESULT GetNamespaceID(
	    [in]
	    LPCSTR                  pszNamespace,
	    [out]
	    DWORD                   *pdwNamespaceID);

	HRESULT GetNamespacePrefix(
	    [in]
	    DWORD                   dwNamespaceID,
	    [out]
	    LPSTR                   *ppszNamespacePrefix);
    }

	// ---------------------------------------------------------------------------------------
    // IID_IPropPatchRequest
    // ---------------------------------------------------------------------------------------
    [
	uuid(AB8B8D2A-227F-11d2-A8B5-0000F8084F96),
	helpstring("DAV PropPatch Request"),
    local,
    ]
    interface IPropPatchRequest : IDAVNamespaceArbiter
    {
	HRESULT SetProperty(
	    [in]
	    DWORD                   dwNamespaceID,
	    [in]
	    LPCSTR                  pszPropertyName,
	    [in]
	    LPCSTR                  pszNewValue);

	HRESULT RemoveProperty(
	    [in]
	    DWORD                   dwNamespaceID,
	    [in]
	    LPCSTR                  pszPropertyName);

	HRESULT GenerateXML(
	    [out]
	    LPSTR                   *pszXML);
    }

	// ---------------------------------------------------------------------------------------
    // IID_IPropFindRequest
    // ---------------------------------------------------------------------------------------
    [
	uuid(5CFC6308-0544-11d2-A894-0000F8084F96),
	helpstring("DAV PropFind Request"),
    local,
    ]
    interface IPropFindRequest : IDAVNamespaceArbiter
    {
	HRESULT AddProperty(
	    [in]
	    DWORD                   dwNamespaceID,
	    [in]
	    LPCSTR                  pszPropertyName);

	HRESULT GenerateXML(
	    [out]
	    LPSTR                   *pszXML);
    }

	// ---------------------------------------------------------------------------------------
    // IID_IPropFindMultiResponse
    // ---------------------------------------------------------------------------------------
    [
	uuid(0DEE87DE-0547-11d2-A894-0000F8084F96),
	helpstring("DAV PropFind MultiResponse"),
    local,
    ]
    interface IPropFindMultiResponse : IUnknown
    {
	BOOL IsComplete(void);

	HRESULT GetLength(
	    [out]
	    ULONG                   *pulLength);

	HRESULT GetResponse(
	    [in]
	    ULONG                   ulIndex,
	    [out]
	    IPropFindResponse       **ppResponse);
    }

    // ---------------------------------------------------------------------------------------
    // IID_IPropFindResponse
    // ---------------------------------------------------------------------------------------
	[
	uuid(8A523716-0548-11d2-A894-0000F8084F96),
	helpstring("DAV PropFind Response"),
    local,
    ]
    interface IPropFindResponse : IUnknown
    {
	BOOL IsComplete(void);

	HRESULT GetHref(
	    [out]
	    LPSTR                   *ppszHref);

	HRESULT GetProperty(
	    [in]
	    DWORD                   dwNamespaceID,
	    [in]
	    LPCSTR                  pszPropertyName,
	    [out]
	    LPSTR                   *ppszPropertyValue);
    }

    // ---------------------------------------------------------------------------------------
    // IID_IHTTPMailCallback
    // ---------------------------------------------------------------------------------------
	[
		uuid(19F6481C-E5F0-11d1-A86E-0000F8084F96),
		helpstring("HTTPMail Callback Interface"),
        local,
	]
	interface IHTTPMailCallback : ITransportCallback
	{

    // -----------------------------------------------------------------------------------
    // HTTPMAILCOMMAND
    // -----------------------------------------------------------------------------------
    typedef enum tagHTTPMAILCOMMAND
    {
        HTTPMAIL_NONE,
        HTTPMAIL_GETPROP,
        HTTPMAIL_GET,
        HTTPMAIL_PUT,
        HTTPMAIL_POST,
        HTTPMAIL_DELETE,
        HTTPMAIL_BDELETE,
        HTTPMAIL_PROPFIND,
        HTTPMAIL_PROPPATCH,
        HTTPMAIL_MKCOL,
        HTTPMAIL_COPY,
        HTTPMAIL_BCOPY,
        HTTPMAIL_MOVE,
        HTTPMAIL_BMOVE,
        HTTPMAIL_MEMBERINFO,
        HTTPMAIL_FINDFOLDERS,
        HTTPMAIL_MARKREAD,
        HTTPMAIL_SENDMESSAGE,
        HTTPMAIL_LISTCONTACTS,
        HTTPMAIL_CONTACTINFO,
        HTTPMAIL_POSTCONTACT,
        HTTPMAIL_PATCHCONTACT,
        HTTPMAIL_WAITROOTPROP
    } HTTPMAILCOMMAND;

    // -----------------------------------------------------------------------------------
	// HTTPMAILGETPROP
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPMAILGETPROP
	{
        HTTPMAILPROPTYPE    type;
        LPSTR               pszProp;
        DWORD               dwProp;
	} HTTPMAILGETPROP, *LPHTTPMAILGETPROP;

	// -----------------------------------------------------------------------------------
	// HTTPMAILGET
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPMAILGET
	{
        BOOL            fTotalKnown;            // server provided a content-length (cbTotal is valid)
        DWORD           cbIncrement;            // bytes in this response
        DWORD           cbCurrent;              // bytes downloaded so far
        DWORD           cbTotal;                // total bytes in the response (if fTotalKnown == TRUE)
        LPVOID          pvBody;                 // content bytes
        LPSTR           pszContentType;
	} HTTPMAILGET, *LPHTTPMAILGET;

	// -----------------------------------------------------------------------------------
	// HTTPMAILPOST
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPMAILPOST
	{
	    LPSTR       pszLocation;
	    BOOL        fResend;
	    DWORD       cbIncrement;
	    DWORD       cbCurrent;
	    DWORD       cbTotal;
	} HTTPMAILPOST, *LPHTTPMAILPOST;

    // -----------------------------------------------------------------------------------
	// HTTPMAILPROPFIND
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPMAILPROPFIND
	{
	    IPropFindMultiResponse *pMultiResponse;     // parsed propfind response
	} HTTPMAILPROPFIND, *LPHTTPMAILPROPFIND;

	// -----------------------------------------------------------------------------------
	// HTTPMAILLOCATION
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPMAILLOCATION
	{
	    LPSTR       pszLocation;
	} HTTPMAILLOCATION, *LPHTTPMAILLOCATION;

	// -----------------------------------------------------------------------------------
	// HTTPMAILBCOPYMOVE
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPMAILBCOPYMOVE
	{
	    LPSTR       pszHref;
	    LPSTR       pszLocation;
	    HRESULT     hrResult;
	} HTTPMAILBCOPYMOVE, *LPHTTPMAILBCOPYMOVE;

	// -----------------------------------------------------------------------------------
	// HTTPMAILBCOPYMOVELIST
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPMAILBCOPYMOVELIST
	{
	    ULONG               cBCopyMove;
	    LPHTTPMAILBCOPYMOVE prgBCopyMove;
	} HTTPMAILBCOPYMOVELIST, *LPHTTPMAILBCOPYMOVELIST;

    // -----------------------------------------------------------------------------------
    // HTTPMAILMEMBERINFO
    // -----------------------------------------------------------------------------------
    typedef struct tagHTTPMEMBERINFO
    {
        // common properties

        LPSTR                   pszHref;
        BOOL                    fIsFolder;

        // folder properties

        LPSTR                   pszDisplayName;
        BOOL                    fHasSubs;
        BOOL                    fNoSubs;
        DWORD                   dwUnreadCount;
        DWORD                   dwVisibleCount;
        HTTPMAILSPECIALFOLDER   tySpecial;

        // message properties

	    BOOL                    fRead;
        BOOL                    fHasAttachment;
	    LPSTR                   pszTo;
	    LPSTR                   pszFrom;
	    LPSTR                   pszSubject;
	    LPSTR                   pszDate;
        DWORD                   dwContentLength;
    } HTTPMEMBERINFO, *LPHTTPMEMBERINFO;

    // -----------------------------------------------------------------------------------
    // HTTPMEMBERINFOLIST
    // -----------------------------------------------------------------------------------
    typedef struct tagHTTPMEMBERINFOLIST
    {
        ULONG                   cMemberInfo;        // count of elements in prgMemberInfo
        LPHTTPMEMBERINFO        prgMemberInfo;      // array of HTTPMEMBERINFO
        LPSTR                   pszRootTimeStamp;
        LPSTR                   pszFolderTimeStamp;
    } HTTPMEMBERINFOLIST, *LPHTTPMEMBERINFOLIST;

    // -----------------------------------------------------------------------------------
    // HTTPMEMBERERROR
    // -----------------------------------------------------------------------------------
    typedef struct tagHTTPMEMBERERROR
    {
        LPSTR                   pszHref;
        HRESULT                 hrResult;
    } HTTPMEMBERERROR, *LPHTTPMEMBERERROR;

	// -----------------------------------------------------------------------------------
    // HTTPMEMBERERRORLIST
    // -----------------------------------------------------------------------------------
    typedef struct tagHTTPMEMBERERRORLIST
    {
        ULONG                   cMemberError;
        LPHTTPMEMBERERROR       prgMemberError;
    } HTTPMEMBERERRORLIST, *LPHTTPMEMBERERRORLIST;

	// -----------------------------------------------------------------------------------
	// HTTPCONTACTID
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPCONTACTID
	{
	    LPSTR                   pszHref;
	    LPSTR                   pszId;
	    HTTPMAILCONTACTTYPE     tyContact;
	    LPSTR                   pszModified;
	} HTTPCONTACTID, *LPHTTPCONTACTID;

	// -----------------------------------------------------------------------------------
	// HTTPCONTACTIDLIST
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPCONTACTIDLIST
	{
	    ULONG           cContactId;         // number of elements in prgContactId
	    LPHTTPCONTACTID prgContactId;       // array cf contact ids
	} HTTPCONTACTIDLIST, *LPHTTPCONTACTIDLIST;

	// -----------------------------------------------------------------------------------
	// HTTPCONTACTINFO
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPCONTACTINFO
	{
	    LPSTR                   pszHref;
	    LPSTR                   pszId;
	    HTTPMAILCONTACTTYPE     tyContact;
	    LPSTR                   pszModified;
	    LPSTR                   pszDisplayName;
	    LPSTR                   pszGivenName;
	    LPSTR                   pszSurname;
	    LPSTR                   pszNickname;
	    LPSTR                   pszEmail;
	    LPSTR                   pszHomeStreet;
	    LPSTR                   pszHomeCity;
	    LPSTR                   pszHomeState;
	    LPSTR                   pszHomePostalCode;
	    LPSTR                   pszHomeCountry;
	    LPSTR                   pszCompany;
	    LPSTR                   pszWorkStreet;
	    LPSTR                   pszWorkCity;
	    LPSTR                   pszWorkState;
	    LPSTR                   pszWorkPostalCode;
	    LPSTR                   pszWorkCountry;
	    LPSTR                   pszHomePhone;
	    LPSTR                   pszHomeFax;
	    LPSTR                   pszWorkPhone;
	    LPSTR                   pszWorkFax;
	    LPSTR                   pszMobilePhone;
	    LPSTR                   pszOtherPhone;
	    LPSTR                   pszBday;
        LPSTR                   pszPager;
	} HTTPCONTACTINFO, *LPHTTPCONTACTINFO;

	// -----------------------------------------------------------------------------------
	// HTTPCONTACTINFOLIST
	// -----------------------------------------------------------------------------------
	typedef struct tagHTTPCONTACTINFOLIST
	{
	    ULONG               cContactInfo;
	    LPHTTPCONTACTINFO   prgContactInfo;
	} HTTPCONTACTINFOLIST, *LPHTTPCONTACTINFOLIST;

	// -----------------------------------------------------------------------------------
	// HTTPMAILRESPONSE
	// -----------------------------------------------------------------------------------
    typedef struct tagHTTPMAILRESPONSE
	{
	    HTTPMAILCOMMAND         command;        // Command for which the response was generated
	    DWORD                   dwContext;      // Client context
	    BOOL                    fDone;          // Is this the last response for the command
	    IXPRESULT               rIxpResult;     // Result information
	    IHTTPMailTransport      *pTransport;    // Pointer to the HTTPMail transport that generated the response

	    // This is a union of response information based on the command
	    [switch_type(HTTPMAILCOMMAND), switch_is((HTTPMAILCOMMAND)command)]
	    union
	    {
	        [case(HTTPMAIL_GETPROP)] HTTPMAILGETPROP            rGetPropInfo;
	        [case(HTTPMAIL_GET)] HTTPMAILGET                    rGetInfo;
	        [case(HTTPMAIL_PUT)] HTTPMAILPOST                   rPutInfo;
	        [case(HTTPMAIL_POST)] HTTPMAILPOST                  rPostInfo;
	        [case(HTTPMAIL_PROPFIND)] HTTPMAILPROPFIND          rPropFindInfo;
            [case(HTTPMAIL_MKCOL)]HTTPMAILLOCATION              rMkColInfo;
	        [case(HTTPMAIL_COPY)]HTTPMAILLOCATION               rCopyMoveInfo;
	        [case(HTTPMAIL_BCOPY)]HTTPMAILBCOPYMOVELIST         rBCopyMoveList;
            [case(HTTPMAIL_MEMBERINFO)] HTTPMEMBERINFOLIST      rMemberInfoList;    // response for MemberInfo, FindFolders
            [case(HTTPMAIL_MARKREAD)] HTTPMEMBERERRORLIST       rMemberErrorList;   // response for MarkRead, BDELETE
	        [case(HTTPMAIL_SENDMESSAGE)] HTTPMAILPOST           rSendMessageInfo;
	        [case(HTTPMAIL_LISTCONTACTS)] HTTPCONTACTIDLIST     rContactIdList;
	        [case(HTTPMAIL_CONTACTINFO)] HTTPCONTACTINFOLIST    rContactInfoList;
	        [case(HTTPMAIL_POSTCONTACT)] HTTPCONTACTID          rPostContactInfo;
	        [case(HTTPMAIL_PATCHCONTACT)] HTTPCONTACTID         rPatchContactInfo;
	        [default];
	    };
	} HTTPMAILRESPONSE, *LPHTTPMAILRESPONSE;

	// -----------------------------------------------------------------------------------
	// OnResponse
	//
	// Description
	// Called by IHTTPMailTransport when a command response is received from the HTTP server
	//
	// Paramters
	// pResponse                                            Response information
	//
	// Return values:
	// S_OK                                                         The client should always return S_OK
	//
	// -----------------------------------------------------------------------------------
	HRESULT OnResponse(
	    [in]
	    LPHTTPMAILRESPONSE                      pResponse);

	HRESULT GetParentWindow(
	    [out]
	    HWND                        *phwndParent);
	}

    // ---------------------------------------------------------------------------------------
    // IID_IHTTPMailTransport
    // ---------------------------------------------------------------------------------------
    [
	uuid(B8BDE03C-E548-11d1-A86E-0000F8084F96),
	helpstring("HTTPMail Internet Transport Interface"),
    local,
    ]
    interface IHTTPMailTransport : IInternetTransport
    {
	typedef struct tagHTTPTARGETLIST
	{
	    ULONG       cTarget;
	    LPCSTR      *prgTarget;
	} HTTPTARGETLIST, *LPHTTPTARGETLIST;


	// -----------------------------------------------------------------------------------
	//  InitNew
	//
	//  Description:
	//  This method Initializes the internet transport. This method be called before
	//  the transport can doing anything.
	//
	//  Parameters:
	//  pszUserAgent                User agent string sent in http queries
	//
	//  pszLogFilePath              Full file path in which to log the protocol commands.
	//                              NULL is a valid value (no logging)
	//  pCallback(required)         Specifies the Transport callback interface.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT InitNew(
	    [in]
	    LPCSTR                  pszUserAgent,
	    [in]
	    LPCSTR                  pszLogFilePath,
	    [in]
	    IHTTPMailCallback       *pCallback);

	// -----------------------------------------------------------------------------------
	//  CommandGET
	//  rgszAcceptTypes is a null terminated list of accept types.
	// -----------------------------------------------------------------------------------
    HRESULT CommandGET(
        [in]
        LPCSTR          pszPath,
        [in]
        LPCSTR          *rgszAcceptTypes,
        [in]
	    BOOL            fTranslate,
	    [in]
        DWORD           dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandPUT
	// -----------------------------------------------------------------------------------
    HRESULT CommandPUT(
	    [in]
        LPCSTR          pszPath,
	    [in]
	    LPVOID          lpvData,
	    [in]
	    ULONG           cbSize,
		[in]
		DWORD           dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandPOST
	// -----------------------------------------------------------------------------------
	HRESULT CommandPOST(
	    [in]
        LPCSTR          pszPath,
        [in]
        IStream         *pStream,
        [in]
        LPCSTR          pszContentType,
        [in]
        DWORD           dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandDELETE
	// -----------------------------------------------------------------------------------
	HRESULT CommandDELETE(
	    [in]
	    LPCSTR          pszPath,
	    [in]
	    DWORD           dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandBDELETE
	// -----------------------------------------------------------------------------------
	HRESULT CommandBDELETE(
	    [in]
	    LPCSTR                  pszSourceCollection,
	    [in]
	    LPHTTPTARGETLIST        pTargets,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandPROPFIND
	// -----------------------------------------------------------------------------------
    HRESULT CommandPROPFIND(
        [in]
        LPCSTR                  pszPath,
        [in]
        IPropFindRequest        *pRequest,
        [in]
        DWORD                   dwDepth,
        [in]
        DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandPROPPATCH
	// -----------------------------------------------------------------------------------
	HRESULT CommandPROPPATCH(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
	    IPropPatchRequest       *pRequest,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandMKCOL
	// -----------------------------------------------------------------------------------
	HRESULT CommandMKCOL(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandCOPY
	// -----------------------------------------------------------------------------------
	HRESULT CommandCOPY(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
	    LPCSTR                  pszDestination,
	    [in]
	    BOOL                    fAllowRename,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandBCOPY
	// -----------------------------------------------------------------------------------
	HRESULT CommandBCOPY(
	    [in]
	    LPCSTR                  pszSourceCollection,
	    [in]
	    LPHTTPTARGETLIST        pTargets,
	    [in]
	    LPCSTR                  pszDestCollection,
	    [in]
	    LPHTTPTARGETLIST        pDestinations,
	    [in]
	    BOOL                    fAllowRename,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  CommandMOVE
	// -----------------------------------------------------------------------------------
	HRESULT CommandMOVE(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
	    LPCSTR                  pszDestination,
	    [in]
	    BOOL                    fAllowRename,
	    [in]
	    DWORD                   dwContext);


	// -----------------------------------------------------------------------------------
	//  CommandBMOVE
	// -----------------------------------------------------------------------------------
	HRESULT CommandBMOVE(
	    [in]
	    LPCSTR                  pszSourceCollection,
	    [in]
	    LPHTTPTARGETLIST        pTargets,
	    [in]
	    LPCSTR                  pszDestCollection,
	    [in]
	    LPHTTPTARGETLIST        pDestinations,
	    [in]
	    BOOL                    fAllowRename,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  GetProperty
	//  Retrieves the requested account property synchronously or asynchronously.
	//  If the property is immediately available, it is returned synchronously,
	//  and the result of the function is S_OK. In the sync case, it is the caller's
	//  responsibility to free the property string by calling CoTaskMemFree.
	//  If the property is not available immediately, the function result is
	//  E_PENDING, and the result is returned via a call to the callback's
	//  OnResponse method.
	//
	//  The caller can force the call to return async by passing a null ppszProp.
	//  The call CANNOT force the call to return sync.
    //
    //  Returns: if requesting the root props succeeded, and the server returned
    //  xml that did not contain the specific root property requested by the client,
    //  the return value will be IXP_E_HTTP_ROOT_PROP_NOT_FOUND.
	// -----------------------------------------------------------------------------------
	HRESULT GetProperty(
			[in]
			HTTPMAILPROPTYPE            proptype,
			[out]
			LPSTR                       *ppszProp);

	// -----------------------------------------------------------------------------------
	//  MemberInfo
    //
    //  Description:
    //  This method is called to discover folders, messages, and specific properties
    //  of folders and messages.
    //
    //  Parameters:
    //
    //  pszPath                     null terminated string that is the complete path
    //                              to the resource (or collection)
    //                              examples:
    //                                  a message: "http://www.hotmail.com/inbox/msg12345
    //                                  a folder:  "http://www.hotmail.com/inbox/"
    //  MEMBERINFOFLAGS             flags that define which properties should be requested
    //  dwDepth                     maps to the DAV depth header. Can be an integer or the
    //                              constant DEPTH_INFINITY. A depth of 0 means request
    //                              properties on the resource at pszPath. A depth of
    //                              1 means request properties on the resource at pszPath
    //                              and at all of its first-level children, etc.
    //  fIncludeRoot                boolean indicating whether or not to include the item
    //                              at pszPath in the response. Maps to the "noroot" token
    //                              optionally included in the DAV depth header. To request
    //                              properties on all of the first-level members of a
    //                              resource, and omit the resource itself from the response,
    //                              set dwDepth = 1 and fIncludeRoot = FALSE.
	// -----------------------------------------------------------------------------------
    HRESULT MemberInfo(
        [in]
        LPCSTR                  pszPath,
        [in]
        MEMBERINFOFLAGS         flags,
        [in]
        DWORD                   dwDepth,
        [in]
        BOOL                    fIncludeRoot,
        [in]
        DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  FindFolders
    //
    //  Description:
    //  This method is called to discover the collection hierarchy that exists underneath
    //  the pszPath URL. The response is identical to the MemberInfo response. This method
    //  causes a non-DAV 1.0 verb (SEARCH) to be sent to the server. Callers should be
    //  prepared to fallback to other forms of folder discovery if this method fails.
    //
    //  Parameters:
    //
    //  pszPath                     null terminated string that is the complete path
    //                              to the root of the folder hiearchy. The collection at
    //                              pszPath will not be included in the response.
    //
    //  dwContext                   context provided by caller.
	// -----------------------------------------------------------------------------------
    HRESULT FindFolders(
        [in]
        LPCSTR                  pszPath,
        [in]
        DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  MarkRead
	// -----------------------------------------------------------------------------------
    HRESULT MarkRead(
        [in]
        LPCSTR                  pszPath,
	    [in]
	    LPHTTPTARGETLIST        pTargets,
        [in]
        BOOL                    fMarkRead,
        [in]
        DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  SendMessage:
    //  Send a message using an http server that supports the http-based RFC821
    //  send protocol.
    //
    //  Parameters:
    //
    //  pszPath                     "sendmsg" url. server url that can receive
    //                              "POST" commands with request bodies that
    //                              conform to the http mail spec.
    //  pszFrom                     The "from" address associated with the outbound
    //                              mail. This address must be of the form:
    //                                  foo@bar.com
    //  pTargets                    List of e-mail address that will receive
    //                              copies of the message. This list should include
    //                              all direct recipients as well as "cc" and "bcc"
    //                              recipients. Addresses must be of the form:
    //                                  foo@bar.com
    //  fSaveInSent                 Indicates whether or not the server should save
    //                              a copy of the outbound message in the users
    //                              "Sent Items" folder. It is up to the server
    //                              to determine the specific behavior associated
    //                              with saving an outboundmessage.
    //  pMessageStream              A stream that contains an rfc822 compliant
    //                              message. The contents of this stream are not
    //                              validated by this API. It is the responsibility
    //                              of the caller to insure that the message is
    //                              rfc822 compliant.
    //  dwContext                   A dword which indentifies the specific request.
    //                              This dword will be included in all async responses,
    //                              and enables the caller to uniquely identify the request.
	// -----------------------------------------------------------------------------------
    HRESULT SendMessage(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
        LPCSTR                  pszFrom,
        [in]
        LPHTTPTARGETLIST        pTargets,
        [in]
        BOOL                    fSaveInSent,
        [in]
        IStream                 *pMessageStream,
        [in]
        DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  ListContacts
	// -----------------------------------------------------------------------------------
	HRESULT ListContacts(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  ListContactInfos : temporary method. pszPath is assumed to be a collection.
	//  returns all contacts in the specified collection. this method will go away
	//  when the hotmail server supports bpropfind. response is contained in the
	//  rContactInfoList and the command is the same as ContactInfo.
	// -----------------------------------------------------------------------------------
	HRESULT ListContactInfos(
	    [in]
	    LPCSTR                  pszCollectionPath,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  ContactInfo
	// -----------------------------------------------------------------------------------
	HRESULT ContactInfo(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  PostContact
	// -----------------------------------------------------------------------------------
	    HRESULT PostContact(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
	    LPHTTPCONTACTINFO       pciInfo,
	    [in]
	    DWORD                   dwContext);

	// -----------------------------------------------------------------------------------
	//  PatchContact
	// -----------------------------------------------------------------------------------
	HRESULT PatchContact(
	    [in]
	    LPCSTR                  pszPath,
	    [in]
	    LPHTTPCONTACTINFO       pciInfo,
	    [in]
	    DWORD                   dwContext);
    }

    //------------------------------------------------------------------------------------
    // IID_IHTTPMailTransport2
    //------------------------------------------------------------------------------------
    [
    uuid(82758005-D38A-11d3-8E81-00C04F79E13B),
    helpstring("HTTPMail Internet Transport Interface2"),
    ]
    interface IHTTPMailTransport2 : IUnknown
    {
        HRESULT RootMemberInfo(
            [in]
            LPCSTR                  pszPath,
            [in]
            MEMBERINFOFLAGS         flags,
            [in]
            DWORD                   dwDepth,
            [in]
            BOOL                    fIncludeRoot,
            [in]
            DWORD                   dwContext,
            [in]
            LPSTR                   pszRootTimeStamp,
            [in]
            LPSTR                   pszInboxTimeStamp);

        HRESULT FolderMemberInfo(
            [in]
            LPCSTR                  pszPath,
            [in]
            MEMBERINFOFLAGS         flags,
            [in]
            DWORD                   dwDepth,
            [in]
            BOOL                    fIncludeRoot,
            [in]
            DWORD                   dwContext,
            [in]
            LPSTR                   pszFolderTimeStamp,
            [in]
            LPSTR                   pszFolderName);

        //------------------------------------------------------------------------------------
        // GetPropertyDw
        // This behaves similar to GetProperty but retrieves a dword property
        //------------------------------------------------------------------------------------
        HRESULT GetPropertyDw(
            [in]
            HTTPMAILPROPTYPE        proptype,
            [out]
            LPDWORD                 lpdwProp);
    }

    // ---------------------------------------------------------------------------------------
    // IID_IPOP3Callback
    // ---------------------------------------------------------------------------------------
    [
	uuid(0DF2C7E3-3435-11d0-81D0-00C04FD85AB4),
	helpstring("POP3 Callback Interface"),
    local,
    ]
    interface IPOP3Callback : ITransportCallback
    {
	// -----------------------------------------------------------------------------------
	// POP3COMMAND
	// -----------------------------------------------------------------------------------
	typedef enum tagPOP3COMMAND {
	    POP3_NONE,
	    POP3_BANNER,
	    POP3_CONNECTED,
	    POP3_USER,
	    POP3_PASS,
	    POP3_AUTH,
	    POP3_UIDL,
	    POP3_STAT,
	    POP3_LIST,
	    POP3_DELE,
	    POP3_RETR,
	    POP3_TOP,
	    POP3_NOOP,
	    POP3_QUIT,
	    POP3_RSET,
	    POP3_CUSTOM
	} POP3COMMAND;

	// -----------------------------------------------------------------------------------
	// POP3RETR
	// -----------------------------------------------------------------------------------
	typedef struct tagPOP3RETR {
	    BOOL            fHeader;        // The full rfc/mime header has been downloaded.
	    BOOL            fBody;          // The body has been downloaded.
	    DWORD           dwPopId;        // POP session message id
	    DWORD           cbSoFar;        // Number of bytes downloaded since start of download
	    LPSTR           pszLines;       // Lines of the message (do not free this).
	    ULONG           cbLines;        // Number of bytes in pszLines
	} POP3RETR, *LPPOP3RETR;

	// -----------------------------------------------------------------------------------
	// POP3TOP
	// -----------------------------------------------------------------------------------
	typedef struct tagPOP3TOP {
	    BOOL            fHeader;        // The header has been downloaded.
	    BOOL            fBody;          // The body has been downloaded.
	    DWORD           dwPopId;        // POP session message id
	    DWORD           cPreviewLines;  // Number of lines being previewed
	    DWORD           cbSoFar;        // Number of bytes downloaded since start of download
	    LPSTR           pszLines;       // Header lines
	    ULONG           cbLines;        // Number of bytes in pszLines
	} POP3TOP, *LPPOP3TOP;

	// -----------------------------------------------------------------------------------
	// POP3LIST
	// -----------------------------------------------------------------------------------
	typedef struct tagPOP3LIST {
	    DWORD           dwPopId;        // POP session message id
	    DWORD           cbSize;         // Message Size
	} POP3LIST, *LPPOP3LIST;

	// -----------------------------------------------------------------------------------
	// POP3UIDL
	// -----------------------------------------------------------------------------------
	typedef struct tagPOP3UIDL {
	    DWORD           dwPopId;        // POP session message id
	    LPSTR           pszUidl;        // POP UIDL
	} POP3UIDL, *LPPOP3UIDL;

	// -----------------------------------------------------------------------------------
	// POP3STAT
	// -----------------------------------------------------------------------------------
	typedef struct tagPOP3STAT {
	    DWORD           cMessages;      // Number of messages on the server
	    DWORD           cbMessages;     // Number of bytes of messages on the server
	} POP3STAT, *LPPOP3STAT;

	// -----------------------------------------------------------------------------------
	// POP3RESPONSE
	// -----------------------------------------------------------------------------------
	typedef struct tagPOP3RESPONSE {
	    POP3COMMAND     command;        // Command in which the response was generated for
	    BOOL            fDone;          // Was this the last response for this command
	    IXPRESULT       rIxpResult;     // Result Information
	    IPOP3Transport *pTransport;     // Pointer to the POP3 transport that generated the response
	    BOOL            fValidInfo;     // The data in the union below is valid. This can be FALSE due to the
			    // fact that the fDone == TRUE response can be received with
			    // no data.

	    // This is a union of response information based on the command
	    [switch_type(POP3COMMAND), switch_is((POP3COMMAND)command)]
	    union {
	    [case(POP3_UIDL)] POP3UIDL rUidlInfo;
	    [case(POP3_STAT)] POP3STAT rStatInfo;
	    [case(POP3_LIST)] POP3LIST rListInfo;
	    [case(POP3_DELE)] DWORD    dwPopId;
	    [case(POP3_RETR)] POP3RETR rRetrInfo;
	    [case(POP3_TOP)]  POP3TOP  rTopInfo;
	    [default];
	    };
	} POP3RESPONSE, *LPPOP3RESPONSE;

	// -----------------------------------------------------------------------------------
	//  OnResponse
	// -----------------------------------------------------------------------------------
	HRESULT OnResponse(
	    [in]
	    LPPOP3RESPONSE              pResponse);
    }

    // ---------------------------------------------------------------------------------------
    // IID_IPOP3Transport
    // ---------------------------------------------------------------------------------------
    [
	uuid(0DF2C7E4-3435-11d0-81D0-00C04FD85AB4),
	helpstring("POP3 Internet Transport Interface"),
    local,
    ]
    interface IPOP3Transport : IInternetTransport
    {
	// -----------------------------------------------------------------------------------
	//  POP3 Group/List/Single Item commands
	// -----------------------------------------------------------------------------------
	typedef enum tagPOP3CMDTYPE {
	    POP3CMD_GET_POPID,
	    POP3CMD_GET_MARKED,
	    POP3CMD_GET_ALL
	} POP3CMDTYPE;

	// -----------------------------------------------------------------------------------
	//  InitNew
	//
	//  Description:
	//  This method Initializes the internet transport. This method be called before
	//  the transport can doing anything.
	//
	//  Parameters:
	//  pszLogFilePath              Full file path in which to log the protocol commands.
	//                              NULL is a valid value (no logging)
	//  pCallback(required)         Specifies the Transport callback interface.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT InitNew(
	    [in]
	    LPSTR                   pszLogFilePath,
	    [in]
	    IPOP3Callback          *pCallback);

	// -----------------------------------------------------------------------------------
	//  MarkItem
	// -----------------------------------------------------------------------------------
	typedef enum tagPOP3MARKTYPE {
	    POP3_MARK_FOR_TOP   = 0x00000001,
	    POP3_MARK_FOR_RETR  = 0x00000002,
	    POP3_MARK_FOR_DELE  = 0x00000004,
	    POP3_MARK_FOR_UIDL  = 0x00000008,
	    POP3_MARK_FOR_LIST  = 0x00000010
	} POP3MARKTYPE;

	HRESULT MarkItem(
	    [in]
	    POP3MARKTYPE            marktype,
	    [in]
	    DWORD                   dwPopId,
	    [in]
	    boolean                 fMarked);

	// -----------------------------------------------------------------------------------
	//  CommandAUTH
	// -----------------------------------------------------------------------------------
	HRESULT CommandAUTH(
	    [in]
	    LPSTR                   pszAuthType);

	// -----------------------------------------------------------------------------------
	//  CommandUSER
	// -----------------------------------------------------------------------------------
	HRESULT CommandUSER(
	    [in]
	    LPSTR                   pszUserName);

	// -----------------------------------------------------------------------------------
	//  CommandPass
	// -----------------------------------------------------------------------------------
	HRESULT CommandPASS(
	    [in]
	    LPSTR                   pszPassword);

	// -----------------------------------------------------------------------------------
	//  CommandLIST
	// -----------------------------------------------------------------------------------
	HRESULT CommandLIST(
	    [in]
	    POP3CMDTYPE             cmdtype,
	    [in]
	    DWORD                   dwPopId);

	// -----------------------------------------------------------------------------------
	//  CommandTOP
	// -----------------------------------------------------------------------------------
	HRESULT CommandTOP(
	    [in]
	    POP3CMDTYPE             cmdtype,
	    [in]
	    DWORD                   dwPopId,
	    [in]
	    DWORD                   cPreviewLines);

	// -----------------------------------------------------------------------------------
	//  CommandQUIT
	// -----------------------------------------------------------------------------------
	HRESULT CommandQUIT(void);

	// -----------------------------------------------------------------------------------
	//  CommandSTAT
	// -----------------------------------------------------------------------------------
	HRESULT CommandSTAT(void);

	// -----------------------------------------------------------------------------------
	//  CommandNOOP
	// -----------------------------------------------------------------------------------
	HRESULT CommandNOOP(void);

	// -----------------------------------------------------------------------------------
	//  CommandRSET
	// -----------------------------------------------------------------------------------
	HRESULT CommandRSET(void);

	// -----------------------------------------------------------------------------------
	//  CommandUIDL
	// -----------------------------------------------------------------------------------
	HRESULT CommandUIDL(
	    [in]
	    POP3CMDTYPE             cmdtype,
	    [in]
	    DWORD                   dwPopId);

	// -----------------------------------------------------------------------------------
	//  CommandDELE
	// -----------------------------------------------------------------------------------
	HRESULT CommandDELE(
	    [in]
	    POP3CMDTYPE             cmdtype,
	    [in]
	    DWORD                   dwPopId);

	// -----------------------------------------------------------------------------------
	//  CommandRETR
	// -----------------------------------------------------------------------------------
	HRESULT CommandRETR(
	    [in]
	    POP3CMDTYPE             cmdtype,
	    [in]
	    DWORD                   dwPopId);
    }


    // ---------------------------------------------------------------------------------------
    // IID_INNTPCallback
    // ---------------------------------------------------------------------------------------
    [
	uuid(0DF2C7E6-3435-11d0-81D0-00C04FD85AB4),
	helpstring("NNTP Callback Interface"),
    local,
    ]
    interface INNTPCallback : ITransportCallback
    {
	// -----------------------------------------------------------------------------------
	// NNTPSTATE - These are the various states the NNTP Transport can be in.  These
	//             states are also used to determine which type of data is being returned
	//             in the client's OnResponse() callback.
	// -----------------------------------------------------------------------------------
	typedef enum tagNNTPSTATE {
	    NS_DISCONNECTED,        // not connected
	    NS_CONNECT,             // awaiting connect response
	    NS_AUTHINFO,            // awaiting authorization
	    NS_POST,                // awaiting CommandPOST() to complete
	    NS_IDLE,                // connected (& authorized if necessary)
	    NS_LIST,                // awaiting LIST data
	    NS_LISTGROUP,           // awaiting LISTGROUP data
	    NS_NEWGROUPS,           // awaiting NEWGROUPS data
	    NS_GROUP,               // awaiting GROUP response
	    NS_LAST,                // awaiting LAST response
	    NS_NEXT,                // awaiting NEXT response
	    NS_STAT,                // awaiting STAT response
	    NS_ARTICLE,             // awaiting ARTICLE data
	    NS_HEAD,                // awaiting HEAD data
	    NS_BODY,                // awaiting BODY data
	    NS_DATE,                // awaiting DATE response
	    NS_MODE,                // awaiting MODE response
	    NS_QUIT,                // awaiting QUIT response
	    NS_HEADERS,             // awaiting XOVER or XHDR data from GetHeaders()
	    NS_XHDR,                // awaiting XHDR data
	} NNTPSTATE;


	// -----------------------------------------------------------------------------------
	// NNTPGROUP - This is the response from the CommandGROUP() function.  The data is
	//             the current status of the group that was switched to.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPGROUP {
	    DWORD           dwCount;        // Estimated number of articles in the group
	    DWORD           dwFirst;        // First article number in the group
	    DWORD           dwLast;         // Last article number in the group
	    LPSTR           pszGroup;       // Name of the group
	} NNTPGROUP, *LPNNTPGROUP;


	// -----------------------------------------------------------------------------------
	// NNTPNEXT - This structure will be used for the response from CommandNEXT(),
	//            CommandLAST(), and CommandSTAT().  The data returned is the article
	//            number and message id for the article that is selected by the command
	//            that was issued.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPNEXT {
	    DWORD           dwArticleNum;   // Article number
	    LPSTR           pszMessageId;   // Message ID
	} NNTPNEXT, *LPNNTPNEXT;


	// -----------------------------------------------------------------------------------
	// NNTPARTICLE - This structure returns the data from a CommandARTICLE() function.
	//               Depending on the size of the article being retrieved, the callback
	//               may recieve multiple calls for a single article.  When fDone is TRUE
	//               then all of the article data has been retrieved.  pszLines is not
	//               accumulated over all of the callbacks, it is the client's
	//               responsibility to assemble all of the pszLines that are returned to
	//               build the message.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPARTICLE {
	    DWORD           dwArticleNum;   // Article number
	    LPSTR           pszMessageId;   // Message ID
	    LPSTR           pszLines;       // Lines of the message
	    ULONG           cbLines;        // Number of bytes in pszLines
	    ULONG           cLines;         // Number of lines in pszLines
	    DWORD           dwReserved;     // Reserved for system use
	} NNTPARTICLE, *LPNNTPARTICLE;


	// -----------------------------------------------------------------------------------
	// NNTPLIST - This structure is the data returned from the CommandLIST() function.
	//            Since the NNTP LIST command can have multiple extensions, the data
	//            returned is relatively unparsed to provide greater flexibility to the
	//            client.  The data is returned in array of NULL terminated strings that
	//            contain the lines returned from the server.  When fDone is TRUE, then
	//            all of the data has been retrieved.  rgszLines is not accumulated by
	//            the transport between calls to OnResponse().  It is the client's
	//            responsibility to store this information as it comes in.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPLIST {
	    DWORD           cLines;         // Number of lines returned
	    LPSTR          *rgszLines;      // Array of lines returned by the LIST command.  The
					    // number of lines in rgszLines is cLines.  The recipient
					    // must call INNTPCallback::FreeListResponse() to free
					    // this structure.
	} NNTPLIST, *LPNNTPLIST;

	// -----------------------------------------------------------------------------------
	// NNTPLISTGROUP - This structure is sent in response to a CommandLISTGROUP() call.
	//                 rgArticles is an array of article numbers that are contained in
	//                 the newsgroup.  Since there can be quite a few articles,
	//                 OnResponse() may be called multiple times with the data as it
	//                 arrives.  rgArticles is not accumulated between calls to
	//                 OnResponse() so it is up to the client to store this information
	//                 as it arrives.  fDone will be TRUE when all the information has
	//                 been returned.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPLISTGROUP {
	    DWORD           cArticles;      // Number of article numbers in rgArticles
	    DWORD          *rgArticles;     // Array of article numbers available in the group
	} NNTPLISTGROUP, *LPNNTPLISTGROUP;

	// -----------------------------------------------------------------------------------
	// NNTPHEADER - This structure contains the parsed information for a single header
	//              returned from the GetHeaders() command.  An array of these headers
	//              is contained in the NNTPHEADERRESP struct.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPHEADER {
	    DWORD           dwArticleNum;   // Article number
	    LPSTR           pszSubject;     // Article subject
	    LPSTR           pszFrom;        // Who the article is from
	    LPSTR           pszDate;        // Date the article was posted
	    LPSTR           pszMessageId;   // Message id
	    LPSTR           pszReferences;  // References
	    DWORD           dwBytes;        // Size of the message in bytes (might not be filled in)
	    DWORD           dwLines;        // Size of the message in lines
	    LPSTR           pszXref;        // XREF: header for cross post managment
	} NNTPHEADER, *LPNNTPHEADER;


	// -----------------------------------------------------------------------------------
	// NNTPHEADERRESP - This structure will be returned in response to the GetHeaders()
	//                  command.  Since the number of headers requested may be large,
	//                  OnResponse() may be called multiple times in response to this
	//                  command.  rgHeaders is not accumulated by the transport between
	//                  calls to OnResponse() therefore it is the responsibility of the
	//                  caller to store this information as it is retrieved.  When all
	//                  the data is retrieved, then fDone will be set to TRUE.  Since
	//                  not all servers provide the XREF: header in their XOVER records,
	//                  fSupportsXRef will be set to TRUE if the pszXref field in
	//                  NNTPHEADER is valid.  If this is FALSE, the client can retrieve
	//                  this header with a call to CommandXHDR().
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPHEADERRESP {
	    DWORD           cHeaders;       // Number of headers in rgHeaders
	    LPNNTPHEADER    rgHeaders;      // Array of header structures
	    BOOL            fSupportsXRef;  // TRUE if the headers have a valid pszXref value.
					    //   Otherwise, the client needs to issue an XHdr to
					    //   retrieve that value if they're interested.
	    DWORD_PTR        dwReserved;     // Reserved for system use
	} NNTPHEADERRESP, *LPNNTPHEADERRESP;


	// -----------------------------------------------------------------------------------
	// NNTPXHDR - An array of these structures will be returned in the NNTPXHDRRESP
	//            structure.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPXHDR {
	    DWORD           dwArticleNum;   // Article number this header is for
	    LPSTR           pszHeader;      // Requested article header for this article
	} NNTPXHDR, *LPNNTPXHDR;


	// -----------------------------------------------------------------------------------
	// NNTPXHDRRESP - This will be returned in response to a CommandXHDR() call.  Since
	//                the number of headers returned is potentially large, OnResponse()
	//                may be called multiple times in response to this command.  rgHeaders
	//                is not accumulated between calls to OnResponse(), therefore it is
	//                up to the client to store this data as it arrives.  fDone will be
	//                set to TRUE when all of the headers have been returned.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPXHDRRESP {
	    DWORD           cHeaders;       // Number of header values in rgHeaders
	    LPNNTPXHDR      rgHeaders;      // Array of NNTPXHDR structs containing the requested headers
	    DWORD_PTR       dwReserved;     // Reserved for system use
	} NNTPXHDRRESP, *LPNNTPXHDRRESP;

	// -----------------------------------------------------------------------------------
	// NNTPRESPONSE - This structure is the general holder for all of the data returned
	//                from the INNTPTransport commands.  The state member tells the
	//                receiver which command this data is in response to.  If fMustRelease
	//                is TRUE, then when the client is done with this data, it should
	//                call INNTPTransport::ReleaseResponse() to free that memory.  See
	//                the explanation of the various structures to see the details on
	//                each type of response.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPRESPONSE {
	    NNTPSTATE       state;          // Command in which the response was generated for
	    BOOL            fMustRelease;   // TRUE if the data contained within this struct must be
					    //   freed with a call to INNTPTransport::ReleaseResponse()
	    BOOL            fDone;          // TRUE when there is no more data that will arrive for this
					    //   command
	    IXPRESULT       rIxpResult;     // Result Information
	    INNTPTransport *pTransport;     // Pointer to the NNTP transport that generated the response

	    // This is a union of response information based on the command
	    [switch_type(NNTPSTATE), switch_is((NNTPSTATE) state)]
	    union {
            [case(NS_GROUP)]            NNTPGROUP rGroup;
            [case(NS_LAST)]             NNTPNEXT  rLast;
            [case(NS_NEXT)]             NNTPNEXT  rNext;
            [case(NS_STAT)]             NNTPNEXT  rStat;
            [case(NS_ARTICLE)]          NNTPARTICLE rArticle;
            [case(NS_HEAD)]             NNTPARTICLE rHead;
            [case(NS_BODY)]             NNTPARTICLE rBody;
            [case(NS_LIST)]             NNTPLIST  rList;
            [case(NS_LISTGROUP)]        NNTPLISTGROUP rListGroup;
            [case(NS_NEWGROUPS)]        NNTPLIST  rNewgroups;
            [case(NS_DATE)]             SYSTEMTIME rDate;
            [case(NS_HEADERS)]          NNTPHEADERRESP rHeaders;
            [case(NS_XHDR)]             NNTPXHDRRESP rXhdr;
            [default];
	    };
	} NNTPRESPONSE, *LPNNTPRESPONSE;

	// -----------------------------------------------------------------------------------
	//  OnResponse
	// -----------------------------------------------------------------------------------
	HRESULT OnResponse(
	    [in]
	    LPNNTPRESPONSE              pResponse);
    }

    // ---------------------------------------------------------------------------------------
    // IID_INNTPTransport
    // ---------------------------------------------------------------------------------------
    [
	uuid(0DF2C7E5-3435-11d0-81D0-00C04FD85AB4),
	helpstring("NNTP Internet Transport Interface"),
    local,
    ]
    interface INNTPTransport : IInternetTransport
    {
	// -----------------------------------------------------------------------------------
	// AUTHTYPE
	// -----------------------------------------------------------------------------------
	typedef enum tagAUTHTYPE {
	    AUTHTYPE_USERPASS,
	    AUTHTYPE_SIMPLE,
	    AUTHTYPE_SASL
	} AUTHTYPE;

	// -----------------------------------------------------------------------------------
	// AUTHINFO - This structure is used to specify the type of authentication to use
	//            in the CommandAUTHINFO() command.  For AUTHTYPE_USERPASS and
	//            AUTHTYPE_SIMPLE, pszUser and pszPass are the user name and password
	//            to send with the command.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPAUTHINFO {
	    AUTHTYPE    authtype;
	    LPSTR       pszUser;
	    LPSTR       pszPass;
	} NNTPAUTHINFO, *LPNNTPAUTHINFO;

	// -----------------------------------------------------------------------------------
	// ARTICLEIDTYPE
	// -----------------------------------------------------------------------------------
	typedef enum tagARTICLEIDTYPE {
	    AID_MSGID,
	    AID_ARTICLENUM
	} ARTICLEIDTYPE;

	// -----------------------------------------------------------------------------------
	// ARTICLEID
	//
	// This structure is used to specify an article id to the various NNTP commands that
	// require one (i.e. ARTICLE, BODY, STAT).  These commands accept either a message-id
	// or if the user is current in a the context of a newsgroup the article number within
	// that group.  When filling in this structure the user should set idType to either
	// AID_MSGID of pszMessageId is valid, or AID_ARTICLENUM if dwArticleNum.
	// -----------------------------------------------------------------------------------
	typedef struct ARTICLEID {
	    ARTICLEIDTYPE   idType;
	    [switch_type(ARTICLEIDTYPE), switch_is((ARTICLEIDTYPE)idType)]
	    union {
	    [case(AID_MSGID)]
		LPSTR pszMessageId;
	    [case(AID_ARTICLENUM)]
		DWORD_PTR dwArticleNum;
	    [default];
	    };
	} ARTICLEID, *LPARTICLEID;

	// -----------------------------------------------------------------------------------
	// NNTPMESSAGE
	//
	// This structure provides the information needed to post a message to the news server
	// using the POST command.
	// -----------------------------------------------------------------------------------
	typedef struct tagNNTPMESSAGE {
	    ULONG           cbSize;         // Size of the message in bytes
	    LPSTREAM        pstmMsg;        // Stream containing a ANSI MIME/rfc822/rfc1036 message stream
	} NNTPMESSAGE, *LPNNTPMESSAGE;


	// -----------------------------------------------------------------------------------
	// RANGE
	//
	// The range structure allows the caller to provide arguments for commands that allow
	// a range of headers to be retrieved.  The range structure can be used to specify a
	// single number (ie XOVER 2010), or bounded range (ie XOVER 2000-2010) to request all
	// of the headers within that range [inclusive].  Use the idType field to specify
	// which range you are requesting.
	// -----------------------------------------------------------------------------------
	typedef enum tagRANGETYPE {
	    RT_SINGLE,                      // num
	    RT_RANGE,                       // num-num
	} RANGETYPE;

	typedef struct tagRANGE {
	    RANGETYPE       idType;
	    DWORD           dwFirst;
	    DWORD           dwLast;
	} RANGE, *LPRANGE;


	// -----------------------------------------------------------------------------------
	//  InitNew
	//
	//  Description:
	//  This method Initializes the internet transport. This method be called before
	//  the transport can doing anything.
	//
	//  Parameters:
	//  pszLogFilePath              Full file path in which to log the protocol commands.
	//                              NULL is a valid value (no logging)
	//  pCallback(required)         Specifies the Transport callback interface.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT InitNew(
		[in]
		LPSTR                   pszLogFilePath,
		[in]
		INNTPCallback          *pCallback);

	// -----------------------------------------------------------------------------------
	//  CommandAUTHINFO
	//
	//  Description:
	//  The function issues an NNTPAUTHINFO command to the server along with the information
	//  provided in the pszAuth parameter.  RFC 977 provides the following formats as
	//  valid AUTHINFO commands:
	//
	//      AUTHINFO USER name|PASS password
	//      AUTHINFO SIMPLE
	//          user password
	//
	//
	//  Parameters:
	//  pAuthInfo
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandAUTHINFO(
		[in]
		LPNNTPAUTHINFO          pAuthInfo);


	// -----------------------------------------------------------------------------------
	//  CommandGROUP
	//
	//  Description:
	//  The function issues an GROUP command to the server.  The server's response string
	//  will be returned to the INNTPCallback::OnResponse().
	//
	//  Parameters:
	//  pszGroup                    Name of the newsgroup to enter.
	//
	//  Returns:
	//  E_INVALIDARG                pszGroup is not a valid string pointer
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandGROUP(
	    [in]
	    LPSTR                   pszGroup);

	// -----------------------------------------------------------------------------------
	//  CommandLAST
	//
	//  Description:
	//  This function issues the LAST command to the server.  This has the effect of
	//  moving the current article pointer to the article immediately preceeding the
	//  current article pointer in the newsgroup.  This command is only valid if a GROUP
	//  command has been issued previously.  The article number and message-id pointed to
	//  by the new current article pointer are returned in INNTPCallback::OnResponse().
	//
	//  Returns:
	//  S_OK
	//  E_OUTOFMEMORY
	//  IXP_E_NOT_INIT
	//  IXP_E_NOT_CONNECTED
	//  IXP_E_BUSY
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandLAST(void);


	// -----------------------------------------------------------------------------------
	//  CommandNEXT
	//
	//  Description:
	//  This function issues the NEXT command to the server.  This has the effect of
	//  moving the current article pointer to the article immediately after the current
	//  article pointer in the newsgroup.  This command is only valid if a GROUP command
	//  has been issued previously.  The article number and message-id pointed to by the
	//  new current article pointer are returned in INNTPCallback::OnResponse().
	//
	//  Returns:
	//  S_OK
	//  E_OUTOFMEMORY
	//  IXP_E_NOT_INIT
	//  IXP_E_NOT_CONNECTED
	//  IXP_E_BUSY
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandNEXT(void);


	// -----------------------------------------------------------------------------------
	//  CommandSTAT
	//
	//  Description:
	//  The function issues a STAT command to the server.  If an article is specified
	//  then this command has the effect of moving the current article pointer to the
	//  specified message and returns the article number and message-id of the new current
	//  article.  Otherwise, the function will return the article number and message-id
	//  of the current article.
	//
	//  Parameters:
	//  pArticleId (optional)       Article number or message-id of the article to
	//                              retrieve status for.  If a message-id is specified
	//                              the current article pointer will NOT be updated.
	//
	//  Returns:
	//  E_INVALIDARG                pArticleId is not valid
	//  E_OUTOFMEMORY               An memory allocation failed
	//  IXP_E_NOT_INIT
	//  IXP_E_NOT_CONNECTED
	//  IXP_E_BUSY
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandSTAT(
	    [in]
	    LPARTICLEID             pArticleId);


	// -----------------------------------------------------------------------------------
	//  CommandARTICLE
	//
	//  Description:
	//  This function is used to request an article from the server.  If the caller has
	//  previously issued a GROUP command then the article can be specified by either
	//  article number or message-id.  If the GROUP command has not been issued, then the
	//  article can only be requested by message-id.
	//
	//  Parameters:
	//  pArticleId                  Either the article number or message-id of the article
	//                              to retrieve.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandARTICLE(
	    [in]
	    LPARTICLEID             pArticleId);

	// -----------------------------------------------------------------------------------
	//  CommandHEAD
	//
	//  Description:
	//  This function retrieves just the header for the requested article.  If the caller
	//  has previously issued a GROUP command, then the article can be specified by either
	//  article number or message-id.  Otherwise, the article must be requested by
	//  message-id.  The provided stream will be filled and returned to the caller in
	//  INNTPCallback::OnResponse().
	//
	//  Parameters:
	//  pArticleId                  Structure specifying the article to retreive the
	//                              header for.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandHEAD(
	    [in]
	    LPARTICLEID             pArticleId);

	// -----------------------------------------------------------------------------------
	//  CommandBODY
	//
	//  Description:
	//  This function retrieves just the body for the requested article.  If the caller
	//  has previously issued a GROUP command, then the article can be specified by either
	//  article number or message-id.  Otherwise, the article must be requested by
	//  message-id.  The provided stream will be filled and returned to the caller in
	//  INNTPCallback::OnResponse().
	//
	//  Parameters:
	//  pArticleId                  Structure specifying the article to retreive the
	//                              body for.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandBODY(
	    [in]
	    LPARTICLEID             pArticleId);

	// -----------------------------------------------------------------------------------
	//  CommandPOST
	//
	//  Description:
	//  Posts the specified message to the server.
	//
	//  Parameters:
	//  pMessage                    Specifies a stream that contains a valid RFC1036
	//                              message.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandPOST(
	    [in]
	    LPNNTPMESSAGE           pMessage);

	// -----------------------------------------------------------------------------------
	//  CommandLIST
	//
	//  Description:
	//  Sends a LIST command to the news server.  If pszArgs is NULL, then the command will
	//  retrieve a list of newsgroups available on the news server.  The pszArgs parameter
	//  can be used to issue one of the various extensions to the LIST command, ie.
	//  LIST NEWSGROUPS, LIST ACTIVE, LIST OVERVIEW.FMT, or LIST SUBSCRIPTIONS.  See
	//  RFC 977 at http://ds.internic.net/rfc/rfc977.txt for a full list of extensions.
	//
	//  Parameters:
	//  pszArgs                     Any optional parameters that the user wants to
	//                              send with the LIST command.  See the "Description"
	//                              above for more details.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandLIST(
	    [in]
	    LPSTR                   pszArgs);


	// -----------------------------------------------------------------------------------
	//  CommandLISTGROUP
	//
	//  Description:
	//  Retrieves a list of all the article numbers in a particular news group.  If the
	//  caller specifies a newsgroup name, then the articles are listed for the specified
	//  newsgroup.  Otherwise, the currently selected newsgroup is listed.  NOTE - this
	//  command will reset the current article pointer is reset to the first article in
	//  the newsgroup that was specified.
	//
	//  Parameters:
	//  pszGroup                    Optional newsgroup name to list articles for.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandLISTGROUP(
	    [in]
	    LPSTR                   pszGroup);


	// -----------------------------------------------------------------------------------
	//  CommandNEWGROUPS
	//
	//  Description:
	//  Retrieves the list of newsgroups which have been added to the server since the
	//  date specified in stLast.  The caller can restrict the list by specifying a list
	//  of distributions in pszDist.  For example:
	//
	//                      CommandNEWGROUPS(&stLast, "alt.tv")
	//
	//  will return the list of newsgroups that begin with "alt.tv" that have been added
	//  to the server since the time in stLast.
	//
	//  Parameters:
	//  pstLast                     The time to specify as the last time groups were checked.
	//  pszDist                     Distributions to check.  This can be a single dist
	//                              such as "alt" or a list of dists such as "alt.tv,comp".
	//                              The list of distributions must be separated by commas.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandNEWGROUPS(
	    [in]
	    SYSTEMTIME             *pstLast,
	    [in]
	    LPSTR                   pszDist);

	// -----------------------------------------------------------------------------------
	//  CommandDATE
	//
	//  Description:
	//  Retrieves the date and time from the news server.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandDATE(void);


	// -----------------------------------------------------------------------------------
	//  CommandMODE
	//
	//  Description:
	//  Issues a MODE command to the server.  pszMode is a required argument, an example
	//  of which are "MODE READER" to tell the server that the connection is for a user
	//  instead of another server.  Refer to RFC977 for more details.
	//
	//  Parameters:
	//  pszMode                     Required argument to the MODE command.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandMODE(
	    [in]
	    LPSTR                   pszMode);


	// -----------------------------------------------------------------------------------
	//  CommandXHDR
	//
	//  Description:
	//  Issues an XHDR command to the server.  This command can specify a range of
	//  messages or a single message to retrieve the header from.  If pRange is NULL and
	//  pszMessageId is NULL the the header is retrieved from the message pointed to by
	//  the server's current message pointer (see STAT, NEXT, LAST).
	//
	//  Parameters:
	//  pszHeader                   Which header to retrieve.  IE "subject" or "xref"
	//  pRange (optional)           Range of messages to retrieve the header from
	//  pszMessageId (optional)     Message ID of the mesage to retrieve the header from
	//
	//  Returns:
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandXHDR(
	    [in]
	    LPSTR                   pszHeader,
	    [in]
	    LPRANGE                 pRange,
	    [in]
	    LPSTR                   pszMessageId);



	// -----------------------------------------------------------------------------------
	//  CommandQUIT()
	//
	//  Description:
	//  Issues a QUIT command to the server and terminates the connect.
	//
	//  Returns:
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT CommandQUIT(void);


	// -----------------------------------------------------------------------------------
	//  GetHeaders
	//
	//  Description:
	//  Retrieves an array of headers from the server.  If a GROUP command has not been
	//  previously sent this command is not valid.
	//
	//  This function will first try to retrieve the specifed range of headers using
	//  the XOVER command.  If the server doesn't support XOVER, then the function will
	//  try other methods such as a series of XHDR commands.
	//
	//  Parameters:
	//  pRange                      The range of headers to request.  See the
	//                              documentation for the RANGE structure above to see
	//                              how to specify a range.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//  E_OUTOFMEMORY               An memory allocation failed
	//
	// -----------------------------------------------------------------------------------
	HRESULT GetHeaders(
	    [in]
	    LPRANGE                 pRange);


	// -----------------------------------------------------------------------------------
	//  ReleaseResponse()
	//
	//  Description:
	//  This function is used to free data returned to the client's OnResponse() callback.
	//
	//  Parameters:
	//  pResponse                   A pointer to the NNTPRESPONSE structure passed to the
	//                              OnResponse() callback.
	//
	//  Returns:
	//  E_INVALIDARG                An invalid parameter was passed in
	//
	// -----------------------------------------------------------------------------------
	HRESULT ReleaseResponse(
	    [in]
	    LPNNTPRESPONSE          pResponse);
    }

    // ---------------------------------------------------------------------------------------
    // IID_INNTPTransport2
    // ---------------------------------------------------------------------------------------
    [
	uuid(0DF2C7ED-3435-11d0-81D0-00C04FD85AB4),
	helpstring("NNTP Transport 2 Interface"),
    local,
    ]
    interface INNTPTransport2 : INNTPTransport
    {
	//***************************************************************************
	// Function: SetWindow
	//
	// Purpose:
	//   This function creates a new window for async winsock processing
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT SetWindow(void);


	//***************************************************************************
	// Function: ResetWindow
	//
	// Purpose:
	//   This function closes a window for async winsock processing
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT ResetWindow(void);
    }

    // ---------------------------------------------------------------------------------------
    // IID_IRASCallback
    // ---------------------------------------------------------------------------------------
    [
	uuid(36D88911-3CD6-11d0-81DF-00C04FD85AB4),
	helpstring("RAS Callback Interface"),
    local,
    ]
    interface IRASCallback : IUnknown
    {
	// -----------------------------------------------------------------------------------
	//  OnReconnect
	// -----------------------------------------------------------------------------------
	HRESULT OnReconnect(
		[in]
		LPSTR                   pszCurrentConnectoid,
		[in]
		LPSTR                   pszNewConnectoid,
		[in]
		IRASTransport          *pTransport);

	// -----------------------------------------------------------------------------------
	//  OnLogonPrompt
	// -----------------------------------------------------------------------------------
	typedef struct tagIXPRASLOGON {
	    CHAR        szConnectoid[CCHMAX_CONNECTOID];
	    CHAR        szUserName[CCHMAX_USERNAME];
	    CHAR        szPassword[CCHMAX_PASSWORD];
	    CHAR        szDomain[CCHMAX_DOMAIN];
	    CHAR        szPhoneNumber[CCHMAX_PHONE_NUMBER];
	    BOOL        fSavePassword;
	} IXPRASLOGON, *LPIXPRASLOGON;

	HRESULT OnLogonPrompt(
		[in,out]
		LPIXPRASLOGON           pRasLogon,
		[in]
		IRASTransport          *pTransport);

	// -----------------------------------------------------------------------------------
	//  OnRasDialStatus
	// -----------------------------------------------------------------------------------
	cpp_quote("#ifndef RASCONNSTATE")
	typedef DWORD RASCONNSTATE;
	cpp_quote("#endif")
	HRESULT OnRasDialStatus(
		[in]
		RASCONNSTATE            rasconnstate,
		[in]
		DWORD                   dwError,
		[in]
		IRASTransport          *pTransport);

	// -----------------------------------------------------------------------------------
	//  OnDisconnect
	//
	//  Description:
	//  This method allows the client to decide if the current RAS connection should
	//  be hungup. This is useful, especially on application shutdown, in which case
	//  the user may want to leave their RAS connection established even after the
	//  application using the connection goes away. This client could show UI on this
	//  callback to prompt the user.
	//
	//  Parameters:
	//  pTransport              The RAS transport that generated the OnDisconnect call
	//
	//  Returns:
	//  S_OK                    The client can return S_OK to "hangup" the current
	//                          RAS connnection.
	//  S_FALSE                 The client can return S_FALSE to leave the connection
	//                          established.
	// -----------------------------------------------------------------------------------
	HRESULT OnDisconnect(
		[in]
		LPSTR                   pszCurrentConnectoid,
		[in]
		boolean                 fConnectionOwner,
		[in]
		IRASTransport          *pTransport);
    }

    // ---------------------------------------------------------------------------------------
    // IID_IRASTransport
    // ---------------------------------------------------------------------------------------
    [
	uuid(8A950001-3CCF-11d0-81DF-00C04FD85AB4),
	helpstring("RAS Transport Interface"),
    local,
    ]
    interface IRASTransport : IInternetTransport
    {
	// -----------------------------------------------------------------------------------
	// InitNew
	// -----------------------------------------------------------------------------------
	HRESULT InitNew(
		[in]
		IRASCallback           *pCallback);

	// -----------------------------------------------------------------------------------
	// GetCurrentConnectoid - Returns Connectoid name of the current RAS Connection.
	// If not connected, IXP_E_NOT_CONNECTED is returned. cchMax must be greater than or
	// equal to CCHMAX_CONNECTOID, or E_INVALIDARG will be returned.
	// -----------------------------------------------------------------------------------
	HRESULT GetCurrentConnectoid(
		[in,ref]
		LPSTR                   pszConnectoid,
		[in]
		ULONG                   cchMax);

	// ----------------------------------------------------------
	// GetRasErrorString
	// ----------------------------------------------------------
	HRESULT GetRasErrorString (
		[in]
		UINT                    uRasErrorValue,
		[in,ref]
		LPSTR                   pszErrorString,
		[in]
		ULONG                   cchMax,
		[out]
		DWORD                  *pdwRASResult);

	// ----------------------------------------------------------
	// FillConnectoidCombo
	// ----------------------------------------------------------
	HRESULT FillConnectoidCombo(
		[in]
		HWND                    hwndComboBox,
		[in]
		boolean                 fUpdateOnly,
		[out]
		DWORD                  *pdwRASResult);

	// ----------------------------------------------------------
	// EditConnectoid
	// ----------------------------------------------------------
	HRESULT EditConnectoid(
		[in]
		HWND                    hwndParent,
		[in]
		LPSTR                   pszConnectoid,
		[out]
		DWORD                  *pdwRASResult);

	// ----------------------------------------------------------
	// CreateConnectoid
	// ----------------------------------------------------------
	HRESULT CreateConnectoid(
		[in]
		HWND                    hwndParent,
		[out]
		DWORD                  *pdwRASResult);
    }



    // ***************************************************************************************
    // ---------------------------------------------------------------------------------------
    // IID_IRangeList
    // ---------------------------------------------------------------------------------------
    [
	uuid(8C438160-4EF6-11d0-874F-00AA00530EE9),
	helpstring("Rangelist Interface: used to represent a range of messages."),
    local,
    ]
    interface IRangeList : IUnknown
    {
	// ----------------------------------
	// IID_IRangeList Interface Constants
	// ----------------------------------
	const ULONG RL_RANGE_ERROR = ((ULONG)-1); // [out] Indicates that no match could be found
	const ULONG RL_LAST_MESSAGE = ((ULONG)-1); // [in] Equivalent to "*" in an IMAP range list


	// ----------------------------------
	// IID_IRangeList Interface Functions
	// ----------------------------------

	    //***********************************************************************
	    // Function: Clear
	    // Purpose: Clears all entries in the rangelist. Note that no memory
	    //    is freed by this operation.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT Clear(void);


	    //***********************************************************************
	    // Function: IsInRange
	    // Purpose: Determines whether the given value is in the rangelist.
	    // Arguments:
	    //   [in] const ULONG value - the value to test against the rangelist.
	    //
	    // Returns: S_OK if given value is in the rangelist, else S_FALSE.
	//***********************************************************************
	HRESULT IsInRange([in] const ULONG value);


	    //***********************************************************************
	    // Function: Min
	    // Arguments:
	//   [out] ULONG *pulMin - the minimum value in the rangelist is returned
	//   here. For example, for the rangelist "10-20,31,44,50-65", this
	//   function returns 10. If the rangelist is empty, a value of
	//   RL_RANGE_ERROR is returned.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT Min([out] ULONG *pulMin);


	    //***********************************************************************
	    // Function: Max
	    // Arguments:
	//   [out] ULONG *pulMax - the maximum value in the rangelist is returned
	//   here. For example, for the rangelist "10-20,31,44,50-65", this
	//   function returns 65. If the rangelist is empty, a value of
	//   RL_RANGE_ERROR is returned.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT Max([out] ULONG *pulMax);    // return the maximum in-range value


	    //***********************************************************************
	    // Function: Save
	// Purpose: This function returns a copy of the internal rangelist
	//   representation which may be loaded later via the Load() function.
	//   NOTE THAT THE INTERNAL RANGELIST REPRESENTATION IS NOT SUITABLE FOR
	//   NETWORK TRANSMITTAL.
	// Arguments:
	//   [out] byte **ppbDestination - if successful, this function returns
	//           a pointer to a copy of the internal rangelist representation
	//           suitable for use with the Load() command (but not for
	//           network transmittal).
	//   [out] ULONG *pulSizeOfDestination - if successful, this function
	//           returns the size of the data pointed to by *ppbDestination.
	//
	// Returns: HRESULT indicating success or failure. Failure to allocate
	//   memory is typically the reason for failure.
	//***********************************************************************
	HRESULT Save([out] byte **ppbDestination,
		     [out] ULONG *pulSizeOfDestination);


	    //***********************************************************************
	    // Function: Load
	// Purpose: This function loads the given internal rangelist
	//   representation, obtained via the Save() function, thus restoring
	//   the rangelist which was saved.
	// Arguments:
	//   [in] byte *pbSource - a pointer to the internal rangelist
	//     representation obtained using the Save() function.
	//   [in] ULONG ulSizeOfSource - the size of the data pointed to by
	//     pbSource.
	//
	// Returns: HRESULT indicating success or failure.
	//***********************************************************************
	HRESULT Load([in, size_is(ulSizeOfSource)] byte *pbSource,
		     [in] const ULONG ulSizeOfSource);


	    //***********************************************************************
	    // Function: AddRange
	// Purpose: This function adds a range of values to the rangelist.
	//   For example, to add 19-99 to the rangelist, call AddRange(19,99).
	// Arguments:
	//   [in] ULONG low - low number of the range to add to the rangelist.
	//   [in] ULONG high - high number of the range to add to the rangelist.
	//
	// Returns: HRESULT indicating success or failure.
	//***********************************************************************
	HRESULT AddRange([in] const ULONG low,
			 [in] const ULONG high);



	    //***********************************************************************
	    // Function: AddSingleValue
	// Purpose: This function adds a single value to the rangelist.
	//   For example, to add 69 to the rangelist, call AddRange(69).
	// Arguments:
	//   [in] ULONG value - the single value to add to the rangelist.
	//
	// Returns: HRESULT indicating success or failure.
	//***********************************************************************
	HRESULT AddSingleValue([in] const ULONG value);


	    //***********************************************************************
	    // Function: AddRangeList
	// Purpose: This function adds a rangelist to the rangelist.
	// Arguments:
	//   [in] IRangeList *prl - the rangelist to add to the rangelist.
	//
	// Returns: HRESULT indicating success or failure.
	//***********************************************************************
	HRESULT AddRangeList([in] const IRangeList *prl);


	    //***********************************************************************
	    // Function: DeleteRange
	// Purpose: This function deletes a range of values from the rangelist.
	//   For example, to remove 7-11 from the rangelist, call DeleteRange(7,11).
	// Arguments:
	//   [in] ULONG low - low number of the range to remove from the rangelist.
	//   [in] ULONG high - high number of the range to remove from the rangelist.
	//
	// Returns: HRESULT indicating success or failure.
	//***********************************************************************
	HRESULT DeleteRange([in] const ULONG low,
			    [in] const ULONG high);



	    //***********************************************************************
	    // Function: DeleteSingleValue
	// Purpose: This function removes a single value from the rangelist.
	//   For example, to remove 42 to the rangelist, call DeleteRange(42).
	// Arguments:
	//   [in] ULONG value - the single value to remove from the rangelist.
	//
	// Returns: HRESULT indicating success or failure.
	//***********************************************************************
	HRESULT DeleteSingleValue([in] const ULONG value);


	    //***********************************************************************
	    // Function: DeleteRangeList
	// Purpose: This function removes a rangelist from the rangelist.
	// Arguments:
	//   [in] IRangeList *prl - the rangelist to remove from the rangelist.
	//
	// Returns: HRESULT indicating success or failure.
	//***********************************************************************
	HRESULT DeleteRangeList([in] const IRangeList *prl);


	    //***********************************************************************
	    // Function: MinOfRange
	// Purpose: This function finds the range that the given value belongs
	//   to, and returns the minimum of that range. For example, for the
	//   rangelist "10-20,30,40-50", MinOfRange(45) returns 40.
	// Arguments:
	//   [in] ULONG value - a value in the range for which you would like to
	//           find the minimum.
	//   [out] ULONG *pulMinOfRange - the minimum value in the range of which
	//          "value" is a member is returned here. If "value" is not in
	//          the rangelist, a value of RL_RANGE_ERROR is returned.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT MinOfRange([in] const ULONG value,
			   [out] ULONG *pulMinOfRange);


	    //***********************************************************************
	    // Function: MaxOfRange
	// Purpose: This function finds the range that the given value belongs
	//   to, and returns the maximum of that range. For example, for the
	//   rangelist "10-20,30,40-50", MaxOfRange(15) returns 20.
	// Arguments:
	//   [in] ULONG value - a value in the range for which you would like to
	//           find the maximum.
	//   [out] ULONG *pulMaxOfRange - the maximum value in the range of which
	//   "value" is a member is returned here. If "value" is not in the
	//   rangelist, a value of RL_RANGE_ERROR is returned.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT MaxOfRange([in] const ULONG value,
			   [out] ULONG *pulMaxOfRange);


	    //***********************************************************************
	    // Function: RangeToIMAPString
	// Purpose: This function outputs the rangelist as an IMAP message set,
	//   as specified by the "set" terminal in RFC 1730/2060 (IMAP).
	// Arguments:
	//   [out] LPSTR *ppszDestination - an IMAP message set string is
	//     returned here. It is the responsibility of the caller to CoTaskMemFree
	//     this buffer when he is done with it. Pass in NULL if not interested.
	//   [out] LPDWORD pdwLengthOfDestination - the length of the IMAP
	//     message set string returned by this function (does not include
	//     null-terminator). Pass in NULL if not interested.
	// Returns: HRESULT indicating success or failure.
	//***********************************************************************
	HRESULT RangeToIMAPString([out] LPSTR *ppszDestination,
				  [out] LPDWORD pdwLengthOfDestination);


	    //***********************************************************************
	    // Function: Next
	// Purpose: This function returns the smallest value in the rangelist
	//   which is greater than the given value. For instance, for a rangelist
	//   5-10, the call Next(7) would return 8.
	// Arguments:
	//   [in] ULONG current - the value for which you'd like to find the next
	//           number in the rangelist.
	//   [out] ULONG *pulNext - the smallest number in the rangelist greater
	//           than "value" is returned here, or RL_RANGE_ERROR if no such
	//           number could be found.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT Next([in] const ULONG current, [out] ULONG *pulNext);


	    //***********************************************************************
	    // Function: Prev
	// Purpose: This function returns the largest value in the rangelist
	//   which is smaller than the given value. For instance, for a rangelist
	//   5-10, the call Prev(7) would return 6.
	// Arguments:
	//   [in] ULONG current - the value for which you'd like to find the
	//           previous number in the rangelist.
	//   [out] ULONG *pulPrev - the largest number in the rangelist smaller
	//           than "value" is returned here, or RL_RANGE_ERROR if no such
	//           number could be found.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT Prev([in] const ULONG current, [out] ULONG *pulPrev);


	    //***********************************************************************
	    // Function: Cardinality
	// Purpose: This function counts the members in the rangelist set. For
	//   example, for the rangelist 1-11, Cardinality() returns 11.
	// Arguments:
	//   [out] ULONG *pulCardinality - The number of members in the
	//            rangelist set is returned here.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT Cardinality(ULONG *pulCardinality);


	    //***********************************************************************
	    // Function: CardinalityFrom
	// Purpose: This function counts the members in the rangelist set which
	//   are larger than the given starting point. For example, for the
	//   rangelist 1-11, Cardinality(10) returns 2.
	// Arguments:
	//   [in] ULONG ulStartPoint - represents 1 less than the lowest number
	//           which should be considered in the cardinality count.
	//   [out] ULONG *pulCardinalityFrom - The number of members in the
	//           rangelist set which are larger than the given starting point
	//           is returned here.
	// Returns: S_OK. This function cannot fail.
	//***********************************************************************
	HRESULT CardinalityFrom([in] const ULONG ulStartPoint,
				[out] ULONG *pulCardinalityFrom);

    } // interface IRangeList



    // ***************************************************************************************
    // ---------------------------------------------------------------------------------------
    // IID_IIMAPCallback
    // ---------------------------------------------------------------------------------------
    [
	uuid(E9E9D8A3-4EDD-11d0-874F-00AA00530EE9),
	helpstring("IMAP Callback Interface: used to notify an IID_IIMAPTransport client of IMAP server events."),
    local,
    ]
    interface IIMAPCallback : ITransportCallback
    {

	// -------------------------------------
	// IID_IIMAPCallback Interface Constants
	// -------------------------------------
	typedef DWORD IMAP_MBOXFLAGS; // Mailbox flags returned by the LIST/LSUB command
	const IMAP_MBOXFLAGS IMAP_MBOX_NOFLAGS       = 0x00000000;
	const IMAP_MBOXFLAGS IMAP_MBOX_MARKED        = 0x00000001;
	const IMAP_MBOXFLAGS IMAP_MBOX_NOINFERIORS   = 0x00000002;
	const IMAP_MBOXFLAGS IMAP_MBOX_NOSELECT      = 0x00000004;
	const IMAP_MBOXFLAGS IMAP_MBOX_UNMARKED      = 0x00000008;
	const IMAP_MBOXFLAGS IMAP_MBOX_ALLFLAGS      = 0x0000000F; // Keep this updated


	// --------------------------------------
	// IID_IIMAPCallback Interface Data Types
	// --------------------------------------
	// The following enumeration identifies the types of IMAP_RESPONSE structures
	typedef enum tagIMAP_RESPONSE_TYPE {
	    irtERROR_NOTIFICATION,  // Indicates an error has been encountered during response parsing
	    irtCOMMAND_COMPLETION,  // Indicates this IMAP command is completed
	    irtSERVER_ALERT,        // ALERT response (see IMAP spec)
	    irtPARSE_ERROR,         // PARSE response (see IMAP spec)
	    irtMAILBOX_UPDATE,      // EXISTS, RECENT, or UNSEEN responses (see IMAP spec)
	    irtDELETED_MSG,         // EXPUNGE response (see IMAP spec)
	    irtFETCH_BODY,          // Partial body from a message, returned via FETCH
	    irtUPDATE_MSG,          // FETCH response (see IMAP spec)
	    irtAPPLICABLE_FLAGS,    // FLAGS response (see IMAP spec)
	    irtPERMANENT_FLAGS,     // PERMANENTFLAGS response code (see IMAP spec)
	    irtUIDVALIDITY,         // UIDVALIDITY response code (see IMAP spec)
	    irtREADWRITE_STATUS,    // READ-WRITE or READ-ONLY response code (see IMAP spec)
	    irtTRYCREATE,           // TRYCREATE response code (see IMAP spec)
	    irtSEARCH,              // SEARCH response (see IMAP spec)
	    irtMAILBOX_LISTING,     // LIST or LSUB response (see IMAP spec)
	    irtMAILBOX_STATUS,      // STATUS response (see IMAP spec)
	    irtAPPEND_PROGRESS,     // Progress of APPEND stream upload
	    irtUPDATE_MSG_EX        // Extended FETCH response (see IMAP spec)
	} IMAP_RESPONSE_TYPE;


	// Fetch body part - body parts requested by the client are returned piece-by-piece
	// as they are received from the server, using this structure. After the entire FETCH
	// response is received, the client will also receive a FETCH_CMD_RESULTS structure
	// (see below) with the remaining requested information.
	typedef struct tagFETCH_BODY_PART {
	    DWORD dwMsgSeqNum; // Message sequence number to which this FETCH resp applies

	    LPSTR pszBodyTag; // Pointer to the IMAP tag identifying this body part (eg,
			      // "RFC822.PEEK", or "BODY[2.2]<0.2048>"). NOTE that we terminate
			      // the tag at the FIRST SPACE. This means that even though you sent
			      // "BODY[HEADER.FIELDS (foo bar)]", the tag returned will only be
			      // "BODY[HEADER.FIELDS".

	    DWORD dwTotalBytes; // Total number of bytes expected for this body part
	    DWORD dwSizeOfData; // The number of bytes pointed to by pszData
	    DWORD dwOffset; // Offset of the start of this data buffer
	    BOOL fDone;     // TRUE when this is the last data buffer
	    LPSTR pszData;      // A pointer to the body part data

	    LPARAM lpFetchCookie1; // User-settable values, initially set to 0. These will persist
	    LPARAM lpFetchCookie2; // throughout the FETCH response, ie, for all FETCH_BODY_PART
				   // responses (even if multiple body parts are fetched), and for
				   // the final FETCH_CMD_RESULTS structure.
	} FETCH_BODY_PART;


	// Fetch results structure - holds data from a FETCH response. Since FETCH
	// responses can be unsolicited, the recipient must check that a data item is
	// valid before attempting to use it.
	typedef struct tagFETCH_CMD_RESULTS {
	    DWORD dwMsgSeqNum; // Message sequence number to which this FETCH resp applies

	    BOOL bMsgFlags; // TRUE if MsgFlags (below) contains valid data
	    IMAP_MSGFLAGS mfMsgFlags; // Used to return the FLAGS tag of a FETCH response

	    BOOL bRFC822Size; // TRUE if dwRFC822Size (below) contains valid data
	    DWORD dwRFC822Size; // Used to return the RFC822.SIZE tag of a FETCH response

	    BOOL bUID; // TRUE if dwUID (below) contains valid data
	    DWORD dwUID; // Used to return the UID tag of a FETCH response

	    BOOL bInternalDate; // TRUE if ftInternalDate (below) contains valid data
	    FILETIME ftInternalDate; // Used to return the INTERNALDATE tag of a FETCH response

	    LPARAM lpFetchCookie1; // User-settable values. These will persist throughout
	    LPARAM lpFetchCookie2; // the FETCH, ie, for all FETCH_BODY_PART responses (even
				   // if multiple body parts are fetched), and for the final
				   // FETCH_CMD_RESULTS structure.
	} FETCH_CMD_RESULTS;


	typedef struct tagIMAPADDR {
	    LPSTR   pszName;    // See formal syntax for "addr_name", RFC2060
	    LPSTR   pszADL;     // See formal syntax for "addr_adl", RFC2060
	    LPSTR   pszMailbox; // See formal syntax for "addr_mailbox", RFC2060
	    LPSTR   pszHost;    // See formal syntax for "addr_host", RFC2060
	    struct tagIMAPADDR *pNext; // Pointer to next address
	} IMAPADDR;


	typedef struct tagFETCH_CMD_RESULTS_EX {
	    // *** First part of this structure is exactly like FETCH_CMD_RESULTS ***
	    DWORD dwMsgSeqNum; // Message sequence number to which this FETCH resp applies

	    BOOL bMsgFlags; // TRUE if MsgFlags (below) contains valid data
	    IMAP_MSGFLAGS mfMsgFlags; // Used to return the FLAGS tag of a FETCH response

	    BOOL bRFC822Size; // TRUE if dwRFC822Size (below) contains valid data
	    DWORD dwRFC822Size; // Used to return the RFC822.SIZE tag of a FETCH response

	    BOOL bUID; // TRUE if dwUID (below) contains valid data
	    DWORD dwUID; // Used to return the UID tag of a FETCH response

	    BOOL bInternalDate; // TRUE if ftInternalDate (below) contains valid data
	    FILETIME ftInternalDate; // Used to return the INTERNALDATE tag of a FETCH response

	    LPARAM lpFetchCookie1; // User-settable values. These will persist throughout
	    LPARAM lpFetchCookie2; // the FETCH, ie, for all FETCH_BODY_PART responses (even
				   // if multiple body parts are fetched), and for the final
				   // FETCH_CMD_RESULTS structure.


	    // *** Second part of this structure contains the extensions ***
	    BOOL        bEnvelope;          // TRUE if we received an ENVELOPE response
	    FILETIME    ftENVDate;          // Date returned via ENVELOPE
	    LPSTR       pszENVSubject;      // "Subject" returned via ENVELOPE
	    IMAPADDR   *piaENVFrom;         // "From" addresses returned via ENVELOPE
	    IMAPADDR   *piaENVSender;       // "Sender" addresses returned via ENVELOPE
	    IMAPADDR   *piaENVReplyTo;      // "ReplyTo" addresses returned via ENVELOPE
	    IMAPADDR   *piaENVTo;           // "To" addresses returned via ENVELOPE
	    IMAPADDR   *piaENVCc;           // "Cc" addresses returned via ENVELOPE
	    IMAPADDR   *piaENVBcc;          // "Bcc" addresses returned via ENVELOPE
	    LPSTR       pszENVInReplyTo;    // "InReplyTo" returned via ENVELOPE
	    LPSTR       pszENVMessageID;    // "MessageID" returned via ENVELOPE

	    DWORD       dwReserved1;
	    DWORD       dwReserved2;
	    DWORD       dwReserved3;
	} FETCH_CMD_RESULTS_EX;


	// The following structure is used to track and communicate EXISTS,
	// RECENT and UNSEEN responses from the IMAP server
	typedef struct tagMBOX_MSGCOUNT {
	    BOOL bGotExistsResponse;
	    DWORD dwExists;

	    BOOL bGotRecentResponse;
	    DWORD dwRecent;

	    BOOL bGotUnseenResponse;
	    DWORD dwUnseen;
	} MBOX_MSGCOUNT;

	// The following structure returns the results of a LIST or LSUB response
	typedef struct tagIMAP_LISTLSUB_RESPONSE {
	    LPSTR pszMailboxName;
	    IMAP_MBOXFLAGS imfMboxFlags;
	    char cHierarchyChar;
	} IMAP_LISTLSUB_RESPONSE;

	// The following structure returns the results of a STATUS response
	typedef struct tagIMAP_STATUS_RESPONSE {
	    LPSTR pszMailboxName;

	    BOOL fMessages;
	    DWORD dwMessages;
	    BOOL fRecent;
	    DWORD dwRecent;
	    BOOL fUIDNext;
	    DWORD dwUIDNext;
	    BOOL fUIDValidity;
	    DWORD dwUIDValidity;
	    BOOL fUnseen;
	    DWORD dwUnseen;
	} IMAP_STATUS_RESPONSE;


	// The following structure returns the progress of the current APPEND command
	typedef struct tagAPPEND_PROGRESS {
	    DWORD dwUploaded;
	    DWORD dwTotal;
	} APPEND_PROGRESS;


	// The following union can hold the results of many types of IMAP responses
	typedef [switch_type(IMAP_RESPONSE_TYPE)] union tagIMAP_RESPONSE_DATA {
	    [case (irtMAILBOX_UPDATE)] MBOX_MSGCOUNT *pmcMsgCount; // For mailbox update (EXISTS, RECENT, UNSEEN) data
	    [case (irtDELETED_MSG)] DWORD dwDeletedMsgSeqNum;      // For EXPUNGE response data
	    [case (irtFETCH_BODY)] FETCH_BODY_PART *pFetchBodyPart; // For body parts (eg, RFC822) retrieved via FETCH
	    [case (irtUPDATE_MSG)] FETCH_CMD_RESULTS *pFetchResults; // For message update (FETCH) data
	    [case (irtAPPLICABLE_FLAGS, irtPERMANENT_FLAGS)]
		IMAP_MSGFLAGS imfImapMessageFlags;                 // For FLAGS response or PERMANENTFLAGS response code data
	    [case (irtUIDVALIDITY)] DWORD dwUIDValidity;           // For UIDVALIDITY response code data
	    [case (irtREADWRITE_STATUS)] BOOL bReadWrite;          // For READ-WRITE or READ-ONLY response code data
	    [case (irtSEARCH)] IRangeList *prlSearchResults;       // For SEARCH response data
	    [case (irtMAILBOX_LISTING)]
		IMAP_LISTLSUB_RESPONSE illrdMailboxListing;        // For LIST or LSUB response data
	    [case (irtMAILBOX_STATUS)]
		IMAP_STATUS_RESPONSE *pisrStatusResponse;          // For STATUS response data
	    [case (irtAPPEND_PROGRESS)]
		APPEND_PROGRESS *papAppendProgress;
	    [case (irtUPDATE_MSG_EX)] FETCH_CMD_RESULTS_EX
		*pFetchResultsEx;                                  // For message update (FETCH) data
	} IMAP_RESPONSE_DATA;

	// The following structure is used to represent all IMAP responses
	typedef struct tagIMAP_RESPONSE {
	    WPARAM              wParam; // This is 0 if unsolicited response or unresolvable
	    LPARAM              lParam; // This is 0 if unsolicited response or unresolvable
	    HRESULT             hrResult;
	    LPSTR               lpszResponseText;
	    IMAP_RESPONSE_TYPE  irtResponseType;
	    [switch_is(irtResponseType)] IMAP_RESPONSE_DATA irdResponseData;
	} IMAP_RESPONSE;


	//-----------------------------------------------------------------------
	// IID_IIMAPCallback Interface Functions
	//-----------------------------------------------------------------------

	//***********************************************************************
	// Function: OnResponse
	// Purpose: This function is used to report IMAP server responses to
	//   IMAP commands (or unsolicited responses).
	// Arguments:
	//   [in] IMAP_RESPONSE *pirIMAPResponse - a pointer to an IMAP response
	//           structure is returned to the IID_IIMAPTransport user via
	//           this callback.
	// Returns: This function should always return S_OK.
	//***********************************************************************
	HRESULT OnResponse([in] const IMAP_RESPONSE *pirIMAPResponse);

    } // interface IIMAPCallback



    // ***************************************************************************************
    // ---------------------------------------------------------------------------------------
    // IID_IIMAPTransport
    // ---------------------------------------------------------------------------------------
    [
	uuid(E9E9D8A8-4EDD-11d0-874F-00AA00530EE9),
	helpstring("IMAP Transport Interface: used to send IMAP commands to an IMAP server."),
    local,
    ]
    interface IIMAPTransport : IInternetTransport
    {
	// -------------------------------------
	// IID_IIMAPTransport Interface Constants
	// -------------------------------------
	// The following DWORDs are returned by IIMAPTransport::Capability
	const DWORD IMAP_CAPABILITY_IMAP4       = 0x00000001;
	const DWORD IMAP_CAPABILITY_IMAP4rev1   = 0x00000002;
	const DWORD IMAP_CAPABILITY_IDLE        = 0x00000004;
	const DWORD IMAP_CAPABILITY_ALLFLAGS    = 0x00000007; // Keep this updated



	//-----------------------------------------------------------------------
	// IID_IIMAPTransport Interface Functions
	//-----------------------------------------------------------------------
	//***************************************************************************
	// Function: InitNew
	//
	// Purpose:
	//   This function initializes the CImap4Agent class. This function
	// must be the next function called after instantiating the CImap4Agent class.
	//
	// Arguments:
	//   LPSTR pszLogFilePath [in] - path to a log file (where all input and
	//     output is logged), if the caller wishes to log IMAP transactions.
	//   IIMAPCallback *pCBHandler [in] - pointer to a IIMAPCallback object.
	//     This object allows the CImap4Agent class to report all IMAP response
	//     results to its user.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT InitNew([in] LPSTR pszLogFilePath,
			[in] IIMAPCallback *pCBHandler);


	//***************************************************************************
	// Function: NewIRangeList
	//
	// Purpose:
	//   This function returns a pointer to an IRangeList. Its purpose is to
	// allow full functionality from an IIMAPTransport pointer without needing
	// to resort to CoCreateInstance to get an IRangeList.
	//
	// Arguments:
	//   IRangeList **pprlNewRangeList [out] - if successful, the function
	//      returns a pointer to the new IRangeList.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT NewIRangeList([out] IRangeList **pprlNewRangeList);


	//***************************************************************************
	// Function: Capability
	//
	// Purpose:
	//   The CImap4Agent class always asks for the server's CAPABILITIES after
	// a connection is established. The result is saved in a register and
	// is available by calling this function.
	//
	// Arguments:
	//   [out] DWORD *pdwCapabilityFlags - this function returns a DWORD with
	//            bit-flags specifying which capabilities this IMAP server
	//            supports.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT Capability([out] DWORD *pdwCapabilityFlags);


	//***************************************************************************
	// Function: Select
	//
	// Purpose:
	//   This function issues a SELECT command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxName - pointer to IMAP-compliant mailbox name
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Select([in] WPARAM wParam,
		       [in] LPARAM lParam,
		       [in] IIMAPCallback *pCBHandler,
		       [in] LPSTR lpszMailboxName);


	//***************************************************************************
	// Function: Examine
	//
	// Purpose:
	//   This function issues an EXAMINE command to the IMAP server.
	//
	// Arguments:
	//   Same as for the Select() function.
	//
	// Returns:
	//   Same as for the Select() function.
	//***************************************************************************
	HRESULT Examine([in] WPARAM wParam,
			[in] LPARAM lParam,
			[in] IIMAPCallback *pCBHandler,
			[in] LPSTR lpszMailboxName);


	//***************************************************************************
	// Function: Create
	//
	// Purpose:
	//   This function issues a CREATE command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxName - IMAP-compliant name of the mailbox.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Create([in] WPARAM wParam,
		       [in] LPARAM lParam,
		       [in] IIMAPCallback *pCBHandler,
		       [in] LPSTR lpszMailboxName);


	//***************************************************************************
	// Function: Delete
	//
	// Purpose:
	//   This function issues a DELETE command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxName - IMAP-compliant name of the mailbox.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Delete([in] WPARAM wParam,
		       [in] LPARAM lParam,
		       [in] IIMAPCallback *pCBHandler,
		       [in] LPSTR lpszMailboxName);


	//***************************************************************************
	// Function: Rename
	//
	// Purpose:
	//   This function issues a RENAME command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxName - CURRENT IMAP-compliant name of the mailbox.
	//   LPSTR lpszNewMailboxName - NEW IMAP-compliant name of the mailbox.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Rename([in] WPARAM wParam,
		       [in] LPARAM lParam,
		       [in] IIMAPCallback *pCBHandler,
		       [in] LPSTR lpszMailboxName,
		       [in] LPSTR lpszNewMailboxName);


	//***************************************************************************
	// Function: Subscribe
	//
	// Purpose:
	//   This function issues a SUBSCRIBE command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxName - IMAP-compliant name of the mailbox.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Subscribe([in] WPARAM wParam,
			  [in] LPARAM lParam,
			  [in] IIMAPCallback *pCBHandler,
			  [in] LPSTR lpszMailboxName);


	//***************************************************************************
	// Function: Unsubscribe
	//
	// Purpose:
	//   This function issues an UNSUBSCRIBE command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxName - IMAP-compliant name of the mailbox.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Unsubscribe([in] WPARAM wParam,
			    [in] LPARAM lParam,
			    [in] IIMAPCallback *pCBHandler,
			    [in] LPSTR lpszMailboxName);


	//***************************************************************************
	// Function: List
	//
	// Purpose:
	//   This function issues a LIST command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxNameReference - IMAP-compliant reference for mbox name
	//   LPSTR lpszMailboxNamePattern - IMAP-compliant pattern for mailbox name
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT List([in] WPARAM wParam,
		     [in] LPARAM lParam,
		     [in] IIMAPCallback *pCBHandler,
		     [in] LPSTR lpszMailboxNameReference,
		     [in] LPSTR lpszMailboxNamePattern);


	//***************************************************************************
	// Function: Lsub
	//
	// Purpose:
	//   This function issues a LSUB command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxNameReference - IMAP-compliant reference for mbox name
	//   LPSTR lpszMailboxNamePattern - IMAP-compliant pattern for mailbox name.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Lsub([in] WPARAM wParam,
		     [in] LPARAM lParam,
		     [in] IIMAPCallback *pCBHandler,
		     [in] LPSTR lpszMailboxNameReference,
		     [in] LPSTR lpszMailboxNamePattern);


	//***************************************************************************
	// Function: Append
	//
	// Purpose:
	//   This function issues an APPEND command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszMailboxName - IMAP-compliant mailbox name to append message to.
	//   LPSTR lpszMessageFlags - IMAP-compliant list of msg flags to set for msg.
	//     Set to NULL to set no message flags. (Avoid passing "()" due to old Cyrus
	//     server bug). $REVIEW: This should be changed to IMAP_MSGFLAGS!!!
	//   FILETIME ftMessageDateTime - date/time to associate with msg (GMT/UTC)
	//   LPSTREAM lpstmMessageToSave - the message to save, in RFC822 format.
	//     No need to rewind the stream, this is done by CConnection::SendStream.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Append([in] WPARAM wParam,
		       [in] LPARAM lParam,
		       [in] IIMAPCallback *pCBHandler,
		       [in] LPSTR lpszMailboxName,
		       [in] LPSTR lpszMessageFlags,
		       [in] FILETIME ftMessageDateTime,
		       [in] LPSTREAM lpstmMessageToSave);


	//***************************************************************************
	// Function: Close
	//
	// Purpose:
	//   This function issues a CLOSE command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Close([in] WPARAM wParam,
		      [in] LPARAM lParam,
		      [in] IIMAPCallback *pCBHandler);


	//***************************************************************************
	// Function: Expunge
	//
	// Purpose:
	//   This function issues an EXPUNGE command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//
	// Returns:
	//   HRESULT indicating success or failure on send operation.
	//***************************************************************************
	HRESULT Expunge([in] WPARAM wParam,
			[in] LPARAM lParam,
			[in] IIMAPCallback *pCBHandler);


	//***************************************************************************
	// Function: Search
	//
	// Purpose:
	//   This function issues a SEARCH command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR lpszSearchCriteria - IMAP-compliant list of search criteria
	//   boolean bReturnUIDs - if TRUE, we prepend "UID" to command.
	//   IRangeList *pMsgRange [in] - range of messages over which to operate
	//     the search. This argument should be NULL to exclude the message
	//     set from the search criteria.
	//   boolean bUIDRangeList [in] - TRUE if pMsgRange refers to a UID range,
	//     FALSE if pMsgRange refers to a message sequence number range. If
	//     pMsgRange is NULL, this argument is ignored.
	//
	// Returns:
	//   HRESULT indicating success or failure on send operation.
	//***************************************************************************
	HRESULT Search([in] WPARAM wParam,
		       [in] LPARAM lParam,
		       [in] IIMAPCallback *pCBHandler,
		       [in] LPSTR lpszSearchCriteria,
		       [in] boolean bReturnUIDs,
		       [in] IRangeList *pMsgRange,
		       [in] boolean bUIDRangeList);


	//***************************************************************************
	// Function: Fetch
	//
	// Purpose:
	//   This function issues a FETCH command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   IRangeList *pMsgRange [in] - range of messages to fetch. The caller
	//     should pass NULL if he is using UIDs and he wants to generate his
	//     own message set (in lpszFetchArgs). If the caller is using msg
	//     seq nums, this argument MUST be specified to allow this class to
	//     resequence the msg nums as required.
	//   boolean bUIDMsgRange [in] - if TRUE, prepends "UID" to FETCH command and
	//     treats pMsgRange as a UID range.
	//   LPSTR lpszFetchArgs - arguments to the FETCH command
	//
	//
	// Returns:
	//   HRESULT indicating success or failure of the send operation.
	//***************************************************************************
	HRESULT Fetch([in] WPARAM wParam,
		      [in] LPARAM lParam,
		      [in] IIMAPCallback *pCBHandler,
		      [in] IRangeList *pMsgRange,
		      [in] boolean bUIDMsgRange,
		      [in] LPSTR lpszFetchArgs);


	//***************************************************************************
	// Function: Store
	//
	// Purpose:
	//   This function issues a STORE command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   IRangeList *pMsgRange [in] - range of messages to store. The caller
	//     should pass NULL if he is using UIDs and he wants to generate his
	//     own message set (in lpszStoreArgs). If the caller is using msg
	//     seq nums, this argument MUST be specified to allow this class to
	//     resequence the msg nums as required.
	//   boolean bUIDRangeList [in] - if TRUE, we prepend "UID" to the STORE command
	//   LPSTR lpszStoreArgs - arguments for the STORE command.
	//
	// Returns:
	//   HRESULT indicating success or failure of the send operation.
	//***************************************************************************
	HRESULT Store([in] WPARAM wParam,
		      [in] LPARAM lParam,
		      [in] IIMAPCallback *pCBHandler,
		      [in] IRangeList *pMsgRange,
		      [in] boolean bUIDRangeList,
		      [in] LPSTR lpszStoreArgs);


	//***************************************************************************
	// Function: Copy
	//
	// Purpose:
	//   This function issues a COPY command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   IRangeList *pMsgRange [in] - the range of messages to copy. This
	//     argument must be supplied.
	//   boolean bUIDRangeList [in] - if TRUE, prepends "UID" to COPY command
	//   LPSTR lpszMailboxName [in] - C String of mailbox name
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Copy([in] WPARAM wParam,
		     [in] LPARAM lParam,
		     [in] IIMAPCallback *pCBHandler,
		     [in] IRangeList *pMsgRange,
		     [in] boolean bUIDRangeList,
		     [in] LPSTR lpszMailboxName);


	//***************************************************************************
	// Function: Noop
	//
	// Purpose:
	//   This function issues a NOOP command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//
	// Returns:
	//   HRESULT indicating success or failure of send operation.
	//***************************************************************************
	HRESULT Noop([in] WPARAM wParam,
		     [in] LPARAM lParam,
		     [in] IIMAPCallback *pCBHandler);





	//---------------------------------------------------------------------------
	// Message Sequence Number to UID member functions - the caller may use
	// these functions to map from MSN's to UID's, if the caller uses UIDs
	// to refer to messages. If the caller uses MSN's, there is no need to
	// invoke the following functions.
	//---------------------------------------------------------------------------


	//***************************************************************************
	// Function: ResizeMsgSeqNumTable
	//
	// Purpose:
	//   This function is called whenever we receive an EXISTS response. It
	// resizes the MsgSeqNumToUID table to match the current size of the mailbox.
	//
	// Arguments:
	//   DWORD dwSizeOfMbox [in] - the number returned via the EXISTS response.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT ResizeMsgSeqNumTable([in] DWORD dwSizeOfMbox);


	//***************************************************************************
	// Function: UpdateSeqNumToUID
	//
	// Purpose:
	//   This function is called whenever we receive a FETCH response which has
	// both a message sequence number and a UID number. It updates the
	// MsgSeqNumToUID table so that given msg seq number maps to the given UID.
	//
	// Arguments:
	//   DWORD dwMsgSeqNum [in] - the message sequence number of the FETCH
	//     response.
	//   DWORD dwUID [in] - the UID of the given message sequence number.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT UpdateSeqNumToUID([in] DWORD dwMsgSeqNum,
				  [in] DWORD dwUID);


	//***************************************************************************
	// Function: RemoveSequenceNum
	//
	// Purpose:
	//   This function is called whenever we receive an EXPUNGE response. It
	// removes the given message sequence number from the MsgSeqNumToUID table,
	// and compacts the table so that all message sequence numbers following
	// the deleted one are re-sequenced.
	//
	// Arguments:
	//   DWORD dwDeletedMsgSeqNum [in] - message sequence number of deleted msg.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT RemoveSequenceNum([in] DWORD dwDeletedMsgSeqNum);


	//***************************************************************************
	// Function: MsgSeqNumToUID
	//
	// Purpose:
	//   This function takes a message sequence number and converts it to a UID
	// based on the MsgSeqNumToUID table.
	//
	// Arguments:
	//   DWORD dwMsgSeqNum [in] - the sequence number for which the caller wants
	//     to know the UID.
	//   DWORD *pdwUID [out] - the UID associated with the given sequence number
	//     is returned here. If none could be found, this function returns 0.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT MsgSeqNumToUID([in] DWORD dwMsgSeqNum, [out] DWORD *pdwUID);


	//***************************************************************************
	// Function: GetMsgSeqNumToUIDArray
	//
	// Purpose:
	//   This function returns a copy of the MsgSeqNumToUID array. The caller
	// will want to do this to delete messages from the cache which no longer
	// exist on the server, for example.
	//
	// Arguments:
	//   DWORD **ppdwMsgSeqNumToUIDArray [out] - the function returns a pointer
	//     to the copy of the MsgSeqNumToUID array in this argument. Note that
	//     it is the caller's responsibility to MemFree the array. If no array
	//     is available, or it is empty, the returned pointer value is NULL.
	//   DWORD *pdwNumberOfElements [out] - the function returns the size of
	//     the MsgSeqNumToUID array.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT GetMsgSeqNumToUIDArray([out] DWORD **ppdwMsgSeqNumToUIDArray,
				       [out] DWORD *pdwNumberOfElements);


	//***************************************************************************
	// Function: GetHighestMsgSeqNum
	//
	// Purpose:
	//   This function returns the highest message sequence number reported in
	// the MsgSeqNumToUID array.
	//
	// Arguments:
	//   DWORD *pdwHighestMSN [out] - the highest message sequence number in the
	//     table is returned here.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT GetHighestMsgSeqNum([out] DWORD *pdwHighestMSN);


	//***************************************************************************
	// Function: ResetMsgSeqNumToUID
	//
	// Purpose:
	//   This function resets the variables used to maintain the MsgSeqNumToUID
	// table. This function is AUTOMATICALLY called whenever the MsgSeqNumToUID
	// table becomes invalid (say, when a new mailbox is selected, or we are
	// disconnected). This function shouldn't normally need to be called, but
	// I've placed it here just in case someone needs it.
	//
	// Returns:
	//   S_OK. This function cannot fail.
	//***************************************************************************
	HRESULT ResetMsgSeqNumToUID(void);


	//---------------------------------------------------------------------------
	// Leaving Message Sequence Number to UID member functions zone
	//---------------------------------------------------------------------------

	//***************************************************************************
	// Function: SetDefaultCBHandler
	//
	// Purpose: This function changes the current default IIMAPCallback handler
	//   to the given one.
	//
	// Arguments:
	//   IIMAPCallback *pCBHandler [in] - a pointer to the new callback handler.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT SetDefaultCBHandler([in] IIMAPCallback *pCBHandler);


	//***************************************************************************
	// Function: Status
	//
	// Purpose:
	//   This function issues a STATUS command to the IMAP server.
	//
	// Arguments:
	//   WPARAM wParam [in] - (see below)
	//   LPARAM lParam [in] - the wParam and lParam form a unique ID assigned by
	//     the caller to this IMAP command and its responses. Can be anything,
	//     but note that the value of 0, 0 is reserved for unsolicited responses.
	//   IIMAPCallback *pCBHandler [in] - the CB handler to use to process the
	//     responses for this command. If this is NULL, the default CB handler
	//     is used.
	//   LPSTR pszMailboxName [in] - the mailbox which you want to get the
	//     STATUS of.
	//   LPSTR pszStatusCmdArgs [in] - the arguments for the STATUS command,
	//     eg, "(MESSAGES UNSEEN)".
	//
	// Returns:
	//   HRESULT indicating success or failure of the send operation.
	//***************************************************************************
	HRESULT Status([in] WPARAM wParam,
		       [in] LPARAM lParam,
		       [in] IIMAPCallback *pCBHandler,
		       [in] LPSTR pszMailboxName,
		       [in] LPSTR pszStatusCmdArgs);


    } // interface IIMAPTransport



    // ***************************************************************************************
    // ---------------------------------------------------------------------------------------
    // IID_IIMAPTransport2
    // ---------------------------------------------------------------------------------------
    [
	uuid(DA8283C0-37C5-11d2-ACD9-0080C7B6E3C5),
	helpstring("IMAP Transport Interface 2: Extension to IIMAPTransport."),
    local,
    ]
    interface IIMAPTransport2 : IIMAPTransport
    {

	//-----------------------------------------------------------------------
	// IID_IIMAPTransport Interface Functions
	//-----------------------------------------------------------------------

	//***************************************************************************
	// Function: SetDefaultCP
	//
	// Purpose:
	//   This function allows the caller to tell IIMAPTransport what codepage to
	// use for IMAP mailbox names. After calling this function, all mailbox names
	// submitted to IIMAPTransport will be translated from the default codepage,
	// and all mailbox names returned from the server will be translated to
	// the default codepage before being returned via IIMAPCallback.
	//
	// Arguments:
	//   DWORD dwTranslateFlags [in] - enables/disables automatic translation to
	//     and from default codepage and IMAP-modified UTF-7. If disabled, caller
	//     wishes all mailbox names to be passed verbatim to/from IMAP server.
	//     Note that by default we translate for IMAP4 servers, even with its
	//     round-trippability problems, because this is how we used to do it
	//     in the past.
	//   UINT uiCodePage [in] - the default codepage to use for translations.
	//     By default this value is the CP returned by GetACP().
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT SetDefaultCP([in] DWORD dwTranslateFlags,
			     [in] UINT uiCodePage);

	// TranslateFlags
	const DWORD IMAP_MBOXXLATE_DEFAULT      = 0x00000000; // Always translate, even for IMAP4
	const DWORD IMAP_MBOXXLATE_DISABLE      = 0x00000001; // Always disable
	const DWORD IMAP_MBOXXLATE_DISABLEIMAP4 = 0x00000002; // Disable for IMAP4, translate for IMAP4rev1
	const DWORD IMAP_MBOXXLATE_VERBATIMOK   = 0x00000004; // Non-translatable mbox names can be returned verbatim
							      // Note if translation disabled, all mboxes will be
							      // returned with IXP_S_IMAP_VERBATIM_MBOX
	const DWORD IMAP_MBOXXLATE_RETAINCP     = 0x00000008; // Don't change codepage with this call


	//***************************************************************************
	// Function: MultiByteToModifiedUTF7
	//
	// Purpose:
	//   This function takes a MultiByte string and converts it to modified IMAP
	// UTF7, which is described in RFC2060. This function is only needed if the
	// user has disabled transparent mailbox translation using SetDefaultCP(FALSE,0).
	//
	// Arguments:
	//   LPCSTR pszSource [in] - pointer to the MultiByte string to convert to UTF7.
	//   LPSTR *ppszDestination [out] - a pointer to a string buffer containing
	//     the UTF7 equivalent of pszSource is returned here. It is the caller's
	//     responsibility to MemFree this string.
	//   UINT uiSourceCP [in] - indicates the codepage for pszSource
	//     Note that no translation is performed if SetDefaultCP(FALSE,.) was called.
	//   DWORD dwFlags [in] - Reserved. Leave as 0.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT MultiByteToModifiedUTF7([in] LPCSTR pszSource,
					[out] LPSTR *ppszDestination,
					[in] UINT uiSourceCP,
					[in] DWORD dwFlags);


	//***************************************************************************
	// Function: ModifiedUTF7ToMultiByte
	//
	// Purpose:
	//   This function takes a modified IMAP UTF-7 string (as defined in RFC2060)
	// and converts it to a multi-byte string. This function is only needed if the
	// user has disabled transparent mailbox translation using SetDefaultCP(FALSE,0).
	//
	// Arguments:
	//   LPCSTR pszSource [in] - a null-terminated string containing the modified
	//     IMAP UTF-7 string to convert to multibyte.
	//   LPSTR *ppszDestination [out] - this function returns a pointer to the
	//     null-terminated multibyte string (in the system codepage) obtained
	//     from pszSource. It is the caller's responsiblity to MemFree this
	//     string when it is done with it.
	//   UINT uiDestintationCP [in] - indicates the desired codepage for the
	//     destination string. Note that no translation is performed if
	//     SetDefaultCP(FALSE,.) was called.
	//   DWORD dwFlags [in] - Reserved. Leave as 0.
	//
	// Returns:
	//   HRESULT indicating success or failure. Success result codes include:
	//     S_OK - pszSource successfully converted to modified UTF-7
	//     IXP_S_IMAP_VERBATIM_MBOX - pszSource could not be converted to multibyte,
	//        so ppszDestination contains a duplicate of pszSource. If target CP
	//        is Unicode, pszSource is converted to Unicode with the assumption
	//        that it is USASCII. IMAP_MBOXXLATE_VERBATIMOK must have been set via
	//        SetDefaultCP in order to get this behaviour.
	//***************************************************************************
	HRESULT ModifiedUTF7ToMultiByte([in] LPCSTR pszSource,
					[out] LPSTR *ppszDestination,
					[in] UINT uiDestinationCP,
					[in] DWORD dwFlags);


	//***************************************************************************
	// Function: SetIdleMode
	//
	// Purpose:
	//   The IMAP IDLE extension allows the server to unilaterally report changes
	// to the currently selected mailbox: new email, flag updates, and message
	// expunges. IIMAPTransport always enters IDLE mode when no IMAP commands
	// are pending, but it turns out that this can result in unnecessary
	// entry and exit of IDLE mode when the caller tries to sequence IMAP commands.
	// This function allows the caller to disable the use of the IDLE extension.
	//
	// Arguments:
	//   DWORD dwIdleFlags [in] - enables or disables the use of the IDLE extension.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT SetIdleMode([in] DWORD dwIdleFlags);

	// Idle Flags
	const DWORD IMAP_IDLE_DISABLE   = 0x00000000;
	const DWORD IMAP_IDLE_ENABLE    = 0x00000001;


	//***************************************************************************
	// Function: EnableFetchEx
	//
	// Purpose:
	//   IIMAPTransport only understood a subset of FETCH response tags. Notable
	// omissions included ENVELOPE and BODYSTRUCTURE. Calling this function
	// changes the behaviour of IIMAPTransport::Fetch. Instead of returning
	// FETCH responses via IIMAPCallback::OnResponse(irtUPDATE_MSG),
	// the FETCH response is returned via OnResponse(irtUPDATE_MSG_EX).
	// Other FETCH-related responses remain unaffected (eg, irtFETCH_BODY).
	//
	// Arguments:
	//   DWORD dwFetchExFlags [in] - enables or disables FETCH extensions.
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT EnableFetchEx([in] DWORD dwFetchExFlags);

	// FetchEx flags
	const DWORD IMAP_FETCHEX_DISABLE            = 0x00000000;
	const DWORD IMAP_FETCHEX_ENABLE             = 0x00000001;


	//***************************************************************************
	// Function: SetWindow
	//
	// Purpose:
	//   This function creates a new window for async winsock processing
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT SetWindow(void);


	//***************************************************************************
	// Function: ResetWindow
	//
	// Purpose:
	//   This function closes a window for async winsock processing
	//
	// Returns:
	//   HRESULT indicating success or failure.
	//***************************************************************************
	HRESULT ResetWindow(void);

    } // interface IIMAPTransport2


cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("// Exported C Functions")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("#if !defined(_IMNXPORT_)")
cpp_quote("#define IMNXPORTAPI DECLSPEC_IMPORT HRESULT WINAPI")
cpp_quote("#else")
cpp_quote("#define IMNXPORTAPI HRESULT WINAPI")
cpp_quote("#endif")
cpp_quote("#ifdef __cplusplus")
cpp_quote("extern \"C\" {")
cpp_quote("#endif")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("//   CreateRASTransport")
cpp_quote("//   ")
cpp_quote("//   Description:")
cpp_quote("//   This method creates a IRASTransport object. The client must initialize the")
cpp_quote("//   object by calling IRASTransport::InitNew")
cpp_quote("//   ")
cpp_quote("//   Parameters:")
cpp_quote("//   ppTransport                 Upon successful return, contains the a pointer to")
cpp_quote("//                               an IRASTransport interface")
cpp_quote("//   ")
cpp_quote("//   Return Values:")
cpp_quote("//   S_OK                        Successful.")
cpp_quote("//   E_INVALIDARG                ppTransport is NULL")
cpp_quote("//   E_OUTOFMEMORY               Memory allocation failure...")
cpp_quote("//   ")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("IMNXPORTAPI CreateRASTransport(")
cpp_quote("                  /* out */     __deref_out IRASTransport **ppTransport);")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("//   CreateNNTPTransport")
cpp_quote("//   ")
cpp_quote("//   Description:")
cpp_quote("//   This method creates a INNTPTransport object. The client must initialize the")
cpp_quote("//   object by calling INNTPTransport::InitNew")
cpp_quote("//   ")
cpp_quote("//   Parameters:")
cpp_quote("//   ppTransport                 Upon successful return, contains the a pointer to")
cpp_quote("//                               an INNTPTransport interface")
cpp_quote("//   ")
cpp_quote("//   Return Values:")
cpp_quote("//   S_OK                        Successful.")
cpp_quote("//   E_INVALIDARG                ppTransport is NULL")
cpp_quote("//   E_OUTOFMEMORY               Memory allocation failure...")
cpp_quote("//   ")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("IMNXPORTAPI CreateNNTPTransport(")
cpp_quote("                  /* out */     __deref_out INNTPTransport **ppTransport);")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("//   CreateSMTPTransport")
cpp_quote("//   ")
cpp_quote("//   Description:")
cpp_quote("//   This method creates a ISMTPTransport object. The client must initialize the")
cpp_quote("//   object by calling ISMTPTransport::InitNew")
cpp_quote("//   ")
cpp_quote("//   Parameters:")
cpp_quote("//   ppTransport                 Upon successful return, contains the a pointer to")
cpp_quote("//                               an ISMTPTransport interface")
cpp_quote("//   ")
cpp_quote("//   Return Values:")
cpp_quote("//   S_OK                        Successful.")
cpp_quote("//   E_INVALIDARG                ppTransport is NULL")
cpp_quote("//   E_OUTOFMEMORY               Memory allocation failure...")
cpp_quote("//   ")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("IMNXPORTAPI CreateSMTPTransport(")
cpp_quote("                  /* out */     __deref_out ISMTPTransport **ppTransport);")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("//   CreatePOP3Transport")
cpp_quote("//   ")
cpp_quote("//   Description:")
cpp_quote("//   This method creates a IPOP3Transport object. The client must initialize the")
cpp_quote("//   object by calling IPOP3Transport::InitNew")
cpp_quote("//   ")
cpp_quote("//   Parameters:")
cpp_quote("//   ppTransport                 Upon successful return, contains the a pointer to")
cpp_quote("//                               an IPOP3Transport interface")
cpp_quote("//   ")
cpp_quote("//   Return Values:")
cpp_quote("//   S_OK                        Successful.")
cpp_quote("//   E_INVALIDARG                ppTransport is NULL")
cpp_quote("//   E_OUTOFMEMORY               Memory allocation failure...")
cpp_quote("//   ")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("IMNXPORTAPI CreatePOP3Transport(")
cpp_quote("                  /* out */     __deref_out IPOP3Transport **ppTransport);")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("//   CreateIMAPTransport")
cpp_quote("//   ")
cpp_quote("//   Description:")
cpp_quote("//   This method creates a IIMAPTransport object. The client must initialize the")
cpp_quote("//   object by calling IIMAPTransport::InitNew")
cpp_quote("//   ")
cpp_quote("//   Parameters:")
cpp_quote("//   ppTransport                 Upon successful return, contains the a pointer to")
cpp_quote("//                               an IIMAPTransport interface")
cpp_quote("//   ")
cpp_quote("//   Return Values:")
cpp_quote("//   S_OK                        Successful.")
cpp_quote("//   E_INVALIDARG                ppTransport is NULL")
cpp_quote("//   E_OUTOFMEMORY               Memory allocation failure...")
cpp_quote("//   ")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("IMNXPORTAPI CreateIMAPTransport(")
cpp_quote("                  /* out */     __deref_out IIMAPTransport **ppTransport);")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("//   CreateIMAPTransport2")
cpp_quote("//   ")
cpp_quote("//   Description:")
cpp_quote("//   This method creates an IIMAPTransport2 object. The client must initialize the")
cpp_quote("//   object by calling IIMAPTransport2::InitNew")
cpp_quote("//   ")
cpp_quote("//   Parameters:")
cpp_quote("//   ppTransport                 Upon successful return, contains the a pointer to")
cpp_quote("//                               an IIMAPTransport2 interface")
cpp_quote("//   ")
cpp_quote("//   Return Values:")
cpp_quote("//   S_OK                        Successful.")
cpp_quote("//   E_INVALIDARG                ppTransport is NULL")
cpp_quote("//   E_OUTOFMEMORY               Memory allocation failure...")
cpp_quote("//   ")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("IMNXPORTAPI CreateIMAPTransport2(")
cpp_quote("                  /* out */     __deref_out IIMAPTransport2 **ppTransport);")
cpp_quote("")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("//   CreateRangeList")
cpp_quote("//   ")
cpp_quote("//   Description:")
cpp_quote("//   This method creates a IRangeList object.")
cpp_quote("//   ")
cpp_quote("//   Parameters:")
cpp_quote("//   ppRangeList                 Upon successful return, contains the a pointer to")
cpp_quote("//                               an IRangeList interface")
cpp_quote("//   ")
cpp_quote("//   Return Values:")
cpp_quote("//   S_OK                        Successful.")
cpp_quote("//   E_INVALIDARG                ppRangeList is NULL")
cpp_quote("//   E_OUTOFMEMORY               Memory allocation failure...")
cpp_quote("//   ")
cpp_quote("// --------------------------------------------------------------------------------")
cpp_quote("IMNXPORTAPI CreateRangeList(")
cpp_quote("                  /* out */     __deref_out IRangeList **ppRangeList);")
cpp_quote("")
cpp_quote("#ifdef __cplusplus")
cpp_quote("}")
cpp_quote("#endif")
cpp_quote("")

