OLE Server Specification

From RISC OS
Revision as of 23:32, 1 February 2009 by Erik Groenhuis (talk | contribs) (Major rehash. Re-ordered sections. Corrected factual errors. Some new information.)
Jump to navigationJump to search

This page is intended as a full description of the Computer Concepts OLE protocol as seen from the server side. A programmer writing an application should be able to find here all the information required to let the application work as an OLE server. To let the application work as an OLE client, see the OLE Client Specification.


The server

Any application which provides its own file type and is capable of editing such files may set itself up to be an OLE server. To do so it needs to be able to send and accept OLE messages, and announce itself as a server by setting an environment variable for each file type it can handle.


Setting the environment variable

For the syntax of the OLEServer$Type_XXX variable see the OLE Client Specification.

The !Boot file of the server should set an OLEServer$Type_XXX variable for each type of file it wishes to serve. The -R value should start the server, and the -N value should be a string which can be recognised by the server as referring to itself. The name of the server application is usually a good choice, possibly extended with some characters to prevent confusion with other servers.


An OLE session

An OLE session should be initiated by a client application. The server simply waits until a request comes in.

Opening the session

A client that wants to open a session will broadcast an OLEOpenSession User_Message_Recorded (type 18) message.

   Message_OLEOpenSession (&80E21)
   -------------------------------
    +0 = length of block
    +4 = task handle of the sender
    +8 = my_ref
   +12 = 0
   +16 = message number (&80E21)
   +20 = 16 byte unique name padded with zeros
   +36 = window handle of display holding file
   +40 = x offset of data in window
   +44 = y offset of data in window
   +48 = format number
    format = 0 or 1 (edit file)
     +52 = Session number
     +56 = file type
     +60 = full pathname of data, zero terminated
   format = 2 (re-edit file)
     +52 = Session number
   format > 2 (reserved for future expansion)

The messages to start a new session are format 0 or 1. The server should check that the message is intended for it.

  • It should check that the Unique name at +20 is equal to the value of the -N parameter it set in the environment variable(s).
  • It should check that the file type at +56 is a type it wants to handle.

If either check fails, the server should simply ignore the message.

If the server does want to handle the session, it should send a copy of the message back as a User_Message (17), with the original my_ref code at +8 copied to the your_ref field, and the message number set to the code for OLEOpenSessionAck (&80E22).

   Message_OLEOpenSessionAck (&80E22)
   ----------------------------------
   SWI Wimp_SendMessage
   On entry - R0 = User message (17)
            - R1 = ^Block
                +0 = length of block (unchanged)
                +4 = task handle of sender (not used on entry)
                +8 = my_ref (not used on entry)
               +12 = your_ref: a copy of the my_ref of the OLEOpenSession message
               +16 = message number (&80E22)
               +20 The rest of the message unchanged from the OLEOpenSession message 
            - R2 = Task handle of client, from block+4 of the OLEOpenSession message

This will have the following effects:

  • It tells the WIMP that the original recorded message is acknowledged (because my_ref was copied to your_ref), so that message won't bounce back to the client.
  • It sends the new OLEOpenSessionAck message, so the client will know this server has accepted the session.
  • It informs the client of the task handle of the server.

The server can now start editing the file, whose path was given in the message block (at +60). The server should remember the client's task handle (+4) and the Session number (+52) associated this particular edit session.

For the handling of format 2 messages see below.

File changes

When the user saves the file being edited, the server should send an OLEFileChanged message to the appropriate client.

   Message_OLEFileChanged (&80E1E)
   -------------------------------
   SWI Wimp_SendMessage
   On entry - R0 = User message (17)
            - R1 = ^Block
                +0 = length of block
                +4 = 0 (not used on entry)
                +8 = 0 (not used on entry)
               +12 = 0 (original message)
               +16 = message number (&80E1E)
               +20 = format number
                 format = 0 (saved to a different file) then
                  +24 = Session number
                  +28 = full pathname of data, zero terminated
                 format = 1 (saved to the same file) then
                  +24 = Session number
                        (format used by OLESupport)
                 format > 1 then
                  +24... reserved for future extensions
            - R2 = Task handle of client

The task handle of the client and the Session number should be those associated with the file that is edited. The server can choose to either

  • save the file to the same path as the original (recommended) and send a format 1 message
  • save the modified file to a different temporary location, and send a format 0 message.

Note: the server should not feel it owns the file and thus should not attempt to delete the file during emergencies. Though the client is obliged to check if the format of the file is correct, the server should take care to only write valid data.

Closing the edit

