Added mappings for a few messages.
[wine] / dlls / oleaut32 / ole2disp.c
1 /*
2  *      OLE2DISP library
3  *
4  *      Copyright 1995  Martin von Loewis
5  */
6
7 #include "config.h"
8
9 #include <string.h>
10
11 #include "ole2.h"
12 #include "oleauto.h"
13 #include "windef.h"
14 #include "winbase.h"
15 #include "winerror.h"
16 #include "wingdi.h"
17 #include "winuser.h"
18
19 #include "heap.h"
20 #include "ole2disp.h"
21 #include "olectl.h"
22
23 #include "debugtools.h"
24
25 DEFAULT_DEBUG_CHANNEL(ole);
26
27 /* This implementation of the BSTR API is 16-bit only. It
28    represents BSTR as a 16:16 far pointer, and the strings
29    as ISO-8859 */
30
31 /******************************************************************************
32  *              BSTR_AllocBytes [Internal]
33  */
34 static BSTR16 BSTR_AllocBytes(int n)
35 {
36     void *ptr = SEGPTR_ALLOC(n);
37     return (BSTR16)SEGPTR_GET(ptr);
38 }
39
40 /******************************************************************************
41  * BSTR_Free [INTERNAL]
42  */
43 static void BSTR_Free(BSTR16 in)
44 {
45     SEGPTR_FREE( MapSL((SEGPTR)in) );
46 }
47
48 /******************************************************************************
49  * BSTR_GetAddr [INTERNAL]
50  */
51 static void* BSTR_GetAddr(BSTR16 in)
52 {
53     return in ? MapSL((SEGPTR)in) : 0;
54 }
55
56 /******************************************************************************
57  *              SysAllocString  [OLE2DISP.2]
58  */
59 BSTR16 WINAPI SysAllocString16(LPCOLESTR16 in)
60 {
61         BSTR16 out;
62     
63         if (!in) return 0;
64     
65         out = BSTR_AllocBytes(strlen(in)+1);
66         if(!out)return 0;
67         strcpy(BSTR_GetAddr(out),in);
68         return out;
69 }
70
71 /******************************************************************************
72  *              SysAllocString  [OLEAUT32.2]
73  */
74 BSTR WINAPI SysAllocString(LPCOLESTR in)
75 {
76     if (!in) return 0;
77     
78     /* Delegate this to the SysAllocStringLen32 method. */
79     return SysAllocStringLen(in, lstrlenW(in));
80 }
81
82 /******************************************************************************
83  *              SysReallocString        [OLE2DISP.3]
84  */
85 INT16 WINAPI SysReAllocString16(LPBSTR16 old,LPCOLESTR16 in)
86 {
87         BSTR16 new=SysAllocString16(in);
88         BSTR_Free(*old);
89         *old=new;
90         return 1;
91 }
92
93 /******************************************************************************
94  *              SysReAllocString        [OLEAUT32.3]
95  */
96 INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in)
97 {
98     /*
99      * Sanity check
100      */
101     if (old==NULL) 
102       return 0;
103
104     /*
105      * Make sure we free the old string.
106      */
107     if (*old!=NULL)      
108       SysFreeString(*old);
109
110     /*
111      * Allocate the new string
112      */
113     *old = SysAllocString(in);
114
115      return 1;
116 }
117
118 /******************************************************************************
119  *              SysAllocStringLen       [OLE2DISP.4]
120  */
121 BSTR16 WINAPI SysAllocStringLen16(const char *in, int len)
122 {
123         BSTR16 out=BSTR_AllocBytes(len+1);
124
125         if (!out)
126                 return 0;
127
128     /*
129      * Copy the information in the buffer.
130      * Since it is valid to pass a NULL pointer here, we'll initialize the
131      * buffer to nul if it is the case.
132      */
133     if (in != 0)
134         strcpy(BSTR_GetAddr(out),in);
135     else
136       memset(BSTR_GetAddr(out), 0, len+1);
137
138         return out;
139 }
140
141 /******************************************************************************
142  *             SysAllocStringLen     [OLEAUT32.4]
143  *
144  * In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation
145  * section, he describes the DWORD value placed *before* the BSTR data type.
146  * he describes it as a "DWORD count of characters". By experimenting with
147  * a windows application, this count seems to be a DWORD count of bytes in
148  * the string. Meaning that the count is double the number of wide 
149  * characters in the string.
150  */
151 BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len)
152 {
153     DWORD  bufferSize;
154     DWORD* newBuffer;
155     WCHAR* stringBuffer;
156
157     /*
158      * Find the length of the buffer passed-in in bytes.
159      */
160     bufferSize = len * sizeof (WCHAR);
161
162     /*
163      * Allocate a new buffer to hold the string.
164      * dont't forget to keep an empty spot at the beginning of the
165      * buffer for the character count and an extra character at the
166      * end for the NULL.
167      */
168     newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
169                                  0,
170                                  bufferSize + sizeof(WCHAR) + sizeof(DWORD));
171
172     /*
173      * If the memory allocation failed, return a null pointer.
174      */
175     if (newBuffer==0)
176       return 0;
177
178     /*
179      * Copy the length of the string in the placeholder.
180      */
181     *newBuffer = bufferSize;
182
183     /*
184      * Skip the byte count.
185      */
186     newBuffer++;
187
188     /*
189      * Copy the information in the buffer.
190      * Since it is valid to pass a NULL pointer here, we'll initialize the
191      * buffer to nul if it is the case.
192      */
193     if (in != 0)
194       memcpy(newBuffer, in, bufferSize);
195     else
196       memset(newBuffer, 0, bufferSize);
197
198     /*
199      * Make sure that there is a nul character at the end of the
200      * string.
201      */
202     stringBuffer = (WCHAR*)newBuffer;
203     stringBuffer[len] = L'\0';
204
205     return (LPWSTR)stringBuffer;
206 }
207
208 /******************************************************************************
209  *              SysReAllocStringLen     [OLE2DISP.5]
210  */
211 int WINAPI SysReAllocStringLen16(BSTR16 *old,const char *in,int len)
212 {
213         BSTR16 new=SysAllocStringLen16(in,len);
214         BSTR_Free(*old);
215         *old=new;
216         return 1;
217 }
218
219  
220 /******************************************************************************
221  *             SysReAllocStringLen   [OLEAUT32.5]
222  */
223 int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
224 {
225     /*
226      * Sanity check
227      */
228     if (old==NULL) 
229       return 0;
230
231     /*
232      * Make sure we free the old string.
233      */
234     if (*old!=NULL)      
235       SysFreeString(*old);
236
237     /*
238      * Allocate the new string
239      */
240     *old = SysAllocStringLen(in, len);
241
242     return 1;
243 }
244
245 /******************************************************************************
246  *              SysFreeString   [OLE2DISP.6]
247  */
248 void WINAPI SysFreeString16(BSTR16 in)
249 {
250         BSTR_Free(in);
251 }
252
253 /******************************************************************************
254  *              SysFreeString   [OLEAUT32.6]
255  */
256 void WINAPI SysFreeString(BSTR in)
257 {
258     DWORD* bufferPointer;
259     
260     /* NULL is a valid parameter */
261     if(!in) return;
262
263     /*
264      * We have to be careful when we free a BSTR pointer, it points to
265      * the beginning of the string but it skips the byte count contained
266      * before the string.
267      */
268     bufferPointer = (DWORD*)in;
269
270     bufferPointer--;
271
272     /*
273      * Free the memory from it's "real" origin.
274      */
275     HeapFree(GetProcessHeap(), 0, bufferPointer);
276 }
277
278 /******************************************************************************
279  *              SysStringLen    [OLE2DISP.7]
280  */
281 int WINAPI SysStringLen16(BSTR16 str)
282 {
283         return strlen(BSTR_GetAddr(str));
284 }
285
286 /******************************************************************************
287  *             SysStringLen  [OLEAUT32.7]
288  *
289  * The Windows documentation states that the length returned by this function
290  * is not necessarely the same as the length returned by the _lstrlenW method.
291  * It is the same number that was passed in as the "len" parameter if the
292  * string was allocated with a SysAllocStringLen method call.
293  */
294 int WINAPI SysStringLen(BSTR str)
295 {
296     DWORD* bufferPointer;
297
298      if (!str) return 0;
299     /*
300      * The length of the string (in bytes) is contained in a DWORD placed 
301      * just before the BSTR pointer
302      */
303     bufferPointer = (DWORD*)str;
304
305     bufferPointer--;
306
307     return (int)(*bufferPointer/sizeof(WCHAR));
308 }
309
310 /******************************************************************************
311  *             SysStringByteLen  [OLEAUT32.149]
312  *
313  * The Windows documentation states that the length returned by this function
314  * is not necessarely the same as the length returned by the _lstrlenW method.
315  * It is the same number that was passed in as the "len" parameter if the
316  * string was allocated with a SysAllocStringLen method call.
317  */
318 int WINAPI SysStringByteLen(BSTR str)
319 {
320     DWORD* bufferPointer;
321
322      if (!str) return 0;
323     /*
324      * The length of the string (in bytes) is contained in a DWORD placed 
325      * just before the BSTR pointer
326      */
327     bufferPointer = (DWORD*)str;
328
329     bufferPointer--;
330
331     return (int)(*bufferPointer);
332 }
333
334 /******************************************************************************
335  * CreateDispTypeInfo [OLE2DISP.31]
336  */
337 HRESULT WINAPI CreateDispTypeInfo16(
338         INTERFACEDATA *pidata,
339         LCID lcid,
340         ITypeInfo **pptinfo)
341 {
342         FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
343         return 0;
344 }
345
346 /******************************************************************************
347  * CreateDispTypeInfo [OLEAUT32.31]
348  */
349 HRESULT WINAPI CreateDispTypeInfo(
350         INTERFACEDATA *pidata,
351         LCID lcid,
352         ITypeInfo **pptinfo)
353 {
354         FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
355         return 0;
356 }
357
358 /******************************************************************************
359  * CreateStdDispatch [OLE2DISP.32]
360  */
361 HRESULT WINAPI CreateStdDispatch16(
362         IUnknown* punkOuter,
363         void* pvThis,
364         ITypeInfo* ptinfo,
365         IUnknown** ppunkStdDisp)
366 {
367         FIXME("(%p,%p,%p,%p),stub\n",punkOuter, pvThis, ptinfo,
368                ppunkStdDisp);
369         return 0;
370 }
371
372 /******************************************************************************
373  * CreateStdDispatch [OLEAUT32.32]
374  */
375 HRESULT WINAPI CreateStdDispatch(
376         IUnknown* punkOuter,
377         void* pvThis,
378         ITypeInfo* ptinfo,
379         IUnknown** ppunkStdDisp)
380 {
381         FIXME("(%p,%p,%p,%p),stub\n",punkOuter, pvThis, ptinfo,
382                ppunkStdDisp);
383         return 0;
384 }
385
386 /******************************************************************************
387  * RegisterActiveObject [OLE2DISP.35]
388  */
389 HRESULT WINAPI RegisterActiveObject16(
390         IUnknown *punk, REFCLSID rclsid, DWORD dwFlags, unsigned long *pdwRegister
391 ) {
392         FIXME("(%p,%s,0x%08lx,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister);
393         return 0;
394 }
395
396 /******************************************************************************
397  *              OleTranslateColor       [OLEAUT32.421]
398  *
399  * Converts an OLE_COLOR to a COLORREF.
400  * See the documentation for conversion rules.
401  * pColorRef can be NULL. In that case the user only wants to test the 
402  * conversion.
403  */
404 HRESULT WINAPI OleTranslateColor(
405   OLE_COLOR clr,
406   HPALETTE  hpal,
407   COLORREF* pColorRef)
408 {
409   COLORREF colorref;
410   BYTE b = HIBYTE(HIWORD(clr));
411
412   TRACE("(%08lx, %d, %p):stub\n", clr, hpal, pColorRef);
413
414   /*
415    * In case pColorRef is NULL, provide our own to simplify the code.
416    */
417   if (pColorRef == NULL)
418     pColorRef = &colorref;
419
420   switch (b)
421   {
422     case 0x00:
423     {
424       if (hpal != 0)
425         *pColorRef =  PALETTERGB(GetRValue(clr),
426                                  GetGValue(clr),
427                                  GetBValue(clr));
428       else
429         *pColorRef = clr;
430
431       break;
432     }
433
434     case 0x01:
435     {
436       if (hpal != 0)
437       {
438         PALETTEENTRY pe;
439         /*
440          * Validate the palette index.
441          */
442         if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
443           return E_INVALIDARG;
444       }
445
446       *pColorRef = clr;
447
448       break;
449     }
450
451     case 0x02:
452       *pColorRef = clr;
453       break;
454
455     case 0x80:
456     {
457       int index = LOBYTE(LOWORD(clr));
458
459       /*
460        * Validate GetSysColor index.
461        */
462       if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION))
463         return E_INVALIDARG;
464
465       *pColorRef =  GetSysColor(index);
466
467       break;
468     }
469
470     default:
471       return E_INVALIDARG;
472   }
473
474   return S_OK;
475 }
476
477 /******************************************************************************
478  *             SysAllocStringByteLen     [OLEAUT32.150]
479  *
480  */
481 BSTR WINAPI SysAllocStringByteLen(LPCSTR in, UINT len)
482 {
483     DWORD* newBuffer;
484     char* stringBuffer;
485
486     /*
487      * Allocate a new buffer to hold the string.
488      * dont't forget to keep an empty spot at the begining of the
489      * buffer for the character count and an extra character at the
490      * end for the NULL.
491      */
492     newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
493                                  0,
494                                  len + sizeof(WCHAR) + sizeof(DWORD));
495
496     /*
497      * If the memory allocation failed, return a null pointer.
498      */
499     if (newBuffer==0)
500       return 0;
501
502     /*
503      * Copy the length of the string in the placeholder.
504      */
505     *newBuffer = len;
506
507     /*
508      * Skip the byte count.
509      */
510     newBuffer++;
511
512     /*
513      * Copy the information in the buffer.
514      * Since it is valid to pass a NULL pointer here, we'll initialize the
515      * buffer to nul if it is the case.
516      */
517     if (in != 0)
518       memcpy(newBuffer, in, len);
519
520     /*
521      * Make sure that there is a nul character at the end of the
522      * string.
523      */
524     stringBuffer = (char *)newBuffer;
525     stringBuffer[len] = 0;
526     stringBuffer[len+1] = 0;
527
528     return (LPWSTR)stringBuffer;
529 }
530
531