#ifndef _MAPISPI_H
#define _MAPISPI_H

/* Messaging Applications Programming Interface (MAPI) definitions */

#ifndef _MAPIDEFS_H
#include <mapidefs.h>
#endif
#ifndef _MAPICODE_H
#include <mapicode.h>
#endif
#ifndef _MAPIGUID_H
#include <mapiguid.h>
#endif
#ifndef _MAPITAGS_H
#include <mapitags.h>
#endif

#ifndef BEGIN_INTERFACE
#define BEGIN_INTERFACE
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define CURRENT_SPI_VERSION  0x00010010L

#define PDK1_SPI_VERSION  0x00010000L
#define PDK2_SPI_VERSION  0x00010008L
#define PDK3_SPI_VERSION  0x00010010L

DECLARE_MAPI_INTERFACE_PTR(IMAPISupport,LPMAPISUP);

typedef struct {
    ULONG cb;
    BYTE ab[MAPI_DIM];
} NOTIFKEY, *LPNOTIFKEY;

#define CbNewNOTIFKEY(_cb)  (offsetof(NOTIFKEY,ab) + (_cb))
#define CbNOTIFKEY(_lpkey)  (offsetof(NOTIFKEY,ab) + (_lpkey)->cb)
#define SizedNOTIFKEY(_cb,_name)  struct _NOTIFKEY_ ## _name { ULONG cb; BYTE ab[_cb]; } _name

#define NOTIFY_SYNC  ((ULONG)0x40000000)
#define NOTIFY_CANCELED  ((ULONG)0x80000000)

#define CALLBACK_DISCONTINUE  ((ULONG)0x80000000)

#define NOTIFY_NEWMAIL  ((ULONG)0x00000001)
#define NOTIFY_READYTOSEND  ((ULONG)0x00000002)
#define NOTIFY_SENTDEFERRED  ((ULONG)0x00000004)
#define NOTIFY_CRITSEC  ((ULONG)0x00001000)
#define NOTIFY_NONCRIT  ((ULONG)0x00002000)
#define NOTIFY_CONFIG_CHANGE  ((ULONG)0x00004000)
#define NOTIFY_CRITICAL_ERROR  ((ULONG)0x10000000)
#define NOTIFY_NEWMAIL_RECEIVED ((ULONG)0x20000000)

#define STATUSROW_UPDATE  ((ULONG)0x10000000)

#define STGSTRM_RESET  ((ULONG)0x00000000)
#define STGSTRM_CURRENT  ((ULONG)0x10000000)
#define STGSTRM_MODIFY  ((ULONG)0x00000002)
#define STGSTRM_CREATE  ((ULONG)0x00001000)

#define MAPI_NON_READ  ((ULONG)0x00000001)

typedef HRESULT (STDMETHODCALLTYPE PREPROCESSMESSAGE)(LPVOID,LPMESSAGE,LPADRBOOK,LPMAPIFOLDER,LPALLOCATEBUFFER,LPALLOCATEMORE,LPFREEBUFFER,ULONG*,LPMESSAGE**,LPADRLIST*);
typedef HRESULT (STDMETHODCALLTYPE REMOVEPREPROCESSINFO)(LPMESSAGE lpMessage);

#define MAPI_IMAPISUPPORT_METHODS1(IPURE) \
    MAPIMETHOD(GetLastError)(THIS_ HRESULT,ULONG,LPMAPIERROR*) IPURE; \
    MAPIMETHOD(GetMemAllocRoutines)(THIS_ LPALLOCATEBUFFER*,LPALLOCATEMORE*,LPFREEBUFFER*) IPURE; \
    MAPIMETHOD(Subscribe)(THIS_ LPNOTIFKEY,ULONG,ULONG,LPMAPIADVISESINK,ULONG*) IPURE; \
    MAPIMETHOD(Unsubscribe)(THIS_ ULONG) IPURE; \
    MAPIMETHOD(Notify)(THIS_ LPNOTIFKEY,ULONG,LPNOTIFICATION,ULONG*) IPURE; \
    MAPIMETHOD(ModifyStatusRow)(THIS_ ULONG,LPSPropValue,ULONG) IPURE; \
    MAPIMETHOD(OpenProfileSection)(THIS_ LPMAPIUID,ULONG,LPPROFSECT*) IPURE; \
    MAPIMETHOD(RegisterPreprocessor)(THIS_ LPMAPIUID,LPTSTR,LPTSTR,LPSTR,LPSTR,ULONG) IPURE; \
    MAPIMETHOD(NewUID)(THIS_ LPMAPIUID) IPURE; \
    MAPIMETHOD(MakeInvalid)(THIS_ ULONG,LPVOID,ULONG,ULONG) IPURE;

