home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / mapi / remote.xp / readme.txt < prev    next >
Encoding:
Text File  |  1996-01-16  |  15.6 KB  |  317 lines

  1. WINDS Remote Transport
  2.  
  3.  
  4. SUMMARY
  5. =======
  6.  
  7. The Remote.Xp sample is a remote transport provider (XPWDSR) implemented
  8. in C++. This transport demonstrates the following extended MAPI features:
  9.  
  10.  - Support for the REMOTE interface for slow-link connection to a remote host.
  11.    This includes implementation of the IMAPIFolder methods needed to interact
  12.    with a client remote viewer application.
  13.  - Support for deferred delivery mechanism for scheduled message submission to
  14.    a remote host at a user-settable upload time.
  15.  - Support for forced immediate connection and submission (using the
  16.    FlushQueues method implemented in the IMAPIStatus object) in response to
  17.    Deliver Mail Now and Transfer Mail in the Microsoft Exchange Client.
  18.  - How to implement server-based messaging.
  19.  - Real-world working mail transport which sends messages to a Windows NT
  20.    workstation or server running the Windows Developer Support (WINDS) Sample
  21.    Server Messaging Host included with this and other MAPI samples.
  22.  - Use of the Transport Neutral Encapsulation Format (TNEF) interface to
  23.    encapsulate ALL the message properties.
  24.  - How to implement the IMAPIStatus interface for client access to transport
  25.    status.
  26.  - Multithread safe.
  27.  - Configuration dialogs.
  28.  - Generation of delivery and non-delivery reports.
  29.  - Support for the profile Wizard for interactive profile configuration.
  30.  - Support for the WINDS address type.
  31.  - Support for background download and FlushQueues spooler interaction for
  32.    spooler-marshalled remote connections.
  33.  - Single binary file for Windows NT and Windows 95.
  34.  
  35. MORE INFORMATION
  36. ================
  37.  
  38. This program requires:
  39.  
  40.     Windows NT 3.51 (or later) or Windows 95,
  41.     The MAPI 1.0 SDK included in the Win32 SDK,
  42.     Microsoft Visual C++ version 2.1 (or later.)
  43.  
  44. Optionally, the Win32 SDK tools with the MIDL compiler.
  45.  
  46. This sample uses RPCs over named pipes to establish connections with the
  47. remote server. For convenience to customers without the full Win32 SDK, we
  48. have provided the MIDL compiler-generated C and header files (WINDS.H,
  49. WINDS_S.C, and WINDS_C.C) along with the IDL and ACF files. If you make changes
  50. to the IDL or ACF, you'll NEED to recompile them using the MIDL compiler
  51. available only in the Win32 SDK and Visual C++ 4.0 and later.
  52.  
  53. Building the Sample Code
  54. ------------------------
  55.  
  56. The sample remote transport provider has only been compiled and tested under
  57. Windows NT 3.51 and Windows 95, there are no plans for a Windows 3.1x (16-bit)
  58. release of this sample.
  59.  
  60. Users should update the project file dependencies as soon as the files are
  61. copied to your machine. Use the PROJECTS.UPDATE DEPENDENCIES options in the
  62. Visual C++ Developer Studio.
  63.  
  64. This sample was developed using Microsoft Visual C++ 2.x. Its associated
  65. makefile is XPWDSR32.MAK. Traces can be enabled for Release builds by defining
  66. ENABLE_DEBUG_OUTPUT in the preprocessor symbols define in the project settings
  67. menu.
  68.  
  69. A command-line compiler-independent MAKE file has been provided for users of
  70. command-line tools.
  71.  
  72. Configuration
  73. -------------
  74.  
  75. Use the MERGEINI.EXE utility from the MAPI PDK to merge this transport's
  76. message service INF file, XPWDSR.INF, with the MAPISVC.INF file:
  77.  
  78.     MERGEINI  {full-path}\XPWDSR.INF -m -q
  79.  
  80. for example:
  81.  
  82.     MERGEINI  C:\SAMPLES\MAPI\XPWDSR\XPWDSR.INF -m -q
  83.  
  84. You will then need to configure a profile that includes this transport. When
  85. you create a new profile, the Profile Wizard will detect this transport and set
  86. the initial properties through the wizard pages.
  87.  
  88. XPWDSR has two property sheets for interactive configuration which are
  89. accessible through the service provider logon, through the ServiceEntry call
  90. and through the IMAPIStatus::SettingsDialog method. The sample also defines
  91. custom properties for the configuration options so they may be set and
  92. retrieved programmatically.
  93.  
  94. User Account Configuration Page
  95. -------------------------------
  96.  
  97. Server Name: This is the network UNC (Universal Naming Convention) name of
  98. the machine where the user account is. The server machine MUST be running the
  99. WINDS Sample Server Messaging Host application prior to the provider setup.
  100.  
  101. Mailbox Name: The mailbox name is the name of the account on the remote server.
  102. To select a mailbox or change the current one, click on Browse and select a
  103. name from the list that will appear. Once selected, you will be asked to enter
  104. the password for the mailbox. For new mailboxes, the default password is
  105. PASSWORD. If the list of mailboxes is empty or you don't find the one for you,
  106. then a new account must be created on the server program. This field cannot be
  107. edited manually by the user.
  108.  
  109. Full Name: This is the complete name of the owner of the mailbox selected. This
  110. field is updated automatically when a new mailbox is selected. This information
  111. cannot be edited manually.
  112.  
  113. Change Mailbox Password: Click on this button to change the password for this
  114. mailbox. You will be asked to type the old password, a new password, and then
  115. confirm the new password.
  116.  
  117. Using Local Network (LAN): This is the option to use if the machine is directly
  118. hooked to on the network there is a connection to the server machine at all
  119. times. If this option is selected, when running, the provider will install
  120. notification links with the remote system allowing the provider to update
  121. internal data dynamically as the data changes on the server, and to react to
  122. changes or commands from the server.
  123.  
  124. Remote - With Local Address Book Directory: This setting instructs the provider
  125. to adjust itself to use local data and to defer communication with the server
  126. until the user changes the connection mode. This mode is useful if the server
  127. or the clientmachine are not on a persistent connection link with each other.
  128. If this option is selected the provider will not know of changes that occur on
  129. the server to cached data.
  130.  
  131. Message Transport Configuration Page
  132. ------------------------------------
  133.  
  134. Automatic Remote Uploads At: The daily time when the transport will submit
  135. all the messages it has deferred. At this time it will connect to the server
  136. and submit all the messages in a batch. The time must be entered in the
  137. 24-hour format, i.e. 12:00 AM is 0:00. 10:30 PM is 22:30, etc.
  138.  
  139. When Connected: If this option is selected, after the messages have been
  140. uploaded at the scheduled time, the transport will request to update the
  141. message headers.
  142.  
  143. Note: Prior to installing this transport into a profile, the WINDS Sample
  144. Server Messaging Host should be running in the remote (or local) computer.
  145. See the readme file in the above sample for instructions on compiling,
  146. installing, and using it.
  147.  
  148. Address Format
  149. --------------
  150.  
  151. This transport supports the address type WINDS. When creating new one-off
  152. entries in an address book (i.e. the Personal Address Book), this is the
  153. value for the Address Type field. Email addresses for this transport look
  154. like this:
  155.  
  156.     \\server-name\mailbox-name
  157.  
  158. The backslashes are literals, while the server-name and mailbox-name should
  159. be replaced with the server and mailbox name you wish to send to.
  160.  
  161. Note: When typing one-off addresses in the Exchange client, you must double
  162. the backslashes, like this:
  163.  
  164.     [WINDS:\\\\myserver\\mymailbox]
  165.  
  166. This is because the client treats the backslash as an escape character.
  167.  
  168. Remote Access
  169. -------------
  170.  
  171. The main difference between this transport and a non-remote transport is the
  172. ability to schedule mail transmission and to preview the header information
  173. of messages residing in a user's remote mailbox. Outgoing messages aren't
  174. transmitted at time of submission, but are queued by the spooler until the
  175. scheduled delivery time occurs. This is known as deferred submission. As long
  176. as the message is deferred, it stays in the user's local message store and the
  177. spooler retains responsibility. The spooler maintains an internal queue of
  178. deferred messages which it empties at the scheduled upload time, passing each
  179. message in sequence to the transport for delivery.
  180.  
  181. Inbound messages stay in the user's mailbox on the remote server until
  182. explicitly downloaded. This transport supports the Remote Viewer semantics,
  183. where the user can request the transport to connect to the server and
  184. retrieve a table of mail headers of messages in the user's remote mailbox. The
  185. remote viewer lets the user mark those rows of the header table he wishes to
  186. download. Rows are marked for move, delete, or copy operations according to
  187. which operation the user wants to perform on the corresponding message.
  188. Downloads are started explicitly, not scheduled, since the user has to
  189. explicitly mark the rows of the table that are to be downloaded.
  190.  
  191. The download table is a contents table of a MAPI folder that is returned by
  192. the IMAPIStatus object. This folder has no objects in it, but only exists to
  193. provide the contents table. When the user marks messages for download in the
  194. Remote Viewer, the corresponding row in the table has the PR_MSG_STATUS
  195. property set to a bitmask indicating the requested operation. To obtain the
  196. data for the header table, the transport makes an RPC to the server
  197. requesting the name of a named pipe. The server creates the pipe and
  198. returns the name. The transport then opens its end of the pipe and streams
  199. the actual data over it. This data is used to populate the contents table.
  200.  
  201. Download Semantics
  202. ------------------
  203.  
  204. A user request to start downloading marked messages causes the transport's
  205. IMAPIStatus::ValidateState method to be called with the
  206. PROCESS_XP_HEADER_CACHE flag passed. At this point the download table is
  207. walked and each marked entry is added to a list of messages to be
  208. downloaded. When the list has been constructed, an RPC is made to the server
  209. to obtain the name of a named pipe over which to stream the data.
  210.  
  211. The transport opens the pipe and requests the first message in the to-download
  212. list. The transport uses a simple form of handshaking: control messages are
  213. passed first to tell the server what the operation is, ACK the request, and get
  214. the size of the following stream. Transmission errors can be reported in these
  215. messages also. An error causes the message-in-transit to be dropped and the
  216. next one started.
  217.  
  218. When a message is downloaded, its storage is backed by a temporary file which
  219. is created on the fly to hold the incoming stream. When the message stream
  220. arrives successfully on the client side, its to-download list node is moved
  221. to a just-downloaded list. If the user logs off the session before the
  222. just-dowloaded list is processed, the downloaded file is kept in a to-do
  223. directory which will be processed in the next session logon.
  224.  
  225. Processing the just-downloaded list occurs in the same manner as for a
  226. non-deferred message; each message is pumped through the spooler's
  227. StartMessage loop. The spooler is notified that new mail has arrived by
  228. setting the STATUS_INBOUND_FLUSH in the PR_STATUS_CODE bit in the status table
  229. row. This causes the spooler to start requesting messages from the XP (by
  230. calling StartMessage). We stream the message in from the temp file, decode the
  231. TNEF stream into the passed MAPI message object, remove the non-transmittable
  232. properties, set the transport computed properties, delete the temporary file,
  233. and remove that message's node from the just-downloaded list. When the list is
  234. empty, we signal the spooler to stop requesting incoming messages by clearing
  235. the STATUS_INBOUND_FLUSH bit and passing back the untouched message object in
  236. StartMessage.
  237.  
  238. Upload Semantics
  239. ----------------
  240.  
  241. Uploading messages works in a similar fashion except that we initiate the
  242. process based on the time of day. The user configuration specifies a daily
  243. upload time which is saved in the profile section. The XP can be in several
  244. states with respect to the upload operation. When the upload time arrives, the
  245. state changes from WAITING to PROCESSING_TIMER_EVENT.
  246.  
  247. When a message is submitted by the user, SubmitMessage is called and the
  248. message is passed to us by the spooler. If our state is WAITING, we return
  249. without doing anything. In the subsequent call to EndMessage, we check the
  250. state and if we're WAITING, pass back END_DONT_RESEND. This signals the
  251. spooler to queue this message until later requested.
  252.  
  253. A timer event is initialized on logon with the interval between the current
  254. time and the upload time. When the timer expires, the spooler is notified to
  255. start submitting the earlier deferred messages from its internal queue. We get
  256. called again at SubmitMessage and are passed each message that's dequeued.
  257. In SubmitMessage, we check our state, recognize that we're being called this
  258. time to send the message, take responsibility (PR_RESPONSIBILITY), and go ahead
  259. and deliver it. We also change our status to STATUS_OUTBOUND_FLUSH to signal
  260. the spooler to keep calling our SubmitMessage method as long as it's queue is
  261. not empty. In the subsequent EndMessage, we check our state, realize that a
  262. message has just been dequeued and sent, decrement our counter and pass back
  263. 0. When the spooler has dequeued the last message, it callls TranportNotify,
  264. passing NOTIFY_END_OUTBOUND_FLUSH and we change state back to WAITING.
  265.  
  266. After the transport has finished uploading the messages at the scheduled time,
  267. we also request to get a new table of message headers on the server. This table
  268. is downloaded to the local file and if the remote viewer is displayed, the
  269. table of contents is refreshed.
  270.  
  271. Aborting Message Delivery
  272. -------------------------
  273.  
  274. Once deferred, a message can be aborted any time before the actual delivery.
  275. This happens if the user opens or deletes the message before it's sent. The
  276. XP gets called at TransportNotify with NOTIFY_ABORT_DEFERRED. The spooler
  277. will remove this message from its internal queue and we won't be called at
  278. SubmitMessage for it.
  279.  
  280. Debug Traces and Asserts
  281. ------------------------
  282.  
  283. This sample uses several output debug string functions in the Win32
  284. environment to avoid attaching the DLL to any debugger. By default, the trace
  285. messages are output to a debug terminal attached to COM1 with settings at
  286. 9600, N, 8, 1. The debug messages can also be written to a log file whose
  287. default location is C:\MAPILOG.TXT. The file TRACES.CPP defines some macros
  288. that can be easily modified for different communications settings, output port,
  289. and log file name. It also implements a macro (ASSERT) and function that test
  290. the validity of a given statement. If the assertion fails, the user/developer
  291. has the opportunity to break into the debugger at the exact point where the
  292. assertion occurred.
  293.  
  294. The debug routines are found in the TRACES.CPP and TRACES.H files.
  295.  
  296. To enable the TRACExx functions in the TRACES.CPP files, define the
  297. ENABLE_DEBUG_OUTPUT macro during compilation. These functions work in DEBUG or
  298. RELEASE builds. You can only enable/disable traces at compile time through
  299. ENABLE_DEBUG_OUTPUT. There is no run time switch to enable or disable the
  300. traces.
  301.  
  302. TRACES.CPP implements an ASSERT macro which test a evaluates an expression
  303. expecting a TRUE result, i.e. ASSERT (expression) will interrupt execution if the expression is NOT TRUE (non-zero).
  304.  
  305. The ASSERT macro informs the line and source code file name where the assertion
  306. failed and writes the result to a debug trace. The assert information is also
  307. written to the log file.
  308.  
  309. Also the this file implements a variation of assert: ASSERTMSG (expression,
  310. user-message) which behaves identical to ASSERT except that is the assertion
  311. fails, the message string is printed along with the assertion line and file
  312. information.
  313.  
  314. By default, if an assertion fails, a dialog will come up and interrupt
  315. execution until a selection is made to break into the debugger or ignore the
  316. assertion.
  317.