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