#define MAPI_IMAPISUPPORT_METHODS2(IPURE) \
    MAPIMETHOD(SpoolerYield)(THIS_ ULONG) IPURE; \
    MAPIMETHOD(SpoolerNotify)(THIS_ ULONG,LPVOID) IPURE; \
    MAPIMETHOD(CreateOneOff)(THIS_ LPTSTR,LPTSTR,LPTSTR,ULONG,ULONG*,LPENTRYID*) IPURE; \
    MAPIMETHOD(SetProviderUID)(THIS_ LPMAPIUID,ULONG) IPURE; \
    MAPIMETHOD(CompareEntryIDs)(THIS_ ULONG,LPENTRYID,ULONG,LPENTRYID,ULONG,ULONG*) IPURE; \
    MAPIMETHOD(OpenTemplateID)(THIS_ ULONG,LPENTRYID,ULONG,LPMAPIPROP,LPCIID,LPMAPIPROP*,LPMAPIPROP) IPURE; \
    MAPIMETHOD(OpenEntry)(THIS_ ULONG,LPENTRYID,LPCIID,ULONG,ULONG*,LPUNKNOWN*) IPURE; \
    MAPIMETHOD(GetOneOffTable)(THIS_ ULONG,LPMAPITABLE*) IPURE; \
    MAPIMETHOD(Address)(THIS_ ULONG*,LPADRPARM,LPADRLIST*) IPURE; \
    MAPIMETHOD(Details)(THIS_ ULONG*,LPFNDISMISS,LPVOID,ULONG,LPENTRYID,LPFNBUTTON,LPVOID,LPTSTR,ULONG) IPURE; \
    MAPIMETHOD(NewEntry)(THIS_ ULONG,ULONG,ULONG,LPENTRYID,ULONG,LPENTRYID,ULONG*,LPENTRYID*) IPURE; \
    MAPIMETHOD(DoConfigPropsheet)(THIS_ ULONG,ULONG,LPTSTR,LPMAPITABLE,LPMAPIPROP,ULONG) IPURE; \
    MAPIMETHOD(CopyMessages)(THIS_ LPCIID,LPVOID,LPENTRYLIST,LPCIID,LPVOID,ULONG,LPMAPIPROGRESS,ULONG) IPURE; \
    MAPIMETHOD(CopyFolder)(THIS_ LPCIID,LPVOID,ULONG,LPENTRYID,LPCIID,LPVOID,LPTSTR,ULONG,LPMAPIPROGRESS,ULONG) IPURE;

