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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
41 #include "oleaut32_oaidl.h"
43 #include "wine/debug.h"
44 #include "wine/unicode.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
47 WINE_DECLARE_DEBUG_CHANNEL(heap
);
49 /******************************************************************************
53 * BSTR is a simple typedef for a wide-character string used as the principle
54 * string type in ole automation. When encapsulated in a Variant type they are
55 * automatically copied and destroyed as the variant is processed.
57 * The low level BSTR API allows manipulation of these strings and is used by
58 * higher level API calls to manage the strings transparently to the caller.
60 * Internally the BSTR type is allocated with space for a DWORD byte count before
61 * the string data begins. This is undocumented and non-system code should not
62 * access the count directly. Use SysStringLen() or SysStringByteLen()
63 * instead. Note that the byte count does not include the terminating NUL.
65 * To create a new BSTR, use SysAllocString(), SysAllocStringLen() or
66 * SysAllocStringByteLen(). To change the size of an existing BSTR, use SysReAllocString()
67 * or SysReAllocStringLen(). Finally to destroy a string use SysFreeString().
69 * BSTR's are cached by Ole Automation by default. To override this behaviour
70 * either set the environment variable 'OANOCACHE', or call SetOaNoCache().
73 * 'Inside OLE, second edition' by Kraig Brockshmidt.
76 static BOOL bstr_cache_enabled
;
78 static CRITICAL_SECTION cs_bstr_cache
;
79 static CRITICAL_SECTION_DEBUG cs_bstr_cache_dbg
=
82 { &cs_bstr_cache_dbg
.ProcessLocksList
, &cs_bstr_cache_dbg
.ProcessLocksList
},
83 0, 0, { (DWORD_PTR
)(__FILE__
": bstr_cache") }
85 static CRITICAL_SECTION cs_bstr_cache
= { &cs_bstr_cache_dbg
, -1, 0, 0, 0, 0 };
99 #define BUCKET_SIZE 16
100 #define BUCKET_BUFFER_SIZE 6
105 bstr_t
*buf
[BUCKET_BUFFER_SIZE
];
106 } bstr_cache_entry_t
;
108 #define ARENA_INUSE_FILLER 0x55
109 #define ARENA_TAIL_FILLER 0xab
110 #define ARENA_FREE_FILLER 0xfeeefeee
112 static bstr_cache_entry_t bstr_cache
[0x10000/BUCKET_SIZE
];
114 static inline size_t bstr_alloc_size(size_t size
)
116 return (FIELD_OFFSET(bstr_t
, u
.ptr
[size
]) + sizeof(WCHAR
) + BUCKET_SIZE
-1) & ~(BUCKET_SIZE
-1);
119 static inline bstr_t
*bstr_from_str(BSTR str
)
121 return CONTAINING_RECORD((void *)str
, bstr_t
, u
.str
);
124 static inline bstr_cache_entry_t
*get_cache_entry_from_idx(unsigned cache_idx
)
126 return bstr_cache_enabled
&& cache_idx
< ARRAY_SIZE(bstr_cache
) ? bstr_cache
+ cache_idx
: NULL
;
129 static inline bstr_cache_entry_t
*get_cache_entry(size_t size
)
131 unsigned cache_idx
= FIELD_OFFSET(bstr_t
, u
.ptr
[size
+sizeof(WCHAR
)-1])/BUCKET_SIZE
;
132 return get_cache_entry_from_idx(cache_idx
);
135 static inline bstr_cache_entry_t
*get_cache_entry_from_alloc_size(SIZE_T alloc_size
)
138 if (alloc_size
< BUCKET_SIZE
) return NULL
;
139 cache_idx
= (alloc_size
- BUCKET_SIZE
) / BUCKET_SIZE
;
140 return get_cache_entry_from_idx(cache_idx
);
143 static bstr_t
*alloc_bstr(size_t size
)
145 bstr_cache_entry_t
*cache_entry
= get_cache_entry(size
);
149 EnterCriticalSection(&cs_bstr_cache
);
151 if(!cache_entry
->cnt
) {
152 cache_entry
= get_cache_entry(size
+BUCKET_SIZE
);
153 if(cache_entry
&& !cache_entry
->cnt
)
158 ret
= cache_entry
->buf
[cache_entry
->head
++];
159 cache_entry
->head
%= BUCKET_BUFFER_SIZE
;
163 LeaveCriticalSection(&cs_bstr_cache
);
167 size_t fill_size
= (FIELD_OFFSET(bstr_t
, u
.ptr
[size
])+2*sizeof(WCHAR
)-1) & ~(sizeof(WCHAR
)-1);
168 memset(ret
, ARENA_INUSE_FILLER
, fill_size
);
169 memset((char *)ret
+fill_size
, ARENA_TAIL_FILLER
, bstr_alloc_size(size
)-fill_size
);
176 ret
= CoTaskMemAlloc(bstr_alloc_size(size
));
182 /******************************************************************************
183 * SysStringLen [OLEAUT32.7]
185 * Get the allocated length of a BSTR in wide characters.
188 * str [I] BSTR to find the length of
191 * The allocated length of str, or 0 if str is NULL.
195 * The returned length may be different from the length of the string as
196 * calculated by lstrlenW(), since it returns the length that was used to
197 * allocate the string by SysAllocStringLen().
199 UINT WINAPI
SysStringLen(BSTR str
)
201 return str
? bstr_from_str(str
)->size
/sizeof(WCHAR
) : 0;
204 /******************************************************************************
205 * SysStringByteLen [OLEAUT32.149]
207 * Get the allocated length of a BSTR in bytes.
210 * str [I] BSTR to find the length of
213 * The allocated length of str, or 0 if str is NULL.
216 * See SysStringLen(), BSTR().
218 UINT WINAPI
SysStringByteLen(BSTR str
)
220 return str
? bstr_from_str(str
)->size
: 0;
223 /******************************************************************************
224 * SysAllocString [OLEAUT32.2]
226 * Create a BSTR from an OLESTR.
229 * str [I] Source to create BSTR from
232 * Success: A BSTR allocated with SysAllocStringLen().
233 * Failure: NULL, if oleStr is NULL.
237 * MSDN (October 2001) incorrectly states that NULL is returned if oleStr has
238 * a length of 0. Native Win32 and this implementation both return a valid
239 * empty BSTR in this case.
241 BSTR WINAPI
SysAllocString(LPCOLESTR str
)
245 /* Delegate this to the SysAllocStringLen32 method. */
246 return SysAllocStringLen(str
, lstrlenW(str
));
249 static inline IMalloc
*get_malloc(void)
251 static IMalloc
*malloc
;
254 CoGetMalloc(1, &malloc
);
259 /******************************************************************************
260 * SysFreeString [OLEAUT32.6]
265 * str [I] BSTR to free.
272 * str may be NULL, in which case this function does nothing.
274 void WINAPI DECLSPEC_HOTPATCH
SysFreeString(BSTR str
)
276 bstr_cache_entry_t
*cache_entry
;
278 IMalloc
*malloc
= get_malloc();
284 bstr
= bstr_from_str(str
);
286 alloc_size
= IMalloc_GetSize(malloc
, bstr
);
287 if (alloc_size
== ~0UL)
290 cache_entry
= get_cache_entry_from_alloc_size(alloc_size
);
294 EnterCriticalSection(&cs_bstr_cache
);
296 /* According to tests, freeing a string that's already in cache doesn't corrupt anything.
297 * For that to work we need to search the cache. */
298 for(i
=0; i
< cache_entry
->cnt
; i
++) {
299 if(cache_entry
->buf
[(cache_entry
->head
+i
) % BUCKET_BUFFER_SIZE
] == bstr
) {
300 WARN_(heap
)("String already is in cache!\n");
301 LeaveCriticalSection(&cs_bstr_cache
);
306 if(cache_entry
->cnt
< ARRAY_SIZE(cache_entry
->buf
)) {
307 cache_entry
->buf
[(cache_entry
->head
+cache_entry
->cnt
) % BUCKET_BUFFER_SIZE
] = bstr
;
311 unsigned n
= (alloc_size
-FIELD_OFFSET(bstr_t
, u
.ptr
))/sizeof(DWORD
);
313 bstr
->u
.dwptr
[i
] = ARENA_FREE_FILLER
;
316 LeaveCriticalSection(&cs_bstr_cache
);
320 LeaveCriticalSection(&cs_bstr_cache
);
326 /******************************************************************************
327 * SysAllocStringLen [OLEAUT32.4]
329 * Create a BSTR from an OLESTR of a given wide character length.
332 * str [I] Source to create BSTR from
333 * len [I] Length of oleStr in wide characters
336 * Success: A newly allocated BSTR from SysAllocStringByteLen()
337 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
340 * See BSTR(), SysAllocStringByteLen().
342 BSTR WINAPI
SysAllocStringLen(const OLECHAR
*str
, unsigned int len
)
347 /* Detect integer overflow. */
348 if (len
>= ((UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
))/sizeof(WCHAR
)))
351 TRACE("%s\n", debugstr_wn(str
, len
));
353 size
= len
*sizeof(WCHAR
);
354 bstr
= alloc_bstr(size
);
359 memcpy(bstr
->u
.str
, str
, size
);
360 bstr
->u
.str
[len
] = 0;
362 memset(bstr
->u
.str
, 0, size
+sizeof(WCHAR
));
368 /******************************************************************************
369 * SysReAllocStringLen [OLEAUT32.5]
371 * Change the length of a previously created BSTR.
374 * old [O] BSTR to change the length of
375 * str [I] New source for pbstr
376 * len [I] Length of oleStr in wide characters
379 * Success: 1. The size of pbstr is updated.
380 * Failure: 0, if len >= 0x80000000 or memory allocation fails.
383 * See BSTR(), SysAllocStringByteLen().
384 * *old may be changed by this function.
386 int WINAPI
SysReAllocStringLen(BSTR
* old
, const OLECHAR
* str
, unsigned int len
)
388 /* Detect integer overflow. */
389 if (len
>= ((UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
))/sizeof(WCHAR
)))
393 DWORD newbytelen
= len
*sizeof(WCHAR
);
394 bstr_t
*old_bstr
= bstr_from_str(*old
);
395 bstr_t
*bstr
= CoTaskMemRealloc(old_bstr
, bstr_alloc_size(newbytelen
));
397 if (!bstr
) return FALSE
;
400 bstr
->size
= newbytelen
;
401 /* The old string data is still there when str is NULL */
402 if (str
&& old_bstr
->u
.str
!= str
) memmove(bstr
->u
.str
, str
, newbytelen
);
403 bstr
->u
.str
[len
] = 0;
405 *old
= SysAllocStringLen(str
, len
);
411 /******************************************************************************
412 * SysAllocStringByteLen [OLEAUT32.150]
414 * Create a BSTR from an OLESTR of a given byte length.
417 * str [I] Source to create BSTR from
418 * len [I] Length of oleStr in bytes
421 * Success: A newly allocated BSTR
422 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
425 * -If len is 0 or oleStr is NULL the resulting string is empty ("").
426 * -This function always NUL terminates the resulting BSTR.
427 * -oleStr may be either an LPCSTR or LPCOLESTR, since it is copied
428 * without checking for a terminating NUL.
431 BSTR WINAPI DECLSPEC_HOTPATCH
SysAllocStringByteLen(LPCSTR str
, UINT len
)
435 /* Detect integer overflow. */
436 if (len
>= (UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
)))
439 bstr
= alloc_bstr(len
);
444 memcpy(bstr
->u
.ptr
, str
, len
);
445 bstr
->u
.ptr
[len
] = 0;
447 memset(bstr
->u
.ptr
, 0, len
+1);
449 bstr
->u
.str
[(len
+sizeof(WCHAR
)-1)/sizeof(WCHAR
)] = 0;
454 /******************************************************************************
455 * SysReAllocString [OLEAUT32.3]
457 * Change the length of a previously created BSTR.
460 * old [I/O] BSTR to change the length of
461 * str [I] New source for pbstr
468 * See BSTR(), SysAllocStringStringLen().
470 INT WINAPI
SysReAllocString(LPBSTR old
,LPCOLESTR str
)
479 * Make sure we free the old string.
484 * Allocate the new string
486 *old
= SysAllocString(str
);
491 /******************************************************************************
492 * SetOaNoCache (OLEAUT32.327)
494 * Instruct Ole Automation not to cache BSTR allocations.
503 * SetOaNoCache does not release cached strings, so it leaks by design.
505 void WINAPI
SetOaNoCache(void)
508 bstr_cache_enabled
= FALSE
;
511 static const WCHAR _delimiter
[] = {'!',0}; /* default delimiter apparently */
512 static const WCHAR
*pdelimiter
= &_delimiter
[0];
514 /***********************************************************************
515 * RegisterActiveObject (OLEAUT32.33)
517 * Registers an object in the global item table.
520 * punk [I] Object to register.
521 * rcid [I] CLSID of the object.
523 * pdwRegister [O] Address to store cookie of object registration in.
527 * Failure: HRESULT code.
529 HRESULT WINAPI DECLSPEC_HOTPATCH
RegisterActiveObject(
530 LPUNKNOWN punk
,REFCLSID rcid
,DWORD dwFlags
,LPDWORD pdwRegister
534 LPRUNNINGOBJECTTABLE runobtable
;
536 DWORD rot_flags
= ROTFLAGS_REGISTRATIONKEEPSALIVE
; /* default registration is strong */
538 StringFromGUID2(rcid
,guidbuf
,39);
539 ret
= CreateItemMoniker(pdelimiter
,guidbuf
,&moniker
);
542 ret
= GetRunningObjectTable(0,&runobtable
);
544 IMoniker_Release(moniker
);
547 if(dwFlags
== ACTIVEOBJECT_WEAK
)
549 ret
= IRunningObjectTable_Register(runobtable
,rot_flags
,punk
,moniker
,pdwRegister
);
550 IRunningObjectTable_Release(runobtable
);
551 IMoniker_Release(moniker
);
555 /***********************************************************************
556 * RevokeActiveObject (OLEAUT32.34)
558 * Revokes an object from the global item table.
561 * xregister [I] Registration cookie.
562 * reserved [I] Reserved. Set to NULL.
566 * Failure: HRESULT code.
568 HRESULT WINAPI DECLSPEC_HOTPATCH
RevokeActiveObject(DWORD xregister
,LPVOID reserved
)
570 LPRUNNINGOBJECTTABLE runobtable
;
573 ret
= GetRunningObjectTable(0,&runobtable
);
574 if (FAILED(ret
)) return ret
;
575 ret
= IRunningObjectTable_Revoke(runobtable
,xregister
);
576 if (SUCCEEDED(ret
)) ret
= S_OK
;
577 IRunningObjectTable_Release(runobtable
);
581 /***********************************************************************
582 * GetActiveObject (OLEAUT32.35)
584 * Gets an object from the global item table.
587 * rcid [I] CLSID of the object.
588 * preserved [I] Reserved. Set to NULL.
589 * ppunk [O] Address to store object into.
593 * Failure: HRESULT code.
595 HRESULT WINAPI DECLSPEC_HOTPATCH
GetActiveObject(REFCLSID rcid
,LPVOID preserved
,LPUNKNOWN
*ppunk
)
599 LPRUNNINGOBJECTTABLE runobtable
;
602 StringFromGUID2(rcid
,guidbuf
,39);
603 ret
= CreateItemMoniker(pdelimiter
,guidbuf
,&moniker
);
606 ret
= GetRunningObjectTable(0,&runobtable
);
608 IMoniker_Release(moniker
);
611 ret
= IRunningObjectTable_GetObject(runobtable
,moniker
,ppunk
);
612 IRunningObjectTable_Release(runobtable
);
613 IMoniker_Release(moniker
);
618 /***********************************************************************
619 * OaBuildVersion [OLEAUT32.170]
621 * Get the Ole Automation build version.
630 * Known oleaut32.dll versions:
631 *| OLE Ver. Comments Date Build Ver.
632 *| -------- ------------------------- ---- ---------
633 *| OLE 2.1 NT 1993-95 10 3023
635 *| Win32s Ver 1.1e 20 4049
636 *| OLE 2.20 W95/NT 1993-96 20 4112
637 *| OLE 2.20 W95/NT 1993-96 20 4118
638 *| OLE 2.20 W95/NT 1993-96 20 4122
639 *| OLE 2.30 W95/NT 1993-98 30 4265
640 *| OLE 2.40 NT?? 1993-98 40 4267
641 *| OLE 2.40 W98 SE orig. file 1993-98 40 4275
642 *| OLE 2.40 W2K orig. file 1993-XX 40 4514
644 * Currently the versions returned are 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
645 * and 2.40 for all later versions. The build number is maximum, i.e. 0xffff.
647 ULONG WINAPI
OaBuildVersion(void)
649 switch(GetVersion() & 0x8000ffff) /* mask off build number */
651 case 0x80000a03: /* WIN31 */
652 return MAKELONG(0xffff, 20);
653 case 0x00003303: /* NT351 */
654 return MAKELONG(0xffff, 30);
655 case 0x80000004: /* WIN95; I'd like to use the "standard" w95 minor
656 version here (30), but as we still use w95
657 as default winver (which is good IMHO), I better
658 play safe and use the latest value for w95 for now.
659 Change this as soon as default winver gets changed
660 to something more recent */
661 case 0x80000a04: /* WIN98 */
662 case 0x00000004: /* NT40 */
663 case 0x00000005: /* W2K */
664 return MAKELONG(0xffff, 40);
665 case 0x00000105: /* WinXP */
666 case 0x00000006: /* Vista */
667 case 0x00000106: /* Win7 */
668 return MAKELONG(0xffff, 50);
670 FIXME("Version value not known yet. Please investigate it !\n");
671 return MAKELONG(0xffff, 40); /* for now return the same value as for w2k */
675 /******************************************************************************
676 * OleTranslateColor [OLEAUT32.421]
678 * Convert an OLE_COLOR to a COLORREF.
681 * clr [I] Color to convert
682 * hpal [I] Handle to a palette for the conversion
683 * pColorRef [O] Destination for converted color, or NULL to test if the conversion is ok
686 * Success: S_OK. The conversion is ok, and pColorRef contains the converted color if non-NULL.
687 * Failure: E_INVALIDARG, if any argument is invalid.
690 * Document the conversion rules.
692 HRESULT WINAPI
OleTranslateColor(
698 BYTE b
= HIBYTE(HIWORD(clr
));
700 TRACE("(%08x, %p, %p)\n", clr
, hpal
, pColorRef
);
703 * In case pColorRef is NULL, provide our own to simplify the code.
705 if (pColorRef
== NULL
)
706 pColorRef
= &colorref
;
713 *pColorRef
= PALETTERGB(GetRValue(clr
),
728 * Validate the palette index.
730 if (GetPaletteEntries(hpal
, LOWORD(clr
), 1, &pe
) == 0)
745 int index
= LOBYTE(LOWORD(clr
));
748 * Validate GetSysColor index.
750 if ((index
< COLOR_SCROLLBAR
) || (index
> COLOR_MENUBAR
))
753 *pColorRef
= GetSysColor(index
);
765 extern HRESULT WINAPI
OLEAUTPS_DllGetClassObject(REFCLSID
, REFIID
, LPVOID
*) DECLSPEC_HIDDEN
;
766 extern BOOL WINAPI
OLEAUTPS_DllMain(HINSTANCE
, DWORD
, LPVOID
) DECLSPEC_HIDDEN
;
767 extern HRESULT WINAPI
OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN
;
768 extern HRESULT WINAPI
OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
770 extern HRESULT WINAPI
CreateProxyFromTypeInfo(ITypeInfo
*typeinfo
,
771 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **obj
);
772 extern HRESULT WINAPI
CreateStubFromTypeInfo(ITypeInfo
*typeinfo
, REFIID iid
,
773 IUnknown
*server
, IRpcStubBuffer
**stub
);
775 struct ifacepsredirect_data
787 struct tlibredirect_data
801 static BOOL
actctx_get_typelib_module(REFIID iid
, WCHAR
*module
, DWORD len
)
803 struct ifacepsredirect_data
*iface
;
804 struct tlibredirect_data
*tlib
;
805 ACTCTX_SECTION_KEYED_DATA data
;
808 data
.cbSize
= sizeof(data
);
809 if (!FindActCtxSectionGuid(0, NULL
, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION
,
813 iface
= (struct ifacepsredirect_data
*)data
.lpData
;
814 if (!FindActCtxSectionGuid(0, NULL
, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
,
815 &iface
->tlbid
, &data
))
818 tlib
= (struct tlibredirect_data
*)data
.lpData
;
819 ptrW
= (WCHAR
*)((BYTE
*)data
.lpSectionBase
+ tlib
->name_offset
);
821 if (tlib
->name_len
/sizeof(WCHAR
) >= len
)
823 ERR("need larger module buffer, %u\n", tlib
->name_len
);
827 memcpy(module
, ptrW
, tlib
->name_len
);
828 module
[tlib
->name_len
/sizeof(WCHAR
)] = 0;
832 static HRESULT
reg_get_typelib_module(REFIID iid
, WCHAR
*module
, DWORD len
)
834 REGSAM opposite
= (sizeof(void*) == 8) ? KEY_WOW64_32KEY
: KEY_WOW64_64KEY
;
835 char tlguid
[200], typelibkey
[300], interfacekey
[300], ver
[100], tlfn
[260];
836 DWORD tlguidlen
, verlen
, type
;
841 sprintf( interfacekey
, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
842 iid
->Data1
, iid
->Data2
, iid
->Data3
,
843 iid
->Data4
[0], iid
->Data4
[1], iid
->Data4
[2], iid
->Data4
[3],
844 iid
->Data4
[4], iid
->Data4
[5], iid
->Data4
[6], iid
->Data4
[7]
847 err
= RegOpenKeyExA(HKEY_CLASSES_ROOT
,interfacekey
,0,KEY_READ
,&ikey
);
848 if (err
&& (opposite
== KEY_WOW64_32KEY
|| (IsWow64Process(GetCurrentProcess(), &is_wow64
)
850 err
= RegOpenKeyExA(HKEY_CLASSES_ROOT
,interfacekey
,0,KEY_READ
|opposite
,&ikey
);
854 ERR("No %s key found.\n", interfacekey
);
858 tlguidlen
= sizeof(tlguid
);
859 if (RegQueryValueExA(ikey
, NULL
, NULL
, &type
, (BYTE
*)tlguid
, &tlguidlen
))
861 ERR("Getting typelib guid failed.\n");
866 verlen
= sizeof(ver
);
867 if (RegQueryValueExA(ikey
, "Version", NULL
, &type
, (BYTE
*)ver
, &verlen
))
869 ERR("Could not get version value?\n");
876 sprintf(typelibkey
, "Typelib\\%s\\%s\\0\\win%u", tlguid
, ver
, sizeof(void *) == 8 ? 64 : 32);
877 tlfnlen
= sizeof(tlfn
);
878 if (RegQueryValueA(HKEY_CLASSES_ROOT
, typelibkey
, tlfn
, &tlfnlen
))
881 sprintf(typelibkey
, "Typelib\\%s\\%s\\0\\win32", tlguid
, ver
);
882 tlfnlen
= sizeof(tlfn
);
883 if (RegQueryValueA(HKEY_CLASSES_ROOT
, typelibkey
, tlfn
, &tlfnlen
))
886 ERR("Could not get typelib fn?\n");
892 MultiByteToWideChar(CP_ACP
, 0, tlfn
, -1, module
, len
);
896 static HRESULT
get_typeinfo_for_iid(REFIID iid
, ITypeInfo
**typeinfo
)
898 WCHAR module
[MAX_PATH
];
905 if (!actctx_get_typelib_module(iid
, module
, ARRAY_SIZE(module
)))
907 hr
= reg_get_typelib_module(iid
, module
, ARRAY_SIZE(module
));
912 hr
= LoadTypeLib(module
, &typelib
);
914 ERR("Failed to load typelib for %s, but it should be there.\n", debugstr_guid(iid
));
918 hr
= ITypeLib_GetTypeInfoOfGuid(typelib
, iid
, typeinfo
);
919 ITypeLib_Release(typelib
);
921 ERR("typelib does not contain info for %s\n", debugstr_guid(iid
));
926 static HRESULT WINAPI
typelib_ps_QueryInterface(IPSFactoryBuffer
*iface
, REFIID iid
, void **out
)
928 if (IsEqualIID(iid
, &IID_IPSFactoryBuffer
) || IsEqualIID(iid
, &IID_IUnknown
))
934 FIXME("No interface for %s.\n", debugstr_guid(iid
));
936 return E_NOINTERFACE
;
939 static ULONG WINAPI
typelib_ps_AddRef(IPSFactoryBuffer
*iface
)
944 static ULONG WINAPI
typelib_ps_Release(IPSFactoryBuffer
*iface
)
949 static HRESULT WINAPI
typelib_ps_CreateProxy(IPSFactoryBuffer
*iface
,
950 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **out
)
955 hr
= get_typeinfo_for_iid(iid
, &typeinfo
);
956 if (FAILED(hr
)) return hr
;
958 hr
= CreateProxyFromTypeInfo(typeinfo
, outer
, iid
, proxy
, out
);
960 ERR("Failed to create proxy, hr %#x.\n", hr
);
962 ITypeInfo_Release(typeinfo
);
966 static HRESULT WINAPI
typelib_ps_CreateStub(IPSFactoryBuffer
*iface
, REFIID iid
,
967 IUnknown
*server
, IRpcStubBuffer
**stub
)
972 hr
= get_typeinfo_for_iid(iid
, &typeinfo
);
973 if (FAILED(hr
)) return hr
;
975 hr
= CreateStubFromTypeInfo(typeinfo
, iid
, server
, stub
);
977 ERR("Failed to create stub, hr %#x.\n", hr
);
979 ITypeInfo_Release(typeinfo
);
983 static const IPSFactoryBufferVtbl typelib_ps_vtbl
=
985 typelib_ps_QueryInterface
,
988 typelib_ps_CreateProxy
,
989 typelib_ps_CreateStub
,
992 static IPSFactoryBuffer typelib_ps
= { &typelib_ps_vtbl
};
994 extern void _get_STDFONT_CF(LPVOID
*);
995 extern void _get_STDPIC_CF(LPVOID
*);
997 static HRESULT WINAPI
PSDispatchFacBuf_QueryInterface(IPSFactoryBuffer
*iface
, REFIID riid
, void **ppv
)
999 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1000 IsEqualIID(riid
, &IID_IPSFactoryBuffer
))
1002 IPSFactoryBuffer_AddRef(iface
);
1006 return E_NOINTERFACE
;
1009 static ULONG WINAPI
PSDispatchFacBuf_AddRef(IPSFactoryBuffer
*iface
)
1014 static ULONG WINAPI
PSDispatchFacBuf_Release(IPSFactoryBuffer
*iface
)
1019 static HRESULT WINAPI
PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer
*iface
,
1020 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **obj
)
1022 IPSFactoryBuffer
*factory
;
1025 if (IsEqualIID(iid
, &IID_IDispatch
))
1027 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&factory
);
1028 if (FAILED(hr
)) return hr
;
1030 hr
= IPSFactoryBuffer_CreateProxy(factory
, outer
, iid
, proxy
, obj
);
1031 IPSFactoryBuffer_Release(factory
);
1035 return IPSFactoryBuffer_CreateProxy(&typelib_ps
, outer
, iid
, proxy
, obj
);
1038 static HRESULT WINAPI
PSDispatchFacBuf_CreateStub(IPSFactoryBuffer
*iface
,
1039 REFIID iid
, IUnknown
*server
, IRpcStubBuffer
**stub
)
1041 IPSFactoryBuffer
*factory
;
1044 if (IsEqualIID(iid
, &IID_IDispatch
))
1046 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&factory
);
1047 if (FAILED(hr
)) return hr
;
1049 hr
= IPSFactoryBuffer_CreateStub(factory
, iid
, server
, stub
);
1050 IPSFactoryBuffer_Release(factory
);
1054 return IPSFactoryBuffer_CreateStub(&typelib_ps
, iid
, server
, stub
);
1057 static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl
=
1059 PSDispatchFacBuf_QueryInterface
,
1060 PSDispatchFacBuf_AddRef
,
1061 PSDispatchFacBuf_Release
,
1062 PSDispatchFacBuf_CreateProxy
,
1063 PSDispatchFacBuf_CreateStub
1066 /* This is the whole PSFactoryBuffer object, just the vtableptr */
1067 static const IPSFactoryBufferVtbl
*pPSDispatchFacBuf
= &PSDispatchFacBuf_Vtbl
;
1069 /***********************************************************************
1070 * DllGetClassObject (OLEAUT32.@)
1072 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID iid
, LPVOID
*ppv
)
1075 if (IsEqualGUID(rclsid
,&CLSID_StdFont
)) {
1076 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
1077 _get_STDFONT_CF(ppv
);
1078 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1082 if (IsEqualGUID(rclsid
,&CLSID_StdPicture
)) {
1083 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
1084 _get_STDPIC_CF(ppv
);
1085 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1089 if (IsEqualCLSID(rclsid
, &CLSID_PSDispatch
) && IsEqualIID(iid
, &IID_IPSFactoryBuffer
)) {
1090 *ppv
= &pPSDispatchFacBuf
;
1091 IPSFactoryBuffer_AddRef((IPSFactoryBuffer
*)*ppv
);
1095 if (IsEqualGUID(rclsid
, &CLSID_PSOAInterface
))
1096 return IPSFactoryBuffer_QueryInterface(&typelib_ps
, iid
, ppv
);
1098 if (IsEqualCLSID(rclsid
, &CLSID_PSTypeComp
) ||
1099 IsEqualCLSID(rclsid
, &CLSID_PSTypeInfo
) ||
1100 IsEqualCLSID(rclsid
, &CLSID_PSTypeLib
) ||
1101 IsEqualCLSID(rclsid
, &CLSID_PSDispatch
) ||
1102 IsEqualCLSID(rclsid
, &CLSID_PSEnumVariant
))
1103 return OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, iid
, ppv
);
1105 return OLEAUTPS_DllGetClassObject(rclsid
, iid
, ppv
);
1108 /***********************************************************************
1109 * DllCanUnloadNow (OLEAUT32.@)
1111 * Determine if this dll can be unloaded from the callers address space.
1117 * Always returns S_FALSE. This dll cannot be unloaded.
1119 HRESULT WINAPI
DllCanUnloadNow(void)
1124 /*****************************************************************************
1125 * DllMain [OLEAUT32.@]
1127 BOOL WINAPI
DllMain(HINSTANCE hInstDll
, DWORD fdwReason
, LPVOID lpvReserved
)
1129 static const WCHAR oanocacheW
[] = {'o','a','n','o','c','a','c','h','e',0};
1131 if(fdwReason
== DLL_PROCESS_ATTACH
)
1132 bstr_cache_enabled
= !GetEnvironmentVariableW(oanocacheW
, NULL
, 0);
1134 return OLEAUTPS_DllMain( hInstDll
, fdwReason
, lpvReserved
);
1137 /***********************************************************************
1138 * DllRegisterServer (OLEAUT32.@)
1140 HRESULT WINAPI
DllRegisterServer(void)
1142 return OLEAUTPS_DllRegisterServer();
1145 /***********************************************************************
1146 * DllUnregisterServer (OLEAUT32.@)
1148 HRESULT WINAPI
DllUnregisterServer(void)
1150 return OLEAUTPS_DllUnregisterServer();
1153 /***********************************************************************
1154 * OleIconToCursor (OLEAUT32.415)
1156 HCURSOR WINAPI
OleIconToCursor( HINSTANCE hinstExe
, HICON hIcon
)
1158 FIXME("(%p,%p), partially implemented.\n",hinstExe
,hIcon
);
1159 /* FIXME: make an extended conversation from HICON to HCURSOR */
1160 return CopyCursor(hIcon
);
1163 /***********************************************************************
1164 * GetAltMonthNames (OLEAUT32.@)
1166 HRESULT WINAPI
GetAltMonthNames(LCID lcid
, LPOLESTR
**str
)
1168 static const WCHAR ar_month1W
[] = {0x645,0x62d,0x631,0x645,0};
1169 static const WCHAR ar_month2W
[] = {0x635,0x641,0x631,0};
1170 static const WCHAR ar_month3W
[] = {0x631,0x628,0x64a,0x639,' ',0x627,0x644,0x627,0x648,0x644,0};
1171 static const WCHAR ar_month4W
[] = {0x631,0x628,0x64a,0x639,' ',0x627,0x644,0x62b,0x627,0x646,0x64a,0};
1172 static const WCHAR ar_month5W
[] = {0x62c,0x645,0x627,0x62f,0x649,' ',0x627,0x644,0x627,0x648,0x644,0x649,0};
1173 static const WCHAR ar_month6W
[] = {0x62c,0x645,0x627,0x62f,0x649,' ',0x627,0x644,0x62b,0x627,0x646,0x64a,0x629,0};
1174 static const WCHAR ar_month7W
[] = {0x631,0x62c,0x628,0};
1175 static const WCHAR ar_month8W
[] = {0x634,0x639,0x628,0x627,0x646,0};
1176 static const WCHAR ar_month9W
[] = {0x631,0x645,0x636,0x627,0x646,0};
1177 static const WCHAR ar_month10W
[] = {0x634,0x648,0x627,0x643,0};
1178 static const WCHAR ar_month11W
[] = {0x630,0x648,' ',0x627,0x644,0x642,0x639,0x62f,0x629,0};
1179 static const WCHAR ar_month12W
[] = {0x630,0x648,' ',0x627,0x644,0x62d,0x62c,0x629,0};
1181 static const WCHAR
*arabic_hijri
[] =
1198 static const WCHAR pl_month1W
[] = {'s','t','y','c','z','n','i','a',0};
1199 static const WCHAR pl_month2W
[] = {'l','u','t','e','g','o',0};
1200 static const WCHAR pl_month3W
[] = {'m','a','r','c','a',0};
1201 static const WCHAR pl_month4W
[] = {'k','w','i','e','t','n','i','a',0};
1202 static const WCHAR pl_month5W
[] = {'m','a','j','a',0};
1203 static const WCHAR pl_month6W
[] = {'c','z','e','r','w','c','a',0};
1204 static const WCHAR pl_month7W
[] = {'l','i','p','c','a',0};
1205 static const WCHAR pl_month8W
[] = {'s','i','e','r','p','n','i','a',0};
1206 static const WCHAR pl_month9W
[] = {'w','r','z','e',0x15b,'n','i','a',0};
1207 static const WCHAR pl_month10W
[] = {'p','a',0x17a,'d','z','i','e','r','n','i','k','a',0};
1208 static const WCHAR pl_month11W
[] = {'l','i','s','t','o','p','a','d','a',0};
1209 static const WCHAR pl_month12W
[] = {'g','r','u','d','n','i','a',0};
1211 static const WCHAR
*polish_genitive_names
[] =
1228 static const WCHAR ru_month1W
[] = {0x44f,0x43d,0x432,0x430,0x440,0x44f,0};
1229 static const WCHAR ru_month2W
[] = {0x444,0x435,0x432,0x440,0x430,0x43b,0x44f,0};
1230 static const WCHAR ru_month3W
[] = {0x43c,0x430,0x440,0x442,0x430,0};
1231 static const WCHAR ru_month4W
[] = {0x430,0x43f,0x440,0x435,0x43b,0x44f,0};
1232 static const WCHAR ru_month5W
[] = {0x43c,0x430,0x44f,0};
1233 static const WCHAR ru_month6W
[] = {0x438,0x44e,0x43d,0x44f,0};
1234 static const WCHAR ru_month7W
[] = {0x438,0x44e,0x43b,0x44f,0};
1235 static const WCHAR ru_month8W
[] = {0x430,0x432,0x433,0x443,0x441,0x442,0x430,0};
1236 static const WCHAR ru_month9W
[] = {0x441,0x435,0x43d,0x442,0x44f,0x431,0x440,0x44f,0};
1237 static const WCHAR ru_month10W
[] = {0x43e,0x43a,0x442,0x44f,0x431,0x440,0x44f,0};
1238 static const WCHAR ru_month11W
[] = {0x43d,0x43e,0x44f,0x431,0x440,0x44f,0};
1239 static const WCHAR ru_month12W
[] = {0x434,0x435,0x43a,0x430,0x431,0x440,0x44f,0};
1241 static const WCHAR
*russian_genitive_names
[] =
1258 TRACE("%#x, %p\n", lcid
, str
);
1260 if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_ARABIC
)
1261 *str
= (LPOLESTR
*)arabic_hijri
;
1262 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_POLISH
)
1263 *str
= (LPOLESTR
*)polish_genitive_names
;
1264 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_RUSSIAN
)
1265 *str
= (LPOLESTR
*)russian_genitive_names
;