wine/ipc/dde.tex
Alexandre Julliard b7258befe0 Release 950901
Thu Aug 31 17:19:57 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [Configure]
	Added compile-time option for IPC.

	* [configure.in]
	Added command-line options for language, IPC and malloc
	debugging.

	* [controls/menu.c]
	WM_MENUSELECT was sometimes sent to the wrong window.

	* [debugger/break.c]
	For the 'next' command, only step over instruction that require
	it. This allows 'next' to do the right thing with jmp and ret
	instructions.

	* [ipc/*.c] [memory/atom.c] [memory/global.c]
	IPC can now be configured out at compile-time.

	* [loader/task.c]
	Bug fix in TASK_Reschedule() that could cause a task to be deleted
	twice.

	* [miscemu/dosmem.c] (New file)
	Partial emulation of the BIOS data segment.

	* [miscemu/instr.c]
	Trap attempts to access selector 0x40 and remap the access to
	segment __0040H.

	* [tools/build.c]
	Fixed bug in CallTo32_LargeStack() that caused problems when
	compiling Wine with the -fomit-frame-pointer option.

	* [windows/message.c]
	Fixed bug in hardware event handling that could cause some events
	to get ignored.

Sat Aug 26 13:12:59 IST 1995 Michael Veksler <mveksler@vnet.ibm.com>

	* [ipc/README] [ipc/dde.tex]
	LaTeX documentation for the ipc and DDE stuff.

Wed Aug 23 22:01:23 GMT 1995 Michael Veksler <mveksler@vnet.ibm.com>

	* [ipc/Imakefile] [ipc/wine_test_stub.c]
	Fixed IPC testing. Now it can be compiled with "make tests"

Wed Aug 23 21:04:14 1995  Fons Botman  <botman@wab-tis.rabobank.nl>

	* [if1632/kernel.spec] [include/windows.h] [misc/main.c]
	Added GetWinDebugInfo/SetWinDebugInfo stub for player.exe

Sun Aug  20 13:49:42 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>

	* [miscemu/int21.c]
	Misc fix to int21,ah=40 (write) to match _lwrite().
	AX=0x440A (check if handle is remote) added.

	* [multimedia/mmsystem.c]
	Moved mciSendString to mcistring.c.

	* [multimedia/mcistring.c]
	New file, string interface for MCI (not complete, not thoroughly
	tested).

	* [multimedia/audio.c]
	IOCTL prints errors; one paranoid check disabled.

	* [misc/file.c]
	Misc operator precedence fixes.

	* [if1632/gdi.spec] [objects/bitblt.c]
	Stub for FastWindowFrame (parameters not correct).

Sat Aug 19 01:31:23 1995  Graham Menhennitt <gfm@werple.mira.net.au>

	* [loader/ne_image.c]
	Preliminary support for iterated segments.

Sat Aug 19 00:43:04 1995  Andrew Taylor  (andrew@riscan.com)

	* [windows/mapping.c]
	In function MAPPING_FixIsotropic(), VportExt[XY] is multiplied by
 	the absolute value of (ydim / xdim) or (xdim / ydim).

Thu Aug 15 23:00:16  Gregory Trubetskoy  <grisha@mira.com>

	* [objects/oembitmap.c]
	Added some includes for Windows 95.

	* [include/sysmetrics.h]
	Added some sysmetrics for Windows 95.

	* [include/bitmaps/*95]
	New files: obm_close_95, obm_closed_95, obm_reduce_95, obm_reduced_95
	obm_zoom_95, obm_zoomd_95 - these are some pixmaps for Windows 95.

Thu Aug 10 12:00:00 1995  Jan Willamowius  (jan@janhh.shnet.org)

	* [misc/shell.c] [rc/sysres*.rc]
	The caption of the ShellAbout dialog box is language specific and
 	should be defined in the resources.
1995-09-01 15:57:28 +00:00

963 lines
37 KiB
TeX

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Written by Michael Veksler.
%% May be freely redistributed as long as this header is unchanged.
%% The file be modified as long as there will be appropriate comment
%% containing the Author and a description.
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentstyle{article}
\renewcommand{\thepage}{}
\newcommand{\Wine}{Wine}
\newcommand{\WINE}{{\em WINdows Emulator}}
\newcommand{\DDE}{{\em Dynamic Data Exchange}}
\newcommand{\windoz}{MS-Win\-dows}
\newcommand{\fname}[1]{{\tt #1}}
\newcommand{\libwine}{\fname{libwine.a}}
\title{DDE\footnote{DDE is \DDE\ mechanism provided by \windoz.
(Appendix~\protect\ref{sec:DDE}).
}
\ capability for \Wine\footnote{\Wine\ (\WINE) Runs \windoz\
programs under UNIX\@. (Appendix~\protect\ref{sec:Wine}).
}
}
\author{Michael Veksler 11678223}
%%\date{Aug 6, 1995}
\begin{document}
\maketitle
\vfill
\abstract{\Wine{} provides an environment for running or compiling
\windoz{} applications for UNIX clones (such as Linux).
\Wine{} is not yet finished and lacks many basic important features.
One of the missing features is DDE\@. DDE implementation
(especially for \libwine) requires
UNIX IPC\footnote{IPC - Inter-Process Communication}. This Project
introduces the IPC mechanism into \Wine{}, thus allowing DDE to work
between different \Wine{} processes.}
\vfill
{\LARGE
\begin{itemize}
\item[Instructor:] Avner Lottem
\item[Done for:] Technion- Israel Institute of Technology,\\
Electrical Engineering software lab$^{\mbox{\small\copyright}}$.
\end{itemize}
}
\vfill
\newpage
\renewcommand{\thepage}{\roman{page}}
\setcounter{page}{1}
\begin{center}
{\LARGE Table Of Contents}
\end{center}
\tableofcontents
\newpage
\renewcommand{\thepage}{\arabic{page}}
\setcounter{page}{1}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% end of title
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction}
\subsection{The project}
The purpose of the project is to add DDE capabilities into \Wine.
The project enables \Wine{} DDE client-server applications communication.
This involved messing around with:
\begin{itemize}
\item \windoz\ message mechanism.
\item \windoz\ memory management.
\item \windoz\ task management.
\item UNIX messages among \Wine\ processes.
\item Exchanging (sharing) UNIX memory.
\end{itemize}
\subsection{Problem description}
DDE is essentially a communication protocol between \windoz\
tasks. Implementing this protocol requires communication among
\Wine{} processes and among tasks in one process (each \Wine{} process
can contain several tasks). Since \Wine\ already provides
communication among internal tasks, this project provides communication
between \Wine\ processes.
Different \Wine\ processes should be able to send \windoz\ messages
and to pass \windoz\ memory handles. There also has to be a
synchronization mechanism between the processes (\windoz\ applications
make assumptions about task switching - and don't use semaphores, or
any \windoz\ equivalent).
Passing messages is a bit tricky. \windoz\ gives a feedback about the
success of a message (fails if the window does not exist).
In case of SendMessage (see Appendix~\ref{sec:WindozMsg}), the process
will have to halt until the message has been processed.
In case of PostMessage, things are simpler - only the existence of the
recipient has to be checked.
\windoz\ switches tasks only when certain system calls are used (such
as delivering or polling messages). \windoz\ applications rely on this
behavior. The problem arises when two applications run on different
\Wine\ processes. Since UNIX preempts processes there is no guaranty
that the UNIX task will occur at the correct place (in respect of the
application).
One one hand is the need for compatibility (no UNIX ``current''
execution), and on the other hand is performance and stability.
Another problem is passing handles between \Wine\ processes. \windoz\
applications pass atoms\footnote{See appendix~\ref{sec:WhatAreAtoms}},
memory handles and window handles. These handles have to be allocated
globally (in shared memory) or translated on the fly.
If a process dies from ``unnatural causes'' (e.g.\ kill $-9$). It will
leave garbage in memory and other IPC handles will start floating
around. There should be some way to collect this garbage.
\subsection{Solutions}
\label{sec:ProjSolutions}
\Wine\ uses Sys-V IPC mechanism (See
Appendix~\ref{sec:SysV-IPC}). This allows sharing data and passing
data between processes (The alternatives are not that good in that
respect - see Appendix~\ref{DDE-Alternatives}).
The shared data contains only essential information (performance or
compatibility). The minimum is kept on shared memory in order to get
maximum stability (\windoz\ is known as an unstable system, \Wine\
should not imitate \windoz\ in this respect).
Communications are done by Sys-V messages and UNIX signals (a signal
wakes \Wine\ up and the message passes the data). Sys-V messages are
used for carrying \windoz\ messages, as well as synchronization
information. There are 3 types of messages: sent, posted and ack.
Ack message is used for synchronization as well as for returning error
codes (In case sending/posting messages fail). When a message is sent,
the sending process will block until \Wine's {\em ack}{} message is
received.
Synchronization between \Wine\ processes is divided into 2 categories,
in both cases the sender of a message waits for an ack message:
\begin{enumerate}
\item Sent messages - Wait until the recipient delivers ack message.
(When the recipient finished message processing)
\item Posted message - The recipient will send ack only during
task switching instructions (like PostMessage, GetMessage, Yield,
etc.). This way nothing will be done after PostMessage until it is
safe.
\end{enumerate}
There is no real \Wine\ server. Every \Wine\ process has to handle
it's end. This approach somehow resembles a distributed OS\@. This
introduces some problems (Resources might not be freed in case of a
crash). On the other hand this ``distributed OS'' approach simplifies
installation and use, and improves performance.
Atoms are stored on shared memory, so every two \Wine\ processes will
be in sync in this respect (atom 5 will mean the same on both
processes). Shared memory handles are stored on shared memory as
well. Shared memory handles are not from the same range as local
memory handles (\windoz\ requires an plication to declare about it's
shared memory). Since local memory handles have different range they
can be allocated locally (without any sync requirements - handle x may
appear on 10 different \Wine\ processes and address different data).
Window handles are allocated locally. This approach gives stability,
but window handles are no longer unique (same handle may appear
on different processes). This requires on the fly window handle
translation. When an \windoz\ message is transfered, \Wine\ will
translate any contained window handle. The sender translates the
handle to a global (unique) handle, the receiver translates the global
handle to the local window handle.
Collecting the garbage of dead processes is done in two cases:
\begin{enumerate}
\item When setting up a new \Wine\ process: If no \Wine\ process is
running and shared memory is floating around all the IPC stuff is
deleted.
\item When sending a message: If the recipient is dead it's IPC
handles are deleted.
\end{enumerate}
\section{The software}
\subsection{DDE project structure}
Old \Wine\ functions call the new DDE functions whenever needed.
(e.g.\ when sending a DDE message, the original SendMessage function calls
DDE\_SendMessage). This approach minimizes changes to original \Wine{}
code. The new code was written in C. The new capabilities where written
as much as possible in OOP\footnote{OOP stands for Object Oriented
Programming}{} style.
Currently DDE uses Sys-V IPC mechanism, for it's operation.
\paragraph{Major OOP objects and files:}
\begin{table}[h]
\begin{center}
\leavevmode
\begin{tabular}{|l|p{20em}|} \hline
Object & Description \\ \hline
shm\_block & shared memory block operations. \\
shm\_main\_block & (derived from shm\_block.) Things all
DDE applications need access to. \\
shm\_fragment & Allocation of in-block fragments. \\
shm\_semaph & Semaphore operations. \\
dde\_proc & Process and DDE message handling. \\
dde\_mem & Front end of DDE memory handling
(Interface of DDE to outer world). \\
dde\_atom & Handling global atoms. \\
bit\_array & Array of bits. It has atomic
operations, so bits can be used instead
of semaphores. \\ \hline
\end{tabular}
\caption{Objects constructing the DDE extension.}
\label{tab:ObjList}
\end{center}
\end{table}
Table~\ref{tab:ObjList}{} lists the objects used in the DDE code.
The following rules apply to objects:
\begin{itemize}
\item Object names that begin with {\em dde\_$\cdots$}{} are the front
end. These objects are working directly with the rest of
\Wine. Objects that start with {\em shm\_$\cdots$}{} are the back
end. These objects provide services for the rest of the
implementation.
\item The objects are stored in file with the same name as the object.
(e.g.\ dde\_mem is stored in dde\_mem.c and dde\_mem.h).
\item For each object there is a test file (that partially tests it).
The name of this file is object's name with the word ``test''
(e.g.\ dde\_mem object has dde\_mem\_test.c).
\item dde.h file has declarations used by dde\_proc and external DDE
users.
\end{itemize}
\subsection{Major algorithms}
\paragraph{Delivering messages:}
\label{sec:DeliveringMessages}
\windoz\ messages are passed using Sys-V IPC messages. Processing
starts with SendMessage() or PostMessage() \windoz\ system
functions:
\begin{enumerate}
\item SendMessage and PostMessage call the DDE functions (same names
prefixed with DDE\_). If the DDE functions pass, don't go any
further. If it fails try to process the message in the
conventional way.
\item The DDE message functions call DDE\_DoMessage, which is
the main DDE message processing function. From now on there is no
difference between sending and posting messages (from initiator's
point of view).
\item If the message is not a DDE message or the recipient is not
remote, fail and return to original message functions.
\item Bring the message to a format suitable for IPC delivery. The
format includes:
\begin{itemize}
\item message type (sent or posted).
\item Sender window handle (translated to global window id.)
\item Other message ingredients (msg, lParam).
\end{itemize}
\item Deliver the message to every recipients using
DDE\_DoOneMessage. There might be many recipients in case of a
broadcast (when the ``recipient'' window is -1).
\item DDE\_DoOneMessage delivers the message and waits for response.
Fail if timeout is reached.
\end{enumerate}
\paragraph{Receiving messages:}
Messages from other \Wine\ processes are received. Processing start
from DDE\_GetRemoteMessage():
\begin{enumerate}
\item DDE\_GetRemoteMessage is called whenever wine is going to wait
or receive X-windows message. If wine is sleeping (waiting for X),
it will waken by a SIGUSR2 signal. In this case the handler will
siglongjmp() out of the select() function.
\item If no remote message is pending in the message queue - exit.
(Sys-V message queue holds the remote messages until they are
read).
\item If the message is broadcasted, goto stage~\ref{BroadcastAlgo}.
\item Translate the global window handle of the recipient to local
handle.
\item Do this if the message was sent. Send the message to the
recipient window. Reply with ack to the sender. (Reply with the
return code of the SendMessage function). {\em \bf Return}\ with
positive return value.
\item Post the message.
\item If PostMessage fails - send failing ack message.
\item If PostMessage passes, add the message data into a FIFO\@. This
FIFO contains all messages that have to be acknowledged (who's
sender is waiting for ack). Whenever internal task switch occurs,
a item from this FIFO is popped out and an ack message is sent.
\item \label{BroadcastAlgo} Iterate through the local windows and
deliver the message to every one of them.
\item Send a positive ack message.
\end{enumerate}
\paragraph{Allocating memory:}
Shared memory allocation is divided into two categories: internal wine
and \windoz\ application. The memory used by \windoz\ applications is
allocated in two phases - allocate internal wine, and then prepare all
the stuff needed by \windoz.
The internal allocation (DDE\_malloc):
\begin{enumerate}
\item Try to allocate big enough memory fragment in allocated shared
memory.
\item If fragment could not be allocated, allocate a new shared
memory block. Allocate the memory fragment.
\item Allocate a shared memory handle (call the dde\_alloc\_handle()
function). The allocated handle is from a range used only by
shared memory handles. This allocation function is used only for
shared DDE memory.
\item Write the handle in the data structure. Also write the
relative location of this handle (Pointer location is useless since
it differs from one \Wine\ process to another).
This information is written in the main shared memory block.
\end{enumerate}
When a fragment is allocated, it is removed from the list of free
memory.
Allocation for \windoz\ applications (this is done in GlobalAlloc):
\begin{enumerate}
\item Do the internal allocation (instead of malloc in the local
allocation).
\item Everything else is the same as with local memory. A segment is
allocated for the new memory, and it's data is kept in the data
structure.
\end{enumerate}
\paragraph{Atoms:}
Atoms have pretty simple algorithms operating on them. Since atoms are
supposed to give a unique number for each string - atoms are
implemented as hash tables. The id of the atom is the entry in the
hash table. The disadvantage of this approach is that there is a limit
on the number of atoms, the big advantages are simplicity and
speed.
Since implementing a hash tables is strait forward, I will not
discuss it in depth. This hash table has two hash functions - primary
and secondary. When searching for an item (for deletion, addition, or
a seek) the following steps are taken:
\begin{enumerate}
\item The primary hash function returns the first entry.
\item \label{AtomHashLoop}
If the entry is empty or no unchecked entries {\bf \em fail}.
\item If the entry is correct, {\bf \em success!!!}.
\item Add the result of secondary hash function to the item index.
\item Goto step~\ref{AtomHashLoop}.
\end{enumerate}
\subsection{Major data structures}
There are two kinds of data structure, local and shared. The local
data structures are strait forward and will not be discussed in
detail.
The shared data structures have four level hierarchy. Each level
depend on the other and can not exist without it. Most structures have
much less than four levels.
\paragraph{Level one data structure - the main block:}
This data structure is part of the shm\_main\_block object. It
contains essential information needed by all \Wine\ processes. :
\begin{enumerate}
\item Semaphore identifier used for locking the data structure.
\item A table containing information about \Wine\ processes.
\item Relative pointers to atoms.
\item A table containing window information.
\item Tables with global memory handles.
\end{enumerate}
The first level is allocated and initialized when \Wine\ calls a DDE
function the first time. DDE functions are: global memory allocation,
global atoms or DDE messages.
The first level data structure contains the second level data
structure.
\paragraph{Atom element (level two):}
Each element is allocated dynamically (the size of the string is
unknown). The allocation is gained from the shm\_fragment object (each
atom is an instance of that object). Each atom contains:
\begin{enumerate}
\item Count of links. Each allocation of the atom establishes a new
link and each deallocation deletes one link (until all links are
removed).
\item The string of the atom. The string ends with a null character.
\end{enumerate}
\paragraph{Wine processes data (level two):}
(part of the dde\_proc object) :
\begin{enumerate}
\item pid (\Wine\ process id).
\item Message queue id.
\item Semaphore used for locking process's data structure.
\item Sys-V shared memory id of the first block in the chain of
process's blocks.
\end{enumerate}
\paragraph{Window information (level two):}
This is part of the dde\_proc object. The index of array entry
specifies the window handle. Each entry contains:
\begin{enumerate}
\item The process index of the \Wine\ process running this window.
\item The local window handle of this window (remember that each DDE
window has different global and local handles).
\end{enumerate}
\paragraph{Global memory handles (Level two):}
(part of bit\_array and dde\_mem objects):
\begin{enumerate}
\item A bit array contains '1' in every entry that refers to
used global memory handle.
\item Array of handles contains handle data. Each entry refers
to a global memory handle (The index is a function of the
handle). The data includes: 1) Sys-V shared memory handles 2)
offset into the memory block.
\end{enumerate}
\paragraph{Block allocation data structure (Level three):}
This data structure a part of the shm\_block object. It is local to
each shared memory block, so every memory block has it's own data
structure. The shared memory blocks are organized in chains grouped by
processes (each DDE process has one and only one chain):
\begin{enumerate}
\item The id of the next shared memory block in the chain.
\item The size of the block.
\item Number of free bytes in the block.
\item The index of the owner process.
\item The first item in the free list (a linked list of free items).
\end{enumerate}
\paragraph{Fragment allocation (Level four):}
This data is a part of the shm\_fragment object. It is a part of the shared
memory allocation mechanism. Every fragment is a part of shared memory
block. Each fragments contain:
\begin{enumerate}
\item The size of the fragment (for allocating and freeing this
fragment).
\item A union that contains one of:
\begin{itemize}
\item data - if it is allocated.
\item offset of the next free fragment (if it is a member of the
free list).
\end{itemize}
\end{enumerate}
\paragraph{Local reference to global memory:}
Global memory blocks are referenced from local memory. This is used
for storing pointers that refer to the memory block. It contains:
\begin{enumerate}
\item next item in the list.
\item shared memory block id.
\item Owner process.
\item Pointer to the data.
\end{enumerate}
\paragraph{Local mirroring of global handles:}
Global handles require local segments handles (when they are locked).
These segments have to be deleted when the handle is freed.
There is a minimal mirroring of handles in the original tables of
wine, this information is stored the way local handles have always
been stored.
\subsection{Interface and IO}
The DDE section of wine has several interfaces to different entities:
\begin{enumerate}
\item User debug information.
\item Interface between several \Wine\ processes.
\item Interface to the `old' code of \Wine.
\end{enumerate}
\paragraph{User debug information:}
The debug information is written according to \Wine's
conventions. This means that dprintf\_$\cdots$ macros are used to
print the debug information. (These macros allow runtime or compile time
disabling of a any sort of debug information).
In some cases the dprintf\_$\cdots$ macros are not powerful enough. In
those cases the following construct is used instead:
\begin{verbatim}
if (debugging_dde) {
/* print whatever is needed for dde debugging */
}
\end{verbatim}
\paragraph{Interface between \Wine\ processes:}
The interface between processes includes:
\begin{itemize}
\item Message delivery (see Section~\ref{sec:DeliveringMessages}).
\item Sharing \windoz\ constructs (atoms, memory, window
handles).
\item Synchronization among different \Wine\ processes so it will
appear to a \windoz\ as if there is only one process.
\end{itemize}
\paragraph{Interface to the rest of \Wine:}
Most of the interface has been minimized to an additional few lines in
the original functions. The hook for DDE are in the following
locations:
\begin{itemize}
\item Global atoms functions - these are called directly from
\windoz\ applications.
\item Message delivery - a hook calls the DDE functions from the
original message delivery functions.
\item Initialization - Every PeekMessage() call a DDE function to
check if the current window has DDE management (by sending
a dummy WM\_DDE\_INITIATE message).
\item Waiting on messages - The original code for waiting on X
messages was enhanced to wait on DDE messages as well. This
includes aborting sleeps when SIGUSR2 signal is sent. The actual
test for DDE messages is done in the DDE code.
\end{itemize}
\subsection{Major functions and their role}
\paragraph{Message delivery functions:}
\begin{itemize}
\item DDE\_SendMessage and DDE\_PostMessage - hooks used by original
\Wine's SendMessage and PostMessage. They return true if the
message could be successfully sent to a remote \Wine\ process.
Only in this case SendMessage and PostMessage stop further
processing.
\item DDE\_DoMessage - Try to post or send a message to another
\Wine\ process. This function can do broadcasting as well as
sending. (A message is `broadcasted' if it is delivered to every
window on the system).
\item DDE\_DoOneMessage - Deliver a message to a given wine
{\bf process}.
\item dde\_proc\_send\_ack - Send ack message to \Wine\
process. The input window handle is used for detecting the
process.
\item get\_ack - wait for ack or timeout.
\end{itemize}
\paragraph{Memory allocation functions:}
\begin{itemize}
\item DDE\_malloc - Allocate a shared memory fragment. This function
also allocates global memory handle.
\item DDE\_GlobalFree - Free a shared memory fragment according to
it's handle. And free the handle.
\item DDE\_SyncHandle - synchronize the global handles mirrored
locally. Delete any outdated handles, or remap reallocated
handles.
\item DDE\_mem\_init - initialize or attach the main shared memory
block, and relevant local data structures.
\item shm\_delete\_all - delete all IPC stuff related to this
process. Kill the main memory block if appropriate.
\end{itemize}
\section{Software testing}
The testing of this module was a substantial part of the
development. Testing revealed bugs just as they where created.
\subsection{Testing methods utilized}
\label{sec:TestMethod}
Two major testing methods where used:
\begin{enumerate}
\item Running DDE \windoz\ applications. The applications used are
DDE demonstration applications. This applications seem to show
precisely what DDE is all about. The applications used where:
ddepop1.exe (server), showpop1.exe (client). These
applications come with \windoz\ programming manual by Charles
Petzold \cite{bib:WinManual}.
\item Running standalone DDE objects linked with a test
object. Every object was tested this way. Some objects had to be
linked with a stub that emulated \Wine's functions. The stub is
pretty poor with dde\_mem object since this object requires hard
to emulate functionalities (things like allocating a segment).
For some objects the coverage seems to be perfect (100\%). For
some object the coverage is poor. The objects with massive stub
usage suffer from this (especially dde\_mem).
\end{enumerate}
\subsection{input for testing}
Most of the testing described in section~\ref{sec:TestMethod} has no
input. Most of the testing knowledge is in the test objects
themselves. There are two exceptions to this rule:
\begin{enumerate}
\item The \windoz\ applications described in
section~\ref{sec:TestMethod} - which are essentially an input to
the software. These applications can't be distributed since it
will be a \copyright{} violation.
\item A trace file which is used for comparing test's output with
the expected trace result. This trace file is used for
shm\_fragment validation. This file is implementation Dependants
and should be updated whenever the object is rewritten. When
updating the trace, it should be inspected manually before it is
released.
\end{enumerate}
\subsection{usage instructions}
\paragraph{Running the DDE applications:}
To test the DDE applications one must run:
\begin{verbatim}
prompt> wine /full-path/ddepop1.exe > /dev/null &
\end{verbatim}
Wait for the server window to pop up (A tiny window should appear at
the lower left corner of your screen). Then activate the client by
typing:
\begin{verbatim}
prompt> wine /full-path/showpop1.exe > /dev/null
\end{verbatim}
The server updates ``USA population'' data every 5 seconds. The client
asks for a hot link (i.e.\ it sends a WM\_DDE\_ADVISE on every
item). From that point on the server updates the client of any
population change.
\paragraph{Running the object tests:}
The {\em run\_tests}{} script is provided to automate the object
tests. Every object test is run and the script checks for results. At
the end the script prints a nice summary table.
Invoking tests outside the {\em run\_tests}{} script is not as simple
as it may look. Every test has differently looking output.
\begin{itemize}
\item dde\_atom\_test - The executable is run. It passes if no
errors are printed at the bottom.
\item dde\_mem\_test - The same as for dde\_atom\_test.
\item shm\_semaph\_test - The same as for dde\_atom\_test.
\item bit\_array\_test - The same as for dde\_atom\_test.
\item shm\_fragment\_test - After the executable is run, the output
has to be compared with TEST\_FRAGMENT.std
\item dde\_proc\_test - This actually runs as a client and as a
server. To activate the server one should write:
\begin{verbatim}
prompt> dde_proc_test 1 > server.log
\end{verbatim}
Then the client has to be activated within five seconds by
writing:
\begin{verbatim}
prompt> dde_proc_test > client.log
\end{verbatim}
The log files should contain:
\begin{description}
\item[server.log:] Should contain traces of received
WM\_DDE\_INITIATE message, and ack sent for it. (Pretty much
the same what {\em run\_tests}{} does).
\item[client.log:] Should contain traces of sending
WM\_DDE\_INITIATE and then receiving an ack message.
\end{description}
No `timeout' traces should be present in the log files.
\end{itemize}
\section{Summary}
\subsection{Software limitations}
\begin{itemize}
\item Only most fundamental memory management functions where
written. This means that the following functions will not work:
\begin{itemize}
\item GlobalReAlloc
\item GlobalSize - two line fix.
\item GlobalFlags - two line fix.
\item LockSegment - two line fix.
\item UnlockSegment - two line fix.
\item GlobalFreeAll - will not free DDE memory.
\item GlobalPageLock - two line fix.
\item GlobalPageUnlock - two line fix.
\item GlobalFix - two line fix.
\item GlobalUnfix - two line fix.
\end{itemize}
\item Non DDE messages to remote windows will not work. This is
currently only a sanity check, it may be removed in the future.
\item Message sending has a timeout limit. This is incompatible with
\windoz. This limit increases stability of a singe \Wine\ process.
\item Synchronization mechanism between wine processes is not
perfect. It was not proved theoretically. I never saw it fail.
\end{itemize}
\subsection{Concluding Remarks}
This extension to \Wine{} enables further development of \windoz\ IPC
support. Things like OLE can be extended using these features -
although some modifications might be inevitable.
The most important contribution of this project is the support for
\libwine{}. Any \windoz\ application compiled under UNIX and linked to
\libwine{} will need the IPC mechanism provided by this project.
During the progress of the project it got a bit outdated. During that
time \Wine{} started to handle tasks internally, so the external IPC
was no longer needed for the emulator configuration of
wine. Nevertheless the support of IPC for \libwine will never
be obsolete.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Appendixes
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\clearpage
\appendix
\section{\Wine}
\label{sec:Wine}
\Wine\ stand for {\em WINdows Emulator}. It is an X-windows - UNIX
application (Linux and FreeBSD). \Wine\ emulates \windoz\ environment
for the \windoz\ applications. It has two uses:
\begin{enumerate}
\item Run \windoz\ binary code (compiled under \windoz).
\item To be used as a toolkit for compiling \windoz\ applications
under UNIX. (The \libwine\ library is provided)
\end{enumerate}
For emulation, only Intel-Architecture CPU (386, 486, Pentium) are
supported. \libwine\ Toolkit should run on any platforms, but it was not
tested. \Wine\ is still in alpha state, and does not support all \windoz\
capabilities yet.
\section{Messages under \windoz}
\label{sec:WindozMsg}
Messages are the means of communication to a user window (from another
window or from \windoz\ itself).
Messages can be delivered in two ways:
\begin{itemize}
\item Messages can be sent. The sent message enters the window handler
asynchronously (The handler may be reentered many times).
A window sending the message waits for the recipient to process
the message and return an exit code.
\item Messages can be posted. The posted message enters a queue, and
it's up to the recipient to process it. If the recipient ignores
it, the message might be eventually sent to the recipient from
WinMain handler.
\end{itemize}
\section{DDE}
\label{sec:DDE}
DDE stands for \DDE\@. DDE is an \windoz\
protocol used for data exchange between applications.
It has synchronous and asynchronous operation modes.
DDE mechanism is based on messages, atoms
(Section~\ref{sec:WhatAreAtoms}) and shared memory.
DDE applications are divided roughly into two classes: servers AND
clients. Clients have the initiative, they try to connect to the
server. Servers only maintain an existing DDE link.
\subsection{DDE Messages}
\paragraph{DDE message format}:
\label{sec:DDEMessageFormat}
DDE messages contain the following fields.
\begin{description}
\item[wnd] The recipient of this message ($-1$ if every window
should receive).
\item[msg] The ID of the message.
\item[wParam] Who sent this message.
\item[lParam] 32 bit parameter, divided into two 16 bit words.
Usually, the lower 16 bits contain a memory handle. The handle
points to some extra DATA about this message.
\end{description}
\paragraph{Available messages:}
\begin{description}
\item[WM\_DDE\_INITIATE]
This message is sent by the client to the whole ``world''.
{\em lParam}{} contains the two atoms used for passing the topic and
application information.
Every server application checks if this message refers to it
(According to the Application and the Topic atoms).
\item[WM\_DDE\_ACK]
This is a generic response to various events
(one of them is WM\_DDE\_INITIATE).
The low part of {\em lParam}{} passes extra information, such as
success/failure.
\item[WM\_DDE\_TERMINATE]
Kill the DDE link.
\item[WM\_DDE\_ADVISE]
Tell the server to inform the client of any updates.
\item[WM\_DDE\_UNADVISE]
Stop the WM\_DDE\_UNADVISE mode.
\item[WM\_DDE\_DATA]
Transfer data handle (note that the data handle must be globally allocated
with the GMEM\_DDESHARE flag).
\item[WM\_DDE\_REQUEST]
Request a data item from the server. This message is used in a
cold link. {\em lParam}{} contains an atom describing the desired
item, and a WORD describing the wanted data format.
\item[WM\_DDE\_POKE]
The client gives the server new data.
\item[WM\_DDE\_EXECUTE]
The client asks the server to execute a procedure (according to a
command string).
\end{description}
\subsection{Atoms}
\label{sec:WhatAreAtoms}
Atoms are represented by numbers. Every atom maps uniquely to a string
(i.e.\ two atoms can't map to the same string).
There are two types of atoms - local and global. The local are visible
only to the application that created them. Global atoms are seen by all
\windoz\ applications.
Functions:
\begin{description}
\item[AddAtom(str)] create a local atom that maps to ``str''.
If it exists, increment the allocation-counter,
and return the atom.
\item[DeleteAtom(atom)] decrement the allocation-counter. When it
reaches zero the atom, will be deleted.
\item[FindAtom(str)] Find the atom that maps to this string (if exist).
\item[GetAtomName(\ldots)] Find the string that this atom points to.
\end{description}
NOTE:
\begin{description}
\item[Global atoms] Add ``Global'' before the listed names to get Global
atom functions.
\item[Case sensitivity] All atom operations ignore case.
\end{description}
\section{DDE under \Wine\ - Alternatives}
\label{DDE-Alternatives}
There where three possible approaches for this project. I have chosen
System-V IPC, but it can be easily changed.
\subsection{IPC - Inter-Process Communication}
\label{sec:SysV-IPC}
The IPC mechanism was originated from System-V UNIX\@. This mechanism
allows complicate communication between two process (on the same machine).
IPC includes the following capabilities:
\begin{enumerate}
\item Shared Memory (shm) - can be shared among few processes and users.
\item Semaphores (These semaphores allow grouped operations - i.e.\
operations gathered as an atomic operation).
\item Message Queues (allow few messages at a time).
\end{enumerate}
The advantages of IPC over the other variants are:
\begin{itemize}
\item Memory access speed is good. (after the memory was attached).
\item Easy to block critical code (don't enter critical code from two
processes at the same time)
\end{itemize}
Disadvantages of IPC:
\begin{itemize}
\item Impossible to communicate to other machine.
\item Requires complex mechanism to wait both for X and IPC messages.
\end{itemize}
\subsection{X-Windows Communication mechanisms}
The advantages of X-Windows Communication over the other variants are:
\begin{itemize}
\item Possible to communicate to other machines.
\item No need for additional mechanism that will wait both for X and DDE\@.
\item Many of the required capabilities are already there.
\end{itemize}
Disadvantages of X-windows communication:
\begin{itemize}
\item {\em Slow}\ and complex memory access.
\item May be hard to avoid two applications from entering critical
code at the same time.
\end{itemize}
\subsection{BSD Sockets}
The advantages of Sockets are:
\begin{itemize}
\item Possible to communicate to other machines.
\item No need for complex mechanism that will wait both for X and
DDE\@. (can use one ``select'' on X-windows socket in concert with
the DDE socket).
\end{itemize}
Disadvantages of socket are:
\begin{itemize}
\item {\em Slow}{} and complex memory access. (note that mmap on a
descriptor does not work for Linux 0.99).
\item May be hard to avoid two applications from entering critical
code at the same time.
\end{itemize}
\subsection{Why was it written in C? Pros and cons.}
Advantages of C:
\begin{itemize}
\item History- \Wine{} is already written in C.
\item Portability- not all systems have C++.
\item Speed- C++ sometimes makes it very difficult to write fast code.
\item Maintenance- More programmers know C than C++.
\end{itemize}
Advantages of C++:
\begin{itemize}
\item smaller code - Templates allow Smaller and more readable code.
\item Maintenance - It is easier to add and modify code in C++ (than in C).
\item Verification - Functionality can be verified and debugged for
individual objects.
\end{itemize}
I have decided to use C. Most of C++ advantages can be acquired
by using OOP methodologies. OOP methods that require inline functions
can't be used (without performance impact). GCC supports inline functions,
but this solution is not compatible.
\section{\Wine\ basics}
\subsection{How it runs}
\Wine\ works in the following order:
\begin{enumerate}
\item \Wine\ loads the \windoz\ application into it's memory.
(in the process it, links
DLL's\footnote{DLL (Dynamically Linked Library) is linked on load-time.}
creates 16-bit segments).
\item \windoz\ code is executed.
\end{enumerate}
\section{bibliography}
\begin{thebibliography}{99}
\bibitem{bib:WinManual} Charles Petzold {\em Programming
Windows~3.1}{} - 1992. \\
On cover: {\em the Microsoft guide to writing applications for
windows~3.1}. \\
Published by {\em Microsoft press}.
\end{thebibliography}
\newpage
\end{document}