Add VarParseNumFromStr()/VarNumFromParseNum(), use them for
[wine/multimedia.git] / dlls / oleaut32 / oleaut.c
blobf0d79f2fe7d769a15f34ae6251080a93fec0836f
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 <stdarg.h>
22 #include <string.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winerror.h"
30 #include "ole2.h"
31 #include "olectl.h"
32 #include "oleauto.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 /* IDispatch marshaler */
44 extern const GUID CLSID_PSDispatch;
46 static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
48 /******************************************************************************
49 * BSTR {OLEAUT32}
51 * NOTES
52 * BSTR is a simple typedef for a wide-character string used as the principle
53 * string type in ole automation. When encapsulated in a Variant type they are
54 * automatically copied and destroyed as the variant is processed.
56 * The low level BSTR Api allows manipulation of these strings and is used by
57 * higher level Api calls to manage the strings transparently to the caller.
59 * Internally the BSTR type is allocated with space for a DWORD byte count before
60 * the string data begins. This is undocumented and non-system code should not
61 * access the count directly. Use SysStringLen() or SysStringByteLen()
62 * instead. Note that the byte count does not include the terminating NUL.
64 * To create a new BSTR, use SysAllocString(), SysAllocStringLen() or
65 * SysAllocStringByteLen(). To change the size of an existing BSTR, use SysReAllocString()
66 * or SysReAllocStringLen(). Finally to destroy a string use SysFreeString().
68 * BSTR's are cached by Ole Automation by default. To override this behaviour
69 * either set the environment variable 'OANOCACHE', or call SetOaNoCache().
71 * SEE ALSO
72 * 'Inside OLE, second edition' by Kraig Brockshmidt.
75 /******************************************************************************
76 * SysStringLen [OLEAUT32.7]
78 * Get the allocated length of a BSTR in wide characters.
80 * PARAMS
81 * str [I] BSTR to find the length of
83 * RETURNS
84 * The allocated length of str, or 0 if str is NULL.
86 * NOTES
87 * See BSTR.
88 * The returned length may be different from the length of the string as
89 * calculated by lstrlenW(), since it returns the length that was used to
90 * allocate the string by SysAllocStringLen().
92 int WINAPI SysStringLen(BSTR str)
94 DWORD* bufferPointer;
96 if (!str) return 0;
98 * The length of the string (in bytes) is contained in a DWORD placed
99 * just before the BSTR pointer
101 bufferPointer = (DWORD*)str;
103 bufferPointer--;
105 return (int)(*bufferPointer/sizeof(WCHAR));
108 /******************************************************************************
109 * SysStringByteLen [OLEAUT32.149]
111 * Get the allocated length of a BSTR in bytes.
113 * PARAMS
114 * str [I] BSTR to find the length of
116 * RETURNS
117 * The allocated length of str, or 0 if str is NULL.
119 * NOTES
120 * See SysStringLen(), BSTR().
122 int WINAPI SysStringByteLen(BSTR str)
124 DWORD* bufferPointer;
126 if (!str) return 0;
128 * The length of the string (in bytes) is contained in a DWORD placed
129 * just before the BSTR pointer
131 bufferPointer = (DWORD*)str;
133 bufferPointer--;
135 return (int)(*bufferPointer);
138 /******************************************************************************
139 * SysAllocString [OLEAUT32.2]
141 * Create a BSTR from an OLESTR.
143 * PARAMS
144 * str [I] Source to create BSTR from
146 * RETURNS
147 * Success: A BSTR allocated with SysAllocStringLen().
148 * Failure: NULL, if oleStr is NULL.
150 * NOTES
151 * See BSTR.
152 * MSDN (October 2001) incorrectly states that NULL is returned if oleStr has
153 * a length of 0. Native Win32 and this implementation both return a valid
154 * empty BSTR in this case.
156 BSTR WINAPI SysAllocString(LPCOLESTR str)
158 if (!str) return 0;
160 /* Delegate this to the SysAllocStringLen32 method. */
161 return SysAllocStringLen(str, lstrlenW(str));
164 /******************************************************************************
165 * SysFreeString [OLEAUT32.6]
167 * Free a BSTR.
169 * PARAMS
170 * str [I] BSTR to free.
172 * RETURNS
173 * Nothing.
175 * NOTES
176 * See BSTR.
177 * str may be NULL, in which case this function does nothing.
179 void WINAPI SysFreeString(BSTR str)
181 DWORD* bufferPointer;
183 /* NULL is a valid parameter */
184 if(!str) return;
187 * We have to be careful when we free a BSTR pointer, it points to
188 * the beginning of the string but it skips the byte count contained
189 * before the string.
191 bufferPointer = (DWORD*)str;
193 bufferPointer--;
196 * Free the memory from its "real" origin.
198 HeapFree(GetProcessHeap(), 0, bufferPointer);
201 /******************************************************************************
202 * SysAllocStringLen [OLEAUT32.4]
204 * Create a BSTR from an OLESTR of a given wide character length.
206 * PARAMS
207 * str [I] Source to create BSTR from
208 * len [I] Length of oleStr in wide characters
210 * RETURNS
211 * Success: A newly allocated BSTR from SysAllocStringByteLen()
212 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
214 * NOTES
215 * See BSTR(), SysAllocStringByteLen().
217 BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
219 DWORD bufferSize;
220 DWORD* newBuffer;
221 WCHAR* stringBuffer;
224 * Find the length of the buffer passed-in in bytes.
226 bufferSize = len * sizeof (WCHAR);
229 * Allocate a new buffer to hold the string.
230 * dont't forget to keep an empty spot at the beginning of the
231 * buffer for the character count and an extra character at the
232 * end for the NULL.
234 newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
236 bufferSize + sizeof(WCHAR) + sizeof(DWORD));
239 * If the memory allocation failed, return a null pointer.
241 if (newBuffer==0)
242 return 0;
245 * Copy the length of the string in the placeholder.
247 *newBuffer = bufferSize;
250 * Skip the byte count.
252 newBuffer++;
255 * Copy the information in the buffer.
256 * Since it is valid to pass a NULL pointer here, we'll initialize the
257 * buffer to nul if it is the case.
259 if (str != 0)
260 memcpy(newBuffer, str, bufferSize);
261 else
262 memset(newBuffer, 0, bufferSize);
265 * Make sure that there is a nul character at the end of the
266 * string.
268 stringBuffer = (WCHAR*)newBuffer;
269 stringBuffer[len] = L'\0';
271 return (LPWSTR)stringBuffer;
274 /******************************************************************************
275 * SysReAllocStringLen [OLEAUT32.5]
277 * Change the length of a previously created BSTR.
279 * PARAMS
280 * old [O] BSTR to change the length of
281 * str [I] New source for pbstr
282 * len [I] Length of oleStr in wide characters
284 * RETURNS
285 * Success: 1. The size of pbstr is updated.
286 * Failure: 0, if len >= 0x80000000 or memory allocation fails.
288 * NOTES
289 * See BSTR(), SysAllocStringByteLen().
290 * *pbstr may be changed by this function.
292 int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
295 * Sanity check
297 if (old==NULL)
298 return 0;
300 if (*old!=NULL) {
301 DWORD newbytelen = len*sizeof(WCHAR);
302 DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD));
303 *old = (BSTR)(ptr+1);
304 *ptr = newbytelen;
305 if (str) {
306 memcpy(*old, str, newbytelen);
307 (*old)[len] = 0;
308 } else {
309 /* Subtle hidden feature: The old string data is still there
310 * when 'in' is NULL!
311 * Some Microsoft program needs it.
314 } else {
316 * Allocate the new string
318 *old = SysAllocStringLen(str, len);
321 return 1;
324 /******************************************************************************
325 * SysAllocStringByteLen [OLEAUT32.150]
327 * Create a BSTR from an OLESTR of a given byte length.
329 * PARAMS
330 * str [I] Source to create BSTR from
331 * len [I] Length of oleStr in bytes
333 * RETURNS
334 * Success: A newly allocated BSTR
335 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
337 * NOTES
338 * -If len is 0 or oleStr is NULL the resulting string is empty ("").
339 * -This function always NUL terminates the resulting BSTR.
340 * -oleStr may be either an LPCSTR or LPCOLESTR, since it is copied
341 * without checking for a terminating NUL.
342 * See BSTR.
344 BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
346 DWORD* newBuffer;
347 char* stringBuffer;
350 * Allocate a new buffer to hold the string.
351 * dont't forget to keep an empty spot at the beginning of the
352 * buffer for the character count and an extra character at the
353 * end for the NULL.
355 newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
357 len + sizeof(WCHAR) + sizeof(DWORD));
360 * If the memory allocation failed, return a null pointer.
362 if (newBuffer==0)
363 return 0;
366 * Copy the length of the string in the placeholder.
368 *newBuffer = len;
371 * Skip the byte count.
373 newBuffer++;
376 * Copy the information in the buffer.
377 * Since it is valid to pass a NULL pointer here, we'll initialize the
378 * buffer to nul if it is the case.
380 if (str != 0)
381 memcpy(newBuffer, str, len);
384 * Make sure that there is a nul character at the end of the
385 * string.
387 stringBuffer = (char *)newBuffer;
388 stringBuffer[len] = 0;
389 stringBuffer[len+1] = 0;
391 return (LPWSTR)stringBuffer;
394 /******************************************************************************
395 * SysReAllocString [OLEAUT32.3]
397 * Change the length of a previously created BSTR.
399 * PARAMS
400 * old [I/O] BSTR to change the length of
401 * str [I] New source for pbstr
403 * RETURNS
404 * Success: 1
405 * Failure: 0.
407 * NOTES
408 * See BSTR(), SysAllocStringStringLen().
410 INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR str)
413 * Sanity check
415 if (old==NULL)
416 return 0;
419 * Make sure we free the old string.
421 if (*old!=NULL)
422 SysFreeString(*old);
425 * Allocate the new string
427 *old = SysAllocString(str);
429 return 1;
432 /******************************************************************************
433 * SetOaNoCache (OLEAUT32.327)
435 * Instruct Ole Automation not to cache BSTR allocations.
437 * PARAMS
438 * None.
440 * RETURNS
441 * Nothing.
443 * NOTES
444 * See BSTR.
446 void WINAPI SetOaNoCache(void)
448 BSTR_bCache = FALSE;
451 static WCHAR _delimiter[2] = {'!',0}; /* default delimiter apparently */
452 static WCHAR *pdelimiter = &_delimiter[0];
454 /***********************************************************************
455 * RegisterActiveObject (OLEAUT32.33)
457 HRESULT WINAPI RegisterActiveObject(
458 LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister
460 WCHAR guidbuf[80];
461 HRESULT ret;
462 LPRUNNINGOBJECTTABLE runobtable;
463 LPMONIKER moniker;
465 StringFromGUID2(rcid,guidbuf,39);
466 ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
467 if (FAILED(ret))
468 return ret;
469 ret = GetRunningObjectTable(0,&runobtable);
470 if (FAILED(ret)) {
471 IMoniker_Release(moniker);
472 return ret;
474 ret = IRunningObjectTable_Register(runobtable,dwFlags,punk,moniker,pdwRegister);
475 IRunningObjectTable_Release(runobtable);
476 IMoniker_Release(moniker);
477 return ret;
480 /***********************************************************************
481 * RevokeActiveObject (OLEAUT32.34)
483 HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
485 LPRUNNINGOBJECTTABLE runobtable;
486 HRESULT ret;
488 ret = GetRunningObjectTable(0,&runobtable);
489 if (FAILED(ret)) return ret;
490 ret = IRunningObjectTable_Revoke(runobtable,xregister);
491 if (SUCCEEDED(ret)) ret = S_OK;
492 IRunningObjectTable_Release(runobtable);
493 return ret;
496 /***********************************************************************
497 * GetActiveObject (OLEAUT32.35)
499 HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk)
501 WCHAR guidbuf[80];
502 HRESULT ret;
503 LPRUNNINGOBJECTTABLE runobtable;
504 LPMONIKER moniker;
506 StringFromGUID2(rcid,guidbuf,39);
507 ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker);
508 if (FAILED(ret))
509 return ret;
510 ret = GetRunningObjectTable(0,&runobtable);
511 if (FAILED(ret)) {
512 IMoniker_Release(moniker);
513 return ret;
515 ret = IRunningObjectTable_GetObject(runobtable,moniker,ppunk);
516 IRunningObjectTable_Release(runobtable);
517 IMoniker_Release(moniker);
518 return ret;
522 /***********************************************************************
523 * OaBuildVersion [OLEAUT32.170]
525 * known OLEAUT32.DLL versions:
526 * OLE 2.1 NT 1993-95 10 3023
527 * OLE 2.1 10 3027
528 * Win32s 1.1e 20 4049
529 * OLE 2.20 W95/NT 1993-96 20 4112
530 * OLE 2.20 W95/NT 1993-96 20 4118
531 * OLE 2.20 W95/NT 1993-96 20 4122
532 * OLE 2.30 W95/NT 1993-98 30 4265
533 * OLE 2.40 NT?? 1993-98 40 4267
534 * OLE 2.40 W98 SE orig. file 1993-98 40 4275
535 * OLE 2.40 W2K orig. file 1993-XX 40 4514
537 * I just decided to use version 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
538 * and 2.40 for all newer OSs. The build number is maximum, i.e. 0xffff.
540 UINT WINAPI OaBuildVersion()
542 switch(GetVersion() & 0x8000ffff) /* mask off build number */
544 case 0x80000a03: /* WIN31 */
545 return MAKELONG(0xffff, 20);
546 case 0x00003303: /* NT351 */
547 return MAKELONG(0xffff, 30);
548 case 0x80000004: /* WIN95; I'd like to use the "standard" w95 minor
549 version here (30), but as we still use w95
550 as default winver (which is good IMHO), I better
551 play safe and use the latest value for w95 for now.
552 Change this as soon as default winver gets changed
553 to something more recent */
554 case 0x80000a04: /* WIN98 */
555 case 0x00000004: /* NT40 */
556 case 0x00000005: /* W2K */
557 return MAKELONG(0xffff, 40);
558 default:
559 ERR("Version value not known yet. Please investigate it !\n");
560 return 0x0;
564 /******************************************************************************
565 * OleTranslateColor [OLEAUT32.421]
567 * Converts an OLE_COLOR to a COLORREF.
568 * See the documentation for conversion rules.
569 * pColorRef can be NULL. In that case the user only wants to test the
570 * conversion.
572 HRESULT WINAPI OleTranslateColor(
573 OLE_COLOR clr,
574 HPALETTE hpal,
575 COLORREF* pColorRef)
577 COLORREF colorref;
578 BYTE b = HIBYTE(HIWORD(clr));
580 TRACE("(%08lx, %p, %p):stub\n", clr, hpal, pColorRef);
583 * In case pColorRef is NULL, provide our own to simplify the code.
585 if (pColorRef == NULL)
586 pColorRef = &colorref;
588 switch (b)
590 case 0x00:
592 if (hpal != 0)
593 *pColorRef = PALETTERGB(GetRValue(clr),
594 GetGValue(clr),
595 GetBValue(clr));
596 else
597 *pColorRef = clr;
599 break;
602 case 0x01:
604 if (hpal != 0)
606 PALETTEENTRY pe;
608 * Validate the palette index.
610 if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
611 return E_INVALIDARG;
614 *pColorRef = clr;
616 break;
619 case 0x02:
620 *pColorRef = clr;
621 break;
623 case 0x80:
625 int index = LOBYTE(LOWORD(clr));
628 * Validate GetSysColor index.
630 if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION))
631 return E_INVALIDARG;
633 *pColorRef = GetSysColor(index);
635 break;
638 default:
639 return E_INVALIDARG;
642 return S_OK;
645 extern HRESULT OLEAUTPS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
647 extern void _get_STDFONT_CF(LPVOID);
648 extern void _get_STDPIC_CF(LPVOID);
650 /***********************************************************************
651 * DllGetClassObject (OLEAUT32.1)
653 HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
655 *ppv = NULL;
656 if (IsEqualGUID(rclsid,&CLSID_StdFont)) {
657 if (IsEqualGUID(iid,&IID_IClassFactory)) {
658 _get_STDFONT_CF(ppv);
659 IClassFactory_AddRef((IClassFactory*)*ppv);
660 return S_OK;
663 if (IsEqualGUID(rclsid,&CLSID_StdPicture)) {
664 if (IsEqualGUID(iid,&IID_IClassFactory)) {
665 _get_STDPIC_CF(ppv);
666 IClassFactory_AddRef((IClassFactory*)*ppv);
667 return S_OK;
670 if (IsEqualGUID(rclsid,&CLSID_PSDispatch)) {
671 return OLEAUTPS_DllGetClassObject(rclsid,iid,ppv);
673 if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
674 if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv))
675 return S_OK;
676 /*FALLTHROUGH*/
678 FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
679 return CLASS_E_CLASSNOTAVAILABLE;
682 /***********************************************************************
683 * DllCanUnloadNow (OLEAUT32.410)
685 HRESULT WINAPI OLEAUT32_DllCanUnloadNow() {
686 FIXME("(), stub!\n");
687 return S_FALSE;