When including 'wine/port.h', include it first.
[wine] / dlls / user / dde / dde_private.h
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  * DDEML library
5  *
6  * Copyright 1997 Alexandre Julliard
7  * Copyright 1997 Len White
8  * Copyright 1999 Keith Matthews
9  * Copyright 2000 Corel
10  * Copyright 2001 Eric Pouech
11  */
12
13 #ifndef __WINE_DDEML_PRIVATE_H
14 #define __WINE_DDEML_PRIVATE_H
15
16 /* defined in atom.c file.
17  */
18 #define MAX_ATOM_LEN              255
19
20 /* Maximum buffer size ( including the '\0' ).
21  */
22 #define MAX_BUFFER_LEN            (MAX_ATOM_LEN + 1)
23
24 /* The internal structures (prefixed by WDML) are used as follows:
25  * + a WDML_INSTANCE is created for each instance creation (DdeInitialize)
26  *      - a popup window (InstanceClass) is created for each instance.
27  *      - this window is used to receive all the DDEML events (server registration, 
28  *        conversation confirmation...). See the WM_WDML_???? messages for details
29  * + when registring a server (DdeNameService) a WDML_SERVER is created
30  *      - a popup window (ServerNameClass) is created
31  * + a conversation is represented by two WDML_CONV structures:
32  *      - one on the client side, the other one on the server side
33  *      - this is needed because the address spaces may be different
34  *      - therefore, two lists of links are kept for each instance
35  *      - two windows are created for a conversation:
36  *              o a popup window on client side (ClientConvClass)
37  *              o a child window (of the ServerName) on the server side
38  *                (ServerConvClass)
39  *      - all the exchanges then take place between those two windows
40  *      - windows for the conversation exist in two forms (Ansi & Unicode). This
41  *        is only needed when a partner in a conv is not handled by DDEML. The
42  *        type (A/W) of the window is used to handle the ansi <=> unicode 
43  *        transformations
44  *      - two handles are created for a conversation (on each side). Each handle
45  *        is linked to a structure. To help differentiate those handles, the
46  *        local one has an even value, whereas the remote one has an odd value.
47  * + a (warm or link) is represented by two WDML_LINK structures:
48  *      - one on client side, the other one on server side
49  *      - therefore, two lists of links are kept for each instance
50  *      
51  * To help getting back to data, WDML windows store information:
52  *      - offset 0: the DDE instance
53  *      - offset 4: the current conversation (for ClientConv and ServerConv only)
54  *
55  * All the implementation (client & server) makes the assumption that the other side
56  * is not always a DDEML partner. However, if it's the case, supplementary services
57  * are available (most notably the REGISTER/UNREGISTER and CONNECT_CONFIRM messages
58  * to the callback function). To be correct in every situation, all the basic 
59  * exchanges are made using the 'pure' DDE protocol. A (future !) enhancement would
60  * be to provide a new protocol in the case were both partners are handled by DDEML.
61  *
62  * The StringHandles are in fact stored as local atoms. So an HSZ and a (local) atom
63  * can be used interchangably. However, in order to keep track of the allocated HSZ, 
64  * and to free them upon instance termination, all HSZ are stored in a link list.
65  * When the HSZ need to be passed thru DDE messages, we need to convert them back and
66  * forth to global atoms.
67  */
68
69 /* this struct has the same mapping as all the DDE??? structures */
70 typedef struct {
71     unsigned short unused:12,
72                    fResponse:1,
73                    fRelease:1,
74                    fDeferUpd:1,
75                    fAckReq:1;
76     short    cfFormat;
77 } WINE_DDEHEAD;
78
79 typedef struct tagHSZNode
80 {
81     struct tagHSZNode*          next;
82     HSZ                         hsz;
83     unsigned                    refCount;
84 } HSZNode;
85
86 typedef struct tagWDML_SERVER
87 {
88     struct tagWDML_SERVER*      next;
89     HSZ                         hszService;
90     HSZ                         hszServiceSpec;
91     ATOM                        atomService;
92     ATOM                        atomServiceSpec;
93     BOOL                        filterOn;
94     HWND                        hwndServer;
95 } WDML_SERVER;
96
97 typedef struct tagWDML_XACT {
98     struct tagWDML_XACT*        next;           /* list of transactions in conversation */
99     DWORD                       xActID;
100     UINT                        ddeMsg;
101     HDDEDATA                    hDdeData;
102     DWORD                       dwTimeout;
103     DWORD                       hUser;
104     UINT                        wType;
105     UINT                        wFmt;
106     HSZ                         hszItem;
107     ATOM                        atom;           /* as converted from or to hszItem */
108     HGLOBAL                     hMem;
109     LPARAM                      lParam;         /* useful for reusing */
110 } WDML_XACT;
111
112 typedef struct tagWDML_CONV 
113 {
114     struct tagWDML_CONV*        next;           /* to link all the conversations */
115     struct tagWDML_INSTANCE*    instance;
116     HSZ                         hszService;     /* pmt used for connection */
117     HSZ                         hszTopic;       /* pmt used for connection */
118     UINT                        afCmd;          /* service name flag */
119     CONVCONTEXT                 convContext;
120     HWND                        hwndClient;     /* source of conversation (ClientConvClass) */
121     HWND                        hwndServer;     /* destination of conversation (ServerConvClass) */
122     WDML_XACT*                  transactions;   /* pending transactions */
123     DWORD                       hUser;          /* user defined value */
124     DWORD                       wStatus;        /* same bits as convinfo.wStatus */
125     DWORD                       wConvst;        /* same values as convinfo.wConvst */
126 } WDML_CONV;
127
128 /* DDE_LINK struct defines hot, warm, and cold links */
129 typedef struct tagWDML_LINK {
130     struct tagWDML_LINK*        next;           /* to link all the active links */
131     HCONV                       hConv;          /* to get back to the converstaion */
132     UINT                        transactionType;/* 0 for no link */
133     HSZ                         hszItem;        /* item targetted for (hot/warm) link */
134     UINT                        uFmt;           /* format for data */
135     HDDEDATA                    hDdeData;       /* data them selves */
136 } WDML_LINK;
137
138 typedef struct tagWDML_INSTANCE
139 {
140     struct tagWDML_INSTANCE*    next;
141     DWORD                       instanceID;     /* needed to track monitor usage */
142     DWORD                       threadID;       /* needed to keep instance linked to a unique thread */
143     BOOL                        monitor;        /* have these two as full Booleans cos they'll be tested frequently */
144     BOOL                        clientOnly;     /* bit wasteful of space but it will be faster */
145     BOOL                        unicode;        /* Flag to indicate Win32 API used to initialise */
146     BOOL                        win16;          /* flag to indicate Win16 API used to initialize */
147     HSZNode*                    nodeList;       /* for cleaning upon exit */
148     PFNCALLBACK                 callback;
149     DWORD                       CBFflags;
150     DWORD                       monitorFlags;
151     DWORD                       lastError; 
152     HWND                        hwndEvent;
153     WDML_SERVER*                servers;        /* list of registered servers */
154     WDML_CONV*                  convs[2];       /* active conversations for this instance (client and server) */
155     WDML_LINK*                  links[2];       /* active links for this instance (client and server) */
156 } WDML_INSTANCE;
157
158 extern CRITICAL_SECTION WDML_CritSect;          /* protection for instance list */
159
160 /* header for the DDE Data objects */
161 typedef struct tagDDE_DATAHANDLE_HEAD
162 {
163     short       cfFormat;
164 } DDE_DATAHANDLE_HEAD;
165
166 typedef enum tagWDML_SIDE
167 {
168     WDML_CLIENT_SIDE = 0, WDML_SERVER_SIDE = 1
169 } WDML_SIDE;
170
171 typedef enum {
172     WDML_QS_ERROR, WDML_QS_HANDLED, WDML_QS_PASS, WDML_QS_SWALLOWED, WDML_QS_BLOCK,
173 } WDML_QUEUE_STATE;
174
175 extern  HDDEDATA        WDML_InvokeCallback(WDML_INSTANCE* pInst, UINT uType, UINT uFmt, HCONV hConv,
176                                             HSZ hsz1, HSZ hsz2, HDDEDATA hdata, 
177                                             DWORD dwData1, DWORD dwData2);
178 extern  HDDEDATA        WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt, HCONV hConv,
179                                               HSZ hsz1, HSZ hsz2, HDDEDATA hdata, 
180                                               DWORD dwData1, DWORD dwData2);
181 extern  WDML_SERVER*    WDML_AddServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic);
182 extern  void            WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic);
183 extern  WDML_SERVER*    WDML_FindServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic);
184 /* called both in DdeClientTransaction and server side. */              
185 extern  UINT            WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
186                                         DWORD afCmd, DWORD ulRes, BOOL bUnicode, BOOL b16);
187 extern  WDML_CONV*      WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side, 
188                                      HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer);
189 extern  void            WDML_RemoveConv(WDML_CONV* pConv, WDML_SIDE side);
190 extern  WDML_CONV*      WDML_GetConv(HCONV hConv, BOOL checkConnected);
191 extern  WDML_CONV*      WDML_GetConvFromWnd(HWND hWnd);
192 extern  WDML_CONV*      WDML_FindConv(WDML_INSTANCE* pInstance, WDML_SIDE side, 
193                                       HSZ hszService, HSZ hszTopic);    
194 extern  LPARAM          WDML_PostAck(WDML_CONV* pConv, WDML_SIDE side, WORD appRetCode, 
195                                      BOOL fBusy, BOOL fAck, ATOM atom, LPARAM lParam, UINT oldMsg);
196 extern  void            WDML_AddLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, 
197                                      UINT wType, HSZ hszItem, UINT wFmt);
198 extern  WDML_LINK*      WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, 
199                                       HSZ hszItem, UINT uFmt);
200 extern  void            WDML_RemoveLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side, 
201                                         HSZ hszItem, UINT wFmt);
202 extern  void            WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE side);
203 /* string internals */
204 extern  void            WDML_FreeAllHSZ(WDML_INSTANCE* pInstance);
205 extern  BOOL            WDML_DecHSZ(WDML_INSTANCE* pInstance, HSZ hsz);
206 extern  BOOL            WDML_IncHSZ(WDML_INSTANCE* pInstance, HSZ hsz);
207 extern  ATOM            WDML_MakeAtomFromHsz(HSZ hsz);
208 extern  HSZ             WDML_MakeHszFromAtom(WDML_INSTANCE* pInstance, ATOM atom);
209 /* client calls these */
210 extern  WDML_XACT*      WDML_AllocTransaction(WDML_INSTANCE* pInstance, UINT ddeMsg, UINT wFmt, HSZ hszItem);
211 extern  void            WDML_QueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct);
212 extern  BOOL            WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT*  pXAct);
213 extern  void            WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt);
214 extern  WDML_XACT*      WDML_FindTransaction(WDML_CONV* pConv, DWORD tid);
215 extern  HGLOBAL         WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease, 
216                                                BOOL fDeferUpd, BOOL dAckReq);
217 extern  HDDEDATA        WDML_Global2DataHandle(HGLOBAL hMem, WINE_DDEHEAD* da);
218 extern  WDML_INSTANCE*  WDML_GetInstance(DWORD InstId);
219 extern  WDML_INSTANCE*  WDML_GetInstanceFromWnd(HWND hWnd);
220 /* broadcasting to DDE windows */
221 extern  void            WDML_BroadcastDDEWindows(const char* clsName, UINT uMsg, 
222                                                  WPARAM wParam, LPARAM lParam);
223 extern  void            WDML_NotifyThreadExit(DWORD tid);
224
225 static inline void WDML_ExtractAck(WORD status, DDEACK* da)
226 {
227     *da = *((DDEACK*)&status);
228 }
229
230 extern const char       WDML_szEventClass[];       /* class of window for events (aka instance) */
231 extern const char       WDML_szServerConvClassA[]; /* class of window for server side conv (ansi) */
232 extern const WCHAR      WDML_szServerConvClassW[]; /* class of window for server side conv (unicode) */
233 extern const char       WDML_szClientConvClassA[]; /* class of window for client side conv (ansi) */
234 extern const WCHAR      WDML_szClientConvClassW[]; /* class of window for client side conv (unicode) */
235
236 #define WM_WDML_REGISTER        (WM_USER + 0x200)
237 #define WM_WDML_UNREGISTER      (WM_USER + 0x201)
238 #define WM_WDML_CONNECT_CONFIRM (WM_USER + 0x202)
239
240 /* parameters for messages: 
241  *                      wParam                          lParam
242  * Register             atom for service name           atom for service spec
243  * Unregister           atom for service name           atom for service spec
244  * ConnectConfirm       client window handle            server window handle
245  */
246
247 #define GWL_WDML_INSTANCE       (0)
248 #define GWL_WDML_CONVERSATION   (4)
249 #define GWL_WDML_SERVER         (4)
250
251 #endif  /* __WINE_DDEML_PRIVATE_H */