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
39 #include "oleaut32_oaidl.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
44 WINE_DECLARE_DEBUG_CHANNEL(heap
);
46 /******************************************************************************
50 * BSTR is a simple typedef for a wide-character string used as the principle
51 * string type in ole automation. When encapsulated in a Variant type they are
52 * automatically copied and destroyed as the variant is processed.
54 * The low level BSTR API allows manipulation of these strings and is used by
55 * higher level API calls to manage the strings transparently to the caller.
57 * Internally the BSTR type is allocated with space for a DWORD byte count before
58 * the string data begins. This is undocumented and non-system code should not
59 * access the count directly. Use SysStringLen() or SysStringByteLen()
60 * instead. Note that the byte count does not include the terminating NUL.
62 * To create a new BSTR, use SysAllocString(), SysAllocStringLen() or
63 * SysAllocStringByteLen(). To change the size of an existing BSTR, use SysReAllocString()
64 * or SysReAllocStringLen(). Finally to destroy a string use SysFreeString().
66 * BSTR's are cached by Ole Automation by default. To override this behaviour
67 * either set the environment variable 'OANOCACHE', or call SetOaNoCache().
70 * 'Inside OLE, second edition' by Kraig Brockshmidt.
73 static BOOL bstr_cache_enabled
;
75 static CRITICAL_SECTION cs_bstr_cache
;
76 static CRITICAL_SECTION_DEBUG cs_bstr_cache_dbg
=
79 { &cs_bstr_cache_dbg
.ProcessLocksList
, &cs_bstr_cache_dbg
.ProcessLocksList
},
80 0, 0, { (DWORD_PTR
)(__FILE__
": bstr_cache") }
82 static CRITICAL_SECTION cs_bstr_cache
= { &cs_bstr_cache_dbg
, -1, 0, 0, 0, 0 };
96 #define BUCKET_SIZE 16
97 #define BUCKET_BUFFER_SIZE 6
102 bstr_t
*buf
[BUCKET_BUFFER_SIZE
];
103 } bstr_cache_entry_t
;
105 #define ARENA_INUSE_FILLER 0x55
106 #define ARENA_TAIL_FILLER 0xab
107 #define ARENA_FREE_FILLER 0xfeeefeee
109 static bstr_cache_entry_t bstr_cache
[0x10000/BUCKET_SIZE
];
111 static inline size_t bstr_alloc_size(size_t size
)
113 return (FIELD_OFFSET(bstr_t
, u
.ptr
[size
]) + sizeof(WCHAR
) + BUCKET_SIZE
-1) & ~(BUCKET_SIZE
-1);
116 static inline bstr_t
*bstr_from_str(BSTR str
)
118 return CONTAINING_RECORD(str
, bstr_t
, u
.str
);
121 static inline bstr_cache_entry_t
*get_cache_entry_from_idx(unsigned cache_idx
)
123 return bstr_cache_enabled
&& cache_idx
< ARRAY_SIZE(bstr_cache
) ? bstr_cache
+ cache_idx
: NULL
;
126 static inline bstr_cache_entry_t
*get_cache_entry(size_t size
)
128 unsigned cache_idx
= FIELD_OFFSET(bstr_t
, u
.ptr
[size
+sizeof(WCHAR
)-1])/BUCKET_SIZE
;
129 return get_cache_entry_from_idx(cache_idx
);
132 static inline bstr_cache_entry_t
*get_cache_entry_from_alloc_size(SIZE_T alloc_size
)
135 if (alloc_size
< BUCKET_SIZE
) return NULL
;
136 cache_idx
= (alloc_size
- BUCKET_SIZE
) / BUCKET_SIZE
;
137 return get_cache_entry_from_idx(cache_idx
);
140 static bstr_t
*alloc_bstr(size_t size
)
142 bstr_cache_entry_t
*cache_entry
= get_cache_entry(size
);
146 EnterCriticalSection(&cs_bstr_cache
);
148 if(!cache_entry
->cnt
) {
149 cache_entry
= get_cache_entry(size
+BUCKET_SIZE
);
150 if(cache_entry
&& !cache_entry
->cnt
)
155 ret
= cache_entry
->buf
[cache_entry
->head
++];
156 cache_entry
->head
%= BUCKET_BUFFER_SIZE
;
160 LeaveCriticalSection(&cs_bstr_cache
);
164 size_t fill_size
= (FIELD_OFFSET(bstr_t
, u
.ptr
[size
])+2*sizeof(WCHAR
)-1) & ~(sizeof(WCHAR
)-1);
165 memset(ret
, ARENA_INUSE_FILLER
, fill_size
);
166 memset((char *)ret
+fill_size
, ARENA_TAIL_FILLER
, bstr_alloc_size(size
)-fill_size
);
173 ret
= CoTaskMemAlloc(bstr_alloc_size(size
));
179 /******************************************************************************
180 * SysStringLen [OLEAUT32.7]
182 * Get the allocated length of a BSTR in wide characters.
185 * str [I] BSTR to find the length of
188 * The allocated length of str, or 0 if str is NULL.
192 * The returned length may be different from the length of the string as
193 * calculated by lstrlenW(), since it returns the length that was used to
194 * allocate the string by SysAllocStringLen().
196 UINT WINAPI
SysStringLen(BSTR str
)
198 return str
? bstr_from_str(str
)->size
/sizeof(WCHAR
) : 0;
201 /******************************************************************************
202 * SysStringByteLen [OLEAUT32.149]
204 * Get the allocated length of a BSTR in bytes.
207 * str [I] BSTR to find the length of
210 * The allocated length of str, or 0 if str is NULL.
213 * See SysStringLen(), BSTR().
215 UINT WINAPI
SysStringByteLen(BSTR str
)
217 return str
? bstr_from_str(str
)->size
: 0;
220 /******************************************************************************
221 * SysAllocString [OLEAUT32.2]
223 * Create a BSTR from an OLESTR.
226 * str [I] Source to create BSTR from
229 * Success: A BSTR allocated with SysAllocStringLen().
230 * Failure: NULL, if oleStr is NULL.
234 * MSDN (October 2001) incorrectly states that NULL is returned if oleStr has
235 * a length of 0. Native Win32 and this implementation both return a valid
236 * empty BSTR in this case.
238 BSTR WINAPI
SysAllocString(LPCOLESTR str
)
242 /* Delegate this to the SysAllocStringLen32 method. */
243 return SysAllocStringLen(str
, lstrlenW(str
));
246 static inline IMalloc
*get_malloc(void)
248 static IMalloc
*malloc
;
251 CoGetMalloc(1, &malloc
);
256 /******************************************************************************
257 * SysFreeString [OLEAUT32.6]
262 * str [I] BSTR to free.
269 * str may be NULL, in which case this function does nothing.
271 void WINAPI DECLSPEC_HOTPATCH
SysFreeString(BSTR str
)
273 bstr_cache_entry_t
*cache_entry
;
275 IMalloc
*malloc
= get_malloc();
281 bstr
= bstr_from_str(str
);
283 alloc_size
= IMalloc_GetSize(malloc
, bstr
);
284 if (alloc_size
== ~0UL)
287 cache_entry
= get_cache_entry_from_alloc_size(alloc_size
);
291 EnterCriticalSection(&cs_bstr_cache
);
293 /* According to tests, freeing a string that's already in cache doesn't corrupt anything.
294 * For that to work we need to search the cache. */
295 for(i
=0; i
< cache_entry
->cnt
; i
++) {
296 if(cache_entry
->buf
[(cache_entry
->head
+i
) % BUCKET_BUFFER_SIZE
] == bstr
) {
297 WARN_(heap
)("String already is in cache!\n");
298 LeaveCriticalSection(&cs_bstr_cache
);
303 if(cache_entry
->cnt
< ARRAY_SIZE(cache_entry
->buf
)) {
304 cache_entry
->buf
[(cache_entry
->head
+cache_entry
->cnt
) % BUCKET_BUFFER_SIZE
] = bstr
;
308 unsigned n
= (alloc_size
-FIELD_OFFSET(bstr_t
, u
.ptr
))/sizeof(DWORD
);
310 bstr
->u
.dwptr
[i
] = ARENA_FREE_FILLER
;
313 LeaveCriticalSection(&cs_bstr_cache
);
317 LeaveCriticalSection(&cs_bstr_cache
);
323 /******************************************************************************
324 * SysAllocStringLen [OLEAUT32.4]
326 * Create a BSTR from an OLESTR of a given wide character length.
329 * str [I] Source to create BSTR from
330 * len [I] Length of oleStr in wide characters
333 * Success: A newly allocated BSTR from SysAllocStringByteLen()
334 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
337 * See BSTR(), SysAllocStringByteLen().
339 BSTR WINAPI
SysAllocStringLen(const OLECHAR
*str
, unsigned int len
)
344 /* Detect integer overflow. */
345 if (len
>= ((UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
))/sizeof(WCHAR
)))
348 TRACE("%s\n", debugstr_wn(str
, len
));
350 size
= len
*sizeof(WCHAR
);
351 bstr
= alloc_bstr(size
);
356 memcpy(bstr
->u
.str
, str
, size
);
357 bstr
->u
.str
[len
] = 0;
359 memset(bstr
->u
.str
, 0, size
+sizeof(WCHAR
));
365 /******************************************************************************
366 * SysReAllocStringLen [OLEAUT32.5]
368 * Change the length of a previously created BSTR.
371 * old [O] BSTR to change the length of
372 * str [I] New source for pbstr
373 * len [I] Length of oleStr in wide characters
376 * Success: 1. The size of pbstr is updated.
377 * Failure: 0, if len >= 0x80000000 or memory allocation fails.
380 * See BSTR(), SysAllocStringByteLen().
381 * *old may be changed by this function.
383 int WINAPI
SysReAllocStringLen(BSTR
* old
, const OLECHAR
* str
, unsigned int len
)
385 /* Detect integer overflow. */
386 if (len
>= ((UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
))/sizeof(WCHAR
)))
390 DWORD newbytelen
= len
*sizeof(WCHAR
);
391 bstr_t
*old_bstr
= bstr_from_str(*old
);
392 bstr_t
*bstr
= CoTaskMemRealloc(old_bstr
, bstr_alloc_size(newbytelen
));
394 if (!bstr
) return FALSE
;
397 bstr
->size
= newbytelen
;
398 /* The old string data is still there when str is NULL */
399 if (str
&& old_bstr
->u
.str
!= str
) memmove(bstr
->u
.str
, str
, newbytelen
);
400 bstr
->u
.str
[len
] = 0;
402 *old
= SysAllocStringLen(str
, len
);
408 /******************************************************************************
409 * SysAllocStringByteLen [OLEAUT32.150]
411 * Create a BSTR from an OLESTR of a given byte length.
414 * str [I] Source to create BSTR from
415 * len [I] Length of oleStr in bytes
418 * Success: A newly allocated BSTR
419 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
422 * -If len is 0 or oleStr is NULL the resulting string is empty ("").
423 * -This function always NUL terminates the resulting BSTR.
424 * -oleStr may be either an LPCSTR or LPCOLESTR, since it is copied
425 * without checking for a terminating NUL.
428 BSTR WINAPI DECLSPEC_HOTPATCH
SysAllocStringByteLen(LPCSTR str
, UINT len
)
432 /* Detect integer overflow. */
433 if (len
>= (UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
)))
436 bstr
= alloc_bstr(len
);
441 memcpy(bstr
->u
.ptr
, str
, len
);
442 bstr
->u
.ptr
[len
] = 0;
444 memset(bstr
->u
.ptr
, 0, len
+1);
446 bstr
->u
.str
[(len
+sizeof(WCHAR
)-1)/sizeof(WCHAR
)] = 0;
451 /******************************************************************************
452 * SysReAllocString [OLEAUT32.3]
454 * Change the length of a previously created BSTR.
457 * old [I/O] BSTR to change the length of
458 * str [I] New source for pbstr
465 * See BSTR(), SysAllocStringStringLen().
467 INT WINAPI
SysReAllocString(LPBSTR old
,LPCOLESTR str
)
476 * Make sure we free the old string.
481 * Allocate the new string
483 *old
= SysAllocString(str
);
488 /******************************************************************************
489 * SetOaNoCache (OLEAUT32.327)
491 * Instruct Ole Automation not to cache BSTR allocations.
500 * SetOaNoCache does not release cached strings, so it leaks by design.
502 void WINAPI
SetOaNoCache(void)
505 bstr_cache_enabled
= FALSE
;
508 /***********************************************************************
509 * RegisterActiveObject (OLEAUT32.33)
511 * Registers an object in the global item table.
514 * punk [I] Object to register.
515 * rcid [I] CLSID of the object.
517 * pdwRegister [O] Address to store cookie of object registration in.
521 * Failure: HRESULT code.
523 HRESULT WINAPI DECLSPEC_HOTPATCH
RegisterActiveObject(
524 LPUNKNOWN punk
,REFCLSID rcid
,DWORD dwFlags
,LPDWORD pdwRegister
528 LPRUNNINGOBJECTTABLE runobtable
;
530 DWORD rot_flags
= ROTFLAGS_REGISTRATIONKEEPSALIVE
; /* default registration is strong */
532 StringFromGUID2(rcid
,guidbuf
,39);
533 ret
= CreateItemMoniker(L
"!", guidbuf
, &moniker
);
536 ret
= GetRunningObjectTable(0,&runobtable
);
538 IMoniker_Release(moniker
);
541 if(dwFlags
== ACTIVEOBJECT_WEAK
)
543 ret
= IRunningObjectTable_Register(runobtable
,rot_flags
,punk
,moniker
,pdwRegister
);
544 IRunningObjectTable_Release(runobtable
);
545 IMoniker_Release(moniker
);
549 /***********************************************************************
550 * RevokeActiveObject (OLEAUT32.34)
552 * Revokes an object from the global item table.
555 * xregister [I] Registration cookie.
556 * reserved [I] Reserved. Set to NULL.
560 * Failure: HRESULT code.
562 HRESULT WINAPI DECLSPEC_HOTPATCH
RevokeActiveObject(DWORD xregister
,LPVOID reserved
)
564 LPRUNNINGOBJECTTABLE runobtable
;
567 ret
= GetRunningObjectTable(0,&runobtable
);
568 if (FAILED(ret
)) return ret
;
569 ret
= IRunningObjectTable_Revoke(runobtable
,xregister
);
570 if (SUCCEEDED(ret
)) ret
= S_OK
;
571 IRunningObjectTable_Release(runobtable
);
575 /***********************************************************************
576 * GetActiveObject (OLEAUT32.35)
578 * Gets an object from the global item table.
581 * rcid [I] CLSID of the object.
582 * preserved [I] Reserved. Set to NULL.
583 * ppunk [O] Address to store object into.
587 * Failure: HRESULT code.
589 HRESULT WINAPI DECLSPEC_HOTPATCH
GetActiveObject(REFCLSID rcid
,LPVOID preserved
,LPUNKNOWN
*ppunk
)
593 LPRUNNINGOBJECTTABLE runobtable
;
596 StringFromGUID2(rcid
,guidbuf
,39);
597 ret
= CreateItemMoniker(L
"!", guidbuf
, &moniker
);
600 ret
= GetRunningObjectTable(0,&runobtable
);
602 IMoniker_Release(moniker
);
605 ret
= IRunningObjectTable_GetObject(runobtable
,moniker
,ppunk
);
606 IRunningObjectTable_Release(runobtable
);
607 IMoniker_Release(moniker
);
612 /***********************************************************************
613 * OaBuildVersion [OLEAUT32.170]
615 * Get the Ole Automation build version.
624 * Known oleaut32.dll versions:
625 *| OLE Ver. Comments Date Build Ver.
626 *| -------- ------------------------- ---- ---------
627 *| OLE 2.1 NT 1993-95 10 3023
629 *| Win32s Ver 1.1e 20 4049
630 *| OLE 2.20 W95/NT 1993-96 20 4112
631 *| OLE 2.20 W95/NT 1993-96 20 4118
632 *| OLE 2.20 W95/NT 1993-96 20 4122
633 *| OLE 2.30 W95/NT 1993-98 30 4265
634 *| OLE 2.40 NT?? 1993-98 40 4267
635 *| OLE 2.40 W98 SE orig. file 1993-98 40 4275
636 *| OLE 2.40 W2K orig. file 1993-XX 40 4514
638 * Currently the versions returned are 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
639 * and 2.40 for all later versions. The build number is maximum, i.e. 0xffff.
641 ULONG WINAPI
OaBuildVersion(void)
643 switch(GetVersion() & 0x8000ffff) /* mask off build number */
645 case 0x80000a03: /* WIN31 */
646 return MAKELONG(0xffff, 20);
647 case 0x00003303: /* NT351 */
648 return MAKELONG(0xffff, 30);
649 case 0x80000004: /* WIN95; I'd like to use the "standard" w95 minor
650 version here (30), but as we still use w95
651 as default winver (which is good IMHO), I better
652 play safe and use the latest value for w95 for now.
653 Change this as soon as default winver gets changed
654 to something more recent */
655 case 0x80000a04: /* WIN98 */
656 case 0x00000004: /* NT40 */
657 case 0x00000005: /* W2K */
658 return MAKELONG(0xffff, 40);
659 case 0x00000105: /* WinXP */
660 case 0x00000006: /* Vista */
661 case 0x00000106: /* Win7 */
662 return MAKELONG(0xffff, 50);
664 FIXME("Version value not known yet. Please investigate it !\n");
665 return MAKELONG(0xffff, 40); /* for now return the same value as for w2k */
669 /******************************************************************************
670 * OleTranslateColor [OLEAUT32.421]
672 * Convert an OLE_COLOR to a COLORREF.
675 * clr [I] Color to convert
676 * hpal [I] Handle to a palette for the conversion
677 * pColorRef [O] Destination for converted color, or NULL to test if the conversion is ok
680 * Success: S_OK. The conversion is ok, and pColorRef contains the converted color if non-NULL.
681 * Failure: E_INVALIDARG, if any argument is invalid.
684 * Document the conversion rules.
686 HRESULT WINAPI
OleTranslateColor(
692 BYTE b
= HIBYTE(HIWORD(clr
));
694 TRACE("(%08x, %p, %p)\n", clr
, hpal
, pColorRef
);
697 * In case pColorRef is NULL, provide our own to simplify the code.
699 if (pColorRef
== NULL
)
700 pColorRef
= &colorref
;
707 *pColorRef
= PALETTERGB(GetRValue(clr
),
722 * Validate the palette index.
724 if (GetPaletteEntries(hpal
, LOWORD(clr
), 1, &pe
) == 0)
739 int index
= LOBYTE(LOWORD(clr
));
742 * Validate GetSysColor index.
744 if ((index
< COLOR_SCROLLBAR
) || (index
> COLOR_MENUBAR
))
747 *pColorRef
= GetSysColor(index
);
759 extern HRESULT WINAPI
OLEAUTPS_DllGetClassObject(REFCLSID
, REFIID
, LPVOID
*) DECLSPEC_HIDDEN
;
760 extern BOOL WINAPI
OLEAUTPS_DllMain(HINSTANCE
, DWORD
, LPVOID
) DECLSPEC_HIDDEN
;
761 extern HRESULT WINAPI
OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN
;
762 extern HRESULT WINAPI
OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
764 extern HRESULT WINAPI
CreateProxyFromTypeInfo(ITypeInfo
*typeinfo
,
765 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **obj
);
766 extern HRESULT WINAPI
CreateStubFromTypeInfo(ITypeInfo
*typeinfo
, REFIID iid
,
767 IUnknown
*server
, IRpcStubBuffer
**stub
);
769 struct ifacepsredirect_data
781 struct tlibredirect_data
795 static BOOL
actctx_get_typelib_module(REFIID iid
, WCHAR
*module
, DWORD len
)
797 struct ifacepsredirect_data
*iface
;
798 struct tlibredirect_data
*tlib
;
799 ACTCTX_SECTION_KEYED_DATA data
;
802 data
.cbSize
= sizeof(data
);
803 if (!FindActCtxSectionGuid(0, NULL
, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION
,
807 iface
= (struct ifacepsredirect_data
*)data
.lpData
;
808 if (!FindActCtxSectionGuid(0, NULL
, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
,
809 &iface
->tlbid
, &data
))
812 tlib
= (struct tlibredirect_data
*)data
.lpData
;
813 ptrW
= (WCHAR
*)((BYTE
*)data
.lpSectionBase
+ tlib
->name_offset
);
815 if (tlib
->name_len
/sizeof(WCHAR
) >= len
)
817 ERR("need larger module buffer, %u\n", tlib
->name_len
);
821 memcpy(module
, ptrW
, tlib
->name_len
);
822 module
[tlib
->name_len
/sizeof(WCHAR
)] = 0;
826 static HRESULT
reg_get_typelib_module(REFIID iid
, WCHAR
*module
, DWORD len
)
828 REGSAM opposite
= (sizeof(void*) == 8) ? KEY_WOW64_32KEY
: KEY_WOW64_64KEY
;
829 char tlguid
[200], typelibkey
[316], interfacekey
[300], ver
[100], tlfn
[260];
830 DWORD tlguidlen
, verlen
, type
;
835 sprintf( interfacekey
, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
836 iid
->Data1
, iid
->Data2
, iid
->Data3
,
837 iid
->Data4
[0], iid
->Data4
[1], iid
->Data4
[2], iid
->Data4
[3],
838 iid
->Data4
[4], iid
->Data4
[5], iid
->Data4
[6], iid
->Data4
[7]
841 err
= RegOpenKeyExA(HKEY_CLASSES_ROOT
,interfacekey
,0,KEY_READ
,&ikey
);
842 if (err
&& (opposite
== KEY_WOW64_32KEY
|| (IsWow64Process(GetCurrentProcess(), &is_wow64
)
844 err
= RegOpenKeyExA(HKEY_CLASSES_ROOT
,interfacekey
,0,KEY_READ
|opposite
,&ikey
);
848 ERR("No %s key found.\n", interfacekey
);
852 tlguidlen
= sizeof(tlguid
);
853 if (RegQueryValueExA(ikey
, NULL
, NULL
, &type
, (BYTE
*)tlguid
, &tlguidlen
))
855 ERR("Getting typelib guid failed.\n");
860 verlen
= sizeof(ver
);
861 if (RegQueryValueExA(ikey
, "Version", NULL
, &type
, (BYTE
*)ver
, &verlen
))
863 ERR("Could not get version value?\n");
870 sprintf(typelibkey
, "Typelib\\%s\\%s\\0\\win%u", tlguid
, ver
, sizeof(void *) == 8 ? 64 : 32);
871 tlfnlen
= sizeof(tlfn
);
872 if (RegQueryValueA(HKEY_CLASSES_ROOT
, typelibkey
, tlfn
, &tlfnlen
))
875 sprintf(typelibkey
, "Typelib\\%s\\%s\\0\\win32", tlguid
, ver
);
876 tlfnlen
= sizeof(tlfn
);
877 if (RegQueryValueA(HKEY_CLASSES_ROOT
, typelibkey
, tlfn
, &tlfnlen
))
880 ERR("Could not get typelib fn?\n");
886 MultiByteToWideChar(CP_ACP
, 0, tlfn
, -1, module
, len
);
890 static HRESULT
get_typeinfo_for_iid(REFIID iid
, ITypeInfo
**typeinfo
)
892 WCHAR module
[MAX_PATH
];
899 if (!actctx_get_typelib_module(iid
, module
, ARRAY_SIZE(module
)))
901 hr
= reg_get_typelib_module(iid
, module
, ARRAY_SIZE(module
));
906 hr
= LoadTypeLib(module
, &typelib
);
908 ERR("Failed to load typelib for %s, but it should be there.\n", debugstr_guid(iid
));
912 hr
= ITypeLib_GetTypeInfoOfGuid(typelib
, iid
, typeinfo
);
913 ITypeLib_Release(typelib
);
915 ERR("typelib does not contain info for %s\n", debugstr_guid(iid
));
920 static HRESULT WINAPI
dispatch_typelib_ps_QueryInterface(IPSFactoryBuffer
*iface
, REFIID iid
, void **out
)
922 if (IsEqualIID(iid
, &IID_IPSFactoryBuffer
) || IsEqualIID(iid
, &IID_IUnknown
))
928 FIXME("No interface for %s.\n", debugstr_guid(iid
));
930 return E_NOINTERFACE
;
933 static ULONG WINAPI
dispatch_typelib_ps_AddRef(IPSFactoryBuffer
*iface
)
938 static ULONG WINAPI
dispatch_typelib_ps_Release(IPSFactoryBuffer
*iface
)
943 static HRESULT
dispatch_create_proxy(IUnknown
*outer
, IRpcProxyBuffer
**proxy
, void **out
)
945 IPSFactoryBuffer
*factory
;
948 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&factory
);
949 if (FAILED(hr
)) return hr
;
951 hr
= IPSFactoryBuffer_CreateProxy(factory
, outer
, &IID_IDispatch
, proxy
, out
);
952 IPSFactoryBuffer_Release(factory
);
956 static HRESULT WINAPI
dispatch_typelib_ps_CreateProxy(IPSFactoryBuffer
*iface
,
957 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **out
)
963 if (IsEqualGUID(iid
, &IID_IDispatch
))
964 return dispatch_create_proxy(outer
, proxy
, out
);
966 hr
= get_typeinfo_for_iid(iid
, &typeinfo
);
967 if (FAILED(hr
)) return hr
;
969 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &attr
);
972 ITypeInfo_Release(typeinfo
);
976 if (attr
->typekind
== TKIND_INTERFACE
|| (attr
->wTypeFlags
& TYPEFLAG_FDUAL
))
977 hr
= CreateProxyFromTypeInfo(typeinfo
, outer
, iid
, proxy
, out
);
979 hr
= dispatch_create_proxy(outer
, proxy
, out
);
982 ERR("Failed to create proxy, hr %#x.\n", hr
);
984 ITypeInfo_ReleaseTypeAttr(typeinfo
, attr
);
985 ITypeInfo_Release(typeinfo
);
989 static HRESULT
dispatch_create_stub(IUnknown
*server
, IRpcStubBuffer
**stub
)
991 IPSFactoryBuffer
*factory
;
994 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&factory
);
995 if (FAILED(hr
)) return hr
;
997 hr
= IPSFactoryBuffer_CreateStub(factory
, &IID_IDispatch
, server
, stub
);
998 IPSFactoryBuffer_Release(factory
);
1002 static HRESULT WINAPI
dispatch_typelib_ps_CreateStub(IPSFactoryBuffer
*iface
,
1003 REFIID iid
, IUnknown
*server
, IRpcStubBuffer
**stub
)
1005 ITypeInfo
*typeinfo
;
1009 if (IsEqualGUID(iid
, &IID_IDispatch
))
1010 return dispatch_create_stub(server
, stub
);
1012 hr
= get_typeinfo_for_iid(iid
, &typeinfo
);
1013 if (FAILED(hr
)) return hr
;
1015 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &attr
);
1018 ITypeInfo_Release(typeinfo
);
1022 if (attr
->typekind
== TKIND_INTERFACE
|| (attr
->wTypeFlags
& TYPEFLAG_FDUAL
))
1023 hr
= CreateStubFromTypeInfo(typeinfo
, iid
, server
, stub
);
1025 hr
= dispatch_create_stub(server
, stub
);
1028 ERR("Failed to create proxy, hr %#x.\n", hr
);
1030 ITypeInfo_ReleaseTypeAttr(typeinfo
, attr
);
1031 ITypeInfo_Release(typeinfo
);
1035 static const IPSFactoryBufferVtbl dispatch_typelib_ps_vtbl
=
1037 dispatch_typelib_ps_QueryInterface
,
1038 dispatch_typelib_ps_AddRef
,
1039 dispatch_typelib_ps_Release
,
1040 dispatch_typelib_ps_CreateProxy
,
1041 dispatch_typelib_ps_CreateStub
,
1044 static IPSFactoryBuffer dispatch_typelib_ps
= { &dispatch_typelib_ps_vtbl
};
1046 extern void _get_STDFONT_CF(LPVOID
*);
1047 extern void _get_STDPIC_CF(LPVOID
*);
1049 /***********************************************************************
1050 * DllGetClassObject (OLEAUT32.@)
1052 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID iid
, LPVOID
*ppv
)
1055 if (IsEqualGUID(rclsid
,&CLSID_StdFont
)) {
1056 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
1057 _get_STDFONT_CF(ppv
);
1058 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1062 if (IsEqualGUID(rclsid
,&CLSID_StdPicture
)) {
1063 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
1064 _get_STDPIC_CF(ppv
);
1065 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1070 if (IsEqualGUID(rclsid
, &CLSID_PSDispatch
) || IsEqualGUID(rclsid
, &CLSID_PSOAInterface
))
1071 return IPSFactoryBuffer_QueryInterface(&dispatch_typelib_ps
, iid
, ppv
);
1073 if (IsEqualCLSID(rclsid
, &CLSID_PSTypeComp
) ||
1074 IsEqualCLSID(rclsid
, &CLSID_PSTypeInfo
) ||
1075 IsEqualCLSID(rclsid
, &CLSID_PSTypeLib
) ||
1076 IsEqualCLSID(rclsid
, &CLSID_PSDispatch
) ||
1077 IsEqualCLSID(rclsid
, &CLSID_PSEnumVariant
))
1078 return OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, iid
, ppv
);
1080 return OLEAUTPS_DllGetClassObject(rclsid
, iid
, ppv
);
1083 /***********************************************************************
1084 * DllCanUnloadNow (OLEAUT32.@)
1086 * Determine if this dll can be unloaded from the callers address space.
1092 * Always returns S_FALSE. This dll cannot be unloaded.
1094 HRESULT WINAPI
DllCanUnloadNow(void)
1099 /*****************************************************************************
1100 * DllMain [OLEAUT32.@]
1102 BOOL WINAPI
DllMain(HINSTANCE hInstDll
, DWORD fdwReason
, LPVOID lpvReserved
)
1104 if(fdwReason
== DLL_PROCESS_ATTACH
)
1105 bstr_cache_enabled
= !GetEnvironmentVariableW(L
"oanocache", NULL
, 0);
1107 return OLEAUTPS_DllMain( hInstDll
, fdwReason
, lpvReserved
);
1110 /***********************************************************************
1111 * DllRegisterServer (OLEAUT32.@)
1113 HRESULT WINAPI
DllRegisterServer(void)
1115 return OLEAUTPS_DllRegisterServer();
1118 /***********************************************************************
1119 * DllUnregisterServer (OLEAUT32.@)
1121 HRESULT WINAPI
DllUnregisterServer(void)
1123 return OLEAUTPS_DllUnregisterServer();
1126 /***********************************************************************
1127 * OleIconToCursor (OLEAUT32.415)
1129 HCURSOR WINAPI
OleIconToCursor( HINSTANCE hinstExe
, HICON hIcon
)
1131 FIXME("(%p,%p), partially implemented.\n",hinstExe
,hIcon
);
1132 /* FIXME: make an extended conversation from HICON to HCURSOR */
1133 return CopyCursor(hIcon
);
1136 /***********************************************************************
1137 * GetAltMonthNames (OLEAUT32.@)
1139 HRESULT WINAPI
GetAltMonthNames(LCID lcid
, LPOLESTR
**str
)
1141 static const WCHAR
*arabic_hijri
[] =
1143 L
"\x0645\x062d\x0631\x0645",
1144 L
"\x0635\x0641\x0631",
1145 L
"\x0631\x0628\x064a\x0639 \x0627\x0644\x0627\x0648\x0644",
1146 L
"\x0631\x0628\x064a\x0639 \x0627\x0644\x062b\x0627\x0646\x064a",
1147 L
"\x062c\x0645\x0627\x062f\x0649 \x0627\x0644\x0627\x0648\x0644\x0649",
1148 L
"\x062c\x0645\x0627\x062f\x0649 \x0627\x0644\x062b\x0627\x0646\x064a\x0629",
1149 L
"\x0631\x062c\x0628",
1150 L
"\x0634\x0639\x0628\x0627\x0646",
1151 L
"\x0631\x0645\x0636\x0627\x0646",
1152 L
"\x0634\x0648\x0627\x0643",
1153 L
"\x0630\x0648 \x0627\x0644\x0642\x0639\x062f\x0629",
1154 L
"\x0630\x0648 \x0627\x0644\x062d\x062c\x0629",
1158 static const WCHAR
*polish_genitive_names
[] =
1169 L
"pa\x017a" "dziernika",
1175 static const WCHAR
*russian_genitive_names
[] =
1177 L
"\x044f\x043d\x0432\x0430\x0440\x044f",
1178 L
"\x0444\x0435\x0432\x0440\x0430\x043b\x044f",
1179 L
"\x043c\x0430\x0440\x0442\x0430",
1180 L
"\x0430\x043f\x0440\x0435\x043b\x044f",
1181 L
"\x043c\x0430\x044f",
1182 L
"\x0438\x044e\x043d\x044f",
1183 L
"\x0438\x044e\x043b\x044f",
1184 L
"\x0430\x0432\x0433\x0443\x0441\x0442\x0430",
1185 L
"\x0441\x0435\x043d\x0442\x044f\x0431\x0440\x044f",
1186 L
"\x043e\x043a\x0442\x044f\x0431\x0440\x044f",
1187 L
"\x043d\x043e\x044f\x0431\x0440\x044f",
1188 L
"\x0434\x0435\x043a\x0430\x0431\x0440\x044f",
1192 TRACE("%#x, %p\n", lcid
, str
);
1194 if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_ARABIC
)
1195 *str
= (LPOLESTR
*)arabic_hijri
;
1196 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_POLISH
)
1197 *str
= (LPOLESTR
*)polish_genitive_names
;
1198 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_RUSSIAN
)
1199 *str
= (LPOLESTR
*)russian_genitive_names
;