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");
877 sprintf(typelibkey
, "Typelib\\%s\\%s\\0\\win%u", tlguid
, ver
, sizeof(void *) == 8 ? 64 : 32);
879 snprintf(typelibkey
, sizeof(typelibkey
), "Typelib\\%s\\%s\\0\\win%u", tlguid
, ver
, sizeof(void *) == 8 ? 64 : 32);
880 #endif // __REACTOS__
881 tlfnlen
= sizeof(tlfn
);
882 if (RegQueryValueA(HKEY_CLASSES_ROOT
, typelibkey
, tlfn
, &tlfnlen
))
885 sprintf(typelibkey
, "Typelib\\%s\\%s\\0\\win32", tlguid
, ver
);
886 tlfnlen
= sizeof(tlfn
);
887 if (RegQueryValueA(HKEY_CLASSES_ROOT
, typelibkey
, tlfn
, &tlfnlen
))
890 ERR("Could not get typelib fn?\n");
896 MultiByteToWideChar(CP_ACP
, 0, tlfn
, -1, module
, len
);
900 static HRESULT
get_typeinfo_for_iid(REFIID iid
, ITypeInfo
**typeinfo
)
902 WCHAR module
[MAX_PATH
];
909 if (!actctx_get_typelib_module(iid
, module
, ARRAY_SIZE(module
)))
911 hr
= reg_get_typelib_module(iid
, module
, ARRAY_SIZE(module
));
916 hr
= LoadTypeLib(module
, &typelib
);
918 ERR("Failed to load typelib for %s, but it should be there.\n", debugstr_guid(iid
));
922 hr
= ITypeLib_GetTypeInfoOfGuid(typelib
, iid
, typeinfo
);
923 ITypeLib_Release(typelib
);
925 ERR("typelib does not contain info for %s\n", debugstr_guid(iid
));
930 static HRESULT WINAPI
typelib_ps_QueryInterface(IPSFactoryBuffer
*iface
, REFIID iid
, void **out
)
932 if (IsEqualIID(iid
, &IID_IPSFactoryBuffer
) || IsEqualIID(iid
, &IID_IUnknown
))
938 FIXME("No interface for %s.\n", debugstr_guid(iid
));
940 return E_NOINTERFACE
;
943 static ULONG WINAPI
typelib_ps_AddRef(IPSFactoryBuffer
*iface
)
948 static ULONG WINAPI
typelib_ps_Release(IPSFactoryBuffer
*iface
)
953 static HRESULT WINAPI
typelib_ps_CreateProxy(IPSFactoryBuffer
*iface
,
954 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **out
)
959 hr
= get_typeinfo_for_iid(iid
, &typeinfo
);
960 if (FAILED(hr
)) return hr
;
962 hr
= CreateProxyFromTypeInfo(typeinfo
, outer
, iid
, proxy
, out
);
964 ERR("Failed to create proxy, hr %#x.\n", hr
);
966 ITypeInfo_Release(typeinfo
);
970 static HRESULT WINAPI
typelib_ps_CreateStub(IPSFactoryBuffer
*iface
, REFIID iid
,
971 IUnknown
*server
, IRpcStubBuffer
**stub
)
976 hr
= get_typeinfo_for_iid(iid
, &typeinfo
);
977 if (FAILED(hr
)) return hr
;
979 hr
= CreateStubFromTypeInfo(typeinfo
, iid
, server
, stub
);
981 ERR("Failed to create stub, hr %#x.\n", hr
);
983 ITypeInfo_Release(typeinfo
);
987 static const IPSFactoryBufferVtbl typelib_ps_vtbl
=
989 typelib_ps_QueryInterface
,
992 typelib_ps_CreateProxy
,
993 typelib_ps_CreateStub
,
996 static IPSFactoryBuffer typelib_ps
= { &typelib_ps_vtbl
};
998 extern void _get_STDFONT_CF(LPVOID
*);
999 extern void _get_STDPIC_CF(LPVOID
*);
1001 static HRESULT WINAPI
PSDispatchFacBuf_QueryInterface(IPSFactoryBuffer
*iface
, REFIID riid
, void **ppv
)
1003 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1004 IsEqualIID(riid
, &IID_IPSFactoryBuffer
))
1006 IPSFactoryBuffer_AddRef(iface
);
1010 return E_NOINTERFACE
;
1013 static ULONG WINAPI
PSDispatchFacBuf_AddRef(IPSFactoryBuffer
*iface
)
1018 static ULONG WINAPI
PSDispatchFacBuf_Release(IPSFactoryBuffer
*iface
)
1023 static HRESULT WINAPI
PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer
*iface
,
1024 IUnknown
*outer
, REFIID iid
, IRpcProxyBuffer
**proxy
, void **obj
)
1026 IPSFactoryBuffer
*factory
;
1029 if (IsEqualIID(iid
, &IID_IDispatch
))
1031 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&factory
);
1032 if (FAILED(hr
)) return hr
;
1034 hr
= IPSFactoryBuffer_CreateProxy(factory
, outer
, iid
, proxy
, obj
);
1035 IPSFactoryBuffer_Release(factory
);
1039 return IPSFactoryBuffer_CreateProxy(&typelib_ps
, outer
, iid
, proxy
, obj
);
1042 static HRESULT WINAPI
PSDispatchFacBuf_CreateStub(IPSFactoryBuffer
*iface
,
1043 REFIID iid
, IUnknown
*server
, IRpcStubBuffer
**stub
)
1045 IPSFactoryBuffer
*factory
;
1048 if (IsEqualIID(iid
, &IID_IDispatch
))
1050 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&factory
);
1051 if (FAILED(hr
)) return hr
;
1053 hr
= IPSFactoryBuffer_CreateStub(factory
, iid
, server
, stub
);
1054 IPSFactoryBuffer_Release(factory
);
1058 return IPSFactoryBuffer_CreateStub(&typelib_ps
, iid
, server
, stub
);
1061 static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl
=
1063 PSDispatchFacBuf_QueryInterface
,
1064 PSDispatchFacBuf_AddRef
,
1065 PSDispatchFacBuf_Release
,
1066 PSDispatchFacBuf_CreateProxy
,
1067 PSDispatchFacBuf_CreateStub
1070 /* This is the whole PSFactoryBuffer object, just the vtableptr */
1071 static const IPSFactoryBufferVtbl
*pPSDispatchFacBuf
= &PSDispatchFacBuf_Vtbl
;
1073 /***********************************************************************
1074 * DllGetClassObject (OLEAUT32.@)
1076 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID iid
, LPVOID
*ppv
)
1079 if (IsEqualGUID(rclsid
,&CLSID_StdFont
)) {
1080 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
1081 _get_STDFONT_CF(ppv
);
1082 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1086 if (IsEqualGUID(rclsid
,&CLSID_StdPicture
)) {
1087 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
1088 _get_STDPIC_CF(ppv
);
1089 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1093 if (IsEqualCLSID(rclsid
, &CLSID_PSDispatch
) && IsEqualIID(iid
, &IID_IPSFactoryBuffer
)) {
1094 *ppv
= &pPSDispatchFacBuf
;
1095 IPSFactoryBuffer_AddRef((IPSFactoryBuffer
*)*ppv
);
1099 if (IsEqualGUID(rclsid
, &CLSID_PSOAInterface
))
1100 return IPSFactoryBuffer_QueryInterface(&typelib_ps
, iid
, ppv
);
1102 if (IsEqualCLSID(rclsid
, &CLSID_PSTypeComp
) ||
1103 IsEqualCLSID(rclsid
, &CLSID_PSTypeInfo
) ||
1104 IsEqualCLSID(rclsid
, &CLSID_PSTypeLib
) ||
1105 IsEqualCLSID(rclsid
, &CLSID_PSDispatch
) ||
1106 IsEqualCLSID(rclsid
, &CLSID_PSEnumVariant
))
1107 return OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, iid
, ppv
);
1109 return OLEAUTPS_DllGetClassObject(rclsid
, iid
, ppv
);
1112 /***********************************************************************
1113 * DllCanUnloadNow (OLEAUT32.@)
1115 * Determine if this dll can be unloaded from the callers address space.
1121 * Always returns S_FALSE. This dll cannot be unloaded.
1123 HRESULT WINAPI
DllCanUnloadNow(void)
1128 /*****************************************************************************
1129 * DllMain [OLEAUT32.@]
1131 BOOL WINAPI
DllMain(HINSTANCE hInstDll
, DWORD fdwReason
, LPVOID lpvReserved
)
1133 static const WCHAR oanocacheW
[] = {'o','a','n','o','c','a','c','h','e',0};
1135 if(fdwReason
== DLL_PROCESS_ATTACH
)
1136 bstr_cache_enabled
= !GetEnvironmentVariableW(oanocacheW
, NULL
, 0);
1138 return OLEAUTPS_DllMain( hInstDll
, fdwReason
, lpvReserved
);
1141 /***********************************************************************
1142 * DllRegisterServer (OLEAUT32.@)
1144 HRESULT WINAPI
DllRegisterServer(void)
1146 return OLEAUTPS_DllRegisterServer();
1149 /***********************************************************************
1150 * DllUnregisterServer (OLEAUT32.@)
1152 HRESULT WINAPI
DllUnregisterServer(void)
1154 return OLEAUTPS_DllUnregisterServer();
1157 /***********************************************************************
1158 * OleIconToCursor (OLEAUT32.415)
1160 HCURSOR WINAPI
OleIconToCursor( HINSTANCE hinstExe
, HICON hIcon
)
1162 FIXME("(%p,%p), partially implemented.\n",hinstExe
,hIcon
);
1163 /* FIXME: make an extended conversation from HICON to HCURSOR */
1164 return CopyCursor(hIcon
);
1167 /***********************************************************************
1168 * GetAltMonthNames (OLEAUT32.@)
1170 HRESULT WINAPI
GetAltMonthNames(LCID lcid
, LPOLESTR
**str
)
1172 static const WCHAR ar_month1W
[] = {0x645,0x62d,0x631,0x645,0};
1173 static const WCHAR ar_month2W
[] = {0x635,0x641,0x631,0};
1174 static const WCHAR ar_month3W
[] = {0x631,0x628,0x64a,0x639,' ',0x627,0x644,0x627,0x648,0x644,0};
1175 static const WCHAR ar_month4W
[] = {0x631,0x628,0x64a,0x639,' ',0x627,0x644,0x62b,0x627,0x646,0x64a,0};
1176 static const WCHAR ar_month5W
[] = {0x62c,0x645,0x627,0x62f,0x649,' ',0x627,0x644,0x627,0x648,0x644,0x649,0};
1177 static const WCHAR ar_month6W
[] = {0x62c,0x645,0x627,0x62f,0x649,' ',0x627,0x644,0x62b,0x627,0x646,0x64a,0x629,0};
1178 static const WCHAR ar_month7W
[] = {0x631,0x62c,0x628,0};
1179 static const WCHAR ar_month8W
[] = {0x634,0x639,0x628,0x627,0x646,0};
1180 static const WCHAR ar_month9W
[] = {0x631,0x645,0x636,0x627,0x646,0};
1181 static const WCHAR ar_month10W
[] = {0x634,0x648,0x627,0x643,0};
1182 static const WCHAR ar_month11W
[] = {0x630,0x648,' ',0x627,0x644,0x642,0x639,0x62f,0x629,0};
1183 static const WCHAR ar_month12W
[] = {0x630,0x648,' ',0x627,0x644,0x62d,0x62c,0x629,0};
1185 static const WCHAR
*arabic_hijri
[] =
1202 static const WCHAR pl_month1W
[] = {'s','t','y','c','z','n','i','a',0};
1203 static const WCHAR pl_month2W
[] = {'l','u','t','e','g','o',0};
1204 static const WCHAR pl_month3W
[] = {'m','a','r','c','a',0};
1205 static const WCHAR pl_month4W
[] = {'k','w','i','e','t','n','i','a',0};
1206 static const WCHAR pl_month5W
[] = {'m','a','j','a',0};
1207 static const WCHAR pl_month6W
[] = {'c','z','e','r','w','c','a',0};
1208 static const WCHAR pl_month7W
[] = {'l','i','p','c','a',0};
1209 static const WCHAR pl_month8W
[] = {'s','i','e','r','p','n','i','a',0};
1210 static const WCHAR pl_month9W
[] = {'w','r','z','e',0x15b,'n','i','a',0};
1211 static const WCHAR pl_month10W
[] = {'p','a',0x17a,'d','z','i','e','r','n','i','k','a',0};
1212 static const WCHAR pl_month11W
[] = {'l','i','s','t','o','p','a','d','a',0};
1213 static const WCHAR pl_month12W
[] = {'g','r','u','d','n','i','a',0};
1215 static const WCHAR
*polish_genitive_names
[] =
1232 static const WCHAR ru_month1W
[] = {0x44f,0x43d,0x432,0x430,0x440,0x44f,0};
1233 static const WCHAR ru_month2W
[] = {0x444,0x435,0x432,0x440,0x430,0x43b,0x44f,0};
1234 static const WCHAR ru_month3W
[] = {0x43c,0x430,0x440,0x442,0x430,0};
1235 static const WCHAR ru_month4W
[] = {0x430,0x43f,0x440,0x435,0x43b,0x44f,0};
1236 static const WCHAR ru_month5W
[] = {0x43c,0x430,0x44f,0};
1237 static const WCHAR ru_month6W
[] = {0x438,0x44e,0x43d,0x44f,0};
1238 static const WCHAR ru_month7W
[] = {0x438,0x44e,0x43b,0x44f,0};
1239 static const WCHAR ru_month8W
[] = {0x430,0x432,0x433,0x443,0x441,0x442,0x430,0};
1240 static const WCHAR ru_month9W
[] = {0x441,0x435,0x43d,0x442,0x44f,0x431,0x440,0x44f,0};
1241 static const WCHAR ru_month10W
[] = {0x43e,0x43a,0x442,0x44f,0x431,0x440,0x44f,0};
1242 static const WCHAR ru_month11W
[] = {0x43d,0x43e,0x44f,0x431,0x440,0x44f,0};
1243 static const WCHAR ru_month12W
[] = {0x434,0x435,0x43a,0x430,0x431,0x440,0x44f,0};
1245 static const WCHAR
*russian_genitive_names
[] =
1262 TRACE("%#x, %p\n", lcid
, str
);
1264 if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_ARABIC
)
1265 *str
= (LPOLESTR
*)arabic_hijri
;
1266 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_POLISH
)
1267 *str
= (LPOLESTR
*)polish_genitive_names
;
1268 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_RUSSIAN
)
1269 *str
= (LPOLESTR
*)russian_genitive_names
;