/* Microsoft Exchange. Copyright 1986 - 1998, Microsoft Corporation -
   All Rights Reserved */

/*
 * E X C H C L I . H
 * Client-side Exchange programmability interfaces
 *
 * This file contains interfaces to the following Exchange features:
 *	Enterprise-wide forms registry
 *	Conflict resolution interfaces for forms
 *	Custom actions on inbox management rules
 *
 * Information in this document is subject to change without notice and does
 * not represent a commitment on the part of Microsoft Corporation.
 */

#ifndef _EXCHCLI_H_
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
#define _EXCHCLI_H_


/* Parameter to IMAPIFormMgr::OpenFormContainer
   denoting the Exchange Enterprise Forms Registry */

#if defined(HFRMREG_DEFAULT)
#define HFRMREG_ENTERPRISE 4
#endif


/* The GUID for Exchange's form extension properties. */

#if !defined(INITGUID) || defined(USES_GUID_ExchangeFormExts)
DEFINE_GUID (
	GUID_ExchangeFormExts,
	0x77f69534, 0x6b7d, 0x101b, 0x9f, 0x0d, 0x00, 0xaa, 0x00, 0x3b, 0xa9, 0x05);
#endif
#define IDFEXT_ExchangeResolvesConflict 0


/*
	Interfaces for "custom actions," the client rule extensions.

	Exchange rules are evaluated against each message on the server,
	where matches result in the server executing one or more actions
	against the message.  For purposes of performance and robustness
	the server offers a fixed set of actions.
	However, some actions must necessarily execute on a client machine.
	To allow this, the server encodes the desired action in a message
	(known as a DAM, or Deferred Action Message), then waits for a client
	to open the mailbox and process these client-side action requests.
	Client side actions include popup alerts, cross-store moves and copies,
	and CUSTOM ACTIONS.

	Custom actions are the sole rule extensibility mechanism available
	to clients.  A user installs a DLL containing a custom action on
	his workstation, then writes a rule naming this DLL as its action.
	When the server finds a match for the rule, it generates a DAM
	specifying the action named.  Subsequently the client reads the DAM
	and executes the action by invoking the proper DLL.

	A custom action DLL very much resembles a Capone super-extension in
    its gross structure.  One installs it on 16 bit platforms by creating
    a section [Custom Actions] in exchng.ini, there adding a key
    "tag=4.0;DLL;ordinal" just as for a superextension.  On 32 bit platforms
    the custom action is specified in the Registry as a name/value pair
    under the registry key:

    \\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Custom Actions

    The name/value pair is identical to that used on the 16 bit platform,
    where the 'name' is the 'tag' mentioned above, and the value is the
    DLL entry point information in the form: "4.0;DLL;ordinal".

    The tag should be suitable for display, as the Inbox Assistant will
    use it to represent the custom action for selection in its UI.  DLL
    should contain a fully qualified path to the DLL.  Ordinal is an
    integer denoting the ordinal of the extension entry point; it defaults
    to 1.

	That entry point is of type LPFNEXCHANGERULEEXTENTRY: it must allocate
	and return an instance of an IUnknown, off of which the Exchange
	client will QueryInterface the IExchangeRulesExt interface.  All
	subsequent calls will take place through this returned interface.
	Hence a custom action may easily reside in the same DLL as a super
	extension.

	Some methods of IExchangeRuleExt are passed an instance of the
	interface IExchangeRuleExtCallback.  This will return the extension
	information about the running Exchange client, including its MAPI
	session (off of which the extension may make calls) and a window
	handle (off of which to parent UI of its own).

	After the initial sequence of IUnknown methods, Exchange will
	invoke IExchangeRuleExt::Install.  This informs the extension into which
	context it is being invoked: either ERCONTEXT_INFO, that of the
	Inbox Assistant dialog, in which case it will be called upon to
	get new commands and translate existing commands; or else ERCONTEXT_EXEC,
	that of the client rule execution engine, in which case it will be
	called upon to execute the actual extension commands on a message.
	Return S_FALSE to abort installation or further processing.

		HRESULT IExchangeRuleExt::Install(
			LPEXCHANGERULEEXTCALLBACK percb,
				- an instance of IExchangeRuleExtCallback
			ULONG ulContext
				- one of ERCONTEXT_INFO or ERCONTEXT_EXEC
			)

    The QueryRelease() method is reserved for future use.  For now all rule
    extensions should return S_OK in response to a call on this method.

		HRESULT IExchangeRuleExt::QueryRelease()

	When a user selects the extension's tag from the Inbox Assistant,
	that extension is queried via IExchangeRuleExt::GetCommand for the
	command encoding it wishes to use.  This is an opportunity for it
	to present further UI refining the user's selection or specifying
	options if necessary.  The extension should return both an
	encoding of the command and a display string suitably representing
	the command to the user.  Return S_OK or S_FALSE as per the user's
	Ok or Cancel to any secondary UI.

		HRESULT IExchangeRuleExt::GetCommand(
			LPEXCHANGERULEEXTCALLBACK percb,
				- an instance of IExchangeRuleExtCallback
			TCHAR FAR* pszCommand, ULONG cchCommand,
                - an IN/OUT buffer in which to return the encoded command,
                  the buffer may be pre-initialized with a previously
                  existing command for this provider.
				  together with the length of the buffer given
			TCHAR FAR* pszDisplayName, ULONG cchDisplayName
                - IN/OUT, as the previous buffer, but for the display string
			)

	When the Inbox Assistant is invoked to edit an existing rule which
	specifies a custom action, it queries the appropriate extension
	via IExchangeRuleExt::QueryCommandDisplayName for the display string
	corresponding to the encoded command.  This should match the
	display string originally returned from GetCommand.  (Note that
	Exchange does not save the display string when saving the rule.)

		HRESULT IExchangeRuleExt::QueryCommandDisplayName(
			LPEXCHANGERULEEXTCALLBACK percb,
				- an instance of IExchangeRuleExtCallback
			LPCTSTR pszCommand,
				- the encoded command for which we want the display string
			TCHAR FAR* pszDisplayName, ULONG cchDisplayName
				- a buffer in which to return the display string,
				  together with the length of the buffer given
			)

	At the time that Exchange processes client-side rule actions, any
	custom actions invoked will result in their extensions receiving
	IExchangeRuleExt::Command calls.

		HRESULT IExchangeRuleExt::Command(
			LPEXCHANGERULEEXTCALLBACK percb,
				- an instance of IExchangeRuleExtCallback
			LPCTSTR pszCommand,
				- the encoded command to execute
			ULONG cb, LPENTRYID peid
				- the entryid of the message on which to execute
			)

*/