#define MAPI_IMAPISUPPORT_METHODS3(IPURE) \
    MAPIMETHOD(DoCopyTo)(THIS_ LPCIID,LPVOID,ULONG,LPCIID,LPSPropTagArray,ULONG,LPMAPIPROGRESS,LPCIID,LPVOID,ULONG,LPSPropProblemArray*) IPURE; \
    MAPIMETHOD(DoCopyProps)(THIS_ LPCIID,LPVOID,LPSPropTagArray,ULONG,LPMAPIPROGRESS,LPCIID,LPVOID,ULONG,LPSPropProblemArray*) IPURE; \
    MAPIMETHOD(DoProgressDialog)(THIS_ ULONG,ULONG,LPMAPIPROGRESS*) IPURE; \
    MAPIMETHOD(ReadReceipt)(THIS_ ULONG,LPMESSAGE,LPMESSAGE*) IPURE; \
    MAPIMETHOD(PrepareSubmit)(THIS_ LPMESSAGE,ULONG*) IPURE; \
    MAPIMETHOD(ExpandRecips)(THIS_ LPMESSAGE,ULONG*) IPURE; \
    MAPIMETHOD(UpdatePAB)(THIS_ ULONG,LPMESSAGE) IPURE; \
    MAPIMETHOD(DoSentMail)(THIS_ ULONG,LPMESSAGE) IPURE; \
    MAPIMETHOD(OpenAddressBook)(THIS_ LPCIID,ULONG,LPADRBOOK*) IPURE; \
    MAPIMETHOD(Preprocess)(THIS_ ULONG,ULONG,LPENTRYID) IPURE; \
    MAPIMETHOD(CompleteMsg)(THIS_ ULONG,ULONG,LPENTRYID) IPURE; \
    MAPIMETHOD(StoreLogoffTransports)(THIS_ ULONG*) IPURE; \
    MAPIMETHOD(StatusRecips)(THIS_ LPMESSAGE,LPADRLIST) IPURE; \
    MAPIMETHOD(WrapStoreEntryID)(THIS_ ULONG,LPENTRYID,ULONG*,LPENTRYID*) IPURE; \
    MAPIMETHOD(ModifyProfile)(THIS_ ULONG) IPURE; \
    MAPIMETHOD(IStorageFromStream)(THIS_ LPUNKNOWN,LPCIID,ULONG,LPSTORAGE*) IPURE; \
    MAPIMETHOD(GetSvcConfigSupportObj)(THIS_ ULONG,LPMAPISUP*) IPURE;

#undef INTERFACE
#define INTERFACE IMAPISupport
DECLARE_MAPI_INTERFACE_(IMAPISupport,IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IMAPISUPPORT_METHODS1(PURE)
    MAPI_IMAPISUPPORT_METHODS2(PURE)
    MAPI_IMAPISUPPORT_METHODS3(PURE)
};

#define FILL_ENTRY  ((ULONG)0x00000001)

DECLARE_MAPI_INTERFACE_PTR(IABProvider,LPABPROVIDER);
DECLARE_MAPI_INTERFACE_PTR(IABLogon,LPABLOGON);

#define MAPI_IABPROVIDER_METHODS(IPURE) \
    MAPIMETHOD(Shutdown)(THIS_ ULONG*) IPURE; \
    MAPIMETHOD(Logon)(THIS_ LPMAPISUP,ULONG,LPTSTR,ULONG,ULONG*,LPBYTE*,LPMAPIERROR*,LPABLOGON*) IPURE;

#undef INTERFACE
#define INTERFACE IABProvider
DECLARE_MAPI_INTERFACE_(IABProvider,IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IABPROVIDER_METHODS(PURE)
};

#define MAPI_IABLOGON_METHODS(IPURE) \
    MAPIMETHOD(GetLastError)(THIS_ HRESULT,ULONG,LPMAPIERROR*) IPURE; \
    MAPIMETHOD(Logoff)(THIS_ ULONG) IPURE; \
    MAPIMETHOD(OpenEntry)(THIS_ ULONG,LPENTRYID,LPCIID,ULONG,ULONG*,LPUNKNOWN*) IPURE; \
    MAPIMETHOD(CompareEntryIDs)(THIS_ ULONG,LPENTRYID,ULONG,LPENTRYID,ULONG,ULONG*) IPURE; \
    MAPIMETHOD(Advise)(THIS_ ULONG,LPENTRYID,ULONG,LPMAPIADVISESINK,ULONG*) IPURE; \
    MAPIMETHOD(Unadvise)(THIS_ ULONG) IPURE; \
    MAPIMETHOD(OpenStatusEntry)(THIS_ LPCIID,ULONG,ULONG*,LPMAPISTATUS*) IPURE; \
    MAPIMETHOD(OpenTemplateID)(THIS_ ULONG,LPENTRYID,ULONG,LPMAPIPROP,LPCIID,LPMAPIPROP*,LPMAPIPROP) IPURE; \
    MAPIMETHOD(GetOneOffTable)(THIS_ ULONG,LPMAPITABLE*) IPURE; \
    MAPIMETHOD(PrepareRecips)(THIS_ ULONG,LPSPropTagArray,LPADRLIST) IPURE;

