2495 lines
108 KiB
C++
2495 lines
108 KiB
C++
|
||
#ifndef _SERVERDLL_INC
|
||
#define _SERVERDLL_INC
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/***************************************************************************
|
||
|
||
Name : lmi.h
|
||
|
||
Comment : Defines the Logical Modem Interface.
|
||
|
||
Created : 9/9/93
|
||
|
||
Author : Sharad Mathur
|
||
|
||
Contribs :
|
||
|
||
Changes : 12/29/93: Changed UINTS to WORDS
|
||
12/29/93: Put min length restriction on String in LMI_AddModem
|
||
12/29/93: Changed display string comments to remove "Fax Modem
|
||
on"
|
||
12/29/93: Changed NetAuthenticateDll API
|
||
8/4/94 : Defined FAXERROR
|
||
8/4/94 : Changed capabilities to bits & added new ones
|
||
8/4/94 : Changed SERVERSTATE to be a bitfield
|
||
8/4/94 : Changed NetReportRecv & LMI_ReportSends to return
|
||
DWORD
|
||
counts.
|
||
8/4/94 : Changed enum's to #define's
|
||
8/4/94 : Changed LPSTR to LPTSTR, & added fUnicode.
|
||
9/23/94 : Added Poll request support -
|
||
LMIPOLLREQUEST, POLLTYPE, wszPollRequest(LMISENDJOB),
|
||
dwPollContext(LMIRECVSTATUS), POLL_REQUEST capability
|
||
9/23/94 : Added Custom msg options support
|
||
LMI_SetCustomMsgOptions,
|
||
wrgbCustomOptionsOffset(LMISENDJOB),
|
||
CUSTOM_MSG_OPTIONS capability.
|
||
9/23/94 : Added 4 ext error codes to T30_DIALFAIL.
|
||
9/23/94 : Added lpatError to LMI_CheckProvider.
|
||
9/26/94 : Added NRR_COMMITTED_RECEIVE to
|
||
LMI_ReportReceives
|
||
10/6/94 : Added ABOVE64K_STRUCTURES to caps, and made total
|
||
size & struct offsets in LMISENDJOB DWORDS.
|
||
10/6/94 : Made all structs DWORDS aligned.
|
||
10/6/94 : Added User request fields to LMI_ReportSends
|
||
10/6/94 : Added user request flags to LMI_GetQueueFile
|
||
10/6/94 : Changed dwNumEntries in LMIQUEUEFILEHEADER to dword
|
||
10/6/94 : Updated AtWork address definition to include \@ & |
|
||
10/7/94 : Consolidated all unsupported dialchar codes.
|
||
10/17/94: Added NCUDIAL_BADDIALSTRING
|
||
10/17/94: Moved lpatClientName from LMI_InitProvider to
|
||
LMI_InitLogicalModem
|
||
10/17/94: Added LMIERR_PROVIDER_BUSY
|
||
|
||
03/16/95 (kentse) The big reorg. changed from Srvrdll to
|
||
LMI. (A large change).
|
||
04/05/95 (kentse) Completed the big rewrite.
|
||
|
||
***************************************************************************/
|
||
|
||
|
||
#define MAX_SERVERNAME_SIZE 32
|
||
#define MAX_SUBJECT_SIZE 128
|
||
|
||
|
||
typedef ATOM FAR* LPATOM;
|
||
typedef UINT FAR* LPUINT;
|
||
|
||
|
||
//////////////////////// OVERVIEWS ///////////////////////////////////////
|
||
/****
|
||
@doc EXTERNAL SRVRDLL OVERVIEW
|
||
|
||
@topic Introduction to the Logical Modem Interface | The Logical Modem
|
||
Interface (LMI) was developed to facilitate the easy creation of a fax
|
||
service provider for a Microsoft Fax transport running on a PC. Microsoft
|
||
Fax is supported in Windows 95 and will be supported in the shell update
|
||
release of Windows NT 3.51. There is also support in Windows for
|
||
Workgroups<tm> 3.11 (where Microsoft Fax was known as Microsoft At
|
||
Work <tm>). A fax service provider written to the LMI will work on all
|
||
these platforms. For this discussion of the LMI, no distinction is made
|
||
between operating environments.
|
||
|
||
The Logical Modem Interface divides Microsoft Fax support in Windows
|
||
into two parts: a fax transport that sits above the LMI, and
|
||
one or more LMI providers that sit underneath. The fax transport is
|
||
a messaging provider integrated with mail (MAPI) that can
|
||
expose faxing capabilities to the user in many ways. Most fundamentally,
|
||
faxing capability is exposed through the Microsoft Mail or Microsoft
|
||
Exchange Send Note form, where fax is treated as just another valid
|
||
address type by the user. But faxing capability is also exposed to the user
|
||
through a <lq>print to fax<rq> mechanism hooked into the printing system
|
||
(this user interface is more typical for alternative fax packages).
|
||
In the new Windows shell, fax is also exposed through a <lq>send fax
|
||
wizard<rq>. Regardless of the method chosen by the user to compose a fax,
|
||
once <lq>sent<rq> by the user the fax message ends up as a message in the
|
||
mail store. In general, any outbound message in the store is extracted by MAPI,
|
||
and, if addressed to one or more fax recipients, the message is handed over to
|
||
the fax transport for delivery.
|
||
|
||
The fax transport performs several types of processing on a fax message after
|
||
receiving it from MAPI. The objective of this processing is to create a data
|
||
stream that contains the actual bits that need to be sent across the wire. (It is
|
||
assumed that in most cases, a fax will be sent over a PSTN connection. This need
|
||
not always be so, such as in the case of a NetFax server.) The format of this
|
||
data might be one of the standard MH, MR, or MMR formats; or it might be the
|
||
Microsoft Fax linearized file format, which allows multiple, binary attachments.
|
||
The transport intelligently decides which format or formats to generate (more than
|
||
one may be generated) based partly on cached (or unknown) capabilities of the
|
||
recipient, and partly on preferences expressed by the user. Especially in cases
|
||
where the transport cannot decide the best format, it may generate several,
|
||
postponing the actual decision of which to send until run time.
|
||
|
||
Once the appropriate formats have been generated, the main work of the fax
|
||
transport is done. From that point, responsibility for sending the fax belongs
|
||
to the active LMI provider. The user could have several LMI providers
|
||
installed, such as a local modem and a network fax service provider, but only
|
||
one can be active at a time.
|
||
|
||
The fax transport has no knowledge of any physical modem or phone line. It
|
||
only knows about the existence of a <lq>logical modem<rq>. The transport can
|
||
submit jobs to be sent over this modem without worrying about how they will be sent.
|
||
An LMI provider can accept these jobs and complete them in any way, including
|
||
by forwarding the data to a different machine (which could be running a custom
|
||
operating system) where a physical fax modem is installed.
|
||
|
||
Once it completes sending the fax, the LMI provider must return the results of
|
||
the send to the sending fax transport. Because sending faxes and communicating
|
||
between machines can be time-consuming, the interface is completely asynchronous.
|
||
None of the calls into the interface require blocking of the fax transport while the
|
||
LMI provider performs some operation. The LMI provider benefits from this division
|
||
of labor because all of the intelligence is kept common in the fax transport,
|
||
including all knowledge about keeping capabilities, rendering
|
||
attachments to the message, getting data from OLE objects, and so on.
|
||
|
||
The LMI is designed so that all structures and data passed
|
||
through the interface are already marshaled into blocks of BYTES.
|
||
This simplifies the implementation of the LMI provider in the case where the
|
||
provider is used with a network front-end processor and where the actual fax
|
||
call is not made in the same process context as the provider
|
||
interface. The LMI provider must parse the structures, dial
|
||
the numbers, and send the appropriate format across the connection. To
|
||
communicate with other Microsoft Fax-enabled machines over a PSTN
|
||
connection, the LMI provider must be able to talk the Microsoft Extended Fax
|
||
Protocol (MEFP) on the wire. MEFP is a set of NSF extensions to the ITU T.30
|
||
protocol; the details of this protocol are documented elsewhere. The current
|
||
document assumes that the LMI provider can talk to Microsoft Fax clients and
|
||
decipher their capabilities in order to make intelligent decisions about which
|
||
format is to be sent.
|
||
|
||
There is a wide range of functionality an LMI provider may choose
|
||
to provide. At the simplest, an LMI provider can decide to only
|
||
provide send-fax services, with no capability of queuing,
|
||
scheduling, and so on. A more complex LMI provider can have
|
||
it's own phone books, generate cover pages, print incoming faxes,
|
||
do inbound routing of other faxes, do load balancing with multiple
|
||
hardware phone lines, and much more. The LMI encourages vendors to
|
||
differentiate their offerings. The same fax transport can talk to
|
||
an LMI provider with any kind of functionality. The fax transport
|
||
makes dynamic decisions based on capability flags that are part of
|
||
the LMI.
|
||
|
||
Except for a few configuration functions, the interface is guaranteed to be
|
||
called from a single process context.
|
||
However, the client software can consist of multiple threads,
|
||
each of which may call portions of this interface.
|
||
It is possible for a second API to be called while
|
||
still in the middle of a previous call (the calls would be in different
|
||
thread contexts). This is important. It means that the LMI provider must
|
||
protect itself from reentrancy issues.
|
||
|
||
A logical modem is treated as a single queue to which jobs can be sent. There is
|
||
not necessarily a one-to-one correspondence between a logical modem and a
|
||
physical modem. An implementation can hide several modems behind a single
|
||
queue and do load balancing among the modems.
|
||
|
||
Important: Unless explicitly stated otherwise, an LMI provider should not
|
||
present any user interface in any interface calls. Many of these calls are
|
||
made in the background and are not expected to put up UI (including
|
||
message boxes).
|
||
|
||
@topic Overview of the LMI Provider Interface | This document describes the
|
||
services a fax provider must implement to act as a fax provider to a Microsoft
|
||
Fax client through the LMI. The interface has several main components. The
|
||
parts are installation, configuration, queue administration and status,
|
||
sending faxes, receiving faxes, and uploading documents and cover pages.
|
||
Each of these is covered in detail in the following sections.
|
||
|
||
It is useful to present a high-level overview of how the fax transport
|
||
calls into the Logical Modem Interface. At first, the transport's
|
||
configuration user interface calls <f LMI_AddModem> and
|
||
<f LMI_RemoveModem> to control which modems exist in the list
|
||
of available modems. It also calls <f LMI_ExchangeCaps>
|
||
to make any necessary configuration decisions. When the fax transport
|
||
initializes, it calls <f LMI_InitProvider> and <f LMI_InitLogicalModem>.
|
||
The transport can then send faxes with <f LMI_SendFax>. The transport
|
||
polls for the status of sent faxes with <f LMI_ReportSend> and looks at the
|
||
provider's queue with <f LMI_GetQueueFile>. To abort or reschedule
|
||
a fax that has been sent but has not yet left the queue, the transport
|
||
can call <f LMI_AbortSendJob> and <f LMI_RescheduleSendJob>.
|
||
The transport polls for received faxes with <f LMI_ReportReceives>.
|
||
Finally, the transport calls <f LMI_DeinitLogicalModem> and
|
||
<f LMI_DeinitProvider> when it is time to shut down.
|
||
|
||
A useful example to study for understanding the flow across the
|
||
LMI is the simple case of a send on one machine leading to a
|
||
receive on another. A send starts off as a note composed in a
|
||
mail client by the user. In this example, the user types in some
|
||
text and attaches a bitmap. The user addresses the note to
|
||
a single fax recipient at the phone number 555-1234 and chooses
|
||
to send the note in the best format possible at the cheap-rate time. When
|
||
the note is ready, the user <lq>sends<rq> the note (this really
|
||
just saves the message to the store).
|
||
|
||
The message is then picked up from the store and is handed to
|
||
the fax transport, because the message has a fax recipient. The
|
||
fax transport looks into its capability database for the number
|
||
555-1234, but (in this example) finds no entry. Because the user chose
|
||
to send the message in the best format possible, the fax transport converts the
|
||
message into two formats: a rendered, MMR version (images only) and a
|
||
linearized file-format version (binary file). For the rendered version, the
|
||
transport itself renders the text; calls Paintbrush to render the bitmap
|
||
file; and finally generates a file combining the rendered images, to which
|
||
it attaches a linearized header. For the linearized version, the transport
|
||
calls the linearizer, which assembles the binary attachments as-is into
|
||
a file with a linearized header.
|
||
|
||
After creating the two separate files, the fax transport calls
|
||
<f LMI_SendFax> in the LMI provider. In the call, the transport passes
|
||
in the details of the job as well as the file name for each of the
|
||
two formats that were generated. In response to the call, the LMI provider
|
||
examines the details of the send job. Seeing that the fax (in this example)
|
||
is to be sent at cheap rates, it leaves the job on its internal queue. The fax
|
||
transport periodically polls the LMI provider for the status of the fax.
|
||
|
||
When cheap times roll around, the LMI provider connects to 555-1234
|
||
using a local modem and sends the appropriate format (the MMR file if the
|
||
receiver is a G3 fax machine, or the linearized file if the receiver uses
|
||
Microsoft Fax). The next time the fax transport calls <f LMI_ReportSend>
|
||
after the fax is sent over the wire, the LMI provider returns the final status of
|
||
the send job. Upon receipt of this status, the fax transport passes it on to the
|
||
user, typically generating a Non-Delivery Report (NDR) if there was an
|
||
error, or moving the message into the Sent Mail folder if the send was
|
||
successful.
|
||
|
||
Received faxes are available immediately to the LMI provider on the remote
|
||
machine, since it is the one picking up the phone. The LMI provider then
|
||
has to decide to which client the message needs to be routed. For reception of
|
||
G3 faxes, intelligent decisions are not possible since there is no structured
|
||
routing information; routing to some default client is probably best. For
|
||
Microsoft Fax messages, the LMI provider can interpret the linearized header
|
||
(using some helper functions) and extract the Microsoft
|
||
Fax address of the recipient. If this address contains a routing name,
|
||
the name can be matched to a list of clients and the fax can be easily routed.
|
||
|
||
Once the LMI provider has decided on the recipient client, it waits for that
|
||
client's fax transport to regularly poll for new faxes. When polled (by a call
|
||
to <f LMI_ReportReceives>), the provider creates a file with the received data
|
||
in an appropriate format. If the fax was received from a G3 fax machine, the
|
||
provider can use helper functions to construct a file starting with a linearized header,
|
||
followed by AWG3 page headers, finally followed by the data. For linearized file-format
|
||
faxes, the exact data received is passed in. Finally, the client fax transport parses the
|
||
data file (of whichever format) and creates a new message in the mail client Inbox
|
||
containing the data in a format the user can view.
|
||
|
||
@topic Installation |
|
||
Installing a new LMI provider module is a two step process. First, the
|
||
installation program must create an entry in the MSATWORK.INF file
|
||
as defined below.
|
||
|
||
MSATWORK.INF file format:
|
||
|
||
[External Devices]<nl>
|
||
\<device name\>=\<description\><nl>
|
||
.<nl>
|
||
.<nl>
|
||
\<device name\>=\<description\>
|
||
|
||
[\<device name\>]<nl>
|
||
Display Name=\<name to show devices list box\><nl>
|
||
DLL Name=\<name of the DLL for this device\><nl>
|
||
Flags=\<see below\><nl>
|
||
|
||
[\<device name\>]<nl>
|
||
Display Name=\<name to show devices list box\><nl>
|
||
DLL Name=\<name of the DLL for this device\><nl>
|
||
Flags=\<see below\>
|
||
|
||
Explanation:
|
||
|
||
\<device name\>: Name of the section of the below device.<nl>
|
||
\<description\>: Description of the device, for INF-file purposes
|
||
only, not used anywhere else.<nl>
|
||
Display Name: Name of the device. This name will be displayed
|
||
in the AddDevice dialog listbox.<nl>
|
||
DLL Name: Name of the DLL that services this device.<nl>
|
||
Flags: Currently will be zero. Can be used for various device
|
||
capabilities, like whether this device allows setup, etc.
|
||
|
||
Example:
|
||
|
||
[External Devices]<nl>
|
||
IFAX=An intelligent fax machine<nl>
|
||
AcmeFax=A future fax provider
|
||
|
||
[IFAX]<nl>
|
||
Display Name=Intelligent fax machine<nl>
|
||
DLL Name=ifax32.dll<nl>
|
||
Flags=0
|
||
|
||
[AcmeFax]<nl>
|
||
DLL Name=acme32.dll
|
||
|
||
Next, when the user installs a new fax modem from the
|
||
configuration interface, the user is presented with a list of all strings
|
||
from the Display Name section of the MSATWORK.INF file. When the
|
||
user chooses Display Name, <f LMI_AddModem> is called to allow the
|
||
LMI provider to put up a dialog box that asks the user to choose a
|
||
logical modem from that LMI provider.
|
||
|
||
<f LMI_AddModem> returns a string representing the logical modem
|
||
the user has selected. This string is then displayed in the list of
|
||
currently available modems. The user can choose the current default
|
||
fax modem from this list.
|
||
|
||
@topic Configuration |
|
||
The user is allowed to configure any of the available
|
||
fax modems (logical modems). <f LMI_ConfigureModem> is called for
|
||
the appropriate LMI provider. This function allows the user
|
||
to do whatever remote configuration options are permitted. These may
|
||
be divided into user-configurable and administrator-configurable
|
||
options. In general, there should be very few user configurable
|
||
options. For administrator options, this function should
|
||
probably use some kind of password protection.
|
||
|
||
@topic Initialization |
|
||
When the fax transport starts, the <f LMI_InitProvider> function
|
||
is called for the appropriate LMI provider. Then, the
|
||
<f LMI_InitLogicalModem> function is called for the modem the
|
||
client wants to use. This function intializes the logical
|
||
modem and return to the client a handle to the modem, as well as the
|
||
modem<65>s capabilities. The capabilities include support for advanced
|
||
features and are used by the client to decide what kind of
|
||
operations are supported by the LMI provider. An example of an
|
||
important capability is whether or not the modem is Microsoft Fax
|
||
enabled. The phone number of the modem is some other
|
||
information returned by this call. Several logical modems may be
|
||
initialized at the same time. All operations on a modem use the
|
||
handle returned by the <f LMI_InitLogicalModem> call.
|
||
|
||
@topic Queue Management |
|
||
To allow the user to see up-to-date status for all the jobs of an
|
||
LMI provider, functions have been defined to let the client
|
||
monitor and administer the provider's queue.
|
||
<f LMI_GetQueueFile> is called whenever the user wants to see the
|
||
queue. This function gives access to a specific set of information
|
||
about each job in the provider's queue. The information is
|
||
displayed in a uniform manner by the fax transport. To allow
|
||
value-added, extended-status displays, arbitrary binary
|
||
information can also be passed back as part of the status. If
|
||
the user wants detailed status on a particular job,
|
||
<f LMI_DisplayCustomStatus> is called with this binary
|
||
information to display more detailed status. If the user wants
|
||
to cancel or reschedule jobs, the functions <f LMI_AbortSendJob>
|
||
and <f LMI_RescheduleSendJob> may be called.
|
||
|
||
@topic Sending Faxes |
|
||
When a fax is to be sent, the transport assumes all responsibility
|
||
for rendering the appropriate formats for transmission. The transport
|
||
maintains a cache of the capabilities for all fax machines it has
|
||
talked to before and uses the database to attempt intelligent decisions
|
||
about the most efficient format to be sent. The transport also takes
|
||
into account explicit user preferences.
|
||
|
||
There are three different formats that can be sent. The first is
|
||
for sending to standard fax machines and consists of MH, MR or
|
||
MMR data. The second format is a linearized EFAX message containing
|
||
only image data. The third format is a linearized EFAX message containing
|
||
binary data. All three formats are always preceded by a linearized header
|
||
describing the file. See <lq>Microsoft At Work Linearized File Format<rq>
|
||
for details of this header. Details of the fax file format are in <lq>AWG3 File
|
||
Format<rq>.
|
||
|
||
When the fax has been sent, the LMI provider reports the final
|
||
status for the job via <f LMI_ReportSend>. This function is
|
||
polled periodically by the fax transport. Along with the final
|
||
status, the Provider must return the newly found capabilities of
|
||
all the recipients of the fax. The client can also ask for
|
||
attention using the <f LMI_CheckProvider> function.
|
||
|
||
Poll requests are also submitted using LMI_SendFax. Fields in the LMISENDJOB
|
||
structure provide the information for the poll request.
|
||
|
||
@topic Receiving Faxes|
|
||
All received faxes need to be routed by the fax transport to the
|
||
appropriate LMI provider. The Microsoft At Work fax transport
|
||
polls for received faxes using the <f LMI_ReportReceives>
|
||
function.
|
||
|
||
As with sent faxes, received faxes can be in any one of three
|
||
formats. The header for the file describes the format and gives
|
||
information about the recipients of this message. All formats
|
||
MUST have a linearized header describing the format and contents
|
||
of the message. See
|
||
<lq>Microsoft At Work Linearized File Format<rq>
|
||
for details of this header. Details of the Fax file format are
|
||
in <lq>AWG3 File Format<rq>.
|
||
****/
|
||
|
||
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@topic Microsoft At Work Address |
|
||
|
||
This section describes the Microsoft At Work address format. In
|
||
its most common form, this consists of a name and a phone number.
|
||
The phone number is assumed to begin at the last @ in the address.
|
||
In its more complex forms, the name could contain more routing
|
||
information.
|
||
|
||
Ideally, the phone number in the address is in the canonical form.
|
||
This consists of
|
||
+\<country code\>[\<area code\>]\<local number\>[\|\<suffix\>].
|
||
|
||
Other important things to note: An @ can be escaped by using a
|
||
backslash, and a suffix may be added to the canonical number
|
||
by using a \| symbol after the number and following that with the
|
||
suffix.
|
||
|
||
@ex Some Examples: |
|
||
A simple Micsosoft At Work Address might look like
|
||
|
||
JohnDoe@+1(206)5551212|$999
|
||
|
||
which would indicate that after dialing the number, we should wait
|
||
for a beep and dial a 999. THe receiving number would then route
|
||
to JohnDoe. If the number is an IFAX machine, John would have an
|
||
account with the login JohnDoe, or if the number was a PC, JohnDoe
|
||
would be the email alias for his account.
|
||
|
||
In general, the <name> part of the address must be interpreted by
|
||
the receiving machine and can contain any routing information
|
||
necessary for inbound routing by this machine.
|
||
|
||
*********/
|
||
|
||
|
||
|
||
|
||
/****
|
||
@doc EXTERNAL SRVRDLL OVERVIEW
|
||
|
||
@topic Constants|
|
||
The following section contains a list of predefined return codes,
|
||
error codes, and other predefined values used throughout this
|
||
document.
|
||
|
||
****/
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@type NONE | LMI_RETURN | Return codes for LMI provider API's.
|
||
|
||
@emem LMI_SUCCESS | No error - function was successful.
|
||
|
||
@emem LMIERR_CONNECT_FAILED | Connection to Provider failed. Client
|
||
should go offline.
|
||
|
||
@emem LMIERR_NOT_SUPPORTED | Some function/parameter was not
|
||
supported by this LMI provider.
|
||
|
||
@emem LMIERR_OPERATION_FAILED | Generic failure code.
|
||
|
||
@emem LMIERR_OP_CANCELLED | Operation canceled by user.
|
||
|
||
@emem LMIERR_PROVIDER_BUSY | The Provider was temporarily unavailable to
|
||
accept requests. This might be useful for Providers which have
|
||
limits on the number of connections supported. The clients response
|
||
to this error code should be to try and retry the operation if
|
||
possible, particularly for API's like <f LMI_SendFax>. However,
|
||
some clients may treat this as a failure.
|
||
|
||
@emem LMIERR_SERVER_RESOURCES_LOW | The Provider failed due to a low
|
||
resource situation on a server.
|
||
|
||
********/
|
||
|
||
typedef DWORD LMI_RETURN;
|
||
|
||
#define LMI_SUCCESS 0
|
||
#define LMIERR_CONNECT_FAILED 1
|
||
#define LMIERR_NOT_SUPPORTED 2
|
||
#define LMIERR_OPERATION_FAILED 3
|
||
#define LMIERR_OP_CANCELLED 4
|
||
#define LMIERR_PROVIDER_BUSY 5
|
||
#define LMIERR_SERVER_RESOURCES_LOW 6
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@type NONE | FAXERROR |
|
||
DWORD Error status codes returned in the
|
||
<t LMIFORMAT>, <t LMIRECIPSTATUS>, <t LMISENDSTATUS>, and
|
||
<t LMIRECVSTATUS> structures. This error consists of three parts:
|
||
an error code, an extended error code, and error specific data
|
||
(in some cases). The extended error code must be set to
|
||
T30_UNKNOWN if the means for setting a more meaningful error are
|
||
not available. A value of zero in the data field implies that
|
||
there is no valid data for this error. In those cases where the
|
||
extended error or data fields are unused, they must be set to zero.
|
||
This is to allow these fields to be used in the future.
|
||
|
||
@emem Error Code | The low BYTE of the low word of the error is the
|
||
error code. Use the macro GetErrCode(error) to extract this
|
||
BYTE. The error codes defined are:
|
||
|
||
@flag T30_CALLFAIL | An error occured during actual
|
||
transmission of the fax. Detailed error status can be determined
|
||
from the extended error field.
|
||
@flag T30_DIALFAIL | An error occured during dialing
|
||
the fax number. Detailed error status can be determined from
|
||
the extended error field.
|
||
@flag T30_ANSWERFAIL | An error occured during answering of a phone
|
||
call. Detailed error status can be determined from the extended
|
||
error field.
|
||
@flag T30_NOMODEM | The Provider could not find any hardware modem
|
||
to send the fax over. This would typically indicate that the user
|
||
had physically removed some hardware from the machine.
|
||
@flag T30_FILE_ERROR | An error occured trying to read or parse the
|
||
format files which were passed in. Detailed error status may
|
||
be found in the extended error.
|
||
@flag T30_MODEMERROR | An error occured while trying to talk with
|
||
the hardware modem.
|
||
@flag T30_PORTBUSY | The port on which the hardware modem was
|
||
installed cannot be opened. Extended error status contains more
|
||
details.
|
||
@flag T30_MODEMDEAD | The hardware modem has stopped responding to
|
||
any AT commands. This typically requires some human intervention,
|
||
such as turning the power off and back on.
|
||
@flag RES_NOMEMORY | The Provider ran out of memory resources.
|
||
@flag RES_LOWDISK | The Provider ran out of disk space.
|
||
@flag USER_ABORT | The job was cancelled on a user request.
|
||
@flag RENDERING_FAILURE | For Provider's that do any rendering, this
|
||
indicates the class of failures which result in the inability to
|
||
render a final format to be sent. Extended errors give more
|
||
details.
|
||
@flag RES_LOW_SERVER | The Provider failed due to a low resource
|
||
problem on a server.
|
||
@flag CUSTOM_ERROR | If the Provider happens to get an error
|
||
which does not fall into any of the classes specifically
|
||
defined here, then it can pass back a custom error. In this
|
||
case the data field contains a global atom
|
||
which identifies a string describing the error in terms
|
||
understandable to the user. NOTE: This error is not supported
|
||
by Windows 95, but will be in a later release.
|
||
@flag GENERAL_FAILURE | Indicates a serious internal error in the
|
||
software.
|
||
|
||
@emem Extended error codes for T30_DIALFAIL | Any of the following could
|
||
be the reason for a dial failure:
|
||
|
||
@flag NCUDIAL_ERROR | Detailed error is unknown.
|
||
@flag NCUDIAL_BUSY | The called number was busy.
|
||
@flag NCUDIAL_NOANSWER | The dialed number did not answer.
|
||
@flag NCUDIAL_NODIALTONE | No dialtone could be detected.
|
||
@flag NCUDIAL_MODEMERROR | There was some hardware problem in
|
||
the modem while trying to dial.
|
||
@flag NCUDIAL_BADDIALSTRING | The dial string was badly formed. In
|
||
general, logical modems should try to be as robust as possible,
|
||
ignoring characters which are not understood. This error code
|
||
should only be used for cases where the string is so obviously
|
||
malformed that there is no point even attempting to dial.
|
||
|
||
@emem Extended error codes for T30_ANSWERFAIL | The provider does not have
|
||
to report receives which failed in the answering phase itself.
|
||
However, if it chooses to do so, the following codes apply:
|
||
|
||
@flag NCUANSWER_ERROR | Detailed error is unknown.
|
||
@flag NCUANSWER_NORING | No ring was detected.
|
||
@flag NCUANSWER_MODEMERROR | There was some hardware problem in
|
||
the modem while trying to answer.
|
||
|
||
@emem Extended error codes for T30_PORTBUSY | The port could be busy for
|
||
two reasons:
|
||
|
||
@flag PORTBUSY_SELFUSE | The port is already being used by us. A common
|
||
case causing this error is if a receive is in progress. The
|
||
client will typically retry the call at a later time,
|
||
transparently to the user.
|
||
@flag PORTBUSY_OTHERAPP | The device or port is used by some other
|
||
application.
|
||
|
||
@emem Extended error codes for T30_CALLFAIL | This is likely to be the
|
||
most common error, and very detailed error codes are defined for
|
||
it. The extended error can be any of the following:
|
||
|
||
@flag T30FAILS_T1 | Send T1 timeout (No NSF/DIS Received).
|
||
@flag T30FAILS_TCF_DCN | Received DCN after TCF.
|
||
@flag T30FAILS_3TCFS_NOREPLY | No reply to three attempts at training
|
||
(TCF).
|
||
@flag T30FAILS_3TCFS_DISDTC | Remote does not see our TCFs.
|
||
@flag T30FAILS_TCF_UNKNOWN | Got garbage response to TCF.
|
||
@flag T30FAILS_SENDMODE_PHASEC | Modem error or timeout at start of
|
||
page.
|
||
@flag T30FAILS_MODEMSEND_PHASEC | Modem error or timeout within page.
|
||
@flag T30FAILS_MODEMSEND_ENDPHASEC | Modem error or timeout at end of
|
||
page.
|
||
@flag T30FAILSE_SENDMODE_PHASEC | Modem error or timeout at start of
|
||
ECM page.
|
||
@flag T30FAILSE_MODEMSEND_PHASEC | Modem error or timeout within ECM
|
||
page.
|
||
@flag T30FAILSE_MODEMSEND_ENDPHASEC | Modem error or timeout at end of
|
||
ECM page.
|
||
@flag T30FAILSE_BADPPR | Bad PPR received from receiver.
|
||
@flag T30FAILS_3POSTPAGE_NOREPLY | No response after page: Probably
|
||
receiver hungup during page transmit.
|
||
@flag T30FAILS_POSTPAGE_DCN | Received DCN after page.
|
||
@flag T30FAILSE_3POSTPAGE_NOREPLY | No response after page. Probably
|
||
receiver hungup during page transmit.
|
||
@flag T30FAILSE_POSTPAGE_DCN | Received DCN after ECM page.
|
||
@flag T30FAILSE_POSTPAGE_UNKNOWN | Received garbage after ECM page.
|
||
@flag T30FAILSE_RR_T5 | Receiver was not ready for more than 60 seconds
|
||
during ECM flow-control.
|
||
@flag T30FAILSE_RR_DCN | Received DCN after RR during ECM flow-control.
|
||
@flag T30FAILSE_RR_3xT4 | No response from receiver during ECM
|
||
flow-control.
|
||
@flag T30FAILSE_CTC_3xT4 | No response from receiver after CTC
|
||
(ECM baud-rate fallback).
|
||
@flag T30FAILSE_CTC_UNKNOWN | Garbage response from receiver after CTC
|
||
(ECM baud-rate fallback).
|
||
@flag T30FAILR_PHASEB_DCN | Receiver: Sender decided we're incompatible.
|
||
@flag T30FAILR_T1 | Receiver: Caller is not a fax machine or hung up.
|
||
@flag T30FAILR_UNKNOWN_DCN1 | Receiver: Received DCN when command was
|
||
expected.
|
||
@flag T30FAILR_T2 | Receiver: No command was received for seven seconds.
|
||
@flag T30FAILR_UNKNOWN_UNKNOWN2 | Receiver: Received garbage when
|
||
command was expected.
|
||
@flag T30FAILR_MODEMRECV_PHASEC | Receiver: Page not received, modem
|
||
error or timeout at start of page.
|
||
@flag T30FAILRE_MODEMRECV_PHASEC | Receiver: Data not received, modem
|
||
error or timeout during page.
|
||
@flag T30FAILRE_PPS_RNR_LOOP | Receiver: Timeout during ECM flow
|
||
control after PPS.
|
||
@flag T30FAILRE_EOR_RNR_LOOP | Receiver: Timeout during ECM flow
|
||
control after EOR.
|
||
@flag T30FAIL_NODEA_UNKNOWN | Sender: Garbage frames instead of DIS/DTC.
|
||
@flag T30FAILS_POSTPAGE_UNKNOWN | Sender: Unknown response after page.
|
||
@flag T30FAILS_POSTPAGE_OVER | Sender: We've sent a DCN (decided to
|
||
end call).
|
||
@flag T30FAILS_4PPR_ERRORS | Sender: Too many line errors in ECM mode.
|
||
@flag T30FAILS_FTT_FALLBACK | Sender: Receiver doesn't like our
|
||
training at all speeds.
|
||
@flag T30FAILS_RTN_FALLBACK | Sender: Too many line errors in non-ECM
|
||
mode even at 2400.
|
||
@flag T30FAILS_4PPR_FALLBACK | Sender: Too many line errors in ECM mode
|
||
even at 2400.
|
||
@flag T30FAILS_MG3_NOFILE | Negotiation failed: Remote was G3 and there
|
||
was no AWG3 format to send.
|
||
@flag T30FAILS_NEGOT_ENCODING | Negotiation failed: Encoding mismatch.
|
||
@flag T30FAILS_NEGOT_WIDTH | Negotiation failed: Paper Size Not
|
||
Supported.
|
||
@flag T30FAILS_NEGOT_LENGTH | Negotiation failed: Paper Size Not
|
||
Supported.
|
||
@flag T30FAILS_NEGOT_RES | Negotiation failed: Resolution Not Supported.
|
||
@flag T30FAILS_EFX_BADFILE | Bad Linearized file was passed.
|
||
@flag T30FAILS_MG3_BADFILE | Bad AWG3 file was passed in.
|
||
@flag T30FAIL_ABORT | User abort
|
||
@flag T30FAILS_SECURITY_NEGOT | Negotiation failed: Remote machine does
|
||
not support security. If set, the error data contains the
|
||
security version number supported by the recipient.
|
||
@flag T30FAILS_NEGOT_MSGPROTOCOL | Negotiation failed: Remote machine
|
||
does not support a compatible message protocol. If set, the
|
||
error data contains the message protocol version number
|
||
supported by the recipient.
|
||
@flag T30FAILS_NEGOT_SECURITY | Negotiation failed: Remote machine does not support
|
||
security. If set, the error data contains the security version number supported
|
||
by the recipient.
|
||
@flag T30FAILS_NEGOT_BINARYDATA | Negotiation failed: Remote machine
|
||
does not support receiving binary data.
|
||
@flag T30FAILS_NEGOT_COMPRESSION | Negotiation failed: Remote machine
|
||
does not support a compatible version of compression. If set,
|
||
the error data contains the compression version supported by
|
||
the recipient.
|
||
@flag T30FAILS_NEGOT_POLLING | Negotiation failed: Remote machine does
|
||
not support polling.
|
||
@flag T30FAILS_NEGOT_POLLBYNAME | Negotiation failed: Remote machine
|
||
does not support poll by name.
|
||
@flag T30FAILS_NEGOT_POLLBYRECIP | Negotiation failed: Remote machine
|
||
does not support poll by recipient name.
|
||
@flag T30FAILS_NEGOT_FILEPOLL | Negotiation failed: Remote machine
|
||
does not support poll by filename.
|
||
|
||
@emem Error data values for T30_CALLFAIL | Error data must be zero for negotiation failures. For all other failures, the error data may be set
|
||
to one of the following fields:
|
||
|
||
@flag T30_SENTNONE | Indicates that no pages were sent at all.
|
||
@flag T30_SENTSOME | Indicates that some pages were successfuly
|
||
transmitted and acknowledged by the remote machine.
|
||
@flag T30_SENTALL | Indicates that all pages were successfuly sent.
|
||
This should not really happen; it would generally indicate a
|
||
successful transmission.
|
||
|
||
@emem Extended error codes for T30_FILE_ERROR | This error indicates a
|
||
problem in one of the format files sent across the interface by
|
||
the client. Different possible extended error codes are:
|
||
|
||
@flag AWG3_INVALID_LINHDR | The linearized header at the head of the
|
||
AWG3 file was invalid.
|
||
@flag AWG3_INVALID_AWG3HDR | An invalid AWG3 header was found in the
|
||
file.
|
||
@flag LIN_INVALIDHDR | A linearized file had an invalid header.
|
||
|
||
|
||
********/
|
||
|
||
typedef DWORD FAXERROR;
|
||
|
||
#define GetErrCode(fe) (LOBYTE(LOWORD(fe)))
|
||
#define GetExtErrCode(fe) (HIBYTE(LOWORD(fe)))
|
||
#define GetErrData(fe) (HIWORD(fe))
|
||
#define FormFaxError(ErrCode,ExtErrCode,ErrData) MAKELONG(MAKEWORD(ErrCode,ExtErrCode),ErrData)
|
||
|
||
// Error codes
|
||
#define T30_CALLFAIL 2
|
||
#define T30_DIALFAIL 4
|
||
#define T30_ANSWERFAIL 5
|
||
#define T30_NOMODEM 9
|
||
#define T30_FILE_ERROR 11
|
||
#define T30_MODEMERROR 15
|
||
#define T30_PORTBUSY 16
|
||
#define T30_MODEMDEAD 17
|
||
|
||
#define RES_NOMEMORY 64
|
||
#define RES_LOWDISK 65
|
||
#define USER_ABORT 66
|
||
#define RENDERING_FAILURE 67
|
||
#define RES_LOW_SERVER 68
|
||
|
||
#define CUSTOM_ERROR 254
|
||
#define GENERAL_FAILURE 255
|
||
|
||
// Extended Error codes
|
||
#define T30_UNKNOWN 0
|
||
|
||
// RENDERING_FAILURE
|
||
#define ATTACH_NOT_PRINTABLE 1
|
||
#define COVER_TEMPLATE_INVALID 2
|
||
|
||
// T30_FILE_ERROR
|
||
#define AWG3_INVALID_LINHDR 1
|
||
#define AWG3_INVALID_AWG3HDR 2
|
||
#define LIN_INVALIDHDR 3
|
||
|
||
// T30_DIALFAIL
|
||
#define NCUDIAL_ERROR 0
|
||
#define NCUDIAL_BUSY 2
|
||
#define NCUDIAL_NOANSWER 3
|
||
#define NCUDIAL_NODIALTONE 4
|
||
#define NCUDIAL_MODEMERROR 5
|
||
#define NCUDIAL_UNSUPPORTED_DIALCHAR 6
|
||
#define NCUDIAL_BADDIALSTRING 7
|
||
|
||
// Extended error code for T30_ANSWERFAIL
|
||
#define NCUANSWER_ERROR 0
|
||
#define NCUANSWER_NORING 8
|
||
#define NCUANSWER_MODEMERROR 5
|
||
|
||
// Extended error code for T30_PORTBUSY
|
||
#define PORTBUSY_SELFUSE 0
|
||
#define PORTBUSY_OTHERAPP 1
|
||
|
||
|
||
// Includes T30FAIL.H so that the values here (which should be a subset of
|
||
// those in T30FAIL.H) are kept in sync.
|
||
#include <t30fail.h>
|
||
|
||
// Extended error code for T30_CALLFAIL
|
||
#define T30FAILS_T1 6 // Send T1 timeout (No NSF/DIS Recvd)
|
||
#define T30FAILS_TCF_DCN 7 // Recvd DCN after TCF (weird...)
|
||
#define T30FAILS_3TCFS_NOREPLY 8 // No reply to 3 attempts at training (TCF)
|
||
#define T30FAILS_3TCFS_DISDTC 9 // Remote does not see our TCFs for some reason
|
||
#define T30FAILS_TCF_UNKNOWN 10 // Got garbage response to TCF
|
||
|
||
#define T30FAILS_SENDMODE_PHASEC 11 // Modem Error/Timeout at start of page
|
||
#define T30FAILS_MODEMSEND_PHASEC 12 // Modem Error/Timeout within page
|
||
#define T30FAILS_MODEMSEND_ENDPHASEC 14 // Modem Error/Timeout at end of page
|
||
|
||
#define T30FAILSE_SENDMODE_PHASEC 15 // Modem Error/Timeout at start of ECM page
|
||
#define T30FAILSE_MODEMSEND_PHASEC 17 // Modem Error/Timeout within ECM page
|
||
#define T30FAILSE_MODEMSEND_ENDPHASEC 19 // Modem Error/Timeout at end of ECM page
|
||
#define T30FAILSE_BADPPR 20 // Bad PPR recvd from Recvr (bug on recvr)
|
||
|
||
#define T30FAILS_3POSTPAGE_NOREPLY 21 // No response after page: Probably Recvr hungup during page transmit
|
||
#define T30FAILS_POSTPAGE_DCN 22 // Recvd DCN after page. (weird...)
|
||
|
||
#define T30FAILSE_3POSTPAGE_NOREPLY 23 // No response after page: Probably Recvr hungup during page transmit
|
||
#define T30FAILSE_POSTPAGE_DCN 24 // Recvd DCN after ECM page. (weird...)
|
||
#define T30FAILSE_POSTPAGE_UNKNOWN 25 // Recvd garbage after ECM page.
|
||
|
||
#define T30FAILSE_RR_T5 26 // Recvr was not ready for more than 60secs during ECM flow-control
|
||
#define T30FAILSE_RR_DCN 27 // Recvd DCN after RR during ECM flow-control(weird...)
|
||
#define T30FAILSE_RR_3xT4 28 // No response from Recvr during ECM flow-control
|
||
#define T30FAILSE_CTC_3xT4 29 // No response from Recvr after CTC (ECM baud-rate fallback)
|
||
#define T30FAILSE_CTC_UNKNOWN 30 // Garbage response from Recvr after CTC (ECM baud-rate fallback)
|
||
|
||
#define T30FAILR_PHASEB_DCN 35 // Recvr: Sender decided we're incompatible
|
||
#define T30FAILR_T1 36 // Recvr: Caller is not a fax machine or hung up
|
||
|
||
#define T30FAILR_UNKNOWN_DCN1 37 // Recvr: Recvd DCN when command was expected(1)
|
||
#define T30FAILR_T2 38 // Recvr: No command was recvd for 7 seconds
|
||
#define T30FAILR_UNKNOWN_UNKNOWN2 40 // Recvr: Recvd grabge when command was expected
|
||
|
||
#define T30FAILR_MODEMRECV_PHASEC 41 // Recvr: Page not received, modem error or timeout at start of page
|
||
#define T30FAILRE_MODEMRECV_PHASEC 42 // Recvr: Data not received, modem error or
|
||
|
||
#define T30FAILRE_PPS_RNR_LOOP 43 // Recvr: Timeout during ECM flow control after PPS (bug)
|
||
#define T30FAILRE_EOR_RNR_LOOP 44 // Recvr: Timeout during ECM flow control after EOR (bug)
|
||
|
||
#define T30FAIL_NODEA_UNKNOWN 45 // Sender: Garbage frames instead of DIS/DTC
|
||
|
||
#define T30FAILS_POSTPAGE_UNKNOWN 47 // Sender: Unknown response after page
|
||
#define T30FAILS_POSTPAGE_OVER 48 // Sender: We've sent a DCN (decided to end call)
|
||
#define T30FAILS_4PPR_ERRORS 50 // Sender: Too many line errors in ECM mode
|
||
|
||
#define T30FAILS_FTT_FALLBACK 51 // Sender: Recvr doesn't like our training at all speeds
|
||
#define T30FAILS_RTN_FALLBACK 52 // Sender: Too many line errors in non-ECM mode even at 2400
|
||
#define T30FAILS_4PPR_FALLBACK 53 // Sender: Too many line errors in ECM mode even at 2400
|
||
|
||
#define T30FAILS_MG3_NOFILE 63 // Negotiation failed: Remote in G3-only and no MG3 file *** Email Form Not Supported ***
|
||
#define T30FAILS_NEGOT_ENCODING 64 // Negotiation failed: Encoding mismatch
|
||
#define T30FAILS_NEGOT_WIDTH 66 // Negotiation failed: Send image too wide *** Paper Size Not Supported ***
|
||
#define T30FAILS_NEGOT_LENGTH 67 // Negotiation failed: Send image too long *** Paper Size Not Supported ***
|
||
#define T30FAILS_NEGOT_RES 68 // Negotiation failed: Resolution mismatch *** Resolution Not Supported ***
|
||
|
||
#define T30FAILS_EFX_BADFILE 69 // Bad EFX file
|
||
#define T30FAILS_MG3_BADFILE 71 // Bad MG3 file
|
||
|
||
#define T30FAIL_ABORT 87 // User abort
|
||
|
||
#define T30FAILS_SECURITY_NEGOT 110// Negotiation failed: Remote in G3-only and no MG3 file *** Email Form Not Supported ***
|
||
|
||
// New failure codes
|
||
#define T30FAILS_NEGOT_MSGPROTOCOL 128
|
||
#define T30FAILS_NEGOT_SECURITY 129
|
||
#define T30FAILS_NEGOT_BINARYDATA 130
|
||
#define T30FAILS_NEGOT_COMPRESSION 131
|
||
|
||
#define T30FAILS_NEGOT_COVERATTACH 132
|
||
#define T30FAILS_NEGOT_ADDRATTACH 133
|
||
#define T30FAILS_NEGOT_METAFILE 134
|
||
|
||
#define T30FAILS_NEGOT_POLLING 135
|
||
#define T30FAILS_NEGOT_POLLBYNAME 136
|
||
#define T30FAILS_NEGOT_POLLBYRECIP 137
|
||
#define T30FAILS_NEGOT_FILEPOLL 138
|
||
#define T30FAILS_NEGOT_RELAY 139
|
||
|
||
|
||
// Data word
|
||
// Data for T30_CALLFAIL - non negotiation errors
|
||
#define T30_UNKNOWN 0
|
||
#define T30_SENTALL 1
|
||
#define T30_SENTNONE 2
|
||
#define T30_SENTSOME 3
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@type NONE | FORMATTYPE | These are all the different kinds of formats
|
||
that can be rendered for sending. It is typedef'd to a WORD.
|
||
|
||
@emem LMIFORMAT_G3 | A standard T4/T6 encoded file, with a linearizer
|
||
header put on top of it. See <lq>AWG3 File Format<rq> for details.
|
||
|
||
@emem LMIFORMAT_LIN_IMAGE | A Linearized Microsoft At Work rendered
|
||
image file.
|
||
|
||
@emem LMIFORMAT_LIN_BINARY | A linearized binary file.
|
||
|
||
********/
|
||
|
||
typedef WORD FORMATTYPE;
|
||
|
||
#define LMIFORMAT_G3 1
|
||
#define LMIFORMAT_LIN_IMAGE 2
|
||
#define LMIFORMAT_LIN_BINARY 3
|
||
#define LMIFORMAT_STORE_REF 4
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@type NONE | POLLTYPE | These are all the different kinds of poll
|
||
requests that can be sent. It is typedef'd to a WORD.
|
||
|
||
@emem POLLREQ_ADDRESS | Polls for a document for a particular
|
||
address. The Poll name is the address for which messages are
|
||
desired, and a password can also be used. This feature
|
||
is unimplemented and should not be used.
|
||
|
||
@emem POLLREQ_FILE | Polls for a directory or file on the recipient
|
||
system. The poll name contains the file system path to be accessed,
|
||
and a password can also be used. This feature is unimplemented and
|
||
should not be used.
|
||
|
||
@emem POLLREQ_MSGNAME | Polls for a particular message name.
|
||
The poll name contains the message name wanted,
|
||
and a password can also be used.
|
||
|
||
@emem POLLREQ_G3 | Standard G3 compliant poll request. Polls for
|
||
any file which has been stored at the recipient machine. Neither
|
||
pollname or password are currently supported.
|
||
|
||
All poll types except POLLREQ G3 require both sender and receiver to be
|
||
Microsoft Extended Fax Protocol (MEFP)-enabled.
|
||
********/
|
||
|
||
typedef WORD POLLTYPE;
|
||
|
||
#define POLLREQ_ADDRESS 1
|
||
#define POLLREQ_FILE 2
|
||
#define POLLREQ_MSGNAME 3
|
||
#define POLLREQ_G3 4
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@type NONE |SCHEDTYPE | Kinds of possible scheduling. Typedef'd to
|
||
a WORD.
|
||
|
||
@emem SCHED_ASAP | Schedule immediately.
|
||
|
||
@emem SCHED_BEFORE | Schedule immediately, and fail if the specified
|
||
time is past.
|
||
|
||
@emem SCHED_AFTER | Schedule any time after the specified time is past.
|
||
|
||
@emem SCHED_CHEAPTIMES | Schedule only between cheap time periods
|
||
as specified by the Provider's local settings. Only the time of
|
||
day, as specified by the start time and stop time elements of the
|
||
<t SENDJOBTIME> structure, have any meaning. In fact, the day,
|
||
date, month, and year are not guaranteed to be filled in.
|
||
|
||
********/
|
||
|
||
typedef WORD SCHEDTYPE;
|
||
|
||
#define SCHED_ASAP 1
|
||
#define SCHED_BEFORE 2
|
||
#define SCHED_AFTER 3
|
||
#define SCHED_CHEAPTIMES 4
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@type NONE | PROVIDERSTATE | A DWORD which describes the state of the Provider.
|
||
Can consist of a combination of the following flags:
|
||
|
||
@emem PROVIDER_OK | Standard OK state - no action is required.
|
||
|
||
@emem PROVIDER_OFFLINE | Provider is offline - client should do
|
||
the same. Offline indicates that the Provider is no longer
|
||
actively able to send or receive jobs.
|
||
|
||
@emem PROVIDER_NO_RESPONSE | No response from Provider. Client
|
||
should go offline.
|
||
|
||
@emem PROVIDER_BADERROR | Bad error at Provider. Client should go
|
||
offline.
|
||
|
||
@emem PROVIDER_RECEIVES_WAITING | Client should poll for receives.
|
||
|
||
@emem PROVIDER_SENDS_COMPLETED | Client should poll for completed
|
||
send status.
|
||
********/
|
||
|
||
typedef DWORD PROVIDERSTATE;
|
||
|
||
#define PROVIDER_OK 0x0000
|
||
#define PROVIDER_OFFLINE 0x0001
|
||
#define PROVIDER_NO_RESPONSE 0x0002
|
||
#define PROVIDER_BADERROR 0x0004
|
||
#define PROVIDER_RECEIVES_WAITING 0x0008
|
||
#define PROVIDER_SENDS_COMPLETED 0x0010
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@type NONE | JOBSTATE | A WORD identifying the state of a fax job.
|
||
|
||
@emem jstNewMsg | Just received from mail spooler.
|
||
@emem jstProcessingRecipients | Deciding what needs to be sent.
|
||
@emem jstRendering | Being rendered (Used internally by client).
|
||
@emem jstReadyToSend | Waiting to be schedulable.
|
||
@emem jstSchedulable | Ready to be transmitted.
|
||
@emem jstTransmitting | Being transmitted.
|
||
@emem jstWaitingForServer | Given to network Provider (Used internally
|
||
by client).
|
||
@emem jstWaitingForClient | Waiting for client to take back.
|
||
|
||
********/
|
||
|
||
typedef WORD JOBSTATE;
|
||
|
||
#define jstNewMsg 0
|
||
#define jstProcessingRecipients 1
|
||
#define jstRendering 2
|
||
#define jstReadyToSend 3
|
||
#define jstSchedulable 4
|
||
#define jstTransmitting 5
|
||
#define jstAllDone 6
|
||
#define jstWaitingForServer 7
|
||
#define jstWaitingForClient 8
|
||
|
||
|
||
|
||
|
||
/****
|
||
@doc EXTERNAL SRVRDLL OVERVIEW
|
||
|
||
@topic Data Structures |
|
||
Most structures defined here are in a packed format; that is,
|
||
there are no pointers to external objects. This is done so
|
||
they can be easily stored in a file or transmitted as a block
|
||
across the network.
|
||
|
||
Most structures
|
||
have two size fields. The HeaderSize field gives the defined
|
||
size of the structure, which is used for versioning the structure.
|
||
If the structure is expanded in the future, this size can be
|
||
used to maintain backward compatibility. The TotalSize field
|
||
indicates the size of the whole structure along with all its data.
|
||
|
||
All strings and other variable-length data items such as
|
||
structures are represented in the structure by an offset from the
|
||
beginning of the structure. The actual data for these elements
|
||
begins at that offset. The length of the data is indicated by
|
||
the item itself. If it is a string, it is null-terminated. If
|
||
it is another structure, the size fields will convey this
|
||
information.
|
||
|
||
All files referenced in the structures are created in the spool
|
||
directory specified in LMI_InitProvider.
|
||
|
||
****/
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types LMICUSTOMOPTION | Overlay of LMI Custom Option data. For
|
||
MAPI 1.0, Win32 implementations, this structure is found
|
||
in the MAPI message property PR_FAX_LMI_CUSTOM_OPTION
|
||
(property tag value 0x4513.)
|
||
|
||
@field DWORD | dwTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wNumRecords | Number of records in the Custom Option
|
||
data. This is also eqaul to the size of the dwOffsetTable.
|
||
|
||
@field DWORD | dwOffsetTable[] | Table of offsets to the records
|
||
of type LMICUSTOMOPTIONRECORD. All offsets are from the
|
||
top of the LMICUSTOMOPTION structure. The records should
|
||
directly follow this array.
|
||
********/
|
||
|
||
#ifndef RC_INVOKED
|
||
#pragma warning (disable: 4200)
|
||
#endif
|
||
|
||
typedef struct _LMICUSTOMOPTION {
|
||
DWORD dwTotalSize;
|
||
WORD wHeaderSize;
|
||
WORD wNumRecords;
|
||
DWORD dwOffsetTable[0];
|
||
} LMICUSTOMOPTION, FAR *LPLMICUSTOMOPTION;
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types LMICUSTOMOPTIONRECORD | Record overlay of LMI Custom Option data.
|
||
|
||
@field DWORD | dwTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wPad | Keep DWORD alignment.
|
||
|
||
@field CHAR | szUniqueName[32] | Unique name specified by
|
||
provider. This is used for identification of the
|
||
provider's record within the LMICUSTOMOPTION and should
|
||
contain some encoding of the provider developer company.
|
||
eg, "Microsoft:Netfax". The string MUST be null
|
||
terminated so that providers may do strcmp's to detect
|
||
their own section.
|
||
|
||
@field BYTE | lpData[] | Here's the data.
|
||
|
||
********/
|
||
typedef struct _LMICUSTOMOPTIONRECORD {
|
||
DWORD dwTotalSize;
|
||
WORD wHeaderSize;
|
||
WORD wPad;
|
||
CHAR szUniqueName[32];
|
||
BYTE lpData[];
|
||
} LMICUSTOMOPTIONRECORD, FAR *LPLMICUSTOMOPTIONRECORD;
|
||
|
||
#ifndef RC_INVOKED
|
||
#pragma warning (default: 4200)
|
||
#endif
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types LMIFORMAT | Describes a format.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field FAXERROR | feError | Indicates if there were any errors while
|
||
trying to generate this format. If this field is not set to
|
||
zero, the format file pointed to by the szFileName field may be
|
||
invalid and should not be used. This error value might need to be
|
||
propagated into the <e LMIRECIPSTATUS.feError> field for recipients
|
||
which fail as a result of this format not being ready.
|
||
|
||
@field CHAR | szFileName[16] | The filename containing the actual
|
||
format data.
|
||
|
||
@field FORMATTYPE | ftFormatType | Which format this represents.
|
||
|
||
@field WORD | wPad | Keep DWORD alignment.
|
||
********/
|
||
typedef struct _LMIFORMAT {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
FAXERROR feError;
|
||
CHAR szFileName[16];
|
||
FORMATTYPE ftFormatType;
|
||
WORD wPad;
|
||
} LMIFORMAT, FAR *LPLMIFORMAT;
|
||
#define MAXFORMATSIZE (sizeof(LMIFORMAT))
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types LMIPOLLREQUEST | Describes a poll request message.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field WORD | wszRecipName | The name of this recipient. This
|
||
is present only if this recipient is from a Provider implemented
|
||
address book. In this case <e LMIRECIPIENT.wszAddressOffset> is zero.
|
||
|
||
@field WORD | wszAddressOffset | The Microsoft At Work address for this
|
||
recipient. Not present for recipients implemented in the
|
||
Provider's address book. See <t Microsoft At Work Address> for
|
||
details.
|
||
|
||
@field DWORD | dwPollContext |
|
||
The provider should report this value in the dwPollContext field
|
||
of the LMIRECVSTATUS structure for all the messages received as a
|
||
result of this poll request. This enables the client to associate the
|
||
received messages (reported to the client via LMI_ReportReceives)
|
||
with a particular poll request. A value of zero is valid, but not
|
||
useful, because all non-polled receives reported by LMI_ReportReceives
|
||
have zero as the dwPollContext in their LMIRECVSTATUS structure.
|
||
|
||
@field POLLTYPE | ptPollType | What type of a poll request this is.
|
||
|
||
@field WORD | wszPollNameOffset | The name to be sent along with the
|
||
poll request. The specific semantic meaning depends on the poll
|
||
type.
|
||
|
||
@field WORD | wszPollPasswordOffset | Offset to the password to be sent
|
||
along with the poll request.
|
||
|
||
@field WORD | wPad | Keep DWORD alignment.
|
||
********/
|
||
typedef struct _LMIPOLLREQUEST {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
WORD wszRecipName;
|
||
WORD wszAddressOffset;
|
||
DWORD dwPollContext;
|
||
POLLTYPE ptPollType;
|
||
WORD wszPollNameOffset;
|
||
WORD wszPollPasswordOffset;
|
||
WORD wPad;
|
||
} LMIPOLLREQUEST, FAR *LPLMIPOLLREQUEST;
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@types LMIQUEUEDATA | Represents queue information about a single job.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field DWORD | dwUniqueID | This can be used by the Provider to
|
||
pass in a context. Along with <e LMIQUEUEDATA.dwUniqueID2> and
|
||
<e LMIQUEUEDATA.wszSenderMachineNameOffset> this
|
||
must uniquely identify this job.
|
||
|
||
@field DWORD | dwUniqueID2 | See <e LMIQUEUEDATA.dwUniqueID>.
|
||
|
||
@field WORD | wszSenderMachineNameOffset | Points to a string which
|
||
identifies the machine originating this job. Used for display in
|
||
the queue. Also uniquely identifies the job along with the unique
|
||
ID's. This should be the same as the string pointed to by the
|
||
<e LMISENDJOB.wszSenderMachineNameOffset> field in <t LMISENDJOB>.
|
||
|
||
@field WORD | wszSubjectOffset | Offset to the subject of this
|
||
message. This should be the same as the string pointed to by the
|
||
<e LMISENDJOB.wszSubjectOffset> field in <t LMISENDJOB>.
|
||
|
||
@field DWORD | dwSize | This should be the same as what was passed
|
||
in as <e LMISENDJOB.dwTotalFileSize> in <t LMISENDJOB>.
|
||
|
||
@field WORD | wNumRecipients | This should be the same as what was passed
|
||
in as <e LMISENDJOB.wNumRecipients> in <t LMISENDJOB>.
|
||
|
||
@field JOBSTATE | jstState | Current overall status for this job.
|
||
|
||
@field WORD | wNumRecipDone | Number of recipients for which transmission
|
||
has been completed, either succesfully or unsuccesfully.
|
||
|
||
@field WORD | wtmSendTimeOffset | Current scheduling state for this
|
||
job. Offset to a <t SENDJOBTIME> structure.
|
||
|
||
@field WORD | wrgbCustomStatusOffset | Offset to Provider defined custom
|
||
status information. This is passed to the
|
||
<f LMI_DisplayCustomStatus> function when the user asks to see
|
||
detailed status for this job.
|
||
|
||
@field WORD | wCustomDataSize | Size of the custom data pointed to by
|
||
the <e LMISENDJOB.wrgbCustomStatusOffset> field.
|
||
|
||
********/
|
||
|
||
typedef struct _LMIQUEUEDATA {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
DWORD dwUniqueID;
|
||
DWORD dwUniqueID2;
|
||
WORD wszSenderMachineNameOffset;
|
||
WORD wszSubjectOffset;
|
||
DWORD dwSize;
|
||
WORD wNumRecipients;
|
||
JOBSTATE jstState;
|
||
WORD wNumRecipDone;
|
||
WORD wtmSendTimeOffset;
|
||
WORD wrgbCustomStatusOffset;
|
||
WORD wCustomDataSize;
|
||
} LMIQUEUEDATA, NEAR *NPLMIQUEUEDATA, FAR *LPLMIQUEUEDATA;
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@types LMIQUEUEFILEHEADER | A queue file consists of this header followed
|
||
by the queue data.
|
||
|
||
@field DWORD | dwSig | This must be set to SIG_QUEUEFILE.
|
||
|
||
@field DWORD | dwSize | Must be set to the total file size.
|
||
|
||
@field DWORD | dwNumEntries | Number of queue entries in the file. The
|
||
header is followed by this many <t LMIQUEUEDATA> structures.
|
||
********/
|
||
|
||
#define SIG_QUEUEFILE 0x56873
|
||
typedef struct _LMIQUEUEFILEHEADER {
|
||
DWORD dwSig; // Should always be NQFH
|
||
DWORD dwSize; // Total file size
|
||
DWORD dwNumEntries; // Num of entries in the file
|
||
} LMIQUEUEFILEHEADER;
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types LMIRECIPIENT | Describes a recipient.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field WORD | wszRecipName | The name of this recipient. This
|
||
is present only if this recipient is from a Provider implemented
|
||
address book. In this case <e LMIRECIPIENT.wszAddressOffset> is
|
||
zero and <e LMIRECIPIENT.szCoverFile> is a reference to a template
|
||
on the Provider.
|
||
|
||
@field WORD | wszAddressOffset | The Microsoft At Work address for this
|
||
recipient. Not present for recipients implemented in the
|
||
Provider's address book. See <lq>Microsoft At Work Address<rq> for
|
||
details.
|
||
|
||
@field CHAR | szCoverFile[16] | The filename containing the cover
|
||
page data if any for this recipient. This could be a reference to
|
||
a previously uploaded template if this is a recipient from the
|
||
Provider's address book. If the first word of this character array
|
||
is 0 but the second word is non-null, then the second word represent
|
||
a WORD offset into the LMIRECIPIENT structure where the fully
|
||
qualified path may be found.
|
||
|
||
@field CHAR | szEncryptFile[16] | If one of the linearized formats
|
||
pointed to by this recipient structure is a public key encrypted
|
||
message being sent to multiple recipients, then this field contains
|
||
the filename for a linearized format of the message encrypted with
|
||
this recipients public key. This field will not be valid under any
|
||
other circumstance.
|
||
|
||
@field WORD | wG3FormatIndex | If non-zero, this specifies a 1-based
|
||
index into the format structure array. It implies that this
|
||
recipient can accept this version of the G3 format. Note that
|
||
there may still be some run time conversions necessary on this
|
||
format at the time of sending. For instance, the format may be
|
||
MMR, whereas on calling it may be discovered that the recipient
|
||
only accepts MH. In this case, the Provider is responsible
|
||
for converting this on the fly.
|
||
|
||
@field WORD | wLinImageFormatIndex | Index into the format array. Pointer
|
||
to a linearized image format which can be sent to this recipient.
|
||
|
||
@field WORD | wLinBinaryFormatIndex | Index into the format array. Pointer
|
||
to a linearized binary format which can be sent to this recipient.
|
||
|
||
@field WORD | wPad | Keep DWORD alignment.
|
||
|
||
********/
|
||
|
||
typedef struct _LMIRECIPIENT {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
WORD wszRecipName;
|
||
WORD wszAddressOffset;
|
||
CHAR szCoverFile[16];
|
||
CHAR szEncryptFile[16];
|
||
WORD wG3FormatIndex;
|
||
WORD wLinImageFormatIndex;
|
||
WORD wLinBinaryFormatIndex;
|
||
WORD wPad;
|
||
} LMIRECIPIENT, FAR *LPLMIRECIPIENT;
|
||
#define MAXRECIPIENTSIZE (sizeof(LMIRECIPIENT) + MAX_ADDRESS_LENGTH)
|
||
|
||
|
||
/*******
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types LMIRECIPSTATUS | Used to convey information for the final
|
||
status of the completed send for a recipient.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field WORD | wrcCapsOffset | An offset to a <t MACHINECAPS> structure
|
||
containing the updated capabilites for this recipient.
|
||
|
||
@field FORMATTYPE | ftSentFormat | The format type which was finally sent
|
||
to this recipient.
|
||
|
||
@field FAXERROR | feError | The final status for this recipient.
|
||
|
||
@field SYSTEMTIME | dtTransmitTime | The time at which the fax was last
|
||
attempted to be sent.
|
||
|
||
@field DWORD | dwConnectTime | Connect time for the transmission in
|
||
seconds.
|
||
|
||
*******/
|
||
|
||
typedef struct _LMIRECIPSTATUS {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
WORD wrcCapsOffset;
|
||
FORMATTYPE ftSentFormat;
|
||
FAXERROR feError;
|
||
DWORD dwConnectTime;
|
||
SYSTEMTIME dtTransmitTime;
|
||
} LMIRECIPSTATUS, FAR *LPLMIRECIPSTATUS;
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@types LMIRECVSTATUS | Gives the status for a received fax.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field FAXERROR | feError | The final status for this receive.
|
||
|
||
@field SYSTEMTIME | dtRecvTime | Should be filled with the time at
|
||
which the fax was received.
|
||
|
||
@field DWORD | dwConnectTime | The connect time for the
|
||
transmission in seconds.
|
||
|
||
@field DWORD | dwPollContext | If this receive was actually in response
|
||
to a poll request, then this will be set to the same value which
|
||
was passed in in the <t LMIPOLLREQUEST> structure sent along with
|
||
the poll request.
|
||
|
||
@field ATOM | atFile | The filename containing the received fax file. This
|
||
file should be in the spool directory agreed upon in the
|
||
<f LMI_InitLogicalModem> call.
|
||
|
||
@field WORD | wPad | Keep DWORD alignment.
|
||
|
||
********/
|
||
|
||
typedef struct _LMIRECVSTATUS {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
FAXERROR feError;
|
||
SYSTEMTIME dtRecvTime;
|
||
DWORD dwConnectTime;
|
||
DWORD dwPollContext;
|
||
ATOM atFile;
|
||
WORD wPad;
|
||
} LMIRECVSTATUS, FAR *LPLMIRECVSTATUS;
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types LMISENDJOB | Describes a new fax job. A fax job specifies a send to
|
||
one or more recipients.
|
||
|
||
@field DWORD | dwTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | fUnicode | Indicates whether the string pointed to by
|
||
<e LMISENDJOB.wszSenderMachineNameOffset> is a Unicode string or
|
||
not.
|
||
|
||
@field WORD | wszSenderMachineNameOffset | Points to a string which
|
||
identifies the machine originating this job. Used for display in
|
||
the queue. Also uniquely identifies the job along with the unique
|
||
ID's.
|
||
|
||
@field WORD | wszSubjectOffset | Subject of the message. Used for display
|
||
purposes in the queue.
|
||
|
||
@field DWORD | dwUniqueID | Used by the client to uniquely identify
|
||
this send fax job along with <e LMISENDJOB.dwUniqueID2>.
|
||
|
||
@field DWORD | dwUniqueID2 | Used along with <e LMISENDJOB.dwUniqueID> to
|
||
identify this job.
|
||
|
||
@field DWORD | dwBillingCode | Billing code for this job. This is to allow
|
||
Providers to keep accurate billing logs.
|
||
|
||
@field DWORD | dwTotalFileSize | An approximation for the total size
|
||
of the data required to be transmitted for this message for all
|
||
recipients combined. Meant for display purposes in the queue to allow some
|
||
idea of how long the job is likely to take.
|
||
|
||
@field WORD | wtmSendTimeOffset | Offset to a <t SENDJOBTIME> scheduling
|
||
structure.
|
||
|
||
@field WORD | wprPollRequestOffset | Offset to a poll request structure.
|
||
See <t LMIPOLLREQUEST> for details. If this offset is set, there
|
||
are no recipient or format structures associated with this job. In
|
||
other words, the rgwStructOffsets field will be zero.
|
||
|
||
@field WORD | wrgbCustomOptionOffset | Offset to custom message options
|
||
set for this message. This is an offset to data returned by a
|
||
call to <f LMI_SetCustomMsgOptions>. The first DWORD of the data
|
||
indicates the size of the data.
|
||
|
||
@field WORD | wNumRecipients | The number of recipients for this job.
|
||
|
||
@field WORD | wNumFormats | The number of rendered formats associated
|
||
with this job.
|
||
|
||
@field WORD | wPad | Keep DWORD alignment.
|
||
|
||
@field DWORD | rgdwStructOffsets[] | Array of size
|
||
<e LMISENDJOB.wNumFormats> and <e LMISENDJOB.wNumRecipients>
|
||
offsets to format and recipient structures. The <t LMISENDJOB>
|
||
structure is followed by all these structures. The <t LMIFORMAT>
|
||
structures come first.
|
||
|
||
********/
|
||
|
||
#ifndef RC_INVOKED
|
||
#pragma warning (disable: 4200)
|
||
#endif
|
||
|
||
// The basic fax job structure for any send
|
||
typedef struct _LMISENDJOB {
|
||
DWORD dwTotalSize;
|
||
WORD wHeaderSize;
|
||
WORD fUnicode;
|
||
WORD wszSenderMachineNameOffset;
|
||
WORD wszSubjectOffset;
|
||
DWORD dwUniqueID;
|
||
DWORD dwUniqueID2;
|
||
DWORD dwBillingCode;
|
||
DWORD dwTotalFileSize;
|
||
WORD wtmSendTimeOffset;
|
||
WORD wprPollRequestOffset;
|
||
WORD wrgbCustomOptOffset;
|
||
WORD wNumRecipients;
|
||
WORD wNumFormats;
|
||
WORD wPad;
|
||
DWORD rgdwStructOffsets[];
|
||
} LMISENDJOB, FAR *LPLMISENDJOB;
|
||
|
||
#ifndef RC_INVOKED
|
||
#pragma warning (default: 4200)
|
||
#endif
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types LMISENDSTATUS | Conveys back status information at the end of a
|
||
send job.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed
|
||
size header portion of the structure.
|
||
|
||
@field WORD | wTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field FAXERROR | feJobError | Indicates any global error which
|
||
caused all recipients to fail, such as cancellation by the user, or
|
||
an out of memory situation. This should only be set if none of
|
||
the recipients for this message were succesfully contacted.
|
||
|
||
@field DWORD | dwUniqueID | Used by the client to uniquely identify
|
||
this send fax job along with <e LMISENDSTATUS.dwUniqueID2>.
|
||
This should be the same as the one passed in the <t LMISENDJOB>
|
||
structure.
|
||
|
||
@field DWORD | dwUniqueID2 | Used along with <e LMISENDSTATUS.dwUniqueID>
|
||
to identify this job. Should be the same as the one passed in the
|
||
<t LMISENDJOB> structure.
|
||
|
||
@field WORD | fUnicode | Indicates that the
|
||
<e LMISENDSTATUS.szSenderMachineName> field contains a unicode
|
||
string.
|
||
|
||
@field WORD | wPad | Keep DWORD alignment.
|
||
|
||
@field CHAR | szSenderMachineName[MAX_SERVERNAME_SIZE * 2] | Points to a
|
||
string which identifies the machine originating this job.
|
||
This should be the same as the one passed in the <t LMISENDJOB>
|
||
structure.
|
||
|
||
@field LMIRECIPSTATUS | rgnrsRecipStatus[] | An array of recipient status
|
||
structures, one for each recipient of the message. These structures
|
||
are not required if <e LMISENDSTATUS.feJobError> is set. If present,
|
||
the order of recipients in this array must be the same as the order in
|
||
which they were submitted in the <t LMISENDJOB> structure.
|
||
|
||
********/
|
||
#ifndef RC_INVOKED
|
||
#pragma warning (disable: 4200)
|
||
#endif
|
||
|
||
typedef struct _LMISENDSTATUS {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
FAXERROR feJobError;
|
||
DWORD dwUniqueID;
|
||
DWORD dwUniqueID2;
|
||
WORD fUnicode;
|
||
WORD wPad;
|
||
CHAR szSenderMachineName[MAX_SERVERNAME_SIZE*2];
|
||
LMIRECIPSTATUS rgnrsRecipStatus[];
|
||
} LMISENDSTATUS, FAR *LPLMISENDSTATUS;
|
||
|
||
#ifndef RC_INVOKED
|
||
#pragma warning (default: 4200)
|
||
#endif
|
||
|
||
|
||
/*******
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types MACHINECAPS | This structure describes the capabilites for a
|
||
fax machine. It is used to return updated capabilities for
|
||
any fax machine contacted and allows intelligent preprocessing
|
||
the next time a fax is sent to the same number.
|
||
|
||
@field WORD | wHeaderSize | Gives the size for the fixed size header
|
||
portion of the structure.
|
||
|
||
@field WORD | wTotalSize | Total number of BYTES occupied by the
|
||
structure along with its concomitant variable sized data.
|
||
|
||
@field WORD | wbDISCapsOffset | Offset to a DIS frame containing
|
||
capabilities of the machine. The format of the frame is defined
|
||
by the <t FR> structure.
|
||
|
||
@field WORD | wbNSFCapsOffset | Offset to a sequence of encrypted
|
||
Microsoft At Work NSF frames containing At Work capabilities for
|
||
the machine. The format of each frame is defined by the <t FR>
|
||
structure. A frame with a null type and 0 length terminates the
|
||
sequence. Valid for any Microsoft At Work enabled Provider.
|
||
*******/
|
||
|
||
typedef struct {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
WORD wbDISCapsOffset;
|
||
WORD wbNSFCapsOffset;
|
||
} MACHINECAPS, FAR *LPMACHINECAPS;
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL INITIALIZATION
|
||
|
||
@types MODEMCAPS | Specifies all the capabilities for a logical modem. When
|
||
specified by the client (for example in LMI_ExchangeCaps), the
|
||
structure represents the capabilities which are supported
|
||
by the client.
|
||
|
||
@field WORD | wHeaderSize | Size of this structure.
|
||
|
||
@field WORD | wTotalSize | Total size with concomitant data.
|
||
|
||
@field DWORD | dwGenCaps | Lists general capabilities. The following flags
|
||
can be set:
|
||
|
||
@flag OWN_ADDRESS_BOOK | Indicates that the modem can maintain it's own
|
||
address book.
|
||
@flag ADVANCED_STORE | Indicates that the modem can manage its own
|
||
store and upload messages to it.
|
||
@flag COVER_PAGE_RENDERER | Indicates that the modem can render
|
||
Microsoft At Work cover page templates.
|
||
@flag REAL_TIME_STATUS | Indicates that real time status updates for
|
||
the current job are supported.
|
||
@flag MULTIPLE_RECIPIENTS | Indicatest that messages can be sent to
|
||
multiple recipients.
|
||
@flag PER_RECIP_COVER | Indicates that per recipient cover pages are
|
||
supported. If this is not set, the <e LMIRECIPIENT.szCoverFile>
|
||
field of the <t LMIRECIPIENT> structure will not be used.
|
||
@flag PER_RECIP_ENCRYPTION | Indicates that key encrypted sends to
|
||
multiple recipients are supported. If this is not set,
|
||
the <e LMIRECIPIENT.szEncryptFile> field of
|
||
the <t LMIRECIPIENT> structure will never be used.
|
||
@flag CUSTOM_MSG_OPTIONS | Indicates that the modem supports setting of
|
||
custom per message options. If not set, the function
|
||
<f LMI_SetCustomMsgOptions> need not be implemented.
|
||
@flag POLL_REQUEST | Indicates that poll requests using T30 fields
|
||
is supported. If not, the <t LMIPOLLREQUEST> structure should
|
||
not be used.
|
||
@flag ABOVE64K_STRUCTURES | Indicates that the <t LMISENDJOB> structure
|
||
can have a total size > 64K. For x86 based systems, this allows
|
||
far pointers to be used instead of huge pointers.
|
||
|
||
@flag ALLOW_SHARING | Indicates that this device can be shared.
|
||
|
||
|
||
@flag PRECIOUS_RESOURCE | Indicates that this device is a precious
|
||
resource on the local machine which may need to be shared with
|
||
other MAPI providers. For example, a modem which may be used
|
||
by another provider to access dial-up services for mail delivery.
|
||
The MAPI transport will use this flag to determine if it should
|
||
support MAPI's FlushQueues semantics.
|
||
|
||
@field DWORD | dwSchedCaps | Lists scheduling related capabilities. The
|
||
following flags are defined:
|
||
|
||
@flag SUPPORT_QUEUEING | Indicates whether the modem can queue up
|
||
multiple jobs at a time, or can only process them one at a time.
|
||
@flag ALLOW_SCHED_ASAP | Indicates that jobs can be scheduled as ASAP.
|
||
@flag ALLOW_SCHED_AFTER | Indicates that jobs can be scheduled as
|
||
SCHED_AFTER.
|
||
@flag ALLOW_SCHED_BEFORE | Indicates that jobs can be scheduled as
|
||
SCHED_BEFORE.
|
||
@flag ALLOW_SCHED_CHEAPTIMES | Indicates that jobs can be scheduled
|
||
for cheap times. This capability assumes that the cheap times are
|
||
defined by the Provider.
|
||
@flag ALLOW_CLIENT_CHEAPTIMES | Allows the client to set the cheap
|
||
times independently for each job.
|
||
@flag USE_UTC_TIMES | Indicates that the times indicated in the
|
||
<t SENDJOBTIME> structure are in UTC and not in local time. If
|
||
any of the client or the Provider do not support this capability
|
||
the times will revert to being local times.
|
||
|
||
@field WORD | wmcOffset | Offset to <t MACHINECAPS> structure which should
|
||
be filled in with all the capabilities which this modem has:
|
||
essentially what it would send back to a caller in the
|
||
DIS and NSF frames.
|
||
|
||
@field WORD | wMaxRetries | Indicates the maximum number of retries
|
||
permitted for a send. The client should not set the
|
||
<e SENDJOBTIME.wNumRetries> field of the <t SENDJOBTIME> structure
|
||
to a number greater than this.
|
||
|
||
@field WORD | wMinTimeBetweenRetries | Specifies the minimum amount of
|
||
time that can be specified between retries. The client should never
|
||
set the <e SENDJOBTIME.wMinBetweenRetries> field of the
|
||
<t SENDJOBTIME> structure to anything less than this.
|
||
|
||
@field WORD | wPad | Keep DWORD alignment.
|
||
|
||
********/
|
||
|
||
typedef struct {
|
||
WORD wHeaderSize;
|
||
WORD wTotalSize;
|
||
DWORD dwGenCaps;
|
||
DWORD dwSchedCaps;
|
||
WORD wmcOffset;
|
||
WORD wMaxRetries;
|
||
WORD wMinTimeBetweenRetries;
|
||
WORD wPad;
|
||
} MODEMCAPS, FAR *LPMODEMCAPS;
|
||
|
||
// General caps
|
||
#define OWN_ADDRESS_BOOK 0x0001
|
||
#define ADVANCED_STORE 0x0002
|
||
#define COVER_PAGE_RENDERER 0x0004
|
||
#define REAL_TIME_STATUS 0x0008
|
||
#define MULTIPLE_RECIPIENTS 0x0010
|
||
#define PER_RECIP_COVER 0x0020
|
||
#define PER_RECIP_ENCRYPTION 0x0040
|
||
#define CUSTOM_MSG_OPTIONS 0x0080
|
||
#define POLL_REQUEST 0x0100
|
||
#define ABOVE64K_STRUCTURES 0x0200
|
||
#define ALLOW_SHARING 0x0400
|
||
#define ALLOW_RESHARING 0x0800
|
||
#define PRECIOUS_RESOURCE 0x1000
|
||
|
||
// Sched caps
|
||
#define SUPPORT_QUEUEING 0x0001
|
||
#define ALLOW_SCHED_ASAP 0x0002
|
||
#define ALLOW_SCHED_AFTER 0x0004
|
||
#define ALLOW_SCHED_BEFORE 0x0008
|
||
#define ALLOW_SCHED_CHEAPTIMES 0x0010
|
||
#define ALLOW_CLIENT_CHEAPTIMES 0x0020
|
||
#define USE_UTC_TIMES 0x0040
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL DATATYPES
|
||
|
||
@types SENDJOBTIME | Contains all the scheduling informations for a job.
|
||
|
||
@field WORD | wHeaderSize | Size of this structure.
|
||
|
||
@field WORD | wNumRetries | Maximum number of retries for busy numbers.
|
||
|
||
@field WORD | wMinBetweenRetries | Minutes to be allowed to elapse between successive
|
||
retries.
|
||
|
||
@field SCHEDTYPE | stSchedType | Type of scheduling required for this job.
|
||
|
||
@field SYSTEMTIME | dtStartTime | Time after which job is schedulable.
|
||
|
||
@field SYSTEMTIME | dtStopTime | Time after which job is not schedulable.
|
||
|
||
********/
|
||
|
||
typedef struct {
|
||
WORD wHeaderSize;
|
||
WORD wNumRetries;
|
||
WORD wMinBetweenRetries;
|
||
SCHEDTYPE stSchedType;
|
||
SYSTEMTIME dtStopTime;
|
||
SYSTEMTIME dtStartTime;
|
||
} SENDJOBTIME, FAR *LPSENDJOBTIME;
|
||
|
||
|
||
|
||
|
||
/****
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@topic The Logical Modem Interface |
|
||
The following section details the functions that make up the
|
||
Logical Modem Interface.
|
||
|
||
****/
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_AbortSendJob | Aborts the specified send job
|
||
from the Provider's queue.
|
||
|
||
@parm DWORD | dwLogicalModem | The logical modem from whose queue the
|
||
job is to be cancelled.
|
||
|
||
@parm LPTSTR | lpszSenderMachineName | String identifying the sender
|
||
machine name. This parameter, along with the <p dwUniqueID> and
|
||
<p dwUniqueID2> uniquely identify this job for the Provider.
|
||
These all must be same as the values passed in the
|
||
<t LMISENDJOB> structure passed into <f LMI_SendFax>.
|
||
|
||
@parm DWORD | dwUniqueID | See <p lpszSenderMachineName>.
|
||
|
||
@parm DWORD | dwUniqueID2 | See <p lpszSenderMachineName>.
|
||
|
||
@rdesc LMI_SUCCESS on success.
|
||
|
||
@comm The abort can be performed asynchronously by the Provider. Return
|
||
from this function does not imply any guarantees as to the time
|
||
within which the job will be aborted. The provider reports
|
||
the final state of the job via LMI_ReportSend. The client will ensure
|
||
that this function is only called to abort jobs which were
|
||
initiated on its machine.
|
||
|
||
********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_AbortSendJob(DWORD dwLogicalModem,
|
||
LPTSTR lpszSenderMachineName,
|
||
DWORD dwUniqueID,
|
||
DWORD dwUniqueID2);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_AbortSendJob)(DWORD dwLogicalModem,
|
||
LPTSTR lpszSenderMachineName,
|
||
DWORD dwUniqueID,
|
||
DWORD dwUniqueID2);
|
||
|
||
/********
|
||
|
||
@doc EXTERNAL SRVRDLL INSTALLATION
|
||
|
||
@func LMI_RETURN | LMI_AddModem | Called to add a new logical modem to
|
||
the list of current modems.
|
||
|
||
@parm HWND | hDlg | The window handle of the parent dialog box. This
|
||
should be used as the parent for any new dialog boxes which are
|
||
displayed.
|
||
|
||
@parm LPTSTR | modembuf | Pointer to the buffer where the call
|
||
should return a zero-terminated string uniquely identifying the
|
||
logical modem the user selected. <p buflen> gives the maximum
|
||
length this string can be (including the zero termination).
|
||
|
||
@parm WORD | buflen | Length of the buffer pointed to by
|
||
<p modembuf>. This is guaranteed to be at least 64 BYTES.
|
||
|
||
@rdesc The dialog should handle notifying the user of errors if it can
|
||
put its first dialog up.
|
||
|
||
@comm This function is called to put up a dialog box allowing the user
|
||
to select a logical modem to add to the list of current modems.
|
||
The function should return a displayable string that is shown
|
||
in the user list. This is also the string which is passed in to
|
||
identify the modem in the <f LMI_InitLogicalModem> call.
|
||
|
||
********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_AddModem(HWND hDlg,
|
||
LPTSTR modembuf,
|
||
WORD buflen);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_AddModem)(HWND hDlg,
|
||
LPTSTR modembuf,
|
||
WORD buflen);
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api PROVIDERSTATE | LMI_CheckProvider | Pings the Provider to see if it
|
||
is alive.
|
||
|
||
@rdesc Returns state of Provider. This return value can be used to make
|
||
the client poll the Provider for events.
|
||
|
||
@comm This can be called periodically by the client and should be
|
||
implemented in as efficient a manner as possible. It can be
|
||
used by the client to decide whether it needs to go offline
|
||
among other things.
|
||
|
||
It is not mandatory for this to return a completely accurate
|
||
state of the Provider. If finding this information is very
|
||
expensive, the Provider can, at its discretion, do this less
|
||
frequently, and return the stale state in the intermediate polls.
|
||
|
||
@parm DWORD | dwLogicalModem | Handle representing the logical modem to
|
||
be checked.
|
||
|
||
@parm LPATOM | lpatError | If there was an error and the Provider is
|
||
having problems, a global atom containing a descriptive string
|
||
for this error can be returned here. Any string returned will be
|
||
displayed to the user at the client's discretion. The atom will
|
||
be freed by the client.
|
||
********/
|
||
|
||
PROVIDERSTATE FAR PASCAL LMI_CheckProvider(DWORD dwLogicalModem,
|
||
LPATOM lpatError);
|
||
typedef PROVIDERSTATE (FAR PASCAL FAR *LPLMI_CheckProvider) (DWORD dwLogicalModem,
|
||
LPATOM lpatError);
|
||
|
||
|
||
/*******
|
||
@doc EXTERNAL SRVRDLL CONFIGURATION
|
||
|
||
@api LMI_RETURN | LMI_ConfigureModem | Called to let the user
|
||
configure a logical modem.
|
||
|
||
@parm HWND | hDlg | The window handle of the parent dialog box. This
|
||
should be used as the parent for any new dialog boxes which are
|
||
displayed.
|
||
|
||
@parm LPTSTR | lpszModem | Pointer to string representing the logical
|
||
modem to be configured. This is the same string which was
|
||
returned by <f LMI_AddModem>.
|
||
|
||
@rdesc Returns LMI_SUCCESS if successful.
|
||
|
||
*******/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_ConfigureModem(HWND hDlg,
|
||
LPTSTR lpszModem);
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_DeinitLogicalModem | Deinitializes the
|
||
specified logical modem.
|
||
|
||
@parm DWORD | dwLogicalModem | Handle representing the logical modem to
|
||
be deinitialized.
|
||
|
||
@rdesc LMI_SUCCESS if successful.
|
||
********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_DeinitLogicalModem (DWORD dwLogicalModem);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_DeinitLogicalModem) (DWORD
|
||
dwLogicalModem);
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_DeinitProvider| Deinitializes the LMI provider.
|
||
|
||
@rdesc LMI_SUCCESS if successful.
|
||
********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_DeinitProvider (VOID);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_DeinitProvider) (VOID);
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_DisplayCustomStatus | Displays extended status
|
||
information for a job.
|
||
|
||
@parm HWND | hwndParent | Parent window handle which should be used for
|
||
displaying any dialogs.
|
||
|
||
@parm LPBYTE | lpbCustomData | Pointer to the start of the custom
|
||
data associated with this job.
|
||
|
||
@parm WORD | wCustomDataSize | Size in BYTES of the data pointed to
|
||
by <p lpbCustomData>.
|
||
*********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_DisplayCustomStatus(HWND hwndParent,
|
||
LPBYTE lpbCustomData,
|
||
WORD wCustomDataSize);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_DisplayCustomStatus)(HWND hwndParent,
|
||
LPBYTE lpbCustomData,
|
||
WORD wCustomDataSize);
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_ExchangeCaps | Allows the client and the Provider
|
||
to exchangde <t MODEMCAPS> structures without having to initialize
|
||
the Provider or a logical modem. This is one of two calls which
|
||
can be made without an initialized modem.
|
||
|
||
@parm LPTSTR | lpszLogicalModem | Pointer to string identifying logical
|
||
modem the caps belong to.
|
||
|
||
@parm LPMODEMCAPS | lpmcClient | Pointer to a <t MODEMCAPS> structure
|
||
that describes the capabilities of the client. This should be used
|
||
by the Provider to decide which formats can be understood by the
|
||
client. For instance, if the client only understands MH, then
|
||
the Provider would need to convert any received faxes into MH
|
||
before reporting them in <f LMI_ReportReceives>. Similarly, this
|
||
can indicate to the Provider whether or not features such as
|
||
uploading of messages and Provider address books are supported by
|
||
this particular client implementation. If this pointer is null,
|
||
it should be ignored.
|
||
|
||
@parm LPMODEMCAPS | lpmcProvider | Points to a <t MODEMCAPS> structure
|
||
which should be filled in with the capabilities of this Provider.
|
||
The size of the memory pointed to by this structure is filled in
|
||
the wTotalSize field of the structure. If this pointer is null,
|
||
no capabilities need to be returned.
|
||
|
||
@rdesc LMI_SUCCESS on success.
|
||
|
||
@comm It is perfectly valid for a Provider to return LMIERR_NOT_SUPPORTED
|
||
for this call. A Provider may need to do this if it cannot
|
||
determine the modem capabilities without actually initializing
|
||
the modem.
|
||
********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_ExchangeCaps (LPTSTR lpszLogicalModem,
|
||
LPMODEMCAPS lpmcClient,
|
||
LPMODEMCAPS lpmcProvider);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_ExchangeCaps)(LPTSTR lpszLogicalModem,
|
||
LPMODEMCAPS lpmcClient,
|
||
LPMODEMCAPS lpmcProvider);
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api DWORD | LMI_GetQueueFile | Retrieves the name of the queue file
|
||
for a logical modem from the Provider.
|
||
|
||
@parm DWORD | dwLogicalModem | A handle to the logical modem for which
|
||
the queue is desired. If a valid handle is supplied, the
|
||
<p lpszLogicalModemName> parameter should
|
||
be NULL.
|
||
|
||
@parm LPTSTR | lpszLogicalModemName | A string identifying the logical
|
||
modem for which the user wants to see the queue, if this modem
|
||
has not been initialized previously. This is one of two APIs which
|
||
can be called without initializing a modem. If this parameter is
|
||
used, the <p dwLogicalModem> parameter should be ignored.
|
||
|
||
@parm LPATOM | lpatFileName | The function should return a global
|
||
atom containing a fully qualified path name to the queue file.
|
||
This does not have to be on the local disk. The pathname should
|
||
be such that it can be passed to a Windows CreateFile call.
|
||
|
||
@parm WORD | wFlags | Can be any combination of the following flags:
|
||
|
||
@flag NGQ_USER_REQUEST | Implies that the queue update request
|
||
is being made due to an explicit user refresh request. Transports
|
||
which have expensive updates can use this to divide the normal
|
||
refresh rate while making sure that explicit requeusts do not
|
||
get ignored.
|
||
|
||
@rdesc LMI_SUCCESS on success.
|
||
|
||
@comm Ideally the client should be able to retrieve the queue for any
|
||
logical modem supported by this Provider, not necessarily the
|
||
one which is currently initialized. This allows the client to
|
||
choose a new modem intelligently if needed.
|
||
|
||
********/
|
||
|
||
#define NGQ_USER_REQUEST 0x0001
|
||
|
||
LMI_RETURN FAR PASCAL LMI_GetQueueFile (DWORD dwLogicalModem,
|
||
LPTSTR lpszLogicalModemName,
|
||
LPATOM lpatFileName,
|
||
WORD wFlags);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_GetQueueFile)(DWORD dwLogicalModem,
|
||
LPTSTR lpszLogicalModemName,
|
||
LPATOM lpatFileName,
|
||
WORD wFlags);
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_InitLogicalModem | Used to initialize a particular
|
||
logical modem.
|
||
|
||
@parm LPTSTR | lpszLogicalModem | String identifying the logical modem
|
||
to be initialized.
|
||
|
||
@parm LPDWORD | lpdwLogicalModem | A DWORD handle representing this
|
||
logical modem should be returned in this pointer if the function
|
||
is successful. The handle is valid until the client calls
|
||
LMI_DeinitLogicalModem with this handle.
|
||
|
||
@parm LPATOM | lpatClientName | A global atom containing an ASCII name
|
||
identifying this client must be returned here. This string is
|
||
used in the queue displays to identify jobs from this client on
|
||
the Provider. It is used by clients to restrict the jobs which
|
||
can be cancelled or rescheduled from their machines, so it
|
||
should be unique enough to prevent security holes. All string
|
||
comparisons using this name should be case-insensitive because case
|
||
is not necessarily preserved when using atoms.
|
||
|
||
@parm LPATOM | lpatPhone | A global atom containing the canonical phone
|
||
number for this logical modem. This is used to construct the
|
||
client's Microsoft At Work Address, and is the number put into
|
||
the FROM field of any messages sent. This needs to be filled in
|
||
if a non-null pointer is passed in.
|
||
|
||
@parm LPMODEMCAPS | lpmc | Points to a <t MODEMCAPS> structure which
|
||
should be filled in with the capabilities of this logical modem.
|
||
The size of the memory pointed to by this structure is filled in
|
||
the wTotalSize field of the structure. If this pointer is null,
|
||
no capabilities need to be returned.
|
||
|
||
@rdesc LMI_SUCCESS if successful. A handle to the logical modem should
|
||
be returned in <p lpdwLogicalModem>.
|
||
|
||
@comm Initializes a logical modem for further operations. The Provider
|
||
should use this to set up any necessary connections, and to make
|
||
sure that the Provider is up and running. The handle returned by
|
||
this function is used by any subsequent functions invoked for
|
||
this modem. Multiple modems may be initialized at the same time.
|
||
The handle returned may be used in multiple process contexts, so
|
||
the implementor should make sure any memory it references can be
|
||
accessed in different process contexts.
|
||
********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_InitLogicalModem (LPTSTR lpszLogicalModem,
|
||
LPDWORD lpdwLogicalModem,
|
||
LPATOM lpatClientName,
|
||
LPATOM lpatPhone,
|
||
LPMODEMCAPS lpmc);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_InitLogicalModem) (LPTSTR lpszLogicalModem,
|
||
LPDWORD lpdwLogicalModem,
|
||
LPATOM lpatClientName,
|
||
LPATOM lpatPhone,
|
||
LPMODEMCAPS lpmc);
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_InitProvider | Used to initialize the LMI provider.
|
||
|
||
@parm LPTSTR | lpszCurSpoolDir | Pointer to the current spool directory.
|
||
The spool directory is where all intermediate format files get
|
||
created, and where the client expects received fax files.
|
||
|
||
@parm LPMODEMCAPS | lpmcClient | Pointer to a <t MODEMCAPS> structure that
|
||
describes the capabilities of the client. This should be used by
|
||
the Provider to decide which formats can be understood by the
|
||
client. For instance, if the client only understands MH, then
|
||
the Provider would need to convert any received faxes into MH
|
||
before reporting them in <f LMI_ReportReceives>. Similarly, this
|
||
can indicate to the Provider whether or not features such as
|
||
uploading of messages and Provider address books are supported by
|
||
this particular client implementation.
|
||
|
||
@parm LPTSTR | lpszDefRecipAdd | For incoming G3 faxes for which the
|
||
recipient is unknown, this address should be used. This typically
|
||
happens for faxes received from G3 machines without a programmed
|
||
CSI. In this case, this address should be put inside the
|
||
linearized header on the AWG3 file. If this address ends in an
|
||
<lq>@<rq> the Provider should append the phone number of the modem on
|
||
which the fax was received, as well as any locally-obtained
|
||
subaddressing information, using the Microsoft Fax Address format.
|
||
For example, if the provider detects a DID string \<did\>, it
|
||
should append <lq>\<local-phone-number>\|\<did\><rq> after the
|
||
<lq>@<rq> sign.
|
||
|
||
@parm LPTSTR | lpszDefRecipName | Friendly name to be used for the
|
||
default recipient. Goes along with <p lpszDefRecipAdd> to form
|
||
an address pair.
|
||
|
||
@rdesc LMI_SUCCESS if successful.
|
||
|
||
@comm This call is made once per session. It is guaranteed to be the
|
||
first call made to the Provider.
|
||
|
||
********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_InitProvider (LPTSTR lpszCurSpoolDir,
|
||
LPMODEMCAPS lpmc,
|
||
LPTSTR lpszDefRecipAdd,
|
||
LPSTR lpszDefRecipName);
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_InitProvider) (LPTSTR lpszCurSpoolDir,
|
||
LPMODEMCAPS lpmc,
|
||
LPTSTR lpszDefRecipAdd,
|
||
LPSTR lpszDefRecipName);
|
||
|
||
/********
|
||
|
||
@doc EXTERNAL SRVRDLL INSTALLATION
|
||
|
||
@func LMI_RETURN | LMI_RemoveModem | Called when a logical modem is removed
|
||
from the list of current modems.
|
||
|
||
@parm LPTSTR | lpszModem | Pointer to the string identifying the
|
||
logical modem being removed.
|
||
|
||
@rdesc Returns LMI_SUCCESS if successful.
|
||
|
||
@comm This call should be used to delete any context which has been
|
||
cached for this logical modem. For instance, if in the
|
||
<f LMI_AddModem> call, a lot of connection information had been
|
||
stored in an ini file with the key being returned as the logical
|
||
modem name, then this call would be used to delete this
|
||
information.
|
||
|
||
********/
|
||
|
||
|
||
LMI_RETURN FAR PASCAL LMI_RemoveModem(LPTSTR lpszModem);
|
||
typedef LMI_RETURN (FAR PASCAL FAR * LPLMI_RemoveModem)(LPTSTR lpszModem);
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api DWORD | LMI_ReportReceives | Lets LMI provider report back
|
||
received faxes.
|
||
|
||
@parm DWORD | dwLogicalModem | Handle representing the logical modem
|
||
to be checked. If this is null, all logical modems owned by this
|
||
Provider should be checked.
|
||
|
||
@parm WORD | wFlags | Can consist of a combination of the following
|
||
flags:
|
||
|
||
@flag NRR_USER_REQUEST | This flag will be set if new faxes are
|
||
being checked for on an explicit user request. This is meant for
|
||
transports which tend to reduce the number of times they actually
|
||
check for receives to reduce overhead. Providers should make
|
||
sure to do the checks when this flag is set.
|
||
|
||
@flag NRR_RETRIEVE_DATA | Set if the client wishes to process the 1st receive
|
||
in the queue. If set, the provider fills out a LMIRECVSTATUS
|
||
structure and specifies a pointer to it in *lplpnrtStatus. If
|
||
the client makes successive calls specifying NRR_RETRIEVE_DATA (but not
|
||
NRR_COMMITTED_RECV), information on the same receive (the 1st one
|
||
on the queue) should be returned. Each time, a fresh atom needs to
|
||
be allocated for the atFile field in LMIRECVSTATUS, and the client
|
||
is responsible for freeing this atom. If this flag is not set,
|
||
indicates that the client wants to
|
||
simply find out if there are any receives waiting, and the provider
|
||
should ignore lplpnrtStaus.
|
||
|
||
@flag NRR_COMMITTED_RECV | Indicates that the previous receive
|
||
has been committed to permanent storage by the client and can be
|
||
deleted by the Provider from its queue. It also indicates that
|
||
the memory used for the LMIRECVSTATUS structure for that job can
|
||
be freed or reused. Until this point, the Provider must not
|
||
remove the received fax from its internal permanent storage.
|
||
This helps avoid a fax being lost if the power goes off in the
|
||
middle of the handoff. In the worst case, it causes two copies of
|
||
the received fax to be processed instead of none.
|
||
If this flag is specified, NRR_RETRIEVE_DATA is irrelevant and if
|
||
specified should be ignored by the provider.
|
||
|
||
@parm LPDWORD | lpdwNumRecvs | Pointer to a DWORD which should be
|
||
filled in with the number of new received faxes which are waiting
|
||
to be picked up. If NRR_RETRIEVE_DATA is set in wFlags, the
|
||
received fax being returned in the current call should not be
|
||
included in this count.
|
||
|
||
@parm LPLMIRECVSTATUS FAR* | lplpnrtStatus | Pointer to a pointer
|
||
which should be set to point to a <t LMIRECVSTATUS> structure.
|
||
The client assumes this pointer to point into accesible memory which is
|
||
valid until the next call made with the flag
|
||
NRR_COMMITTED_RECEIVE set. There can never be more than one
|
||
pending receive, so a single piece of memory can be reused.
|
||
This should be set only if <p wFlags> has the RETRIEVE_DATA flag
|
||
set. The atom passed in this structure will be freed by the
|
||
client. It should be set to null if there are no receives.
|
||
|
||
@rdesc Returns LMI_SUCCESS if succesful.
|
||
|
||
@comm It is possible for receives to be routed independent of this API
|
||
directly to the client's mail store. This would happen if the
|
||
client and Provider could communicate using another mail transport
|
||
(such as Microsoft SFS) to do this more easily.
|
||
********/
|
||
|
||
#define NRR_USER_REQUEST 0x0001
|
||
#define NRR_RETRIEVE_DATA 0x0002
|
||
#define NRR_COMMITTED_RECV 0x0004
|
||
|
||
LMI_RETURN FAR PASCAL LMI_ReportReceives(DWORD dwLogicalModem,
|
||
WORD wFlags,
|
||
LPDWORD lpdwNumRecvs,
|
||
LPLMIRECVSTATUS FAR *lplpnrtStatus);
|
||
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_ReportReceives)(DWORD dwLogicalModem,
|
||
WORD wFlags,
|
||
LPDWORD lpdwNumRecvs,
|
||
LPLMIRECVSTATUS FAR *lplpnrtStatus);
|
||
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_ReportSend | Reports status of completed send jobs.
|
||
|
||
@parm DWORD | dwLogicalModem | Handle representing the logical modem
|
||
to be checked. If this is null, all logical modems owned by this
|
||
Provider should be checked.
|
||
|
||
@parm WORD | wFlags | Can consist of a combination of the following
|
||
flags:
|
||
|
||
@flag NRS_USER_REQUEST | This flag will be set if the fax status
|
||
is being checked for on an explicit user request. This is meant
|
||
for transports which tend to reduce the number of times they
|
||
actually check for receives to reduce overhead. Such transports
|
||
should make sure to do the checks when this flag is set.
|
||
|
||
@flag NRS_RETRIEVE_DATA | If set, indicates that the client wishes to
|
||
process the status for the first one in the queue. If not set,
|
||
indicates that the client wants to
|
||
simply find out if there are any jobs completed.
|
||
|
||
@parm LPDWORD | lpdwNumDone | Pointer to a DWORD which should be filled
|
||
in with the number of jobs which have been completed and are
|
||
waiting to be picked up. If NRS_RETRIEVE_DATA flag is set, then
|
||
this should be filled in with the number of jobs left not
|
||
counting the one being returned in this call.
|
||
|
||
@parm LPLMISENDSTATUS FAR* | lplpnstStatus | Pointer to a pointer which
|
||
should be set to point to a <t LMISENDSTATUS> structure. The
|
||
client assumes this pointer to be valid until the next call it
|
||
makes to this function. It should be set to null if there are no
|
||
completed sends. It should only be filled in if NRS_RETRIEVE_DATA
|
||
is set in wFlags.
|
||
|
||
@rdesc Returns LMI_SUCCESS if succesful.
|
||
********/
|
||
|
||
#define NRS_USER_REQUEST 0x0001
|
||
#define NRS_RETRIEVE_DATA 0x0002
|
||
|
||
LMI_RETURN FAR PASCAL LMI_ReportSend(DWORD dwLogicalModem,
|
||
WORD wFlags,
|
||
LPDWORD lpdwNumDone,
|
||
LPLMISENDSTATUS FAR *lplpnstStatus);
|
||
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_ReportSend)(DWORD dwLogicalModem,
|
||
WORD wFlags,
|
||
LPDWORD lpdwNumDone,
|
||
LPLMISENDSTATUS FAR *lplpnstStatus);
|
||
|
||
/********
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_RescheduleSendJob | Reschedules the specified
|
||
send job from the Provider's queue.
|
||
|
||
@parm DWORD | dwLogicalModem | The logical modem in whose queue the
|
||
job to be rescheduled lives. This does not have to be the
|
||
currently active modem.
|
||
|
||
@parm LPTSTR | lpszSenderMachineName | Pointer to a string identifying
|
||
the sender machine name. This parameter, along with the
|
||
<p dwUniqueID> and <p dwUniqueID2> uniquely identify this job for
|
||
the Provider. These all must be same as the values passed in the
|
||
<t LMISENDJOB> structure passed into <f LMI_SendFax>.
|
||
|
||
@parm DWORD | dwUniqueID | See <p lpszSenderMachineName>.
|
||
|
||
@parm DWORD | dwUniqueID2 | See <p lpszSenderMachineName>.
|
||
|
||
@parm LPSENDJOBTIME | lpsjtNewTime | Pointer to a new <t SENDJOBTIME>
|
||
structure containing the reschedule information.
|
||
|
||
@rdesc LMI_SUCCESS on success.
|
||
|
||
@comm The reschedule can be performed asyncronously by the Provider.
|
||
Return from this function does not imply any guarantee as to the
|
||
time within which the job will be rescheduled. The client will
|
||
ensure that this function is only called to reschedule jobs which
|
||
were initiated on its machine.
|
||
|
||
********/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_RescheduleSendJob (DWORD dwLogicalModem,
|
||
LPTSTR lpszSenderMachineName,
|
||
DWORD dwUniqueID,
|
||
DWORD dwUniqueID2,
|
||
LPSENDJOBTIME lpsjtNewTime);
|
||
|
||
typedef LMI_RETURN (FAR PASCAL FAR *LPLMI_RescheduleSendJob) (DWORD dwLogicalModem,
|
||
LPTSTR lpszSenderMachineName,
|
||
DWORD dwUniqueID,
|
||
DWORD dwUniqueID2,
|
||
LPSENDJOBTIME lpsjtNewTime);
|
||
|
||
/*******
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LMI_RETURN | LMI_SendFax | Accepts a job for sending. Job is already
|
||
completely rendered.
|
||
|
||
@parm DWORD | dwLogicalModem | Handle representing the logical modem
|
||
from which this should be sent.
|
||
|
||
@parm LPLMISENDJOB | lpnj | Points to a <t LMISENDJOB> structure
|
||
containing all the pertinent information about this job. The
|
||
structure is allocated by the client and is freed on return of
|
||
this call.
|
||
|
||
@rdesc Returns LMI_SUCCESS if the job is accepted. A successful return
|
||
of this function implies that the job has been queued for
|
||
subsequent processing and transmission. This function should
|
||
fail only if there is a general failure in the provider or a
|
||
parameter validation failure. Processing or transmission failures
|
||
should be returned in the appropriate <f LMI_ReportSend> call.
|
||
|
||
*******/
|
||
|
||
LMI_RETURN FAR PASCAL LMI_SendFax (DWORD dwLogicalModem,
|
||
LPLMISENDJOB lpnj);
|
||
|
||
typedef LMI_RETURN (FAR PASCAL FAR * LPLMI_SendFax) (DWORD dwLogicalModem,
|
||
LPLMISENDJOB lpnj);
|
||
|
||
|
||
/*******
|
||
@doc EXTERNAL SRVRDLL
|
||
|
||
@api LPBYTE | LMI_SetCustomMsgOptions | This function is called to
|
||
allow the user to set custom per message options.
|
||
|
||
@parm DWORD | dwLogicalModem | Handle representing the logical modem
|
||
which is currently in use.
|
||
|
||
@parm LPBYTE | lpbOld | Pointer to a previously returned piece of
|
||
memory which needs to be freed. If this parameter is being used
|
||
the function should simply free the memory and return without
|
||
putting up any UI.
|
||
|
||
@rdesc Returns a pointer to a memory block containing all the custom
|
||
information which has been set. The first DWORD of the block
|
||
MUST contain the total size of the memory being used. This data
|
||
will be passed along with the <t LMISENDJOB> structure when this
|
||
message is finally submitted. The memory will be freed by
|
||
calling this same API again with the memory pointer passed in as
|
||
a parameter.
|
||
|
||
@comm This function can be used to enable all kinds of advance options
|
||
to the user. One example of this could be usage of TAPI locations
|
||
and credit cards for calls. If the Provider can support these, it
|
||
can allow the user to setup credit card calls and then use these
|
||
when resolving the phone numbers into dialable strings. If the
|
||
Provider is using the TAPI translation services, the user could
|
||
select a specific outbound device or line for the call, and
|
||
do a credit card ID override on cards setup on the Provider TAPI
|
||
setup.
|
||
|
||
*******/
|
||
|
||
LPBYTE FAR PASCAL LMI_SetCustomMsgOptions(DWORD dwLogicalModem,
|
||
LPBYTE lpbOld);
|
||
typedef LPBYTE (FAR PASCAL FAR *LPLMI_SetCustomMsgOptions)(DWORD dwLogicalModem,
|
||
LPBYTE lpbOld);
|
||
|
||
#ifdef __cplusplus
|
||
} // extern "C" {
|
||
#endif
|
||
|
||
#endif
|