Implemented DuplicateIcon().
[wine/gsoc_dplay.git] / dlls / oleaut32 / ole2disp.c
blob66917faaa7ac67f28855fb3b8929145a4be0ba8f
1 /*
2 * OLE2DISP library
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 "olectl.h"
12 #include "oleauto.h"
13 #include "heap.h"
14 #include "ldt.h"
15 #include "debugtools.h"
17 DEFAULT_DEBUG_CHANNEL(ole);
19 /* 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 */
23 /******************************************************************************
24 * BSTR_AllocBytes [Internal]
26 static BSTR16 BSTR_AllocBytes(int n)
28 void *ptr = SEGPTR_ALLOC(n);
29 return (BSTR16)SEGPTR_GET(ptr);
32 /******************************************************************************
33 * BSTR_Free [INTERNAL]
35 static void BSTR_Free(BSTR16 in)
37 SEGPTR_FREE( PTR_SEG_TO_LIN(in) );
40 /******************************************************************************
41 * BSTR_GetAddr [INTERNAL]
43 static void* BSTR_GetAddr(BSTR16 in)
45 return in ? PTR_SEG_TO_LIN(in) : 0;
48 /******************************************************************************
49 * SysAllocString16 [OLE2DISP.2]
51 BSTR16 WINAPI SysAllocString16(LPCOLESTR16 in)
53 BSTR16 out;
55 if (!in) return 0;
57 out = BSTR_AllocBytes(strlen(in)+1);
58 if(!out)return 0;
59 strcpy(BSTR_GetAddr(out),in);
60 return out;
63 /******************************************************************************
64 * SysAllocString [OLEAUT32.2]
66 BSTR WINAPI SysAllocString(LPCOLESTR in)
68 if (!in) return 0;
70 /* Delegate this to the SysAllocStringLen32 method. */
71 return SysAllocStringLen(in, lstrlenW(in));
74 /******************************************************************************
75 * SysReAllocString16 [OLE2DISP.3]
77 INT16 WINAPI SysReAllocString16(LPBSTR16 old,LPCOLESTR16 in)
79 BSTR16 new=SysAllocString16(in);
80 BSTR_Free(*old);
81 *old=new;
82 return 1;
85 /******************************************************************************
86 * SysReAllocString [OLEAUT32.3]
88 INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in)
91 * Sanity check
93 if (old==NULL)
94 return 0;
97 * Make sure we free the old string.
99 if (*old!=NULL)
100 SysFreeString(*old);
103 * Allocate the new string
105 *old = SysAllocString(in);
107 return 1;
110 /******************************************************************************
111 * SysAllocStringLen16 [OLE2DISP.4]
113 BSTR16 WINAPI SysAllocStringLen16(const char *in, int len)
115 BSTR16 out=BSTR_AllocBytes(len+1);
117 if (!out)
118 return 0;
121 * Copy the information in the buffer.
122 * Since it is valid to pass a NULL pointer here, we'll initialize the
123 * buffer to nul if it is the case.
125 if (in != 0)
126 strcpy(BSTR_GetAddr(out),in);
127 else
128 memset(BSTR_GetAddr(out), 0, len+1);
130 return out;
133 /******************************************************************************
134 * SysAllocStringLen [OLEAUT32.4]
136 * In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation
137 * section, he describes the DWORD value placed before the BSTR data type.
138 * he describes it as a "DWORD count of characters". By experimenting with
139 * a windows application, this count seems to be a DWORD count of bytes in
140 * the string. Meaning that the count is double the number of wide
141 * characters in the string.
143 BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len)
145 DWORD bufferSize;
146 DWORD* newBuffer;
147 WCHAR* stringBuffer;
150 * Find the lenth of the buffer passed-in in bytes.
152 bufferSize = len * sizeof (WCHAR);
155 * Allocate a new buffer to hold the string.
156 * dont't forget to keep an empty spot at the begining of the
157 * buffer for the character count and an extra character at the
158 * end for the NULL.
160 newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
162 bufferSize + sizeof(WCHAR) + sizeof(DWORD));
165 * If the memory allocation failed, return a null pointer.
167 if (newBuffer==0)
168 return 0;
171 * Copy the length of the string in the placeholder.
173 *newBuffer = bufferSize;
176 * Skip the byte count.
178 newBuffer++;
181 * Copy the information in the buffer.
182 * Since it is valid to pass a NULL pointer here, we'll initialize the
183 * buffer to nul if it is the case.
185 if (in != 0)
186 memcpy(newBuffer, in, bufferSize);
187 else
188 memset(newBuffer, 0, bufferSize);
191 * Make sure that there is a nul character at the end of the
192 * string.
194 stringBuffer = (WCHAR*)newBuffer;
195 stringBuffer[len] = L'\0';
197 return (LPWSTR)stringBuffer;
200 /******************************************************************************
201 * SysReAllocStringLen16 [OLE2DISP.5]
203 int WINAPI SysReAllocStringLen16(BSTR16 *old,const char *in,int len)
205 BSTR16 new=SysAllocStringLen16(in,len);
206 BSTR_Free(*old);
207 *old=new;
208 return 1;
212 /******************************************************************************
213 * SysReAllocStringLen [OLEAUT32.5]
215 int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
218 * Sanity check
220 if (old==NULL)
221 return 0;
224 * Make sure we free the old string.
226 if (*old!=NULL)
227 SysFreeString(*old);
230 * Allocate the new string
232 *old = SysAllocStringLen(in, len);
234 return 1;
237 /******************************************************************************
238 * SysFreeString16 [OLE2DISP.6]
240 void WINAPI SysFreeString16(BSTR16 in)
242 BSTR_Free(in);
245 /******************************************************************************
246 * SysFreeString [OLEAUT32.6]
248 void WINAPI SysFreeString(BSTR in)
250 DWORD* bufferPointer;
252 /* NULL is a valid parameter */
253 if(!in) return;
256 * We have to be careful when we free a BSTR pointer, it points to
257 * the beginning of the string but it skips the byte count contained
258 * before the string.
260 bufferPointer = (DWORD*)in;
262 bufferPointer--;
265 * Free the memory from it's "real" origin.
267 HeapFree(GetProcessHeap(), 0, bufferPointer);
270 /******************************************************************************
271 * SysStringLen16 [OLE2DISP.7]
273 int WINAPI SysStringLen16(BSTR16 str)
275 return strlen(BSTR_GetAddr(str));
278 /******************************************************************************
279 * SysStringLen [OLEAUT32.7]
281 * The Windows documentation states that the length returned by this function
282 * is not necessarely the same as the length returned by the _lstrlenW method.
283 * It is the same number that was passed in as the "len" parameter if the
284 * string was allocated with a SysAllocStringLen method call.
286 int WINAPI SysStringLen(BSTR str)
288 DWORD* bufferPointer;
290 if (!str) return 0;
292 * The length of the string (in bytes) is contained in a DWORD placed
293 * just before the BSTR pointer
295 bufferPointer = (DWORD*)str;
297 bufferPointer--;
299 return (int)(*bufferPointer/sizeof(WCHAR));
302 /******************************************************************************
303 * SysStringByteLen [OLEAUT32.149]
305 * The Windows documentation states that the length returned by this function
306 * is not necessarely the same as the length returned by the _lstrlenW method.
307 * It is the same number that was passed in as the "len" parameter if the
308 * string was allocated with a SysAllocStringLen method call.
310 int WINAPI SysStringByteLen(BSTR str)
312 DWORD* bufferPointer;
314 if (!str) return 0;
316 * The length of the string (in bytes) is contained in a DWORD placed
317 * just before the BSTR pointer
319 bufferPointer = (DWORD*)str;
321 bufferPointer--;
323 return (int)(*bufferPointer);
326 /******************************************************************************
327 * CreateDispTypeInfo [OLE2DISP.31]
329 HRESULT WINAPI CreateDispTypeInfo16(
330 INTERFACEDATA *pidata,
331 LCID lcid,
332 ITypeInfo **pptinfo
334 FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
335 return 0;
338 /******************************************************************************
339 * RegisterActiveObject [OLE2DISP.35]
341 HRESULT WINAPI RegisterActiveObject16(
342 IUnknown *punk, REFCLSID rclsid, DWORD dwFlags, unsigned long *pdwRegister
344 FIXME("(%p,%s,0x%08lx,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister);
345 return 0;
348 /******************************************************************************
349 * OleTranslateColor [OLEAUT32.421]
351 * Converts an OLE_COLOR to a COLORREF.
352 * See the documentation for conversion rules.
353 * pColorRef can be NULL. In that case the user only wants to test the
354 * conversion.
356 HRESULT WINAPI OleTranslateColor(
357 OLE_COLOR clr,
358 HPALETTE hpal,
359 COLORREF* pColorRef)
361 COLORREF colorref;
362 BYTE b = HIBYTE(HIWORD(clr));
364 TRACE("(%08lx, %d, %p):stub\n", clr, hpal, pColorRef);
367 * In case pColorRef is NULL, provide our own to simplify the code.
369 if (pColorRef == NULL)
370 pColorRef = &colorref;
372 switch (b)
374 case 0x00:
376 if (hpal != 0)
377 *pColorRef = PALETTERGB(GetRValue(clr),
378 GetGValue(clr),
379 GetBValue(clr));
380 else
381 *pColorRef = clr;
383 break;
386 case 0x01:
388 if (hpal != 0)
390 PALETTEENTRY pe;
392 * Validate the palette index.
394 if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
395 return E_INVALIDARG;
398 *pColorRef = clr;
400 break;
403 case 0x02:
404 *pColorRef = clr;
405 break;
407 case 0x80:
409 int index = LOBYTE(LOWORD(clr));
412 * Validate GetSysColor index.
414 if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION))
415 return E_INVALIDARG;
417 *pColorRef = GetSysColor(index);
419 break;
422 default:
423 return E_INVALIDARG;
426 return S_OK;
429 /******************************************************************************
430 * SysAllocStringByteLen [OLEAUT32.150]
433 BSTR WINAPI SysAllocStringByteLen(char *in, int len)
435 DWORD* newBuffer;
436 char* stringBuffer;
439 * Allocate a new buffer to hold the string.
440 * dont't forget to keep an empty spot at the begining of the
441 * buffer for the character count and an extra character at the
442 * end for the NULL.
444 newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
446 len + sizeof(WCHAR) + sizeof(DWORD));
449 * If the memory allocation failed, return a null pointer.
451 if (newBuffer==0)
452 return 0;
455 * Copy the length of the string in the placeholder.
457 *newBuffer = len;
460 * Skip the byte count.
462 newBuffer++;
465 * Copy the information in the buffer.
466 * Since it is valid to pass a NULL pointer here, we'll initialize the
467 * buffer to nul if it is the case.
469 if (in != 0)
470 memcpy(newBuffer, in, len);
473 * Make sure that there is a nul character at the end of the
474 * string.
476 stringBuffer = (char *)newBuffer;
477 stringBuffer[len] = 0;
478 stringBuffer[len+1] = 0;
480 return (LPWSTR)stringBuffer;