#undef INTERFACE
#define INTERFACE IABLogon
DECLARE_MAPI_INTERFACE_(IABLogon,IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IABLOGON_METHODS(PURE)
};

typedef HRESULT (STDMAPIINITCALLTYPE ABPROVIDERINIT)(HINSTANCE,LPMALLOC,LPALLOCATEBUFFER,LPALLOCATEMORE,LPFREEBUFFER,ULONG,ULONG,ULONG*,LPABPROVIDER*);
ABPROVIDERINIT ABProviderInit;

#define DEINIT_NORMAL  ((ULONG)0x00000001)
#define DEINIT_HURRY  ((ULONG)0x80000000)

#define LOGON_NO_DIALOG  ((ULONG)0x00000001)
#define LOGON_NO_CONNECT  ((ULONG)0x00000004)
#define LOGON_NO_INBOUND  ((ULONG)0x00000008)
#define LOGON_NO_OUTBOUND  ((ULONG)0x00000010)

#define LOGON_SP_IDLE  ((ULONG)0x00010000)
#define LOGON_SP_POLL  ((ULONG)0x00020000)
#define LOGON_SP_RESOLVE  ((ULONG)0x00040000)

DECLARE_MAPI_INTERFACE_PTR(IXPProvider, LPXPPROVIDER);
DECLARE_MAPI_INTERFACE_PTR(IXPLogon, LPXPLOGON);

#define MAPI_IXPPROVIDER_METHODS(IPURE) \
    MAPIMETHOD(Shutdown)(THIS_ ULONG*) IPURE; \
    MAPIMETHOD(TransportLogon)(THIS_ LPMAPISUP,ULONG,LPTSTR,ULONG*,LPMAPIERROR*,LPXPLOGON*) IPURE;

#undef INTERFACE
#define INTERFACE IXPProvider
DECLARE_MAPI_INTERFACE_(IXPProvider,IUnknown)
{
    BEGIN_INTERFACE 
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IXPPROVIDER_METHODS(PURE)
};

#define OPTION_TYPE_RECIPIENT  ((ULONG)0x00000001)
#define OPTION_TYPE_MESSAGE  ((ULONG)0x00000002)

typedef struct _OPTIONDATA {
    ULONG ulFlags;
    LPGUID lpRecipGUID;
    LPTSTR lpszAdrType;
    LPTSTR lpszDLLName;
    ULONG ulOrdinal;
    ULONG cbOptionsData;
    LPBYTE lpbOptionsData;
    ULONG cOptionsProps;
    LPSPropValue lpOptionsProps;
} OPTIONDATA, *LPOPTIONDATA;

typedef SCODE (STDMAPIINITCALLTYPE OPTIONCALLBACK)(HINSTANCE,LPMALLOC,ULONG,ULONG,LPBYTE,LPMAPISUP,LPMAPIPROP,LPMAPIPROP*,LPMAPIERROR*);

#define NOTIFY_ABORT_DEFERRED  ((ULONG)0x40000000)
#define NOTIFY_CANCEL_MESSAGE  ((ULONG)0x80000000)
#define NOTIFY_BEGIN_INBOUND  ((ULONG)0x00000001)
#define NOTIFY_END_INBOUND  ((ULONG)0x00010000)
#define NOTIFY_BEGIN_OUTBOUND  ((ULONG)0x00000002)
#define NOTIFY_END_OUTBOUND  ((ULONG)0x00020000)
#define NOTIFY_BEGIN_INBOUND_FLUSH  ((ULONG)0x00000004)
#define NOTIFY_END_INBOUND_FLUSH  ((ULONG)0x00040000)
#define NOTIFY_BEGIN_OUTBOUND_FLUSH  ((ULONG)0x00000008)
#define NOTIFY_END_OUTBOUND_FLUSH  ((ULONG)0x00080000)

