Posted by Hal Bonnin on 2000-01-16
this is from the MSDN Library. had to convert it to plain text to post so
it wont read well :)
Developing a Hook Provider or Preprocessor
MAPI defines two types of extensions that it uses to allow custom code to be
inserted into the message transmission and reception processes-hook
providers and preprocessors. A hook provider, also called a spooler hook,
can be called after an outbound message reaches the transport providers and
before an inbound message is delivered to the default folder for its message
class. Preprocessors operate on outbound messages only and are called before
and after transport providers handle the message.
Since hook providers and preprocessors act during the message sending and
receiving processes, you should familiarize yourself with the roles that
other MAPI components play in these processes. Specifically, you should read
Sending Messages with MAPI, Service Provider Basics, Developing a Transport
Provider, and Developing a Message Store Provider. You do not need to learn
the material in these sections in any great detail in order to implement a
hook provider or preprocessor, but you should have a basic understanding of
the way these components interact to send and receive messages.
There are several things to consider when choosing whether to use a hook
provider or a preprocessor to implement your custom code:
Whether your component needs to be able to operate on inbound messages. If
it needs to act on inbound messages, you must use a hook provider, since
preprocessors are not called for inbound messages.
Whether your component needs to operate before or after transport providers
for outbound messages. Preprocessors are called before transport providers,
hook providers are called after.
What your component needs to do. Preprocessors are typically used to modify
a message's contents or recipient list before sending. For example, a
preprocessor can be used to automatically add a signature to outgoing
messages. Hook providers are typically used to archive messages or automatic
ally file them in different folders; that is, to manipulate the relationship
between the message and its message store although they can also modify a
message's content. Hook providers cannot, however, modify a message's
recipients. Only preprocessors can cause a message to be sent to different
recipients than those entered by the user sending the message.
Ease of implementation. Hook providers are actual MAPI service providers,
albeit simple ones, and must follow the guidelines for service providers.
However, preprocessors have to be registered by means of a transport
provider. If you also happen to have a transport provider that you can
modify to register the preprocessor, then creating a preprocessor is
probably easier than creating a hook provider. If not, you will have to
create a minimal transport provider whose sole job is to register the
preprocessor.
For an overview of the process of creating hook providers and preprocessors,
see Using Message Filtering to Manage Messages.
Using Message Filtering to Manage Messages
The MAPI spooler makes calls to two different types of extensions by which
code can be inserted in the message transmission process. These extensions -
known as preprocessors and spooler hooks - can be used for a wide variety of
purposes including altering the recipient list or content of an outbound
message, archiving outbound messages in local storage or on a central
server, directing inbound messages to a particular folder based on arbitrary
criteria, and responding automatically to inbound messages.
Design Tasks
Decide whether to use a preprocessor or a spooler hook.
A preprocessor is called for outbound messages only. It may choose to be
called for all messages, or for messages that have recipients of a
particular type. Those recipients can be selected based on the address type
(PR_ADDRTYPE), on the MAPIUID which qualifies the recipient's entry
identifier, or both. See IMAPISupport::RegisterPreprocessor.
A preprocessor can create new messages based on the input message, returning
them through its lpppMessage parameter. In no case should the input message
be placed in the lpppMessage parameter. If a preprocessor does not want the
input message to be sent, it should delete all the recipients and set the
PR_DELETE_AFTER_SUBMIT property; the input message should not be deleted
using message store calls.
A spooler hook may choose to be called for all inbound messages, all
outbound messages, or both, by setting the HOOK_INBOUND flag, the
HOOK_OUTBOUND flag, or both in its PR_RESOURCE_FLAGS property on the
provider profile section in MAPISVC.INF. See File Format of MAPISVC.INF.
To delete an inbound or outbound message, a hook should set the HOOK_DELETE
flag in its lpulFlags parameter. It should not use message store calls to
delete the message presented to it through its interface; it may use message
store calls to create, modify, or delete other messages. A hook can prevent
processing of a message by other hooks, including the default hook that
processes receive folder settings, by setting the HOOK_CANCEL flag in
lpulFlags.
When working with a tightly coupled message store and transport, the store
itself can transmit a message that is not destined for any spooler-based
transports. Whether preprocessors and hooks are called in this situation
depends upon the message store implementation. Microsoft Exchange Server,
for example, calls preprocessors on outbound messages but does not call
either inbound or outbound spooler hooks. See Sending Messages with MAPI.
On an outbound message, hooks and preprocessors participate in a complicated
sequence of events. The following steps involve hooks and preprocessors.
a. The PreprocessMessage entry point of each preprocessor is called
before any transport provider handles the message. It can update the
recipient list, alter message content, or even create additional messages.
The order in which preprocessors are called is the same as the order in
which the transports that registered them are called to handle outbound
messages. See Creating and Configuring a Profile.
b. Transport providers are called to transmit the message. If any
transport defers message processing, no hooks are called until the deferred
processing is complete.
c. The RemovePreprocessInfo entry point of each preprocessor is
called after all transports have handled the message.
d. The ISpoolerHook::OutboundMsgHook method is called for each hook
that sets the HOOK_OUTBOUND flag in the PR_RESOURCE_FLAGS property. The
order in which hooks are called is the same as the order in which they were
installed in the profile; it does not follow the transport order because a
hook does not necessarily have an associated transport provider.
For inbound messages, preprocessors are not called. Hooks are called as
follows:
a. The receiving transport provider completes its work.
b. The ISpoolerHook::InboundMsgHook method is called for each hook
that sets the HOOK_INBOUND flag in the PR_RESOURCE_FLAGS property. The order
in which hooks are called is the same as the order in which they were
installed in the profile; it does not follow the transport order because a
hook does not have an associated transport provider.
c. For inbound messages, the receive folder assignment is honored
only if a hook has not moved the message to another folder. Conceptually,
the MAPI spooler implements an internal hook which is always called last and
only if no previous hook returns the HOOK_CANCEL flag; it finds the receive
folder based on the message's PR_MESSAGE_CLASS property and places the
message in that folder. See IMsgStore::GetReceiveFolder.
Define configuration parameters and understand how your hook or preprocessor
is to be installed. A spooler hook is a distinct service provider type and
is added to the user's profile as part of a message service, either alone or
together with other related service providers. Any configuration parameters
are normally stored in the profile and edited using the property pages for
the message service. A preprocessor is not a distinct service provider type;
it must be registered by a transport provider. If necessary, a minimal
transport provider can be created for this purpose alone.
Implementation Tasks
To implement a preprocessor
Create a DLL containing the PreprocessMessage and RemovePreprocessInfo entry
points. It is strongly recommended, though not required, that all the code
and entry points listed here be implemented in the same DLL; this minimizes
the delay in loading MAPI applications.
Call the IMAPISupport::RegisterPreprocessor method in a transport provider.
Create a transport provider entry point, and the remainder of a minimal
transport, if there is no existing transport. The minimal transport should
initialize as recommended in the topic Required Functionality for Transport
Providers. In response to the IXPLogon::AddressTypes call, the transport
provider should return a single zero-length string in lpppszAdrTypeArray and
NULL in lpppUIDArray.
Create a MAPISVC.INF fragment for the transport provider and the message
service that contains it. See Implementing a Message Service.
Optionally, but strongly recommended, create a message service entry point
for configuration. See Implementing a Service Provider Entry Point Function.
Optionally, create an online Help file linked to your configuration property
pages, wizard pages, or both, providing full details about all configuration
options.
Optionally, create a header file for custom programmatic configuration by
MAPI clients.
Optionally, create a service wizard entry point for interactive
configuration by users. See Supporting Message Service Configuration and
WIZARDENTRY.
Optionally, create a .PRF file detailing configuration properties for the
message service. See Creating a Profile with NEWPROF.
To implement a spooler hook
Create a DLL containing the HPProviderInit entry point. It is strongly
recommended, though not required, that all the code and entry points listed
here be implemented in the same DLL; this minimizes the delay in loading
MAPI applications. See Implementing a Service Provider Entry Point Function.
Create a MAPISVC.INF fragment for the hook provider and the message service
that contains it. See Implementing a Message Service.
Optionally, but strongly recommended, create a message service entry point
for configuration. See Implementing a Service Provider Entry Point Function.
Optionally, create a header file for custom programmatic configuration by
MAPI clients.
Optionally, create a service wizard entry point for interactive
configuration by users. See Supporting Message Service Configuration and
WIZARDENTRY.
Optionally, create an online Help file linked to your configuration property
pages, wizard pages, or both, providing full details about all configuration
options.
Optionally, create a .PRF file detailing configuration properties for the
message service. See Creating a Profile with NEWPROF.
About Sample Source Code
See the following topics:
Sample Transport Provider
Sample Messaging Hook Provider
Previous post | Next post | Timeline | Home