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 static const WCHAR _delimiter
[] = {'!',0}; /* default delimiter apparently */
509 static const WCHAR
*pdelimiter
= &_delimiter
[0];
511 /***********************************************************************
512 * RegisterActiveObject (OLEAUT32.33)
514 * Registers an object in the global item table.
517 * punk [I] Object to register.
518 * rcid [I] CLSID of the object.
520 * pdwRegister [O] Address to store cookie of object registration in.
524 * Failure: HRESULT code.
526 HRESULT WINAPI DECLSPEC_HOTPATCH
RegisterActiveObject(
527 LPUNKNOWN punk
,REFCLSID rcid
,DWORD dwFlags
,LPDWORD pdwRegister
531 LPRUNNINGOBJECTTABLE runobtable
;
533 DWORD rot_flags
= ROTFLAGS_REGISTRATIONKEEPSALIVE
; /* default registration is strong */
535 StringFromGUID2(rcid
,guidbuf
,39);
536 ret
= CreateItemMoniker(pdelimiter
,guidbuf
,&moniker
);
539 ret
= GetRunningObjectTable(0,&runobtable
);
541 IMoniker_Release(moniker
);
544 if(dwFlags
== ACTIVEOBJECT_WEAK
)
546 ret
= IRunningObjectTable_Register(runobtable
,rot_flags
,punk
,moniker
,pdwRegister
);
547 IRunningObjectTable_Release(runobtable
);
548 IMoniker_Release(moniker
);
552 /***********************************************************************
553 * RevokeActiveObject (OLEAUT32.34)
555 * Revokes an object from the global item table.
558 * xregister [I] Registration cookie.
559 * reserved [I] Reserved. Set to NULL.
563 * Failure: HRESULT code.
565 HRESULT WINAPI DECLSPEC_HOTPATCH
RevokeActiveObject(DWORD xregister
,LPVOID reserved
)
567 LPRUNNINGOBJECTTABLE runobtable
;
570 ret
= GetRunningObjectTable(0,&runobtable
);
571 if (FAILED(ret
)) return ret
;
572 ret
= IRunningObjectTable_Revoke(runobtable
,xregister
);
573 if (SUCCEEDED(ret
)) ret
= S_OK
;
574 IRunningObjectTable_Release(runobtable
);
578 /***********************************************************************
579 * GetActiveObject (OLEAUT32.35)
581 * Gets an object from the global item table.
584 * rcid [I] CLSID of the object.
585 * preserved [I] Reserved. Set to NULL.
586 * ppunk [O] Address to store object into.
590 * Failure: HRESULT code.
592 HRESULT WINAPI DECLSPEC_HOTPATCH
GetActiveObject(REFCLSID rcid
,LPVOID preserved
,LPUNKNOWN
*ppunk
)
596 LPRUNNINGOBJECTTABLE runobtable
;
599 StringFromGUID2(rcid
,guidbuf
,39);
600 ret
= CreateItemMoniker(pdelimiter
,guidbuf
,&moniker
);
603 ret
= GetRunningObjectTable(0,&runobtable
);
605 IMoniker_Release(moniker
);
608 ret
= IRunningObjectTable_GetObject(runobtable
,moniker
,ppunk
);
609 IRunningObjectTable_Release(runobtable
);
610 IMoniker_Release(moniker
);
615 /***********************************************************************
616 * OaBuildVersion [OLEAUT32.170]
618 * Get the Ole Automation build version.
627 * Known oleaut32.dll versions:
628 *| OLE Ver. Comments Date Build Ver.
629 *| -------- ------------------------- ---- ---------
630 *| OLE 2.1 NT 1993-95 10 3023
632 *| Win32s Ver 1.1e 20 4049
633 *| OLE 2.20 W95/NT 1993-96 20 4112
634 *| OLE 2.20 W95/NT 1993-96 20 4118
635 *| OLE 2.20 W95/NT 1993-96 20 4122
636 *| OLE 2.30 W95/NT 1993-98 30 4265
637 *| OLE 2.40 NT?? 1993-98 40 4267
638 *| OLE 2.40 W98 SE orig. file 1993-98 40 4275
639 *| OLE 2.40 W2K orig. file 1993-XX 40 4514
641 * Currently the versions returned are 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
642 * and 2.40 for all later versions. The build number is maximum, i.e. 0xffff.
644 ULONG WINAPI
OaBuildVersion(void)
646 switch(GetVersion() & 0x8000ffff) /* mask off build number */
648 case 0x80000a03: /* WIN31 */
649 return MAKELONG(0xffff, 20);
650 case 0x00003303: /* NT351 */
651 return MAKELONG(0xffff, 30);
652 case 0x80000004: /* WIN95; I'd like to use the "standard" w95 minor
653 version here (30), but as we still use w95
654 as default winver (which is good IMHO), I better
655 play safe and use the latest value for w95 for now.
656 Change this as soon as default winver gets changed
657 to something more recent */
658 case 0x80000a04: /* WIN98 */
659 case 0x00000004: /* NT40 */
660 case 0x00000005: /* W2K */
661 return MAKELONG(0xffff, 40);
662 case 0x00000105: /* WinXP */
663 case 0x00000006: /* Vista */
664 case 0x00000106: /* Win7 */
665 return MAKELONG(0xffff, 50);
667 FIXME("Version value not known yet. Please investigate it !\n");
668 return MAKELONG(0xffff, 40); /* for now return the same value as for w2k */
672 /******************************************************************************
673 * OleTranslateColor [OLEAUT32.421]
675 * Convert an OLE_COLOR to a COLORREF.
678 * clr [I] Color to convert
679 * hpal [I] Handle to a palette for the conversion
680 * pColorRef [O] Destination for converted color, or NULL to test if the conversion is ok
683 * Success: S_OK. The conversion is ok, and pColorRef contains the converted color if non-NULL.
684 * Failure: E_INVALIDARG, if any argument is invalid.
687 * Document the conversion rules.
689 HRESULT WINAPI
OleTranslateColor(
695 BYTE b
= HIBYTE(HIWORD(clr
));
697 TRACE("(%08x, %p, %p)\n", clr
, hpal
, pColorRef
);
700 * In case pColorRef is NULL, provide our own to simplify the code.
702 if (pColorRef
== NULL
)
703 pColorRef
= &colorref
;
710 *pColorRef
= PALETTERGB(GetRValue(clr
),
725 * Validate the palette index.
727 if (GetPaletteEntries(hpal
, LOWORD(clr
), 1, &pe
) == 0)
742 int index
= LOBYTE(LOWORD(clr
));
745 * Validate GetSysColor index.
747 if ((index
< COLOR_SCROLLBAR
) || (index
> COLOR_MENUBAR
))
750 *pColorRef
= GetSysColor(index
);
762 extern HRESULT WINAPI
OLEAUTPS_DllGetClassObject(REFCLSID
, REFIID
, LPVOID
*) DECLSPEC_HIDDEN
;
763 extern BOOL WINAPI
OLEAUTPS_DllMain(HINSTANCE
, DWORD
, LPVOID
) DECLSPEC_HIDDEN
;
764 extern HRESULT WINAPI
OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN
;
765 extern HRESULT WINAPI
OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
767 extern HRESULT WINAPI
CreateProxyFromTypeInfo(ITypeInfo
*typeinfo
,
768 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **obj
);
769 extern HRESULT WINAPI
CreateStubFromTypeInfo(ITypeInfo
*typeinfo
, REFIID iid
,
770 IUnknown
*server
, IRpcStubBuffer
**stub
);
772 struct ifacepsredirect_data
784 struct tlibredirect_data
798 static BOOL
actctx_get_typelib_module(REFIID iid
, WCHAR
*module
, DWORD len
)
800 struct ifacepsredirect_data
*iface
;
801 struct tlibredirect_data
*tlib
;
802 ACTCTX_SECTION_KEYED_DATA data
;
805 data
.cbSize
= sizeof(data
);
806 if (!FindActCtxSectionGuid(0, NULL
, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION
,
810 iface
= (struct ifacepsredirect_data
*)data
.lpData
;
811 if (!FindActCtxSectionGuid(0, NULL
, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION
,
812 &iface
->tlbid
, &data
))
815 tlib
= (struct tlibredirect_data
*)data
.lpData
;
816 ptrW
= (WCHAR
*)((BYTE
*)data
.lpSectionBase
+ tlib
->name_offset
);
818 if (tlib
->name_len
/sizeof(WCHAR
) >= len
)
820 ERR("need larger module buffer, %u\n", tlib
->name_len
);
824 memcpy(module
, ptrW
, tlib
->name_len
);
825 module
[tlib
->name_len
/sizeof(WCHAR
)] = 0;
829 static HRESULT
reg_get_typelib_module(REFIID iid
, WCHAR
*module
, DWORD len
)
831 REGSAM opposite
= (sizeof(void*) == 8) ? KEY_WOW64_32KEY
: KEY_WOW64_64KEY
;
832 char tlguid
[200], typelibkey
[316], interfacekey
[300], ver
[100], tlfn
[260];
833 DWORD tlguidlen
, verlen
, type
;
838 sprintf( interfacekey
, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
839 iid
->Data1
, iid
->Data2
, iid
->Data3
,
840 iid
->Data4
[0], iid
->Data4
[1], iid
->Data4
[2], iid
->Data4
[3],
841 iid
->Data4
[4], iid
->Data4
[5], iid
->Data4
[6], iid
->Data4
[7]
844 err
= RegOpenKeyExA(HKEY_CLASSES_ROOT
,interfacekey
,0,KEY_READ
,&ikey
);
845 if (err
&& (opposite
== KEY_WOW64_32KEY
|| (IsWow64Process(GetCurrentProcess(), &is_wow64
)
847 err
= RegOpenKeyExA(HKEY_CLASSES_ROOT
,interfacekey
,0,KEY_READ
|opposite
,&ikey
);
851 ERR("No %s key found.\n", interfacekey
);
855 tlguidlen
= sizeof(tlguid
);
856 if (RegQueryValueExA(ikey
, NULL
, NULL
, &type
, (BYTE
*)tlguid
, &tlguidlen
))
858 ERR("Getting typelib guid failed.\n");
863 verlen
= sizeof(ver
);
864 if (RegQueryValueExA(ikey
, "Version", NULL
, &type
, (BYTE
*)ver
, &verlen
))
866 ERR("Could not get version value?\n");
873 sprintf(typelibkey
, "Typelib\\%s\\%s\\0\\win%u", tlguid
, ver
, sizeof(void *) == 8 ? 64 : 32);
874 tlfnlen
= sizeof(tlfn
);
875 if (RegQueryValueA(HKEY_CLASSES_ROOT
, typelibkey
, tlfn
, &tlfnlen
))
878 sprintf(typelibkey
, "Typelib\\%s\\%s\\0\\win32", tlguid
, ver
);
879 tlfnlen
= sizeof(tlfn
);
880 if (RegQueryValueA(HKEY_CLASSES_ROOT
, typelibkey
, tlfn
, &tlfnlen
))
883 ERR("Could not get typelib fn?\n");
889 MultiByteToWideChar(CP_ACP
, 0, tlfn
, -1, module
, len
);
893 static HRESULT
get_typeinfo_for_iid(REFIID iid
, ITypeInfo
**typeinfo
)
895 WCHAR module
[MAX_PATH
];
902 if (!actctx_get_typelib_module(iid
, module
, ARRAY_SIZE(module
)))
904 hr
= reg_get_typelib_module(iid
, module
, ARRAY_SIZE(module
));
909 hr
= LoadTypeLib(module
, &typelib
);
911 ERR("Failed to load typelib for %s, but it should be there.\n", debugstr_guid(iid
));
915 hr
= ITypeLib_GetTypeInfoOfGuid(typelib
, iid
, typeinfo
);
916 ITypeLib_Release(typelib
);
918 ERR("typelib does not contain info for %s\n", debugstr_guid(iid
));
923 static HRESULT WINAPI
dispatch_typelib_ps_QueryInterface(IPSFactoryBuffer
*iface
, REFIID iid
, void **out
)
925 if (IsEqualIID(iid
, &IID_IPSFactoryBuffer
) || IsEqualIID(iid
, &IID_IUnknown
))
931 FIXME("No interface for %s.\n", debugstr_guid(iid
));
933 return E_NOINTERFACE
;
936 static ULONG WINAPI
dispatch_typelib_ps_AddRef(IPSFactoryBuffer
*iface
)
941 static ULONG WINAPI
dispatch_typelib_ps_Release(IPSFactoryBuffer
*iface
)
946 static HRESULT
dispatch_create_proxy(IUnknown
*outer
, IRpcProxyBuffer
**proxy
, void **out
)
948 IPSFactoryBuffer
*factory
;
951 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&factory
);
952 if (FAILED(hr
)) return hr
;
954 hr
= IPSFactoryBuffer_CreateProxy(factory
, outer
, &IID_IDispatch
, proxy
, out
);
955 IPSFactoryBuffer_Release(factory
);
959 static HRESULT WINAPI
dispatch_typelib_ps_CreateProxy(IPSFactoryBuffer
*iface
,
960 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **out
)
966 if (IsEqualGUID(iid
, &IID_IDispatch
))
967 return dispatch_create_proxy(outer
, proxy
, out
);
969 hr
= get_typeinfo_for_iid(iid
, &typeinfo
);
970 if (FAILED(hr
)) return hr
;
972 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &attr
);
975 ITypeInfo_Release(typeinfo
);
979 if (attr
->typekind
== TKIND_INTERFACE
|| (attr
->wTypeFlags
& TYPEFLAG_FDUAL
))
980 hr
= CreateProxyFromTypeInfo(typeinfo
, outer
, iid
, proxy
, out
);
982 hr
= dispatch_create_proxy(outer
, proxy
, out
);
985 ERR("Failed to create proxy, hr %#x.\n", hr
);
987 ITypeInfo_ReleaseTypeAttr(typeinfo
, attr
);
988 ITypeInfo_Release(typeinfo
);
992 static HRESULT
dispatch_create_stub(IUnknown
*server
, IRpcStubBuffer
**stub
)
994 IPSFactoryBuffer
*factory
;
997 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&factory
);
998 if (FAILED(hr
)) return hr
;
1000 hr
= IPSFactoryBuffer_CreateStub(factory
, &IID_IDispatch
, server
, stub
);
1001 IPSFactoryBuffer_Release(factory
);
1005 static HRESULT WINAPI
dispatch_typelib_ps_CreateStub(IPSFactoryBuffer
*iface
,
1006 REFIID iid
, IUnknown
*server
, IRpcStubBuffer
**stub
)
1008 ITypeInfo
*typeinfo
;
1012 if (IsEqualGUID(iid
, &IID_IDispatch
))
1013 return dispatch_create_stub(server
, stub
);
1015 hr
= get_typeinfo_for_iid(iid
, &typeinfo
);
1016 if (FAILED(hr
)) return hr
;
1018 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &attr
);
1021 ITypeInfo_Release(typeinfo
);
1025 if (attr
->typekind
== TKIND_INTERFACE
|| (attr
->wTypeFlags
& TYPEFLAG_FDUAL
))
1026 hr
= CreateStubFromTypeInfo(typeinfo
, iid
, server
, stub
);
1028 hr
= dispatch_create_stub(server
, stub
);
1031 ERR("Failed to create proxy, hr %#x.\n", hr
);
1033 ITypeInfo_ReleaseTypeAttr(typeinfo
, attr
);
1034 ITypeInfo_Release(typeinfo
);
1038 static const IPSFactoryBufferVtbl dispatch_typelib_ps_vtbl
=
1040 dispatch_typelib_ps_QueryInterface
,
1041 dispatch_typelib_ps_AddRef
,
1042 dispatch_typelib_ps_Release
,
1043 dispatch_typelib_ps_CreateProxy
,
1044 dispatch_typelib_ps_CreateStub
,
1047 static IPSFactoryBuffer dispatch_typelib_ps
= { &dispatch_typelib_ps_vtbl
};
1049 extern void _get_STDFONT_CF(LPVOID
*);
1050 extern void _get_STDPIC_CF(LPVOID
*);
1052 /***********************************************************************
1053 * DllGetClassObject (OLEAUT32.@)
1055 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID iid
, LPVOID
*ppv
)
1058 if (IsEqualGUID(rclsid
,&CLSID_StdFont
)) {
1059 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
1060 _get_STDFONT_CF(ppv
);
1061 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1065 if (IsEqualGUID(rclsid
,&CLSID_StdPicture
)) {
1066 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
1067 _get_STDPIC_CF(ppv
);
1068 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1073 if (IsEqualGUID(rclsid
, &CLSID_PSDispatch
) || IsEqualGUID(rclsid
, &CLSID_PSOAInterface
))
1074 return IPSFactoryBuffer_QueryInterface(&dispatch_typelib_ps
, iid
, ppv
);
1076 if (IsEqualCLSID(rclsid
, &CLSID_PSTypeComp
) ||
1077 IsEqualCLSID(rclsid
, &CLSID_PSTypeInfo
) ||
1078 IsEqualCLSID(rclsid
, &CLSID_PSTypeLib
) ||
1079 IsEqualCLSID(rclsid
, &CLSID_PSDispatch
) ||
1080 IsEqualCLSID(rclsid
, &CLSID_PSEnumVariant
))
1081 return OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, iid
, ppv
);
1083 return OLEAUTPS_DllGetClassObject(rclsid
, iid
, ppv
);
1086 /***********************************************************************
1087 * DllCanUnloadNow (OLEAUT32.@)
1089 * Determine if this dll can be unloaded from the callers address space.
1095 * Always returns S_FALSE. This dll cannot be unloaded.
1097 HRESULT WINAPI
DllCanUnloadNow(void)
1102 /*****************************************************************************
1103 * DllMain [OLEAUT32.@]
1105 BOOL WINAPI
DllMain(HINSTANCE hInstDll
, DWORD fdwReason
, LPVOID lpvReserved
)
1107 static const WCHAR oanocacheW
[] = {'o','a','n','o','c','a','c','h','e',0};
1109 if(fdwReason
== DLL_PROCESS_ATTACH
)
1110 bstr_cache_enabled
= !GetEnvironmentVariableW(oanocacheW
, NULL
, 0);
1112 return OLEAUTPS_DllMain( hInstDll
, fdwReason
, lpvReserved
);
1115 /***********************************************************************
1116 * DllRegisterServer (OLEAUT32.@)
1118 HRESULT WINAPI
DllRegisterServer(void)
1120 return OLEAUTPS_DllRegisterServer();
1123 /***********************************************************************
1124 * DllUnregisterServer (OLEAUT32.@)
1126 HRESULT WINAPI
DllUnregisterServer(void)
1128 return OLEAUTPS_DllUnregisterServer();
1131 /***********************************************************************
1132 * OleIconToCursor (OLEAUT32.415)
1134 HCURSOR WINAPI
OleIconToCursor( HINSTANCE hinstExe
, HICON hIcon
)
1136 FIXME("(%p,%p), partially implemented.\n",hinstExe
,hIcon
);
1137 /* FIXME: make an extended conversation from HICON to HCURSOR */
1138 return CopyCursor(hIcon
);
1141 /***********************************************************************
1142 * GetAltMonthNames (OLEAUT32.@)
1144 HRESULT WINAPI
GetAltMonthNames(LCID lcid
, LPOLESTR
**str
)
1146 static const WCHAR ar_month1W
[] = {0x645,0x62d,0x631,0x645,0};
1147 static const WCHAR ar_month2W
[] = {0x635,0x641,0x631,0};
1148 static const WCHAR ar_month3W
[] = {0x631,0x628,0x64a,0x639,' ',0x627,0x644,0x627,0x648,0x644,0};
1149 static const WCHAR ar_month4W
[] = {0x631,0x628,0x64a,0x639,' ',0x627,0x644,0x62b,0x627,0x646,0x64a,0};
1150 static const WCHAR ar_month5W
[] = {0x62c,0x645,0x627,0x62f,0x649,' ',0x627,0x644,0x627,0x648,0x644,0x649,0};
1151 static const WCHAR ar_month6W
[] = {0x62c,0x645,0x627,0x62f,0x649,' ',0x627,0x644,0x62b,0x627,0x646,0x64a,0x629,0};
1152 static const WCHAR ar_month7W
[] = {0x631,0x62c,0x628,0};
1153 static const WCHAR ar_month8W
[] = {0x634,0x639,0x628,0x627,0x646,0};
1154 static const WCHAR ar_month9W
[] = {0x631,0x645,0x636,0x627,0x646,0};
1155 static const WCHAR ar_month10W
[] = {0x634,0x648,0x627,0x643,0};
1156 static const WCHAR ar_month11W
[] = {0x630,0x648,' ',0x627,0x644,0x642,0x639,0x62f,0x629,0};
1157 static const WCHAR ar_month12W
[] = {0x630,0x648,' ',0x627,0x644,0x62d,0x62c,0x629,0};
1159 static const WCHAR
*arabic_hijri
[] =
1176 static const WCHAR pl_month1W
[] = {'s','t','y','c','z','n','i','a',0};
1177 static const WCHAR pl_month2W
[] = {'l','u','t','e','g','o',0};
1178 static const WCHAR pl_month3W
[] = {'m','a','r','c','a',0};
1179 static const WCHAR pl_month4W
[] = {'k','w','i','e','t','n','i','a',0};
1180 static const WCHAR pl_month5W
[] = {'m','a','j','a',0};
1181 static const WCHAR pl_month6W
[] = {'c','z','e','r','w','c','a',0};
1182 static const WCHAR pl_month7W
[] = {'l','i','p','c','a',0};
1183 static const WCHAR pl_month8W
[] = {'s','i','e','r','p','n','i','a',0};
1184 static const WCHAR pl_month9W
[] = {'w','r','z','e',0x15b,'n','i','a',0};
1185 static const WCHAR pl_month10W
[] = {'p','a',0x17a,'d','z','i','e','r','n','i','k','a',0};
1186 static const WCHAR pl_month11W
[] = {'l','i','s','t','o','p','a','d','a',0};
1187 static const WCHAR pl_month12W
[] = {'g','r','u','d','n','i','a',0};
1189 static const WCHAR
*polish_genitive_names
[] =
1206 static const WCHAR ru_month1W
[] = {0x44f,0x43d,0x432,0x430,0x440,0x44f,0};
1207 static const WCHAR ru_month2W
[] = {0x444,0x435,0x432,0x440,0x430,0x43b,0x44f,0};
1208 static const WCHAR ru_month3W
[] = {0x43c,0x430,0x440,0x442,0x430,0};
1209 static const WCHAR ru_month4W
[] = {0x430,0x43f,0x440,0x435,0x43b,0x44f,0};
1210 static const WCHAR ru_month5W
[] = {0x43c,0x430,0x44f,0};
1211 static const WCHAR ru_month6W
[] = {0x438,0x44e,0x43d,0x44f,0};
1212 static const WCHAR ru_month7W
[] = {0x438,0x44e,0x43b,0x44f,0};
1213 static const WCHAR ru_month8W
[] = {0x430,0x432,0x433,0x443,0x441,0x442,0x430,0};
1214 static const WCHAR ru_month9W
[] = {0x441,0x435,0x43d,0x442,0x44f,0x431,0x440,0x44f,0};
1215 static const WCHAR ru_month10W
[] = {0x43e,0x43a,0x442,0x44f,0x431,0x440,0x44f,0};
1216 static const WCHAR ru_month11W
[] = {0x43d,0x43e,0x44f,0x431,0x440,0x44f,0};
1217 static const WCHAR ru_month12W
[] = {0x434,0x435,0x43a,0x430,0x431,0x440,0x44f,0};
1219 static const WCHAR
*russian_genitive_names
[] =
1236 TRACE("%#x, %p\n", lcid
, str
);
1238 if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_ARABIC
)
1239 *str
= (LPOLESTR
*)arabic_hijri
;
1240 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_POLISH
)
1241 *str
= (LPOLESTR
*)polish_genitive_names
;
1242 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_RUSSIAN
)
1243 *str
= (LPOLESTR
*)russian_genitive_names
;