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
40 #include "oleaut32_oaidl.h"
42 #include "wine/debug.h"
43 #include "wine/unicode.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
46 WINE_DECLARE_DEBUG_CHANNEL(heap
);
48 /******************************************************************************
52 * BSTR is a simple typedef for a wide-character string used as the principle
53 * string type in ole automation. When encapsulated in a Variant type they are
54 * automatically copied and destroyed as the variant is processed.
56 * The low level BSTR API allows manipulation of these strings and is used by
57 * higher level API calls to manage the strings transparently to the caller.
59 * Internally the BSTR type is allocated with space for a DWORD byte count before
60 * the string data begins. This is undocumented and non-system code should not
61 * access the count directly. Use SysStringLen() or SysStringByteLen()
62 * instead. Note that the byte count does not include the terminating NUL.
64 * To create a new BSTR, use SysAllocString(), SysAllocStringLen() or
65 * SysAllocStringByteLen(). To change the size of an existing BSTR, use SysReAllocString()
66 * or SysReAllocStringLen(). Finally to destroy a string use SysFreeString().
68 * BSTR's are cached by Ole Automation by default. To override this behaviour
69 * either set the environment variable 'OANOCACHE', or call SetOaNoCache().
72 * 'Inside OLE, second edition' by Kraig Brockshmidt.
75 static BOOL bstr_cache_enabled
;
77 static CRITICAL_SECTION cs_bstr_cache
;
78 static CRITICAL_SECTION_DEBUG cs_bstr_cache_dbg
=
81 { &cs_bstr_cache_dbg
.ProcessLocksList
, &cs_bstr_cache_dbg
.ProcessLocksList
},
82 0, 0, { (DWORD_PTR
)(__FILE__
": bstr_cache") }
84 static CRITICAL_SECTION cs_bstr_cache
= { &cs_bstr_cache_dbg
, -1, 0, 0, 0, 0 };
98 #define BUCKET_SIZE 16
99 #define BUCKET_BUFFER_SIZE 6
104 bstr_t
*buf
[BUCKET_BUFFER_SIZE
];
105 } bstr_cache_entry_t
;
107 #define ARENA_INUSE_FILLER 0x55
108 #define ARENA_TAIL_FILLER 0xab
109 #define ARENA_FREE_FILLER 0xfeeefeee
111 static bstr_cache_entry_t bstr_cache
[0x10000/BUCKET_SIZE
];
113 static inline size_t bstr_alloc_size(size_t size
)
115 return (FIELD_OFFSET(bstr_t
, u
.ptr
[size
]) + sizeof(WCHAR
) + BUCKET_SIZE
-1) & ~(BUCKET_SIZE
-1);
118 static inline bstr_t
*bstr_from_str(BSTR str
)
120 return CONTAINING_RECORD(str
, bstr_t
, u
.str
);
123 static inline bstr_cache_entry_t
*get_cache_entry_from_idx(unsigned cache_idx
)
125 return bstr_cache_enabled
&& cache_idx
< ARRAY_SIZE(bstr_cache
) ? bstr_cache
+ cache_idx
: NULL
;
128 static inline bstr_cache_entry_t
*get_cache_entry(size_t size
)
130 unsigned cache_idx
= FIELD_OFFSET(bstr_t
, u
.ptr
[size
+sizeof(WCHAR
)-1])/BUCKET_SIZE
;
131 return get_cache_entry_from_idx(cache_idx
);
134 static inline bstr_cache_entry_t
*get_cache_entry_from_alloc_size(SIZE_T alloc_size
)
137 if (alloc_size
< BUCKET_SIZE
) return NULL
;
138 cache_idx
= (alloc_size
- BUCKET_SIZE
) / BUCKET_SIZE
;
139 return get_cache_entry_from_idx(cache_idx
);
142 static bstr_t
*alloc_bstr(size_t size
)
144 bstr_cache_entry_t
*cache_entry
= get_cache_entry(size
);
148 EnterCriticalSection(&cs_bstr_cache
);
150 if(!cache_entry
->cnt
) {
151 cache_entry
= get_cache_entry(size
+BUCKET_SIZE
);
152 if(cache_entry
&& !cache_entry
->cnt
)
157 ret
= cache_entry
->buf
[cache_entry
->head
++];
158 cache_entry
->head
%= BUCKET_BUFFER_SIZE
;
162 LeaveCriticalSection(&cs_bstr_cache
);
166 size_t fill_size
= (FIELD_OFFSET(bstr_t
, u
.ptr
[size
])+2*sizeof(WCHAR
)-1) & ~(sizeof(WCHAR
)-1);
167 memset(ret
, ARENA_INUSE_FILLER
, fill_size
);
168 memset((char *)ret
+fill_size
, ARENA_TAIL_FILLER
, bstr_alloc_size(size
)-fill_size
);
175 ret
= CoTaskMemAlloc(bstr_alloc_size(size
));
181 /******************************************************************************
182 * SysStringLen [OLEAUT32.7]
184 * Get the allocated length of a BSTR in wide characters.
187 * str [I] BSTR to find the length of
190 * The allocated length of str, or 0 if str is NULL.
194 * The returned length may be different from the length of the string as
195 * calculated by lstrlenW(), since it returns the length that was used to
196 * allocate the string by SysAllocStringLen().
198 UINT WINAPI
SysStringLen(BSTR str
)
200 return str
? bstr_from_str(str
)->size
/sizeof(WCHAR
) : 0;
203 /******************************************************************************
204 * SysStringByteLen [OLEAUT32.149]
206 * Get the allocated length of a BSTR in bytes.
209 * str [I] BSTR to find the length of
212 * The allocated length of str, or 0 if str is NULL.
215 * See SysStringLen(), BSTR().
217 UINT WINAPI
SysStringByteLen(BSTR str
)
219 return str
? bstr_from_str(str
)->size
: 0;
222 /******************************************************************************
223 * SysAllocString [OLEAUT32.2]
225 * Create a BSTR from an OLESTR.
228 * str [I] Source to create BSTR from
231 * Success: A BSTR allocated with SysAllocStringLen().
232 * Failure: NULL, if oleStr is NULL.
236 * MSDN (October 2001) incorrectly states that NULL is returned if oleStr has
237 * a length of 0. Native Win32 and this implementation both return a valid
238 * empty BSTR in this case.
240 BSTR WINAPI
SysAllocString(LPCOLESTR str
)
244 /* Delegate this to the SysAllocStringLen32 method. */
245 return SysAllocStringLen(str
, lstrlenW(str
));
248 static inline IMalloc
*get_malloc(void)
250 static IMalloc
*malloc
;
253 CoGetMalloc(1, &malloc
);
258 /******************************************************************************
259 * SysFreeString [OLEAUT32.6]
264 * str [I] BSTR to free.
271 * str may be NULL, in which case this function does nothing.
273 void WINAPI DECLSPEC_HOTPATCH
SysFreeString(BSTR str
)
275 bstr_cache_entry_t
*cache_entry
;
277 IMalloc
*malloc
= get_malloc();
283 bstr
= bstr_from_str(str
);
285 alloc_size
= IMalloc_GetSize(malloc
, bstr
);
286 if (alloc_size
== ~0UL)
289 cache_entry
= get_cache_entry_from_alloc_size(alloc_size
);
293 EnterCriticalSection(&cs_bstr_cache
);
295 /* According to tests, freeing a string that's already in cache doesn't corrupt anything.
296 * For that to work we need to search the cache. */
297 for(i
=0; i
< cache_entry
->cnt
; i
++) {
298 if(cache_entry
->buf
[(cache_entry
->head
+i
) % BUCKET_BUFFER_SIZE
] == bstr
) {
299 WARN_(heap
)("String already is in cache!\n");
300 LeaveCriticalSection(&cs_bstr_cache
);
305 if(cache_entry
->cnt
< ARRAY_SIZE(cache_entry
->buf
)) {
306 cache_entry
->buf
[(cache_entry
->head
+cache_entry
->cnt
) % BUCKET_BUFFER_SIZE
] = bstr
;
310 unsigned n
= (alloc_size
-FIELD_OFFSET(bstr_t
, u
.ptr
))/sizeof(DWORD
);
312 bstr
->u
.dwptr
[i
] = ARENA_FREE_FILLER
;
315 LeaveCriticalSection(&cs_bstr_cache
);
319 LeaveCriticalSection(&cs_bstr_cache
);
325 /******************************************************************************
326 * SysAllocStringLen [OLEAUT32.4]
328 * Create a BSTR from an OLESTR of a given wide character length.
331 * str [I] Source to create BSTR from
332 * len [I] Length of oleStr in wide characters
335 * Success: A newly allocated BSTR from SysAllocStringByteLen()
336 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
339 * See BSTR(), SysAllocStringByteLen().
341 BSTR WINAPI
SysAllocStringLen(const OLECHAR
*str
, unsigned int len
)
346 /* Detect integer overflow. */
347 if (len
>= ((UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
))/sizeof(WCHAR
)))
350 TRACE("%s\n", debugstr_wn(str
, len
));
352 size
= len
*sizeof(WCHAR
);
353 bstr
= alloc_bstr(size
);
358 memcpy(bstr
->u
.str
, str
, size
);
359 bstr
->u
.str
[len
] = 0;
361 memset(bstr
->u
.str
, 0, size
+sizeof(WCHAR
));
367 /******************************************************************************
368 * SysReAllocStringLen [OLEAUT32.5]
370 * Change the length of a previously created BSTR.
373 * old [O] BSTR to change the length of
374 * str [I] New source for pbstr
375 * len [I] Length of oleStr in wide characters
378 * Success: 1. The size of pbstr is updated.
379 * Failure: 0, if len >= 0x80000000 or memory allocation fails.
382 * See BSTR(), SysAllocStringByteLen().
383 * *old may be changed by this function.
385 int WINAPI
SysReAllocStringLen(BSTR
* old
, const OLECHAR
* str
, unsigned int len
)
387 /* Detect integer overflow. */
388 if (len
>= ((UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
))/sizeof(WCHAR
)))
392 DWORD newbytelen
= len
*sizeof(WCHAR
);
393 bstr_t
*old_bstr
= bstr_from_str(*old
);
394 bstr_t
*bstr
= CoTaskMemRealloc(old_bstr
, bstr_alloc_size(newbytelen
));
396 if (!bstr
) return FALSE
;
399 bstr
->size
= newbytelen
;
400 /* The old string data is still there when str is NULL */
401 if (str
&& old_bstr
->u
.str
!= str
) memmove(bstr
->u
.str
, str
, newbytelen
);
402 bstr
->u
.str
[len
] = 0;
404 *old
= SysAllocStringLen(str
, len
);
410 /******************************************************************************
411 * SysAllocStringByteLen [OLEAUT32.150]
413 * Create a BSTR from an OLESTR of a given byte length.
416 * str [I] Source to create BSTR from
417 * len [I] Length of oleStr in bytes
420 * Success: A newly allocated BSTR
421 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
424 * -If len is 0 or oleStr is NULL the resulting string is empty ("").
425 * -This function always NUL terminates the resulting BSTR.
426 * -oleStr may be either an LPCSTR or LPCOLESTR, since it is copied
427 * without checking for a terminating NUL.
430 BSTR WINAPI DECLSPEC_HOTPATCH
SysAllocStringByteLen(LPCSTR str
, UINT len
)
434 /* Detect integer overflow. */
435 if (len
>= (UINT_MAX
-sizeof(WCHAR
)-sizeof(DWORD
)))
438 bstr
= alloc_bstr(len
);
443 memcpy(bstr
->u
.ptr
, str
, len
);
444 bstr
->u
.ptr
[len
] = 0;
446 memset(bstr
->u
.ptr
, 0, len
+1);
448 bstr
->u
.str
[(len
+sizeof(WCHAR
)-1)/sizeof(WCHAR
)] = 0;
453 /******************************************************************************
454 * SysReAllocString [OLEAUT32.3]
456 * Change the length of a previously created BSTR.
459 * old [I/O] BSTR to change the length of
460 * str [I] New source for pbstr
467 * See BSTR(), SysAllocStringStringLen().
469 INT WINAPI
SysReAllocString(LPBSTR old
,LPCOLESTR str
)
478 * Make sure we free the old string.
483 * Allocate the new string
485 *old
= SysAllocString(str
);
490 /******************************************************************************
491 * SetOaNoCache (OLEAUT32.327)
493 * Instruct Ole Automation not to cache BSTR allocations.
502 * SetOaNoCache does not release cached strings, so it leaks by design.
504 void WINAPI
SetOaNoCache(void)
507 bstr_cache_enabled
= FALSE
;
510 static const WCHAR _delimiter
[] = {'!',0}; /* default delimiter apparently */
511 static const WCHAR
*pdelimiter
= &_delimiter
[0];
513 /***********************************************************************
514 * RegisterActiveObject (OLEAUT32.33)
516 * Registers an object in the global item table.
519 * punk [I] Object to register.
520 * rcid [I] CLSID of the object.
522 * pdwRegister [O] Address to store cookie of object registration in.
526 * Failure: HRESULT code.
528 HRESULT WINAPI DECLSPEC_HOTPATCH
RegisterActiveObject(
529 LPUNKNOWN punk
,REFCLSID rcid
,DWORD dwFlags
,LPDWORD pdwRegister
533 LPRUNNINGOBJECTTABLE runobtable
;
535 DWORD rot_flags
= ROTFLAGS_REGISTRATIONKEEPSALIVE
; /* default registration is strong */
537 StringFromGUID2(rcid
,guidbuf
,39);
538 ret
= CreateItemMoniker(pdelimiter
,guidbuf
,&moniker
);
541 ret
= GetRunningObjectTable(0,&runobtable
);
543 IMoniker_Release(moniker
);
546 if(dwFlags
== ACTIVEOBJECT_WEAK
)
548 ret
= IRunningObjectTable_Register(runobtable
,rot_flags
,punk
,moniker
,pdwRegister
);
549 IRunningObjectTable_Release(runobtable
);
550 IMoniker_Release(moniker
);
554 /***********************************************************************
555 * RevokeActiveObject (OLEAUT32.34)
557 * Revokes an object from the global item table.
560 * xregister [I] Registration cookie.
561 * reserved [I] Reserved. Set to NULL.
565 * Failure: HRESULT code.
567 HRESULT WINAPI DECLSPEC_HOTPATCH
RevokeActiveObject(DWORD xregister
,LPVOID reserved
)
569 LPRUNNINGOBJECTTABLE runobtable
;
572 ret
= GetRunningObjectTable(0,&runobtable
);
573 if (FAILED(ret
)) return ret
;
574 ret
= IRunningObjectTable_Revoke(runobtable
,xregister
);
575 if (SUCCEEDED(ret
)) ret
= S_OK
;
576 IRunningObjectTable_Release(runobtable
);
580 /***********************************************************************
581 * GetActiveObject (OLEAUT32.35)
583 * Gets an object from the global item table.
586 * rcid [I] CLSID of the object.
587 * preserved [I] Reserved. Set to NULL.
588 * ppunk [O] Address to store object into.
592 * Failure: HRESULT code.
594 HRESULT WINAPI DECLSPEC_HOTPATCH
GetActiveObject(REFCLSID rcid
,LPVOID preserved
,LPUNKNOWN
*ppunk
)
598 LPRUNNINGOBJECTTABLE runobtable
;
601 StringFromGUID2(rcid
,guidbuf
,39);
602 ret
= CreateItemMoniker(pdelimiter
,guidbuf
,&moniker
);
605 ret
= GetRunningObjectTable(0,&runobtable
);
607 IMoniker_Release(moniker
);
610 ret
= IRunningObjectTable_GetObject(runobtable
,moniker
,ppunk
);
611 IRunningObjectTable_Release(runobtable
);
612 IMoniker_Release(moniker
);
617 /***********************************************************************
618 * OaBuildVersion [OLEAUT32.170]
620 * Get the Ole Automation build version.
629 * Known oleaut32.dll versions:
630 *| OLE Ver. Comments Date Build Ver.
631 *| -------- ------------------------- ---- ---------
632 *| OLE 2.1 NT 1993-95 10 3023
634 *| Win32s Ver 1.1e 20 4049
635 *| OLE 2.20 W95/NT 1993-96 20 4112
636 *| OLE 2.20 W95/NT 1993-96 20 4118
637 *| OLE 2.20 W95/NT 1993-96 20 4122
638 *| OLE 2.30 W95/NT 1993-98 30 4265
639 *| OLE 2.40 NT?? 1993-98 40 4267
640 *| OLE 2.40 W98 SE orig. file 1993-98 40 4275
641 *| OLE 2.40 W2K orig. file 1993-XX 40 4514
643 * Currently the versions returned are 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
644 * and 2.40 for all later versions. The build number is maximum, i.e. 0xffff.
646 ULONG WINAPI
OaBuildVersion(void)
648 switch(GetVersion() & 0x8000ffff) /* mask off build number */
650 case 0x80000a03: /* WIN31 */
651 return MAKELONG(0xffff, 20);
652 case 0x00003303: /* NT351 */
653 return MAKELONG(0xffff, 30);
654 case 0x80000004: /* WIN95; I'd like to use the "standard" w95 minor
655 version here (30), but as we still use w95
656 as default winver (which is good IMHO), I better
657 play safe and use the latest value for w95 for now.
658 Change this as soon as default winver gets changed
659 to something more recent */
660 case 0x80000a04: /* WIN98 */
661 case 0x00000004: /* NT40 */
662 case 0x00000005: /* W2K */
663 return MAKELONG(0xffff, 40);
664 case 0x00000105: /* WinXP */
665 case 0x00000006: /* Vista */
666 case 0x00000106: /* Win7 */
667 return MAKELONG(0xffff, 50);
669 FIXME("Version value not known yet. Please investigate it !\n");
670 return MAKELONG(0xffff, 40); /* for now return the same value as for w2k */
674 /******************************************************************************
675 * OleTranslateColor [OLEAUT32.421]
677 * Convert an OLE_COLOR to a COLORREF.
680 * clr [I] Color to convert
681 * hpal [I] Handle to a palette for the conversion
682 * pColorRef [O] Destination for converted color, or NULL to test if the conversion is ok
685 * Success: S_OK. The conversion is ok, and pColorRef contains the converted color if non-NULL.
686 * Failure: E_INVALIDARG, if any argument is invalid.
689 * Document the conversion rules.
691 HRESULT WINAPI
OleTranslateColor(
697 BYTE b
= HIBYTE(HIWORD(clr
));
699 TRACE("(%08x, %p, %p)\n", clr
, hpal
, pColorRef
);
702 * In case pColorRef is NULL, provide our own to simplify the code.
704 if (pColorRef
== NULL
)
705 pColorRef
= &colorref
;
712 *pColorRef
= PALETTERGB(GetRValue(clr
),
727 * Validate the palette index.
729 if (GetPaletteEntries(hpal
, LOWORD(clr
), 1, &pe
) == 0)
744 int index
= LOBYTE(LOWORD(clr
));
747 * Validate GetSysColor index.
749 if ((index
< COLOR_SCROLLBAR
) || (index
> COLOR_MENUBAR
))
752 *pColorRef
= GetSysColor(index
);
764 extern HRESULT WINAPI
OLEAUTPS_DllGetClassObject(REFCLSID
, REFIID
, LPVOID
*) DECLSPEC_HIDDEN
;
765 extern BOOL WINAPI
OLEAUTPS_DllMain(HINSTANCE
, DWORD
, LPVOID
) DECLSPEC_HIDDEN
;
766 extern HRESULT WINAPI
OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN
;
767 extern HRESULT WINAPI
OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN
;
769 extern void _get_STDFONT_CF(LPVOID
*);
770 extern void _get_STDPIC_CF(LPVOID
*);
772 static HRESULT WINAPI
PSDispatchFacBuf_QueryInterface(IPSFactoryBuffer
*iface
, REFIID riid
, void **ppv
)
774 if (IsEqualIID(riid
, &IID_IUnknown
) ||
775 IsEqualIID(riid
, &IID_IPSFactoryBuffer
))
777 IPSFactoryBuffer_AddRef(iface
);
781 return E_NOINTERFACE
;
784 static ULONG WINAPI
PSDispatchFacBuf_AddRef(IPSFactoryBuffer
*iface
)
789 static ULONG WINAPI
PSDispatchFacBuf_Release(IPSFactoryBuffer
*iface
)
794 static HRESULT WINAPI
PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer
*iface
, IUnknown
*pUnkOuter
, REFIID riid
, IRpcProxyBuffer
**ppProxy
, void **ppv
)
796 IPSFactoryBuffer
*pPSFB
;
799 if (IsEqualIID(riid
, &IID_IDispatch
))
800 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&pPSFB
);
802 hr
= TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface
, &IID_IPSFactoryBuffer
, (void **)&pPSFB
);
804 if (FAILED(hr
)) return hr
;
806 hr
= IPSFactoryBuffer_CreateProxy(pPSFB
, pUnkOuter
, riid
, ppProxy
, ppv
);
808 IPSFactoryBuffer_Release(pPSFB
);
812 static HRESULT WINAPI
PSDispatchFacBuf_CreateStub(IPSFactoryBuffer
*iface
, REFIID riid
, IUnknown
*pUnkOuter
, IRpcStubBuffer
**ppStub
)
814 IPSFactoryBuffer
*pPSFB
;
817 if (IsEqualIID(riid
, &IID_IDispatch
))
818 hr
= OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, &IID_IPSFactoryBuffer
, (void **)&pPSFB
);
820 hr
= TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface
, &IID_IPSFactoryBuffer
, (void **)&pPSFB
);
822 if (FAILED(hr
)) return hr
;
824 hr
= IPSFactoryBuffer_CreateStub(pPSFB
, riid
, pUnkOuter
, ppStub
);
826 IPSFactoryBuffer_Release(pPSFB
);
830 static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl
=
832 PSDispatchFacBuf_QueryInterface
,
833 PSDispatchFacBuf_AddRef
,
834 PSDispatchFacBuf_Release
,
835 PSDispatchFacBuf_CreateProxy
,
836 PSDispatchFacBuf_CreateStub
839 /* This is the whole PSFactoryBuffer object, just the vtableptr */
840 static const IPSFactoryBufferVtbl
*pPSDispatchFacBuf
= &PSDispatchFacBuf_Vtbl
;
842 /***********************************************************************
843 * DllGetClassObject (OLEAUT32.@)
845 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID iid
, LPVOID
*ppv
)
848 if (IsEqualGUID(rclsid
,&CLSID_StdFont
)) {
849 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
850 _get_STDFONT_CF(ppv
);
851 IClassFactory_AddRef((IClassFactory
*)*ppv
);
855 if (IsEqualGUID(rclsid
,&CLSID_StdPicture
)) {
856 if (IsEqualGUID(iid
,&IID_IClassFactory
)) {
858 IClassFactory_AddRef((IClassFactory
*)*ppv
);
862 if (IsEqualCLSID(rclsid
, &CLSID_PSDispatch
) && IsEqualIID(iid
, &IID_IPSFactoryBuffer
)) {
863 *ppv
= &pPSDispatchFacBuf
;
864 IPSFactoryBuffer_AddRef((IPSFactoryBuffer
*)*ppv
);
867 if (IsEqualGUID(rclsid
,&CLSID_PSOAInterface
)) {
868 if (S_OK
==TMARSHAL_DllGetClassObject(rclsid
,iid
,ppv
))
872 if (IsEqualCLSID(rclsid
, &CLSID_PSTypeComp
) ||
873 IsEqualCLSID(rclsid
, &CLSID_PSTypeInfo
) ||
874 IsEqualCLSID(rclsid
, &CLSID_PSTypeLib
) ||
875 IsEqualCLSID(rclsid
, &CLSID_PSDispatch
) ||
876 IsEqualCLSID(rclsid
, &CLSID_PSEnumVariant
))
877 return OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer
, iid
, ppv
);
879 return OLEAUTPS_DllGetClassObject(rclsid
, iid
, ppv
);
882 /***********************************************************************
883 * DllCanUnloadNow (OLEAUT32.@)
885 * Determine if this dll can be unloaded from the callers address space.
891 * Always returns S_FALSE. This dll cannot be unloaded.
893 HRESULT WINAPI
DllCanUnloadNow(void)
898 /*****************************************************************************
899 * DllMain [OLEAUT32.@]
901 BOOL WINAPI
DllMain(HINSTANCE hInstDll
, DWORD fdwReason
, LPVOID lpvReserved
)
903 static const WCHAR oanocacheW
[] = {'o','a','n','o','c','a','c','h','e',0};
905 if(fdwReason
== DLL_PROCESS_ATTACH
)
906 bstr_cache_enabled
= !GetEnvironmentVariableW(oanocacheW
, NULL
, 0);
908 return OLEAUTPS_DllMain( hInstDll
, fdwReason
, lpvReserved
);
911 /***********************************************************************
912 * DllRegisterServer (OLEAUT32.@)
914 HRESULT WINAPI
DllRegisterServer(void)
916 return OLEAUTPS_DllRegisterServer();
919 /***********************************************************************
920 * DllUnregisterServer (OLEAUT32.@)
922 HRESULT WINAPI
DllUnregisterServer(void)
924 return OLEAUTPS_DllUnregisterServer();
927 /***********************************************************************
928 * OleIconToCursor (OLEAUT32.415)
930 HCURSOR WINAPI
OleIconToCursor( HINSTANCE hinstExe
, HICON hIcon
)
932 FIXME("(%p,%p), partially implemented.\n",hinstExe
,hIcon
);
933 /* FIXME: make an extended conversation from HICON to HCURSOR */
934 return CopyCursor(hIcon
);
937 /***********************************************************************
938 * GetAltMonthNames (OLEAUT32.@)
940 HRESULT WINAPI
GetAltMonthNames(LCID lcid
, LPOLESTR
**str
)
942 static const WCHAR ar_month1W
[] = {0x645,0x62d,0x631,0x645,0};
943 static const WCHAR ar_month2W
[] = {0x635,0x641,0x631,0};
944 static const WCHAR ar_month3W
[] = {0x631,0x628,0x64a,0x639,' ',0x627,0x644,0x627,0x648,0x644,0};
945 static const WCHAR ar_month4W
[] = {0x631,0x628,0x64a,0x639,' ',0x627,0x644,0x62b,0x627,0x646,0x64a,0};
946 static const WCHAR ar_month5W
[] = {0x62c,0x645,0x627,0x62f,0x649,' ',0x627,0x644,0x627,0x648,0x644,0x649,0};
947 static const WCHAR ar_month6W
[] = {0x62c,0x645,0x627,0x62f,0x649,' ',0x627,0x644,0x62b,0x627,0x646,0x64a,0x629,0};
948 static const WCHAR ar_month7W
[] = {0x631,0x62c,0x628,0};
949 static const WCHAR ar_month8W
[] = {0x634,0x639,0x628,0x627,0x646,0};
950 static const WCHAR ar_month9W
[] = {0x631,0x645,0x636,0x627,0x646,0};
951 static const WCHAR ar_month10W
[] = {0x634,0x648,0x627,0x643,0};
952 static const WCHAR ar_month11W
[] = {0x630,0x648,' ',0x627,0x644,0x642,0x639,0x62f,0x629,0};
953 static const WCHAR ar_month12W
[] = {0x630,0x648,' ',0x627,0x644,0x62d,0x62c,0x629,0};
955 static const WCHAR
*arabic_hijri
[] =
972 static const WCHAR pl_month1W
[] = {'s','t','y','c','z','n','i','a',0};
973 static const WCHAR pl_month2W
[] = {'l','u','t','e','g','o',0};
974 static const WCHAR pl_month3W
[] = {'m','a','r','c','a',0};
975 static const WCHAR pl_month4W
[] = {'k','w','i','e','t','n','i','a',0};
976 static const WCHAR pl_month5W
[] = {'m','a','j','a',0};
977 static const WCHAR pl_month6W
[] = {'c','z','e','r','w','c','a',0};
978 static const WCHAR pl_month7W
[] = {'l','i','p','c','a',0};
979 static const WCHAR pl_month8W
[] = {'s','i','e','r','p','n','i','a',0};
980 static const WCHAR pl_month9W
[] = {'w','r','z','e',0x15b,'n','i','a',0};
981 static const WCHAR pl_month10W
[] = {'p','a',0x17a,'d','z','i','e','r','n','i','k','a',0};
982 static const WCHAR pl_month11W
[] = {'l','i','s','t','o','p','a','d','a',0};
983 static const WCHAR pl_month12W
[] = {'g','r','u','d','n','i','a',0};
985 static const WCHAR
*polish_genitive_names
[] =
1002 static const WCHAR ru_month1W
[] = {0x44f,0x43d,0x432,0x430,0x440,0x44f,0};
1003 static const WCHAR ru_month2W
[] = {0x444,0x435,0x432,0x440,0x430,0x43b,0x44f,0};
1004 static const WCHAR ru_month3W
[] = {0x43c,0x430,0x440,0x442,0x430,0};
1005 static const WCHAR ru_month4W
[] = {0x430,0x43f,0x440,0x435,0x43b,0x44f,0};
1006 static const WCHAR ru_month5W
[] = {0x43c,0x430,0x44f,0};
1007 static const WCHAR ru_month6W
[] = {0x438,0x44e,0x43d,0x44f,0};
1008 static const WCHAR ru_month7W
[] = {0x438,0x44e,0x43b,0x44f,0};
1009 static const WCHAR ru_month8W
[] = {0x430,0x432,0x433,0x443,0x441,0x442,0x430,0};
1010 static const WCHAR ru_month9W
[] = {0x441,0x435,0x43d,0x442,0x44f,0x431,0x440,0x44f,0};
1011 static const WCHAR ru_month10W
[] = {0x43e,0x43a,0x442,0x44f,0x431,0x440,0x44f,0};
1012 static const WCHAR ru_month11W
[] = {0x43d,0x43e,0x44f,0x431,0x440,0x44f,0};
1013 static const WCHAR ru_month12W
[] = {0x434,0x435,0x43a,0x430,0x431,0x440,0x44f,0};
1015 static const WCHAR
*russian_genitive_names
[] =
1032 TRACE("%#x, %p\n", lcid
, str
);
1034 if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_ARABIC
)
1035 *str
= (LPOLESTR
*)arabic_hijri
;
1036 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_POLISH
)
1037 *str
= (LPOLESTR
*)polish_genitive_names
;
1038 else if (PRIMARYLANGID(LANGIDFROMLCID(lcid
)) == LANG_RUSSIAN
)
1039 *str
= (LPOLESTR
*)russian_genitive_names
;