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