#define LOGOFF_NORMAL  ((ULONG)0x00000001)
#define LOGOFF_HURRY  ((ULONG)0x80000000)

#define BEGIN_DEFERRED  ((ULONG)0x00000001)

#define END_RESEND_NOW  ((ULONG)0x00010000)
#define END_RESEND_LATER  ((ULONG)0x00020000)
#define END_DONT_RESEND  ((ULONG)0x00040000)

#define MAPI_IXPLOGON_METHODS(IPURE) \
    MAPIMETHOD(AddressTypes)(THIS_ ULONG*,ULONG*,LPTSTR**,ULONG*,LPMAPIUID**) IPURE; \
    MAPIMETHOD(RegisterOptions)(THIS_ ULONG*,ULONG*,LPOPTIONDATA*) IPURE; \
    MAPIMETHOD(TransportNotify)(THIS_ ULONG*,LPVOID*) IPURE; \
    MAPIMETHOD(Idle)(THIS_ ULONG ulFlags) IPURE; \
    MAPIMETHOD(TransportLogoff)(THIS_ ULONG ulFlags) IPURE; \
    MAPIMETHOD(SubmitMessage)(THIS_ ULONG ulFlags,LPMESSAGE,ULONG*,ULONG*) IPURE; \
    MAPIMETHOD(EndMessage)(THIS_ ULONG,ULONG*) IPURE; \
    MAPIMETHOD(Poll)(THIS_ ULONG*) IPURE; \
    MAPIMETHOD(StartMessage)(THIS_ ULONG,LPMESSAGE,ULONG*) IPURE; \
    MAPIMETHOD(OpenStatusEntry)(THIS_ LPCIID,ULONG,ULONG*,LPMAPISTATUS*) IPURE; \
    MAPIMETHOD(ValidateState)(THIS_ ULONG,ULONG) IPURE; \
    MAPIMETHOD(FlushQueues)(THIS_ ULONG,ULONG,LPENTRYID,ULONG) IPURE;

#undef INTERFACE
#define INTERFACE IXPLogon
DECLARE_MAPI_INTERFACE_(IXPLogon,IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IXPLOGON_METHODS(PURE)
};

typedef HRESULT (STDMAPIINITCALLTYPE XPPROVIDERINIT)(HINSTANCE,LPMALLOC,LPALLOCATEBUFFER,LPALLOCATEMORE,LPFREEBUFFER,ULONG,ULONG,ULONG*,LPXPPROVIDER*);
XPPROVIDERINIT XPProviderInit;

#define LOGON_SP_TRANSPORT  ((ULONG)0x00000001)
#define LOGON_SP_PROMPT  ((ULONG)0x00000002)
#define LOGON_SP_NEWPW  ((ULONG)0x00000004)
#define LOGON_CHANGED  ((ULONG)0x00000008)

#define DIALOG_FOLDER  ((ULONG)0x00000001)
#define DIALOG_MESSAGE  ((ULONG)0x00000002)
#define DIALOG_PROP  ((ULONG)0x00000004)
#define DIALOG_ATTACH  ((ULONG)0x00000008)
#define DIALOG_MOVE  ((ULONG)0x00000010)
#define DIALOG_COPY  ((ULONG)0x00000020)
#define DIALOG_DELETE  ((ULONG)0x00000040)
#define DIALOG_ALLOW_CANCEL  ((ULONG)0x00000080)
#define DIALOG_CONFIRM_CANCEL  ((ULONG)0x00000100)

#define NEEDS_PREPROCESSING  ((ULONG)0x00000001)
#define NEEDS_SPOOLER  ((ULONG)0x00000002)

#define CHECK_SENDER  ((ULONG)0x00000001)
#define NON_STANDARD  ((ULONG)0x00010000)

