blob: 54353f4762df41ac8fa87762f9d15a92464a93aa [file] [log] [blame]
Alexandre Julliardded30381995-07-06 17:18:27 +00001/*
2 * OLE2DISP library
3 *
4 * Copyright 1995 Martin von Loewis
5 */
Francis Beaudetf1779ed1998-11-25 17:20:36 +00006#include <string.h>
Jeremy Whited3e22d92000-02-10 19:03:02 +00007#include "windef.h"
8#include "wingdi.h"
Michael Veksler4405f3c1999-08-18 18:35:57 +00009#include "winuser.h"
Francis Beaudeteb5a29b1999-02-20 16:48:53 +000010#include "winerror.h"
Eric Pouech853043b2000-02-18 19:06:00 +000011#include "olectl.h"
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000012#include "oleauto.h"
Alexandre Julliardca22b331996-07-12 19:02:39 +000013#include "heap.h"
Alexandre Julliardded30381995-07-06 17:18:27 +000014#include "ldt.h"
Alexandre Julliard359f497e1999-07-04 16:02:24 +000015#include "debugtools.h"
Alexandre Julliardded30381995-07-06 17:18:27 +000016
Eric Pouech853043b2000-02-18 19:06:00 +000017DEFAULT_DEBUG_CHANNEL(ole);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000018
Alexandre Julliardded30381995-07-06 17:18:27 +000019/* This implementation of the BSTR API is 16-bit only. It
20 represents BSTR as a 16:16 far pointer, and the strings
21 as ISO-8859 */
22
Matthew Beckerb05264f1998-10-11 14:21:42 +000023/******************************************************************************
24 * BSTR_AllocBytes [Internal]
25 */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000026static BSTR16 BSTR_AllocBytes(int n)
Alexandre Julliardded30381995-07-06 17:18:27 +000027{
Alexandre Julliardca22b331996-07-12 19:02:39 +000028 void *ptr = SEGPTR_ALLOC(n);
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000029 return (BSTR16)SEGPTR_GET(ptr);
Alexandre Julliardded30381995-07-06 17:18:27 +000030}
31
Matthew Becker75175341998-10-18 14:39:06 +000032/******************************************************************************
33 * BSTR_Free [INTERNAL]
34 */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000035static void BSTR_Free(BSTR16 in)
Alexandre Julliardded30381995-07-06 17:18:27 +000036{
Alexandre Julliardca22b331996-07-12 19:02:39 +000037 SEGPTR_FREE( PTR_SEG_TO_LIN(in) );
Alexandre Julliardded30381995-07-06 17:18:27 +000038}
39
Matthew Becker75175341998-10-18 14:39:06 +000040/******************************************************************************
41 * BSTR_GetAddr [INTERNAL]
42 */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000043static void* BSTR_GetAddr(BSTR16 in)
Alexandre Julliardded30381995-07-06 17:18:27 +000044{
Alexandre Julliardca22b331996-07-12 19:02:39 +000045 return in ? PTR_SEG_TO_LIN(in) : 0;
Alexandre Julliardded30381995-07-06 17:18:27 +000046}
47
Matthew Beckerb05264f1998-10-11 14:21:42 +000048/******************************************************************************
49 * SysAllocString16 [OLE2DISP.2]
Alexandre Julliardded30381995-07-06 17:18:27 +000050 */
Francois Gougetdfc0f5e1999-03-13 18:13:10 +000051BSTR16 WINAPI SysAllocString16(LPCOLESTR16 in)
Alexandre Julliardded30381995-07-06 17:18:27 +000052{
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000053 BSTR16 out=BSTR_AllocBytes(strlen(in)+1);
Alexandre Julliardded30381995-07-06 17:18:27 +000054 if(!out)return 0;
55 strcpy(BSTR_GetAddr(out),in);
56 return out;
57}
58
Matthew Beckerb05264f1998-10-11 14:21:42 +000059/******************************************************************************
60 * SysAllocString32 [OLEAUT32.2]
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000061 */
Francois Gougetdfc0f5e1999-03-13 18:13:10 +000062BSTR WINAPI SysAllocString(LPCOLESTR in)
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000063{
Francis Beaudetf1779ed1998-11-25 17:20:36 +000064 /* Delegate this to the SysAllocStringLen32 method. */
Alexandre Julliarda3960291999-02-26 11:11:13 +000065 return SysAllocStringLen(in, lstrlenW(in));
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000066}
67
Matthew Beckerb05264f1998-10-11 14:21:42 +000068/******************************************************************************
69 * SysReAllocString16 [OLE2DISP.3]
Alexandre Julliardded30381995-07-06 17:18:27 +000070 */
Francois Gougetdfc0f5e1999-03-13 18:13:10 +000071INT16 WINAPI SysReAllocString16(LPBSTR16 old,LPCOLESTR16 in)
Alexandre Julliardded30381995-07-06 17:18:27 +000072{
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000073 BSTR16 new=SysAllocString16(in);
Alexandre Julliardded30381995-07-06 17:18:27 +000074 BSTR_Free(*old);
75 *old=new;
76 return 1;
77}
78
Matthew Beckerb05264f1998-10-11 14:21:42 +000079/******************************************************************************
80 * SysReAllocString32 [OLEAUT32.3]
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000081 */
Francois Gougetdfc0f5e1999-03-13 18:13:10 +000082INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in)
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000083{
Francis Beaudetf1779ed1998-11-25 17:20:36 +000084 /*
85 * Sanity check
86 */
87 if (old==NULL)
88 return 0;
89
90 /*
91 * Make sure we free the old string.
92 */
93 if (*old!=NULL)
Alexandre Julliarda3960291999-02-26 11:11:13 +000094 SysFreeString(*old);
Francis Beaudetf1779ed1998-11-25 17:20:36 +000095
96 /*
97 * Allocate the new string
98 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000099 *old = SysAllocString(in);
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000100
101 return 1;
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000102}
103
Matthew Beckerb05264f1998-10-11 14:21:42 +0000104/******************************************************************************
105 * SysAllocStringLen16 [OLE2DISP.4]
Alexandre Julliardded30381995-07-06 17:18:27 +0000106 */
Francois Gougetdfc0f5e1999-03-13 18:13:10 +0000107BSTR16 WINAPI SysAllocStringLen16(const char *in, int len)
Alexandre Julliardded30381995-07-06 17:18:27 +0000108{
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000109 BSTR16 out=BSTR_AllocBytes(len+1);
Andreas Mohrdeebddf1999-10-25 15:41:24 +0000110
111 if (!out)
112 return 0;
113
114 /*
115 * Copy the information in the buffer.
116 * Since it is valid to pass a NULL pointer here, we'll initialize the
117 * buffer to nul if it is the case.
118 */
119 if (in != 0)
Alexandre Julliardded30381995-07-06 17:18:27 +0000120 strcpy(BSTR_GetAddr(out),in);
Andreas Mohrdeebddf1999-10-25 15:41:24 +0000121 else
122 memset(BSTR_GetAddr(out), 0, len+1);
123
Alexandre Julliardded30381995-07-06 17:18:27 +0000124 return out;
125}
126
Matthew Beckerb05264f1998-10-11 14:21:42 +0000127/******************************************************************************
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000128 * SysAllocStringLen32 [OLEAUT32.4]
129 *
130 * In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation
131 * section, he describes the DWORD value placed before the BSTR data type.
132 * he describes it as a "DWORD count of characters". By experimenting with
133 * a windows application, this count seems to be a DWORD count of bytes in
134 * the string. Meaning that the count is double the number of wide
135 * characters in the string.
136 */
Francois Gougetdfc0f5e1999-03-13 18:13:10 +0000137BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len)
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000138{
139 DWORD bufferSize;
140 DWORD* newBuffer;
141 WCHAR* stringBuffer;
142
143 /*
144 * Find the lenth of the buffer passed-in in bytes.
145 */
146 bufferSize = len * sizeof (WCHAR);
147
148 /*
149 * Allocate a new buffer to hold the string.
150 * dont't forget to keep an empty spot at the begining of the
151 * buffer for the character count and an extra character at the
152 * end for the NULL.
153 */
154 newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
155 0,
156 bufferSize + sizeof(WCHAR) + sizeof(DWORD));
157
158 /*
159 * If the memory allocation failed, return a null pointer.
160 */
161 if (newBuffer==0)
162 return 0;
163
164 /*
165 * Copy the length of the string in the placeholder.
166 */
167 *newBuffer = bufferSize;
168
169 /*
170 * Skip the byte count.
171 */
172 newBuffer++;
173
174 /*
175 * Copy the information in the buffer.
176 * Since it is valid to pass a NULL pointer here, we'll initialize the
177 * buffer to nul if it is the case.
178 */
179 if (in != 0)
180 memcpy(newBuffer, in, bufferSize);
181 else
182 memset(newBuffer, 0, bufferSize);
183
184 /*
185 * Make sure that there is a nul character at the end of the
186 * string.
187 */
188 stringBuffer = (WCHAR*)newBuffer;
189 stringBuffer[len] = L'\0';
190
191 return (LPWSTR)stringBuffer;
192}
193
194/******************************************************************************
Matthew Beckerb05264f1998-10-11 14:21:42 +0000195 * SysReAllocStringLen16 [OLE2DISP.5]
Alexandre Julliardded30381995-07-06 17:18:27 +0000196 */
Francois Gougetdfc0f5e1999-03-13 18:13:10 +0000197int WINAPI SysReAllocStringLen16(BSTR16 *old,const char *in,int len)
Alexandre Julliardded30381995-07-06 17:18:27 +0000198{
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000199 BSTR16 new=SysAllocStringLen16(in,len);
Alexandre Julliardded30381995-07-06 17:18:27 +0000200 BSTR_Free(*old);
201 *old=new;
202 return 1;
203}
204
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000205
206/******************************************************************************
207 * SysReAllocStringLen32 [OLEAUT32.5]
208 */
Francois Gougetdfc0f5e1999-03-13 18:13:10 +0000209int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000210{
211 /*
212 * Sanity check
213 */
214 if (old==NULL)
215 return 0;
216
217 /*
218 * Make sure we free the old string.
219 */
220 if (*old!=NULL)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000221 SysFreeString(*old);
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000222
223 /*
224 * Allocate the new string
225 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000226 *old = SysAllocStringLen(in, len);
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000227
228 return 1;
229}
230
Matthew Beckerb05264f1998-10-11 14:21:42 +0000231/******************************************************************************
232 * SysFreeString16 [OLE2DISP.6]
Alexandre Julliardded30381995-07-06 17:18:27 +0000233 */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000234void WINAPI SysFreeString16(BSTR16 in)
Alexandre Julliardded30381995-07-06 17:18:27 +0000235{
236 BSTR_Free(in);
237}
238
Matthew Beckerb05264f1998-10-11 14:21:42 +0000239/******************************************************************************
240 * SysFreeString32 [OLEAUT32.6]
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000241 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000242void WINAPI SysFreeString(BSTR in)
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000243{
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000244 DWORD* bufferPointer;
Rein Klazes3e9608d1999-06-05 11:53:33 +0000245
246 /* NULL is a valid parameter */
247 if(!in) return;
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000248
249 /*
250 * We have to be careful when we free a BSTR pointer, it points to
251 * the beginning of the string but it skips the byte count contained
252 * before the string.
253 */
254 bufferPointer = (DWORD*)in;
255
256 bufferPointer--;
257
258 /*
259 * Free the memory from it's "real" origin.
260 */
261 HeapFree(GetProcessHeap(), 0, bufferPointer);
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000262}
263
Matthew Beckerb05264f1998-10-11 14:21:42 +0000264/******************************************************************************
265 * SysStringLen16 [OLE2DISP.7]
Alexandre Julliardded30381995-07-06 17:18:27 +0000266 */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000267int WINAPI SysStringLen16(BSTR16 str)
Alexandre Julliardded30381995-07-06 17:18:27 +0000268{
269 return strlen(BSTR_GetAddr(str));
270}
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000271
Matthew Becker75175341998-10-18 14:39:06 +0000272/******************************************************************************
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000273 * SysStringLen32 [OLEAUT32.7]
274 *
275 * The Windows documentation states that the length returned by this function
276 * is not necessarely the same as the length returned by the _lstrlenW method.
277 * It is the same number that was passed in as the "len" parameter if the
278 * string was allocated with a SysAllocStringLen method call.
279 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000280int WINAPI SysStringLen(BSTR str)
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000281{
282 DWORD* bufferPointer;
283
Eric Pouechbe5e3c61999-12-12 21:27:41 +0000284 if (!str) return 0;
Francis Beaudetf1779ed1998-11-25 17:20:36 +0000285 /*
286 * The length of the string (in bytes) is contained in a DWORD placed
287 * just before the BSTR pointer
288 */
289 bufferPointer = (DWORD*)str;
290
291 bufferPointer--;
292
293 return (int)(*bufferPointer/sizeof(WCHAR));
294}
295
296/******************************************************************************
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000297 * SysStringByteLen [OLEAUT32.149]
298 *
299 * The Windows documentation states that the length returned by this function
300 * is not necessarely the same as the length returned by the _lstrlenW method.
301 * It is the same number that was passed in as the "len" parameter if the
302 * string was allocated with a SysAllocStringLen method call.
303 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000304int WINAPI SysStringByteLen(BSTR str)
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000305{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000306 return SysStringLen(str)*sizeof(WCHAR);
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000307}
308
309/******************************************************************************
Matthew Becker75175341998-10-18 14:39:06 +0000310 * CreateDispTypeInfo [OLE2DISP.31]
311 */
Andreas Mohrfaa05bd1999-03-28 13:13:03 +0000312HRESULT WINAPI CreateDispTypeInfo16(
Alexandre Julliard829fe321998-07-26 14:27:39 +0000313 INTERFACEDATA *pidata,
314 LCID lcid,
Paul Quinnea1640f1999-03-10 18:03:53 +0000315 ITypeInfo **pptinfo
Alexandre Julliard829fe321998-07-26 14:27:39 +0000316) {
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000317 FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000318 return 0;
319}
320
Matthew Becker75175341998-10-18 14:39:06 +0000321/******************************************************************************
322 * RegisterActiveObject [OLE2DISP.35]
323 */
Andreas Mohrfaa05bd1999-03-28 13:13:03 +0000324HRESULT WINAPI RegisterActiveObject16(
Paul Quinnea1640f1999-03-10 18:03:53 +0000325 IUnknown *punk, REFCLSID rclsid, DWORD dwFlags, unsigned long *pdwRegister
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000326) {
Alexandre Julliard681c75b2000-01-18 05:09:49 +0000327 FIXME("(%p,%s,0x%08lx,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister);
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000328 return 0;
329}
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000330
331/******************************************************************************
332 * OleTranslateColor [OLEAUT32.421]
Thuy Nguyenad7e9c41999-05-08 09:37:59 +0000333 *
334 * Converts an OLE_COLOR to a COLORREF.
335 * See the documentation for conversion rules.
336 * pColorRef can be NULL. In that case the user only wants to test the
337 * conversion.
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000338 */
Eric Pouech853043b2000-02-18 19:06:00 +0000339HRESULT WINAPI OleTranslateColor(
340 OLE_COLOR clr,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000341 HPALETTE hpal,
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000342 COLORREF* pColorRef)
343{
Thuy Nguyenad7e9c41999-05-08 09:37:59 +0000344 COLORREF colorref;
345 BYTE b = HIBYTE(HIWORD(clr));
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000346
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000347 TRACE("(%08lx, %d, %p):stub\n", clr, hpal, pColorRef);
Thuy Nguyenad7e9c41999-05-08 09:37:59 +0000348
349 /*
350 * In case pColorRef is NULL, provide our own to simplify the code.
351 */
352 if (pColorRef == NULL)
353 pColorRef = &colorref;
354
355 switch (b)
356 {
357 case 0x00:
358 {
359 if (hpal != 0)
360 *pColorRef = PALETTERGB(GetRValue(clr),
361 GetGValue(clr),
362 GetBValue(clr));
363 else
364 *pColorRef = clr;
365
366 break;
367 }
368
369 case 0x01:
370 {
371 if (hpal != 0)
372 {
373 PALETTEENTRY pe;
374 /*
375 * Validate the palette index.
376 */
377 if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
378 return E_INVALIDARG;
379 }
380
381 *pColorRef = clr;
382
383 break;
384 }
385
386 case 0x02:
387 *pColorRef = clr;
388 break;
389
390 case 0x80:
391 {
392 int index = LOBYTE(LOWORD(clr));
393
394 /*
395 * Validate GetSysColor index.
396 */
397 if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION))
398 return E_INVALIDARG;
399
400 *pColorRef = GetSysColor(index);
401
402 break;
403 }
404
405 default:
406 return E_INVALIDARG;
407 }
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000408
409 return S_OK;
410}
411
Stephane Lussier986de4b1999-03-12 17:02:32 +0000412/******************************************************************************
413 * SysAllocStringByteLen [OLEAUT32.150]
414 *
415 */
416BSTR WINAPI SysAllocStringByteLen(char *in, int len)
417{
418 DWORD* newBuffer;
419 char* stringBuffer;
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000420
Stephane Lussier986de4b1999-03-12 17:02:32 +0000421 /*
422 * Allocate a new buffer to hold the string.
423 * dont't forget to keep an empty spot at the begining of the
424 * buffer for the character count and an extra character at the
425 * end for the NULL.
426 */
427 newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
428 0,
429 len + sizeof(WCHAR) + sizeof(DWORD));
430
431 /*
432 * If the memory allocation failed, return a null pointer.
433 */
434 if (newBuffer==0)
435 return 0;
436
437 /*
438 * Copy the length of the string in the placeholder.
439 */
440 *newBuffer = len;
441
442 /*
443 * Skip the byte count.
444 */
445 newBuffer++;
446
447 /*
448 * Copy the information in the buffer.
449 * Since it is valid to pass a NULL pointer here, we'll initialize the
450 * buffer to nul if it is the case.
451 */
452 if (in != 0)
453 memcpy(newBuffer, in, len);
454
455 /*
456 * Make sure that there is a nul character at the end of the
457 * string.
458 */
459 stringBuffer = (char *)newBuffer;
460 stringBuffer[len] = 0;
461 stringBuffer[len+1] = 0;
462
463 return (LPWSTR)stringBuffer;
464}
Francis Beaudeteb5a29b1999-02-20 16:48:53 +0000465
466