Implemented Rtl*ByteSwap() functions, based on a patch by Jon
[wine/multimedia.git] / dlls / oleaut32 / oleaut.c
blob52c58405996b2c5712e48c10861b9f6da3bd05dc
1 /*
2 * OLEAUT32
4 * Copyright 1999, 2000 Marcus Meissner
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.
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.
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
21 #include <string.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winerror.h"
29 #include "ole2.h"
30 #include "olectl.h"
31 #include "oleauto.h"
32 #include "wine/obj_olefont.h"
34 #include "tmarshal.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ole);
40 /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
41 extern const GUID CLSID_PSOAInterface;
43 /******************************************************************************
44 * SysStringLen [OLEAUT32.7]
46 * The Windows documentation states that the length returned by this function
47 * is not necessarely the same as the length returned by the _lstrlenW method.
48 * It is the same number that was passed in as the "len" parameter if the
49 * string was allocated with a SysAllocStringLen method call.
51 int WINAPI SysStringLen(BSTR str)
53 DWORD* bufferPointer;
55 if (!str) return 0;
57 * The length of the string (in bytes) is contained in a DWORD placed
58 * just before the BSTR pointer
60 bufferPointer = (DWORD*)str;
62 bufferPointer--;
64 return (int)(*bufferPointer/sizeof(WCHAR));
67 /******************************************************************************
68 * SysStringByteLen [OLEAUT32.149]
70 * The Windows documentation states that the length returned by this function
71 * is not necessarely the same as the length returned by the _lstrlenW method.
72 * It is the same number that was passed in as the "len" parameter if the
73 * string was allocated with a SysAllocStringLen method call.
75 int WINAPI SysStringByteLen(BSTR str)
77 DWORD* bufferPointer;
79 if (!str) return 0;
81 * The length of the string (in bytes) is contained in a DWORD placed
82 * just before the BSTR pointer
84 bufferPointer = (DWORD*)str;
86 bufferPointer--;
88 return (int)(*bufferPointer);
91 /******************************************************************************
92 * SysAllocString [OLEAUT32.2]
94 * MSDN (October 2001) states that this returns a NULL value if the argument
95 * is a zero-length string. This does not appear to be true; certainly it
96 * returns a value under Win98 (Oleaut32.dll Ver 2.40.4515.0)
98 BSTR WINAPI SysAllocString(LPCOLESTR in)
100 if (!in) return 0;
102 /* Delegate this to the SysAllocStringLen32 method. */
103 return SysAllocStringLen(in, lstrlenW(in));
106 /******************************************************************************
107 * SysFreeString [OLEAUT32.6]
109 void WINAPI SysFreeString(BSTR in)
111 DWORD* bufferPointer;
113 /* NULL is a valid parameter */
114 if(!in) return;
117 * We have to be careful when we free a BSTR pointer, it points to
118 * the beginning of the string but it skips the byte count contained
119 * before the string.
121 bufferPointer = (DWORD*)in;
123 bufferPointer--;
126 * Free the memory from its "real" origin.
128 HeapFree(GetProcessHeap(), 0, bufferPointer);
131 /******************************************************************************
132 * SysAllocStringLen [OLEAUT32.4]
134 * In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation
135 * section, he describes the DWORD value placed *before* the BSTR data type.
136 * he describes it as a "DWORD count of characters". By experimenting with
137 * a windows application, this count seems to be a DWORD count of bytes in
138 * the string. Meaning that the count is double the number of wide
139 * characters in the string.
141 BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len)
143 DWORD bufferSize;
144 DWORD* newBuffer;
145 WCHAR* stringBuffer;
148 * Find the length of the buffer passed-in in bytes.
150 bufferSize = len * sizeof (WCHAR);
153 * Allocate a new buffer to hold the string.
154 * dont't forget to keep an empty spot at the beginning of the
155 * buffer for the character count and an extra character at the
156 * end for the NULL.
158 newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
160 bufferSize + sizeof(WCHAR) + sizeof(DWORD));
163 * If the memory allocation failed, return a null pointer.
165 if (newBuffer==0)
166 return 0;
169 * Copy the length of the string in the placeholder.
171 *newBuffer = bufferSize;
174 * Skip the byte count.
176 newBuffer++;
179 * Copy the information in the buffer.
180 * Since it is valid to pass a NULL pointer here, we'll initialize the
181 * buffer to nul if it is the case.
183 if (in != 0)
184 memcpy(newBuffer, in, bufferSize);
185 else
186 memset(newBuffer, 0, bufferSize);
189 * Make sure that there is a nul character at the end of the
190 * string.
192 stringBuffer = (WCHAR*)newBuffer;
193 stringBuffer[len] = L'\0';
195 return (LPWSTR)stringBuffer;
198 /******************************************************************************
199 * SysReAllocStringLen [OLEAUT32.5]
201 int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
204 * Sanity check
206 if (old==NULL)
207 return 0;
209 if (*old!=NULL) {
210 DWORD newbytelen = len*sizeof(WCHAR);
211 DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD));
212 *old = (BSTR)(ptr+1);
213 *ptr = newbytelen;
214 if (in) {
215 memcpy(*old, in, newbytelen);
216 (*old)[len] = 0;
217 } else {
218 /* Subtle hidden feature: The old string data is still there
219 * when 'in' is NULL!
220 * Some Microsoft program needs it.
223 } else {
225 * Allocate the new string
227 *old = SysAllocStringLen(in, len);
230 return 1;
233 /******************************************************************************
234 * SysAllocStringByteLen [OLEAUT32.150]
237 BSTR WINAPI SysAllocStringByteLen(LPCSTR in, UINT len)
239 DWORD* newBuffer;
240 char* stringBuffer;
243 * Allocate a new buffer to hold the string.
244 * dont't forget to keep an empty spot at the beginning of the
245 * buffer for the character count and an extra character at the
246 * end for the NULL.
248 newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
250 len + sizeof(WCHAR) + sizeof(DWORD));
253 * If the memory allocation failed, return a null pointer.
255 if (newBuffer==0)
256 return 0;
259 * Copy the length of the string in the placeholder.
261 *newBuffer = len;
264 * Skip the byte count.
266 newBuffer++;
269 * Copy the information in the buffer.
270 * Since it is valid to pass a NULL pointer here, we'll initialize the
271 * buffer to nul if it is the case.
273 if (in != 0)
274 memcpy(newBuffer, in, len);
277 * Make sure that there is a nul character at the end of the
278 * string.
280 stringBuffer = (char *)newBuffer;
281 stringBuffer[len] = 0;
282 stringBuffer[len+1] = 0;
284 return (LPWSTR)stringBuffer;
287 /******************************************************************************
288 * SysReAllocString [OLEAUT32.3]
290 INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in)
293 * Sanity check
295 if (old==NULL)
296 return 0;
299 * Make sure we free the old string.
301 if (*old!=NULL)
302 SysFreeString(*old);
305 * Allocate the new string
307 *old = SysAllocString(in);
309 return 1;
312 static WCHAR _delimiter[2] = {'!',0}; /* default delimiter apparently */
313 static WCHAR *pdelimiter = &_delimiter[0];
315 /***********************************************************************
316 * RegisterActiveObject (OLEAUT32.33)
318 HRESULT WINAPI RegisterActiveObject(
319 LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister
321 WCHAR guidbuf[80];
322 HRESULT ret;
323 LPRUNNINGOBJECTTABLE runobtable;
324 LPMONIKER moniker;
326 StringFromGUID2(rcid,guidbuf,39);
327 ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
328 if (FAILED(ret))
329 return ret;
330 ret = GetRunningObjectTable(0,&runobtable);
331 if (FAILED(ret)) {
332 IMoniker_Release(moniker);
333 return ret;
335 ret = IRunningObjectTable_Register(runobtable,dwFlags,punk,moniker,pdwRegister);
336 IRunningObjectTable_Release(runobtable);
337 IMoniker_Release(moniker);
338 return ret;
341 /***********************************************************************
342 * RevokeActiveObject (OLEAUT32.34)
344 HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
346 LPRUNNINGOBJECTTABLE runobtable;
347 HRESULT ret;
349 ret = GetRunningObjectTable(0,&runobtable);
350 if (FAILED(ret)) return ret;
351 ret = IRunningObjectTable_Revoke(runobtable,xregister);
352 if (SUCCEEDED(ret)) ret = S_OK;
353 IRunningObjectTable_Release(runobtable);
354 return ret;
357 /***********************************************************************
358 * GetActiveObject (OLEAUT32.35)
360 HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk)
362 WCHAR guidbuf[80];
363 HRESULT ret;
364 LPRUNNINGOBJECTTABLE runobtable;
365 LPMONIKER moniker;
367 StringFromGUID2(rcid,guidbuf,39);
368 ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
369 if (FAILED(ret))
370 return ret;
371 ret = GetRunningObjectTable(0,&runobtable);
372 if (FAILED(ret)) {
373 IMoniker_Release(moniker);
374 return ret;
376 ret = IRunningObjectTable_GetObject(runobtable,moniker,ppunk);
377 IRunningObjectTable_Release(runobtable);
378 IMoniker_Release(moniker);
379 return ret;
383 /***********************************************************************
384 * OaBuildVersion [OLEAUT32.170]
386 * known OLEAUT32.DLL versions:
387 * OLE 2.1 NT 1993-95 10 3023
388 * OLE 2.1 10 3027
389 * Win32s 1.1e 20 4049
390 * OLE 2.20 W95/NT 1993-96 20 4112
391 * OLE 2.20 W95/NT 1993-96 20 4118
392 * OLE 2.20 W95/NT 1993-96 20 4122
393 * OLE 2.30 W95/NT 1993-98 30 4265
394 * OLE 2.40 NT?? 1993-98 40 4267
395 * OLE 2.40 W98 SE orig. file 1993-98 40 4275
396 * OLE 2.40 W2K orig. file 1993-XX 40 4514
398 * I just decided to use version 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
399 * and 2.40 for all newer OSs. The build number is maximum, i.e. 0xffff.
401 UINT WINAPI OaBuildVersion()
403 switch(GetVersion() & 0x8000ffff) /* mask off build number */
405 case 0x80000a03: /* WIN31 */
406 return MAKELONG(0xffff, 20);
407 case 0x00003303: /* NT351 */
408 return MAKELONG(0xffff, 30);
409 case 0x80000004: /* WIN95; I'd like to use the "standard" w95 minor
410 version here (30), but as we still use w95
411 as default winver (which is good IMHO), I better
412 play safe and use the latest value for w95 for now.
413 Change this as soon as default winver gets changed
414 to something more recent */
415 case 0x80000a04: /* WIN98 */
416 case 0x00000004: /* NT40 */
417 case 0x00000005: /* W2K */
418 return MAKELONG(0xffff, 40);
419 default:
420 ERR("Version value not known yet. Please investigate it !\n");
421 return 0x0;
425 /******************************************************************************
426 * OleTranslateColor [OLEAUT32.421]
428 * Converts an OLE_COLOR to a COLORREF.
429 * See the documentation for conversion rules.
430 * pColorRef can be NULL. In that case the user only wants to test the
431 * conversion.
433 HRESULT WINAPI OleTranslateColor(
434 OLE_COLOR clr,
435 HPALETTE hpal,
436 COLORREF* pColorRef)
438 COLORREF colorref;
439 BYTE b = HIBYTE(HIWORD(clr));
441 TRACE("(%08lx, %p, %p):stub\n", clr, hpal, pColorRef);
444 * In case pColorRef is NULL, provide our own to simplify the code.
446 if (pColorRef == NULL)
447 pColorRef = &colorref;
449 switch (b)
451 case 0x00:
453 if (hpal != 0)
454 *pColorRef = PALETTERGB(GetRValue(clr),
455 GetGValue(clr),
456 GetBValue(clr));
457 else
458 *pColorRef = clr;
460 break;
463 case 0x01:
465 if (hpal != 0)
467 PALETTEENTRY pe;
469 * Validate the palette index.
471 if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
472 return E_INVALIDARG;
475 *pColorRef = clr;
477 break;
480 case 0x02:
481 *pColorRef = clr;
482 break;
484 case 0x80:
486 int index = LOBYTE(LOWORD(clr));
489 * Validate GetSysColor index.
491 if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION))
492 return E_INVALIDARG;
494 *pColorRef = GetSysColor(index);
496 break;
499 default:
500 return E_INVALIDARG;
503 return S_OK;
506 /***********************************************************************
507 * DllRegisterServer (OLEAUT32.320)
509 HRESULT WINAPI OLEAUT32_DllRegisterServer() {
510 FIXME("stub!\n");
511 return S_OK;
514 /***********************************************************************
515 * DllUnregisterServer (OLEAUT32.321)
517 HRESULT WINAPI OLEAUT32_DllUnregisterServer() {
518 FIXME("stub!\n");
519 return S_OK;
522 extern void _get_STDFONT_CF(LPVOID);
523 extern void _get_STDPIC_CF(LPVOID);
525 /***********************************************************************
526 * DllGetClassObject (OLEAUT32.1)
528 HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
530 *ppv = NULL;
531 if (IsEqualGUID(rclsid,&CLSID_StdFont)) {
532 if (IsEqualGUID(iid,&IID_IClassFactory)) {
533 _get_STDFONT_CF(ppv);
534 IClassFactory_AddRef((IClassFactory*)*ppv);
535 return S_OK;
538 if (IsEqualGUID(rclsid,&CLSID_StdPicture)) {
539 if (IsEqualGUID(iid,&IID_IClassFactory)) {
540 _get_STDPIC_CF(ppv);
541 IClassFactory_AddRef((IClassFactory*)*ppv);
542 return S_OK;
545 if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
546 if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv))
547 return S_OK;
548 /*FALLTHROUGH*/
550 FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
551 return CLASS_E_CLASSNOTAVAILABLE;
554 /***********************************************************************
555 * DllCanUnloadNow (OLEAUT32.410)
557 HRESULT WINAPI OLEAUT32_DllCanUnloadNow() {
558 FIXME("(), stub!\n");
559 return S_FALSE;