When the user closes the file being edited, the server should send an OLECloseSession message to the appropriate client.

   Message_OLECloseSession (&80E23)
   --------------------------------
   SWI Wimp_SendMessage
   On entry - R0 = User message (17)
            - R1 = ^Block
                +0 = length of block
                +4 = 0 (not used on entry)
                +8 = 0 (not used on entry)
               +12 = 0 (original message)
               +16 = message number (&80E23)
               +20 = format number
                 format = 0 then
                   +24 = Session number (-1 means all sessions are closing)
                 format > 0 reserved for future extensions
            - R2 = Task handle of client

The task handle of the client and the Session number should be those associated with the file that was edited. The server can considder the session ended and remove any internal data associated with the session. The client will be responsible for the removal of the temporary file.

Alternatively, a server may keep the contents of the edited data in its internal memory and keep the session information in its list, merely marking the session as closed. It can then accept format 2 OLEOpenSession messages for this data in the future.

Actions the server should take

Server is seen by the Filer

The server should setup environment variable for each file type it is willing to handle.

Server is started

The server should be ready to receive OLE messages and have handlers in place for them.

The file changes

Whenever the user saves changes to a file, the server should check its internal data to see if the file is part of an OLE session. If so, it should send an OLEFileChanged message to the client.

The edit is closed

When the user ends an editing session, usually by closing the editing window, the server should check its internal data to see if the file is part of an OLE session. If so, it should send an OLECloseSession message to the client.

The server quits

When the server quits (e.g. because the user selects Quit from the menu), it should broadcast an OLECLoseSession message with Session number -1 to inform all clients which may have a session open with it that it should close those sessions. Note that the server does not really need to check if it actually has any sessions open. It can simply broadcast the message and let the clients work out if they have sessions that need to be closed.

   Message_OLECloseSession (&80E23)
   --------------------------------
   SWI Wimp_SendMessage
   On entry - R0 = User message (17)
            - R1 = ^Block
                +0 = length of block
                +4 = 0 (not used on entry)
                +8 = 0 (not used on entry)
               +12 = 0 (original message)
               +16 = message number (&80E23)
               +20 = format number
                 format = 0 then
                   +24 = Session number (= -1: all sessions are closing)
                 format > 0 reserved for future extensions
            - R2 = 0 for broadcast

Messages to be handled by the server

OLEOpenSession

Format 0 and 1

These messages indicate that a client wishes to start a new OLE session. From the server's point of view there is no difference between a format 0 and a format 1 message. The server should check if this registered broadcast message was intended for it. If not, it should ignore the message.

If it is, the server should acknowledge it by sending an OLEOpenSessionAck message. It should set up internal data describing the OLE session. It can then read the temporary file and offer it to the user to edit.

Format 2

The client may request to re-edit the same file. It can then send a format 2 message which will inform a server that the user has tried to perform an OLE action on the same data a second time. This gives those servers which allow documents to be closed, but not lost from memory (eg ArtWorks) a chance to reopen an edit window on the data. Note that a message of this format does not include a path for a temporary file created by the client, so this format only works if the server still has the file data in it's memory.

Servers which do not keep data from closed edits can simply ignore this message.

If a server does want to handle such request, it should check the client's task handle and the session number to see if it knows the OLE session, and still has the data. If not, the server should ignore the message.

If the server knows the session and still has the data, it can acknowledge the message (in the same way as for format 0 and format 1 OLEOpenSession messages), mark the session open in its internal data, and offer the data to the user for editing.

OLECloseSession

These are sent by a client when it abandons the object for which an OLE session is active. For example, a DTP editor may have a table included in it's document. The user wanted to edit the table, so the DTP editor started an OLE session with a server that can handle the table. While this session is going, the user decides to cut the table from the document. This means that the OLE session can be abandoned, and the DTP editor sends an OLECloseSession to the server.

In another case, if the client quits, it will broadcast an OLECloseSession message with Session number -1.

   Message_OLECloseSession (&80E23)
   --------------------------------
    +0 = length of block
    +4 = task handle of client
    +8 = my ref
   +12 = 0
   +16 = message number (&80E23)
   +20 = format number
     format = 0 then
       +24 = Session number (-1 means all sessions are closing)
     format > 0 reserved for future extensions

The server should check the combination of task handle and session number against the documents it is editing. When a document matches it should quit the edit of that file.

Note EG: it is unclear to me who is responsible for removing the file. It is very probable that the client should remove any files. These can be either the original file or any files with a new path written by the server. This needs to be thought through and specified in these documents, to prevent temporary files from being left behind.

If the Session number is -1, the server should quit all edits of documents that are associated with the task handle of the client.