Avoid excessive heap memory reallocation when generating EMF
[wine] / dlls / user / dde / ddeml16.c
1 /*
2  * DDEML library
3  *
4  * Copyright 1997 Alexandre Julliard
5  * Copyright 1997 Len White
6  * Copyright 1999 Keith Matthews
7  * Copyright 2000 Corel
8  * Copyright 2001,2002 Eric Pouech
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24
25 #include <stdarg.h>
26 #include <string.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wine/windef16.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "winerror.h"
33 #include "wownt32.h"
34 #include "dde.h"
35 #include "ddeml.h"
36 #include "dde/dde_private.h"
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
40
41
42 typedef HDDEDATA (CALLBACK *PFNCALLBACK16)(UINT16,UINT16,HCONV,HSZ,HSZ,HDDEDATA,
43                                            DWORD,DWORD);
44
45 typedef struct
46 {
47     UINT16  cb;
48     UINT16  wFlags;
49     UINT16  wCountryID;
50     INT16   iCodePage;
51     DWORD   dwLangID;
52     DWORD   dwSecurity;
53 } CONVCONTEXT16, *LPCONVCONTEXT16;
54
55 typedef struct
56 {
57     DWORD          cb;
58     DWORD          hUser;
59     HCONV          hConvPartner;
60     HSZ            hszSvcPartner;
61     HSZ            hszServiceReq;
62     HSZ            hszTopic;
63     HSZ            hszItem;
64     UINT16         wFmt;
65     UINT16         wType;
66     UINT16         wStatus;
67     UINT16         wConvst;
68     UINT16         wLastError;
69     HCONVLIST      hConvList;
70     CONVCONTEXT16  ConvCtxt;
71 } CONVINFO16, *LPCONVINFO16;
72
73 static void map1632_conv_context(CONVCONTEXT* cc32, const CONVCONTEXT16* cc16)
74 {
75     cc32->cb = sizeof(*cc32);
76     cc32->wFlags = cc16->wFlags;
77     cc32->wCountryID = cc16->wCountryID;
78     cc32->iCodePage = cc16->iCodePage;
79     cc32->dwLangID = cc16->dwLangID;
80     cc32->dwSecurity = cc16->dwSecurity;
81 }
82
83 static void map3216_conv_context(CONVCONTEXT16* cc16, const CONVCONTEXT* cc32)
84 {
85     cc16->cb = sizeof(*cc16);
86     cc16->wFlags = cc32->wFlags;
87     cc16->wCountryID = cc32->wCountryID;
88     cc16->iCodePage = cc32->iCodePage;
89     cc16->dwLangID = cc32->dwLangID;
90     cc16->dwSecurity = cc32->dwSecurity;
91 }
92
93
94 /******************************************************************
95  *              WDML_InvokeCallback16
96  *
97  *
98  */
99 HDDEDATA        WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt,
100                                       HCONV hConv, HSZ hsz1, HSZ hsz2,
101                                       HDDEDATA hdata, DWORD dwData1, DWORD dwData2)
102 {
103     DWORD               d1 = 0;
104     HDDEDATA            ret;
105     CONVCONTEXT16       cc16;
106     WORD args[16];
107
108     switch (uType)
109     {
110     case XTYP_CONNECT:
111     case XTYP_WILDCONNECT:
112         if (dwData1)
113         {
114             map3216_conv_context(&cc16, (const CONVCONTEXT*)dwData1);
115             d1 = MapLS(&cc16);
116         }
117         else
118         break;
119     default:
120         d1 = dwData1;
121         break;
122     }
123     args[15] = HIWORD(uType);
124     args[14] = LOWORD(uType);
125     args[13] = HIWORD(uFmt);
126     args[12] = LOWORD(uFmt);
127     args[11] = HIWORD(hConv);
128     args[10] = LOWORD(hConv);
129     args[9]  = HIWORD(hsz1);
130     args[8]  = LOWORD(hsz1);
131     args[7]  = HIWORD(hsz2);
132     args[6]  = LOWORD(hsz2);
133     args[5]  = HIWORD(hdata);
134     args[4]  = LOWORD(hdata);
135     args[3]  = HIWORD(d1);
136     args[2]  = LOWORD(d1);
137     args[1]  = HIWORD(dwData2);
138     args[0]  = LOWORD(dwData2);
139     WOWCallback16Ex( (DWORD)pfn, WCB16_PASCAL, sizeof(args), args, (DWORD *)&ret );
140
141     switch (uType)
142     {
143     case XTYP_CONNECT:
144     case XTYP_WILDCONNECT:
145         if (d1 != 0) UnMapLS(d1);
146         break;
147     }
148     return ret;
149 }
150
151 /******************************************************************************
152  *            DdeInitialize   (DDEML.2)
153  */
154 UINT16 WINAPI DdeInitialize16(LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
155                               DWORD afCmd, DWORD ulRes)
156 {
157     return WDML_Initialize(pidInst, (PFNCALLBACK)pfnCallback, afCmd, ulRes,
158                            FALSE, TRUE);
159 }
160
161 /*****************************************************************
162  *            DdeUninitialize   (DDEML.3)
163  */
164 BOOL16 WINAPI DdeUninitialize16(DWORD idInst)
165 {
166     return (BOOL16)DdeUninitialize(idInst);
167 }
168
169 /*****************************************************************
170  * DdeConnectList [DDEML.4]
171  */
172
173 HCONVLIST WINAPI DdeConnectList16(DWORD idInst, HSZ hszService, HSZ hszTopic,
174                                   HCONVLIST hConvList, LPCONVCONTEXT16 pCC16)
175 {
176     CONVCONTEXT         cc;
177     CONVCONTEXT*        pCC = NULL;
178
179     if (pCC16)
180         map1632_conv_context(pCC = &cc, pCC16);
181     return DdeConnectList(idInst, hszService, hszTopic, hConvList, pCC);
182 }
183
184 /*****************************************************************
185  * DdeQueryNextServer [DDEML.5]
186  */
187 HCONV WINAPI DdeQueryNextServer16(HCONVLIST hConvList, HCONV hConvPrev)
188 {
189     return DdeQueryNextServer(hConvList, hConvPrev);
190 }
191
192 /*****************************************************************
193  *            DdeDisconnectList (DDEML.6)
194  */
195 BOOL16 WINAPI DdeDisconnectList16(HCONVLIST hConvList)
196 {
197     return (BOOL16)DdeDisconnectList(hConvList);
198 }
199
200
201 /*****************************************************************
202  *              DdeQueryString (DDEML.23)
203  */
204 DWORD WINAPI DdeQueryString16(DWORD idInst, HSZ hsz, LPSTR lpsz, DWORD cchMax,
205                               INT16 codepage)
206 {
207     return DdeQueryStringA(idInst, hsz, lpsz, cchMax, codepage);
208 }
209
210 /*****************************************************************
211  *            DdeConnect   (DDEML.7)
212  */
213 HCONV WINAPI DdeConnect16(DWORD idInst, HSZ hszService, HSZ hszTopic,
214                           LPCONVCONTEXT16 pCC16)
215 {
216     CONVCONTEXT         cc;
217     CONVCONTEXT*        pCC = NULL;
218
219     if (pCC16)
220         map1632_conv_context(pCC = &cc, pCC16);
221     return DdeConnect(idInst, hszService, hszTopic, pCC);
222 }
223
224 /*****************************************************************
225  *            DdeDisconnect   (DDEML.8)
226  */
227 BOOL16 WINAPI DdeDisconnect16(HCONV hConv)
228 {
229     return (BOOL16)DdeDisconnect(hConv);
230 }
231
232 /*****************************************************************
233  *            DdeSetUserHandle (DDEML.10)
234  */
235 BOOL16 WINAPI DdeSetUserHandle16(HCONV hConv, DWORD id, DWORD hUser)
236 {
237     return DdeSetUserHandle(hConv, id, hUser);
238 }
239
240 /*****************************************************************
241  *            DdeCreateDataHandle (DDEML.14)
242  */
243 HDDEDATA WINAPI DdeCreateDataHandle16(DWORD idInst, LPBYTE pSrc, DWORD cb,
244                                       DWORD cbOff, HSZ hszItem, UINT16 wFmt,
245                                       UINT16 afCmd)
246 {
247     return DdeCreateDataHandle(idInst, pSrc, cb, cbOff, hszItem, wFmt, afCmd);
248 }
249
250 /*****************************************************************
251  *            DdeCreateStringHandle   (DDEML.21)
252  */
253 HSZ WINAPI DdeCreateStringHandle16(DWORD idInst, LPCSTR str, INT16 codepage)
254 {
255     if  (codepage)
256     {
257         return DdeCreateStringHandleA(idInst, str, codepage);
258     }
259     else
260     {
261         TRACE("Default codepage supplied\n");
262         return DdeCreateStringHandleA(idInst, str, CP_WINANSI);
263     }
264 }
265
266 /*****************************************************************
267  *            DdeFreeStringHandle   (DDEML.22)
268  */
269 BOOL16 WINAPI DdeFreeStringHandle16(DWORD idInst, HSZ hsz)
270 {
271     return (BOOL16)DdeFreeStringHandle(idInst, hsz);
272 }
273
274 /*****************************************************************
275  *            DdeFreeDataHandle   (DDEML.19)
276  */
277 BOOL16 WINAPI DdeFreeDataHandle16(HDDEDATA hData)
278 {
279     return (BOOL16)DdeFreeDataHandle(hData);
280 }
281
282 /*****************************************************************
283  *            DdeKeepStringHandle   (DDEML.24)
284  */
285 BOOL16 WINAPI DdeKeepStringHandle16(DWORD idInst, HSZ hsz)
286 {
287     return (BOOL)DdeKeepStringHandle(idInst, hsz);
288 }
289
290 /*****************************************************************
291  *            DdeClientTransaction  (DDEML.11)
292  */
293 HDDEDATA WINAPI DdeClientTransaction16(LPVOID pData, DWORD cbData, HCONV hConv,
294                                        HSZ hszItem, UINT16 wFmt, UINT16 wType,
295                                        DWORD dwTimeout, LPDWORD pdwResult)
296 {
297     return DdeClientTransaction((LPBYTE)pData, cbData, hConv, hszItem,
298                                 wFmt, wType, dwTimeout, pdwResult);
299 }
300
301 /*****************************************************************
302  *
303  *            DdeAbandonTransaction (DDEML.12)
304  *
305  */
306 BOOL16 WINAPI DdeAbandonTransaction16(DWORD idInst, HCONV hConv, DWORD idTransaction)
307 {
308     return (BOOL16)DdeAbandonTransaction(idInst, hConv, idTransaction);
309 }
310
311 /*****************************************************************
312  * DdePostAdvise [DDEML.13]
313  */
314 BOOL16 WINAPI DdePostAdvise16(DWORD idInst, HSZ hszTopic, HSZ hszItem)
315 {
316     return (BOOL16)DdePostAdvise(idInst, hszTopic, hszItem);
317 }
318
319 /*****************************************************************
320  *            DdeAddData (DDEML.15)
321  */
322 HDDEDATA WINAPI DdeAddData16(HDDEDATA hData, LPBYTE pSrc, DWORD cb, DWORD cbOff)
323 {
324     return DdeAddData(hData, pSrc, cb, cbOff);
325 }
326
327 /*****************************************************************
328  * DdeGetData [DDEML.16]
329  */
330 DWORD WINAPI DdeGetData16(HDDEDATA hData, LPBYTE pDst, DWORD cbMax, DWORD cbOff)
331 {
332     return DdeGetData(hData, pDst, cbMax, cbOff);
333 }
334
335 /*****************************************************************
336  *            DdeAccessData (DDEML.17)
337  */
338 LPBYTE WINAPI DdeAccessData16(HDDEDATA hData, LPDWORD pcbDataSize)
339 {
340     FIXME("expect trouble\n");
341     /* FIXME: there's a memory leak here... */
342     return (LPBYTE)MapLS(DdeAccessData(hData, pcbDataSize));
343 }
344
345 /*****************************************************************
346  *            DdeUnaccessData (DDEML.18)
347  */
348 BOOL16 WINAPI DdeUnaccessData16(HDDEDATA hData)
349 {
350     return DdeUnaccessData(hData);
351 }
352
353 /*****************************************************************
354  *            DdeEnableCallback (DDEML.26)
355  */
356 BOOL16 WINAPI DdeEnableCallback16(DWORD idInst, HCONV hConv, UINT16 wCmd)
357 {
358     return DdeEnableCallback(idInst, hConv, wCmd);
359 }
360
361 /*****************************************************************
362  *            DdeNameService  (DDEML.27)
363  */
364 HDDEDATA WINAPI DdeNameService16(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT16 afCmd)
365 {
366     return DdeNameService(idInst, hsz1, hsz2, afCmd);
367 }
368
369 /*****************************************************************
370  *            DdeGetLastError  (DDEML.20)
371  */
372 UINT16 WINAPI DdeGetLastError16(DWORD idInst)
373 {
374     return (UINT16)DdeGetLastError(idInst);
375 }
376
377 /*****************************************************************
378  *            DdeCmpStringHandles (DDEML.36)
379  */
380 INT16 WINAPI DdeCmpStringHandles16(HSZ hsz1, HSZ hsz2)
381 {
382     return DdeCmpStringHandles(hsz1, hsz2);
383 }
384
385 /******************************************************************
386  *              DdeQueryConvInfo (DDEML.9)
387  *
388  */
389 UINT16 WINAPI DdeQueryConvInfo16(HCONV hConv, DWORD idTransaction,
390                                  LPCONVINFO16 lpConvInfo)
391 {
392     CONVINFO    ci32;
393     CONVINFO16  ci16;
394     UINT        ret;
395
396     ci32.cb = sizeof(ci32);
397     ci32.ConvCtxt.cb = sizeof(ci32.ConvCtxt);
398
399     ret = DdeQueryConvInfo(hConv, idTransaction, &ci32);
400     if (ret == 0) return 0;
401
402     ci16.hUser = ci32.hUser;
403     ci16.hConvPartner = ci32.hConvPartner;
404     ci16.hszSvcPartner = ci32.hszSvcPartner;
405     ci16.hszServiceReq = ci32.hszServiceReq;
406     ci16.hszTopic = ci32.hszTopic;
407     ci16.hszItem = ci32.hszItem;
408     ci16.wFmt = ci32.wFmt;
409     ci16.wType = ci32.wType;
410     ci16.wStatus = ci32.wStatus;
411     ci16.wConvst = ci32.wConvst;
412     ci16.wLastError = ci32.wLastError;
413     ci16.hConvList = ci32.hConvList;
414
415     map3216_conv_context(&ci16.ConvCtxt, &ci32.ConvCtxt);
416
417     memcpy(lpConvInfo, &ci16, lpConvInfo->cb);
418     return lpConvInfo->cb;
419 }