/* Extensibility contexts used with IExchangeRuleExt::Install */

#define ERCONTEXT_INFO (0x00000001)
#define ERCONTEXT_EXEC (0x00000002)


#undef INTERFACE
#define INTERFACE   IExchangeRuleExtCallback

DECLARE_INTERFACE_(IExchangeRuleExtCallback, IUnknown)
{
	BEGIN_INTERFACE
    /* IUnknown methods */
    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* lppvObj) PURE;
    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
    STDMETHOD_(ULONG,Release) (THIS) PURE;

	/* IExchangeRuleExtCallback methods */
	STDMETHOD(GetVersion) (THIS_ ULONG FAR* pulVersion, ULONG ulFlags) PURE;
    STDMETHOD(GetWindow) (THIS_ HWND FAR* phwnd) PURE;
    STDMETHOD(GetSession) (THIS_ LPMAPISESSION FAR* ppses) PURE;
};
typedef IExchangeRuleExtCallback FAR * LPEXCHANGERULEEXTCALLBACK;

#undef INTERFACE
#define INTERFACE   IExchangeRuleExt

DECLARE_INTERFACE_(IExchangeRuleExt, IUnknown)
{
    /* IUnknown methods */
    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * lppvObj) PURE;
    STDMETHOD_(ULONG,AddRef) (THIS) PURE;
    STDMETHOD_(ULONG,Release) (THIS) PURE;

    /* IExchangeRuleExt methods */
    STDMETHOD(Install) (THIS_
    	LPEXCHANGERULEEXTCALLBACK percb, ULONG ulContext) PURE;
    STDMETHOD(QueryRelease) (THIS) PURE;

	STDMETHOD(GetCommand)(THIS_
		LPEXCHANGERULEEXTCALLBACK percb,
		TCHAR FAR* pszCommand, ULONG cchCommand,
		TCHAR FAR* pszDisplayName, ULONG cchDisplayName) PURE;
	STDMETHOD(QueryCommandDisplayName) (THIS_
		LPEXCHANGERULEEXTCALLBACK percb,
		LPCTSTR pszCommand,
		TCHAR FAR* pszDisplayName, ULONG cchDisplayName) PURE;

	STDMETHOD(Command) (THIS_
		LPEXCHANGERULEEXTCALLBACK percb,
		LPCTSTR pszCommand,
		ULONG cb, LPENTRYID peid ) PURE;
};
typedef IExchangeRuleExt FAR* LPEXCHANGERULEEXT;


/* Type of function called by rules to load a provider */
typedef LPUNKNOWN (CALLBACK * LPFNEXCHANGERULEEXTENTRY)(VOID);

#define DEFINE_RULEEXTGUID(name, b) \
    DEFINE_GUID(name, 0x00020E00 | (b), 0, 0, 0xC0,0,0,0,0,0,0,0x46)

DEFINE_RULEEXTGUID(IID_IExchangeRuleExtCallback,			0x10);
DEFINE_RULEEXTGUID(IID_IExchangeRuleExt,					0x11);

#pragma option pop /*P_O_Pop*/
#endif /* end of file exchcli.h */