DECLARE_MAPI_INTERFACE_PTR(IMSLogon, LPMSLOGON);
DECLARE_MAPI_INTERFACE_PTR(IMSProvider, LPMSPROVIDER);

#define MAPI_IMSPROVIDER_METHODS(IPURE) \
    MAPIMETHOD(Shutdown)(THIS_  ULONG*) IPURE; \
    MAPIMETHOD(Logon)(THIS_ LPMAPISUP,ULONG,LPTSTR,ULONG,LPENTRYID,ULONG,LPCIID,ULONG*,LPBYTE*,LPMAPIERROR*,LPMSLOGON*,LPMDB*) IPURE; \
    MAPIMETHOD(SpoolerLogon)(THIS_ LPMAPISUP,ULONG,LPTSTR,ULONG,LPENTRYID,ULONG,LPCIID,ULONG,LPBYTE,LPMAPIERROR*,LPMSLOGON*,LPMDB*) IPURE; \
    MAPIMETHOD(CompareStoreIDs)(THIS_ ULONG,LPENTRYID,ULONG,LPENTRYID,ULONG,ULONG*) IPURE;

#undef INTERFACE
#define INTERFACE IMSProvider
DECLARE_MAPI_INTERFACE_(IMSProvider,IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IMSPROVIDER_METHODS(PURE)
};

#define MAPI_IMSLOGON_METHODS(IPURE) \
    MAPIMETHOD(GetLastError)(THIS_ HRESULT,ULONG,LPMAPIERROR*) IPURE; \
    MAPIMETHOD(Logoff)(THIS_ ULONG*) IPURE; \
    MAPIMETHOD(OpenEntry)(THIS_ ULONG,LPENTRYID,LPCIID,ULONG,ULONG*,LPUNKNOWN*) IPURE; \
    MAPIMETHOD(CompareEntryIDs)(THIS_ ULONG,LPENTRYID,ULONG,LPENTRYID,ULONG,ULONG*) IPURE; \
    MAPIMETHOD(Advise)(THIS_ ULONG,LPENTRYID,ULONG,LPMAPIADVISESINK,ULONG*) IPURE; \
    MAPIMETHOD(Unadvise)(THIS_ ULONG) IPURE; \
    MAPIMETHOD(OpenStatusEntry)(THIS_ LPCIID,ULONG,ULONG*,LPVOID*) IPURE;

#undef INTERFACE
#define INTERFACE IMSLogon
DECLARE_MAPI_INTERFACE_(IMSLogon,IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IMSLOGON_METHODS(PURE)
};

typedef HRESULT (STDMAPIINITCALLTYPE MSPROVIDERINIT)(HINSTANCE,LPMALLOC,LPALLOCATEBUFFER,LPALLOCATEMORE,LPFREEBUFFER,ULONG,ULONG,ULONG*,LPMSPROVIDER*);
MSPROVIDERINIT MSProviderInit;

#define MSG_SERVICE_UI_READ_ONLY  0x00000008
#define SERVICE_LOGON_FAILED  0x00000020

#define MSG_SERVICE_INSTALL  0x00000001
#define MSG_SERVICE_CREATE  0x00000002
#define MSG_SERVICE_CONFIGURE  0x00000003
#define MSG_SERVICE_DELETE  0x00000004
#define MSG_SERVICE_UNINSTALL  0x00000005
#define MSG_SERVICE_PROVIDER_CREATE  0x00000006
#define MSG_SERVICE_PROVIDER_DELETE  0x00000007

typedef HRESULT (STDAPICALLTYPE MSGSERVICEENTRY)(HINSTANCE,LPMALLOC,LPMAPISUP,ULONG,ULONG,ULONG,ULONG,LPSPropValue,LPPROVIDERADMIN,LPMAPIERROR*);
typedef MSGSERVICEENTRY *LPMSGSERVICEENTRY;

#ifdef __cplusplus
}
#endif

#endif /* MAPISPI_H */
