Documentation update.

diff --git a/documentation/ole.sgml b/documentation/ole.sgml
new file mode 100644
index 0000000..20e4555
--- /dev/null
+++ b/documentation/ole.sgml
@@ -0,0 +1,397 @@
+  <chapter id="ole">
+    <title>COM/OLE in Wine</title>
+
+    <sect1 id="ole-architecture">
+      <title>COM/OLE Architecture in Wine</title>
+
+      <para>
+        The section goes into detail about how COM/OLE2 are
+        implemented in Wine.
+      </para>
+    </sect1>
+
+    <sect1 id="ole-binary">
+      <title>Using Binary OLE components in Wine</title>
+      <para>
+        This section describes how to import pre-compiled COM/OLE
+        components...
+      </para>
+    </sect1>
+
+    <sect1 id="com-writing">
+      <title>Writing OLE Components for Wine</title>
+
+      <para>
+        Based on the comments in <filename>wine/include/wine/obj_base.h</filename>.
+      </para>
+      <para>
+        This section describes how to create your own natively
+        compiled COM/OLE components.
+      </para>
+
+      <sect2>
+        <title>Macros to define a COM interface</title>
+
+        <para>
+          The goal of the following set of definitions is to provide a
+          way to use the same header file definitions to provide both
+          a C interface and a C++ object oriented interface to COM
+          interfaces. The type of interface is selected automatically
+          depending on the language but it is always possible to get
+          the C interface in C++ by defining CINTERFACE.
+        </para>
+        <para>
+          It is based on the following assumptions:
+        </para>
+        <itemizedlist>
+          <listitem>
+            <para>
+              all COM interfaces derive from IUnknown, this should not
+              be a problem.
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              the header file only defines the interface, the actual
+              fields are defined separately in the C file implementing
+              the interface.
+            </para>
+          </listitem>
+        </itemizedlist>
+        <para>
+          The natural approach to this problem would be to make sure
+          we get a C++ class and virtual methods in C++ and a
+          structure with a table of pointer to functions in C.
+          Unfortunately the layout of the virtual table is compiler
+          specific, the layout of g++ virtual tables is not the same
+          as that of an egcs virtual table which is not the same as
+          that generated by Visual C+. There are workarounds to make
+          the virtual tables compatible via padding but unfortunately
+          the one which is imposed to the WINE emulator by the Windows
+          binaries, i.e. the Visual C++ one, is the most compact of
+          all.
+        </para>
+        <para>
+          So the solution I finally adopted does not use virtual
+          tables. Instead I use inline non virtual methods that
+          dereference the method pointer themselves and perform the
+          call.
+        </para>
+        <para>
+          Let's take Direct3D as an example:
+        </para>
+        <programlisting>#define ICOM_INTERFACE IDirect3D
+#define IDirect3D_METHODS \
+    ICOM_METHOD1(HRESULT,Initialize,    REFIID,) \
+    ICOM_METHOD2(HRESULT,EnumDevices,   LPD3DENUMDEVICESCALLBACK,, LPVOID,) \
+    ICOM_METHOD2(HRESULT,CreateLight,   LPDIRECT3DLIGHT*,, IUnknown*,) \
+    ICOM_METHOD2(HRESULT,CreateMaterial,LPDIRECT3DMATERIAL*,, IUnknown*,) \
+    ICOM_METHOD2(HRESULT,CreateViewport,LPDIRECT3DVIEWPORT*,, IUnknown*,) \
+    ICOM_METHOD2(HRESULT,FindDevice,    LPD3DFINDDEVICESEARCH,, LPD3DFINDDEVICERESULT,)
+#define IDirect3D_IMETHODS \
+    IUnknown_IMETHODS \
+    IDirect3D_METHODS
+ICOM_DEFINE(IDirect3D,IUnknown)
+#undef ICOM_INTERFACE
+
+#ifdef ICOM_CINTERFACE
+// *** IUnknown methods *** //
+#define IDirect3D_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
+#define IDirect3D_AddRef(p)             ICOM_CALL (AddRef,p)
+#define IDirect3D_Release(p)            ICOM_CALL (Release,p)
+// *** IDirect3D methods *** //
+#define IDirect3D_Initialize(p,a)       ICOM_CALL1(Initialize,p,a)
+#define IDirect3D_EnumDevices(p,a,b)    ICOM_CALL2(EnumDevice,p,a,b)
+#define IDirect3D_CreateLight(p,a,b)    ICOM_CALL2(CreateLight,p,a,b)
+#define IDirect3D_CreateMaterial(p,a,b) ICOM_CALL2(CreateMaterial,p,a,b)
+#define IDirect3D_CreateViewport(p,a,b) ICOM_CALL2(CreateViewport,p,a,b)
+#define IDirect3D_FindDevice(p,a,b)     ICOM_CALL2(FindDevice,p,a,b)
+#endif</programlisting>
+        <para>
+          Comments:
+        </para>
+        <para>
+          The ICOM_INTERFACE macro is used in the ICOM_METHOD macros
+          to define the type of the 'this' pointer. Defining this
+          macro here saves us the trouble of having to repeat the
+          interface name everywhere. Note however that because of the
+          way macros work, a macro like ICOM_METHOD1 cannot use
+          'ICOM_INTERFACE##_VTABLE' because this would give
+          'ICOM_INTERFACE_VTABLE' and not 'IDirect3D_VTABLE'.
+        </para>
+        <para>
+          ICOM_METHODS defines the methods specific to this
+          interface. It is then aggregated with the inherited methods
+          to form ICOM_IMETHODS.
+        </para>
+        <para>
+          ICOM_IMETHODS defines the list of methods that are
+          inheritable from this interface. It must be written manually
+          (rather than using a macro to generate the equivalent code)
+          to avoid macro recursion (which compilers don't like).
+        </para>
+        <para>
+          The ICOM_DEFINE finally declares all the structures
+          necessary for the interface. We have to explicitly use the
+          interface name for macro expansion reasons again.  Inherited
+          methods are inherited in C by using the IDirect3D_METHODS
+          macro and the parent's Xxx_IMETHODS macro. In C++ we need
+          only use the IDirect3D_METHODS since method inheritance is
+          taken care of by the language.
+        </para>
+        <para>
+          In C++ the ICOM_METHOD macros generate a function prototype
+          and a call to a function pointer method. This means using
+          once 't1 p1, t2 p2, ...' and once 'p1, p2' without the
+          types. The only way I found to handle this is to have one
+          ICOM_METHOD macro per number of parameters and to have it
+          take only the type information (with const if necessary) as
+          parameters.  The 'undef ICOM_INTERFACE' is here to remind
+          you that using ICOM_INTERFACE in the following macros will
+          not work. This time it's because the ICOM_CALL macro
+          expansion is done only once the 'IDirect3D_Xxx' macro is
+          expanded. And by that time ICOM_INTERFACE will be long gone
+          anyway.
+        </para>
+        <para>
+          You may have noticed the double commas after each parameter
+          type. This allows you to put the name of that parameter
+          which I think is good for documentation. It is not required
+          and since I did not know what to put there for this example
+          (I could only find doc about IDirect3D2), I left them blank.
+        </para>
+        <para>
+          Finally the set of 'IDirect3D_Xxx' macros is a standard set
+          of macros defined to ease access to the interface methods in
+          C. Unfortunately I don't see any way to avoid having to
+          duplicate the inherited method definitions there. This time
+          I could have used a trick to use only one macro whatever the
+          number of parameters but I prefered to have it work the same
+          way as above.
+        </para>
+        <para>
+          You probably have noticed that we don't define the fields we
+          need to actually implement this interface: reference count,
+          pointer to other resources and miscellaneous fields. That's
+          because these interfaces are just that: interfaces. They may
+          be implemented more than once, in different contexts and
+          sometimes not even in Wine. Thus it would not make sense to
+          impose that the interface contains some specific fields.
+        </para>
+      </sect2>
+
+      <sect2>
+        <title>Bindings in C</title>
+
+        <para>
+          In C this gives:
+        </para>
+        <programlisting>typedef struct IDirect3DVtbl IDirect3DVtbl;
+struct IDirect3D {
+    IDirect3DVtbl* lpVtbl;
+};
+struct IDirect3DVtbl {
+    HRESULT (*fnQueryInterface)(IDirect3D* me, REFIID riid, LPVOID* ppvObj);
+    ULONG (*fnAddRef)(IDirect3D* me);
+    ULONG (*fnRelease)(IDirect3D* me);
+    HRESULT (*fnInitialize)(IDirect3D* me, REFIID a);
+    HRESULT (*fnEnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b);
+    HRESULT (*fnCreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b);
+    HRESULT (*fnCreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b);
+    HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
+    HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
+}; 
+
+#ifdef ICOM_CINTERFACE
+// *** IUnknown methods *** //
+#define IDirect3D_QueryInterface(p,a,b) (p)->lpVtbl->fnQueryInterface(p,a,b)
+#define IDirect3D_AddRef(p)             (p)->lpVtbl->fnAddRef(p)
+#define IDirect3D_Release(p)            (p)->lpVtbl->fnRelease(p)
+// *** IDirect3D methods *** //
+#define IDirect3D_Initialize(p,a)       (p)->lpVtbl->fnInitialize(p,a)
+#define IDirect3D_EnumDevices(p,a,b)    (p)->lpVtbl->fnEnumDevice(p,a,b)
+#define IDirect3D_CreateLight(p,a,b)    (p)->lpVtbl->fnCreateLight(p,a,b)
+#define IDirect3D_CreateMaterial(p,a,b) (p)->lpVtbl->fnCreateMaterial(p,a,b)
+#define IDirect3D_CreateViewport(p,a,b) (p)->lpVtbl->fnCreateViewport(p,a,b)
+#define IDirect3D_FindDevice(p,a,b)     (p)->lpVtbl->fnFindDevice(p,a,b)
+#endif</programlisting>
+        <para>
+          Comments:
+        </para>
+        <para>
+          IDirect3D only contains a pointer to the IDirect3D
+          virtual/jump table. This is the only thing the user needs to
+          know to use the interface. Of course the structure we will
+          define to implement this interface will have more fields but
+          the first one will match this pointer.
+        </para>
+        <para>
+          The code generated by ICOM_DEFINE defines both the structure
+          representing the interface and the structure for the jump
+          table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to
+          automatically repeat the prototypes of all the inherited
+          methods and then uses IDirect3D_METHODS to define the
+          IDirect3D methods.
+        </para>
+        <para>
+          Each method is declared as a pointer to function field in
+          the jump table. The implementation will fill this jump table
+          with appropriate values, probably using a static variable,
+          and initialize the lpVtbl field to point to this variable.
+        </para>
+        <para>
+          The IDirect3D_Xxx macros then just derefence the lpVtbl
+          pointer and use the function pointer corresponding to the
+          macro name. This emulates the behavior of a virtual table
+          and should be just as fast.
+        </para>
+        <para>
+          This C code should be quite compatible with the Windows
+          headers both for code that uses COM interfaces and for code
+          implementing a COM interface.
+        </para>
+      </sect2>
+
+      <sect2>
+        <title>Bindings in C++</title>
+        <para>
+          And in C++ (with gcc's g++):
+        </para>
+        <programlisting>typedef struct IDirect3D: public IUnknown {
+    private: HRESULT (*fnInitialize)(IDirect3D* me, REFIID a);
+    public: inline HRESULT Initialize(REFIID a) { return ((IDirect3D*)t.lpVtbl)->fnInitialize(this,a); };
+    private: HRESULT (*fnEnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b);
+    public: inline HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK a, LPVOID b)
+        { return ((IDirect3D*)t.lpVtbl)->fnEnumDevices(this,a,b); };
+    private: HRESULT (*fnCreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b);
+    public: inline HRESULT CreateLight(LPDIRECT3DLIGHT* a, IUnknown* b)
+        { return ((IDirect3D*)t.lpVtbl)->fnCreateLight(this,a,b); };
+    private: HRESULT (*fnCreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b);
+    public: inline HRESULT CreateMaterial(LPDIRECT3DMATERIAL* a, IUnknown* b)
+        { return ((IDirect3D*)t.lpVtbl)->fnCreateMaterial(this,a,b); };
+    private: HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
+    public: inline HRESULT CreateViewport(LPDIRECT3DVIEWPORT* a, IUnknown* b)
+        { return ((IDirect3D*)t.lpVtbl)->fnCreateViewport(this,a,b); };
+    private:  HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
+    public: inline HRESULT FindDevice(LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b)
+        { return ((IDirect3D*)t.lpVtbl)->fnFindDevice(this,a,b); };
+};</programlisting>
+        <para>
+          Comments:
+        </para>
+        <para>
+          In C++ IDirect3D does double duty as both the virtual/jump
+          table and as the interface definition. The reason for this
+          is to avoid having to duplicate the mehod definitions: once
+          to have the function pointers in the jump table and once to
+          have the methods in the interface class. Here one macro can
+          generate both. This means though that the first pointer,
+          t.lpVtbl defined in IUnknown, must be interpreted as the
+          jump table pointer if we interpret the structure as the
+          interface class, and as the function pointer to the
+          QueryInterface method, t.fnQueryInterface, if we interpret
+          the structure as the jump table. Fortunately this gymnastic
+          is entirely taken care of in the header of IUnknown.
+        </para>
+        <para>
+          Of course in C++ we use inheritance so that we don't have to
+          duplicate the method definitions.
+        </para>
+        <para>
+          Since IDirect3D does double duty, each ICOM_METHOD macro
+          defines both a function pointer and a non-virtual inline
+          method which dereferences it and calls it. This way this
+          method behaves just like a virtual method but does not
+          create a true C++ virtual table which would break the
+          structure layout. If you look at the implementation of these
+          methods you'll notice that they would not work for void
+          functions. We have to return something and fortunately this
+          seems to be what all the COM methods do (otherwise we would
+          need another set of macros).
+        </para>
+        <para>
+          Note how the ICOM_METHOD generates both function prototypes
+          mixing types and formal parameter names and the method
+          invocation using only the formal parameter name. This is the
+          reason why we need different macros to handle different
+          numbers of parameters.
+        </para>
+        <para>
+          Finally there is no IDirect3D_Xxx macro. These are not
+          needed in C++ unless the CINTERFACE macro is defined in
+          which case we would not be here.
+        </para>
+        <para>
+          This C++ code works well for code that just uses COM
+          interfaces. But it will not work with C++ code implement a
+          COM interface. That's because such code assumes the
+          interface methods are declared as virtual C++ methods which
+          is not the case here.
+        </para>
+      </sect2>
+
+      <sect2>
+        <title>Implementing a COM interface.</title>
+
+        <para>
+          This continues the above example. This example assumes that
+          the implementation is in C.
+        </para>
+        <programlisting>typedef struct _IDirect3D {
+    void* lpVtbl;
+    // ...
+ } _IDirect3D;
+
+static ICOM_VTABLE(IDirect3D) d3dvt;
+
+// implement the IDirect3D methods here
+
+int IDirect3D_fnQueryInterface(IDirect3D* me)
+{
+    ICOM_THIS(IDirect3D,me);
+    // ...
+}
+
+// ...
+
+static ICOM_VTABLE(IDirect3D) d3dvt = {
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IDirect3D_fnQueryInterface,
+    IDirect3D_fnAdd,
+    IDirect3D_fnAdd2,
+    IDirect3D_fnInitialize,
+    IDirect3D_fnSetWidth
+};</programlisting>
+        <para>
+          Comments:
+        </para>
+        <para>
+          We first define what the interface really contains. This is
+          the _IDirect3D structure. The first field must of course be
+          the virtual table pointer. Everything else is free.
+        </para>
+        <para>
+          Then we predeclare our static virtual table variable, we
+          will need its address in some methods to initialize the
+          virtual table pointer of the returned interface objects.
+        </para>
+        <para>
+          Then we implement the interface methods. To match what has
+          been declared in the header file they must take a pointer to
+          a IDirect3D structure and we must cast it to an _IDirect3D
+          so that we can manipulate the fields. This is performed by
+          the ICOM_THIS macro.
+        </para>
+        <para>
+          Finally we initialize the virtual table.
+        </para>
+      </sect2>
+    </sect1>
+  </chapter>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")
+End:
+-->