diff --git a/reactos/dll/win32/oleaut32/CMakeLists.txt b/reactos/dll/win32/oleaut32/CMakeLists.txt index 138fbe01bbe..5c3621c6c35 100644 --- a/reactos/dll/win32/oleaut32/CMakeLists.txt +++ b/reactos/dll/win32/oleaut32/CMakeLists.txt @@ -2,19 +2,16 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_definitions(-DPROXY_CLSID_IS="{0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}}") - add_definitions( -D__WINESRC__ -DCOM_NO_WINDOWS_H -D_OLEAUT32_ -DPROXY_DELEGATION - -DREGISTER_PROXY_DLL - -DENTRY_PREFIX=OLEAUTPS_) + -DWINE_REGISTER_DLL + -DENTRY_PREFIX=OLEAUTPS_ + -DPROXY_CLSID=CLSID_PSFactoryBuffer) -include_directories( - ${REACTOS_SOURCE_DIR}/include/reactos/libs/libjpeg - ${REACTOS_SOURCE_DIR}/include/reactos/wine) +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) spec2def(oleaut32.dll oleaut32.spec ADD_IMPORTLIB) @@ -27,14 +24,12 @@ list(APPEND SOURCE oleaut.c olefont.c olepicture.c + olepropframe.c recinfo.c - regsvr.c safearray.c - stubs.c tmarshal.c typelib.c typelib2.c - ungif.c usrmarshal.c varformat.c variant.c @@ -51,15 +46,10 @@ if(MSVC) endif() add_library(oleaut32 SHARED ${SOURCE}) +add_idl_headers(oleaut32_idlheader oleaut32_oaidl.idl) +add_dependencies(oleaut32 oleaut32_idlheader) set_module_type(oleaut32 win32dll) - -target_link_libraries(oleaut32 - wine - wineldr - uuid - ${PSEH_LIB}) - +target_link_libraries(oleaut32 wine wineldr uuid ${PSEH_LIB}) add_delay_importlibs(oleaut32 comctl32 urlmon windowscodecs) add_importlibs(oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET oleaut32 DESTINATION reactos/system32 FOR all) - diff --git a/reactos/dll/win32/oleaut32/connpt.c b/reactos/dll/win32/oleaut32/connpt.c index 94e8e7cd2a5..59768a02982 100644 --- a/reactos/dll/win32/oleaut32/connpt.c +++ b/reactos/dll/win32/oleaut32/connpt.c @@ -48,7 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); */ typedef struct ConnectionPointImpl { - const IConnectionPointVtbl *lpvtbl; + IConnectionPoint IConnectionPoint_iface; /* IUnknown of our main object*/ IUnknown *Obj; @@ -74,7 +74,7 @@ static const IConnectionPointVtbl ConnectionPointImpl_VTable; */ typedef struct EnumConnectionsImpl { - const IEnumConnectionsVtbl *lpvtbl; + IEnumConnections IEnumConnections_iface; LONG ref; @@ -94,6 +94,15 @@ static EnumConnectionsImpl *EnumConnectionsImpl_Construct(IUnknown *pUnk, DWORD nSinks, CONNECTDATA *pCD); +static inline ConnectionPointImpl *impl_from_IConnectionPoint(IConnectionPoint *iface) +{ + return CONTAINING_RECORD(iface, ConnectionPointImpl, IConnectionPoint_iface); +} + +static inline EnumConnectionsImpl *impl_from_IEnumConnections(IEnumConnections *iface) +{ + return CONTAINING_RECORD(iface, EnumConnectionsImpl, IEnumConnections_iface); +} /************************************************************************ * ConnectionPointImpl_Construct @@ -104,7 +113,7 @@ static ConnectionPointImpl *ConnectionPointImpl_Construct(IUnknown *pUnk, ConnectionPointImpl *Obj; Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj)); - Obj->lpvtbl = &ConnectionPointImpl_VTable; + Obj->IConnectionPoint_iface.lpVtbl = &ConnectionPointImpl_VTable; Obj->Obj = pUnk; Obj->ref = 1; Obj->iid = *riid; @@ -143,7 +152,7 @@ static HRESULT WINAPI ConnectionPointImpl_QueryInterface( REFIID riid, void** ppvObject) { - ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); /* @@ -178,7 +187,7 @@ static HRESULT WINAPI ConnectionPointImpl_QueryInterface( * Query Interface always increases the reference count by one when it is * successful */ - ConnectionPointImpl_AddRef((IConnectionPoint*)This); + ConnectionPointImpl_AddRef(&This->IConnectionPoint_iface); return S_OK; } @@ -191,7 +200,7 @@ static HRESULT WINAPI ConnectionPointImpl_QueryInterface( */ static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface) { - ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before=%d)\n", This, refCount - 1); @@ -207,7 +216,7 @@ static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface) static ULONG WINAPI ConnectionPointImpl_Release( IConnectionPoint* iface) { - ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before=%d)\n", This, refCount + 1); @@ -228,7 +237,7 @@ static HRESULT WINAPI ConnectionPointImpl_GetConnectionInterface( IConnectionPoint *iface, IID *piid) { - ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); TRACE("(%p)->(%p) returning %s\n", This, piid, debugstr_guid(&(This->iid))); *piid = This->iid; return S_OK; @@ -242,7 +251,7 @@ static HRESULT WINAPI ConnectionPointImpl_GetConnectionPointContainer( IConnectionPoint *iface, IConnectionPointContainer **ppCPC) { - ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); TRACE("(%p)->(%p)\n", This, ppCPC); return IUnknown_QueryInterface(This->Obj, @@ -259,7 +268,7 @@ static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface, DWORD *pdwCookie) { DWORD i; - ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); IUnknown *lpSink; TRACE("(%p)->(%p, %p)\n", This, lpUnk, pdwCookie); @@ -290,7 +299,7 @@ static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface, static HRESULT WINAPI ConnectionPointImpl_Unadvise(IConnectionPoint *iface, DWORD dwCookie) { - ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); TRACE("(%p)->(%d)\n", This, dwCookie); if(dwCookie == 0 || dwCookie > This->maxSinks) return E_INVALIDARG; @@ -311,7 +320,7 @@ static HRESULT WINAPI ConnectionPointImpl_EnumConnections( IConnectionPoint *iface, LPENUMCONNECTIONS *ppEnum) { - ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ConnectionPointImpl *This = impl_from_IConnectionPoint(iface); CONNECTDATA *pCD; DWORD i, nextslot; EnumConnectionsImpl *EnumObj; @@ -339,9 +348,9 @@ static HRESULT WINAPI ConnectionPointImpl_EnumConnections( IUnknown_AddRef((IUnknown*)This); EnumObj = EnumConnectionsImpl_Construct((IUnknown*)This, This->nSinks, pCD); - hr = IEnumConnections_QueryInterface((IEnumConnections*)EnumObj, + hr = IEnumConnections_QueryInterface(&EnumObj->IEnumConnections_iface, &IID_IEnumConnections, (LPVOID)ppEnum); - IEnumConnections_Release((IEnumConnections*)EnumObj); + IEnumConnections_Release(&EnumObj->IEnumConnections_iface); HeapFree(GetProcessHeap(), 0, pCD); return hr; @@ -373,7 +382,7 @@ static EnumConnectionsImpl *EnumConnectionsImpl_Construct(IUnknown *pUnk, EnumConnectionsImpl *Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj)); DWORD i; - Obj->lpvtbl = &EnumConnectionsImpl_VTable; + Obj->IEnumConnections_iface.lpVtbl = &EnumConnectionsImpl_VTable; Obj->ref = 1; Obj->pUnk = pUnk; Obj->pCD = HeapAlloc(GetProcessHeap(), 0, nSinks * sizeof(CONNECTDATA)); @@ -460,7 +469,7 @@ static HRESULT WINAPI EnumConnectionsImpl_QueryInterface( */ static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface) { - EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + EnumConnectionsImpl *This = impl_from_IEnumConnections(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before=%d)\n", This, refCount - 1); @@ -476,7 +485,7 @@ static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface) */ static ULONG WINAPI EnumConnectionsImpl_Release(IEnumConnections* iface) { - EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + EnumConnectionsImpl *This = impl_from_IEnumConnections(iface); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before=%d)\n", This, refCount + 1); @@ -499,7 +508,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections* iface, ULONG cConn, LPCONNECTDATA pCD, ULONG *pEnum) { - EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + EnumConnectionsImpl *This = impl_from_IEnumConnections(iface); DWORD nRet = 0; TRACE("(%p)->(%d, %p, %p)\n", This, cConn, pCD, pEnum); @@ -534,7 +543,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections* iface, static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections* iface, ULONG cSkip) { - EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + EnumConnectionsImpl *This = impl_from_IEnumConnections(iface); TRACE("(%p)->(%d)\n", This, cSkip); if(This->nCur + cSkip >= This->nConns) @@ -552,7 +561,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections* iface, */ static HRESULT WINAPI EnumConnectionsImpl_Reset(IEnumConnections* iface) { - EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + EnumConnectionsImpl *This = impl_from_IEnumConnections(iface); TRACE("(%p)\n", This); This->nCur = 0; @@ -568,7 +577,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Reset(IEnumConnections* iface) static HRESULT WINAPI EnumConnectionsImpl_Clone(IEnumConnections* iface, LPENUMCONNECTIONS *ppEnum) { - EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + EnumConnectionsImpl *This = impl_from_IEnumConnections(iface); EnumConnectionsImpl *newObj; TRACE("(%p)->(%p)\n", This, ppEnum); @@ -613,8 +622,8 @@ HRESULT CreateConnectionPoint(IUnknown *pUnk, REFIID riid, Obj = ConnectionPointImpl_Construct(pUnk, riid); if(!Obj) return E_OUTOFMEMORY; - hr = IConnectionPoint_QueryInterface((IConnectionPoint *)Obj, + hr = IConnectionPoint_QueryInterface(&Obj->IConnectionPoint_iface, &IID_IConnectionPoint, (LPVOID)pCP); - IConnectionPoint_Release((IConnectionPoint *)Obj); + IConnectionPoint_Release(&Obj->IConnectionPoint_iface); return hr; } diff --git a/reactos/dll/win32/oleaut32/dispatch.c b/reactos/dll/win32/oleaut32/dispatch.c index ed3fad47019..760f8aaf305 100644 --- a/reactos/dll/win32/oleaut32/dispatch.c +++ b/reactos/dll/win32/oleaut32/dispatch.c @@ -232,12 +232,17 @@ HRESULT WINAPI CreateStdDispatch( typedef struct { - const IDispatchVtbl *lpVtbl; + IDispatch IDispatch_iface; void * pvThis; ITypeInfo * pTypeInfo; LONG ref; } StdDispatch; +static inline StdDispatch *impl_from_IDispatch(IDispatch *iface) +{ + return CONTAINING_RECORD(iface, StdDispatch, IDispatch_iface); +} + /****************************************************************************** * IDispatch_QueryInterface {OLEAUT32} * @@ -248,7 +253,7 @@ static HRESULT WINAPI StdDispatch_QueryInterface( REFIID riid, void** ppvObject) { - StdDispatch *This = (StdDispatch *)iface; + StdDispatch *This = impl_from_IDispatch(iface); TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject); if (IsEqualIID(riid, &IID_IDispatch) || @@ -268,7 +273,7 @@ static HRESULT WINAPI StdDispatch_QueryInterface( */ static ULONG WINAPI StdDispatch_AddRef(LPDISPATCH iface) { - StdDispatch *This = (StdDispatch *)iface; + StdDispatch *This = impl_from_IDispatch(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); @@ -283,7 +288,7 @@ static ULONG WINAPI StdDispatch_AddRef(LPDISPATCH iface) */ static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface) { - StdDispatch *This = (StdDispatch *)iface; + StdDispatch *This = impl_from_IDispatch(iface); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before=%u)\n", This, refCount + 1); @@ -316,7 +321,7 @@ static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface) */ static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo) { - StdDispatch *This = (StdDispatch *)iface; + StdDispatch *This = impl_from_IDispatch(iface); TRACE("(%p)\n", pctinfo); *pctinfo = This->pTypeInfo ? 1 : 0; @@ -343,7 +348,7 @@ static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pcti */ static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { - StdDispatch *This = (StdDispatch *)iface; + StdDispatch *This = impl_from_IDispatch(iface); TRACE("(%d, %x, %p)\n", iTInfo, lcid, ppTInfo); *ppTInfo = NULL; @@ -386,7 +391,7 @@ static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCI */ static HRESULT WINAPI StdDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) { - StdDispatch *This = (StdDispatch *)iface; + StdDispatch *This = impl_from_IDispatch(iface); TRACE("(%s, %p, %d, 0x%x, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); if (!IsEqualGUID(riid, &IID_NULL)) @@ -424,7 +429,7 @@ static HRESULT WINAPI StdDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) { - StdDispatch *This = (StdDispatch *)iface; + StdDispatch *This = impl_from_IDispatch(iface); TRACE("(%d, %s, 0x%x, 0x%x, %p, %p, %p, %p)\n", dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); if (!IsEqualGUID(riid, &IID_NULL)) @@ -455,9 +460,9 @@ static IDispatch * StdDispatch_Construct( pStdDispatch = CoTaskMemAlloc(sizeof(StdDispatch)); if (!pStdDispatch) - return (IDispatch *)pStdDispatch; + return &pStdDispatch->IDispatch_iface; - pStdDispatch->lpVtbl = &StdDispatch_VTable; + pStdDispatch->IDispatch_iface.lpVtbl = &StdDispatch_VTable; pStdDispatch->pvThis = pvThis; pStdDispatch->pTypeInfo = pTypeInfo; pStdDispatch->ref = 1; @@ -466,5 +471,5 @@ static IDispatch * StdDispatch_Construct( * being destroyed until we are done with it */ ITypeInfo_AddRef(pTypeInfo); - return (IDispatch *)pStdDispatch; + return &pStdDispatch->IDispatch_iface; } diff --git a/reactos/dll/win32/oleaut32/oleaut.c b/reactos/dll/win32/oleaut32/oleaut.c index 89e1ab9dc2c..250a8129546 100644 --- a/reactos/dll/win32/oleaut32/oleaut.c +++ b/reactos/dll/win32/oleaut32/oleaut.c @@ -33,13 +33,15 @@ #include "ole2.h" #include "olectl.h" #include "oleauto.h" +#include "initguid.h" #include "typelib.h" +#include "oleaut32_oaidl.h" #include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); - -static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */ +WINE_DECLARE_DEBUG_CHANNEL(heap); /****************************************************************************** * BSTR {OLEAUT32} @@ -49,8 +51,8 @@ static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */ * string type in ole automation. When encapsulated in a Variant type they are * automatically copied and destroyed as the variant is processed. * - * The low level BSTR Api allows manipulation of these strings and is used by - * higher level Api calls to manage the strings transparently to the caller. + * The low level BSTR API allows manipulation of these strings and is used by + * higher level API calls to manage the strings transparently to the caller. * * Internally the BSTR type is allocated with space for a DWORD byte count before * the string data begins. This is undocumented and non-system code should not @@ -68,6 +70,100 @@ static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */ * 'Inside OLE, second edition' by Kraig Brockshmidt. */ +static BOOL bstr_cache_enabled; + +static CRITICAL_SECTION cs_bstr_cache; +static CRITICAL_SECTION_DEBUG cs_bstr_cache_dbg = +{ + 0, 0, &cs_bstr_cache, + { &cs_bstr_cache_dbg.ProcessLocksList, &cs_bstr_cache_dbg.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": bstr_cache") } +}; +static CRITICAL_SECTION cs_bstr_cache = { &cs_bstr_cache_dbg, -1, 0, 0, 0, 0 }; + +typedef struct { + DWORD size; + union { + char ptr[1]; + WCHAR str[1]; + DWORD dwptr[1]; + } u; +} bstr_t; + +typedef struct { + unsigned short head; + unsigned short cnt; + bstr_t *buf[6]; +} bstr_cache_entry_t; + +#define BUCKET_SIZE 16 + +#define ARENA_INUSE_FILLER 0x55 +#define ARENA_TAIL_FILLER 0xab +#define ARENA_FREE_FILLER 0xfeeefeee + +static bstr_cache_entry_t bstr_cache[0x10000/BUCKET_SIZE]; + +static inline size_t bstr_alloc_size(size_t size) +{ + return (FIELD_OFFSET(bstr_t, u.ptr[size]) + sizeof(WCHAR) + BUCKET_SIZE-1) & ~(BUCKET_SIZE-1); +} + +static inline bstr_t *bstr_from_str(BSTR str) +{ + return CONTAINING_RECORD(str, bstr_t, u.str); +} + +static inline bstr_cache_entry_t *get_cache_entry(size_t size) +{ + unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size-1])/BUCKET_SIZE; + return bstr_cache_enabled && cache_idx < sizeof(bstr_cache)/sizeof(*bstr_cache) + ? bstr_cache + cache_idx + : NULL; +} + +static bstr_t *alloc_bstr(size_t size) +{ + bstr_cache_entry_t *cache_entry = get_cache_entry(size+sizeof(WCHAR)); + bstr_t *ret; + + if(cache_entry) { + EnterCriticalSection(&cs_bstr_cache); + + if(!cache_entry->cnt) { + cache_entry = get_cache_entry(size+sizeof(WCHAR)+BUCKET_SIZE); + if(cache_entry && !cache_entry->cnt) + cache_entry = NULL; + } + + if(cache_entry) { + ret = cache_entry->buf[cache_entry->head++]; + cache_entry->head %= sizeof(cache_entry->buf)/sizeof(*cache_entry->buf); + cache_entry->cnt--; + } + + LeaveCriticalSection(&cs_bstr_cache); + + if(cache_entry) { + if(WARN_ON(heap)) { + size_t tail; + + memset(ret, ARENA_INUSE_FILLER, FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)])); + tail = bstr_alloc_size(size) - FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)]); + if(tail) + memset(ret->u.ptr+size+sizeof(WCHAR), ARENA_TAIL_FILLER, tail); + } + ret->size = size; + return ret; + } + } + + ret = HeapAlloc(GetProcessHeap(), 0, bstr_alloc_size(size)); + if(ret) + ret->size = size; + return ret; +} + /****************************************************************************** * SysStringLen [OLEAUT32.7] * @@ -87,18 +183,7 @@ static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */ */ UINT WINAPI SysStringLen(BSTR str) { - DWORD* bufferPointer; - - if (!str) return 0; - /* - * The length of the string (in bytes) is contained in a DWORD placed - * just before the BSTR pointer - */ - bufferPointer = (DWORD*)str; - - bufferPointer--; - - return (int)(*bufferPointer/sizeof(WCHAR)); + return str ? bstr_from_str(str)->size/sizeof(WCHAR) : 0; } /****************************************************************************** @@ -117,18 +202,7 @@ UINT WINAPI SysStringLen(BSTR str) */ UINT WINAPI SysStringByteLen(BSTR str) { - DWORD* bufferPointer; - - if (!str) return 0; - /* - * The length of the string (in bytes) is contained in a DWORD placed - * just before the BSTR pointer - */ - bufferPointer = (DWORD*)str; - - bufferPointer--; - - return (int)(*bufferPointer); + return str ? bstr_from_str(str)->size : 0; } /****************************************************************************** @@ -174,24 +248,36 @@ BSTR WINAPI SysAllocString(LPCOLESTR str) */ void WINAPI SysFreeString(BSTR str) { - DWORD* bufferPointer; + bstr_cache_entry_t *cache_entry; + bstr_t *bstr; - /* NULL is a valid parameter */ - if(!str) return; + if(!str) + return; - /* - * We have to be careful when we free a BSTR pointer, it points to - * the beginning of the string but it skips the byte count contained - * before the string. - */ - bufferPointer = (DWORD*)str; + bstr = bstr_from_str(str); + cache_entry = get_cache_entry(bstr->size+sizeof(WCHAR)); + if(cache_entry) { + EnterCriticalSection(&cs_bstr_cache); - bufferPointer--; + if(cache_entry->cnt < sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)) { + cache_entry->buf[(cache_entry->head+cache_entry->cnt)%((sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)))] = bstr; + cache_entry->cnt++; - /* - * Free the memory from its "real" origin. - */ - HeapFree(GetProcessHeap(), 0, bufferPointer); + if(WARN_ON(heap)) { + unsigned i, n = bstr_alloc_size(bstr->size) / sizeof(DWORD) - 1; + bstr->size = ARENA_FREE_FILLER; + for(i=0; iu.dwptr[i] = ARENA_FREE_FILLER; + } + + LeaveCriticalSection(&cs_bstr_cache); + return; + } + + LeaveCriticalSection(&cs_bstr_cache); + } + + HeapFree(GetProcessHeap(), 0, bstr); } /****************************************************************************** @@ -212,61 +298,28 @@ void WINAPI SysFreeString(BSTR str) */ BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len) { - DWORD bufferSize; - DWORD* newBuffer; - WCHAR* stringBuffer; + bstr_t *bstr; + DWORD size; /* Detect integer overflow. */ if (len >= ((UINT_MAX-sizeof(WCHAR)-sizeof(DWORD))/sizeof(WCHAR))) return NULL; - /* - * Find the length of the buffer passed-in, in bytes. - */ - bufferSize = len * sizeof (WCHAR); - /* - * Allocate a new buffer to hold the string. - * don't forget to keep an empty spot at the beginning of the - * buffer for the character count and an extra character at the - * end for the NULL. - */ - newBuffer = HeapAlloc(GetProcessHeap(), 0, - bufferSize + sizeof(WCHAR) + sizeof(DWORD)); + TRACE("%s\n", debugstr_wn(str, len)); - /* - * If the memory allocation failed, return a null pointer. - */ - if (!newBuffer) - return NULL; + size = len*sizeof(WCHAR); + bstr = alloc_bstr(size); + if(!bstr) + return NULL; - /* - * Copy the length of the string in the placeholder. - */ - *newBuffer = bufferSize; + if(str) { + memcpy(bstr->u.str, str, size); + bstr->u.str[len] = 0; + }else { + memset(bstr->u.str, 0, size+sizeof(WCHAR)); + } - /* - * Skip the byte count. - */ - newBuffer++; - - /* - * Copy the information in the buffer. - * Since it is valid to pass a NULL pointer here, we'll initialize the - * buffer to nul if it is the case. - */ - if (str != 0) - memcpy(newBuffer, str, bufferSize); - else - memset(newBuffer, 0, bufferSize); - - /* - * Make sure that there is a nul character at the end of the - * string. - */ - stringBuffer = (WCHAR*)newBuffer; - stringBuffer[len] = '\0'; - - return stringBuffer; + return bstr->u.str; } /****************************************************************************** @@ -296,12 +349,13 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len) if (*old!=NULL) { BSTR old_copy = *old; DWORD newbytelen = len*sizeof(WCHAR); - DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD)); - *old = (BSTR)(ptr+1); - *ptr = newbytelen; + bstr_t *bstr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,bstr_alloc_size(newbytelen)); + *old = bstr->u.str; + bstr->size = newbytelen; /* Subtle hidden feature: The old string data is still there * when 'in' is NULL! * Some Microsoft program needs it. + * FIXME: Is it a sideeffect of BSTR caching? */ if (str && old_copy!=str) memmove(*old, str, newbytelen); (*old)[len] = 0; @@ -337,55 +391,24 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len) */ BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len) { - DWORD* newBuffer; - char* stringBuffer; + bstr_t *bstr; /* Detect integer overflow. */ if (len >= (UINT_MAX-sizeof(WCHAR)-sizeof(DWORD))) return NULL; - /* - * Allocate a new buffer to hold the string. - * don't forget to keep an empty spot at the beginning of the - * buffer for the character count and an extra character at the - * end for the NULL. - */ - newBuffer = HeapAlloc(GetProcessHeap(), 0, - len + sizeof(WCHAR) + sizeof(DWORD)); + bstr = alloc_bstr(len); + if(!bstr) + return NULL; - /* - * If the memory allocation failed, return a null pointer. - */ - if (newBuffer==0) - return 0; + if(str) { + memcpy(bstr->u.ptr, str, len); + bstr->u.ptr[len] = bstr->u.ptr[len+1] = 0; + }else { + memset(bstr->u.ptr, 0, len+sizeof(WCHAR)); + } - /* - * Copy the length of the string in the placeholder. - */ - *newBuffer = len; - - /* - * Skip the byte count. - */ - newBuffer++; - - /* - * Copy the information in the buffer. - * Since it is valid to pass a NULL pointer here, we'll initialize the - * buffer to nul if it is the case. - */ - if (str != 0) - memcpy(newBuffer, str, len); - - /* - * Make sure that there is a nul character at the end of the - * string. - */ - stringBuffer = (char *)newBuffer; - stringBuffer[len] = 0; - stringBuffer[len+1] = 0; - - return (LPWSTR)stringBuffer; + return bstr->u.str; } /****************************************************************************** @@ -437,14 +460,15 @@ INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR str) * Nothing. * * NOTES - * See BSTR. + * SetOaNoCache does not release cached strings, so it leaks by design. */ void WINAPI SetOaNoCache(void) { - BSTR_bCache = FALSE; + TRACE("\n"); + bstr_cache_enabled = FALSE; } -static const WCHAR _delimiter[2] = {'!',0}; /* default delimiter apparently */ +static const WCHAR _delimiter[] = {'!',0}; /* default delimiter apparently */ static const WCHAR *pdelimiter = &_delimiter[0]; /*********************************************************************** @@ -469,6 +493,7 @@ HRESULT WINAPI RegisterActiveObject( HRESULT ret; LPRUNNINGOBJECTTABLE runobtable; LPMONIKER moniker; + DWORD rot_flags = ROTFLAGS_REGISTRATIONKEEPSALIVE; /* default registration is strong */ StringFromGUID2(rcid,guidbuf,39); ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker); @@ -479,7 +504,9 @@ HRESULT WINAPI RegisterActiveObject( IMoniker_Release(moniker); return ret; } - ret = IRunningObjectTable_Register(runobtable,dwFlags,punk,moniker,pdwRegister); + if(dwFlags == ACTIVEOBJECT_WEAK) + rot_flags = 0; + ret = IRunningObjectTable_Register(runobtable,rot_flags,punk,moniker,pdwRegister); IRunningObjectTable_Release(runobtable); IMoniker_Release(moniker); return ret; @@ -594,8 +621,11 @@ ULONG WINAPI OaBuildVersion(void) case 0x80000a04: /* WIN98 */ case 0x00000004: /* NT40 */ case 0x00000005: /* W2K */ - case 0x00000105: /* WinXP */ return MAKELONG(0xffff, 40); + case 0x00000105: /* WinXP */ + case 0x00000006: /* Vista */ + case 0x00000106: /* Win7 */ + return MAKELONG(0xffff, 50); default: FIXME("Version value not known yet. Please investigate it !\n"); return MAKELONG(0xffff, 40); /* for now return the same value as for w2k */ @@ -694,6 +724,8 @@ HRESULT WINAPI OleTranslateColor( extern HRESULT WINAPI OLEAUTPS_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN; extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; +extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN; +extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN; extern GUID const CLSID_PSFactoryBuffer DECLSPEC_HIDDEN; extern void _get_STDFONT_CF(LPVOID *); @@ -704,7 +736,7 @@ static HRESULT WINAPI PSDispatchFacBuf_QueryInterface(IPSFactoryBuffer *iface, R if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPSFactoryBuffer)) { - IUnknown_AddRef(iface); + IPSFactoryBuffer_AddRef(iface); *ppv = iface; return S_OK; } @@ -829,9 +861,29 @@ HRESULT WINAPI DllCanUnloadNow(void) */ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved) { + static const WCHAR oanocacheW[] = {'o','a','n','o','c','a','c','h','e',0}; + + bstr_cache_enabled = !GetEnvironmentVariableW(oanocacheW, NULL, 0); + return OLEAUTPS_DllMain( hInstDll, fdwReason, lpvReserved ); } +/*********************************************************************** + * DllRegisterServer (OLEAUT32.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return OLEAUTPS_DllRegisterServer(); +} + +/*********************************************************************** + * DllUnregisterServer (OLEAUT32.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return OLEAUTPS_DllUnregisterServer(); +} + /*********************************************************************** * OleIconToCursor (OLEAUT32.415) */ diff --git a/reactos/dll/win32/oleaut32/oleaut32.rc b/reactos/dll/win32/oleaut32/oleaut32.rc index 3b523758990..b15b856b5e7 100644 --- a/reactos/dll/win32/oleaut32/oleaut32.rc +++ b/reactos/dll/win32/oleaut32/oleaut32.rc @@ -1,5 +1,5 @@ /* - * Top level resource file for oleaut32 + * Resources for oleaut32 * * Copyright 2003 Jon Griffiths * @@ -22,8 +22,6 @@ #include "winbase.h" #include "resource.h" -#include "version.rc" - #ifdef LANGUAGE_BG_BG #include "oleaut32_Bg.rc" #endif @@ -108,3 +106,17 @@ * Turkish (at least) are localised in XP Home. * I expect Chinese etc are localised in Asian Editions also. */ + +/* @makedep: oleaut32.rgs */ +1 WINE_REGISTRY oleaut32.rgs + +2 WINE_REGISTRY oleaut32_oaidl.rgs +3 WINE_REGISTRY oleaut32_ocidl.rgs + +#define WINE_FILEDESCRIPTION_STR "Wine OLE dll" +#define WINE_FILENAME_STR "oleaut32.dll" +#define WINE_FILEVERSION 6, 0, 6001, 18000 /* version from Vista SP1 */ +#define WINE_FILEVERSION_STR "6.0.6001.18000" +#define WINE_EXTRAVALUES VALUE "OLESelfRegister","" + +#include "wine/wine_common_ver.rc" diff --git a/reactos/dll/win32/oleaut32/oleaut32.rgs b/reactos/dll/win32/oleaut32/oleaut32.rgs new file mode 100644 index 00000000000..87a848c6298 --- /dev/null +++ b/reactos/dll/win32/oleaut32/oleaut32.rgs @@ -0,0 +1,57 @@ +HKCR +{ + NoRemove CLSID + { + '{00020420-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' } + '{00020421-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' } + '{00020422-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' } + '{00020423-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' } + '{00020424-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' } + '{00020425-0000-0000-C000-000000000046}' { InprocServer = s 'ole2disp.dll' } + '{DF0B3D60-548F-101B-8E65-08002B2BD119}' { InprocServer = s 'ole2disp.dll' } + } + NoRemove Interface + { + '{0000002E-0000-0000-C000-000000000046}' + { + ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}' + } + '{00020400-0000-0000-C000-000000000046}' + { + ProxyStubClsid = s '{00020420-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}' + } + '{00020401-0000-0000-C000-000000000046}' + { + ProxyStubClsid = s '{00020422-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020422-0000-0000-C000-000000000046}' + } + '{00020402-0000-0000-C000-000000000046}' + { + ProxyStubClsid = s '{00020423-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020423-0000-0000-C000-000000000046}' + } + '{00020403-0000-0000-C000-000000000046}' + { + ProxyStubClsid = s '{00020425-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020425-0000-0000-C000-000000000046}' + } + '{00020404-0000-0000-C000-000000000046}' + { + ProxyStubClsid = s '{00020421-0000-0000-C000-000000000046}' + ProxyStubClsid32 = s '{00020421-0000-0000-C000-000000000046}' + } + '{00020411-0000-0000-C000-000000000046}' + { + ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}' + } + '{00020412-0000-0000-C000-000000000046}' + { + ProxyStubClsid32 = s '{00020420-0000-0000-C000-000000000046}' + } + '{DF0B3D60-548F-101B-8E65-08002B2BD119}' + { + ProxyStubClsid32 = s '{DF0B3D60-548F-101B-8E65-08002B2BD119}' + } + } +} diff --git a/reactos/dll/win32/oleaut32/oleaut32_oaidl.idl b/reactos/dll/win32/oleaut32/oleaut32_oaidl.idl index 320e7ecfdc2..3574d081ab2 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_oaidl.idl +++ b/reactos/dll/win32/oleaut32/oleaut32_oaidl.idl @@ -23,3 +23,9 @@ cpp_quote("#if 0 /* oleaut32_oaidl.idl hack */") #include "oaidl.idl" cpp_quote("#endif /* oleaut32_oaidl.idl hack */") + +[ + threading(both), + uuid(b196b286-bab4-101a-b69c-00aa00341d07) +] +coclass PSFactoryBuffer { interface IFactoryBuffer; } diff --git a/reactos/dll/win32/oleaut32/oleaut32_oaidl.rgs b/reactos/dll/win32/oleaut32/oleaut32_oaidl.rgs new file mode 100644 index 00000000000..ebd7b5a2624 --- /dev/null +++ b/reactos/dll/win32/oleaut32/oleaut32_oaidl.rgs @@ -0,0 +1,78 @@ +HKCR +{ + NoRemove Interface + { + '{00020400-0000-0000-C000-000000000046}' = s 'IDispatch' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{00020404-0000-0000-C000-000000000046}' = s 'IEnumVARIANT' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{00020403-0000-0000-C000-000000000046}' = s 'ITypeComp' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{00020401-0000-0000-C000-000000000046}' = s 'ITypeInfo' + { + NumMethods = s 22 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{00020412-0000-0000-C000-000000000046}' = s 'ITypeInfo2' + { + NumMethods = s 37 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{00020402-0000-0000-C000-000000000046}' = s 'ITypeLib' + { + NumMethods = s 13 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{00020411-0000-0000-C000-000000000046}' = s 'ITypeLib2' + { + NumMethods = s 17 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{1CF2B120-547D-101B-8E65-08002B2BD119}' = s 'IErrorInfo' + { + NumMethods = s 8 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{22F03340-547D-101B-8E65-08002B2BD119}' = s 'ICreateErrorInfo' + { + NumMethods = s 8 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{DF0B3D60-548F-101B-8E65-08002B2BD119}' = s 'ISupportErrorInfo' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{0000002E-0000-0000-C000-000000000046}' = s 'ITypeFactory' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{3127CA40-446E-11CE-8135-00AA004BB851}' = s 'IErrorLog' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{55272A00-42CB-11CE-8135-00AA004BB851}' = s 'IPropertyBag' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + } + NoRemove CLSID + { + '{B196B286-BAB4-101A-B69C-00AA00341D07}' = s 'PSFactoryBuffer' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + } +} \ No newline at end of file diff --git a/reactos/dll/win32/oleaut32/oleaut32_ocidl.idl b/reactos/dll/win32/oleaut32/oleaut32_ocidl.idl index dcd3ea458da..fad374183e2 100644 --- a/reactos/dll/win32/oleaut32/oleaut32_ocidl.idl +++ b/reactos/dll/win32/oleaut32/oleaut32_ocidl.idl @@ -17,3 +17,81 @@ */ #include "ocidl.idl" + +[ + threading(both), + uuid(b196b286-bab4-101a-b69c-00aa00341d07) +] +coclass PSFactoryBuffer { interface IFactoryBuffer; } + +[ + helpstring("Standard Font"), + progid("StdFont"), + threading(both), + uuid(0be35203-8f91-11ce-9de3-00aa004bb851) +] +coclass StdFont { interface IFont; } + +[ + helpstring("Obsolete Font"), + progid("OldFont"), + threading(both), + uuid(46763ee0-cab2-11ce-8c20-00aa0051e5d4) +] +coclass OldFont { interface IFont; } + +[ + helpstring("Standard Picture"), + progid("StdPicture"), + threading(apartment), + uuid(0be35204-8f91-11ce-9de3-00aa004bb851) +] +coclass StdPicture { interface IPicture; } + +[ + threading(both), + uuid(00020420-0000-0000-c000-000000000046) +] +coclass PSDispatch { } + +[ + threading(both), + uuid(00020421-0000-0000-c000-000000000046) +] +coclass PSEnumVariant { } + +[ + threading(both), + uuid(00020422-0000-0000-c000-000000000046) +] +coclass PSTypeInfo { } + +[ + threading(both), + uuid(00020423-0000-0000-c000-000000000046) +] +coclass PSTypeLib { } + +[ + threading(both), + uuid(00020424-0000-0000-c000-000000000046) +] +coclass PSOAInterface { } + +[ + threading(both), + uuid(00020425-0000-0000-c000-000000000046) +] +coclass PSTypeComp { } + +[ + threading(both), + uuid(df0b3d60-548f-101b-8e65-08002b2bd119) +] +coclass PSSupportErrorInfo { } + +[ + threading(both), + uuid(0000002f-0000-0000-c000-000000000046) +] +coclass CLSID_RecordInfo { } diff --git a/reactos/dll/win32/oleaut32/oleaut32_ocidl.rgs b/reactos/dll/win32/oleaut32/oleaut32_ocidl.rgs new file mode 100644 index 00000000000..e8b25ae3b2e --- /dev/null +++ b/reactos/dll/win32/oleaut32/oleaut32_ocidl.rgs @@ -0,0 +1,252 @@ +HKCR +{ + NoRemove Interface + { + '{BEF6E002-A874-101A-8BBA-00AA00300CAB}' = s 'IFont' + { + NumMethods = s 27 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{BEF6E003-A874-101A-8BBA-00AA00300CAB}' = s 'IFontDisp' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{4EF6100A-AF88-11D0-9846-00C04FC29993}' = s 'IFontEventsDisp' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{7BF80980-BF32-101A-8BBB-00AA00300CAB}' = s 'IPicture' + { + NumMethods = s 17 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{7BF80981-BF32-101A-8BBB-00AA00300CAB}' = s 'IPictureDisp' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B288-BAB4-101A-B69C-00AA00341D07}' = s 'IOleControl' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B289-BAB4-101A-B69C-00AA00341D07}' = s 'IOleControlSite' + { + NumMethods = s 10 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{9C2CAD80-3424-11CF-B670-00AA004CD6D8}' = s 'IOleInPlaceSiteEx' + { + NumMethods = s 18 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B28F-BAB4-101A-B69C-00AA00341D07}' = s 'IClassFactory2' + { + NumMethods = s 8 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B283-BAB4-101A-B69C-00AA00341D07}' = s 'IProvideClassInfo' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{A6BC3AC0-DBAA-11CE-9DE3-00AA004BB851}' = s 'IProvideClassInfo2' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{A7ABA9C1-8983-11CF-8F20-00805F2CD064}' = s 'IProvideMultipleClassInfo' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B286-BAB4-101A-B69C-00AA00341D07}' = s 'IConnectionPoint' + { + NumMethods = s 8 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B284-BAB4-101A-B69C-00AA00341D07}' = s 'IConnectionPointContainer' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B287-BAB4-101A-B69C-00AA00341D07}' = s 'IEnumConnections' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B285-BAB4-101A-B69C-00AA00341D07}' = s 'IEnumConnectionPoints' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B28D-BAB4-101A-B69C-00AA00341D07}' = s 'IPropertyPage' + { + NumMethods = s 14 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{01E44665-24AC-101B-84ED-08002B2EC713}' = s 'IPropertyPage2' + { + NumMethods = s 15 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B28C-BAB4-101A-B69C-00AA00341D07}' = s 'IPropertyPageSite' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{9BFBBC02-EFF1-101A-84ED-00AA00341D07}' = s 'IPropertyNotifySink' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{742B0E01-14E6-101B-914E-00AA00300CAB}' = s 'ISimpleFrameSite' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{7FD52380-4E07-101B-AE2D-08002B2EC713}' = s 'IPersistStreamInit' + { + NumMethods = s 9 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{BD1AE5E0-A6AE-11CE-BD37-504200C10000}' = s 'IPersistMemory' + { + NumMethods = s 9 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{37D84F60-42CB-11CE-8135-00AA004BB851}' = s 'IPersistPropertyBag' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{22F55882-280B-11D0-A8A9-00A0C90C2004}' = s 'IPropertyBag2' + { + NumMethods = s 8 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{22F55881-280B-11D0-A8A9-00A0C90C2004}' = s 'IPersistPropertyBag2' + { + NumMethods = s 8 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B196B28B-BAB4-101A-B69C-00AA00341D07}' = s 'ISpecifyPropertyPages' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{376BD3AA-3845-101B-84ED-08002B2EC713}' = s 'IPerPropertyBrowsing' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{3AF24290-0C96-11CE-A0CF-00AA00600AB8}' = s 'IAdviseSinkEx' + { + NumMethods = s 9 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{55980BA0-35AA-11CF-B671-00AA004CD6D8}' = s 'IPointerInactive' + { + NumMethods = s 6 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{FC4801A3-2BA9-11CF-A229-00AA003D7352}' = s 'IObjectWithSite' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{894AD3B0-EF97-11CE-9BC9-00AA00608E01}' = s 'IOleUndoUnit' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{A1FAF330-EF97-11CE-9BC9-00AA00608E01}' = s 'IOleParentUndoUnit' + { + NumMethods = s 12 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{B3E7C340-EF97-11CE-9BC9-00AA00608E01}' = s 'IEnumOleUndoUnits' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{D001F200-EF97-11CE-9BC9-00AA00608E01}' = s 'IOleUndoManager' + { + NumMethods = s 15 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + '{CF51ED10-62FE-11CF-BF86-00A0C9034836}' = s 'IQuickActivate' + { + NumMethods = s 6 + ProxyStubClsid32 = s '{B196B286-BAB4-101A-B69C-00AA00341D07}' + } + } + NoRemove CLSID + { + '{B196B286-BAB4-101A-B69C-00AA00341D07}' = s 'PSFactoryBuffer' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{0BE35203-8F91-11CE-9DE3-00AA004BB851}' = s 'Standard Font' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + ProgId = s 'StdFont' + } + '{46763EE0-CAB2-11CE-8C20-00AA0051E5D4}' = s 'Obsolete Font' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + ProgId = s 'OldFont' + } + '{0BE35204-8F91-11CE-9DE3-00AA004BB851}' = s 'Standard Picture' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } + ProgId = s 'StdPicture' + } + '{00020420-0000-0000-C000-000000000046}' = s 'PSDispatch' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{00020421-0000-0000-C000-000000000046}' = s 'PSEnumVariant' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{00020422-0000-0000-C000-000000000046}' = s 'PSTypeInfo' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{00020423-0000-0000-C000-000000000046}' = s 'PSTypeLib' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{00020424-0000-0000-C000-000000000046}' = s 'PSOAInterface' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{00020425-0000-0000-C000-000000000046}' = s 'PSTypeComp' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{DF0B3D60-548F-101B-8E65-08002B2BD119}' = s 'PSSupportErrorInfo' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{0000002F-0000-0000-C000-000000000046}' = s 'CLSID_RecordInfo' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + } + 'StdFont' = s 'Standard Font' + { + CLSID = s '{0BE35203-8F91-11CE-9DE3-00AA004BB851}' + } + 'OldFont' = s 'Obsolete Font' + { + CLSID = s '{46763EE0-CAB2-11CE-8C20-00AA0051E5D4}' + } + 'StdPicture' = s 'Standard Picture' + { + CLSID = s '{0BE35204-8F91-11CE-9DE3-00AA004BB851}' + } +} \ No newline at end of file diff --git a/reactos/dll/win32/oleaut32/olefont.c b/reactos/dll/win32/oleaut32/olefont.c index 3c8c91f9f66..b5c0cb4882b 100644 --- a/reactos/dll/win32/oleaut32/olefont.c +++ b/reactos/dll/win32/oleaut32/olefont.c @@ -251,12 +251,12 @@ struct OLEFontImpl * The first two are supported by the first vtable, the next two are * supported by the second table and the last two have their own. */ - const IFontVtbl* lpVtbl; - const IDispatchVtbl* lpvtblIDispatch; - const IPersistStreamVtbl* lpvtblIPersistStream; - const IConnectionPointContainerVtbl* lpvtblIConnectionPointContainer; - const IPersistPropertyBagVtbl* lpvtblIPersistPropertyBag; - const IPersistStreamInitVtbl* lpvtblIPersistStreamInit; + IFont IFont_iface; + IDispatch IDispatch_iface; + IPersistStream IPersistStream_iface; + IConnectionPointContainer IConnectionPointContainer_iface; + IPersistPropertyBag IPersistPropertyBag_iface; + IPersistStreamInit IPersistStreamInit_iface; /* * Reference count for that instance of the class. */ @@ -278,40 +278,43 @@ struct OLEFontImpl LONG cyLogical; LONG cyHimetric; + /* + * Stash realized height (pixels) from TEXTMETRIC - used in get_Size() + */ + LONG nRealHeight; + IConnectionPoint *pPropertyNotifyCP; IConnectionPoint *pFontEventsCP; }; -/* - * Here, I define utility macros to help with the casting of the - * "this" parameter. - * There is a version to accommodate all of the VTables implemented - * by this object. - */ +static inline OLEFontImpl *impl_from_IFont(IFont *iface) +{ + return CONTAINING_RECORD(iface, OLEFontImpl, IFont_iface); +} static inline OLEFontImpl *impl_from_IDispatch( IDispatch *iface ) { - return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIDispatch)); + return CONTAINING_RECORD(iface, OLEFontImpl, IDispatch_iface); } static inline OLEFontImpl *impl_from_IPersistStream( IPersistStream *iface ) { - return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStream)); + return CONTAINING_RECORD(iface, OLEFontImpl, IPersistStream_iface); } static inline OLEFontImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface ) { - return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIConnectionPointContainer)); + return CONTAINING_RECORD(iface, OLEFontImpl, IConnectionPointContainer_iface); } static inline OLEFontImpl *impl_from_IPersistPropertyBag( IPersistPropertyBag *iface ) { - return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistPropertyBag)); + return CONTAINING_RECORD(iface, OLEFontImpl, IPersistPropertyBag_iface); } static inline OLEFontImpl *impl_from_IPersistStreamInit( IPersistStreamInit *iface ) { - return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStreamInit)); + return CONTAINING_RECORD(iface, OLEFontImpl, IPersistStreamInit_iface); } @@ -331,21 +334,17 @@ HRESULT WINAPI OleCreateFontIndirect( REFIID riid, LPVOID* ppvObj) { - OLEFontImpl* newFont = 0; - HRESULT hr = S_OK; + OLEFontImpl* newFont; + HRESULT hr; + FONTDESC fd; TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj); - /* - * Sanity check - */ - if (ppvObj==0) - return E_POINTER; + + if (!ppvObj) return E_POINTER; *ppvObj = 0; if (!lpFontDesc) { - FONTDESC fd; - static WCHAR fname[] = { 'S','y','s','t','e','m',0 }; fd.cbSizeofstruct = sizeof(fd); @@ -360,24 +359,11 @@ HRESULT WINAPI OleCreateFontIndirect( lpFontDesc = &fd; } - /* - * Try to construct a new instance of the class. - */ newFont = OLEFontImpl_Construct(lpFontDesc); + if (!newFont) return E_OUTOFMEMORY; - if (newFont == 0) - return E_OUTOFMEMORY; - - /* - * Make sure it supports the interface required by the caller. - */ - hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj); - - /* - * Release the reference obtained in the constructor. If - * the QueryInterface was unsuccessful, it will free the class. - */ - IFont_Release((IFont*)newFont); + hr = IFont_QueryInterface(&newFont->IFont_iface, riid, ppvObj); + IFont_Release(&newFont->IFont_iface); return hr; } @@ -455,11 +441,11 @@ static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID) IFontEventsDisp *disp; IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp); - IDispatch_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL, - LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL, - NULL, NULL); + IFontEventsDisp_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL, + LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL, + NULL, NULL); - IDispatch_Release(disp); + IFontEventsDisp_Release(disp); IUnknown_Release(CD.pUnk); } VariantClear(&vararg); @@ -477,82 +463,75 @@ static HRESULT WINAPI OLEFontImpl_QueryInterface( REFIID riid, void** ppvObject) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); + TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject); - /* - * Perform a sanity check on the parameters. - */ - if ( (this==0) || (ppvObject==0) ) - return E_INVALIDARG; - - /* - * Initialize the return parameter. - */ *ppvObject = 0; - /* - * Compare the riid with the interface IDs implemented by this object. - */ - if (IsEqualGUID(&IID_IUnknown, riid)) - *ppvObject = this; - if (IsEqualGUID(&IID_IFont, riid)) - *ppvObject = this; - if (IsEqualGUID(&IID_IDispatch, riid)) - *ppvObject = &this->lpvtblIDispatch; - if (IsEqualGUID(&IID_IFontDisp, riid)) - *ppvObject = &this->lpvtblIDispatch; - if (IsEqualIID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistStream, riid)) - *ppvObject = &this->lpvtblIPersistStream; - if (IsEqualGUID(&IID_IConnectionPointContainer, riid)) - *ppvObject = &this->lpvtblIConnectionPointContainer; - if (IsEqualGUID(&IID_IPersistPropertyBag, riid)) - *ppvObject = &this->lpvtblIPersistPropertyBag; - if (IsEqualGUID(&IID_IPersistStreamInit, riid)) - *ppvObject = &this->lpvtblIPersistStreamInit; - - /* - * Check that we obtained an interface. - */ - if ((*ppvObject)==0) + if (IsEqualGUID(&IID_IUnknown, riid) || + IsEqualGUID(&IID_IFont, riid)) { - FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid)); + *ppvObject = this; + } + else if (IsEqualGUID(&IID_IDispatch, riid) || + IsEqualGUID(&IID_IFontDisp, riid)) + { + *ppvObject = &this->IDispatch_iface; + } + else if (IsEqualGUID(&IID_IPersist, riid) || + IsEqualGUID(&IID_IPersistStream, riid)) + { + *ppvObject = &this->IPersistStream_iface; + } + else if (IsEqualGUID(&IID_IConnectionPointContainer, riid)) + { + *ppvObject = &this->IConnectionPointContainer_iface; + } + else if (IsEqualGUID(&IID_IPersistPropertyBag, riid)) + { + *ppvObject = &this->IPersistPropertyBag_iface; + } + else if (IsEqualGUID(&IID_IPersistStreamInit, riid)) + { + *ppvObject = &this->IPersistStreamInit_iface; + } + + if (!*ppvObject) + { + FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } - OLEFontImpl_AddRef((IFont*)this); + + IFont_AddRef(iface); + return S_OK; } /************************************************************************ * OLEFontImpl_AddRef (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static ULONG WINAPI OLEFontImpl_AddRef( IFont* iface) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(ref=%d)\n", this, this->ref); return InterlockedIncrement(&this->ref); } /************************************************************************ * OLEFontImpl_Release (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ -static ULONG WINAPI OLEFontImpl_Release( - IFont* iface) +static ULONG WINAPI OLEFontImpl_Release(IFont* iface) { - OLEFontImpl *this = (OLEFontImpl *)iface; - ULONG ret; + OLEFontImpl *this = impl_from_IFont(iface); + ULONG ref; + TRACE("(%p)->(ref=%d)\n", this, this->ref); - /* Decrease the reference count for current interface */ - ret = InterlockedDecrement(&this->ref); + ref = InterlockedDecrement(&this->ref); - /* If the reference count goes down to 0, destroy. */ - if (ret == 0) + if (ref == 0) { ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt); @@ -574,7 +553,7 @@ static ULONG WINAPI OLEFontImpl_Release( OLEFontImpl_Destroy(this); } - return ret; + return ref; } typedef struct @@ -598,86 +577,85 @@ static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, static void realize_font(OLEFontImpl *This) { - if (This->dirty) + LOGFONTW logFont; + INT fontHeight; + WCHAR text_face[LF_FACESIZE]; + HDC hdc = get_dc(); + HFONT old_font; + TEXTMETRICW tm; + + if (!This->dirty) return; + + text_face[0] = 0; + + if(This->gdiFont) { - LOGFONTW logFont; - INT fontHeight; - WCHAR text_face[LF_FACESIZE]; - HDC hdc = get_dc(); - HFONT old_font; - TEXTMETRICW tm; - - text_face[0] = 0; - - if(This->gdiFont) - { - old_font = SelectObject(hdc, This->gdiFont); - GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); - SelectObject(hdc, old_font); - dec_int_ref(This->gdiFont); - This->gdiFont = 0; - } - - memset(&logFont, 0, sizeof(LOGFONTW)); - - lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE); - logFont.lfCharSet = This->description.sCharset; - - /* If the font name has been changed then enumerate all charsets - and pick one that'll result in the font specified being selected */ - if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName)) - { - enum_data data; - data.orig_cs = This->description.sCharset; - data.avail_cs = -1; - logFont.lfCharSet = DEFAULT_CHARSET; - EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0); - if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs; - } - - - /* - * The height of the font returned by the get_Size property is the - * height of the font in points multiplied by 10000... Using some - * simple conversions and the ratio given by the application, it can - * be converted to a height in pixels. - * - * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. - * Ratio is applied here relative to the standard. - */ - - fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 ); - - - logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 : - (-fontHeight/10000L); - logFont.lfItalic = This->description.fItalic; - logFont.lfUnderline = This->description.fUnderline; - logFont.lfStrikeOut = This->description.fStrikethrough; - logFont.lfWeight = This->description.sWeight; - logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; - logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; - logFont.lfQuality = DEFAULT_QUALITY; - logFont.lfPitchAndFamily = DEFAULT_PITCH; - - This->gdiFont = CreateFontIndirectW(&logFont); - This->dirty = FALSE; - - add_hfontitem(This->gdiFont); - - /* Fixup the name and charset properties so that they match the - selected font */ - old_font = SelectObject(get_dc(), This->gdiFont); + old_font = SelectObject(hdc, This->gdiFont); GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); - if(lstrcmpiW(text_face, This->description.lpstrName)) - { - HeapFree(GetProcessHeap(), 0, This->description.lpstrName); - This->description.lpstrName = strdupW(text_face); - } - GetTextMetricsW(hdc, &tm); - This->description.sCharset = tm.tmCharSet; SelectObject(hdc, old_font); + dec_int_ref(This->gdiFont); + This->gdiFont = 0; } + + memset(&logFont, 0, sizeof(LOGFONTW)); + + lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE); + logFont.lfCharSet = This->description.sCharset; + + /* If the font name has been changed then enumerate all charsets + and pick one that'll result in the font specified being selected */ + if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName)) + { + enum_data data; + data.orig_cs = This->description.sCharset; + data.avail_cs = -1; + logFont.lfCharSet = DEFAULT_CHARSET; + EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0); + if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs; + } + + /* + * The height of the font returned by the get_Size property is the + * height of the font in points multiplied by 10000... Using some + * simple conversions and the ratio given by the application, it can + * be converted to a height in pixels. + * + * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. + * Ratio is applied here relative to the standard. + */ + + fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 ); + + logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 : + (-fontHeight/10000L); + logFont.lfItalic = This->description.fItalic; + logFont.lfUnderline = This->description.fUnderline; + logFont.lfStrikeOut = This->description.fStrikethrough; + logFont.lfWeight = This->description.sWeight; + logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; + logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logFont.lfQuality = DEFAULT_QUALITY; + logFont.lfPitchAndFamily = DEFAULT_PITCH; + + This->gdiFont = CreateFontIndirectW(&logFont); + This->dirty = FALSE; + + add_hfontitem(This->gdiFont); + + /* Fixup the name and charset properties so that they match the + selected font */ + old_font = SelectObject(get_dc(), This->gdiFont); + GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); + if(lstrcmpiW(text_face, This->description.lpstrName)) + { + HeapFree(GetProcessHeap(), 0, This->description.lpstrName); + This->description.lpstrName = strdupW(text_face); + } + GetTextMetricsW(hdc, &tm); + This->description.sCharset = tm.tmCharSet; + /* While we have it handy, stash the realized font height for use by get_Size() */ + This->nRealHeight = tm.tmHeight - tm.tmInternalLeading; /* corresponds to LOGFONT lfHeight */ + SelectObject(hdc, old_font); } /************************************************************************ @@ -689,15 +667,13 @@ static HRESULT WINAPI OLEFontImpl_get_Name( IFont* iface, BSTR* pname) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, pname); - /* - * Sanity check. - */ + if (pname==0) return E_POINTER; - if(this->dirty) realize_font(this); + realize_font(this); if (this->description.lpstrName!=0) *pname = SysAllocString(this->description.lpstrName); @@ -709,78 +685,60 @@ static HRESULT WINAPI OLEFontImpl_get_Name( /************************************************************************ * OLEFontImpl_put_Name (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_put_Name( IFont* iface, BSTR name) { - OLEFontImpl *this = (OLEFontImpl *)iface; - TRACE("(%p)->(%p)\n", this, name); + OLEFontImpl *This = impl_from_IFont(iface); + TRACE("(%p)->(%p)\n", This, name); if (!name) return CTL_E_INVALIDPROPERTYVALUE; - if (this->description.lpstrName==0) - { - this->description.lpstrName = HeapAlloc(GetProcessHeap(), - 0, - (lstrlenW(name)+1) * sizeof(WCHAR)); - } - else - { - this->description.lpstrName = HeapReAlloc(GetProcessHeap(), - 0, - this->description.lpstrName, - (lstrlenW(name)+1) * sizeof(WCHAR)); - } + HeapFree(GetProcessHeap(), 0, This->description.lpstrName); + This->description.lpstrName = strdupW(name); + if (!This->description.lpstrName) return E_OUTOFMEMORY; - if (this->description.lpstrName==0) - return E_OUTOFMEMORY; - - strcpyW(this->description.lpstrName, name); - TRACE("new name %s\n", debugstr_w(this->description.lpstrName)); - OLEFont_SendNotify(this, DISPID_FONT_NAME); + TRACE("new name %s\n", debugstr_w(This->description.lpstrName)); + OLEFont_SendNotify(This, DISPID_FONT_NAME); return S_OK; } /************************************************************************ * OLEFontImpl_get_Size (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_get_Size( IFont* iface, CY* psize) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, psize); + if (!psize) return E_POINTER; + + realize_font(this); + /* - * Sanity check + * Convert realized font height in pixels to points descaled by current + * scaling ratio then scaled up by 10000. */ - if (psize==0) - return E_POINTER; - - if(this->dirty) realize_font(this); - + psize->s.Lo = MulDiv(this->nRealHeight, + this->cyHimetric * 72 * 10000, + this->cyLogical * 2540); psize->s.Hi = 0; - psize->s.Lo = this->description.cySize.s.Lo; return S_OK; } /************************************************************************ * OLEFontImpl_put_Size (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_put_Size( IFont* iface, CY size) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%d)\n", this, size.s.Lo); this->description.cySize.s.Hi = 0; this->description.cySize.s.Lo = size.s.Lo; @@ -798,15 +756,12 @@ static HRESULT WINAPI OLEFontImpl_get_Bold( IFont* iface, BOOL* pbold) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, pbold); - /* - * Sanity check - */ - if (pbold==0) - return E_POINTER; - if(this->dirty) realize_font(this); + if (!pbold) return E_POINTER; + + realize_font(this); *pbold = this->description.sWeight > 550; @@ -815,14 +770,12 @@ static HRESULT WINAPI OLEFontImpl_get_Bold( /************************************************************************ * OLEFontImpl_put_Bold (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_put_Bold( IFont* iface, BOOL bold) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%d)\n", this, bold); this->description.sWeight = bold ? FW_BOLD : FW_NORMAL; OLEFont_SendNotify(this, DISPID_FONT_BOLD); @@ -832,22 +785,18 @@ static HRESULT WINAPI OLEFontImpl_put_Bold( /************************************************************************ * OLEFontImpl_get_Italic (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_get_Italic( IFont* iface, BOOL* pitalic) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, pitalic); - /* - * Sanity check - */ + if (pitalic==0) return E_POINTER; - if(this->dirty) realize_font(this); + realize_font(this); *pitalic = this->description.fItalic; @@ -856,14 +805,12 @@ static HRESULT WINAPI OLEFontImpl_get_Italic( /************************************************************************ * OLEFontImpl_put_Italic (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_put_Italic( IFont* iface, BOOL italic) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%d)\n", this, italic); this->description.fItalic = italic; @@ -874,23 +821,18 @@ static HRESULT WINAPI OLEFontImpl_put_Italic( /************************************************************************ * OLEFontImpl_get_Underline (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_get_Underline( IFont* iface, BOOL* punderline) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, punderline); - /* - * Sanity check - */ if (punderline==0) return E_POINTER; - if(this->dirty) realize_font(this); + realize_font(this); *punderline = this->description.fUnderline; @@ -899,14 +841,12 @@ static HRESULT WINAPI OLEFontImpl_get_Underline( /************************************************************************ * OLEFontImpl_put_Underline (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_put_Underline( IFont* iface, BOOL underline) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%d)\n", this, underline); this->description.fUnderline = underline; @@ -917,23 +857,18 @@ static HRESULT WINAPI OLEFontImpl_put_Underline( /************************************************************************ * OLEFontImpl_get_Strikethrough (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_get_Strikethrough( IFont* iface, BOOL* pstrikethrough) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, pstrikethrough); - /* - * Sanity check - */ if (pstrikethrough==0) return E_POINTER; - if(this->dirty) realize_font(this); + realize_font(this); *pstrikethrough = this->description.fStrikethrough; @@ -942,14 +877,12 @@ static HRESULT WINAPI OLEFontImpl_get_Strikethrough( /************************************************************************ * OLEFontImpl_put_Strikethrough (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_put_Strikethrough( IFont* iface, BOOL strikethrough) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%d)\n", this, strikethrough); this->description.fStrikethrough = strikethrough; @@ -960,23 +893,18 @@ static HRESULT WINAPI OLEFontImpl_put_Strikethrough( /************************************************************************ * OLEFontImpl_get_Weight (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_get_Weight( IFont* iface, short* pweight) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, pweight); - /* - * Sanity check - */ if (pweight==0) return E_POINTER; - if(this->dirty) realize_font(this); + realize_font(this); *pweight = this->description.sWeight; @@ -985,14 +913,12 @@ static HRESULT WINAPI OLEFontImpl_get_Weight( /************************************************************************ * OLEFontImpl_put_Weight (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_put_Weight( IFont* iface, short weight) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%d)\n", this, weight); this->description.sWeight = weight; @@ -1003,23 +929,18 @@ static HRESULT WINAPI OLEFontImpl_put_Weight( /************************************************************************ * OLEFontImpl_get_Charset (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_get_Charset( IFont* iface, short* pcharset) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, pcharset); - /* - * Sanity check - */ if (pcharset==0) return E_POINTER; - if(this->dirty) realize_font(this); + realize_font(this); *pcharset = this->description.sCharset; @@ -1028,14 +949,12 @@ static HRESULT WINAPI OLEFontImpl_get_Charset( /************************************************************************ * OLEFontImpl_put_Charset (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_put_Charset( IFont* iface, short charset) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%d)\n", this, charset); this->description.sCharset = charset; @@ -1046,19 +965,17 @@ static HRESULT WINAPI OLEFontImpl_put_Charset( /************************************************************************ * OLEFontImpl_get_hFont (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_get_hFont( IFont* iface, HFONT* phfont) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, phfont); if (phfont==NULL) return E_POINTER; - if(this->dirty) realize_font(this); + realize_font(this); *phfont = this->gdiFont; TRACE("Returning %p\n", *phfont); @@ -1067,15 +984,13 @@ static HRESULT WINAPI OLEFontImpl_get_hFont( /************************************************************************ * OLEFontImpl_Clone (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_Clone( IFont* iface, IFont** ppfont) { - OLEFontImpl* newObject = 0; - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); + OLEFontImpl* newObject; TRACE("(%p)->(%p)\n", this, ppfont); @@ -1084,32 +999,19 @@ static HRESULT WINAPI OLEFontImpl_Clone( *ppfont = NULL; - /* - * Allocate space for the object. - */ newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl)); - if (newObject==NULL) return E_OUTOFMEMORY; *newObject = *this; - - /* We need to alloc new memory for the string, otherwise - * we free memory twice. - */ - newObject->description.lpstrName = HeapAlloc( - GetProcessHeap(),0, - (1+strlenW(this->description.lpstrName))*2 - ); - strcpyW(newObject->description.lpstrName, this->description.lpstrName); - + /* allocate separate buffer */ + newObject->description.lpstrName = strdupW(this->description.lpstrName); /* Increment internal ref in hfont item list */ if(newObject->gdiFont) inc_int_ref(newObject->gdiFont); InterlockedIncrement(&ifont_cnt); - /* create new connection points */ newObject->pPropertyNotifyCP = NULL; newObject->pFontEventsCP = NULL; CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP); @@ -1122,28 +1024,26 @@ static HRESULT WINAPI OLEFontImpl_Clone( } /* The cloned object starts with a reference count of 1 */ - newObject->ref = 1; + newObject->ref = 1; - *ppfont = (IFont*)newObject; + *ppfont = &newObject->IFont_iface; return S_OK; } /************************************************************************ * OLEFontImpl_IsEqual (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_IsEqual( IFont* iface, IFont* pFontOther) { - OLEFontImpl *left = (OLEFontImpl *)iface; - OLEFontImpl *right = (OLEFontImpl *)pFontOther; + OLEFontImpl *left = impl_from_IFont(iface); + OLEFontImpl *right = impl_from_IFont(pFontOther); INT ret; INT left_len,right_len; - if((iface == NULL) || (pFontOther == NULL)) + if(pFontOther == NULL) return E_POINTER; else if (left->description.cySize.s.Lo != right->description.cySize.s.Lo) return S_FALSE; @@ -1173,27 +1073,27 @@ static HRESULT WINAPI OLEFontImpl_IsEqual( /************************************************************************ * OLEFontImpl_SetRatio (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_SetRatio( IFont* iface, LONG cyLogical, LONG cyHimetric) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric); + if(cyLogical == 0 || cyHimetric == 0) + return E_INVALIDARG; + this->cyLogical = cyLogical; this->cyHimetric = cyHimetric; + this->dirty = TRUE; return S_OK; } /************************************************************************ * OLEFontImpl_QueryTextMetrics (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_QueryTextMetrics( IFont* iface, @@ -1203,7 +1103,7 @@ static HRESULT WINAPI OLEFontImpl_QueryTextMetrics( HFONT hOldFont, hNewFont; hdcRef = GetDC(0); - OLEFontImpl_get_hFont(iface, &hNewFont); + IFont_get_hFont(iface, &hNewFont); hOldFont = SelectObject(hdcRef, hNewFont); GetTextMetricsW(hdcRef, ptm); SelectObject(hdcRef, hOldFont); @@ -1213,14 +1113,12 @@ static HRESULT WINAPI OLEFontImpl_QueryTextMetrics( /************************************************************************ * OLEFontImpl_AddRefHfont (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_AddRefHfont( IFont* iface, HFONT hfont) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, hfont); @@ -1231,14 +1129,12 @@ static HRESULT WINAPI OLEFontImpl_AddRefHfont( /************************************************************************ * OLEFontImpl_ReleaseHfont (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_ReleaseHfont( IFont* iface, HFONT hfont) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); TRACE("(%p)->(%p)\n", this, hfont); @@ -1249,21 +1145,16 @@ static HRESULT WINAPI OLEFontImpl_ReleaseHfont( /************************************************************************ * OLEFontImpl_SetHdc (IFont) - * - * See Windows documentation for more details on IFont methods. */ static HRESULT WINAPI OLEFontImpl_SetHdc( IFont* iface, HDC hdc) { - OLEFontImpl *this = (OLEFontImpl *)iface; + OLEFontImpl *this = impl_from_IFont(iface); FIXME("(%p)->(%p): Stub\n", this, hdc); return E_NOTIMPL; } -/* - * Virtual function tables for the OLEFontImpl class. - */ static const IFontVtbl OLEFontImpl_VTable = { OLEFontImpl_QueryInterface, @@ -1297,8 +1188,6 @@ static const IFontVtbl OLEFontImpl_VTable = /************************************************************************ * OLEFontImpl_IDispatch_QueryInterface (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface( IDispatch* iface, @@ -1306,40 +1195,31 @@ static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface( VOID** ppvoid) { OLEFontImpl *this = impl_from_IDispatch(iface); - - return IFont_QueryInterface((IFont *)this, riid, ppvoid); + return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid); } /************************************************************************ * OLEFontImpl_IDispatch_Release (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static ULONG WINAPI OLEFontImpl_IDispatch_Release( IDispatch* iface) { OLEFontImpl *this = impl_from_IDispatch(iface); - - return IFont_Release((IFont *)this); + return IFont_Release(&this->IFont_iface); } /************************************************************************ * OLEFontImpl_IDispatch_AddRef (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static ULONG WINAPI OLEFontImpl_IDispatch_AddRef( IDispatch* iface) { OLEFontImpl *this = impl_from_IDispatch(iface); - - return IFont_AddRef((IFont *)this); + return IFont_AddRef(&this->IFont_iface); } /************************************************************************ * OLEFontImpl_GetTypeInfoCount (IDispatch) - * - * See Windows documentation for more details on IDispatch methods. */ static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount( IDispatch* iface, @@ -1354,8 +1234,6 @@ static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount( /************************************************************************ * OLEFontImpl_GetTypeInfo (IDispatch) - * - * See Windows documentation for more details on IDispatch methods. */ static HRESULT WINAPI OLEFontImpl_GetTypeInfo( IDispatch* iface, @@ -1386,8 +1264,6 @@ static HRESULT WINAPI OLEFontImpl_GetTypeInfo( /************************************************************************ * OLEFontImpl_GetIDsOfNames (IDispatch) - * - * See Windows documentation for more details on IDispatch methods. */ static HRESULT WINAPI OLEFontImpl_GetIDsOfNames( IDispatch* iface, @@ -1405,33 +1281,24 @@ static HRESULT WINAPI OLEFontImpl_GetIDsOfNames( TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid), rgszNames, cNames, (int)lcid, rgDispId); - if (cNames == 0) + if (cNames == 0) return E_INVALIDARG; + + hres = IDispatch_GetTypeInfo(iface, 0, lcid, &pTInfo); + if (FAILED(hres)) { - return E_INVALIDARG; - } - else - { - /* retrieve type information */ - hres = OLEFontImpl_GetTypeInfo(iface, 0, lcid, &pTInfo); - - if (FAILED(hres)) - { - ERR("GetTypeInfo failed.\n"); - return hres; - } - - /* convert names to DISPIDs */ - hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId); - ITypeInfo_Release(pTInfo); - + ERR("GetTypeInfo failed.\n"); return hres; } + + /* convert names to DISPIDs */ + hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(pTInfo); + + return hres; } /************************************************************************ * OLEFontImpl_Invoke (IDispatch) - * - * See Windows documentation for more details on IDispatch methods. * * Note: Do not call _put_Xxx methods, since setting things here * should not call notify functions as I found out debugging the generic @@ -1494,7 +1361,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( case DISPID_FONT_NAME: if (wFlags & DISPATCH_PROPERTYGET) { V_VT(pVarResult) = VT_BSTR; - return IFont_get_Name((IFont *)this, &V_BSTR(pVarResult)); + return IFont_get_Name(&this->IFont_iface, &V_BSTR(pVarResult)); } else { VARIANTARG vararg; @@ -1503,7 +1370,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( if (FAILED(hr)) return hr; - hr = IFont_put_Name((IFont *)this, V_BSTR(&vararg)); + hr = IFont_put_Name(&this->IFont_iface, V_BSTR(&vararg)); VariantClear(&vararg); return hr; @@ -1512,7 +1379,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( case DISPID_FONT_BOLD: if (wFlags & DISPATCH_PROPERTYGET) { BOOL value; - hr = IFont_get_Bold((IFont *)this, &value); + hr = IFont_get_Bold(&this->IFont_iface, &value); V_VT(pVarResult) = VT_BOOL; V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; return hr; @@ -1524,7 +1391,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( if (FAILED(hr)) return hr; - hr = IFont_put_Bold((IFont *)this, V_BOOL(&vararg)); + hr = IFont_put_Bold(&this->IFont_iface, V_BOOL(&vararg)); VariantClear(&vararg); return hr; @@ -1533,7 +1400,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( case DISPID_FONT_ITALIC: if (wFlags & DISPATCH_PROPERTYGET) { BOOL value; - hr = IFont_get_Italic((IFont *)this, &value); + hr = IFont_get_Italic(&this->IFont_iface, &value); V_VT(pVarResult) = VT_BOOL; V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; return hr; @@ -1545,7 +1412,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( if (FAILED(hr)) return hr; - hr = IFont_put_Italic((IFont *)this, V_BOOL(&vararg)); + hr = IFont_put_Italic(&this->IFont_iface, V_BOOL(&vararg)); VariantClear(&vararg); return hr; @@ -1554,7 +1421,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( case DISPID_FONT_UNDER: if (wFlags & DISPATCH_PROPERTYGET) { BOOL value; - hr = IFont_get_Underline((IFont *)this, &value); + hr = IFont_get_Underline(&this->IFont_iface, &value); V_VT(pVarResult) = VT_BOOL; V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; return hr; @@ -1566,7 +1433,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( if (FAILED(hr)) return hr; - hr = IFont_put_Underline((IFont *)this, V_BOOL(&vararg)); + hr = IFont_put_Underline(&this->IFont_iface, V_BOOL(&vararg)); VariantClear(&vararg); return hr; @@ -1575,7 +1442,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( case DISPID_FONT_STRIKE: if (wFlags & DISPATCH_PROPERTYGET) { BOOL value; - hr = IFont_get_Strikethrough((IFont *)this, &value); + hr = IFont_get_Strikethrough(&this->IFont_iface, &value); V_VT(pVarResult) = VT_BOOL; V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; return hr; @@ -1587,7 +1454,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( if (FAILED(hr)) return hr; - hr = IFont_put_Strikethrough((IFont *)this, V_BOOL(&vararg)); + hr = IFont_put_Strikethrough(&this->IFont_iface, V_BOOL(&vararg)); VariantClear(&vararg); return hr; @@ -1596,7 +1463,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( case DISPID_FONT_SIZE: if (wFlags & DISPATCH_PROPERTYGET) { V_VT(pVarResult) = VT_CY; - return OLEFontImpl_get_Size((IFont *)this, &V_CY(pVarResult)); + return IFont_get_Size(&this->IFont_iface, &V_CY(pVarResult)); } else { VARIANTARG vararg; @@ -1605,7 +1472,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( if (FAILED(hr)) return hr; - hr = IFont_put_Size((IFont *)this, V_CY(&vararg)); + hr = IFont_put_Size(&this->IFont_iface, V_CY(&vararg)); VariantClear(&vararg); return hr; @@ -1614,7 +1481,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( case DISPID_FONT_WEIGHT: if (wFlags & DISPATCH_PROPERTYGET) { V_VT(pVarResult) = VT_I2; - return OLEFontImpl_get_Weight((IFont *)this, &V_I2(pVarResult)); + return IFont_get_Weight(&this->IFont_iface, &V_I2(pVarResult)); } else { VARIANTARG vararg; @@ -1623,7 +1490,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( if (FAILED(hr)) return hr; - hr = IFont_put_Weight((IFont *)this, V_I2(&vararg)); + hr = IFont_put_Weight(&this->IFont_iface, V_I2(&vararg)); VariantClear(&vararg); return hr; @@ -1632,7 +1499,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( case DISPID_FONT_CHARSET: if (wFlags & DISPATCH_PROPERTYGET) { V_VT(pVarResult) = VT_I2; - return OLEFontImpl_get_Charset((IFont *)this, &V_I2(pVarResult)); + return OLEFontImpl_get_Charset(&this->IFont_iface, &V_I2(pVarResult)); } else { VARIANTARG vararg; @@ -1641,7 +1508,7 @@ static HRESULT WINAPI OLEFontImpl_Invoke( if (FAILED(hr)) return hr; - hr = IFont_put_Charset((IFont *)this, V_I2(&vararg)); + hr = IFont_put_Charset(&this->IFont_iface, V_I2(&vararg)); VariantClear(&vararg); return hr; @@ -1666,8 +1533,6 @@ static const IDispatchVtbl OLEFontImpl_IDispatch_VTable = /************************************************************************ * OLEFontImpl_IPersistStream_QueryInterface (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface( IPersistStream* iface, @@ -1676,39 +1541,33 @@ static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface( { OLEFontImpl *this = impl_from_IPersistStream(iface); - return IFont_QueryInterface((IFont *)this, riid, ppvoid); + return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid); } /************************************************************************ * OLEFontImpl_IPersistStream_Release (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static ULONG WINAPI OLEFontImpl_IPersistStream_Release( IPersistStream* iface) { OLEFontImpl *this = impl_from_IPersistStream(iface); - return IFont_Release((IFont *)this); + return IFont_Release(&this->IFont_iface); } /************************************************************************ * OLEFontImpl_IPersistStream_AddRef (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef( IPersistStream* iface) { OLEFontImpl *this = impl_from_IPersistStream(iface); - return IFont_AddRef((IFont *)this); + return IFont_AddRef(&this->IFont_iface); } /************************************************************************ * OLEFontImpl_GetClassID (IPersistStream) - * - * See Windows documentation for more details on IPersistStream methods. */ static HRESULT WINAPI OLEFontImpl_GetClassID( IPersistStream* iface, @@ -1760,80 +1619,50 @@ static HRESULT WINAPI OLEFontImpl_Load( IPersistStream* iface, IStream* pLoadStream) { - char readBuffer[0x100]; + OLEFontImpl *this = impl_from_IPersistStream(iface); + BYTE version, attributes, string_size; + char readBuffer[0x100]; ULONG cbRead; - BYTE bVersion; - BYTE bAttributes; - BYTE bStringSize; INT len; - OLEFontImpl *this = impl_from_IPersistStream(iface); + /* Version */ + IStream_Read(pLoadStream, &version, sizeof(BYTE), &cbRead); + if ((cbRead != sizeof(BYTE)) || (version != 0x01)) return E_FAIL; - /* - * Read the version byte - */ - IStream_Read(pLoadStream, &bVersion, 1, &cbRead); + /* Charset */ + IStream_Read(pLoadStream, &this->description.sCharset, sizeof(WORD), &cbRead); + if (cbRead != sizeof(WORD)) return E_FAIL; - if ( (cbRead!=1) || - (bVersion!=0x01) ) - return E_FAIL; + /* Attributes */ + IStream_Read(pLoadStream, &attributes, sizeof(BYTE), &cbRead); + if (cbRead != sizeof(BYTE)) return E_FAIL; - /* - * Charset - */ - IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead); + this->description.fItalic = (attributes & FONTPERSIST_ITALIC) != 0; + this->description.fStrikethrough = (attributes & FONTPERSIST_STRIKETHROUGH) != 0; + this->description.fUnderline = (attributes & FONTPERSIST_UNDERLINE) != 0; - if (cbRead!=2) - return E_FAIL; + /* Weight */ + IStream_Read(pLoadStream, &this->description.sWeight, sizeof(WORD), &cbRead); + if (cbRead != sizeof(WORD)) return E_FAIL; - /* - * Attributes - */ - IStream_Read(pLoadStream, &bAttributes, 1, &cbRead); - - if (cbRead!=1) - return E_FAIL; - - this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0; - this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0; - this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0; - - /* - * Weight - */ - IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead); - - if (cbRead!=2) - return E_FAIL; - - /* - * Size - */ - IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead); - - if (cbRead!=4) - return E_FAIL; + /* Size */ + IStream_Read(pLoadStream, &this->description.cySize.s.Lo, sizeof(DWORD), &cbRead); + if (cbRead != sizeof(DWORD)) return E_FAIL; this->description.cySize.s.Hi = 0; - /* - * FontName - */ - IStream_Read(pLoadStream, &bStringSize, 1, &cbRead); + /* Name */ + IStream_Read(pLoadStream, &string_size, sizeof(BYTE), &cbRead); + if (cbRead != sizeof(BYTE)) return E_FAIL; - if (cbRead!=1) - return E_FAIL; - - IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead); - - if (cbRead!=bStringSize) - return E_FAIL; + IStream_Read(pLoadStream, readBuffer, string_size, &cbRead); + if (cbRead != string_size) return E_FAIL; HeapFree(GetProcessHeap(), 0, this->description.lpstrName); - len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 ); + len = MultiByteToWideChar( CP_ACP, 0, readBuffer, string_size, NULL, 0 ); this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len ); + MultiByteToWideChar( CP_ACP, 0, readBuffer, string_size, this->description.lpstrName, len ); this->description.lpstrName[len] = 0; /* Ensure use of this font causes a new one to be created */ @@ -1846,99 +1675,72 @@ static HRESULT WINAPI OLEFontImpl_Load( /************************************************************************ * OLEFontImpl_Save (IPersistStream) - * - * See Windows documentation for more details on IPersistStream methods. */ static HRESULT WINAPI OLEFontImpl_Save( IPersistStream* iface, IStream* pOutStream, BOOL fClearDirty) { - char* writeBuffer = NULL; - ULONG cbWritten; - BYTE bVersion = 0x01; - BYTE bAttributes; - BYTE bStringSize; - OLEFontImpl *this = impl_from_IPersistStream(iface); + BYTE attributes, string_size; + const BYTE version = 0x01; + char* writeBuffer = NULL; + ULONG written; - /* - * Read the version byte - */ - IStream_Write(pOutStream, &bVersion, 1, &cbWritten); + TRACE("(%p)->(%p %d)\n", this, pOutStream, fClearDirty); - if (cbWritten!=1) - return E_FAIL; + /* Version */ + IStream_Write(pOutStream, &version, sizeof(BYTE), &written); + if (written != sizeof(BYTE)) return E_FAIL; - /* - * Charset - */ - IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten); + /* Charset */ + IStream_Write(pOutStream, &this->description.sCharset, sizeof(WORD), &written); + if (written != sizeof(WORD)) return E_FAIL; - if (cbWritten!=2) - return E_FAIL; - - /* - * Attributes - */ - bAttributes = 0; + /* Attributes */ + attributes = 0; if (this->description.fItalic) - bAttributes |= FONTPERSIST_ITALIC; + attributes |= FONTPERSIST_ITALIC; if (this->description.fStrikethrough) - bAttributes |= FONTPERSIST_STRIKETHROUGH; + attributes |= FONTPERSIST_STRIKETHROUGH; if (this->description.fUnderline) - bAttributes |= FONTPERSIST_UNDERLINE; + attributes |= FONTPERSIST_UNDERLINE; - IStream_Write(pOutStream, &bAttributes, 1, &cbWritten); + IStream_Write(pOutStream, &attributes, sizeof(BYTE), &written); + if (written != sizeof(BYTE)) return E_FAIL; - if (cbWritten!=1) - return E_FAIL; + /* Weight */ + IStream_Write(pOutStream, &this->description.sWeight, sizeof(WORD), &written); + if (written != sizeof(WORD)) return E_FAIL; - /* - * Weight - */ - IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten); + /* Size */ + IStream_Write(pOutStream, &this->description.cySize.s.Lo, sizeof(DWORD), &written); + if (written != sizeof(DWORD)) return E_FAIL; - if (cbWritten!=2) - return E_FAIL; - - /* - * Size - */ - IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten); - - if (cbWritten!=4) - return E_FAIL; - - /* - * FontName - */ - if (this->description.lpstrName!=0) - bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, + /* FontName */ + if (this->description.lpstrName) + string_size = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, strlenW(this->description.lpstrName), NULL, 0, NULL, NULL ); else - bStringSize = 0; + string_size = 0; - IStream_Write(pOutStream, &bStringSize, 1, &cbWritten); + IStream_Write(pOutStream, &string_size, sizeof(BYTE), &written); + if (written != sizeof(BYTE)) return E_FAIL; - if (cbWritten!=1) - return E_FAIL; - - if (bStringSize!=0) + if (string_size) { - if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY; + if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, string_size ))) return E_OUTOFMEMORY; WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, strlenW(this->description.lpstrName), - writeBuffer, bStringSize, NULL, NULL ); + writeBuffer, string_size, NULL, NULL ); - IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten); - HeapFree(GetProcessHeap(), 0, writeBuffer); + IStream_Write(pOutStream, writeBuffer, string_size, &written); + HeapFree(GetProcessHeap(), 0, writeBuffer); - if (cbWritten!=bStringSize) - return E_FAIL; + if (written != string_size) return E_FAIL; } return S_OK; @@ -1946,8 +1748,6 @@ static HRESULT WINAPI OLEFontImpl_Save( /************************************************************************ * OLEFontImpl_GetSizeMax (IPersistStream) - * - * See Windows documentation for more details on IPersistStream methods. */ static HRESULT WINAPI OLEFontImpl_GetSizeMax( IPersistStream* iface, @@ -1990,8 +1790,6 @@ static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable = /************************************************************************ * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface( IConnectionPointContainer* iface, @@ -2000,40 +1798,33 @@ static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface( { OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); - return IFont_QueryInterface((IFont*)this, riid, ppvoid); + return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid); } /************************************************************************ * OLEFontImpl_IConnectionPointContainer_Release (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release( IConnectionPointContainer* iface) { OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); - return IFont_Release((IFont*)this); + return IFont_Release(&this->IFont_iface); } /************************************************************************ * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown) - * - * See Windows documentation for more details on IUnknown methods. */ static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef( IConnectionPointContainer* iface) { OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); - return IFont_AddRef((IFont*)this); + return IFont_AddRef(&this->IFont_iface); } /************************************************************************ * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer) - * - * See Windows documentation for more details on IConnectionPointContainer - * methods. */ static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints( IConnectionPointContainer* iface, @@ -2047,9 +1838,6 @@ static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints( /************************************************************************ * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer) - * - * See Windows documentation for more details on IConnectionPointContainer - * methods. */ static HRESULT WINAPI OLEFontImpl_FindConnectionPoint( IConnectionPointContainer* iface, @@ -2090,21 +1878,21 @@ static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface( IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj ) { OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); - return IFont_QueryInterface((IFont *)this,riid,ppvObj); + return IFont_QueryInterface(&this->IFont_iface,riid,ppvObj); } static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef( IPersistPropertyBag *iface ) { OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); - return IFont_AddRef((IFont *)this); + return IFont_AddRef(&this->IFont_iface); } static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release( IPersistPropertyBag *iface ) { OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); - return IFont_Release((IFont *)this); + return IFont_Release(&this->IFont_iface); } static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID( @@ -2140,111 +1928,106 @@ static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load( static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0}; static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0}; static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0}; - VARIANT rawAttr; - VARIANT valueAttr; - HRESULT iRes = S_OK; OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); + VARIANT value; + HRESULT iRes; - VariantInit(&rawAttr); - VariantInit(&valueAttr); + VariantInit(&value); + + iRes = IPropertyBag_Read(pPropBag, sAttrName, &value, pErrorLog); + if (iRes == S_OK) + { + iRes = VariantChangeType(&value, &value, 0, VT_BSTR); + if (iRes == S_OK) + iRes = IFont_put_Name(&this->IFont_iface, V_BSTR(&value)); + } + else if (iRes == E_INVALIDARG) + iRes = S_OK; + + VariantClear(&value); if (iRes == S_OK) { - iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog); + iRes = IPropertyBag_Read(pPropBag, sAttrSize, &value, pErrorLog); if (iRes == S_OK) { - iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR); + iRes = VariantChangeType(&value, &value, 0, VT_CY); if (iRes == S_OK) - iRes = IFont_put_Name((IFont *)this, V_BSTR(&valueAttr)); + iRes = IFont_put_Size(&this->IFont_iface, V_CY(&value)); } else if (iRes == E_INVALIDARG) iRes = S_OK; - VariantClear(&rawAttr); - VariantClear(&valueAttr); + + VariantClear(&value); } if (iRes == S_OK) { - iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog); + iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &value, pErrorLog); if (iRes == S_OK) { - iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY); + iRes = VariantChangeType(&value, &value, 0, VT_I2); if (iRes == S_OK) - iRes = IFont_put_Size((IFont *)this, V_CY(&valueAttr)); + iRes = IFont_put_Charset(&this->IFont_iface, V_I2(&value)); } else if (iRes == E_INVALIDARG) iRes = S_OK; - VariantClear(&rawAttr); - VariantClear(&valueAttr); + + VariantClear(&value); } if (iRes == S_OK) { - iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog); + iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &value, pErrorLog); if (iRes == S_OK) { - iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2); + iRes = VariantChangeType(&value, &value, 0, VT_I2); if (iRes == S_OK) - iRes = IFont_put_Charset((IFont *)this, V_I2(&valueAttr)); + iRes = IFont_put_Weight(&this->IFont_iface, V_I2(&value)); } else if (iRes == E_INVALIDARG) iRes = S_OK; - VariantClear(&rawAttr); - VariantClear(&valueAttr); + + VariantClear(&value); } if (iRes == S_OK) { - iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog); + iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &value, pErrorLog); if (iRes == S_OK) { - iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2); + iRes = VariantChangeType(&value, &value, 0, VT_BOOL); if (iRes == S_OK) - iRes = IFont_put_Weight((IFont *)this, V_I2(&valueAttr)); + iRes = IFont_put_Underline(&this->IFont_iface, V_BOOL(&value)); } else if (iRes == E_INVALIDARG) iRes = S_OK; - VariantClear(&rawAttr); - VariantClear(&valueAttr); + VariantClear(&value); } if (iRes == S_OK) { - iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog); + iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &value, pErrorLog); if (iRes == S_OK) { - iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); + iRes = VariantChangeType(&value, &value, 0, VT_BOOL); if (iRes == S_OK) - iRes = IFont_put_Underline((IFont *)this, V_BOOL(&valueAttr)); + iRes = IFont_put_Italic(&this->IFont_iface, V_BOOL(&value)); } else if (iRes == E_INVALIDARG) iRes = S_OK; - VariantClear(&rawAttr); - VariantClear(&valueAttr); + + VariantClear(&value); } if (iRes == S_OK) { - iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog); + iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &value, pErrorLog); if (iRes == S_OK) { - iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); + iRes = VariantChangeType(&value, &value, 0, VT_BOOL); if (iRes == S_OK) - iRes = IFont_put_Italic((IFont *)this, V_BOOL(&valueAttr)); + IFont_put_Strikethrough(&this->IFont_iface, V_BOOL(&value)); } else if (iRes == E_INVALIDARG) iRes = S_OK; - VariantClear(&rawAttr); - VariantClear(&valueAttr); - } - if (iRes == S_OK) { - iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog); - if (iRes == S_OK) - { - iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); - if (iRes == S_OK) - IFont_put_Strikethrough((IFont *)this, V_BOOL(&valueAttr)); - } - else if (iRes == E_INVALIDARG) - iRes = S_OK; - VariantClear(&rawAttr); - VariantClear(&valueAttr); + VariantClear(&value); } if (FAILED(iRes)) @@ -2279,21 +2062,21 @@ static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface( IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj ) { OLEFontImpl *this = impl_from_IPersistStreamInit(iface); - return IFont_QueryInterface((IFont *)this,riid,ppvObj); + return IFont_QueryInterface(&this->IFont_iface,riid,ppvObj); } static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef( IPersistStreamInit *iface ) { OLEFontImpl *this = impl_from_IPersistStreamInit(iface); - return IFont_AddRef((IFont *)this); + return IFont_AddRef(&this->IFont_iface); } static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release( IPersistStreamInit *iface ) { OLEFontImpl *this = impl_from_IPersistStreamInit(iface); - return IFont_Release((IFont *)this); + return IFont_Release(&this->IFont_iface); } static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID( @@ -2363,42 +2146,24 @@ static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable = */ static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc) { - OLEFontImpl* newObject = 0; + OLEFontImpl* newObject; - /* - * Allocate space for the object. - */ newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl)); if (newObject==0) return newObject; - /* - * Initialize the virtual function table. - */ - newObject->lpVtbl = &OLEFontImpl_VTable; - newObject->lpvtblIDispatch = &OLEFontImpl_IDispatch_VTable; - newObject->lpvtblIPersistStream = &OLEFontImpl_IPersistStream_VTable; - newObject->lpvtblIConnectionPointContainer = &OLEFontImpl_IConnectionPointContainer_VTable; - newObject->lpvtblIPersistPropertyBag = &OLEFontImpl_IPersistPropertyBag_VTable; - newObject->lpvtblIPersistStreamInit = &OLEFontImpl_IPersistStreamInit_VTable; + newObject->IFont_iface.lpVtbl = &OLEFontImpl_VTable; + newObject->IDispatch_iface.lpVtbl = &OLEFontImpl_IDispatch_VTable; + newObject->IPersistStream_iface.lpVtbl = &OLEFontImpl_IPersistStream_VTable; + newObject->IConnectionPointContainer_iface.lpVtbl = &OLEFontImpl_IConnectionPointContainer_VTable; + newObject->IPersistPropertyBag_iface.lpVtbl = &OLEFontImpl_IPersistPropertyBag_VTable; + newObject->IPersistStreamInit_iface.lpVtbl = &OLEFontImpl_IPersistStreamInit_VTable; - /* - * Start with one reference count. The caller of this function - * must release the interface pointer when it is done. - */ newObject->ref = 1; - /* - * Copy the description of the font in the object. - */ - assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC)); - newObject->description.cbSizeofstruct = sizeof(FONTDESC); - newObject->description.lpstrName = HeapAlloc(GetProcessHeap(), - 0, - (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR)); - strcpyW(newObject->description.lpstrName, fontDesc->lpstrName); + newObject->description.lpstrName = strdupW(fontDesc->lpstrName); newObject->description.cySize = fontDesc->cySize; newObject->description.sWeight = fontDesc->sWeight; newObject->description.sCharset = fontDesc->sCharset; @@ -2406,18 +2171,15 @@ static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc) newObject->description.fUnderline = fontDesc->fUnderline; newObject->description.fStrikethrough = fontDesc->fStrikethrough; - /* - * Initializing all the other members. - */ newObject->gdiFont = 0; newObject->dirty = TRUE; - newObject->cyLogical = 72L; + newObject->cyLogical = GetDeviceCaps(get_dc(), LOGPIXELSY); newObject->cyHimetric = 2540L; newObject->pPropertyNotifyCP = NULL; newObject->pFontEventsCP = NULL; - CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP); - CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP); + CreateConnectionPoint((IUnknown*)&newObject->IFont_iface, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP); + CreateConnectionPoint((IUnknown*)&newObject->IFont_iface, &IID_IFontEventsDisp, &newObject->pFontEventsCP); if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP) { @@ -2458,13 +2220,18 @@ static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc) typedef struct { /* IUnknown fields */ - const IClassFactoryVtbl *lpVtbl; - LONG ref; + IClassFactory IClassFactory_iface; + LONG ref; } IClassFactoryImpl; +static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); +} + static HRESULT WINAPI SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj); return E_NOINTERFACE; @@ -2472,12 +2239,12 @@ SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { static ULONG WINAPI SFCF_AddRef(LPCLASSFACTORY iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); return InterlockedIncrement(&This->ref); } static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); /* static class, won't be freed */ return InterlockedDecrement(&This->ref); } @@ -2490,7 +2257,7 @@ static HRESULT WINAPI SFCF_CreateInstance( } static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); FIXME("(%p)->(%d),stub!\n",This,dolock); return S_OK; } @@ -2502,6 +2269,6 @@ static const IClassFactoryVtbl SFCF_Vtbl = { SFCF_CreateInstance, SFCF_LockServer }; -static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 }; +static IClassFactoryImpl STDFONT_CF = {{&SFCF_Vtbl}, 1 }; void _get_STDFONT_CF(LPVOID *ppv) { *ppv = &STDFONT_CF; } diff --git a/reactos/dll/win32/oleaut32/olepicture.c b/reactos/dll/win32/oleaut32/olepicture.c index b8e949d2bd8..3fdb1c7e0cf 100644 --- a/reactos/dll/win32/oleaut32/olepicture.c +++ b/reactos/dll/win32/oleaut32/olepicture.c @@ -60,12 +60,19 @@ #include "oleauto.h" #include "connpt.h" #include "urlmon.h" +#include "initguid.h" #include "wincodec.h" #include "wine/debug.h" #include "wine/unicode.h" #include "wine/library.h" -WINE_DEFAULT_DEBUG_CHANNEL(ole); +WINE_DEFAULT_DEBUG_CHANNEL(olepicture); + +#define BITMAP_FORMAT_BMP 0x4d42 /* "BM" */ +#define BITMAP_FORMAT_JPEG 0xd8ff +#define BITMAP_FORMAT_GIF 0x4947 +#define BITMAP_FORMAT_PNG 0x5089 +#define BITMAP_FORMAT_APM 0xcdd7 #include "pshpack1.h" @@ -114,10 +121,10 @@ typedef struct OLEPictureImpl { * IPicture handles IUnknown */ - const IPictureVtbl *lpVtbl; - const IDispatchVtbl *lpvtblIDispatch; - const IPersistStreamVtbl *lpvtblIPersistStream; - const IConnectionPointContainerVtbl *lpvtblIConnectionPointContainer; + IPicture IPicture_iface; + IDispatch IDispatch_iface; + IPersistStream IPersistStream_iface; + IConnectionPointContainer IConnectionPointContainer_iface; /* Object reference count */ LONG ref; @@ -140,6 +147,7 @@ typedef struct OLEPictureImpl { BOOL keepOrigFormat; HDC hDCCur; + HBITMAP stock_bitmap; /* Bitmap transparency mask */ HBITMAP hbmMask; @@ -154,23 +162,24 @@ typedef struct OLEPictureImpl { unsigned int loadtime_format; /* for PICTYPE_BITMAP only, keeps track of image format (GIF/BMP/JPEG) */ } OLEPictureImpl; -/* - * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables. - */ +static inline OLEPictureImpl *impl_from_IPicture(IPicture *iface) +{ + return CONTAINING_RECORD(iface, OLEPictureImpl, IPicture_iface); +} static inline OLEPictureImpl *impl_from_IDispatch( IDispatch *iface ) { - return (OLEPictureImpl *)((char*)iface - FIELD_OFFSET(OLEPictureImpl, lpvtblIDispatch)); + return CONTAINING_RECORD(iface, OLEPictureImpl, IDispatch_iface); } static inline OLEPictureImpl *impl_from_IPersistStream( IPersistStream *iface ) { - return (OLEPictureImpl *)((char*)iface - FIELD_OFFSET(OLEPictureImpl, lpvtblIPersistStream)); + return CONTAINING_RECORD(iface, OLEPictureImpl, IPersistStream_iface); } static inline OLEPictureImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface ) { - return (OLEPictureImpl *)((char*)iface - FIELD_OFFSET(OLEPictureImpl, lpvtblIConnectionPointContainer)); + return CONTAINING_RECORD(iface, OLEPictureImpl, IConnectionPointContainer_iface); } /* @@ -181,28 +190,48 @@ static const IDispatchVtbl OLEPictureImpl_IDispatch_VTable; static const IPersistStreamVtbl OLEPictureImpl_IPersistStream_VTable; static const IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContainer_VTable; +/* pixels to HIMETRIC units conversion */ +static inline OLE_XSIZE_HIMETRIC xpixels_to_himetric(INT pixels, HDC hdc) +{ + return MulDiv(pixels, 2540, GetDeviceCaps(hdc, LOGPIXELSX)); +} + +static inline OLE_YSIZE_HIMETRIC ypixels_to_himetric(INT pixels, HDC hdc) +{ + return MulDiv(pixels, 2540, GetDeviceCaps(hdc, LOGPIXELSY)); +} + /*********************************************************************** * Implementation of the OLEPictureImpl class. */ -static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) { +static void OLEPictureImpl_SetBitmap(OLEPictureImpl *This) +{ BITMAP bm; HDC hdcRef; TRACE("bitmap handle %p\n", This->desc.u.bmp.hbitmap); - if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) { + if(GetObjectW(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) { ERR("GetObject fails\n"); return; } This->origWidth = bm.bmWidth; This->origHeight = bm.bmHeight; + + TRACE("width %d, height %d, bpp %d\n", bm.bmWidth, bm.bmHeight, bm.bmBitsPixel); + /* The width and height are stored in HIMETRIC units (0.01 mm), so we take our pixel width divide by pixels per inch and multiply by 25.4 * 100 */ /* Should we use GetBitmapDimension if available? */ hdcRef = CreateCompatibleDC(0); - This->himetricWidth =(bm.bmWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX); - This->himetricHeight=(bm.bmHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY); + + This->himetricWidth = xpixels_to_himetric(bm.bmWidth, hdcRef); + This->himetricHeight = ypixels_to_himetric(bm.bmHeight, hdcRef); + This->stock_bitmap = GetCurrentObject( hdcRef, OBJ_BITMAP ); + + This->loadtime_format = BITMAP_FORMAT_BMP; + DeleteDC(hdcRef); } @@ -216,7 +245,7 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This) BITMAP bm; TRACE("bitmap handle for icon is %p\n", infoIcon.hbmColor); - if(GetObjectA(infoIcon.hbmColor ? infoIcon.hbmColor : infoIcon.hbmMask, sizeof(bm), &bm) != sizeof(bm)) { + if(GetObjectW(infoIcon.hbmColor ? infoIcon.hbmColor : infoIcon.hbmMask, sizeof(bm), &bm) != sizeof(bm)) { ERR("GetObject fails on icon bitmap\n"); return; } @@ -225,8 +254,10 @@ static void OLEPictureImpl_SetIcon(OLEPictureImpl * This) This->origHeight = infoIcon.hbmColor ? bm.bmHeight : bm.bmHeight / 2; /* see comment on HIMETRIC on OLEPictureImpl_SetBitmap() */ hdcRef = GetDC(0); - This->himetricWidth = (This->origWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX); - This->himetricHeight= (This->origHeight *2540)/GetDeviceCaps(hdcRef, LOGPIXELSY); + + This->himetricWidth = xpixels_to_himetric(This->origWidth, hdcRef); + This->himetricHeight = ypixels_to_himetric(This->origHeight, hdcRef); + ReleaseDC(0, hdcRef); DeleteObject(infoIcon.hbmMask); @@ -263,10 +294,10 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn) /* * Initialize the virtual function table. */ - newObject->lpVtbl = &OLEPictureImpl_VTable; - newObject->lpvtblIDispatch = &OLEPictureImpl_IDispatch_VTable; - newObject->lpvtblIPersistStream = &OLEPictureImpl_IPersistStream_VTable; - newObject->lpvtblIConnectionPointContainer = &OLEPictureImpl_IConnectionPointContainer_VTable; + newObject->IPicture_iface.lpVtbl = &OLEPictureImpl_VTable; + newObject->IDispatch_iface.lpVtbl = &OLEPictureImpl_IDispatch_VTable; + newObject->IPersistStream_iface.lpVtbl = &OLEPictureImpl_IPersistStream_VTable; + newObject->IConnectionPointContainer_iface.lpVtbl = &OLEPictureImpl_IConnectionPointContainer_VTable; newObject->pCP = NULL; CreateConnectionPoint((IUnknown*)newObject,&IID_IPropertyNotifySink,&newObject->pCP); @@ -381,7 +412,7 @@ static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj) static ULONG WINAPI OLEPictureImpl_AddRef( IPicture* iface) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before=%d)\n", This, refCount - 1); @@ -397,7 +428,7 @@ static ULONG WINAPI OLEPictureImpl_AddRef( static ULONG WINAPI OLEPictureImpl_Release( IPicture* iface) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before=%d)\n", This, refCount + 1); @@ -420,48 +451,33 @@ static HRESULT WINAPI OLEPictureImpl_QueryInterface( REFIID riid, void** ppvObject) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); - /* - * Perform a sanity check on the parameters. - */ - if ( (This==0) || (ppvObject==0) ) + if (!ppvObject) return E_INVALIDARG; - /* - * Initialize the return parameter. - */ *ppvObject = 0; - /* - * Compare the riid with the interface IDs implemented by this object. - */ if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IPicture, riid)) *ppvObject = This; else if (IsEqualIID(&IID_IDispatch, riid)) - *ppvObject = &This->lpvtblIDispatch; + *ppvObject = &This->IDispatch_iface; else if (IsEqualIID(&IID_IPictureDisp, riid)) - *ppvObject = &This->lpvtblIDispatch; + *ppvObject = &This->IDispatch_iface; else if (IsEqualIID(&IID_IPersist, riid) || IsEqualIID(&IID_IPersistStream, riid)) - *ppvObject = &This->lpvtblIPersistStream; + *ppvObject = &This->IPersistStream_iface; else if (IsEqualIID(&IID_IConnectionPointContainer, riid)) - *ppvObject = &This->lpvtblIConnectionPointContainer; + *ppvObject = &This->IConnectionPointContainer_iface; - /* - * Check that we obtained an interface. - */ - if ((*ppvObject)==0) + if (!*ppvObject) { FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid)); return E_NOINTERFACE; } - /* - * Query Interface always increases the reference count by one when it is - * successful - */ - OLEPictureImpl_AddRef((IPicture*)This); + IPicture_AddRef(iface); return S_OK; } @@ -477,7 +493,7 @@ static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID) IEnumConnections *pEnum; CONNECTDATA CD; - if (IConnectionPoint_EnumConnections(this->pCP, &pEnum)) + if (IConnectionPoint_EnumConnections(this->pCP, &pEnum) != S_OK) return; while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { IPropertyNotifySink *sink; @@ -496,7 +512,7 @@ static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID) static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface, OLE_HANDLE *phandle) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%p)\n", This, phandle); if(!phandle) @@ -533,7 +549,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface, OLE_HANDLE *phandle) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); HRESULT hres; TRACE("(%p)->(%p)\n", This, phandle); @@ -572,7 +588,7 @@ static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface, short *ptype) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%p): type is %d\n", This, ptype, This->desc.picType); if(!ptype) @@ -588,7 +604,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface, OLE_XSIZE_HIMETRIC *pwidth) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%p): width is %d\n", This, pwidth, This->himetricWidth); *pwidth = This->himetricWidth; return S_OK; @@ -600,7 +616,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface, OLE_YSIZE_HIMETRIC *pheight) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%p): height is %d\n", This, pheight, This->himetricHeight); *pheight = This->himetricHeight; return S_OK; @@ -617,7 +633,7 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc, OLE_YSIZE_HIMETRIC cySrc, LPCRECT prcWBounds) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%p, (%d,%d), (%d,%d) <- (%d,%d), (%d,%d), %p)\n", This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, prcWBounds); if(prcWBounds) @@ -736,7 +752,7 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc, static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface, OLE_HANDLE hpal) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); FIXME("(%p)->(%08x): stub\n", This, hpal); OLEPicture_SendNotify(This,DISPID_PICT_HPAL); return E_NOTIMPL; @@ -748,7 +764,7 @@ static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface, HDC *phdc) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p), returning %p\n", This, This->hDCCur); if (phdc) *phdc = This->hDCCur; return S_OK; @@ -762,13 +778,13 @@ static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface, HDC *phdcOut, OLE_HANDLE *phbmpOut) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%p, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut); if (This->desc.picType == PICTYPE_BITMAP) { - SelectObject(hdcIn,This->desc.u.bmp.hbitmap); - if (phdcOut) *phdcOut = This->hDCCur; + if (This->hDCCur) SelectObject(This->hDCCur,This->stock_bitmap); + if (hdcIn) SelectObject(hdcIn,This->desc.u.bmp.hbitmap); This->hDCCur = hdcIn; if (phbmpOut) *phbmpOut = HandleToUlong(This->desc.u.bmp.hbitmap); @@ -785,7 +801,7 @@ static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface, BOOL *pfKeep) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%p)\n", This, pfKeep); if (!pfKeep) return E_POINTER; @@ -799,7 +815,7 @@ static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface, BOOL keep) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%d)\n", This, keep); This->keepOrigFormat = keep; /* FIXME: what DISPID notification here? */ @@ -811,7 +827,7 @@ static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface, */ static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->()\n", This); OLEPicture_SendNotify(This,DISPID_PICT_HANDLE); This->bIsDirty = TRUE; @@ -826,7 +842,7 @@ static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface, BOOL SaveMemCopy, LONG *pcbSize) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, pcbSize); return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize); } @@ -837,7 +853,7 @@ static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface, DWORD *pdwAttr) { - OLEPictureImpl *This = (OLEPictureImpl *)iface; + OLEPictureImpl *This = impl_from_IPicture(iface); TRACE("(%p)->(%p).\n", This, pdwAttr); if(!pdwAttr) @@ -867,7 +883,7 @@ static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface( { OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface); - return IPicture_QueryInterface((IPicture *)This,riid,ppvoid); + return IPicture_QueryInterface(&This->IPicture_iface,riid,ppvoid); } static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef( @@ -875,7 +891,7 @@ static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef( { OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface); - return IPicture_AddRef((IPicture *)This); + return IPicture_AddRef(&This->IPicture_iface); } static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release( @@ -883,7 +899,7 @@ static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release( { OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface); - return IPicture_Release((IPicture *)This); + return IPicture_Release(&This->IPicture_iface); } static HRESULT WINAPI OLEPictureImpl_EnumConnectionPoints( @@ -929,7 +945,7 @@ static HRESULT WINAPI OLEPictureImpl_IPersistStream_QueryInterface( { OLEPictureImpl *This = impl_from_IPersistStream(iface); - return IPicture_QueryInterface((IPicture *)This, riid, ppvoid); + return IPicture_QueryInterface(&This->IPicture_iface, riid, ppvoid); } /************************************************************************ @@ -942,7 +958,7 @@ static ULONG WINAPI OLEPictureImpl_IPersistStream_AddRef( { OLEPictureImpl *This = impl_from_IPersistStream(iface); - return IPicture_AddRef((IPicture *)This); + return IPicture_AddRef(&This->IPicture_iface); } /************************************************************************ @@ -955,7 +971,7 @@ static ULONG WINAPI OLEPictureImpl_IPersistStream_Release( { OLEPictureImpl *This = impl_from_IPersistStream(iface); - return IPicture_Release((IPicture *)This); + return IPicture_Release(&This->IPicture_iface); } /************************************************************************ @@ -1222,16 +1238,34 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x } if (i==cifd->idCount) i=0; } - - hicon = CreateIconFromResourceEx( - xbuf+cifd->idEntries[i].dwDIBOffset, - cifd->idEntries[i].dwDIBSize, - TRUE, /* is icon */ - 0x00030000, - cifd->idEntries[i].bWidth, - cifd->idEntries[i].bHeight, - 0 - ); + if (cifd->idType == 2) + { + LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, cifd->idEntries[i].dwDIBSize + 4); + memcpy(buf, &cifd->idEntries[i].xHotspot, 4); + memcpy(buf + 4, xbuf+cifd->idEntries[i].dwDIBOffset, cifd->idEntries[i].dwDIBSize); + hicon = CreateIconFromResourceEx( + buf, + cifd->idEntries[i].dwDIBSize + 4, + FALSE, /* is cursor */ + 0x00030000, + cifd->idEntries[i].bWidth, + cifd->idEntries[i].bHeight, + 0 + ); + HeapFree(GetProcessHeap(), 0, buf); + } + else + { + hicon = CreateIconFromResourceEx( + xbuf+cifd->idEntries[i].dwDIBOffset, + cifd->idEntries[i].dwDIBSize, + TRUE, /* is icon */ + 0x00030000, + cifd->idEntries[i].bWidth, + cifd->idEntries[i].bHeight, + 0 + ); + } if (!hicon) { ERR("CreateIcon failed.\n"); return E_FAIL; @@ -1241,8 +1275,8 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x This->origWidth = cifd->idEntries[i].bWidth; This->origHeight = cifd->idEntries[i].bHeight; hdcRef = CreateCompatibleDC(0); - This->himetricWidth =(cifd->idEntries[i].bWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX); - This->himetricHeight=(cifd->idEntries[i].bHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY); + This->himetricWidth = xpixels_to_himetric(cifd->idEntries[i].bWidth, hdcRef); + This->himetricHeight= ypixels_to_himetric(cifd->idEntries[i].bHeight, hdcRef); DeleteDC(hdcRef); return S_OK; } @@ -1297,17 +1331,6 @@ static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This, return S_OK; } -/************************************************************************ - * BITMAP FORMAT FLAGS - - * Flags that differentiate between different types of bitmaps. - */ - -#define BITMAP_FORMAT_BMP 0x4d42 /* "BM" */ -#define BITMAP_FORMAT_JPEG 0xd8ff -#define BITMAP_FORMAT_GIF 0x4947 -#define BITMAP_FORMAT_PNG 0x5089 -#define BITMAP_FORMAT_APM 0xcdd7 - /************************************************************************ * OLEPictureImpl_IPersistStream_Load (IUnknown) * @@ -1316,11 +1339,11 @@ static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This, * DWORD magic; * DWORD len; * - * Currently implemented: BITMAP, ICON, JPEG, GIF, WMF, EMF + * Currently implemented: BITMAP, ICON, CURSOR, JPEG, GIF, WMF, EMF */ -static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { - HRESULT hr = E_FAIL; - BOOL headerisdata = FALSE; +static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm) { + HRESULT hr; + BOOL headerisdata; BOOL statfailed = FALSE; ULONG xread, toread; ULONG headerread; @@ -1348,8 +1371,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { * Also handle streams where we do not have a working "Stat" method by * reading all data until the end of the stream. */ - hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME); - if (hr) { + hr = IStream_Stat(pStm,&statstg,STATFLAG_NONAME); + if (hr != S_OK) { TRACE("stat failed with hres %x, proceeding to read all data.\n",hr); statfailed = TRUE; /* we will read at least 8 byte ... just right below */ @@ -1360,8 +1383,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { headerread = 0; headerisdata = FALSE; do { - hr=IStream_Read(pStm,header,8,&xread); - if (hr || xread!=8) { + hr = IStream_Read(pStm, header, 8, &xread); + if (hr != S_OK || xread!=8) { ERR("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread); return (hr?hr:E_FAIL); } @@ -1379,6 +1402,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { !memcmp(&(header[0]), "BM", 2) || /* BMP header */ !memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */ (header[0] == EMR_HEADER) || /* EMF header */ + (header[0] == 0x10000) || /* icon: idReserved 0, idType 1 */ + (header[0] == 0x20000) || /* cursor: idReserved 0, idType 2 */ (header[1] > statstg.cbSize.QuadPart)|| /* invalid size */ (header[1]==0) ) {/* Found start of bitmap data */ @@ -1406,11 +1431,11 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { while (1) { while (xread < origsize) { hr = IStream_Read(pStm,xbuf+xread,origsize-xread,&nread); - xread+=nread; - if (hr || !nread) + xread += nread; + if (hr != S_OK || !nread) break; } - if (!nread || hr) /* done, or error */ + if (!nread || hr != S_OK) /* done, or error */ break; if (xread == origsize) { origsize += sizeinc; @@ -1418,7 +1443,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { xbuf = HeapReAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, xbuf, origsize); } } - if (hr) + if (hr != S_OK) TRACE("hr in no-stat loader case is %08x\n", hr); TRACE("loaded %d bytes.\n", xread); This->datalen = xread; @@ -1435,8 +1460,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { while (xread < This->datalen) { ULONG nread; hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread); - xread+=nread; - if (hr || !nread) + xread += nread; + if (hr != S_OK || !nread) break; } if (xread != This->datalen) @@ -1471,7 +1496,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { case BITMAP_FORMAT_APM: /* APM */ hr = OLEPictureImpl_LoadAPM(This, xbuf, xread); break; - case 0x0000: { /* ICON , first word is dwReserved */ + case 0x0000: { /* ICON or CURSOR, first word is dwReserved */ hr = OLEPictureImpl_LoadIcon(This, xbuf, xread); break; } @@ -1617,6 +1642,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) pIconDir = (CURSORICONFILEDIR *)pIconData; pIconDir->idType = 1; pIconDir->idCount = 1; + pIconDir->idReserved = 0; /* Fill out the CURSORICONFILEDIRENTRY */ pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD)); @@ -1723,6 +1749,7 @@ static HRESULT WINAPI OLEPictureImpl_Save( HRESULT hResult = E_NOTIMPL; void * pIconData; unsigned int iDataSize; + DWORD header[2]; ULONG dummy; int iSerializeResult = 0; OLEPictureImpl *This = impl_from_IPersistStream(iface); @@ -1730,6 +1757,12 @@ static HRESULT WINAPI OLEPictureImpl_Save( TRACE("%p %p %d\n", This, pStm, fClearDirty); switch (This->desc.picType) { + case PICTYPE_NONE: + header[0] = 0x0000746c; + header[1] = 0; + hResult = IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); + break; + case PICTYPE_ICON: if (This->bIsDirty || !This->data) { if (!serializeIcon(This->desc.u.icon.hicon, &pIconData, &iDataSize)) { @@ -1741,19 +1774,15 @@ static HRESULT WINAPI OLEPictureImpl_Save( This->data = pIconData; This->datalen = iDataSize; } - if (This->loadtime_magic != 0xdeadbeef) { - DWORD header[2]; - header[0] = This->loadtime_magic; - header[1] = This->datalen; - IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); - } + header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c; + header[1] = This->datalen; + IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); IStream_Write(pStm, This->data, This->datalen, &dummy); - hResult = S_OK; break; case PICTYPE_BITMAP: - if (This->bIsDirty) { + if (This->bIsDirty || !This->data) { switch (This->keepOrigFormat ? This->loadtime_format : BITMAP_FORMAT_BMP) { case BITMAP_FORMAT_BMP: iSerializeResult = serializeBMP(This->desc.u.bmp.hbitmap, &pIconData, &iDataSize); @@ -1771,38 +1800,23 @@ static HRESULT WINAPI OLEPictureImpl_Save( FIXME("(%p,%p,%d), PICTYPE_BITMAP (format UNKNOWN, using BMP?) not implemented!\n",This,pStm,fClearDirty); break; } - if (iSerializeResult) { - /* - if (This->loadtime_magic != 0xdeadbeef) { - */ - if (1) { - DWORD header[2]; - header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c; - header[1] = iDataSize; - IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); - } - IStream_Write(pStm, pIconData, iDataSize, &dummy); - - HeapFree(GetProcessHeap(), 0, This->data); - This->data = pIconData; - This->datalen = iDataSize; - hResult = S_OK; + if (!iSerializeResult) + { + hResult = E_FAIL; + break; } - } else { - /* - if (This->loadtime_magic != 0xdeadbeef) { - */ - if (1) { - DWORD header[2]; - header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c; - header[1] = This->datalen; - IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); - } - IStream_Write(pStm, This->data, This->datalen, &dummy); - hResult = S_OK; + HeapFree(GetProcessHeap(), 0, This->data); + This->data = pIconData; + This->datalen = iDataSize; } + + header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c; + header[1] = This->datalen; + IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); + IStream_Write(pStm, This->data, This->datalen, &dummy); + hResult = S_OK; break; case PICTYPE_METAFILE: FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty); @@ -1843,7 +1857,7 @@ static HRESULT WINAPI OLEPictureImpl_IDispatch_QueryInterface( { OLEPictureImpl *This = impl_from_IDispatch(iface); - return IPicture_QueryInterface((IPicture *)This, riid, ppvoid); + return IPicture_QueryInterface(&This->IPicture_iface, riid, ppvoid); } /************************************************************************ @@ -1856,7 +1870,7 @@ static ULONG WINAPI OLEPictureImpl_IDispatch_AddRef( { OLEPictureImpl *This = impl_from_IDispatch(iface); - return IPicture_AddRef((IPicture *)This); + return IPicture_AddRef(&This->IPicture_iface); } /************************************************************************ @@ -1869,7 +1883,7 @@ static ULONG WINAPI OLEPictureImpl_IDispatch_Release( { OLEPictureImpl *This = impl_from_IDispatch(iface); - return IPicture_Release((IPicture *)This); + return IPicture_Release(&This->IPicture_iface); } /************************************************************************ @@ -2025,7 +2039,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( { TRACE("DISPID_PICT_HANDLE\n"); V_VT(pVarResult) = VT_I4; - return IPicture_get_Handle((IPicture *)&This->lpVtbl, &V_UINT(pVarResult)); + return IPicture_get_Handle(&This->IPicture_iface, &V_UINT(pVarResult)); } break; case DISPID_PICT_HPAL: @@ -2033,7 +2047,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( { TRACE("DISPID_PICT_HPAL\n"); V_VT(pVarResult) = VT_I4; - return IPicture_get_hPal((IPicture *)&This->lpVtbl, &V_UINT(pVarResult)); + return IPicture_get_hPal(&This->IPicture_iface, &V_UINT(pVarResult)); } else if (wFlags & DISPATCH_PROPERTYPUT) { @@ -2046,7 +2060,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( if (FAILED(hr)) return hr; - hr = IPicture_set_hPal((IPicture *)&This->lpVtbl, V_I4(&vararg)); + hr = IPicture_set_hPal(&This->IPicture_iface, V_I4(&vararg)); VariantClear(&vararg); return hr; @@ -2057,7 +2071,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( { TRACE("DISPID_PICT_TYPE\n"); V_VT(pVarResult) = VT_I2; - return OLEPictureImpl_get_Type((IPicture *)&This->lpVtbl, &V_I2(pVarResult)); + return OLEPictureImpl_get_Type(&This->IPicture_iface, &V_I2(pVarResult)); } break; case DISPID_PICT_WIDTH: @@ -2065,7 +2079,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( { TRACE("DISPID_PICT_WIDTH\n"); V_VT(pVarResult) = VT_I4; - return IPicture_get_Width((IPicture *)&This->lpVtbl, &V_I4(pVarResult)); + return IPicture_get_Width(&This->IPicture_iface, &V_I4(pVarResult)); } break; case DISPID_PICT_HEIGHT: @@ -2073,7 +2087,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke( { TRACE("DISPID_PICT_HEIGHT\n"); V_VT(pVarResult) = VT_I4; - return IPicture_get_Height((IPicture *)&This->lpVtbl, &V_I4(pVarResult)); + return IPicture_get_Height(&This->IPicture_iface, &V_I4(pVarResult)); } break; } @@ -2140,25 +2154,16 @@ static const IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContai * OleCreatePictureIndirect (OLEAUT32.419) */ HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid, - BOOL fOwn, LPVOID *ppvObj ) + BOOL Own, void **ppvObj ) { - OLEPictureImpl* newPict = NULL; - HRESULT hr = S_OK; + OLEPictureImpl* newPict; + HRESULT hr; - TRACE("(%p,%s,%d,%p)\n", lpPictDesc, debugstr_guid(riid), fOwn, ppvObj); - - /* - * Sanity check - */ - if (ppvObj==0) - return E_POINTER; + TRACE("(%p,%s,%d,%p)\n", lpPictDesc, debugstr_guid(riid), Own, ppvObj); *ppvObj = NULL; - /* - * Try to construct a new instance of the class. - */ - newPict = OLEPictureImpl_Construct(lpPictDesc, fOwn); + newPict = OLEPictureImpl_Construct(lpPictDesc, Own); if (newPict == NULL) return E_OUTOFMEMORY; @@ -2166,13 +2171,13 @@ HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid, /* * Make sure it supports the interface required by the caller. */ - hr = IPicture_QueryInterface((IPicture*)newPict, riid, ppvObj); + hr = IPicture_QueryInterface(&newPict->IPicture_iface, riid, ppvObj); /* * Release the reference obtained in the constructor. If * the QueryInterface was unsuccessful, it will free the class. */ - IPicture_Release((IPicture*)newPict); + IPicture_Release(&newPict->IPicture_iface); return hr; } @@ -2192,10 +2197,10 @@ HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode, lpstream, lSize, fRunmode, debugstr_guid(riid), ppvObj); hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic); - if (hr) + if (hr != S_OK) return hr; hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps); - if (hr) { + if (hr != S_OK) { ERR("Could not get IPersistStream iface from Ole Picture?\n"); IPicture_Release(newpic); *ppvObj = NULL; @@ -2211,7 +2216,7 @@ HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode, return hr; } hr = IPicture_QueryInterface(newpic,riid,ppvObj); - if (hr) + if (hr != S_OK) ERR("Failed to get interface %s from IPicture.\n",debugstr_guid(riid)); IPicture_Release(newpic); return hr; @@ -2231,10 +2236,10 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode, lpstream, lSize, fRunmode, debugstr_guid(riid), xsiz, ysiz, flags, ppvObj); hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic); - if (hr) + if (hr != S_OK) return hr; hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps); - if (hr) { + if (hr != S_OK) { ERR("Could not get IPersistStream iface from Ole Picture?\n"); IPicture_Release(newpic); *ppvObj = NULL; @@ -2250,7 +2255,7 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode, return hr; } hr = IPicture_QueryInterface(newpic,riid,ppvObj); - if (hr) + if (hr != S_OK) ERR("Failed to get interface %s from IPicture.\n",debugstr_guid(riid)); IPicture_Release(newpic); return hr; @@ -2304,7 +2309,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, hFile = CreateFileW(file_candidate, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) - return E_UNEXPECTED; + return INET_E_RESOURCE_NOT_FOUND; dwFileSize = GetFileSize(hFile, NULL); if (dwFileSize != INVALID_FILE_SIZE ) @@ -2323,7 +2328,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, CloseHandle(hFile); if (!hGlobal) - return E_UNEXPECTED; + return INET_E_RESOURCE_NOT_FOUND; hRes = CreateStreamOnHGlobal(hGlobal, TRUE, &stream); if (FAILED(hRes)) @@ -2385,13 +2390,18 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, typedef struct { /* IUnknown fields */ - const IClassFactoryVtbl *lpVtbl; - LONG ref; + IClassFactory IClassFactory_iface; + LONG ref; } IClassFactoryImpl; +static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); +} + static HRESULT WINAPI SPCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj); return E_NOINTERFACE; @@ -2399,12 +2409,12 @@ SPCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { static ULONG WINAPI SPCF_AddRef(LPCLASSFACTORY iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); return InterlockedIncrement(&This->ref); } static ULONG WINAPI SPCF_Release(LPCLASSFACTORY iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); /* static class, won't be freed */ return InterlockedDecrement(&This->ref); } @@ -2418,7 +2428,7 @@ static HRESULT WINAPI SPCF_CreateInstance( } static HRESULT WINAPI SPCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); FIXME("(%p)->(%d),stub!\n",This,dolock); return S_OK; } @@ -2430,6 +2440,6 @@ static const IClassFactoryVtbl SPCF_Vtbl = { SPCF_CreateInstance, SPCF_LockServer }; -static IClassFactoryImpl STDPIC_CF = {&SPCF_Vtbl, 1 }; +static IClassFactoryImpl STDPIC_CF = {{&SPCF_Vtbl}, 1 }; void _get_STDPIC_CF(LPVOID *ppv) { *ppv = &STDPIC_CF; } diff --git a/reactos/dll/win32/oleaut32/olepropframe.c b/reactos/dll/win32/oleaut32/olepropframe.c new file mode 100644 index 00000000000..8111e6b478c --- /dev/null +++ b/reactos/dll/win32/oleaut32/olepropframe.c @@ -0,0 +1,346 @@ +/* + * Copyright 1999 Corel Corporation + * Sean Langley + * Copyright 2010 Geoffrey Hausheer + * Copyright 2010 Piotr Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "ole2.h" +#include "olectl.h" +#include "oledlg.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +typedef struct { + IPropertyPageSite IPropertyPageSite_iface; + LCID lcid; + LONG ref; +} PropertyPageSite; + +static inline PropertyPageSite *impl_from_IPropertyPageSite(IPropertyPageSite *iface) +{ + return CONTAINING_RECORD(iface, PropertyPageSite, IPropertyPageSite_iface); +} + +static INT_PTR CALLBACK property_sheet_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + IPropertyPage *property_page = (IPropertyPage*)GetWindowLongPtrW(hwnd, DWLP_USER); + + switch(msg) { + case WM_INITDIALOG: { + RECT rect; + + property_page = (IPropertyPage*)((LPPROPSHEETPAGEW)lparam)->lParam; + + GetClientRect(hwnd, &rect); + IPropertyPage_Activate(property_page, hwnd, &rect, TRUE); + IPropertyPage_Show(property_page, SW_SHOW); + + SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)property_page); + return FALSE; + } + case WM_DESTROY: + IPropertyPage_Show(property_page, SW_HIDE); + IPropertyPage_Deactivate(property_page); + return FALSE; + default: + return FALSE; + } +} + +static HRESULT WINAPI PropertyPageSite_QueryInterface(IPropertyPageSite* iface, + REFIID riid, void** ppv) +{ + TRACE("(%p riid: %s)\n",iface, debugstr_guid(riid)); + + if(IsEqualGUID(&IID_IUnknown, riid) + || IsEqualGUID(&IID_IPropertyPageSite, riid)) + *ppv = iface; + else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI PropertyPageSite_AddRef(IPropertyPageSite* iface) +{ + PropertyPageSite *this = impl_from_IPropertyPageSite(iface); + LONG ref = InterlockedIncrement(&this->ref); + + TRACE("(%p) ref=%d\n", this, ref); + return ref; +} + +static ULONG WINAPI PropertyPageSite_Release(IPropertyPageSite* iface) +{ + PropertyPageSite *this = impl_from_IPropertyPageSite(iface); + LONG ref = InterlockedDecrement(&this->ref); + + TRACE("(%p) ref=%d\n", this, ref); + if(!ref) + HeapFree(GetProcessHeap(), 0, this); + return ref; +} + +static HRESULT WINAPI PropertyPageSite_OnStatusChange( + IPropertyPageSite *iface, DWORD dwFlags) +{ + TRACE("(%p, %x)\n", iface, dwFlags); + return S_OK; +} + +static HRESULT WINAPI PropertyPageSite_GetLocaleID( + IPropertyPageSite *iface, LCID *pLocaleID) +{ + PropertyPageSite *this = impl_from_IPropertyPageSite(iface); + + TRACE("(%p, %p)\n", iface, pLocaleID); + *pLocaleID = this->lcid; + return S_OK; +} + +static HRESULT WINAPI PropertyPageSite_GetPageContainer( + IPropertyPageSite* iface, IUnknown** ppUnk) +{ + FIXME("(%p, %p)\n", iface, ppUnk); + return E_NOTIMPL; +} + +static HRESULT WINAPI PropertyPageSite_TranslateAccelerator( + IPropertyPageSite* iface, MSG *pMsg) +{ + FIXME("(%p, %p)\n", iface, pMsg); + return E_NOTIMPL; +} + +IPropertyPageSiteVtbl PropertyPageSiteVtbl = { + PropertyPageSite_QueryInterface, + PropertyPageSite_AddRef, + PropertyPageSite_Release, + PropertyPageSite_OnStatusChange, + PropertyPageSite_GetLocaleID, + PropertyPageSite_GetPageContainer, + PropertyPageSite_TranslateAccelerator +}; + +/*********************************************************************** + * OleCreatePropertyFrameIndirect (OLEAUT32.416) + */ +HRESULT WINAPI OleCreatePropertyFrameIndirect(LPOCPFIPARAMS lpParams) +{ + static const WCHAR comctlW[] = { 'c','o','m','c','t','l','3','2','.','d','l','l',0 }; + + PROPSHEETHEADERW property_sheet; + PROPSHEETPAGEW property_sheet_page; + struct { + DLGTEMPLATE template; + WORD menu; + WORD class; + WORD title; + } *dialogs; + IPropertyPage **property_page; + PropertyPageSite *property_page_site; + HRESULT res; + int i; + HMODULE hcomctl; + HRSRC property_sheet_dialog_find = NULL; + HGLOBAL property_sheet_dialog_load = NULL; + WCHAR *property_sheet_dialog_data = NULL; + HDC hdc; + LOGFONTW font_desc; + HFONT hfont; + LONG font_width = 4, font_height = 8; + + if(!lpParams) + return E_POINTER; + + TRACE("(%d %p %d %d %s %d %p %d %p %d %d)\n", lpParams->cbStructSize, + lpParams->hWndOwner, lpParams->x, lpParams->y, + debugstr_w(lpParams->lpszCaption), lpParams->cObjects, + lpParams->lplpUnk, lpParams->cPages, lpParams->lpPages, + lpParams->lcid, lpParams->dispidInitialProperty); + + if(!lpParams->lplpUnk || !lpParams->lpPages) + return E_POINTER; + + if(lpParams->cbStructSize != sizeof(OCPFIPARAMS)) { + WARN("incorrect structure size\n"); + return E_INVALIDARG; + } + + if(lpParams->dispidInitialProperty) + FIXME("dispidInitialProperty not yet implemented\n"); + + hdc = GetDC(NULL); + hcomctl = LoadLibraryW(comctlW); + if(hcomctl) + property_sheet_dialog_find = FindResourceW(hcomctl, + MAKEINTRESOURCEW(1006 /*IDD_PROPSHEET*/), (LPWSTR)RT_DIALOG); + if(property_sheet_dialog_find) + property_sheet_dialog_load = LoadResource(hcomctl, property_sheet_dialog_find); + if(property_sheet_dialog_load) + property_sheet_dialog_data = LockResource(property_sheet_dialog_load); + + if(property_sheet_dialog_data) { + if(property_sheet_dialog_data[1] == 0xffff) { + ERR("Expected DLGTEMPLATE structure\n"); + return E_OUTOFMEMORY; + } + + property_sheet_dialog_data += sizeof(DLGTEMPLATE)/sizeof(WCHAR); + /* Skip menu, class and title */ + property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1; + property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1; + property_sheet_dialog_data += lstrlenW(property_sheet_dialog_data)+1; + + memset(&font_desc, 0, sizeof(LOGFONTW)); + /* Calculate logical height */ + font_desc.lfHeight = -MulDiv(property_sheet_dialog_data[0], + GetDeviceCaps(hdc, LOGPIXELSY), 72); + font_desc.lfCharSet = DEFAULT_CHARSET; + memcpy(font_desc.lfFaceName, property_sheet_dialog_data+1, + sizeof(WCHAR)*(lstrlenW(property_sheet_dialog_data+1)+1)); + hfont = CreateFontIndirectW(&font_desc); + + if(hfont) { + hfont = SelectObject(hdc, hfont); + font_width = GdiGetCharDimensions(hdc, NULL, &font_height); + SelectObject(hdc, hfont); + } + } + if(hcomctl) + FreeLibrary(hcomctl); + ReleaseDC(NULL, hdc); + + memset(&property_sheet, 0, sizeof(property_sheet)); + property_sheet.dwSize = sizeof(property_sheet); + if(lpParams->lpszCaption) { + property_sheet.dwFlags = PSH_PROPTITLE; + property_sheet.pszCaption = lpParams->lpszCaption; + } + + property_sheet.u3.phpage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + lpParams->cPages*sizeof(HPROPSHEETPAGE)); + property_page = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + lpParams->cPages*sizeof(IPropertyPage*)); + dialogs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + lpParams->cPages*sizeof(*dialogs)); + if(!property_sheet.u3.phpage || !property_page || !dialogs) { + HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage); + HeapFree(GetProcessHeap(), 0, property_page); + HeapFree(GetProcessHeap(), 0, dialogs); + return E_OUTOFMEMORY; + } + + memset(&property_sheet_page, 0, sizeof(PROPSHEETPAGEW)); + property_sheet_page.dwSize = sizeof(PROPSHEETPAGEW); + property_sheet_page.dwFlags = PSP_DLGINDIRECT|PSP_USETITLE; + property_sheet_page.pfnDlgProc = property_sheet_proc; + + for(i=0; icPages; i++) { + PROPPAGEINFO page_info; + + res = CoCreateInstance(&lpParams->lpPages[i], NULL, CLSCTX_INPROC_SERVER, + &IID_IPropertyPage, (void**)&property_page[i]); + if(FAILED(res)) + continue; + + property_page_site = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyPageSite)); + if(!property_page_site) + continue; + property_page_site->IPropertyPageSite_iface.lpVtbl = &PropertyPageSiteVtbl; + property_page_site->ref = 1; + property_page_site->lcid = lpParams->lcid; + + res = IPropertyPage_SetPageSite(property_page[i], + &property_page_site->IPropertyPageSite_iface); + IPropertyPageSite_Release(&property_page_site->IPropertyPageSite_iface); + if(FAILED(res)) + continue; + + res = IPropertyPage_SetObjects(property_page[i], + lpParams->cObjects, lpParams->lplpUnk); + if(FAILED(res)) + continue; + + res = IPropertyPage_GetPageInfo(property_page[i], &page_info); + if(FAILED(res)) + continue; + + dialogs[i].template.cx = MulDiv(page_info.size.cx, 4, font_width); + dialogs[i].template.cy = MulDiv(page_info.size.cy, 8, font_height); + + property_sheet_page.u.pResource = &dialogs[i].template; + property_sheet_page.lParam = (LPARAM)property_page[i]; + property_sheet_page.pszTitle = page_info.pszTitle; + + property_sheet.u3.phpage[property_sheet.nPages++] = + CreatePropertySheetPageW(&property_sheet_page); + } + + PropertySheetW(&property_sheet); + + for(i=0; icPages; i++) { + if(property_page[i]) { + IPropertyPage_SetPageSite(property_page[i], NULL); + IPropertyPage_Release(property_page[i]); + } + } + + HeapFree(GetProcessHeap(), 0, dialogs); + HeapFree(GetProcessHeap(), 0, property_page); + HeapFree(GetProcessHeap(), 0, property_sheet.u3.phpage); + return S_OK; +} + +/*********************************************************************** + * OleCreatePropertyFrame (OLEAUT32.417) + */ +HRESULT WINAPI OleCreatePropertyFrame( + HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption, ULONG cObjects, + LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid, + DWORD dwReserved, LPVOID pvReserved) +{ + OCPFIPARAMS ocpf; + + ocpf.cbStructSize = sizeof(OCPFIPARAMS); + ocpf.hWndOwner = hwndOwner; + ocpf.x = x; + ocpf.y = y; + ocpf.lpszCaption = lpszCaption; + ocpf.cObjects = cObjects; + ocpf.lplpUnk = ppUnk; + ocpf.cPages = cPages; + ocpf.lpPages = pPageClsID; + ocpf.lcid = lcid; + ocpf.dispidInitialProperty = 0; + + return OleCreatePropertyFrameIndirect(&ocpf); +} diff --git a/reactos/dll/win32/oleaut32/recinfo.c b/reactos/dll/win32/oleaut32/recinfo.c index c23aad7eb82..f6f56535863 100644 --- a/reactos/dll/win32/oleaut32/recinfo.c +++ b/reactos/dll/win32/oleaut32/recinfo.c @@ -41,7 +41,7 @@ typedef struct { } fieldstr; typedef struct { - const IRecordInfoVtbl *lpVtbl; + IRecordInfo IRecordInfo_iface; LONG ref; GUID guid; @@ -53,6 +53,11 @@ typedef struct { ITypeInfo *pTypeInfo; } IRecordInfoImpl; +static inline IRecordInfoImpl *impl_from_IRecordInfo(IRecordInfo *iface) +{ + return CONTAINING_RECORD(iface, IRecordInfoImpl, IRecordInfo_iface); +} + static HRESULT copy_to_variant(void *src, VARIANT *pvar, enum VARENUM vt) { TRACE("%p %p %d\n", src, pvar, vt); @@ -155,7 +160,7 @@ static HRESULT WINAPI IRecordInfoImpl_QueryInterface(IRecordInfo *iface, REFIID static ULONG WINAPI IRecordInfoImpl_AddRef(IRecordInfo *iface) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) -> %d\n", This, ref); return ref; @@ -163,7 +168,7 @@ static ULONG WINAPI IRecordInfoImpl_AddRef(IRecordInfo *iface) static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) -> %d\n", This, ref); @@ -182,7 +187,7 @@ static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface) static HRESULT WINAPI IRecordInfoImpl_RecordInit(IRecordInfo *iface, PVOID pvNew) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); TRACE("(%p)->(%p)\n", This, pvNew); if(!pvNew) @@ -194,7 +199,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordInit(IRecordInfo *iface, PVOID pvNew static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvExisting) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); int i; PVOID var; @@ -251,7 +256,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvEx static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExisting, PVOID pvNew) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); TRACE("(%p)->(%p %p)\n", This, pvExisting, pvNew); @@ -264,7 +269,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExi static HRESULT WINAPI IRecordInfoImpl_GetGuid(IRecordInfo *iface, GUID *pguid) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); TRACE("(%p)->(%p)\n", This, pguid); @@ -277,7 +282,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetGuid(IRecordInfo *iface, GUID *pguid) static HRESULT WINAPI IRecordInfoImpl_GetName(IRecordInfo *iface, BSTR *pbstrName) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); TRACE("(%p)->(%p)\n", This, pbstrName); @@ -290,8 +295,8 @@ static HRESULT WINAPI IRecordInfoImpl_GetName(IRecordInfo *iface, BSTR *pbstrNam static HRESULT WINAPI IRecordInfoImpl_GetSize(IRecordInfo *iface, ULONG *pcbSize) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; - + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); + TRACE("(%p)->(%p)\n", This, pcbSize); if(!pcbSize) @@ -303,7 +308,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetSize(IRecordInfo *iface, ULONG *pcbSize static HRESULT WINAPI IRecordInfoImpl_GetTypeInfo(IRecordInfo *iface, ITypeInfo **ppTypeInfo) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); TRACE("(%p)->(%p)\n", This, ppTypeInfo); @@ -319,7 +324,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetTypeInfo(IRecordInfo *iface, ITypeInfo static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); int i; TRACE("(%p)->(%p %s %p)\n", This, pvData, debugstr_w(szFieldName), pvarField); @@ -341,7 +346,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData, static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); int i; TRACE("(%p)->(%p %s %p %p)\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray); @@ -365,7 +370,7 @@ static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID p static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); int i; TRACE("(%p)->(%08x %p %s %p)\n", This, wFlags, pvData, debugstr_w(szFieldName), @@ -393,7 +398,7 @@ static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags, static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); int i; FIXME("(%p)->(%08x %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField); @@ -414,7 +419,7 @@ static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG w static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *pcNames, BSTR *rgBstrNames) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); ULONG n = This->n_vars, i; TRACE("(%p)->(%p %p)\n", This, pcNames, rgBstrNames); @@ -434,18 +439,25 @@ static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *p return S_OK; } -static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInfo *pRecordInfo) +static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInfo *info2) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); + GUID guid2; - FIXME("(%p)->(%p) stub\n", This, pRecordInfo); + TRACE( "(%p)->(%p)\n", This, info2 ); + + IRecordInfo_GetGuid( info2, &guid2 ); + if (IsEqualGUID( &This->guid, &guid2 )) return TRUE; + + FIXME( "records have different guids (%s %s) but could still match\n", + debugstr_guid( &This->guid ), debugstr_guid( &guid2 ) ); return FALSE; } static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); TRACE("(%p)\n", This); @@ -455,7 +467,7 @@ static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface) static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource, PVOID *ppvDest) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); TRACE("(%p)->(%p %p)\n", This, pvSource, ppvDest); @@ -468,7 +480,7 @@ static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID static HRESULT WINAPI IRecordInfoImpl_RecordDestroy(IRecordInfo *iface, PVOID pvRecord) { - IRecordInfoImpl *This = (IRecordInfoImpl*)iface; + IRecordInfoImpl *This = impl_from_IRecordInfo(iface); HRESULT hres; TRACE("(%p)->(%p)\n", This, pvRecord); @@ -585,7 +597,7 @@ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo } ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret)); - ret->lpVtbl = &IRecordInfoImplVtbl; + ret->IRecordInfo_iface.lpVtbl = &IRecordInfoImplVtbl; ret->ref = 1; ret->pTypeInfo = pTypeInfo; ret->n_vars = typeattr->cVars; @@ -621,8 +633,8 @@ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo WARN("GetDocumentation failed: %08x\n", hres); ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc); } - - *ppRecInfo = (IRecordInfo*)ret; + + *ppRecInfo = &ret->IRecordInfo_iface; return S_OK; } diff --git a/reactos/dll/win32/oleaut32/regsvr.c b/reactos/dll/win32/oleaut32/regsvr.c deleted file mode 100644 index f97544f51ed..00000000000 --- a/reactos/dll/win32/oleaut32/regsvr.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * self-registerable dll functions for oleaut32.dll - * - * Copyright (C) 2003 John K. Hohm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include - -#define COBJMACROS -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "winreg.h" -#include "winerror.h" - -#include "ole2.h" -#include "olectl.h" -#include "oleauto.h" -#include "initguid.h" -#include "typelib.h" -#include "wincodec.h" - -#include "wine/debug.h" -#include "wine/unicode.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -/* - * Near the bottom of this file are the exported DllRegisterServer and - * DllUnregisterServer, which make all this worthwhile. - */ - -/*********************************************************************** - * interface for self-registering - */ -struct regsvr_interface -{ - IID const *iid; /* NULL for end of list */ - LPCSTR name; /* can be NULL to omit */ - IID const *base_iid; /* can be NULL to omit */ - int num_methods; /* can be <0 to omit */ - CLSID const *ps_clsid; /* can be NULL to omit */ - CLSID const *ps_clsid32; /* can be NULL to omit */ -}; - -static HRESULT register_interfaces(struct regsvr_interface const *list); -static HRESULT unregister_interfaces(struct regsvr_interface const *list); - -struct regsvr_coclass -{ - CLSID const *clsid; /* NULL for end of list */ - LPCSTR name; /* can be NULL to omit */ - LPCSTR ips; /* can be NULL to omit */ - LPCSTR ips32; /* can be NULL to omit */ - LPCSTR ips32_tmodel; /* can be NULL to omit */ - LPCSTR clsid_str; /* can be NULL to omit */ - LPCSTR progid; /* can be NULL to omit */ -}; - -static HRESULT register_coclasses(struct regsvr_coclass const *list); -static HRESULT unregister_coclasses(struct regsvr_coclass const *list); - -/*********************************************************************** - * static string constants - */ -static WCHAR const interface_keyname[10] = { - 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; -static WCHAR const base_ifa_keyname[14] = { - 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', - 'e', 0 }; -static WCHAR const num_methods_keyname[11] = { - 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 }; -static WCHAR const ps_clsid_keyname[15] = { - 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', - 'i', 'd', 0 }; -static WCHAR const ps_clsid32_keyname[17] = { - 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', - 'i', 'd', '3', '2', 0 }; -static WCHAR const clsid_keyname[6] = { - 'C', 'L', 'S', 'I', 'D', 0 }; -static WCHAR const ips_keyname[13] = { - 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', - 0 }; -static WCHAR const ips32_keyname[15] = { - 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', - '3', '2', 0 }; -static WCHAR const progid_keyname[7] = { - 'P', 'r', 'o', 'g', 'I', 'D', 0 }; -static char const tmodel_valuename[] = "ThreadingModel"; - -/*********************************************************************** - * static helper functions - */ -static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid); -static LONG register_key_defvalueW(HKEY base, WCHAR const *name, - WCHAR const *value); -static LONG register_key_defvalueA(HKEY base, WCHAR const *name, - char const *value); - -/*********************************************************************** - * register_interfaces - */ -static HRESULT register_interfaces(struct regsvr_interface const *list) -{ - LONG res = ERROR_SUCCESS; - HKEY interface_key; - - res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0, - KEY_READ | KEY_WRITE, NULL, &interface_key, NULL); - if (res != ERROR_SUCCESS) goto error_return; - - for (; res == ERROR_SUCCESS && list->iid; ++list) { - WCHAR buf[39]; - HKEY iid_key; - - StringFromGUID2(list->iid, buf, 39); - res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0, - KEY_READ | KEY_WRITE, NULL, &iid_key, NULL); - if (res != ERROR_SUCCESS) goto error_close_interface_key; - - if (list->name) { - res = RegSetValueExA(iid_key, NULL, 0, REG_SZ, - (CONST BYTE*)(list->name), - strlen(list->name) + 1); - if (res != ERROR_SUCCESS) goto error_close_iid_key; - } - - if (list->base_iid) { - res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid); - if (res != ERROR_SUCCESS) goto error_close_iid_key; - } - - if (0 <= list->num_methods) { - static WCHAR const fmt[3] = { '%', 'd', 0 }; - HKEY key; - - res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0, - KEY_READ | KEY_WRITE, NULL, &key, NULL); - if (res != ERROR_SUCCESS) goto error_close_iid_key; - - sprintfW(buf, fmt, list->num_methods); - res = RegSetValueExW(key, NULL, 0, REG_SZ, - (CONST BYTE*)buf, - (lstrlenW(buf) + 1) * sizeof(WCHAR)); - RegCloseKey(key); - - if (res != ERROR_SUCCESS) goto error_close_iid_key; - } - - if (list->ps_clsid) { - res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid); - if (res != ERROR_SUCCESS) goto error_close_iid_key; - } - - if (list->ps_clsid32) { - res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32); - if (res != ERROR_SUCCESS) goto error_close_iid_key; - } - - error_close_iid_key: - RegCloseKey(iid_key); - } - -error_close_interface_key: - RegCloseKey(interface_key); -error_return: - return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; -} - -/*********************************************************************** - * unregister_interfaces - */ -static HRESULT unregister_interfaces(struct regsvr_interface const *list) -{ - LONG res = ERROR_SUCCESS; - HKEY interface_key; - - res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, - KEY_READ | KEY_WRITE, &interface_key); - if (res == ERROR_FILE_NOT_FOUND) return S_OK; - if (res != ERROR_SUCCESS) goto error_return; - - for (; res == ERROR_SUCCESS && list->iid; ++list) { - WCHAR buf[39]; - - StringFromGUID2(list->iid, buf, 39); - res = RegDeleteTreeW(interface_key, buf); - if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; - } - - RegCloseKey(interface_key); -error_return: - return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; -} - -/*********************************************************************** - * register_coclasses - */ -static HRESULT register_coclasses(struct regsvr_coclass const *list) -{ - LONG res = ERROR_SUCCESS; - HKEY coclass_key; - - res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, - KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); - if (res != ERROR_SUCCESS) goto error_return; - - for (; res == ERROR_SUCCESS && list->clsid; ++list) { - WCHAR buf[39]; - HKEY clsid_key; - - StringFromGUID2(list->clsid, buf, 39); - res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, - KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); - if (res != ERROR_SUCCESS) goto error_close_coclass_key; - - if (list->name) { - res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, - (CONST BYTE*)(list->name), - strlen(list->name) + 1); - if (res != ERROR_SUCCESS) goto error_close_clsid_key; - } - - if (list->ips) { - res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); - if (res != ERROR_SUCCESS) goto error_close_clsid_key; - } - - if (list->ips32) { - HKEY ips32_key; - - res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, - KEY_READ | KEY_WRITE, NULL, - &ips32_key, NULL); - if (res != ERROR_SUCCESS) goto error_close_clsid_key; - - res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, - (CONST BYTE*)list->ips32, - lstrlenA(list->ips32) + 1); - if (res == ERROR_SUCCESS && list->ips32_tmodel) - res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, - (CONST BYTE*)list->ips32_tmodel, - strlen(list->ips32_tmodel) + 1); - RegCloseKey(ips32_key); - if (res != ERROR_SUCCESS) goto error_close_clsid_key; - } - - if (list->clsid_str) { - res = register_key_defvalueA(clsid_key, clsid_keyname, - list->clsid_str); - if (res != ERROR_SUCCESS) goto error_close_clsid_key; - } - - if (list->progid) { - HKEY progid_key; - - res = register_key_defvalueA(clsid_key, progid_keyname, - list->progid); - if (res != ERROR_SUCCESS) goto error_close_clsid_key; - - res = RegCreateKeyExA(HKEY_CLASSES_ROOT, list->progid, 0, - NULL, 0, KEY_READ | KEY_WRITE, NULL, - &progid_key, NULL); - if (res != ERROR_SUCCESS) goto error_close_clsid_key; - - res = register_key_defvalueW(progid_key, clsid_keyname, buf); - RegCloseKey(progid_key); - if (res != ERROR_SUCCESS) goto error_close_clsid_key; - } - - error_close_clsid_key: - RegCloseKey(clsid_key); - } - -error_close_coclass_key: - RegCloseKey(coclass_key); -error_return: - return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; -} - -/*********************************************************************** - * unregister_coclasses - */ -static HRESULT unregister_coclasses(struct regsvr_coclass const *list) -{ - LONG res = ERROR_SUCCESS; - HKEY coclass_key; - - res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, - KEY_READ | KEY_WRITE, &coclass_key); - if (res == ERROR_FILE_NOT_FOUND) return S_OK; - if (res != ERROR_SUCCESS) goto error_return; - - for (; res == ERROR_SUCCESS && list->clsid; ++list) { - WCHAR buf[39]; - - StringFromGUID2(list->clsid, buf, 39); - res = RegDeleteTreeW(coclass_key, buf); - if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; - if (res != ERROR_SUCCESS) goto error_close_coclass_key; - - if (list->progid) { - res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); - if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; - if (res != ERROR_SUCCESS) goto error_close_coclass_key; - } - } - -error_close_coclass_key: - RegCloseKey(coclass_key); -error_return: - return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; -} - -/*********************************************************************** - * regsvr_key_guid - */ -static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid) -{ - WCHAR buf[39]; - - StringFromGUID2(guid, buf, 39); - return register_key_defvalueW(base, name, buf); -} - -/*********************************************************************** - * regsvr_key_defvalueW - */ -static LONG register_key_defvalueW( - HKEY base, - WCHAR const *name, - WCHAR const *value) -{ - LONG res; - HKEY key; - - res = RegCreateKeyExW(base, name, 0, NULL, 0, - KEY_READ | KEY_WRITE, NULL, &key, NULL); - if (res != ERROR_SUCCESS) return res; - res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, - (lstrlenW(value) + 1) * sizeof(WCHAR)); - RegCloseKey(key); - return res; -} - -/*********************************************************************** - * regsvr_key_defvalueA - */ -static LONG register_key_defvalueA( - HKEY base, - WCHAR const *name, - char const *value) -{ - LONG res; - HKEY key; - - res = RegCreateKeyExW(base, name, 0, NULL, 0, - KEY_READ | KEY_WRITE, NULL, &key, NULL); - if (res != ERROR_SUCCESS) return res; - res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, - lstrlenA(value) + 1); - RegCloseKey(key); - return res; -} - -/*********************************************************************** - * register_typelib - */ -static HRESULT register_typelib( const WCHAR *name ) -{ - static const WCHAR backslash[] = {'\\',0}; - HRESULT hr; - ITypeLib *typelib; - WCHAR *path; - DWORD len; - - len = GetSystemDirectoryW( NULL, 0 ) + strlenW( name ) + 1; - if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; - GetSystemDirectoryW( path, len ); - strcatW( path, backslash ); - strcatW( path, name ); - hr = LoadTypeLib( path, &typelib ); - if (SUCCEEDED(hr)) - { - hr = RegisterTypeLib( typelib, path, NULL ); - ITypeLib_Release( typelib ); - } - HeapFree( GetProcessHeap(), 0, path ); - return hr; -} - -/*********************************************************************** - * coclass list - */ -static GUID const CLSID_RecordInfo = { - 0x0000002F, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; - -static GUID const CLSID_OldFont = { - 0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} }; - -static struct regsvr_coclass const coclass_list[] = { - { &CLSID_RecordInfo, - "CLSID_RecordInfo", - NULL, - "oleaut32.dll", - "Both" - }, - { &CLSID_PSDispatch, - "PSDispatch", - "ole2disp.dll", - "oleaut32.dll", - "Both" - }, - { &CLSID_StdFont, - "CLSID_StdFont", - NULL, - "oleaut32.dll", - "Both", - "Standard Font", - "StdFont" - }, - { &CLSID_StdPicture, - "CLSID_StdPict", - NULL, - "oleaut32.dll", - "Apartment", - "Standard Picture", - "StdPicture" - }, - { &CLSID_PSEnumVariant, - "PSEnumVariant", - "ole2disp.dll", - "oleaut32.dll", - "Both" - }, - { &CLSID_PSTypeInfo, - "PSTypeInfo", - "ole2disp.dll", - "oleaut32.dll", - "Both" - }, - { &CLSID_PSTypeLib, - "PSTypeLib", - "ole2disp.dll", - "oleaut32.dll", - "Both" - }, - { &CLSID_PSOAInterface, - "PSOAInterface", - "ole2disp.dll", - "oleaut32.dll", - "Both" - }, - { &CLSID_PSTypeComp, - "PSTypeComp", - "ole2disp.dll", - "oleaut32.dll", - "Both" - }, - { &CLSID_OldFont, - "Obsolete Font", - NULL, - "oleaut32.dll", - NULL, - "Obsolete Font", - "OldFont" - }, - { &IID_ISupportErrorInfo, - "PSSupportErrorInfo", - "ole2disp.dll", - "oleaut32.dll", - NULL - }, - { NULL } /* list terminator */ -}; - -/*********************************************************************** - * interface list - */ -#define INTERFACE_ENTRY(interface, clsid16, clsid32) { &IID_##interface, #interface, NULL, sizeof(interface##Vtbl)/sizeof(void*), clsid16, clsid32 } -#define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL) -#define CLSID_INTERFACE_ENTRY(interface,clsid) INTERFACE_ENTRY(interface, clsid, clsid) - -static struct regsvr_interface const interface_list[] = { - LCL_INTERFACE_ENTRY(ICreateTypeInfo), - LCL_INTERFACE_ENTRY(ICreateTypeLib), - CLSID_INTERFACE_ENTRY(IDispatch,&CLSID_PSDispatch), - CLSID_INTERFACE_ENTRY(IEnumVARIANT,&CLSID_PSEnumVariant), - CLSID_INTERFACE_ENTRY(ITypeComp,&CLSID_PSTypeComp), - CLSID_INTERFACE_ENTRY(ITypeInfo,&CLSID_PSTypeInfo), - CLSID_INTERFACE_ENTRY(ITypeLib,&CLSID_PSTypeLib), - INTERFACE_ENTRY(ISupportErrorInfo,NULL,&CLSID_PSDispatch), - INTERFACE_ENTRY(ITypeFactory,NULL,&CLSID_PSDispatch), - INTERFACE_ENTRY(ITypeInfo2,NULL,&CLSID_PSDispatch), - INTERFACE_ENTRY(ITypeLib2,NULL,&CLSID_PSDispatch), - { NULL } /* list terminator */ -}; - -extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN; -extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN; - -/*********************************************************************** - * DllRegisterServer (OLEAUT32.@) - */ -HRESULT WINAPI DllRegisterServer(void) -{ - HRESULT hr; - - TRACE("\n"); - - hr = OLEAUTPS_DllRegisterServer(); - if (SUCCEEDED(hr)) - hr = register_coclasses(coclass_list); - if (SUCCEEDED(hr)) - hr = register_interfaces(interface_list); - if (SUCCEEDED(hr)) - { - const WCHAR stdole32W[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0}; - const WCHAR stdole2W[] = {'s','t','d','o','l','e','2','.','t','l','b',0}; - hr = register_typelib( stdole2W ); - if (SUCCEEDED(hr)) hr = register_typelib( stdole32W ); - } - return hr; -} - -/*********************************************************************** - * DllUnregisterServer (OLEAUT32.@) - */ -HRESULT WINAPI DllUnregisterServer(void) -{ - HRESULT hr; - - TRACE("\n"); - - hr = unregister_coclasses(coclass_list); - if (SUCCEEDED(hr)) - hr = unregister_interfaces(interface_list); - if (SUCCEEDED(hr)) - hr = OLEAUTPS_DllUnregisterServer(); - return hr; -} diff --git a/reactos/dll/win32/oleaut32/safearray.c b/reactos/dll/win32/oleaut32/safearray.c index f8f87ebd8b9..57a0d107c82 100644 --- a/reactos/dll/win32/oleaut32/safearray.c +++ b/reactos/dll/win32/oleaut32/safearray.c @@ -172,11 +172,15 @@ static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa) /* Allocate a descriptor for an array */ static HRESULT SAFEARRAY_AllocDescriptor(ULONG ulSize, SAFEARRAY **ppsaOut) { - *ppsaOut = (SAFEARRAY*)((char*)SAFEARRAY_Malloc(ulSize + SAFEARRAY_HIDDEN_SIZE) + SAFEARRAY_HIDDEN_SIZE); + char *ptr = SAFEARRAY_Malloc(ulSize + SAFEARRAY_HIDDEN_SIZE); - if (!*ppsaOut) - return E_UNEXPECTED; + if (!ptr) + { + *ppsaOut = NULL; + return E_UNEXPECTED; + } + *ppsaOut = (SAFEARRAY*)(ptr + SAFEARRAY_HIDDEN_SIZE); return S_OK; } @@ -1012,7 +1016,7 @@ HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound) * * PARAMS * psa [I] Array to get dimension lower bound from - * nDim [I] The dimension number to get the lowe bound of + * nDim [I] The dimension number to get the lower bound of * plLbound [O] Destination for the lower bound * * RETURNS @@ -1352,10 +1356,7 @@ HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut) return S_OK; /* Handles copying of NULL arrays */ if (!psa->cbElements) - { - ERR("not copying an array of 0 elements\n"); return E_INVALIDARG; - } if (psa->fFeatures & (FADF_RECORD|FADF_HAVEIID|FADF_HAVEVARTYPE)) { diff --git a/reactos/dll/win32/oleaut32/stubs.c b/reactos/dll/win32/oleaut32/stubs.c deleted file mode 100644 index d87e76e2d13..00000000000 --- a/reactos/dll/win32/oleaut32/stubs.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * OlePro32 Stubs - * - * Copyright 1999 Corel Corporation - * - * Sean Langley - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "wine/debug.h" -#include "ole2.h" -#include "olectl.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -/*********************************************************************** - * OleCreatePropertyFrameIndirect (OLEAUT32.416) - */ -HRESULT WINAPI OleCreatePropertyFrameIndirect( LPOCPFIPARAMS lpParams) -{ - FIXME("(%p), not implemented (olepro32.dll)\n",lpParams); - return S_OK; -} - -/*********************************************************************** - * OleCreatePropertyFrame (OLEAUT32.417) - */ -HRESULT WINAPI OleCreatePropertyFrame( - HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption,ULONG cObjects, - LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid, - DWORD dwReserved, LPVOID pvReserved ) -{ - FIXME("(%p,%d,%d,%s,%d,%p,%d,%p,%x,%d,%p), not implemented (olepro32.dll)\n", - hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,ppUnk,cPages, - pPageClsID, (int)lcid,dwReserved,pvReserved); - return S_OK; -} diff --git a/reactos/dll/win32/oleaut32/tmarshal.c b/reactos/dll/win32/oleaut32/tmarshal.c index db1a6c972f6..1c5326ba03b 100644 --- a/reactos/dll/win32/oleaut32/tmarshal.c +++ b/reactos/dll/win32/oleaut32/tmarshal.c @@ -54,8 +54,6 @@ static const WCHAR IDispatchW[] = { 'I','D','i','s','p','a','t','c','h',0}; WINE_DEFAULT_DEBUG_CHANNEL(ole); WINE_DECLARE_DEBUG_CHANNEL(olerelay); -#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field)) - static HRESULT TMarshalDispatchChannel_Create( IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid, IRpcChannelBuffer **ppChannel); @@ -155,6 +153,7 @@ _unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) { hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res); if (hres) { ERR("stream write %x\n",hres); + IStream_Release(pStm); return hres; } @@ -162,12 +161,14 @@ _unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) { hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); if (hres) { ERR("Failed Seek %x\n",hres); + IStream_Release(pStm); return hres; } hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk); if (hres) { ERR("Unmarshalling interface %s failed with %x\n",debugstr_guid(riid),hres); + IStream_Release(pStm); return hres; } @@ -245,7 +246,7 @@ _marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) { fail: xsize = 0; xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize)); - if (pStm) IUnknown_Release(pStm); + if (pStm) IStream_Release(pStm); HeapFree(GetProcessHeap(), 0, tempbuf); return hres; } @@ -322,48 +323,85 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) { } /* - * Determine the number of functions including all inherited functions. + * Determine the number of functions including all inherited functions + * and well as the size of the vtbl. * Note for non-dual dispinterfaces we simply return the size of IDispatch. */ -static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num) +static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num, + unsigned int *vtbl_size) { - HRESULT hres; + HRESULT hr; TYPEATTR *attr; ITypeInfo *tinfo2; + UINT inherited_funcs = 0, i; *num = 0; - hres = ITypeInfo_GetTypeAttr(tinfo, &attr); - if (hres) { - ERR("GetTypeAttr failed with %x\n",hres); - return hres; + if(vtbl_size) *vtbl_size = 0; + + hr = ITypeInfo_GetTypeAttr(tinfo, &attr); + if (hr) + { + ERR("GetTypeAttr failed with %x\n", hr); + return hr; } - if(attr->typekind == TKIND_DISPATCH && (attr->wTypeFlags & TYPEFLAG_FDUAL)) + if(attr->typekind == TKIND_DISPATCH) + { + if(attr->wTypeFlags & TYPEFLAG_FDUAL) + { + HREFTYPE href; + + ITypeInfo_ReleaseTypeAttr(tinfo, attr); + hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href); + if(FAILED(hr)) + { + ERR("Unable to get interface href from dual dispinterface\n"); + return hr; + } + hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2); + if(FAILED(hr)) + { + ERR("Unable to get interface from dual dispinterface\n"); + return hr; + } + hr = num_of_funcs(tinfo2, num, vtbl_size); + ITypeInfo_Release(tinfo2); + return hr; + } + else /* non-dual dispinterface */ + { + /* These will be the size of IDispatchVtbl */ + *num = attr->cbSizeVft / sizeof(void *); + if(vtbl_size) *vtbl_size = attr->cbSizeVft; + ITypeInfo_ReleaseTypeAttr(tinfo, attr); + return hr; + } + } + + for (i = 0; i < attr->cImplTypes; i++) { HREFTYPE href; - hres = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href); - if(FAILED(hres)) - { - ERR("Unable to get interface href from dual dispinterface\n"); - goto end; - } - hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2); - if(FAILED(hres)) - { - ERR("Unable to get interface from dual dispinterface\n"); - goto end; - } - hres = num_of_funcs(tinfo2, num); - ITypeInfo_Release(tinfo2); - } - else - { - *num = attr->cbSizeVft / 4; + ITypeInfo *pSubTypeInfo; + UINT sub_funcs; + + hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href); + if (FAILED(hr)) goto end; + hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo); + if (FAILED(hr)) goto end; + + hr = num_of_funcs(pSubTypeInfo, &sub_funcs, NULL); + ITypeInfo_Release(pSubTypeInfo); + + if(FAILED(hr)) goto end; + inherited_funcs += sub_funcs; } + *num = inherited_funcs + attr->cFuncs; + if(vtbl_size) *vtbl_size = attr->cbSizeVft; + end: ITypeInfo_ReleaseTypeAttr(tinfo, attr); - return hres; + return hr; } #ifdef __i386__ @@ -397,7 +435,7 @@ typedef struct _TMAsmProxy { typedef struct _TMProxyImpl { LPVOID *lpvtbl; - const IRpcProxyBufferVtbl *lpvtbl2; + IRpcProxyBuffer IRpcProxyBuffer_iface; LONG ref; TMAsmProxy *asmstubs; @@ -410,6 +448,11 @@ typedef struct _TMProxyImpl { IRpcProxyBuffer *dispatch_proxy; } TMProxyImpl; +static inline TMProxyImpl *impl_from_IRpcProxyBuffer( IRpcProxyBuffer *iface ) +{ + return CONTAINING_RECORD(iface, TMProxyImpl, IRpcProxyBuffer_iface); +} + static HRESULT WINAPI TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv) { @@ -426,7 +469,7 @@ TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv) static ULONG WINAPI TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface) { - ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface); + TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface ); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); @@ -437,7 +480,7 @@ TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface) static ULONG WINAPI TMProxyImpl_Release(LPRPCPROXYBUFFER iface) { - ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface); + TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface ); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); @@ -460,7 +503,7 @@ static HRESULT WINAPI TMProxyImpl_Connect( LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer) { - ICOM_THIS_MULTI(TMProxyImpl, lpvtbl2, iface); + TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface ); TRACE("(%p)\n", pRpcChannelBuffer); @@ -488,7 +531,7 @@ TMProxyImpl_Connect( static void WINAPI TMProxyImpl_Disconnect(LPRPCPROXYBUFFER iface) { - ICOM_THIS_MULTI(TMProxyImpl, lpvtbl2, iface); + TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface ); TRACE("()\n"); @@ -558,9 +601,8 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) { return sizeof(DATE); case VT_CY: return sizeof(CY); - /* FIXME: VT_BOOL should return 2? */ case VT_VARIANT: - return sizeof(VARIANT)+3; /* FIXME: why the +3? */ + return sizeof(VARIANT); case VT_CARRAY: { int i, arrsize = 1; const ARRAYDESC *adesc = td->u.lpadesc; @@ -575,6 +617,7 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) { return 8; case VT_UI2: case VT_I2: + case VT_BOOL: return 2; case VT_UI1: case VT_I1: @@ -600,6 +643,17 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) { } } +/* Whether we pass this type by reference or by value */ +static int +_passbyref(const TYPEDESC *td, ITypeInfo *tinfo) { + if (td->vt == VT_USERDEFINED || + td->vt == VT_VARIANT || + td->vt == VT_PTR) + return 1; + + return 0; +} + static HRESULT serialize_param( ITypeInfo *tinfo, @@ -620,6 +674,7 @@ serialize_param( vartype = VT_SAFEARRAY; switch (vartype) { + case VT_DATE: case VT_I8: case VT_UI8: case VT_R8: @@ -629,7 +684,6 @@ serialize_param( if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,8); return hres; - case VT_BOOL: case VT_ERROR: case VT_INT: case VT_UINT: @@ -643,6 +697,7 @@ serialize_param( return hres; case VT_I2: case VT_UI2: + case VT_BOOL: hres = S_OK; if (debugout) TRACE_(olerelay)("%04x\n",*arg & 0xffff); if (writeit) @@ -673,7 +728,7 @@ serialize_param( return S_OK; } case VT_BSTR: { - if (debugout) { + if (writeit && debugout) { if (*arg) TRACE_(olerelay)("%s",relaystr((WCHAR*)*arg)); else @@ -798,7 +853,7 @@ serialize_param( ELEMDESC *elem2; TYPEDESC *tdesc2; - hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc); + hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc); if (hres) { ERR("Could not get vardesc of %d\n",i); return hres; @@ -853,7 +908,8 @@ serialize_param( if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt)); if (debugout) TRACE_(olerelay)("["); for (i=0;itdescElem, (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), buf); + LPBYTE base = _passbyref(&adesc->tdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg; + hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf); if (hres) return hres; if (debugout && (icVars;i++) { VARDESC *vdesc; - hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc); + hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc); if (hres) { ERR("Could not get vardesc of %d\n",i); ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); @@ -1102,7 +1159,7 @@ deserialize_param( (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), buf ); - ITypeInfo2_ReleaseVarDesc(tinfo2, vdesc); + ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); if (debugout && (icVars-1)) TRACE_(olerelay)(","); } if (debugout) TRACE_(olerelay)("}"); @@ -1132,13 +1189,18 @@ deserialize_param( } case VT_CARRAY: { /* arg is pointing to the start of the array. */ + LPBYTE base = (LPBYTE) arg; ARRAYDESC *adesc = tdesc->u.lpadesc; int arrsize,i; arrsize = 1; if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n"); for (i=0;icDims;i++) arrsize *= adesc->rgbounds[i].cElements; - *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize); + if (_passbyref(&adesc->tdescElem, tinfo)) + { + base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize); + *arg = (DWORD) base; + } for (i=0;itdescElem, - (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), + (DWORD*)(base + i*_xsize(&adesc->tdescElem, tinfo)), buf ); return S_OK; @@ -1345,11 +1407,20 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */) TRACE_(olerelay)("%s=",relaystr(names[i+1])); } /* No need to marshal other data than FIN and any VT_PTR. */ - if (!is_in_elem(elem) && (elem->tdesc.vt != VT_PTR)) { - xargs+=_argsize(&elem->tdesc, tinfo); - if (relaydeb) TRACE_(olerelay)("[out]"); - continue; - } + if (!is_in_elem(elem)) + { + if (elem->tdesc.vt != VT_PTR) + { + xargs+=_argsize(&elem->tdesc, tinfo); + if (relaydeb) TRACE_(olerelay)("[out]"); + continue; + } + else + { + memset( *(void **)xargs, 0, _xsize( elem->tdesc.u.lptdesc, tinfo ) ); + } + } + hres = serialize_param( tinfo, is_in_elem(elem), @@ -1526,20 +1597,25 @@ static HRESULT WINAPI ProxyIDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMembe typedef struct { - const IRpcChannelBufferVtbl *lpVtbl; + IRpcChannelBuffer IRpcChannelBuffer_iface; LONG refs; /* the IDispatch-derived interface we are handling */ - IID tmarshal_iid; + IID tmarshal_iid; IRpcChannelBuffer *pDelegateChannel; } TMarshalDispatchChannel; -static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(LPRPCCHANNELBUFFER iface, REFIID riid, LPVOID *ppv) +static inline TMarshalDispatchChannel *impl_from_IRpcChannelBuffer(IRpcChannelBuffer *iface) +{ + return CONTAINING_RECORD(iface, TMarshalDispatchChannel, IRpcChannelBuffer_iface); +} + +static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(IRpcChannelBuffer *iface, REFIID riid, LPVOID *ppv) { *ppv = NULL; if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown)) { *ppv = iface; - IUnknown_AddRef(iface); + IRpcChannelBuffer_AddRef(iface); return S_OK; } return E_NOINTERFACE; @@ -1547,13 +1623,13 @@ static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(LPRPCCHANNELBUFFER static ULONG WINAPI TMarshalDispatchChannel_AddRef(LPRPCCHANNELBUFFER iface) { - TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface; + TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); return InterlockedIncrement(&This->refs); } static ULONG WINAPI TMarshalDispatchChannel_Release(LPRPCCHANNELBUFFER iface) { - TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface; + TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); ULONG ref; ref = InterlockedDecrement(&This->refs); @@ -1567,7 +1643,7 @@ static ULONG WINAPI TMarshalDispatchChannel_Release(LPRPCCHANNELBUFFER iface) static HRESULT WINAPI TMarshalDispatchChannel_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg, REFIID riid) { - TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface; + TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); TRACE("(%p, %s)\n", olemsg, debugstr_guid(riid)); /* Note: we are pretending to invoke a method on the interface identified * by tmarshal_iid so that we can re-use the IDispatch proxy/stub code @@ -1577,28 +1653,28 @@ static HRESULT WINAPI TMarshalDispatchChannel_GetBuffer(LPRPCCHANNELBUFFER iface static HRESULT WINAPI TMarshalDispatchChannel_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus) { - TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface; + TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); TRACE("(%p, %p)\n", olemsg, pstatus); return IRpcChannelBuffer_SendReceive(This->pDelegateChannel, olemsg, pstatus); } static HRESULT WINAPI TMarshalDispatchChannel_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg) { - TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface; + TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); TRACE("(%p)\n", olemsg); return IRpcChannelBuffer_FreeBuffer(This->pDelegateChannel, olemsg); } static HRESULT WINAPI TMarshalDispatchChannel_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD* pdwDestContext, void** ppvDestContext) { - TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface; + TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); TRACE("(%p,%p)\n", pdwDestContext, ppvDestContext); return IRpcChannelBuffer_GetDestCtx(This->pDelegateChannel, pdwDestContext, ppvDestContext); } static HRESULT WINAPI TMarshalDispatchChannel_IsConnected(LPRPCCHANNELBUFFER iface) { - TMarshalDispatchChannel *This = (TMarshalDispatchChannel *)iface; + TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); TRACE("()\n"); return IRpcChannelBuffer_IsConnected(This->pDelegateChannel); } @@ -1623,13 +1699,13 @@ static HRESULT TMarshalDispatchChannel_Create( if (!This) return E_OUTOFMEMORY; - This->lpVtbl = &TMarshalDispatchChannelVtbl; + This->IRpcChannelBuffer_iface.lpVtbl = &TMarshalDispatchChannelVtbl; This->refs = 1; IRpcChannelBuffer_AddRef(pDelegateChannel); This->pDelegateChannel = pDelegateChannel; This->tmarshal_iid = *tmarshal_riid; - *ppChannel = (IRpcChannelBuffer *)&This->lpVtbl; + *ppChannel = &This->IRpcChannelBuffer_iface; return S_OK; } @@ -1690,7 +1766,7 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num) xasm->lret = 0xc2; xasm->bytestopop = (nrofargs+2)*4; /* pop args, This, iMethod */ xasm->nop = 0x90; - proxy->lpvtbl[num] = xasm; + proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm; #else FIXME("not implemented on non i386\n"); return E_FAIL; @@ -1705,7 +1781,7 @@ PSFacBuf_CreateProxy( { HRESULT hres; ITypeInfo *tinfo; - unsigned int i, nroffuncs; + unsigned int i, nroffuncs, vtbl_size; TMProxyImpl *proxy; TYPEATTR *typeattr; BOOL defer_to_dispatch = FALSE; @@ -1717,7 +1793,9 @@ PSFacBuf_CreateProxy( return hres; } - hres = num_of_funcs(tinfo, &nroffuncs); + hres = num_of_funcs(tinfo, &nroffuncs, &vtbl_size); + TRACE("Got %d funcs, vtbl size %d\n", nroffuncs, vtbl_size); + if (FAILED(hres)) { ERR("Cannot get number of functions for typeinfo %s\n",debugstr_guid(riid)); ITypeInfo_Release(tinfo); @@ -1738,7 +1816,7 @@ PSFacBuf_CreateProxy( CoTaskMemFree(proxy); return E_OUTOFMEMORY; } - proxy->lpvtbl2 = &tmproxyvtable; + proxy->IRpcProxyBuffer_iface.lpVtbl = &tmproxyvtable; /* one reference for the proxy */ proxy->ref = 1; proxy->tinfo = tinfo; @@ -1748,7 +1826,7 @@ PSFacBuf_CreateProxy( InitializeCriticalSection(&proxy->crit); proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TMProxyImpl.crit"); - proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs); + proxy->lpvtbl = HeapAlloc(GetProcessHeap(), 0, vtbl_size); /* if we derive from IDispatch then defer to its proxy for its methods */ hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr); @@ -1830,17 +1908,17 @@ PSFacBuf_CreateProxy( if (hres == S_OK) { *ppv = proxy; - *ppProxy = (IRpcProxyBuffer *)&(proxy->lpvtbl2); + *ppProxy = &proxy->IRpcProxyBuffer_iface; IUnknown_AddRef((IUnknown *)*ppv); return S_OK; } else - TMProxyImpl_Release((IRpcProxyBuffer *)&proxy->lpvtbl2); + TMProxyImpl_Release(&proxy->IRpcProxyBuffer_iface); return hres; } typedef struct _TMStubImpl { - const IRpcStubBufferVtbl *lpvtbl; + IRpcStubBuffer IRpcStubBuffer_iface; LONG ref; LPUNKNOWN pUnk; @@ -1850,6 +1928,11 @@ typedef struct _TMStubImpl { BOOL dispatch_derivative; } TMStubImpl; +static inline TMStubImpl *impl_from_IRpcStubBuffer(IRpcStubBuffer *iface) +{ + return CONTAINING_RECORD(iface, TMStubImpl, IRpcStubBuffer_iface); +} + static HRESULT WINAPI TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv) { @@ -1865,7 +1948,7 @@ TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv) static ULONG WINAPI TMStubImpl_AddRef(LPRPCSTUBBUFFER iface) { - TMStubImpl *This = (TMStubImpl *)iface; + TMStubImpl *This = impl_from_IRpcStubBuffer(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before=%u)\n", This, refCount - 1); @@ -1876,7 +1959,7 @@ TMStubImpl_AddRef(LPRPCSTUBBUFFER iface) static ULONG WINAPI TMStubImpl_Release(LPRPCSTUBBUFFER iface) { - TMStubImpl *This = (TMStubImpl *)iface; + TMStubImpl *This = impl_from_IRpcStubBuffer(iface); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before=%u)\n", This, refCount + 1); @@ -1895,7 +1978,7 @@ TMStubImpl_Release(LPRPCSTUBBUFFER iface) static HRESULT WINAPI TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer) { - TMStubImpl *This = (TMStubImpl *)iface; + TMStubImpl *This = impl_from_IRpcStubBuffer(iface); TRACE("(%p)->(%p)\n", This, pUnkServer); @@ -1911,7 +1994,7 @@ TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer) static void WINAPI TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface) { - TMStubImpl *This = (TMStubImpl *)iface; + TMStubImpl *This = impl_from_IRpcStubBuffer(iface); TRACE("(%p)->()\n", This); @@ -1932,7 +2015,7 @@ TMStubImpl_Invoke( #ifdef __i386__ int i; const FUNCDESC *fdesc; - TMStubImpl *This = (TMStubImpl *)iface; + TMStubImpl *This = impl_from_IRpcStubBuffer(iface); HRESULT hres; DWORD *args = NULL, res, *xargs, nrofargs; marshal_state buf; @@ -1950,16 +2033,19 @@ TMStubImpl_Invoke( if (This->dispatch_derivative && xmsg->iMethod < sizeof(IDispatchVtbl)/sizeof(void *)) { - IPSFactoryBuffer *factory_buffer; - hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer); - if (hres == S_OK) + if (!This->dispatch_stub) { - hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch, - This->pUnk, &This->dispatch_stub); - IPSFactoryBuffer_Release(factory_buffer); + IPSFactoryBuffer *factory_buffer; + hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer); + if (hres == S_OK) + { + hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch, + This->pUnk, &This->dispatch_stub); + IPSFactoryBuffer_Release(factory_buffer); + } + if (hres != S_OK) + return hres; } - if (hres != S_OK) - return hres; return IRpcStubBuffer_Invoke(This->dispatch_stub, xmsg, rpcchanbuf); } @@ -2108,7 +2194,7 @@ TMStubImpl_IsIIDSupported(LPRPCSTUBBUFFER iface, REFIID riid) { static ULONG WINAPI TMStubImpl_CountRefs(LPRPCSTUBBUFFER iface) { - TMStubImpl *This = (TMStubImpl *)iface; + TMStubImpl *This = impl_from_IRpcStubBuffer(iface); FIXME("()\n"); return This->ref; /*FIXME? */ @@ -2158,14 +2244,14 @@ PSFacBuf_CreateStub( stub = CoTaskMemAlloc(sizeof(TMStubImpl)); if (!stub) return E_OUTOFMEMORY; - stub->lpvtbl = &tmstubvtbl; + stub->IRpcStubBuffer_iface.lpVtbl = &tmstubvtbl; stub->ref = 1; stub->tinfo = tinfo; stub->dispatch_stub = NULL; stub->dispatch_derivative = FALSE; stub->iid = *riid; - hres = IRpcStubBuffer_Connect((LPRPCSTUBBUFFER)stub,pUnkServer); - *ppStub = (LPRPCSTUBBUFFER)stub; + hres = IRpcStubBuffer_Connect(&stub->IRpcStubBuffer_iface,pUnkServer); + *ppStub = &stub->IRpcStubBuffer_iface; TRACE("IRpcStubBuffer: %p\n", stub); if (hres) ERR("Connect to pUnkServer failed?\n"); diff --git a/reactos/dll/win32/oleaut32/typelib.c b/reactos/dll/win32/oleaut32/typelib.c index 46c0d284be0..fa9b0501ecb 100644 --- a/reactos/dll/win32/oleaut32/typelib.c +++ b/reactos/dll/win32/oleaut32/typelib.c @@ -367,6 +367,11 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin, */ HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path ) { +#ifdef _WIN64 + HRESULT hres = query_typelib_path( guid, wMaj, wMin, SYS_WIN64, lcid, path ); + if(SUCCEEDED(hres)) + return hres; +#endif return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path ); } @@ -441,7 +446,7 @@ HRESULT WINAPI LoadTypeLibEx( case REGKIND_REGISTER: if (FAILED(res = RegisterTypeLib(*pptLib, szPath, NULL))) { - IUnknown_Release(*pptLib); + ITypeLib_Release(*pptLib); *pptLib = 0; } break; @@ -813,7 +818,7 @@ HRESULT WINAPI UnRegisterTypeLib( } /* Try and load the type library */ - if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib)) { + if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib) != S_OK) { result = TYPE_E_INVALIDSTATE; goto end; } @@ -952,7 +957,7 @@ typedef struct tagTLBCustData { GUID guid; VARIANT data; - struct tagTLBCustData* next; + struct list entry; } TLBCustData; /* data structure for import typelibs */ @@ -972,7 +977,7 @@ typedef struct tagTLBImpLib struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib, or NULL if not yet loaded */ - struct tagTLBImpLib * next; + struct list entry; } TLBImpLib; /* internal ITypeLib data */ @@ -993,10 +998,9 @@ typedef struct tagITypeLibImpl BSTR HelpStringDll; DWORD dwHelpContext; int TypeInfoCount; /* nr of typeinfo's in librarry */ - struct tagITypeInfoImpl *pTypeInfo; /* linked list of type info data */ - int ctCustData; /* number of items in cust data list */ - TLBCustData * pCustData; /* linked list to cust data */ - TLBImpLib * pImpLibs; /* linked list to all imported typelibs */ + struct tagITypeInfoImpl **typeinfos; + struct list custdata_list; + struct list implib_list; int ctTypeDesc; /* number of items in type desc array */ TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the library. Only used while reading MSFT @@ -1006,7 +1010,7 @@ typedef struct tagITypeLibImpl /* typelibs are cached, keyed by path and index, so store the linked list info within them */ - struct tagITypeLibImpl *next, *prev; + struct list entry; WCHAR *path; INT index; } ITypeLibImpl; @@ -1052,8 +1056,7 @@ typedef struct tagTLBRefType typedef struct tagTLBParDesc { BSTR Name; - int ctCustData; - TLBCustData * pCustData; /* linked list to cust data */ + struct list custdata_list; } TLBParDesc; /* internal Function data */ @@ -1066,9 +1069,7 @@ typedef struct tagTLBFuncDesc int HelpStringContext; BSTR HelpString; BSTR Entry; /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */ - int ctCustData; - TLBCustData * pCustData; /* linked list to cust data; */ - struct tagTLBFuncDesc * next; + struct list custdata_list; } TLBFuncDesc; /* internal Variable data */ @@ -1077,11 +1078,9 @@ typedef struct tagTLBVarDesc VARDESC vardesc; /* lots of info on the variable and its attributes. */ BSTR Name; /* the name of this variable */ int HelpContext; - int HelpStringContext; /* FIXME: where? */ + int HelpStringContext; BSTR HelpString; - int ctCustData; - TLBCustData * pCustData;/* linked list to cust data; */ - struct tagTLBVarDesc * next; + struct list custdata_list; } TLBVarDesc; /* internal implemented interface data */ @@ -1089,9 +1088,7 @@ typedef struct tagTLBImplType { HREFTYPE hRef; /* hRef of interface */ int implflags; /* IMPLFLAG_*s */ - int ctCustData; - TLBCustData * pCustData;/* linked list to custom data; */ - struct tagTLBImplType *next; + struct list custdata_list; } TLBImplType; /* internal TypeInfo data */ @@ -1115,17 +1112,15 @@ typedef struct tagITypeInfoImpl DWORD dwHelpStringContext; /* functions */ - TLBFuncDesc * funclist; /* linked list with function descriptions */ + TLBFuncDesc *funcdescs; /* variables */ - TLBVarDesc * varlist; /* linked list with variable descriptions */ + TLBVarDesc *vardescs; /* Implemented Interfaces */ - TLBImplType * impltypelist; + TLBImplType *impltypes; - int ctCustData; - TLBCustData * pCustData; /* linked list to cust data; */ - struct tagITypeInfoImpl * next; + struct list custdata_list; } ITypeInfoImpl; static inline ITypeInfoImpl *info_impl_from_ITypeComp( ITypeComp *iface ) @@ -1136,8 +1131,8 @@ static inline ITypeInfoImpl *info_impl_from_ITypeComp( ITypeComp *iface ) static const ITypeInfo2Vtbl tinfvt; static const ITypeCompVtbl tcompvt; -static ITypeInfo2 * ITypeInfo_Constructor(void); -static void ITypeInfo_fnDestroy(ITypeInfoImpl *This); +static ITypeInfoImpl* ITypeInfoImpl_Constructor(void); +static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This); typedef struct tagTLBContext { @@ -1285,21 +1280,23 @@ static void dump_TLBFuncDescOne(const TLBFuncDesc * pfd) MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString)); MESSAGE("\tentry: %s\n", (pfd->Entry == (void *)-1) ? "invalid" : debugstr_w(pfd->Entry)); } -static void dump_TLBFuncDesc(const TLBFuncDesc * pfd) +static void dump_TLBFuncDesc(const TLBFuncDesc * pfd, UINT n) { - while (pfd) + while (n) { dump_TLBFuncDescOne(pfd); - pfd = pfd->next; - }; + ++pfd; + --n; + } } -static void dump_TLBVarDesc(const TLBVarDesc * pvd) +static void dump_TLBVarDesc(const TLBVarDesc * pvd, UINT n) { - while (pvd) + while (n) { TRACE_(typelib)("%s\n", debugstr_w(pvd->Name)); - pvd = pvd->next; - }; + ++pvd; + --n; + } } static void dump_TLBImpLib(const TLBImpLib *import) @@ -1330,13 +1327,15 @@ static void dump_TLBRefType(const ITypeLibImpl *pTL) } } -static void dump_TLBImplType(const TLBImplType * impl) +static void dump_TLBImplType(const TLBImplType * impl, UINT n) { - while (impl) { - TRACE_(typelib)( - "implementing/inheriting interface hRef = %x implflags %x\n", - impl->hRef, impl->implflags); - impl = impl->next; + if(!impl) + return; + while (n) { + TRACE_(typelib)("implementing/inheriting interface hRef = %x implflags %x\n", + impl->hRef, impl->implflags); + ++impl; + --n; } } @@ -1428,9 +1427,9 @@ static void dump_TypeInfo(const ITypeInfoImpl * pty) TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index); if (pty->TypeAttr.typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(pty->DllName)); if (TRACE_ON(ole)) - dump_TLBFuncDesc(pty->funclist); - dump_TLBVarDesc(pty->varlist); - dump_TLBImplType(pty->impltypelist); + dump_TLBFuncDesc(pty->funcdescs, pty->TypeAttr.cFuncs); + dump_TLBVarDesc(pty->vardescs, pty->TypeAttr.cVars); + dump_TLBImplType(pty->impltypes, pty->TypeAttr.cImplTypes); } static void dump_VARDESC(const VARDESC *v) @@ -1443,17 +1442,17 @@ static void dump_VARDESC(const VARDESC *v) MESSAGE("varkind %d\n",v->varkind); } -static TYPEDESC stndTypeDesc[VT_LPWSTR+1]= +static TYPEDESC std_typedesc[VT_LPWSTR+1] = { - /* VT_LPWSTR is largest type that */ - /* may appear in type description*/ - {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4}, - {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9}, - {{0},10},{{0},11},{{0},12},{{0},13},{{0},14}, - {{0},15},{{0},16},{{0},17},{{0},18},{{0},19}, - {{0},20},{{0},21},{{0},22},{{0},23},{{0},24}, - {{0},25},{{0},26},{{0},27},{{0},28},{{0},29}, - {{0},30},{{0},31} + /* VT_LPWSTR is largest type that, may appear in type description */ + {{0}, VT_EMPTY}, {{0}, VT_NULL}, {{0}, VT_I2}, {{0}, VT_I4}, + {{0}, VT_R4}, {{0}, VT_R8}, {{0}, VT_CY}, {{0}, VT_DATE}, + {{0}, VT_BSTR}, {{0}, VT_DISPATCH}, {{0}, VT_ERROR}, {{0}, VT_BOOL}, + {{0}, VT_VARIANT},{{0}, VT_UNKNOWN}, {{0}, VT_DECIMAL}, {{0}, 15}, /* unused in VARENUM */ + {{0}, VT_I1}, {{0}, VT_UI1}, {{0}, VT_UI2}, {{0}, VT_UI4}, + {{0}, VT_I8}, {{0}, VT_UI8}, {{0}, VT_INT}, {{0}, VT_UINT}, + {{0}, VT_VOID}, {{0}, VT_HRESULT}, {{0}, VT_PTR}, {{0}, VT_SAFEARRAY}, + {{0}, VT_CARRAY}, {{0}, VT_USERDEFINED}, {{0}, VT_LPSTR}, {{0}, VT_LPWSTR} }; static void TLB_abort(void) @@ -1461,18 +1460,26 @@ static void TLB_abort(void) DebugBreak(); } -static void * TLB_Alloc(unsigned size) __WINE_ALLOC_SIZE(1); -static void * TLB_Alloc(unsigned size) +void* __WINE_ALLOC_SIZE(1) heap_alloc_zero(unsigned size) { - void * ret; - if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){ - /* FIXME */ - ERR("cannot allocate memory\n"); - } + void *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (!ret) ERR("cannot allocate memory\n"); return ret; } -static void TLB_Free(void * ptr) +void* __WINE_ALLOC_SIZE(1) heap_alloc(unsigned size) +{ + void *ret = HeapAlloc(GetProcessHeap(), 0, size); + if (!ret) ERR("cannot allocate memory\n"); + return ret; +} + +void* __WINE_ALLOC_SIZE(2) heap_realloc(void *ptr, unsigned size) +{ + return HeapReAlloc(GetProcessHeap(), 0, ptr, size); +} + +void heap_free(void *ptr) { HeapFree(GetProcessHeap(), 0, ptr); } @@ -1529,15 +1536,14 @@ static void *TLB_CopyTypeDesc( TYPEDESC *dest, const TYPEDESC *src, void *buffer } /* free custom data allocated by MSFT_CustData */ -static inline void TLB_FreeCustData(TLBCustData *pCustData) +static inline void TLB_FreeCustData(struct list *custdata_list) { - TLBCustData *pCustDataNext; - for (; pCustData; pCustData = pCustDataNext) + TLBCustData *cd, *cdn; + LIST_FOR_EACH_ENTRY_SAFE(cd, cdn, custdata_list, TLBCustData, entry) { - VariantClear(&pCustData->data); - - pCustDataNext = pCustData->next; - TLB_Free(pCustData); + list_remove(&cd->entry); + VariantClear(&cd->data); + heap_free(cd); } } @@ -1553,6 +1559,127 @@ static BSTR TLB_MultiByteToBSTR(const char *ptr) return ret; } +static inline TLBFuncDesc *TLB_get_funcdesc_by_memberid(TLBFuncDesc *funcdescs, + UINT n, MEMBERID memid) +{ + while(n){ + if(funcdescs->funcdesc.memid == memid) + return funcdescs; + ++funcdescs; + --n; + } + return NULL; +} + +static inline TLBFuncDesc *TLB_get_funcdesc_by_name(TLBFuncDesc *funcdescs, + UINT n, const OLECHAR *name) +{ + while(n){ + if(!lstrcmpiW(funcdescs->Name, name)) + return funcdescs; + ++funcdescs; + --n; + } + return NULL; +} + +static inline TLBVarDesc *TLB_get_vardesc_by_memberid(TLBVarDesc *vardescs, + UINT n, MEMBERID memid) +{ + while(n){ + if(vardescs->vardesc.memid == memid) + return vardescs; + ++vardescs; + --n; + } + return NULL; +} + +static inline TLBVarDesc *TLB_get_vardesc_by_name(TLBVarDesc *vardescs, + UINT n, const OLECHAR *name) +{ + while(n){ + if(!lstrcmpiW(vardescs->Name, name)) + return vardescs; + ++vardescs; + --n; + } + return NULL; +} + +static inline TLBCustData *TLB_get_custdata_by_guid(struct list *custdata_list, REFGUID guid) +{ + TLBCustData *cust_data; + LIST_FOR_EACH_ENTRY(cust_data, custdata_list, TLBCustData, entry) + if(IsEqualIID(&cust_data->guid, guid)) + return cust_data; + return NULL; +} + +static TLBVarDesc *TLBVarDesc_Constructor(UINT n) +{ + TLBVarDesc *ret; + + ret = heap_alloc_zero(sizeof(TLBVarDesc) * n); + if(!ret) + return NULL; + + while(n){ + list_init(&ret[n-1].custdata_list); + --n; + } + + return ret; +} + +static TLBParDesc *TLBParDesc_Constructor(UINT n) +{ + TLBParDesc *ret; + + ret = heap_alloc_zero(sizeof(TLBParDesc) * n); + if(!ret) + return NULL; + + while(n){ + list_init(&ret[n-1].custdata_list); + --n; + } + + return ret; +} + +static TLBFuncDesc *TLBFuncDesc_Constructor(UINT n) +{ + TLBFuncDesc *ret; + + ret = heap_alloc_zero(sizeof(TLBFuncDesc) * n); + if(!ret) + return NULL; + + while(n){ + list_init(&ret[n-1].custdata_list); + --n; + } + + return ret; +} + +static TLBImplType *TLBImplType_Constructor(UINT n) +{ + TLBImplType *ret; + + ret = heap_alloc_zero(sizeof(TLBImplType) * n); + if(!ret) + return NULL; + + while(n){ + list_init(&ret[n-1].custdata_list); + --n; + } + + return ret; +} + /********************************************************************** * * Functions for reading MSFT typelibs (those created by CreateTypeLib2) @@ -1656,7 +1783,7 @@ static BSTR MSFT_ReadName( TLBContext *pcx, int offset) MSFT_ReadLEDWords(&niName, sizeof(niName), pcx, pcx->pTblDir->pNametab.offset+offset); niName.namelen &= 0xFF; /* FIXME: correct ? */ - name=TLB_Alloc((niName.namelen & 0xff) +1); + name = heap_alloc_zero((niName.namelen & 0xff) +1); MSFT_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK); name[niName.namelen & 0xff]='\0'; @@ -1671,7 +1798,7 @@ static BSTR MSFT_ReadName( TLBContext *pcx, int offset) /* don't check for invalid character since this has been done previously */ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, bstrName, lengthInChars); } - TLB_Free(name); + heap_free(name); TRACE_(typelib)("%s %d\n", debugstr_w(bstrName), lengthInChars); return bstrName; @@ -1687,7 +1814,7 @@ static BSTR MSFT_ReadString( TLBContext *pcx, int offset) if(offset<0) return NULL; MSFT_ReadLEWords(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset); if(length <= 0) return 0; - string=TLB_Alloc(length +1); + string = heap_alloc_zero(length +1); MSFT_Read(string, length, pcx, DO_NOT_SEEK); string[length]='\0'; @@ -1702,7 +1829,7 @@ static BSTR MSFT_ReadString( TLBContext *pcx, int offset) /* don't check for invalid character since this has been done previously */ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, bstr, lengthInChars); } - TLB_Free(string); + heap_free(string); TRACE_(typelib)("%s %d\n", debugstr_w(bstr), lengthInChars); return bstr; @@ -1764,13 +1891,13 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx ) size = nullPos - origPos; MSFT_Seek(pcx, origPos); } - ptr=TLB_Alloc(size);/* allocate temp buffer */ + ptr = heap_alloc_zero(size);/* allocate temp buffer */ MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */ V_BSTR(pVar)=SysAllocStringLen(NULL,size); /* FIXME: do we need a AtoW conversion here? */ V_UNION(pVar, bstrVal[size])='\0'; while(size--) V_UNION(pVar, bstrVal[size])=ptr[size]; - TLB_Free(ptr); + heap_free(ptr); } size=-4; break; /* FIXME: this will not work AT ALL when the variant contains a pointer */ @@ -1804,7 +1931,7 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx ) /* * create a linked list with custom data */ -static int MSFT_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData ) +static int MSFT_CustData( TLBContext *pcx, int offset, struct list *custdata_list) { MSFT_CDGuid entry; TLBCustData* pNew; @@ -1812,15 +1939,15 @@ static int MSFT_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData TRACE_(typelib)("\n"); + if (pcx->pTblDir->pCDGuids.offset < 0) return 0; + while(offset >=0){ count++; - pNew=TLB_Alloc(sizeof(TLBCustData)); + pNew=heap_alloc_zero(sizeof(TLBCustData)); MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset); MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx); MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx); - /* add new custom data at head of the list */ - pNew->next=*ppCustData; - *ppCustData=pNew; + list_add_head(custdata_list, &pNew->entry); offset = entry.next; } return count; @@ -1901,20 +2028,22 @@ MSFT_DoFuncs(TLBContext* pcx, * in the first part of this file segment. */ - int infolen, nameoffset, reclength, nrattributes, i; + int infolen, nameoffset, reclength, i; int recoffset = offset + sizeof(INT); - char *recbuf = HeapAlloc(GetProcessHeap(), 0, 0xffff); - MSFT_FuncRecord * pFuncRec=(MSFT_FuncRecord *) recbuf; - TLBFuncDesc *ptfd_prev = NULL; + char *recbuf = heap_alloc(0xffff); + MSFT_FuncRecord *pFuncRec = (MSFT_FuncRecord*)recbuf; + TLBFuncDesc *ptfd_prev = NULL, *ptfd; TRACE_(typelib)("\n"); MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset); + *pptfd = TLBFuncDesc_Constructor(cFuncs); + ptfd = *pptfd; for ( i = 0; i < cFuncs ; i++ ) { - *pptfd = TLB_Alloc(sizeof(TLBFuncDesc)); + int optional; /* name, eventually add to a hash table */ MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx, @@ -1923,79 +2052,63 @@ MSFT_DoFuncs(TLBContext* pcx, /* nameoffset is sometimes -1 on the second half of a propget/propput * pair of functions */ if ((nameoffset == -1) && (i > 0)) - (*pptfd)->Name = SysAllocString(ptfd_prev->Name); + ptfd->Name = SysAllocString(ptfd_prev->Name); else - (*pptfd)->Name = MSFT_ReadName(pcx, nameoffset); + ptfd->Name = MSFT_ReadName(pcx, nameoffset); /* read the function information record */ - MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset); + MSFT_ReadLEDWords(&reclength, sizeof(pFuncRec->Info), pcx, recoffset); reclength &= 0xffff; - MSFT_ReadLEDWords(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK); + MSFT_ReadLEDWords(&pFuncRec->DataType, reclength - FIELD_OFFSET(MSFT_FuncRecord, DataType), pcx, DO_NOT_SEEK); - /* do the attributes */ - nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18) - / sizeof(int); + /* size without argument data */ + optional = reclength - pFuncRec->nrargs*sizeof(MSFT_ParameterInfo); - if ( nrattributes > 0 ) + if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpContext)) + ptfd->helpcontext = pFuncRec->HelpContext; + + if (optional > FIELD_OFFSET(MSFT_FuncRecord, oHelpString)) + ptfd->HelpString = MSFT_ReadString(pcx, pFuncRec->oHelpString); + + if (optional > FIELD_OFFSET(MSFT_FuncRecord, oEntry)) { - (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ; - - if ( nrattributes > 1 ) + if (pFuncRec->FKCCIC & 0x2000 ) { - (*pptfd)->HelpString = MSFT_ReadString(pcx, - pFuncRec->OptAttr[1]) ; - - if ( nrattributes > 2 ) - { - if ( pFuncRec->FKCCIC & 0x2000 ) - { - if (!IS_INTRESOURCE(pFuncRec->OptAttr[2])) - ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->OptAttr[2]); - (*pptfd)->Entry = (BSTR)(DWORD_PTR)LOWORD(pFuncRec->OptAttr[2]); - } - else - { - (*pptfd)->Entry = MSFT_ReadString(pcx, - pFuncRec->OptAttr[2]); - } - if( nrattributes > 5 ) - { - (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ; - - if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 ) - { - MSFT_CustData(pcx, - pFuncRec->OptAttr[6], - &(*pptfd)->pCustData); - } - } - } - else - { - (*pptfd)->Entry = (BSTR)-1; - } + if (!IS_INTRESOURCE(pFuncRec->oEntry)) + ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->oEntry); + ptfd->Entry = (BSTR)(DWORD_PTR)LOWORD(pFuncRec->oEntry); } + else + ptfd->Entry = MSFT_ReadString(pcx, pFuncRec->oEntry); } + else + ptfd->Entry = (BSTR)-1; + + if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpStringContext)) + ptfd->HelpStringContext = pFuncRec->HelpStringContext; + + if (optional > FIELD_OFFSET(MSFT_FuncRecord, oCustData) && pFuncRec->FKCCIC & 0x80) + MSFT_CustData(pcx, pFuncRec->oCustData, &ptfd->custdata_list); /* fill the FuncDesc Structure */ - MSFT_ReadLEDWords( & (*pptfd)->funcdesc.memid, sizeof(INT), pcx, + MSFT_ReadLEDWords( & ptfd->funcdesc.memid, sizeof(INT), pcx, offset + infolen + ( i + 1) * sizeof(INT)); - (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7; - (*pptfd)->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF; - (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF; - (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ; - (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ; - (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset; - (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ; + ptfd->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7; + ptfd->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF; + ptfd->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF; + ptfd->funcdesc.cParams = pFuncRec->nrargs ; + ptfd->funcdesc.cParamsOpt = pFuncRec->nroargs ; + ptfd->funcdesc.oVft = pFuncRec->VtableOffset & ~1; + ptfd->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ; MSFT_GetTdesc(pcx, pFuncRec->DataType, - &(*pptfd)->funcdesc.elemdescFunc.tdesc, + &ptfd->funcdesc.elemdescFunc.tdesc, pTI); - MSFT_ResolveReferencedTypes(pcx, pTI, &(*pptfd)->funcdesc.elemdescFunc.tdesc); + MSFT_ResolveReferencedTypes(pcx, pTI, &ptfd->funcdesc.elemdescFunc.tdesc); /* do the parameters/arguments */ if(pFuncRec->nrargs) @@ -2003,18 +2116,17 @@ MSFT_DoFuncs(TLBContext* pcx, int j = 0; MSFT_ParameterInfo paraminfo; - (*pptfd)->funcdesc.lprgelemdescParam = - TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC)); + ptfd->funcdesc.lprgelemdescParam = + heap_alloc_zero(pFuncRec->nrargs * sizeof(ELEMDESC)); - (*pptfd)->pParamDesc = - TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc)); + ptfd->pParamDesc = TLBParDesc_Constructor(pFuncRec->nrargs); MSFT_ReadLEDWords(¶minfo, sizeof(paraminfo), pcx, recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo)); for ( j = 0 ; j < pFuncRec->nrargs ; j++ ) { - ELEMDESC *elemdesc = &(*pptfd)->funcdesc.lprgelemdescParam[j]; + ELEMDESC *elemdesc = &ptfd->funcdesc.lprgelemdescParam[j]; MSFT_GetTdesc(pcx, paraminfo.DataType, @@ -2028,11 +2140,11 @@ MSFT_DoFuncs(TLBContext* pcx, /* this occurs for [propput] or [propget] methods, so * we should just set the name of the parameter to the * name of the method. */ - (*pptfd)->pParamDesc[j].Name = SysAllocString((*pptfd)->Name); + ptfd->pParamDesc[j].Name = SysAllocString(ptfd->Name); else - (*pptfd)->pParamDesc[j].Name = + ptfd->pParamDesc[j].Name = MSFT_ReadName( pcx, paraminfo.oName ); - TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w((*pptfd)->pParamDesc[j].Name)); + TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w(ptfd->pParamDesc[j].Name)); MSFT_ResolveReferencedTypes(pcx, pTI, &elemdesc->tdesc); @@ -2042,11 +2154,11 @@ MSFT_DoFuncs(TLBContext* pcx, { INT* pInt = (INT *)((char *)pFuncRec + reclength - - (pFuncRec->nrargs * 4 + 1) * sizeof(INT) ); + (pFuncRec->nrargs * 4) * sizeof(INT) ); PARAMDESC* pParamDesc = &elemdesc->u.paramdesc; - pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX)); + pParamDesc->pparamdescex = heap_alloc_zero(sizeof(PARAMDESCEX)); pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX); MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue), @@ -2054,12 +2166,15 @@ MSFT_DoFuncs(TLBContext* pcx, } else elemdesc->u.paramdesc.pparamdescex = NULL; + /* custom info */ - if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 ) + if (optional > (FIELD_OFFSET(MSFT_FuncRecord, oArgCustData) + + j*sizeof(pFuncRec->oArgCustData[0])) && + pFuncRec->FKCCIC & 0x80 ) { MSFT_CustData(pcx, - pFuncRec->OptAttr[7+j], - &(*pptfd)->pParamDesc[j].pCustData); + pFuncRec->oArgCustData[j], + &ptfd->pParamDesc[j].custdata_list); } /* SEEK value = jump to offset, @@ -2074,14 +2189,14 @@ MSFT_DoFuncs(TLBContext* pcx, } /* scode is not used: archaic win16 stuff FIXME: right? */ - (*pptfd)->funcdesc.cScodes = 0 ; - (*pptfd)->funcdesc.lprgscode = NULL ; + ptfd->funcdesc.cScodes = 0 ; + ptfd->funcdesc.lprgscode = NULL ; - ptfd_prev = *pptfd; - pptfd = & ((*pptfd)->next); + ptfd_prev = ptfd; + ++ptfd; recoffset += reclength; } - HeapFree(GetProcessHeap(), 0, recbuf); + heap_free(recbuf); } static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, @@ -2089,53 +2204,57 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, { int infolen, nameoffset, reclength; char recbuf[256]; - MSFT_VarRecord * pVarRec=(MSFT_VarRecord *) recbuf; + MSFT_VarRecord *pVarRec = (MSFT_VarRecord*)recbuf; + TLBVarDesc *ptvd; int i; int recoffset; TRACE_(typelib)("\n"); + ptvd = *pptvd = TLBVarDesc_Constructor(cVars); MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset); MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen + ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT)); recoffset += offset+sizeof(INT); - for(i=0;iName=MSFT_ReadName(pcx, nameoffset); + ptvd->Name=MSFT_ReadName(pcx, nameoffset); /* read the variable information record */ - MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset); - reclength &=0xff; - MSFT_ReadLEDWords(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK); - /* Optional data */ - if(reclength >(6*sizeof(INT)) ) - (*pptvd)->HelpContext=pVarRec->HelpContext; - if(reclength >(7*sizeof(INT)) ) - (*pptvd)->HelpString = MSFT_ReadString(pcx, pVarRec->oHelpString) ; - if(reclength >(8*sizeof(INT)) ) - if(reclength >(9*sizeof(INT)) ) - (*pptvd)->HelpStringContext=pVarRec->HelpStringContext; + MSFT_ReadLEDWords(&reclength, sizeof(pVarRec->Info), pcx, recoffset); + reclength &= 0xff; + MSFT_ReadLEDWords(&pVarRec->DataType, reclength - FIELD_OFFSET(MSFT_VarRecord, DataType), pcx, DO_NOT_SEEK); + + /* optional data */ + if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpContext)) + ptvd->HelpContext = pVarRec->HelpContext; + + if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpString)) + ptvd->HelpString = MSFT_ReadString(pcx, pVarRec->HelpString); + + if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpStringContext)) + ptvd->HelpStringContext = pVarRec->HelpStringContext; + /* fill the VarDesc Structure */ - MSFT_ReadLEDWords(&(*pptvd)->vardesc.memid, sizeof(INT), pcx, + MSFT_ReadLEDWords(&ptvd->vardesc.memid, sizeof(INT), pcx, offset + infolen + (cFuncs + i + 1) * sizeof(INT)); - (*pptvd)->vardesc.varkind = pVarRec->VarKind; - (*pptvd)->vardesc.wVarFlags = pVarRec->Flags; + ptvd->vardesc.varkind = pVarRec->VarKind; + ptvd->vardesc.wVarFlags = pVarRec->Flags; MSFT_GetTdesc(pcx, pVarRec->DataType, - &(*pptvd)->vardesc.elemdescVar.tdesc, pTI); -/* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */ + &ptvd->vardesc.elemdescVar.tdesc, pTI); +/* ptvd->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */ if(pVarRec->VarKind == VAR_CONST ){ - (*pptvd)->vardesc.u.lpvarValue=TLB_Alloc(sizeof(VARIANT)); - MSFT_ReadValue((*pptvd)->vardesc.u.lpvarValue, + ptvd->vardesc.u.lpvarValue = heap_alloc_zero(sizeof(VARIANT)); + MSFT_ReadValue(ptvd->vardesc.u.lpvarValue, pVarRec->OffsValue, pcx); } else - (*pptvd)->vardesc.u.oInst=pVarRec->OffsValue; - MSFT_ResolveReferencedTypes(pcx, pTI, &(*pptvd)->vardesc.elemdescVar.tdesc); - pptvd=&((*pptvd)->next); + ptvd->vardesc.u.oInst=pVarRec->OffsValue; + MSFT_ResolveReferencedTypes(pcx, pTI, &ptvd->vardesc.elemdescVar.tdesc); recoffset += reclength; } } + /* fill in data for a hreftype (offset). When the referenced type is contained * in the typelib, it's just an (file) offset in the type info base dir. * If comes from import, it's an offset+1 in the ImpInfo table @@ -2152,23 +2271,24 @@ static void MSFT_DoRefType(TLBContext *pcx, ITypeLibImpl *pTL, if(ref->reference == offset) return; } - ref = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref)); + ref = heap_alloc_zero(sizeof(TLBRefType)); list_add_tail(&pTL->ref_list, &ref->entry); if(!MSFT_HREFTYPE_INTHISFILE( offset)) { /* external typelib */ MSFT_ImpInfo impinfo; - TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs); + TLBImpLib *pImpLib; TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc)); MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx, pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc)); - while (pImpLib){ /* search the known offsets of all import libraries */ - if(pImpLib->offset==impinfo.oImpFile) break; - pImpLib=pImpLib->next; - } - if(pImpLib){ + + LIST_FOR_EACH_ENTRY(pImpLib, &pcx->pLibInfo->implib_list, TLBImpLib, entry) + if(pImpLib->offset==impinfo.oImpFile) + break; + + if(&pImpLib->entry != &pcx->pLibInfo->implib_list){ ref->reference = offset; ref->pImpTLInfo = pImpLib; if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) { @@ -2196,21 +2316,21 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, { int i; MSFT_RefRecord refrec; - TLBImplType **ppImpl = &pTI->impltypelist; + TLBImplType *pImpl; TRACE_(typelib)("\n"); + pTI->impltypes = TLBImplType_Constructor(count); + pImpl = pTI->impltypes; for(i=0;ipTblDir->pRefTab.offset); MSFT_DoRefType(pcx, pTI->pTypeLib, refrec.reftype); - (*ppImpl)->hRef = refrec.reftype; - (*ppImpl)->implflags=refrec.flags; - (*ppImpl)->ctCustData= - MSFT_CustData(pcx, refrec.oCustData, &(*ppImpl)->pCustData); + pImpl->hRef = refrec.reftype; + pImpl->implflags=refrec.flags; + MSFT_CustData(pcx, refrec.oCustData, &pImpl->custdata_list); offset=refrec.onext; - ppImpl=&((*ppImpl)->next); + ++pImpl; } } /* @@ -2226,7 +2346,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo( TRACE_(typelib)("count=%u\n", count); - ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor(); + ptiRet = ITypeInfoImpl_Constructor(); MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx , pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase)); @@ -2274,12 +2394,12 @@ static ITypeInfoImpl * MSFT_DoTypeInfo( if(ptiRet->TypeAttr.cFuncs >0 ) MSFT_DoFuncs(pcx, ptiRet, ptiRet->TypeAttr.cFuncs, ptiRet->TypeAttr.cVars, - tiBase.memoffset, & ptiRet->funclist); + tiBase.memoffset, &ptiRet->funcdescs); /* variables */ if(ptiRet->TypeAttr.cVars >0 ) MSFT_DoVars(pcx, ptiRet, ptiRet->TypeAttr.cFuncs, ptiRet->TypeAttr.cVars, - tiBase.memoffset, & ptiRet->varlist); + tiBase.memoffset, &ptiRet->vardescs); if(ptiRet->TypeAttr.cImplTypes >0 ) { switch(ptiRet->TypeAttr.typekind) { @@ -2296,20 +2416,19 @@ static ITypeInfoImpl * MSFT_DoTypeInfo( if (tiBase.datatype1 != -1) { - ptiRet->impltypelist = TLB_Alloc(sizeof(TLBImplType)); - ptiRet->impltypelist->hRef = tiBase.datatype1; + ptiRet->impltypes = TLBImplType_Constructor(1); + ptiRet->impltypes[0].hRef = tiBase.datatype1; MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1); } - break; + break; default: - ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType)); + ptiRet->impltypes = TLBImplType_Constructor(1); MSFT_DoRefType(pcx, pLibInfo, tiBase.datatype1); - ptiRet->impltypelist->hRef = tiBase.datatype1; + ptiRet->impltypes[0].hRef = tiBase.datatype1; break; } } - ptiRet->ctCustData= - MSFT_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData); + MSFT_CustData(pcx, tiBase.oCustData, &ptiRet->custdata_list); TRACE_(typelib)("%s guid: %s kind:%s\n", debugstr_w(ptiRet->Name), @@ -2326,7 +2445,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo( * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable * tradeoff here. */ -static ITypeLibImpl *tlb_cache_first; +static struct list tlb_cache = LIST_INIT(tlb_cache); static CRITICAL_SECTION cache_section; static CRITICAL_SECTION_DEBUG cache_section_debug = { @@ -2375,7 +2494,7 @@ static ULONG WINAPI TLB_PEFile_Release(IUnknown *iface) FreeResource(This->typelib_global); if (This->dll) FreeLibrary(This->dll); - HeapFree(GetProcessHeap(), 0, This); + heap_free(This); } return refs; } @@ -2390,8 +2509,9 @@ static const IUnknownVtbl TLB_PEFile_Vtable = static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile) { TLB_PEFile *This; + HRESULT hr = TYPE_E_CANTLOADLIBRARY; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + This = heap_alloc(sizeof(TLB_PEFile)); if (!This) return E_OUTOFMEMORY; @@ -2424,11 +2544,13 @@ static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p return S_OK; } } + + hr = E_FAIL; } } TLB_PEFile_Release((IUnknown *)&This->lpvtbl); - return TYPE_E_CANTLOADLIBRARY; + return hr; } typedef struct TLB_NEFile @@ -2462,8 +2584,8 @@ static ULONG WINAPI TLB_NEFile_Release(IUnknown *iface) ULONG refs = InterlockedDecrement(&This->refs); if (!refs) { - HeapFree(GetProcessHeap(), 0, This->typelib_base); - HeapFree(GetProcessHeap(), 0, This); + heap_free(This->typelib_base); + heap_free(This); } return refs; } @@ -2532,13 +2654,13 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid, } /* Read in resource table */ - resTab = HeapAlloc( GetProcessHeap(), 0, resTabSize ); + resTab = heap_alloc( resTabSize ); if ( !resTab ) return FALSE; LZSeek( lzfd, nehd.ne_rsrctab + nehdoffset, SEEK_SET ); if ( resTabSize != LZRead( lzfd, (char*)resTab, resTabSize ) ) { - HeapFree( GetProcessHeap(), 0, resTab ); + heap_free( resTab ); return FALSE; } @@ -2570,7 +2692,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid, } } TRACE("No typeid entry found for %p\n", typeid ); - HeapFree( GetProcessHeap(), 0, resTab ); + heap_free( resTab ); return FALSE; found_type: @@ -2593,7 +2715,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid, if (nameInfo->id == id) goto found_name; } TRACE("No resid entry found for %p\n", typeid ); - HeapFree( GetProcessHeap(), 0, resTab ); + heap_free( resTab ); return FALSE; found_name: @@ -2601,7 +2723,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid, if ( resLen ) *resLen = nameInfo->length << *(WORD *)resTab; if ( resOff ) *resOff = nameInfo->offset << *(WORD *)resTab; - HeapFree( GetProcessHeap(), 0, resTab ); + heap_free( resTab ); return TRUE; } @@ -2610,9 +2732,9 @@ static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p HFILE lzfd = -1; OFSTRUCT ofs; HRESULT hr = TYPE_E_CANTLOADLIBRARY; - TLB_NEFile *This = NULL; + TLB_NEFile *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + This = heap_alloc(sizeof(TLB_NEFile)); if (!This) return E_OUTOFMEMORY; This->lpvtbl = &TLB_NEFile_Vtable; @@ -2625,7 +2747,7 @@ static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *p DWORD reslen, offset; if( find_ne_resource( lzfd, "TYPELIB", MAKEINTRESOURCEA(index), &reslen, &offset ) ) { - This->typelib_base = HeapAlloc(GetProcessHeap(), 0, reslen); + This->typelib_base = heap_alloc(reslen); if( !This->typelib_base ) hr = E_OUTOFMEMORY; else @@ -2685,7 +2807,7 @@ static ULONG WINAPI TLB_Mapping_Release(IUnknown *iface) CloseHandle(This->mapping); if (This->file != INVALID_HANDLE_VALUE) CloseHandle(This->file); - HeapFree(GetProcessHeap(), 0, This); + heap_free(This); } return refs; } @@ -2701,7 +2823,7 @@ static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLengt { TLB_Mapping *This; - This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + This = heap_alloc(sizeof(TLB_Mapping)); if (!This) return E_OUTOFMEMORY; @@ -2739,7 +2861,7 @@ static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLengt * find the type of the typelib file and map the typelib resource into * the memory */ -#define MSFT_SIGNATURE 0x5446534D /* "MSFT" */ + #define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib) { @@ -2762,7 +2884,7 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath { int str_len = index_str - pszFileName - 1; index = idx; - file = HeapAlloc(GetProcessHeap(), 0, (str_len + 1) * sizeof(WCHAR)); + file = heap_alloc((str_len + 1) * sizeof(WCHAR)); memcpy(file, pszFileName, str_len * sizeof(WCHAR)); file[str_len] = 0; } @@ -2782,19 +2904,19 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath } } - if(file != pszFileName) HeapFree(GetProcessHeap(), 0, file); + if(file != pszFileName) heap_free(file); TRACE_(typelib)("File %s index %d\n", debugstr_w(pszPath), index); /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */ EnterCriticalSection(&cache_section); - for (entry = tlb_cache_first; entry != NULL; entry = entry->next) + LIST_FOR_EACH_ENTRY(entry, &tlb_cache, ITypeLibImpl, entry) { if (!strcmpiW(entry->path, pszPath) && entry->index == index) { TRACE("cache hit\n"); *ppTypeLib = (ITypeLib2*)entry; - ITypeLib_AddRef(*ppTypeLib); + ITypeLib2_AddRef(*ppTypeLib); LeaveCriticalSection(&cache_section); return S_OK; } @@ -2827,21 +2949,21 @@ static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath ret = TYPE_E_CANTLOADLIBRARY; IUnknown_Release(pFile); } + else + ret = TYPE_E_CANTLOADLIBRARY; if(*ppTypeLib) { ITypeLibImpl *impl = (ITypeLibImpl*)*ppTypeLib; TRACE("adding to cache\n"); - impl->path = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszPath)+1) * sizeof(WCHAR)); + impl->path = heap_alloc((strlenW(pszPath)+1) * sizeof(WCHAR)); lstrcpyW(impl->path, pszPath); /* We should really canonicalise the path here. */ impl->index = index; /* FIXME: check if it has added already in the meantime */ EnterCriticalSection(&cache_section); - if ((impl->next = tlb_cache_first) != NULL) impl->next->prev = impl; - impl->prev = NULL; - tlb_cache_first = impl; + list_add_head(&tlb_cache, &impl->entry); LeaveCriticalSection(&cache_section); ret = S_OK; } else @@ -2856,13 +2978,15 @@ static ITypeLibImpl* TypeLibImpl_Constructor(void) { ITypeLibImpl* pTypeLibImpl; - pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl)); + pTypeLibImpl = heap_alloc_zero(sizeof(ITypeLibImpl)); if (!pTypeLibImpl) return NULL; pTypeLibImpl->lpVtbl = &tlbvt; pTypeLibImpl->lpVtblTypeComp = &tlbtcvt; pTypeLibImpl->ref = 1; + list_init(&pTypeLibImpl->implib_list); + list_init(&pTypeLibImpl->custdata_list); list_init(&pTypeLibImpl->ref_list); pTypeLibImpl->dispatch_href = -1; @@ -2918,7 +3042,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F) { ERR("cannot find the table directory, ptr=0x%x\n",lPSegDir); - HeapFree(GetProcessHeap(),0,pTypeLibImpl); + heap_free(pTypeLibImpl); return NULL; } @@ -2953,7 +3077,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) /* custom data */ if(tlbHeader.CustomDataOffset >= 0) { - pTypeLibImpl->ctCustData = MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData); + MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->custdata_list); } /* fill in type descriptions */ @@ -2962,7 +3086,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT)); INT16 td[4]; pTypeLibImpl->ctTypeDesc = cTD; - pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC)); + pTypeLibImpl->pTypeDesc = heap_alloc_zero( cTD * sizeof(TYPEDESC)); MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset); for(i=0; ipTypeDesc[i].u.lptdesc= & stndTypeDesc[td[2]]; + pTypeLibImpl->pTypeDesc[i].u.lptdesc = &std_typedesc[td[2]]; else - pTypeLibImpl->pTypeDesc[i].u.lptdesc= & pTypeLibImpl->pTypeDesc[td[2]/8]; + pTypeLibImpl->pTypeDesc[i].u.lptdesc = &pTypeLibImpl->pTypeDesc[td[2]/8]; } else if(td[0] == VT_CARRAY) { @@ -2995,7 +3119,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) if(tlbSegDir.pArrayDescriptions.offset>0) { MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (INT_PTR)pTypeLibImpl->pTypeDesc[i].u.lpadesc); - pTypeLibImpl->pTypeDesc[i].u.lpadesc = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1)); + pTypeLibImpl->pTypeDesc[i].u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1)); if(td[1]<0) pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK; @@ -3023,7 +3147,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) /* imported type libs */ if(tlbSegDir.pImpFiles.offset>0) { - TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs); + TLBImpLib *pImpLib; int oGuid, offset = tlbSegDir.pImpFiles.offset; UINT16 size; @@ -3031,25 +3155,25 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) { char *name; - *ppImpLib = TLB_Alloc(sizeof(TLBImpLib)); - (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset; + pImpLib = heap_alloc_zero(sizeof(TLBImpLib)); + pImpLib->offset = offset - tlbSegDir.pImpFiles.offset; MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset); - MSFT_ReadLEDWords(&(*ppImpLib)->lcid, sizeof(LCID), &cx, DO_NOT_SEEK); - MSFT_ReadLEWords(&(*ppImpLib)->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK); - MSFT_ReadLEWords(&(*ppImpLib)->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK); + MSFT_ReadLEDWords(&pImpLib->lcid, sizeof(LCID), &cx, DO_NOT_SEEK); + MSFT_ReadLEWords(&pImpLib->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK); + MSFT_ReadLEWords(&pImpLib->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK); MSFT_ReadLEWords(& size, sizeof(UINT16), &cx, DO_NOT_SEEK); size >>= 2; - name = TLB_Alloc(size+1); + name = heap_alloc_zero(size+1); MSFT_Read(name, size, &cx, DO_NOT_SEEK); - (*ppImpLib)->name = TLB_MultiByteToBSTR(name); - TLB_Free(name); + pImpLib->name = TLB_MultiByteToBSTR(name); + heap_free(name); - MSFT_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx); + MSFT_ReadGuid(&pImpLib->guid, oGuid, &cx); offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3; - ppImpLib = &(*ppImpLib)->next; + list_add_tail(&pTypeLibImpl->implib_list, &pImpLib->entry); } } @@ -3057,18 +3181,19 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) if(pTypeLibImpl->dispatch_href != -1) MSFT_DoRefType(&cx, pTypeLibImpl, pTypeLibImpl->dispatch_href); - /* type info's */ + /* type infos */ if(tlbHeader.nrtypeinfos >= 0 ) { - /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */ - ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo); + ITypeInfoImpl **ppTI; int i; + ppTI = pTypeLibImpl->typeinfos = heap_alloc_zero(sizeof(ITypeInfoImpl*) * tlbHeader.nrtypeinfos); + for(i = 0; i < tlbHeader.nrtypeinfos; i++) { *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl); - ppTI = &((*ppTI)->next); + ++ppTI; (pTypeLibImpl->TypeInfoCount)++; } } @@ -3122,7 +3247,7 @@ static WORD SLTG_ReadStringA(const char *ptr, char **str) *str = NULL; bytelen = *(const WORD*)ptr; if(bytelen == 0xffff) return 2; - *str = HeapAlloc(GetProcessHeap(), 0, bytelen + 1); + *str = heap_alloc(bytelen + 1); memcpy(*str, ptr + 2, bytelen); (*str)[bytelen] = '\0'; return bytelen + 2; @@ -3206,15 +3331,13 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_ while(!done) { if((*pType & 0xe00) == 0xe00) { pTD->vt = VT_PTR; - pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(TYPEDESC)); + pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC)); pTD = pTD->u.lptdesc; } switch(*pType & 0x3f) { case VT_PTR: pTD->vt = VT_PTR; - pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(TYPEDESC)); + pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC)); pTD = pTD->u.lptdesc; break; @@ -3232,9 +3355,7 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_ SAFEARRAY *pSA = (SAFEARRAY *)(pBlk + *(++pType)); pTD->vt = VT_CARRAY; - pTD->u.lpadesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(ARRAYDESC) + - (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND)); + pTD->u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC) + (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND)); pTD->u.lpadesc->cDims = pSA->cDims; memcpy(pTD->u.lpadesc->rgbounds, pSA->rgsabound, pSA->cDims * sizeof(SAFEARRAYBOUND)); @@ -3250,8 +3371,7 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_ pType++; pTD->vt = VT_SAFEARRAY; - pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(TYPEDESC)); + pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC)); pTD = pTD->u.lptdesc; break; } @@ -3303,7 +3423,7 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, } name = ( (char*)pRef->names + pRef->number); - table = HeapAlloc(GetProcessHeap(), 0, sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0])); + table = heap_alloc(sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0])); table->num = pRef->number >> 3; /* FIXME should scan the existing list and reuse matching refs added by previous typeinfos */ @@ -3315,32 +3435,30 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, char *refname; unsigned int lib_offs, type_num; - ref_type = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref_type)); + ref_type = heap_alloc_zero(sizeof(TLBRefType)); name += SLTG_ReadStringA(name, &refname); if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2) FIXME_(typelib)("Can't sscanf ref\n"); if(lib_offs != 0xffff) { - TLBImpLib **import = &pTL->pImpLibs; + TLBImpLib *import; - while(*import) { - if((*import)->offset == lib_offs) - break; - import = &(*import)->next; - } - if(!*import) { + LIST_FOR_EACH_ENTRY(import, &pTL->implib_list, TLBImpLib, entry) + if(import->offset == lib_offs) + break; + + if(&import->entry == &pTL->implib_list) { char fname[MAX_PATH+1]; int len; - *import = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(**import)); - (*import)->offset = lib_offs; + import = heap_alloc_zero(sizeof(*import)); + import->offset = lib_offs; TLB_GUIDFromString( pNameTable + lib_offs + 4, - &(*import)->guid); + &import->guid); if(sscanf(pNameTable + lib_offs + 40, "}#%hd.%hd#%x#%s", - &(*import)->wVersionMajor, - &(*import)->wVersionMinor, - &(*import)->lcid, fname) != 4) { + &import->wVersionMajor, + &import->wVersionMinor, + &import->lcid, fname) != 4) { FIXME_(typelib)("can't sscanf ref %s\n", pNameTable + lib_offs + 40); } @@ -3348,12 +3466,13 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, if(fname[len-1] != '#') FIXME("fname = %s\n", fname); fname[len-1] = '\0'; - (*import)->name = TLB_MultiByteToBSTR(fname); + import->name = TLB_MultiByteToBSTR(fname); + list_add_tail(&pTL->implib_list, &import->entry); } - ref_type->pImpTLInfo = *import; + ref_type->pImpTLInfo = import; /* Store a reference to IDispatch */ - if(pTL->dispatch_href == -1 && IsEqualGUID(&(*import)->guid, &IID_StdOle) && type_num == 4) + if(pTL->dispatch_href == -1 && IsEqualGUID(&import->guid, &IID_StdOle) && type_num == 4) pTL->dispatch_href = typelib_ref; } else { /* internal ref */ @@ -3362,7 +3481,7 @@ static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, ref_type->reference = typelib_ref; ref_type->index = type_num; - HeapFree(GetProcessHeap(), 0, refname); + heap_free(refname); list_add_tail(&pTL->ref_list, &ref_type->entry); table->refs[ref] = typelib_ref; @@ -3378,7 +3497,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, BOOL OneOnly, const sltg_ref_lookup_t *ref_lookup) { SLTG_ImplInfo *info; - TLBImplType **ppImplType = &pTI->impltypelist; + TLBImplType *pImplType; /* I don't really get this structure, usually it's 0x16 bytes long, but iuser.tlb contains some that are 0x18 bytes long. That's ok because we can use the next ptr to jump to the next @@ -3387,15 +3506,22 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, the last one is the regular 0x16 bytes. */ info = (SLTG_ImplInfo*)pBlk; - while(1) { - *ppImplType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(**ppImplType)); - sltg_get_typelib_ref(ref_lookup, info->ref, &(*ppImplType)->hRef); - (*ppImplType)->implflags = info->impltypeflags; - pTI->TypeAttr.cImplTypes++; - ppImplType = &(*ppImplType)->next; - + while(1){ + pTI->TypeAttr.cImplTypes++; if(info->next == 0xffff) + break; + info = (SLTG_ImplInfo*)(pBlk + info->next); + } + + info = (SLTG_ImplInfo*)pBlk; + pTI->impltypes = TLBImplType_Constructor(pTI->TypeAttr.cImplTypes); + pImplType = pTI->impltypes; + while(1) { + sltg_get_typelib_ref(ref_lookup, info->ref, &pImplType->hRef); + pImplType->implflags = info->impltypeflags; + ++pImplType; + + if(info->next == 0xffff) break; if(OneOnly) FIXME_(typelib)("Interface inheriting more than one interface\n"); @@ -3408,18 +3534,18 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, const char *pNameTable, const sltg_ref_lookup_t *ref_lookup) { - TLBVarDesc **ppVarDesc = &pTI->varlist; + TLBVarDesc *pVarDesc; BSTR bstrPrevName = NULL; SLTG_Variable *pItem; unsigned short i; WORD *pType; - for(pItem = (SLTG_Variable *)pFirstItem, i = 0; i < cVars; - pItem = (SLTG_Variable *)(pBlk + pItem->next), i++) { + pVarDesc = pTI->vardescs = TLBVarDesc_Constructor(cVars); - *ppVarDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(**ppVarDesc)); - (*ppVarDesc)->vardesc.memid = pItem->memid; + for(pItem = (SLTG_Variable *)pFirstItem, i = 0; i < cVars; + pItem = (SLTG_Variable *)(pBlk + pItem->next), i++, ++pVarDesc) { + + pVarDesc->vardesc.memid = pItem->memid; if (pItem->magic != SLTG_VAR_MAGIC && pItem->magic != SLTG_VAR_WITH_FLAGS_MAGIC) { @@ -3428,11 +3554,11 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign } if (pItem->name == 0xfffe) - (*ppVarDesc)->Name = SysAllocString(bstrPrevName); + pVarDesc->Name = SysAllocString(bstrPrevName); else - (*ppVarDesc)->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable); + pVarDesc->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable); - TRACE_(typelib)("name: %s\n", debugstr_w((*ppVarDesc)->Name)); + TRACE_(typelib)("name: %s\n", debugstr_w(pVarDesc->Name)); TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs); TRACE_(typelib)("memid = 0x%x\n", pItem->memid); @@ -3445,28 +3571,27 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign FIXME_(typelib)("unhandled flags = %02x\n", pItem->flags & ~0xda); SLTG_DoElem(pType, pBlk, - &(*ppVarDesc)->vardesc.elemdescVar, ref_lookup); + &pVarDesc->vardesc.elemdescVar, ref_lookup); if (TRACE_ON(typelib)) { char buf[300]; - dump_TypeDesc(&(*ppVarDesc)->vardesc.elemdescVar.tdesc, buf); + dump_TypeDesc(&pVarDesc->vardesc.elemdescVar.tdesc, buf); TRACE_(typelib)("elemdescVar: %s\n", buf); } if (pItem->flags & 0x40) { TRACE_(typelib)("VAR_DISPATCH\n"); - (*ppVarDesc)->vardesc.varkind = VAR_DISPATCH; + pVarDesc->vardesc.varkind = VAR_DISPATCH; } else if (pItem->flags & 0x10) { TRACE_(typelib)("VAR_CONST\n"); - (*ppVarDesc)->vardesc.varkind = VAR_CONST; - (*ppVarDesc)->vardesc.u.lpvarValue = HeapAlloc(GetProcessHeap(), 0, - sizeof(VARIANT)); - V_VT((*ppVarDesc)->vardesc.u.lpvarValue) = VT_INT; + pVarDesc->vardesc.varkind = VAR_CONST; + pVarDesc->vardesc.u.lpvarValue = heap_alloc(sizeof(VARIANT)); + V_VT(pVarDesc->vardesc.u.lpvarValue) = VT_INT; if (pItem->flags & 0x08) - V_INT((*ppVarDesc)->vardesc.u.lpvarValue) = pItem->byte_offs; + V_INT(pVarDesc->vardesc.u.lpvarValue) = pItem->byte_offs; else { - switch ((*ppVarDesc)->vardesc.elemdescVar.tdesc.vt) + switch (pVarDesc->vardesc.elemdescVar.tdesc.vt) { case VT_LPSTR: case VT_LPWSTR: @@ -3482,8 +3607,8 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign str = SysAllocStringLen(NULL, alloc_len); MultiByteToWideChar(CP_ACP, 0, pBlk + pItem->byte_offs + 2, len, str, alloc_len); } - V_VT((*ppVarDesc)->vardesc.u.lpvarValue) = VT_BSTR; - V_BSTR((*ppVarDesc)->vardesc.u.lpvarValue) = str; + V_VT(pVarDesc->vardesc.u.lpvarValue) = VT_BSTR; + V_BSTR(pVarDesc->vardesc.u.lpvarValue) = str; break; } case VT_I2: @@ -3492,28 +3617,27 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign case VT_UI4: case VT_INT: case VT_UINT: - V_INT((*ppVarDesc)->vardesc.u.lpvarValue) = + V_INT(pVarDesc->vardesc.u.lpvarValue) = *(INT*)(pBlk + pItem->byte_offs); break; default: - FIXME_(typelib)("VAR_CONST unimplemented for type %d\n", (*ppVarDesc)->vardesc.elemdescVar.tdesc.vt); + FIXME_(typelib)("VAR_CONST unimplemented for type %d\n", pVarDesc->vardesc.elemdescVar.tdesc.vt); } } } else { TRACE_(typelib)("VAR_PERINSTANCE\n"); - (*ppVarDesc)->vardesc.u.oInst = pItem->byte_offs; - (*ppVarDesc)->vardesc.varkind = VAR_PERINSTANCE; + pVarDesc->vardesc.u.oInst = pItem->byte_offs; + pVarDesc->vardesc.varkind = VAR_PERINSTANCE; } if (pItem->magic == SLTG_VAR_WITH_FLAGS_MAGIC) - (*ppVarDesc)->vardesc.wVarFlags = pItem->varflags; + pVarDesc->vardesc.wVarFlags = pItem->varflags; if (pItem->flags & 0x80) - (*ppVarDesc)->vardesc.wVarFlags |= VARFLAG_FREADONLY; + pVarDesc->vardesc.wVarFlags |= VARFLAG_FREADONLY; - bstrPrevName = (*ppVarDesc)->Name; - ppVarDesc = &((*ppVarDesc)->next); + bstrPrevName = pVarDesc->Name; } pTI->TypeAttr.cVars = cVars; } @@ -3523,62 +3647,57 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, { SLTG_Function *pFunc; unsigned short i; - TLBFuncDesc **ppFuncDesc = &pTI->funclist; + TLBFuncDesc *pFuncDesc; - for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs; - pFunc = (SLTG_Function*)(pBlk + pFunc->next), i++) { + pTI->funcdescs = TLBFuncDesc_Constructor(cFuncs); + + pFuncDesc = pTI->funcdescs; + for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs && pFunc != (SLTG_Function*)0xFFFF; + pFunc = (SLTG_Function*)(pBlk + pFunc->next), i++, ++pFuncDesc) { int param; WORD *pType, *pArg; - *ppFuncDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(**ppFuncDesc)); - switch (pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT) { case SLTG_FUNCTION_MAGIC: - (*ppFuncDesc)->funcdesc.funckind = FUNC_PUREVIRTUAL; + pFuncDesc->funcdesc.funckind = FUNC_PUREVIRTUAL; break; case SLTG_DISPATCH_FUNCTION_MAGIC: - (*ppFuncDesc)->funcdesc.funckind = FUNC_DISPATCH; + pFuncDesc->funcdesc.funckind = FUNC_DISPATCH; break; case SLTG_STATIC_FUNCTION_MAGIC: - (*ppFuncDesc)->funcdesc.funckind = FUNC_STATIC; + pFuncDesc->funcdesc.funckind = FUNC_STATIC; break; default: FIXME("unimplemented func magic = %02x\n", pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT); - HeapFree(GetProcessHeap(), 0, *ppFuncDesc); - *ppFuncDesc = NULL; - return; + continue; } - (*ppFuncDesc)->Name = TLB_MultiByteToBSTR(pFunc->name + pNameTable); + pFuncDesc->Name = TLB_MultiByteToBSTR(pFunc->name + pNameTable); - (*ppFuncDesc)->funcdesc.memid = pFunc->dispid; - (*ppFuncDesc)->funcdesc.invkind = pFunc->inv >> 4; - (*ppFuncDesc)->funcdesc.callconv = pFunc->nacc & 0x7; - (*ppFuncDesc)->funcdesc.cParams = pFunc->nacc >> 3; - (*ppFuncDesc)->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; - (*ppFuncDesc)->funcdesc.oVft = pFunc->vtblpos; + pFuncDesc->funcdesc.memid = pFunc->dispid; + pFuncDesc->funcdesc.invkind = pFunc->inv >> 4; + pFuncDesc->funcdesc.callconv = pFunc->nacc & 0x7; + pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3; + pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; + pFuncDesc->funcdesc.oVft = pFunc->vtblpos & ~1; if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT) - (*ppFuncDesc)->funcdesc.wFuncFlags = pFunc->funcflags; + pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; if(pFunc->retnextopt & 0x80) pType = &pFunc->rettype; else pType = (WORD*)(pBlk + pFunc->rettype); - SLTG_DoElem(pType, pBlk, &(*ppFuncDesc)->funcdesc.elemdescFunc, ref_lookup); + SLTG_DoElem(pType, pBlk, &pFuncDesc->funcdesc.elemdescFunc, ref_lookup); - (*ppFuncDesc)->funcdesc.lprgelemdescParam = - HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - (*ppFuncDesc)->funcdesc.cParams * sizeof(ELEMDESC)); - (*ppFuncDesc)->pParamDesc = - HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - (*ppFuncDesc)->funcdesc.cParams * sizeof(TLBParDesc)); + pFuncDesc->funcdesc.lprgelemdescParam = + heap_alloc_zero(pFuncDesc->funcdesc.cParams * sizeof(ELEMDESC)); + pFuncDesc->pParamDesc = TLBParDesc_Constructor(pFuncDesc->funcdesc.cParams); pArg = (WORD*)(pBlk + pFunc->arg_off); - for(param = 0; param < (*ppFuncDesc)->funcdesc.cParams; param++) { + for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) { char *paramName = pNameTable + *pArg; BOOL HaveOffs; /* If arg type follows then paramName points to the 2nd @@ -3605,31 +3724,28 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, if(HaveOffs) { /* the next word is an offset to type */ pType = (WORD*)(pBlk + *pArg); SLTG_DoElem(pType, pBlk, - &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param], ref_lookup); + &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); pArg++; } else { if(paramName) paramName--; pArg = SLTG_DoElem(pArg, pBlk, - &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param], ref_lookup); + &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup); } /* Are we an optional param ? */ - if((*ppFuncDesc)->funcdesc.cParams - param <= - (*ppFuncDesc)->funcdesc.cParamsOpt) - (*ppFuncDesc)->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT; + if(pFuncDesc->funcdesc.cParams - param <= + pFuncDesc->funcdesc.cParamsOpt) + pFuncDesc->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT; if(paramName) { - (*ppFuncDesc)->pParamDesc[param].Name = + pFuncDesc->pParamDesc[param].Name = TLB_MultiByteToBSTR(paramName); } else { - (*ppFuncDesc)->pParamDesc[param].Name = - SysAllocString((*ppFuncDesc)->Name); + pFuncDesc->pParamDesc[param].Name = + SysAllocString(pFuncDesc->Name); } } - - ppFuncDesc = &((*ppFuncDesc)->next); - if(pFunc->next == 0xffff) break; } pTI->TypeAttr.cFuncs = cFuncs; } @@ -3651,7 +3767,7 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) { SLTG_DoImpls(pFirstItem, pTI, FALSE, ref_lookup); } - HeapFree(GetProcessHeap(), 0, ref_lookup); + heap_free(ref_lookup); } @@ -3676,10 +3792,10 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, if (pTITail->funcs_off != 0xffff) SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); - HeapFree(GetProcessHeap(), 0, ref_lookup); + heap_free(ref_lookup); if (TRACE_ON(typelib)) - dump_TLBFuncDesc(pTI->funclist); + dump_TLBFuncDesc(pTI->funcdescs, pTI->TypeAttr.cFuncs); } static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, @@ -3712,7 +3828,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, SLTG_DoType(pType, pBlk, &pTI->TypeAttr.tdescAlias, ref_lookup); - HeapFree(GetProcessHeap(), 0, ref_lookup); + heap_free(ref_lookup); } static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, @@ -3738,9 +3854,9 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */ pTI->TypeAttr.cbSizeVft = pTI->TypeAttr.cFuncs * sizeof(void *); - HeapFree(GetProcessHeap(), 0, ref_lookup); + heap_free(ref_lookup); if (TRACE_ON(typelib)) - dump_TLBFuncDesc(pTI->funclist); + dump_TLBFuncDesc(pTI->funcdescs, pTI->TypeAttr.cFuncs); } static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, @@ -3764,13 +3880,13 @@ static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, if (pTITail->funcs_off != 0xffff) SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup); - HeapFree(GetProcessHeap(), 0, ref_lookup); + heap_free(ref_lookup); if (TRACE_ON(typelib)) dump_TypeInfo(pTI); } /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more - managable copy of it into this */ + manageable copy of it into this */ typedef struct { WORD small_no; char *index_name; @@ -3869,9 +3985,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) /* And now TypeInfoCount of SLTG_OtherTypeInfo */ - pOtherTypeInfoBlks = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(*pOtherTypeInfoBlks) * - pTypeLibImpl->TypeInfoCount); + pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount); ptr = (char*)pLibBlk + len; @@ -3885,8 +3999,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) w = *(WORD*)(ptr + 2); if(w != 0xffff) { len += w; - pOtherTypeInfoBlks[i].index_name = HeapAlloc(GetProcessHeap(),0, - w+1); + pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1); memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w); pOtherTypeInfoBlks[i].index_name[w] = '\0'; } @@ -3894,8 +4007,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) if(w != 0xffff) { TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w)); len += w; - pOtherTypeInfoBlks[i].other_name = HeapAlloc(GetProcessHeap(),0, - w+1); + pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1); memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w); pOtherTypeInfoBlks[i].other_name[w] = '\0'; } @@ -3903,8 +4015,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8); extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len); if(extra) { - pOtherTypeInfoBlks[i].extra = HeapAlloc(GetProcessHeap(),0, - extra); + pOtherTypeInfoBlks[i].extra = heap_alloc(extra); memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra); len += extra; } @@ -3953,7 +4064,8 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) I'll just follow the links along the BlkEntry chain and read them in the order in which they are in the file */ - ppTypeInfoImpl = &(pTypeLibImpl->pTypeInfo); + pTypeLibImpl->typeinfos = heap_alloc_zero(pTypeLibImpl->TypeInfoCount * sizeof(ITypeInfoImpl*)); + ppTypeInfoImpl = pTypeLibImpl->typeinfos; for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0; pBlkEntry[order].next != 0; @@ -3963,22 +4075,23 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) SLTG_TypeInfoTail *pTITail; SLTG_MemberHeader *pMemHeader; - if(strcmp(pBlkEntry[order].index_string + (char*)pMagic, - pOtherTypeInfoBlks[i].index_name)) { - FIXME_(typelib)("Index strings don't match\n"); - return NULL; + if(strcmp(pBlkEntry[order].index_string + (char*)pMagic, pOtherTypeInfoBlks[i].index_name)) { + FIXME_(typelib)("Index strings don't match\n"); + heap_free(pOtherTypeInfoBlks); + return NULL; } pTIHeader = pBlk; if(pTIHeader->magic != SLTG_TIHEADER_MAGIC) { FIXME_(typelib)("TypeInfoHeader magic = %04x\n", pTIHeader->magic); + heap_free(pOtherTypeInfoBlks); return NULL; } TRACE_(typelib)("pTIHeader->res06 = %x, pTIHeader->res0e = %x, " "pTIHeader->res16 = %x, pTIHeader->res1e = %x\n", pTIHeader->res06, pTIHeader->res0e, pTIHeader->res16, pTIHeader->res1e); - *ppTypeInfoImpl = (ITypeInfoImpl*)ITypeInfo_Constructor(); + *ppTypeInfoImpl = ITypeInfoImpl_Constructor(); (*ppTypeInfoImpl)->pTypeLib = pTypeLibImpl; (*ppTypeInfoImpl)->index = i; (*ppTypeInfoImpl)->Name = TLB_MultiByteToBSTR( @@ -4073,16 +4186,17 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) X(32); X(34); #undef X - ppTypeInfoImpl = &((*ppTypeInfoImpl)->next); + ++ppTypeInfoImpl; pBlk = (char*)pBlk + pBlkEntry[order].len; } if(i != pTypeLibImpl->TypeInfoCount) { FIXME("Somehow processed %d TypeInfos\n", i); + heap_free(pOtherTypeInfoBlks); return NULL; } - HeapFree(GetProcessHeap(), 0, pOtherTypeInfoBlks); + heap_free(pOtherTypeInfoBlks); return (ITypeLib2*)pTypeLibImpl; } @@ -4139,22 +4253,19 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) if (!ref) { TLBImpLib *pImpLib, *pImpLibNext; - TLBCustData *pCustData, *pCustDataNext; TLBRefType *ref_type; void *cursor2; int i; - ITypeInfoImpl *pTI, *pTINext; /* remove cache entry */ if(This->path) { TRACE("removing from cache list\n"); EnterCriticalSection(&cache_section); - if (This->next) This->next->prev = This->prev; - if (This->prev) This->prev->next = This->next; - else tlb_cache_first = This->next; + if(This->entry.next) + list_remove(&This->entry); LeaveCriticalSection(&cache_section); - HeapFree(GetProcessHeap(), 0, This->path); + heap_free(This->path); } TRACE(" destroying ITypeLib(%p)\n",This); @@ -4170,42 +4281,34 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) SysFreeString(This->HelpStringDll); This->HelpStringDll = NULL; - for (pCustData = This->pCustData; pCustData; pCustData = pCustDataNext) - { - VariantClear(&pCustData->data); - - pCustDataNext = pCustData->next; - TLB_Free(pCustData); - } + TLB_FreeCustData(&This->custdata_list); for (i = 0; i < This->ctTypeDesc; i++) if (This->pTypeDesc[i].vt == VT_CARRAY) - TLB_Free(This->pTypeDesc[i].u.lpadesc); + heap_free(This->pTypeDesc[i].u.lpadesc); - TLB_Free(This->pTypeDesc); + heap_free(This->pTypeDesc); - for (pImpLib = This->pImpLibs; pImpLib; pImpLib = pImpLibNext) + LIST_FOR_EACH_ENTRY_SAFE(pImpLib, pImpLibNext, &This->implib_list, TLBImpLib, entry) { if (pImpLib->pImpTypeLib) ITypeLib_Release((ITypeLib *)pImpLib->pImpTypeLib); SysFreeString(pImpLib->name); - pImpLibNext = pImpLib->next; - TLB_Free(pImpLib); + list_remove(&pImpLib->entry); + heap_free(pImpLib); } LIST_FOR_EACH_ENTRY_SAFE(ref_type, cursor2, &This->ref_list, TLBRefType, entry) { list_remove(&ref_type->entry); - TLB_Free(ref_type); + heap_free(ref_type); } - for (pTI = This->pTypeInfo; pTI; pTI = pTINext) - { - pTINext = pTI->next; - ITypeInfo_fnDestroy(pTI); - } - HeapFree(GetProcessHeap(),0,This); + for (i = 0; i < This->TypeInfoCount; ++i) + ITypeInfoImpl_Destroy(This->typeinfos[i]); + heap_free(This->typeinfos); + heap_free(This); return 0; } @@ -4232,30 +4335,19 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfo( UINT index, ITypeInfo **ppTInfo) { - UINT i; + ITypeLibImpl *This = (ITypeLibImpl*)iface; - ITypeLibImpl *This = (ITypeLibImpl *)iface; - ITypeInfoImpl *pTypeInfo = This->pTypeInfo; + TRACE("%p %u %p\n", This, index, ppTInfo); - TRACE("(%p)->(index=%d)\n", This, index); + if(!ppTInfo) + return E_INVALIDARG; - if (!ppTInfo) return E_INVALIDARG; - - /* search element n in list */ - for(i=0; i < index; i++) - { - pTypeInfo = pTypeInfo->next; - if (!pTypeInfo) - { - TRACE("-- element not found\n"); + if(index >= This->TypeInfoCount) return TYPE_E_ELEMENTNOTFOUND; - } - } - - *ppTInfo = (ITypeInfo *) pTypeInfo; + *ppTInfo = (ITypeInfo*)This->typeinfos[index]; ITypeInfo_AddRef(*ppTInfo); - TRACE("-- found (%p)\n",*ppTInfo); + return S_OK; } @@ -4270,29 +4362,17 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType( TYPEKIND *pTKind) { ITypeLibImpl *This = (ITypeLibImpl *)iface; - UINT i; - ITypeInfoImpl *pTInfo = This->pTypeInfo; - if (ITypeLib2_fnGetTypeInfoCount(iface) < index + 1) - return TYPE_E_ELEMENTNOTFOUND; + TRACE("(%p, %d, %p)\n", This, index, pTKind); - TRACE("(%p) index %d\n", This, index); + if(!pTKind) + return E_INVALIDARG; - if(!pTKind) return E_INVALIDARG; - - /* search element n in list */ - for(i=0; i < index; i++) - { - if(!pTInfo) - { - TRACE("-- element not found\n"); + if(index >= This->TypeInfoCount) return TYPE_E_ELEMENTNOTFOUND; - } - pTInfo = pTInfo->next; - } - *pTKind = pTInfo->TypeAttr.typekind; - TRACE("-- found Type (%d)\n", *pTKind); + *pTKind = This->typeinfos[index]->TypeAttr.typekind; + return S_OK; } @@ -4307,36 +4387,19 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid( ITypeInfo **ppTInfo) { ITypeLibImpl *This = (ITypeLibImpl *)iface; - ITypeInfoImpl *pTypeInfo = This->pTypeInfo; /* head of list */ + UINT i; - TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid)); + TRACE("%p %s %p\n", This, debugstr_guid(guid), ppTInfo); - if (!pTypeInfo) - { - WARN("-- element not found\n"); - return TYPE_E_ELEMENTNOTFOUND; + for(i = 0; i < This->TypeInfoCount; ++i){ + if(IsEqualIID(&This->typeinfos[i]->TypeAttr.guid, guid)){ + *ppTInfo = (ITypeInfo*)This->typeinfos[i]; + ITypeInfo_AddRef(*ppTInfo); + return S_OK; + } } - /* search linked list for guid */ - while( !IsEqualIID(guid,&pTypeInfo->TypeAttr.guid) ) - { - pTypeInfo = pTypeInfo->next; - - if (!pTypeInfo) - { - /* end of list reached */ - WARN("-- element not found\n"); - return TYPE_E_ELEMENTNOTFOUND; - } - } - - TRACE("-- found (%p, %s)\n", - pTypeInfo, - debugstr_w(pTypeInfo->Name)); - - *ppTInfo = (ITypeInfo*)pTypeInfo; - ITypeInfo_AddRef(*ppTInfo); - return S_OK; + return TYPE_E_ELEMENTNOTFOUND; } /* ITypeLib::GetLibAttr @@ -4346,12 +4409,18 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid( */ static HRESULT WINAPI ITypeLib2_fnGetLibAttr( ITypeLib2 *iface, - LPTLIBATTR *ppTLibAttr) + LPTLIBATTR *attr) { ITypeLibImpl *This = (ITypeLibImpl *)iface; - TRACE("(%p)\n",This); - *ppTLibAttr = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppTLibAttr)); - **ppTLibAttr = This->LibAttr; + + TRACE("(%p, %p)\n", This, attr); + + if (!attr) return E_INVALIDARG; + + *attr = heap_alloc(sizeof(**attr)); + if (!*attr) return E_OUTOFMEMORY; + + **attr = This->LibAttr; return S_OK; } @@ -4486,26 +4555,26 @@ static HRESULT WINAPI ITypeLib2_fnIsName( BOOL *pfName) { ITypeLibImpl *This = (ITypeLibImpl *)iface; - ITypeInfoImpl *pTInfo; - TLBFuncDesc *pFInfo; - TLBVarDesc *pVInfo; - int i; - UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR); + UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR), tic, fdc, vrc, pc; TRACE("(%p)->(%s,%08x,%p)\n", This, debugstr_w(szNameBuf), lHashVal, pfName); *pfName=TRUE; - for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){ + for(tic = 0; tic < This->TypeInfoCount; ++tic){ + ITypeInfoImpl *pTInfo = This->typeinfos[tic]; if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; - for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) { + for(fdc = 0; fdc < pTInfo->TypeAttr.cFuncs; ++fdc) { + TLBFuncDesc *pFInfo = &pTInfo->funcdescs[fdc]; if(!memcmp(szNameBuf,pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; - for(i=0;ifuncdesc.cParams;i++) - if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name, nNameBufLen)) + for(pc=0; pc < pFInfo->funcdesc.cParams; pc++) + if(!memcmp(szNameBuf,pFInfo->pParamDesc[pc].Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; } - for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) + for(vrc = 0; vrc < pTInfo->TypeAttr.cVars; ++vrc){ + TLBVarDesc *pVInfo = &pTInfo->vardescs[vrc]; if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; + } } *pfName=FALSE; @@ -4525,40 +4594,52 @@ ITypeLib2_fnIsName_exit: */ static HRESULT WINAPI ITypeLib2_fnFindName( ITypeLib2 *iface, - LPOLESTR szNameBuf, - ULONG lHashVal, + LPOLESTR name, + ULONG hash, ITypeInfo **ppTInfo, - MEMBERID *rgMemId, - UINT16 *pcFound) + MEMBERID *memid, + UINT16 *found) { ITypeLibImpl *This = (ITypeLibImpl *)iface; - ITypeInfoImpl *pTInfo; - TLBFuncDesc *pFInfo; - TLBVarDesc *pVInfo; - int i,j = 0; - UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR); + UINT tic, count = 0; + UINT len; - for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){ - if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit; - for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) { - if(!memcmp(szNameBuf,pFInfo->Name,nNameBufLen)) goto ITypeLib2_fnFindName_exit; - for(i=0;ifuncdesc.cParams;i++) { - if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name,nNameBufLen)) + TRACE("(%p)->(%s %u %p %p %p)\n", This, debugstr_w(name), hash, ppTInfo, memid, found); + + if ((!name && hash == 0) || !ppTInfo || !memid || !found) + return E_INVALIDARG; + + len = (lstrlenW(name) + 1)*sizeof(WCHAR); + for(tic = 0; tic < This->TypeInfoCount; ++tic) { + ITypeInfoImpl *pTInfo = This->typeinfos[tic]; + TLBVarDesc *var; + UINT fdc; + + if(!memcmp(name, pTInfo->Name, len)) goto ITypeLib2_fnFindName_exit; + for(fdc = 0; fdc < pTInfo->TypeAttr.cFuncs; ++fdc) { + TLBFuncDesc *func = &pTInfo->funcdescs[fdc]; + UINT pc; + + if(!memcmp(name, func->Name, len)) goto ITypeLib2_fnFindName_exit; + for(pc = 0; pc < func->funcdesc.cParams; pc++) { + if(!memcmp(name, func->pParamDesc[pc].Name, len)) goto ITypeLib2_fnFindName_exit; - } + } } - for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) - if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit; + + var = TLB_get_vardesc_by_name(pTInfo->vardescs, pTInfo->TypeAttr.cVars, name); + if (var) + goto ITypeLib2_fnFindName_exit; + continue; ITypeLib2_fnFindName_exit: ITypeInfo_AddRef((ITypeInfo*)pTInfo); - ppTInfo[j]=(LPTYPEINFO)pTInfo; - j++; + ppTInfo[count]=(LPTYPEINFO)pTInfo; + count++; } - TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n", - This, *pcFound, debugstr_w(szNameBuf), j); + TRACE("found %d typeinfos\n", count); - *pcFound=j; + *found = count; return S_OK; } @@ -4574,7 +4655,7 @@ static VOID WINAPI ITypeLib2_fnReleaseTLibAttr( { ITypeLibImpl *This = (ITypeLibImpl *)iface; TRACE("freeing (%p)\n",This); - HeapFree(GetProcessHeap(),0,pTLibAttr); + heap_free(pTLibAttr); } @@ -4590,20 +4671,16 @@ static HRESULT WINAPI ITypeLib2_fnGetCustData( ITypeLibImpl *This = (ITypeLibImpl *)iface; TLBCustData *pCData; - for(pCData=This->pCustData; pCData; pCData = pCData->next) - { - if( IsEqualIID(guid, &pCData->guid)) break; - } + TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal); - TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + pCData = TLB_get_custdata_by_guid(&This->custdata_list, guid); + if(!pCData) + return TYPE_E_ELEMENTNOTFOUND; - if(pCData) - { - VariantInit( pVarVal); - VariantCopy( pVarVal, &pCData->data); - return S_OK; - } - return E_INVALIDARG; /* FIXME: correct? */ + VariantInit(pVarVal); + VariantCopy(pVarVal, &pCData->data); + + return S_OK; } /* ITypeLib2::GetLibStatistics @@ -4693,6 +4770,31 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( return result; } +static HRESULT TLB_copy_all_custdata(struct list *custdata_list, CUSTDATA *pCustData) +{ + TLBCustData *pCData; + unsigned int ct; + CUSTDATAITEM *cdi; + + ct = list_count(custdata_list); + + pCustData->prgCustData = heap_alloc_zero(ct * sizeof(CUSTDATAITEM)); + if(!pCustData->prgCustData) + return E_OUTOFMEMORY; + + pCustData->cCustData = ct; + + cdi = pCustData->prgCustData; + LIST_FOR_EACH_ENTRY(pCData, custdata_list, TLBCustData, entry){ + cdi->guid = pCData->guid; + VariantCopy(&cdi->varValue, &pCData->data); + ++cdi; + } + + return S_OK; +} + + /* ITypeLib2::GetAllCustData * * Gets all custom data items for the library. @@ -4703,21 +4805,8 @@ static HRESULT WINAPI ITypeLib2_fnGetAllCustData( CUSTDATA *pCustData) { ITypeLibImpl *This = (ITypeLibImpl *)iface; - TLBCustData *pCData; - int i; - TRACE("(%p) returning %d items\n", This, This->ctCustData); - pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM)); - if(pCustData->prgCustData ){ - pCustData->cCustData=This->ctCustData; - for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){ - pCustData->prgCustData[i].guid=pCData->guid; - VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data); - } - }else{ - ERR(" OUT OF MEMORY!\n"); - return E_OUTOFMEMORY; - } - return S_OK; + TRACE("%p %p\n", iface, pCustData); + return TLB_copy_all_custdata(&This->custdata_list, pCustData); } static const ITypeLib2Vtbl tlbvt = { @@ -4746,7 +4835,7 @@ static HRESULT WINAPI ITypeLibComp_fnQueryInterface(ITypeComp * iface, REFIID ri { ITypeLibImpl *This = impl_from_ITypeComp(iface); - return ITypeLib2_QueryInterface((ITypeLib *)This, riid, ppv); + return ITypeLib2_QueryInterface((ITypeLib2 *)This, riid, ppv); } static ULONG WINAPI ITypeLibComp_fnAddRef(ITypeComp * iface) @@ -4773,8 +4862,7 @@ static HRESULT WINAPI ITypeLibComp_fnBind( BINDPTR * pBindPtr) { ITypeLibImpl *This = impl_from_ITypeComp(iface); - ITypeInfoImpl *pTypeInfo; - int typemismatch=0; + int typemismatch=0, i; TRACE("(%s, 0x%x, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr); @@ -4782,8 +4870,8 @@ static HRESULT WINAPI ITypeLibComp_fnBind( pBindPtr->lptcomp = NULL; *ppTInfo = NULL; - for (pTypeInfo = This->pTypeInfo; pTypeInfo; pTypeInfo = pTypeInfo->next) - { + for(i = 0; i < This->TypeInfoCount; ++i){ + ITypeInfoImpl *pTypeInfo = This->typeinfos[i]; TRACE("testing %s\n", debugstr_w(pTypeInfo->Name)); /* FIXME: check wFlags here? */ @@ -4910,14 +4998,18 @@ static HRESULT WINAPI ITypeLibComp_fnBindType( ITypeComp ** ppTComp) { ITypeLibImpl *This = impl_from_ITypeComp(iface); - ITypeInfoImpl *pTypeInfo; + UINT i; TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp); - for (pTypeInfo = This->pTypeInfo; pTypeInfo; pTypeInfo = pTypeInfo->next) + if(!szName || !ppTInfo || !ppTComp) + return E_INVALIDARG; + + for(i = 0; i < This->TypeInfoCount; ++i) { + ITypeInfoImpl *pTypeInfo = This->typeinfos[i]; /* FIXME: should use lHash to do the search */ - if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name, szName)) + if (pTypeInfo->Name && !strcmpiW(pTypeInfo->Name, szName)) { TRACE("returning %p\n", pTypeInfo); *ppTInfo = (ITypeInfo *)&pTypeInfo->lpVtbl; @@ -4946,11 +5038,11 @@ static const ITypeCompVtbl tlbtcvt = }; /*================== ITypeInfo(2) Methods ===================================*/ -static ITypeInfo2 * ITypeInfo_Constructor(void) +static ITypeInfoImpl* ITypeInfoImpl_Constructor(void) { - ITypeInfoImpl * pTypeInfoImpl; + ITypeInfoImpl *pTypeInfoImpl; - pTypeInfoImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeInfoImpl)); + pTypeInfoImpl = heap_alloc_zero(sizeof(ITypeInfoImpl)); if (pTypeInfoImpl) { pTypeInfoImpl->lpVtbl = &tinfvt; @@ -4959,9 +5051,10 @@ static ITypeInfo2 * ITypeInfo_Constructor(void) pTypeInfoImpl->hreftype = -1; pTypeInfoImpl->TypeAttr.memidConstructor = MEMBERID_NIL; pTypeInfoImpl->TypeAttr.memidDestructor = MEMBERID_NIL; + list_init(&pTypeInfoImpl->custdata_list); } TRACE("(%p)\n", pTypeInfoImpl); - return (ITypeInfo2*) pTypeInfoImpl; + return pTypeInfoImpl; } /* ITypeInfo::QueryInterface @@ -4982,7 +5075,7 @@ static HRESULT WINAPI ITypeInfo_fnQueryInterface( *ppvObject = This; if(*ppvObject){ - ITypeInfo_AddRef(iface); + ITypeInfo2_AddRef(iface); TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); return S_OK; } @@ -5005,11 +5098,9 @@ static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface) return ref; } -static void ITypeInfo_fnDestroy(ITypeInfoImpl *This) +static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This) { - TLBFuncDesc *pFInfo, *pFInfoNext; - TLBVarDesc *pVInfo, *pVInfoNext; - TLBImplType *pImpl, *pImplNext; + UINT i, j; TRACE("destroying ITypeInfo(%p)\n",This); @@ -5022,51 +5113,55 @@ static void ITypeInfo_fnDestroy(ITypeInfoImpl *This) SysFreeString(This->DllName); This->DllName = NULL; - for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext) + for (i = 0; i < This->TypeAttr.cFuncs; ++i) { - INT i; - for(i = 0;i < pFInfo->funcdesc.cParams; i++) + TLBFuncDesc *pFInfo = &This->funcdescs[i]; + for(j = 0; j < pFInfo->funcdesc.cParams; j++) { - ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i]; + ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[j]; if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) { VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue); - TLB_Free(elemdesc->u.paramdesc.pparamdescex); + heap_free(elemdesc->u.paramdesc.pparamdescex); } - SysFreeString(pFInfo->pParamDesc[i].Name); + TLB_FreeCustData(&pFInfo->pParamDesc[j].custdata_list); + SysFreeString(pFInfo->pParamDesc[j].Name); } - TLB_Free(pFInfo->funcdesc.lprgelemdescParam); - TLB_Free(pFInfo->pParamDesc); - TLB_FreeCustData(pFInfo->pCustData); + heap_free(pFInfo->funcdesc.lprgelemdescParam); + heap_free(pFInfo->pParamDesc); + TLB_FreeCustData(&pFInfo->custdata_list); if (!IS_INTRESOURCE(pFInfo->Entry) && pFInfo->Entry != (BSTR)-1) SysFreeString(pFInfo->Entry); SysFreeString(pFInfo->HelpString); SysFreeString(pFInfo->Name); - - pFInfoNext = pFInfo->next; - TLB_Free(pFInfo); } - for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext) + heap_free(This->funcdescs); + + for(i = 0; i < This->TypeAttr.cVars; ++i) { + TLBVarDesc *pVInfo = &This->vardescs[i]; if (pVInfo->vardesc.varkind == VAR_CONST) { VariantClear(pVInfo->vardesc.u.lpvarValue); - TLB_Free(pVInfo->vardesc.u.lpvarValue); + heap_free(pVInfo->vardesc.u.lpvarValue); } - TLB_FreeCustData(pVInfo->pCustData); + TLB_FreeCustData(&pVInfo->custdata_list); SysFreeString(pVInfo->Name); - pVInfoNext = pVInfo->next; - TLB_Free(pVInfo); + SysFreeString(pVInfo->HelpString); } - for (pImpl = This->impltypelist; pImpl; pImpl = pImplNext) - { - TLB_FreeCustData(pImpl->pCustData); - pImplNext = pImpl->next; - TLB_Free(pImpl); - } - TLB_FreeCustData(This->pCustData); + heap_free(This->vardescs); - HeapFree(GetProcessHeap(), 0, This); + if(This->impltypes){ + for (i = 0; i < This->TypeAttr.cImplTypes; ++i){ + TLBImplType *pImpl = &This->impltypes[i]; + TLB_FreeCustData(&pImpl->custdata_list); + } + heap_free(This->impltypes); + } + + TLB_FreeCustData(&This->custdata_list); + + heap_free(This); } /* ITypeInfo::Release @@ -5083,7 +5178,7 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface) BOOL not_attached_to_typelib = This->not_attached_to_typelib; ITypeLib2_Release((ITypeLib2*)This->pTypeLib); if (not_attached_to_typelib) - HeapFree(GetProcessHeap(), 0, This); + heap_free(This); /* otherwise This will be freed when typelib is freed */ } @@ -5108,7 +5203,7 @@ static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface, if (This->TypeAttr.typekind == TKIND_ALIAS) size += TLB_SizeTypeDesc(&This->TypeAttr.tdescAlias, FALSE); - *ppTypeAttr = HeapAlloc(GetProcessHeap(), 0, size); + *ppTypeAttr = heap_alloc(size); if (!*ppTypeAttr) return E_OUTOFMEMORY; @@ -5121,7 +5216,8 @@ static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface, if((*ppTypeAttr)->typekind == TKIND_DISPATCH) { /* This should include all the inherited funcs */ (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / sizeof(void *); - (*ppTypeAttr)->cbSizeVft = 7 * sizeof(void *); /* This is always the size of IDispatch's vtbl */ + /* This is always the size of IDispatch's vtbl */ + (*ppTypeAttr)->cbSizeVft = sizeof(IDispatchVtbl); (*ppTypeAttr)->wTypeFlags &= ~TYPEFLAG_FOLEAUTOMATION; } return S_OK; @@ -5270,19 +5366,12 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - const TLBFuncDesc *pFDesc; - UINT i; - for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next) - ; + if (index >= This->TypeAttr.cFuncs) + return TYPE_E_ELEMENTNOTFOUND; - if (pFDesc) - { - *ppFuncDesc = &pFDesc->funcdesc; - return S_OK; - } - - return TYPE_E_ELEMENTNOTFOUND; + *ppFuncDesc = &This->funcdescs[index].funcdesc; + return S_OK; } /* internal function to make the inherited interfaces' methods appear @@ -5299,12 +5388,12 @@ static HRESULT ITypeInfoImpl_GetInternalDispatchFuncDesc( ITypeInfo *iface, else *hrefoffset = DISPATCH_HREF_OFFSET; - if(This->impltypelist) + if(This->impltypes) { ITypeInfo *pSubTypeInfo; UINT sub_funcs; - hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, &pSubTypeInfo); + hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pSubTypeInfo); if (FAILED(hr)) return hr; @@ -5464,18 +5553,14 @@ static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index, LPVARDESC *ppVarDesc) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - UINT i; - const TLBVarDesc *pVDesc; + const TLBVarDesc *pVDesc = &This->vardescs[index]; TRACE("(%p) index %d\n", This, index); - for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next) - ; + if(index >= This->TypeAttr.cVars) + return TYPE_E_ELEMENTNOTFOUND; - if (pVDesc) - return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc); - - return E_INVALIDARG; + return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc); } /* ITypeInfo_GetNames @@ -5492,7 +5577,7 @@ static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, const TLBVarDesc *pVDesc; int i; TRACE("(%p) memid=0x%08x Maxname=%d\n", This, memid, cMaxNames); - for(pFDesc=This->funclist; pFDesc && pFDesc->funcdesc.memid != memid; pFDesc=pFDesc->next); + pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->TypeAttr.cFuncs, memid); if(pFDesc) { /* function found, now return function and parameter names */ @@ -5507,7 +5592,7 @@ static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, } else { - for(pVDesc=This->varlist; pVDesc && pVDesc->vardesc.memid != memid; pVDesc=pVDesc->next); + pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->TypeAttr.cVars, memid); if(pVDesc) { *rgBstrNames=SysAllocString(pVDesc->Name); @@ -5515,13 +5600,12 @@ static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, } else { - if(This->impltypelist && + if(This->impltypes && (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) { /* recursive search */ ITypeInfo *pTInfo; HRESULT result; - result=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, - &pTInfo); + result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo); if(SUCCEEDED(result)) { result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames); @@ -5556,9 +5640,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( HREFTYPE *pRefType) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - UINT i; HRESULT hr = S_OK; - const TLBImplType *pImpl = This->impltypelist; TRACE("(%p) index %d\n", This, index); if (TRACE_ON(ole)) dump_TypeInfo(This); @@ -5586,16 +5668,10 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( } else { - /* get element n from linked list */ - for(i=0; pImpl && inext; - } - - if (pImpl) - *pRefType = pImpl->hRef; - else - hr = TYPE_E_ELEMENTNOTFOUND; + if(index >= This->TypeAttr.cImplTypes) + hr = TYPE_E_ELEMENTNOTFOUND; + else + *pRefType = This->impltypes[index].hRef; } if(TRACE_ON(ole)) @@ -5618,24 +5694,20 @@ static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface, UINT index, INT *pImplTypeFlags) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - UINT i; - TLBImplType *pImpl; TRACE("(%p) index %d\n", This, index); - for(i=0, pImpl=This->impltypelist; inext) - ; - if(i==index && pImpl){ - *pImplTypeFlags=pImpl->implflags; + + if(This->TypeAttr.typekind == TKIND_DISPATCH && index == 0){ + *pImplTypeFlags = 0; return S_OK; } - *pImplTypeFlags=0; - if(This->TypeAttr.typekind==TKIND_DISPATCH && !index) - return S_OK; + if(index >= This->TypeAttr.cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; - WARN("ImplType %d not found\n", index); - return TYPE_E_ELEMENTNOTFOUND; + *pImplTypeFlags = This->impltypes[index].implflags; + + return S_OK; } /* GetIDsOfNames @@ -5646,10 +5718,9 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - const TLBFuncDesc *pFDesc; const TLBVarDesc *pVDesc; HRESULT ret=S_OK; - UINT i; + UINT i, fdc; TRACE("(%p) Name %s cNames %d\n", This, debugstr_w(*rgszNames), cNames); @@ -5658,8 +5729,9 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, for (i = 0; i < cNames; i++) pMemId[i] = MEMBERID_NIL; - for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) { + for (fdc = 0; fdc < This->TypeAttr.cFuncs; ++fdc) { int j; + const TLBFuncDesc *pFDesc = &This->funcdescs[fdc]; if(!lstrcmpiW(*rgszNames, pFDesc->Name)) { if(cNames) *pMemId=pFDesc->funcdesc.memid; for(i=1; i < cNames; i++){ @@ -5675,18 +5747,17 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, return ret; } } - for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) { - if(!lstrcmpiW(*rgszNames, pVDesc->Name)) { - if(cNames) *pMemId=pVDesc->vardesc.memid; - return ret; - } + pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->TypeAttr.cVars, *rgszNames); + if(pVDesc){ + if(cNames) + *pMemId = pVDesc->vardesc.memid; + return ret; } /* not found, see if it can be found in an inherited interface */ - if(This->impltypelist) { + if(This->impltypes) { /* recursive search */ ITypeInfo *pTInfo; - ret=ITypeInfo_GetRefTypeInfo(iface, - This->impltypelist->hRef, &pTInfo); + ret = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo); if(SUCCEEDED(ret)){ ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId ); ITypeInfo_Release(pTInfo); @@ -5701,7 +5772,7 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, #ifdef __i386__ -extern DWORD CDECL call_method( void *func, int nb_args, const DWORD *args ); +extern LONGLONG call_method( void *func, int nb_args, const DWORD *args, int *stack_offset ); __ASM_GLOBAL_FUNC( call_method, "pushl %ebp\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") @@ -5713,16 +5784,20 @@ __ASM_GLOBAL_FUNC( call_method, "pushl %edi\n\t" __ASM_CFI(".cfi_rel_offset %edi,-8\n\t") "movl 12(%ebp),%edx\n\t" + "movl %esp,%edi\n\t" "shll $2,%edx\n\t" "jz 1f\n\t" - "subl %edx,%esp\n\t" - "andl $~15,%esp\n\t" + "subl %edx,%edi\n\t" + "andl $~15,%edi\n\t" + "movl %edi,%esp\n\t" "movl 12(%ebp),%ecx\n\t" "movl 16(%ebp),%esi\n\t" - "movl %esp,%edi\n\t" "cld\n\t" "rep; movsl\n" "1:\tcall *8(%ebp)\n\t" + "subl %esp,%edi\n\t" + "movl 20(%ebp),%ecx\n\t" + "movl %edi,(%ecx)\n\t" "leal -8(%ebp),%esp\n\t" "popl %edi\n\t" __ASM_CFI(".cfi_same_value %edi\n\t") @@ -5733,6 +5808,9 @@ __ASM_GLOBAL_FUNC( call_method, __ASM_CFI(".cfi_same_value %ebp\n\t") "ret" ) +/* same function but returning floating point */ +static double (* const call_double_method)(void*,int,const DWORD*,int*) = (void *)call_method; + /* ITypeInfo::Invoke * * Invokes a method, or accesses a property of an object, that implements the @@ -5741,6 +5819,7 @@ __ASM_GLOBAL_FUNC( call_method, DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { DWORD res; + int stack_offset; if (TRACE_ON(ole)) { int i; @@ -5753,7 +5832,7 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { switch (callconv) { case CC_STDCALL: case CC_CDECL: - res = call_method( func, nrargs, args ); + res = call_method( func, nrargs, args, &stack_offset ); break; default: FIXME("unsupported calling convention %d\n",callconv); @@ -5764,33 +5843,53 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { return res; } -/* The size of the argument on the stack in DWORD units (in all x86 call - * convetions the arguments on the stack are DWORD-aligned) - */ -static int _dispargsize(VARTYPE vt) -{ - switch (vt) { - case VT_I8: - case VT_UI8: - return 8/sizeof(DWORD); - case VT_R8: - return sizeof(double)/sizeof(DWORD); - case VT_DECIMAL: - return (sizeof(DECIMAL)+3)/sizeof(DWORD); - case VT_CY: - return sizeof(CY)/sizeof(DWORD); - case VT_DATE: - return sizeof(DATE)/sizeof(DWORD); - case VT_VARIANT: - return (sizeof(VARIANT)+3)/sizeof(DWORD); - case VT_RECORD: - FIXME("VT_RECORD not implemented\n"); - return 1; - default: - return 1; - } -} -#endif /* __i386__ */ +#elif defined(__x86_64__) + +extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args ); +__ASM_GLOBAL_FUNC( call_method, + "pushq %rbp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") + __ASM_CFI(".cfi_rel_offset %rbp,0\n\t") + "movq %rsp,%rbp\n\t" + __ASM_CFI(".cfi_def_cfa_register %rbp\n\t") + "pushq %rsi\n\t" + __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t") + "pushq %rdi\n\t" + __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t") + "movq %rcx,%rax\n\t" + "movq $4,%rcx\n\t" + "cmp %rcx,%rdx\n\t" + "cmovgq %rdx,%rcx\n\t" + "leaq 0(,%rcx,8),%rdx\n\t" + "subq %rdx,%rsp\n\t" + "andq $~15,%rsp\n\t" + "movq %rsp,%rdi\n\t" + "movq %r8,%rsi\n\t" + "rep; movsq\n\t" + "movq 0(%rsp),%rcx\n\t" + "movq 8(%rsp),%rdx\n\t" + "movq 16(%rsp),%r8\n\t" + "movq 24(%rsp),%r9\n\t" + "movq %rcx,%xmm0\n\t" + "movq %rdx,%xmm1\n\t" + "movq %r8,%xmm2\n\t" + "movq %r9,%xmm3\n\t" + "callq *%rax\n\t" + "leaq -16(%rbp),%rsp\n\t" + "popq %rdi\n\t" + __ASM_CFI(".cfi_same_value %rdi\n\t") + "popq %rsi\n\t" + __ASM_CFI(".cfi_same_value %rsi\n\t") + __ASM_CFI(".cfi_def_cfa_register %rsp\n\t") + "popq %rbp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t") + __ASM_CFI(".cfi_same_value %rbp\n\t") + "ret") + +/* same function but returning floating point */ +static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void *)call_method; + +#endif /* __x86_64__ */ static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt) { @@ -5927,6 +6026,42 @@ static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, return hr; } +static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *guid) +{ + ITypeInfo *tinfo2; + TYPEATTR *tattr; + HRESULT hres; + + hres = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2); + if(FAILED(hres)) + return hres; + + hres = ITypeInfo_GetTypeAttr(tinfo2, &tattr); + if(FAILED(hres)) { + ITypeInfo_Release(tinfo2); + return hres; + } + + switch(tattr->typekind) { + case TKIND_ALIAS: + hres = get_iface_guid(tinfo2, &tattr->tdescAlias, guid); + break; + + case TKIND_INTERFACE: + case TKIND_DISPATCH: + *guid = tattr->guid; + break; + + default: + ERR("Unexpected typekind %d\n", tattr->typekind); + hres = E_UNEXPECTED; + } + + ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); + ITypeInfo_Release(tinfo2); + return hres; +} + /*********************************************************************** * DispCallFunc (OLEAUT32.@) * @@ -5971,63 +6106,175 @@ DispCallFunc( VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult) { #ifdef __i386__ - int argsize, argspos; + int argspos, stack_offset; + void *func; UINT i; DWORD *args; - HRESULT hres; TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n", pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult)); - argsize = 0; - if (pvInstance) - argsize++; /* for This pointer */ - - for (i=0;iwFuncFlags & FUNCFLAG_FRESTRICTED) && (desc->memid >= 0); +} + #define INVBUF_ELEMENT_SIZE \ (sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *) + sizeof(VARTYPE)) #define INVBUF_GET_ARG_ARRAY(buffer, params) (buffer) @@ -6061,6 +6313,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( TYPEKIND type_kind; HRESULT hres; const TLBFuncDesc *pFuncInfo; + UINT fdc; TRACE("(%p)(%p,id=%d,flags=0x%08x,%p,%p,%p,%p)\n", This,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr @@ -6086,13 +6339,15 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( /* we do this instead of using GetFuncDesc since it will return a fake * FUNCDESC for dispinterfaces and we want the real function description */ - for (pFuncInfo = This->funclist; pFuncInfo; pFuncInfo=pFuncInfo->next) + for (fdc = 0; fdc < This->TypeAttr.cFuncs; ++fdc){ + pFuncInfo = &This->funcdescs[fdc]; if ((memid == pFuncInfo->funcdesc.memid) && (wFlags & pFuncInfo->funcdesc.invkind) && - (pFuncInfo->funcdesc.wFuncFlags & FUNCFLAG_FRESTRICTED) == 0) + !func_restricted( &pFuncInfo->funcdesc )) break; + } - if (pFuncInfo) { + if (fdc < This->TypeAttr.cFuncs) { const FUNCDESC *func_desc = &pFuncInfo->funcdesc; if (TRACE_ON(ole)) @@ -6104,7 +6359,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( switch (func_desc->funckind) { case FUNC_PUREVIRTUAL: case FUNC_VIRTUAL: { - void *buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, INVBUF_ELEMENT_SIZE * func_desc->cParams); + void *buffer = heap_alloc_zero(INVBUF_ELEMENT_SIZE * func_desc->cParams); VARIANT varresult; VARIANT retval; /* pointer for storing byref retvals in */ VARIANTARG **prgpvarg = INVBUF_GET_ARG_PTR_ARRAY(buffer, func_desc->cParams); @@ -6145,6 +6400,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( for (i = 0; i < func_desc->cParams; i++) { USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags; + TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc; VARIANTARG *src_arg; if (wParamFlags & PARAMFLAG_FLCID) @@ -6213,83 +6469,112 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( { dump_Variant(src_arg); - if (rgvt[i] == VT_VARIANT) - hres = VariantCopy(&rgvarg[i], src_arg); - else if (rgvt[i] == (VT_VARIANT | VT_BYREF)) + if(rgvt[i]!=V_VT(src_arg)) { - if (rgvt[i] == V_VT(src_arg)) - V_VARIANTREF(&rgvarg[i]) = V_VARIANTREF(src_arg); - else + if (rgvt[i] == VT_VARIANT) + hres = VariantCopy(&rgvarg[i], src_arg); + else if (rgvt[i] == (VT_VARIANT | VT_BYREF)) + { + if (rgvt[i] == V_VT(src_arg)) + V_VARIANTREF(&rgvarg[i]) = V_VARIANTREF(src_arg); + else + { + VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams); + if (wParamFlags & PARAMFLAG_FIN) + hres = VariantCopy(&missing_arg[i], src_arg); + V_VARIANTREF(&rgvarg[i]) = &missing_arg[i]; + } + V_VT(&rgvarg[i]) = rgvt[i]; + } + else if (rgvt[i] == (VT_VARIANT | VT_ARRAY) && func_desc->cParamsOpt < 0 && i == func_desc->cParams-1) + { + SAFEARRAY *a; + SAFEARRAYBOUND bound; + VARIANT *v; + LONG j; + bound.lLbound = 0; + bound.cElements = pDispParams->cArgs-i; + if (!(a = SafeArrayCreate(VT_VARIANT, 1, &bound))) + { + ERR("SafeArrayCreate failed\n"); + break; + } + hres = SafeArrayAccessData(a, (LPVOID)&v); + if (hres != S_OK) + { + ERR("SafeArrayAccessData failed with %x\n", hres); + SafeArrayDestroy(a); + break; + } + for (j = 0; j < bound.cElements; j++) + VariantCopy(&v[j], &pDispParams->rgvarg[pDispParams->cArgs - 1 - i - j]); + hres = SafeArrayUnaccessData(a); + if (hres != S_OK) + { + ERR("SafeArrayUnaccessData failed with %x\n", hres); + SafeArrayDestroy(a); + break; + } + V_ARRAY(&rgvarg[i]) = a; + V_VT(&rgvarg[i]) = rgvt[i]; + } + else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg)) { VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams); if (wParamFlags & PARAMFLAG_FIN) - hres = VariantCopy(&missing_arg[i], src_arg); - V_VARIANTREF(&rgvarg[i]) = &missing_arg[i]; + hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF); + else + V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF; + V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]); + V_VT(&rgvarg[i]) = rgvt[i]; } - V_VT(&rgvarg[i]) = rgvt[i]; - } - else if (rgvt[i] == (VT_VARIANT | VT_ARRAY) && func_desc->cParamsOpt < 0 && i == func_desc->cParams-1) - { - SAFEARRAY *a; - SAFEARRAYBOUND bound; - VARIANT *v; - LONG j; - bound.lLbound = 0; - bound.cElements = pDispParams->cArgs-i; - if (!(a = SafeArrayCreate(VT_VARIANT, 1, &bound))) + else if ((rgvt[i] & VT_BYREF) && (rgvt[i] == V_VT(src_arg))) { - ERR("SafeArrayCreate failed\n"); - break; + V_BYREF(&rgvarg[i]) = V_BYREF(src_arg); + V_VT(&rgvarg[i]) = rgvt[i]; } - hres = SafeArrayAccessData(a, (LPVOID)&v); - if (hres != S_OK) - { - ERR("SafeArrayAccessData failed with %x\n", hres); - break; - } - for (j = 0; j < bound.cElements; j++) - VariantCopy(&v[j], &pDispParams->rgvarg[pDispParams->cArgs - 1 - i - j]); - hres = SafeArrayUnaccessData(a); - if (hres != S_OK) - { - ERR("SafeArrayUnaccessData failed with %x\n", hres); - break; - } - V_ARRAY(&rgvarg[i]) = a; - V_VT(&rgvarg[i]) = rgvt[i]; - } - else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg)) - { - VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams); - if (wParamFlags & PARAMFLAG_FIN) - hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF); else - V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF; - V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]); - V_VT(&rgvarg[i]) = rgvt[i]; - } - else if ((rgvt[i] & VT_BYREF) && (rgvt[i] == V_VT(src_arg))) - { - V_BYREF(&rgvarg[i]) = V_BYREF(src_arg); - V_VT(&rgvarg[i]) = rgvt[i]; + { + /* FIXME: this doesn't work for VT_BYREF arguments if + * they are not the same type as in the paramdesc */ + V_VT(&rgvarg[i]) = V_VT(src_arg); + hres = VariantChangeType(&rgvarg[i], src_arg, 0, rgvt[i]); + V_VT(&rgvarg[i]) = rgvt[i]; + } + + if (FAILED(hres)) + { + ERR("failed to convert param %d to %s%s from %s%s\n", i, + debugstr_vt(rgvt[i]), debugstr_vf(rgvt[i]), + debugstr_VT(src_arg), debugstr_VF(src_arg)); + break; + } + prgpvarg[i] = &rgvarg[i]; } else { - /* FIXME: this doesn't work for VT_BYREF arguments if - * they are not the same type as in the paramdesc */ - V_VT(&rgvarg[i]) = V_VT(src_arg); - hres = VariantChangeType(&rgvarg[i], src_arg, 0, rgvt[i]); - V_VT(&rgvarg[i]) = rgvt[i]; + prgpvarg[i] = src_arg; } - if (FAILED(hres)) - { - ERR("failed to convert param %d to %s%s from %s%s\n", i, - debugstr_vt(rgvt[i]), debugstr_vf(rgvt[i]), - debugstr_VT(src_arg), debugstr_VF(src_arg)); - break; + if((tdesc->vt == VT_USERDEFINED || (tdesc->vt == VT_PTR && tdesc->u.lptdesc->vt == VT_USERDEFINED)) + && (V_VT(prgpvarg[i]) == VT_DISPATCH || V_VT(prgpvarg[i]) == VT_UNKNOWN) + && V_UNKNOWN(prgpvarg[i])) { + IUnknown *userdefined_iface; + GUID guid; + + hres = get_iface_guid((ITypeInfo*)iface, tdesc->vt == VT_PTR ? tdesc->u.lptdesc : tdesc, &guid); + if(FAILED(hres)) + break; + + hres = IUnknown_QueryInterface(V_UNKNOWN(prgpvarg[i]), &guid, (void**)&userdefined_iface); + if(FAILED(hres)) { + ERR("argument does not support %s interface\n", debugstr_guid(&guid)); + break; + } + + IUnknown_Release(V_UNKNOWN(prgpvarg[i])); + V_UNKNOWN(prgpvarg[i]) = userdefined_iface; } - prgpvarg[i] = &rgvarg[i]; } else if (wParamFlags & PARAMFLAG_FOPT) { @@ -6482,7 +6767,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( } func_fail: - HeapFree(GetProcessHeap(), 0, buffer); + heap_free(buffer); break; } case FUNC_DISPATCH: { @@ -6526,10 +6811,10 @@ func_fail: /* not found, look for it in inherited interfaces */ ITypeInfo2_GetTypeKind(iface, &type_kind); if(type_kind == TKIND_INTERFACE || type_kind == TKIND_DISPATCH) { - if(This->impltypelist) { + if(This->impltypes) { /* recursive search */ ITypeInfo *pTInfo; - hres = ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, &pTInfo); + hres = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo); if(SUCCEEDED(hres)){ hres = ITypeInfo_Invoke(pTInfo,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr); ITypeInfo_Release(pTInfo); @@ -6570,35 +6855,34 @@ static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface, *pBstrHelpFile=SysAllocString(This->DocString);/* FIXME */ return S_OK; }else {/* for a member */ - for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) - if(pFDesc->funcdesc.memid==memid){ - if(pBstrName) - *pBstrName = SysAllocString(pFDesc->Name); - if(pBstrDocString) - *pBstrDocString=SysAllocString(pFDesc->HelpString); - if(pdwHelpContext) - *pdwHelpContext=pFDesc->helpcontext; - return S_OK; + pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->TypeAttr.cFuncs, memid); + if(pFDesc){ + if(pBstrName) + *pBstrName = SysAllocString(pFDesc->Name); + if(pBstrDocString) + *pBstrDocString=SysAllocString(pFDesc->HelpString); + if(pdwHelpContext) + *pdwHelpContext=pFDesc->helpcontext; + return S_OK; } - for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) - if(pVDesc->vardesc.memid==memid){ - if(pBstrName) - *pBstrName = SysAllocString(pVDesc->Name); - if(pBstrDocString) - *pBstrDocString=SysAllocString(pVDesc->HelpString); - if(pdwHelpContext) - *pdwHelpContext=pVDesc->HelpContext; - return S_OK; + pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->TypeAttr.cVars, memid); + if(pVDesc){ + if(pBstrName) + *pBstrName = SysAllocString(pVDesc->Name); + if(pBstrDocString) + *pBstrDocString=SysAllocString(pVDesc->HelpString); + if(pdwHelpContext) + *pdwHelpContext=pVDesc->HelpContext; + return S_OK; } } - if(This->impltypelist && + if(This->impltypes && (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) { /* recursive search */ ITypeInfo *pTInfo; HRESULT result; - result = ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, - &pTInfo); + result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo); if(SUCCEEDED(result)) { result = ITypeInfo_GetDocumentation(pTInfo, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); @@ -6633,8 +6917,8 @@ static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid if (This->TypeAttr.typekind != TKIND_MODULE) return TYPE_E_BADMODULEKIND; - for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) - if(pFDesc->funcdesc.memid==memid){ + pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->TypeAttr.cFuncs, memid); + if(pFDesc){ dump_TypeInfo(This); if (TRACE_ON(ole)) dump_TLBFuncDescOne(pFDesc); @@ -6668,11 +6952,11 @@ static HRESULT ITypeInfoImpl_GetDispatchRefTypeInfo( ITypeInfo *iface, TRACE("%p, 0x%x\n", iface, *hRefType); - if (This->impltypelist && (*hRefType & DISPATCH_HREF_MASK)) + if (This->impltypes && (*hRefType & DISPATCH_HREF_MASK)) { ITypeInfo *pSubTypeInfo; - hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, &pSubTypeInfo); + hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pSubTypeInfo); if (FAILED(hr)) return hr; @@ -6716,7 +7000,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( /* when we meet a DUAL dispinterface, we must create the interface * version of it. */ - ITypeInfoImpl* pTypeInfoImpl = (ITypeInfoImpl*) ITypeInfo_Constructor(); + ITypeInfoImpl *pTypeInfoImpl = ITypeInfoImpl_Constructor(); /* the interface version contains the same information as the dispinterface @@ -6762,12 +7046,12 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) { UINT Index; - result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index); + result = ITypeInfo2_GetContainingTypeLib(iface, &pTLib, &Index); } else { if(ref_type->pImpTLInfo->pImpTypeLib) { TRACE("typeinfo in imported typelib that is already loaded\n"); pTLib = (ITypeLib*)ref_type->pImpTLInfo->pImpTypeLib; - ITypeLib2_AddRef(pTLib); + ITypeLib_AddRef(pTLib); result = S_OK; } else { TRACE("typeinfo in imported typelib that isn't already loaded\n"); @@ -6784,21 +7068,18 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( } if(SUCCEEDED(result)) { ref_type->pImpTLInfo->pImpTypeLib = (ITypeLibImpl*)pTLib; - ITypeLib2_AddRef(pTLib); + ITypeLib_AddRef(pTLib); } } } if(SUCCEEDED(result)) { if(ref_type->index == TLB_REF_USE_GUID) - result = ITypeLib2_GetTypeInfoOfGuid(pTLib, - &ref_type->guid, - ppTInfo); + result = ITypeLib_GetTypeInfoOfGuid(pTLib, &ref_type->guid, ppTInfo); else - result = ITypeLib2_GetTypeInfo(pTLib, ref_type->index, - ppTInfo); + result = ITypeLib_GetTypeInfo(pTLib, ref_type->index, ppTInfo); } if (pTLib != NULL) - ITypeLib2_Release(pTLib); + ITypeLib_Release(pTLib); } } @@ -6824,7 +7105,7 @@ static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface, TRACE("(%p)->(0x%x, 0x%x, %p)\n", This, memid, invKind, ppv); - hr = ITypeInfo_GetDllEntry(iface, memid, invKind, &dll, &entry, &ordinal); + hr = ITypeInfo2_GetDllEntry(iface, memid, invKind, &dll, &entry, &ordinal); if (FAILED(hr)) return hr; @@ -6842,14 +7123,14 @@ static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface, { LPSTR entryA; INT len = WideCharToMultiByte(CP_ACP, 0, entry, -1, NULL, 0, NULL, NULL); - entryA = HeapAlloc(GetProcessHeap(), 0, len); + entryA = heap_alloc(len); WideCharToMultiByte(CP_ACP, 0, entry, -1, entryA, len, NULL, NULL); *ppv = GetProcAddress(module, entryA); if (!*ppv) ERR("function not found %s\n", debugstr_a(entryA)); - HeapFree(GetProcessHeap(), 0, entryA); + heap_free(entryA); } else { @@ -6889,7 +7170,7 @@ static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface, return CLASS_E_NOAGGREGATION; } - hr = ITypeInfo_GetTypeAttr(iface, &pTA); + hr = ITypeInfo2_GetTypeAttr(iface, &pTA); if(FAILED(hr)) return hr; if(pTA->typekind != TKIND_COCLASS) @@ -6918,7 +7199,7 @@ static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface, riid, ppvObj); end: - ITypeInfo_ReleaseTypeAttr(iface, pTA); + ITypeInfo2_ReleaseTypeAttr(iface, pTA); return hr; } @@ -6953,7 +7234,7 @@ static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface, if (ppTLib) { *ppTLib=(LPTYPELIB )(This->pTypeLib); - ITypeLib2_AddRef(*ppTLib); + ITypeLib_AddRef(*ppTLib); TRACE("returning ppTLib=%p\n", *ppTLib); } @@ -6970,7 +7251,7 @@ static void WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface, { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; TRACE("(%p)->(%p)\n", This, pTypeAttr); - HeapFree(GetProcessHeap(), 0, pTypeAttr); + heap_free(pTypeAttr); } /* ITypeInfo::ReleaseFuncDesc @@ -7047,15 +7328,16 @@ static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface, MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - const TLBFuncDesc *pFuncInfo; - int i; + UINT fdc; HRESULT result; - for(i = 0, pFuncInfo = This->funclist; pFuncInfo; i++, pFuncInfo=pFuncInfo->next) + for (fdc = 0; fdc < This->TypeAttr.cFuncs; ++fdc){ + const TLBFuncDesc *pFuncInfo = &This->funcdescs[fdc]; if(memid == pFuncInfo->funcdesc.memid && (invKind & pFuncInfo->funcdesc.invkind)) break; - if(pFuncInfo) { - *pFuncIndex = i; + } + if(fdc < This->TypeAttr.cFuncs) { + *pFuncIndex = fdc; result = S_OK; } else result = TYPE_E_ELEMENTNOTFOUND; @@ -7076,20 +7358,16 @@ static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface, { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; TLBVarDesc *pVarInfo; - int i; - HRESULT result; - for(i=0, pVarInfo=This->varlist; pVarInfo && - memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next) - ; - if(pVarInfo) { - *pVarIndex = i; - result = S_OK; - } else - result = TYPE_E_ELEMENTNOTFOUND; - TRACE("(%p) memid 0x%08x -> %s\n", This, - memid, SUCCEEDED(result) ? "SUCCESS" : "FAILED"); - return result; + TRACE("%p %d %p\n", iface, memid, pVarIndex); + + pVarInfo = TLB_get_vardesc_by_memberid(This->vardescs, This->TypeAttr.cVars, memid); + if(!pVarInfo) + return TYPE_E_ELEMENTNOTFOUND; + + *pVarIndex = (pVarInfo - This->vardescs); + + return S_OK; } /* ITypeInfo2::GetCustData @@ -7104,10 +7382,9 @@ static HRESULT WINAPI ITypeInfo2_fnGetCustData( ITypeInfoImpl *This = (ITypeInfoImpl *)iface; TLBCustData *pCData; - for(pCData=This->pCustData; pCData; pCData = pCData->next) - if( IsEqualIID(guid, &pCData->guid)) break; + TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal); - TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + pCData = TLB_get_custdata_by_guid(&This->custdata_list, guid); VariantInit( pVarVal); if (pCData) @@ -7128,24 +7405,22 @@ static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( VARIANT *pVarVal) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData=NULL; - TLBFuncDesc * pFDesc; - UINT i; - for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, - pFDesc=pFDesc->next); + TLBCustData *pCData; + TLBFuncDesc *pFDesc = &This->funcdescs[index]; - if(pFDesc) - for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next) - if( IsEqualIID(guid, &pCData->guid)) break; + TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal); - TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + if(index >= This->TypeAttr.cFuncs) + return TYPE_E_ELEMENTNOTFOUND; - if(pCData){ - VariantInit( pVarVal); - VariantCopy( pVarVal, &pCData->data); - return S_OK; - } - return E_INVALIDARG; /* FIXME: correct? */ + pCData = TLB_get_custdata_by_guid(&pFDesc->custdata_list, guid); + if(!pCData) + return TYPE_E_ELEMENTNOTFOUND; + + VariantInit(pVarVal); + VariantCopy(pVarVal, &pCData->data); + + return S_OK; } /* ITypeInfo2::GetParamCustData @@ -7160,26 +7435,26 @@ static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( VARIANT *pVarVal) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData=NULL; - TLBFuncDesc * pFDesc; - UINT i; + TLBCustData *pCData; + TLBFuncDesc *pFDesc = &This->funcdescs[indexFunc]; - for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,pFDesc=pFDesc->next); + TRACE("%p %u %u %s %p\n", This, indexFunc, indexParam, + debugstr_guid(guid), pVarVal); - if(pFDesc && indexParamfuncdesc.cParams) - for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData; - pCData = pCData->next) - if( IsEqualIID(guid, &pCData->guid)) break; + if(indexFunc >= This->TypeAttr.cFuncs) + return TYPE_E_ELEMENTNOTFOUND; - TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + if(indexParam >= pFDesc->funcdesc.cParams) + return TYPE_E_ELEMENTNOTFOUND; - if(pCData) - { - VariantInit( pVarVal); - VariantCopy( pVarVal, &pCData->data); - return S_OK; - } - return E_INVALIDARG; /* FIXME: correct? */ + pCData = TLB_get_custdata_by_guid(&pFDesc->pParamDesc[indexParam].custdata_list, guid); + if(!pCData) + return TYPE_E_ELEMENTNOTFOUND; + + VariantInit(pVarVal); + VariantCopy(pVarVal, &pCData->data); + + return S_OK; } /* ITypeInfo2::GetVarCustData @@ -7193,29 +7468,22 @@ static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( VARIANT *pVarVal) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData=NULL; - TLBVarDesc * pVDesc; - UINT i; + TLBCustData *pCData; + TLBVarDesc *pVDesc = &This->vardescs[index]; - for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next); + TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal); - if(pVDesc) - { - for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next) - { - if( IsEqualIID(guid, &pCData->guid)) break; - } - } + if(index >= This->TypeAttr.cVars) + return TYPE_E_ELEMENTNOTFOUND; - TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + pCData = TLB_get_custdata_by_guid(&pVDesc->custdata_list, guid); + if(!pCData) + return TYPE_E_ELEMENTNOTFOUND; - if(pCData) - { - VariantInit( pVarVal); - VariantCopy( pVarVal, &pCData->data); - return S_OK; - } - return E_INVALIDARG; /* FIXME: correct? */ + VariantInit(pVarVal); + VariantCopy(pVarVal, &pCData->data); + + return S_OK; } /* ITypeInfo2::GetImplCustData @@ -7229,29 +7497,22 @@ static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( VARIANT *pVarVal) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData=NULL; - TLBImplType * pRDesc; - UINT i; + TLBCustData *pCData; + TLBImplType *pRDesc = &This->impltypes[index]; - for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, pRDesc=pRDesc->next); + TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal); - if(pRDesc) - { - for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next) - { - if( IsEqualIID(guid, &pCData->guid)) break; - } - } + if(index >= This->TypeAttr.cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; - TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + pCData = TLB_get_custdata_by_guid(&pRDesc->custdata_list, guid); + if(!pCData) + return TYPE_E_ELEMENTNOTFOUND; - if(pCData) - { - VariantInit( pVarVal); - VariantCopy( pVarVal, &pCData->data); - return S_OK; - } - return E_INVALIDARG; /* FIXME: correct? */ + VariantInit(pVarVal); + VariantCopy(pVarVal, &pCData->data); + + return S_OK; } /* ITypeInfo2::GetDocumentation2 @@ -7290,20 +7551,20 @@ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */ return S_OK; }else {/* for a member */ - for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) - if(pFDesc->funcdesc.memid==memid){ - if(pbstrHelpString) + pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->TypeAttr.cFuncs, memid); + if(pFDesc){ + if(pbstrHelpString) *pbstrHelpString=SysAllocString(pFDesc->HelpString); if(pdwHelpStringContext) *pdwHelpStringContext=pFDesc->HelpStringContext; if(pbstrHelpStringDll) *pbstrHelpStringDll= SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */ - return S_OK; - } - for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) - if(pVDesc->vardesc.memid==memid){ - if(pbstrHelpString) + return S_OK; + } + pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->TypeAttr.cVars, memid); + if(pVDesc){ + if(pbstrHelpString) *pbstrHelpString=SysAllocString(pVDesc->HelpString); if(pdwHelpStringContext) *pdwHelpStringContext=pVDesc->HelpStringContext; @@ -7326,23 +7587,10 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( CUSTDATA *pCustData) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData; - int i; - TRACE("(%p) returning %d items\n", This, This->ctCustData); + TRACE("%p %p\n", This, pCustData); - pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM)); - if(pCustData->prgCustData ){ - pCustData->cCustData=This->ctCustData; - for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){ - pCustData->prgCustData[i].guid=pCData->guid; - VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data); - } - }else{ - ERR(" OUT OF MEMORY!\n"); - return E_OUTOFMEMORY; - } - return S_OK; + return TLB_copy_all_custdata(&This->custdata_list, pCustData); } /* ITypeInfo2::GetAllFuncCustData @@ -7356,31 +7604,14 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( CUSTDATA *pCustData) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData; - TLBFuncDesc * pFDesc; - UINT i; - TRACE("(%p) index %d\n", This, index); - for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, - pFDesc=pFDesc->next) - ; - if(pFDesc){ - pCustData->prgCustData = - TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM)); - if(pCustData->prgCustData ){ - pCustData->cCustData=pFDesc->ctCustData; - for(i=0, pCData=pFDesc->pCustData; pCData; i++, - pCData = pCData->next){ - pCustData->prgCustData[i].guid=pCData->guid; - VariantCopy(& pCustData->prgCustData[i].varValue, - & pCData->data); - } - }else{ - ERR(" OUT OF MEMORY!\n"); - return E_OUTOFMEMORY; - } - return S_OK; - } - return TYPE_E_ELEMENTNOTFOUND; + TLBFuncDesc *pFDesc = &This->funcdescs[index]; + + TRACE("%p %u %p\n", This, index, pCustData); + + if(index >= This->TypeAttr.cFuncs) + return TYPE_E_ELEMENTNOTFOUND; + + return TLB_copy_all_custdata(&pFDesc->custdata_list, pCustData); } /* ITypeInfo2::GetAllParamCustData @@ -7392,32 +7623,17 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface, UINT indexFunc, UINT indexParam, CUSTDATA *pCustData) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData=NULL; - TLBFuncDesc * pFDesc; - UINT i; - TRACE("(%p) index %d\n", This, indexFunc); - for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++, - pFDesc=pFDesc->next) - ; - if(pFDesc && indexParamfuncdesc.cParams){ - pCustData->prgCustData = - TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData * - sizeof(CUSTDATAITEM)); - if(pCustData->prgCustData ){ - pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData; - for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData; - pCData; i++, pCData = pCData->next){ - pCustData->prgCustData[i].guid=pCData->guid; - VariantCopy(& pCustData->prgCustData[i].varValue, - & pCData->data); - } - }else{ - ERR(" OUT OF MEMORY!\n"); - return E_OUTOFMEMORY; - } - return S_OK; - } - return TYPE_E_ELEMENTNOTFOUND; + TLBFuncDesc *pFDesc = &This->funcdescs[indexFunc]; + + TRACE("%p %u %u %p\n", This, indexFunc, indexParam, pCustData); + + if(indexFunc >= This->TypeAttr.cFuncs) + return TYPE_E_ELEMENTNOTFOUND; + + if(indexParam >= pFDesc->funcdesc.cParams) + return TYPE_E_ELEMENTNOTFOUND; + + return TLB_copy_all_custdata(&pFDesc->pParamDesc[indexParam].custdata_list, pCustData); } /* ITypeInfo2::GetAllVarCustData @@ -7429,31 +7645,14 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface, UINT index, CUSTDATA *pCustData) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData; - TLBVarDesc * pVDesc; - UINT i; - TRACE("(%p) index %d\n", This, index); - for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, - pVDesc=pVDesc->next) - ; - if(pVDesc){ - pCustData->prgCustData = - TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM)); - if(pCustData->prgCustData ){ - pCustData->cCustData=pVDesc->ctCustData; - for(i=0, pCData=pVDesc->pCustData; pCData; i++, - pCData = pCData->next){ - pCustData->prgCustData[i].guid=pCData->guid; - VariantCopy(& pCustData->prgCustData[i].varValue, - & pCData->data); - } - }else{ - ERR(" OUT OF MEMORY!\n"); - return E_OUTOFMEMORY; - } - return S_OK; - } - return TYPE_E_ELEMENTNOTFOUND; + TLBVarDesc * pVDesc = &This->vardescs[index]; + + TRACE("%p %u %p\n", This, index, pCustData); + + if(index >= This->TypeAttr.cVars) + return TYPE_E_ELEMENTNOTFOUND; + + return TLB_copy_all_custdata(&pVDesc->custdata_list, pCustData); } /* ITypeInfo2::GetAllImplCustData @@ -7467,31 +7666,14 @@ static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( CUSTDATA *pCustData) { ITypeInfoImpl *This = (ITypeInfoImpl *)iface; - TLBCustData *pCData; - TLBImplType * pRDesc; - UINT i; - TRACE("(%p) index %d\n", This, index); - for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, - pRDesc=pRDesc->next) - ; - if(pRDesc){ - pCustData->prgCustData = - TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM)); - if(pCustData->prgCustData ){ - pCustData->cCustData=pRDesc->ctCustData; - for(i=0, pCData=pRDesc->pCustData; pCData; i++, - pCData = pCData->next){ - pCustData->prgCustData[i].guid=pCData->guid; - VariantCopy(& pCustData->prgCustData[i].varValue, - & pCData->data); - } - }else{ - ERR(" OUT OF MEMORY!\n"); - return E_OUTOFMEMORY; - } - return S_OK; - } - return TYPE_E_ELEMENTNOTFOUND; + TLBImplType *pRDesc = &This->impltypes[index]; + + TRACE("%p %u %p\n", This, index, pCustData); + + if(index >= This->TypeAttr.cImplTypes) + return TYPE_E_ELEMENTNOTFOUND; + + return TLB_copy_all_custdata(&pRDesc->custdata_list, pCustData); } static const ITypeInfo2Vtbl tinfvt = @@ -7560,14 +7742,17 @@ HRESULT WINAPI CreateDispTypeInfo( ITypeInfoImpl *pTIClass, *pTIIface; ITypeLibImpl *pTypeLibImpl; unsigned int param, func; - TLBFuncDesc **ppFuncDesc; + TLBFuncDesc *pFuncDesc; TLBRefType *ref; TRACE("\n"); pTypeLibImpl = TypeLibImpl_Constructor(); if (!pTypeLibImpl) return E_FAIL; - pTIIface = (ITypeInfoImpl*)ITypeInfo_Constructor(); + pTypeLibImpl->TypeInfoCount = 2; + pTypeLibImpl->typeinfos = heap_alloc_zero(pTypeLibImpl->TypeInfoCount * sizeof(ITypeInfoImpl*)); + + pTIIface = pTypeLibImpl->typeinfos[0] = ITypeInfoImpl_Constructor(); pTIIface->pTypeLib = pTypeLibImpl; pTIIface->index = 0; pTIIface->Name = NULL; @@ -7585,49 +7770,43 @@ HRESULT WINAPI CreateDispTypeInfo( pTIIface->TypeAttr.cVars = 0; pTIIface->TypeAttr.wTypeFlags = 0; - ppFuncDesc = &pTIIface->funclist; + pTIIface->funcdescs = TLBFuncDesc_Constructor(pidata->cMembers); + pFuncDesc = pTIIface->funcdescs; for(func = 0; func < pidata->cMembers; func++) { METHODDATA *md = pidata->pmethdata + func; - *ppFuncDesc = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppFuncDesc)); - (*ppFuncDesc)->Name = SysAllocString(md->szName); - (*ppFuncDesc)->funcdesc.memid = md->dispid; - (*ppFuncDesc)->funcdesc.lprgscode = NULL; - (*ppFuncDesc)->funcdesc.funckind = FUNC_VIRTUAL; - (*ppFuncDesc)->funcdesc.invkind = md->wFlags; - (*ppFuncDesc)->funcdesc.callconv = md->cc; - (*ppFuncDesc)->funcdesc.cParams = md->cArgs; - (*ppFuncDesc)->funcdesc.cParamsOpt = 0; - (*ppFuncDesc)->funcdesc.oVft = md->iMeth * sizeof(void *); - (*ppFuncDesc)->funcdesc.cScodes = 0; - (*ppFuncDesc)->funcdesc.wFuncFlags = 0; - (*ppFuncDesc)->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn; - (*ppFuncDesc)->funcdesc.elemdescFunc.u.paramdesc.wParamFlags = PARAMFLAG_NONE; - (*ppFuncDesc)->funcdesc.elemdescFunc.u.paramdesc.pparamdescex = NULL; - (*ppFuncDesc)->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + pFuncDesc->Name = SysAllocString(md->szName); + pFuncDesc->funcdesc.memid = md->dispid; + pFuncDesc->funcdesc.lprgscode = NULL; + pFuncDesc->funcdesc.funckind = FUNC_VIRTUAL; + pFuncDesc->funcdesc.invkind = md->wFlags; + pFuncDesc->funcdesc.callconv = md->cc; + pFuncDesc->funcdesc.cParams = md->cArgs; + pFuncDesc->funcdesc.cParamsOpt = 0; + pFuncDesc->funcdesc.oVft = md->iMeth * sizeof(void *); + pFuncDesc->funcdesc.cScodes = 0; + pFuncDesc->funcdesc.wFuncFlags = 0; + pFuncDesc->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn; + pFuncDesc->funcdesc.elemdescFunc.u.paramdesc.wParamFlags = PARAMFLAG_NONE; + pFuncDesc->funcdesc.elemdescFunc.u.paramdesc.pparamdescex = NULL; + pFuncDesc->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, md->cArgs * sizeof(ELEMDESC)); - (*ppFuncDesc)->pParamDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - md->cArgs * sizeof(TLBParDesc)); + pFuncDesc->pParamDesc = TLBParDesc_Constructor(md->cArgs); for(param = 0; param < md->cArgs; param++) { - (*ppFuncDesc)->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt; - (*ppFuncDesc)->pParamDesc[param].Name = SysAllocString(md->ppdata[param].szName); + pFuncDesc->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt; + pFuncDesc->pParamDesc[param].Name = SysAllocString(md->ppdata[param].szName); } - (*ppFuncDesc)->helpcontext = 0; - (*ppFuncDesc)->HelpStringContext = 0; - (*ppFuncDesc)->HelpString = NULL; - (*ppFuncDesc)->Entry = NULL; - (*ppFuncDesc)->ctCustData = 0; - (*ppFuncDesc)->pCustData = NULL; - (*ppFuncDesc)->next = NULL; + pFuncDesc->helpcontext = 0; + pFuncDesc->HelpStringContext = 0; + pFuncDesc->HelpString = NULL; + pFuncDesc->Entry = NULL; + list_init(&pFuncDesc->custdata_list); pTIIface->TypeAttr.cFuncs++; - ppFuncDesc = &(*ppFuncDesc)->next; + ++pFuncDesc; } dump_TypeInfo(pTIIface); - pTypeLibImpl->pTypeInfo = pTIIface; - pTypeLibImpl->TypeInfoCount++; - - pTIClass = (ITypeInfoImpl*)ITypeInfo_Constructor(); + pTIClass = pTypeLibImpl->typeinfos[1] = ITypeInfoImpl_Constructor(); pTIClass->pTypeLib = pTypeLibImpl; pTIClass->index = 1; pTIClass->Name = NULL; @@ -7645,20 +7824,14 @@ HRESULT WINAPI CreateDispTypeInfo( pTIClass->TypeAttr.cVars = 0; pTIClass->TypeAttr.wTypeFlags = 0; - pTIClass->impltypelist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pTIClass->impltypelist)); - pTIClass->impltypelist->hRef = 0; + pTIClass->impltypes = TLBImplType_Constructor(1); - ref = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ref)); - ref->index = 0; - ref->reference = 0; + ref = heap_alloc_zero(sizeof(*ref)); ref->pImpTLInfo = TLB_REF_INTERNAL; list_add_head(&pTypeLibImpl->ref_list, &ref->entry); dump_TypeInfo(pTIClass); - pTIIface->next = pTIClass; - pTypeLibImpl->TypeInfoCount++; - *pptinfo = (ITypeInfo*)pTIClass; ITypeInfo_AddRef(*pptinfo); @@ -7701,7 +7874,8 @@ static HRESULT WINAPI ITypeComp_fnBind( ITypeInfoImpl *This = info_impl_from_ITypeComp(iface); const TLBFuncDesc *pFDesc; const TLBVarDesc *pVDesc; - HRESULT hr = S_OK; + HRESULT hr = DISP_E_MEMBERNOTFOUND; + UINT fdc; TRACE("(%p)->(%s, %x, 0x%x, %p, %p, %p)\n", This, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr); @@ -7709,7 +7883,8 @@ static HRESULT WINAPI ITypeComp_fnBind( pBindPtr->lpfuncdesc = NULL; *ppTInfo = NULL; - for(pFDesc = This->funclist; pFDesc; pFDesc = pFDesc->next) + for(fdc = 0; fdc < This->TypeAttr.cFuncs; ++fdc){ + pFDesc = &This->funcdescs[fdc]; if (!strcmpiW(pFDesc->Name, szName)) { if (!wFlags || (pFDesc->funcdesc.invkind & wFlags)) break; @@ -7717,8 +7892,9 @@ static HRESULT WINAPI ITypeComp_fnBind( /* name found, but wrong flags */ hr = TYPE_E_TYPEMISMATCH; } + } - if (pFDesc) + if (fdc < This->TypeAttr.cFuncs) { HRESULT hr = TLB_AllocAndInitFuncDesc( &pFDesc->funcdesc, @@ -7731,25 +7907,24 @@ static HRESULT WINAPI ITypeComp_fnBind( ITypeInfo_AddRef(*ppTInfo); return S_OK; } else { - for(pVDesc = This->varlist; pVDesc; pVDesc = pVDesc->next) { - if (!strcmpiW(pVDesc->Name, szName)) { - HRESULT hr = TLB_AllocAndInitVarDesc(&pVDesc->vardesc, &pBindPtr->lpvardesc); - if (FAILED(hr)) - return hr; - *pDescKind = DESCKIND_VARDESC; - *ppTInfo = (ITypeInfo *)&This->lpVtbl; - ITypeInfo_AddRef(*ppTInfo); - return S_OK; - } + pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->TypeAttr.cVars, szName); + if(pVDesc){ + HRESULT hr = TLB_AllocAndInitVarDesc(&pVDesc->vardesc, &pBindPtr->lpvardesc); + if (FAILED(hr)) + return hr; + *pDescKind = DESCKIND_VARDESC; + *ppTInfo = (ITypeInfo *)&This->lpVtbl; + ITypeInfo_AddRef(*ppTInfo); + return S_OK; } } /* FIXME: search each inherited interface, not just the first */ - if (hr == DISP_E_MEMBERNOTFOUND && This->impltypelist) { + if (hr == DISP_E_MEMBERNOTFOUND && This->impltypes) { /* recursive search */ ITypeInfo *pTInfo; ITypeComp *pTComp; HRESULT hr; - hr=ITypeInfo_GetRefTypeInfo((ITypeInfo *)&This->lpVtbl, This->impltypelist->hRef, &pTInfo); + hr=ITypeInfo_GetRefTypeInfo((ITypeInfo *)&This->lpVtbl, This->impltypes[0].hRef, &pTInfo); if (SUCCEEDED(hr)) { hr = ITypeInfo_GetTypeComp(pTInfo,&pTComp); @@ -7763,6 +7938,8 @@ static HRESULT WINAPI ITypeComp_fnBind( } WARN("Could not search inherited interface!\n"); } + if (hr == DISP_E_MEMBERNOTFOUND) + hr = S_OK; TRACE("did not find member with name %s, flags 0x%x\n", debugstr_w(szName), wFlags); return hr; } diff --git a/reactos/dll/win32/oleaut32/typelib.h b/reactos/dll/win32/oleaut32/typelib.h index 058c6a2db8c..d6e752ad80b 100644 --- a/reactos/dll/win32/oleaut32/typelib.h +++ b/reactos/dll/win32/oleaut32/typelib.h @@ -52,8 +52,11 @@ * it is at the beginning of a type lib file * */ + +#define MSFT_SIGNATURE 0x5446534D /* "MSFT" */ + typedef struct tagMSFT_Header { -/*0x00*/INT magic1; /* 0x5446534D "MSFT" */ +/*0x00*/INT magic1; /* 0x5446534D "MSFT" */ INT magic2; /* 0x00010002 version nr? */ INT posguid; /* position of libid in guid table */ /* (should be, else -1) */ @@ -174,7 +177,7 @@ typedef struct tagMSFT_ImpInfo { /* function description data */ typedef struct { -/* INT recsize; record size including some xtra stuff */ + INT Info; /* record size including some extra stuff */ INT DataType; /* data type of the member, eg return of function */ INT Flags; /* something to do with attribute flags (LOWORD) */ #ifdef WORDS_BIGENDIAN @@ -199,19 +202,17 @@ typedef struct { INT16 nrargs; /* number of arguments (including optional ????) */ INT16 nroargs; /* nr of optional arguments */ #endif + /* optional attribute fields, the number of them is variable */ - INT OptAttr[1]; -/* -0* INT helpcontext; -1* INT oHelpString; -2* INT oEntry; // either offset in string table or numeric as it is // -3* INT res9; // unknown (-1) // -4* INT resA; // unknown (-1) // -5* INT HelpStringContext; - // these are controlled by a bit set in the FKCCIC field // -6* INT oCustData; // custom data for function // -7* INT oArgCustData[1]; // custom data per argument // -*/ + INT HelpContext; + INT oHelpString; + INT oEntry; /* either offset in string table or numeric as it is */ + INT res9; /* unknown (-1) */ + INT resA; /* unknown (-1) */ + INT HelpStringContext; + /* these are controlled by a bit set in the FKCCIC field */ + INT oCustData; /* custom data for function */ + INT oArgCustData[1]; /* custom data per argument */ } MSFT_FuncRecord; /* after this may follow an array with default value pointers if the @@ -228,7 +229,7 @@ typedef struct { /* Variable description data */ typedef struct { -/* INT recsize; // record size including some xtra stuff */ + INT Info; /* record size including some extra stuff */ INT DataType; /* data type of the variable */ INT Flags; /* VarFlags (LOWORD) */ #ifdef WORDS_BIGENDIAN @@ -243,11 +244,10 @@ typedef struct { /* optional attribute fields, the number of them is variable */ /* controlled by record length */ INT HelpContext; - INT oHelpString; + INT HelpString; INT res9; /* unknown (-1) */ INT oCustData; /* custom data for variable */ INT HelpStringContext; - } MSFT_VarRecord; /* Structure of the reference data */ @@ -596,6 +596,12 @@ WORD typeofarray #include "poppack.h" +/* heap allocation helpers */ +extern void* heap_alloc_zero(unsigned size); +extern void* heap_alloc(unsigned size); +extern void* heap_realloc(void *ptr, unsigned size); +extern void heap_free(void *ptr); + HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ); extern DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args); diff --git a/reactos/dll/win32/oleaut32/typelib2.c b/reactos/dll/win32/oleaut32/typelib2.c index 1333b68eaad..689d9afca61 100644 --- a/reactos/dll/win32/oleaut32/typelib2.c +++ b/reactos/dll/win32/oleaut32/typelib2.c @@ -118,15 +118,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(typelib2); /*================== Implementation Structures ===================================*/ /* Used for storing cyclic list. Tail address is kept */ -enum tagCyclicListElementType { +typedef enum tagCyclicListElementType { + CyclicListSentinel, CyclicListFunc, CyclicListVar -}; +} CyclicListElementType; typedef struct tagCyclicList { struct tagCyclicList *next; int indice; int name; - enum tagCyclicListElementType type; + CyclicListElementType type; union { int val; @@ -162,17 +163,16 @@ typedef struct tagMSFT_ImpFile { typedef struct tagICreateTypeLib2Impl { - const ICreateTypeLib2Vtbl *lpVtbl; - const ITypeLib2Vtbl *lpVtblTypeLib2; - + ICreateTypeLib2 ICreateTypeLib2_iface; + ITypeLib2 ITypeLib2_iface; LONG ref; - WCHAR *filename; + BSTR filename; MSFT_Header typelib_header; INT helpStringDll; MSFT_pSeg typelib_segdir[MSFT_SEG_MAX]; - char *typelib_segment_data[MSFT_SEG_MAX]; + unsigned char *typelib_segment_data[MSFT_SEG_MAX]; int typelib_segment_block_length[MSFT_SEG_MAX]; int typelib_guids; /* Number of defined typelib guids */ @@ -187,15 +187,20 @@ typedef struct tagICreateTypeLib2Impl struct tagICreateTypeInfo2Impl *last_typeinfo; } ICreateTypeLib2Impl; -static inline ICreateTypeLib2Impl *impl_from_ITypeLib2( ITypeLib2 *iface ) +static inline ICreateTypeLib2Impl *impl_from_ICreateTypeLib2(ICreateTypeLib2 *iface) { - return (ICreateTypeLib2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeLib2Impl, lpVtblTypeLib2)); + return CONTAINING_RECORD(iface, ICreateTypeLib2Impl, ICreateTypeLib2_iface); +} + +static inline ICreateTypeLib2Impl *impl_from_ITypeLib2(ITypeLib2 *iface) +{ + return CONTAINING_RECORD(iface, ICreateTypeLib2Impl, ITypeLib2_iface); } typedef struct tagICreateTypeInfo2Impl { - const ICreateTypeInfo2Vtbl *lpVtbl; - const ITypeInfo2Vtbl *lpVtblTypeInfo2; + ICreateTypeInfo2 ICreateTypeInfo2_iface; + ITypeInfo2 ITypeInfo2_iface; LONG ref; @@ -211,16 +216,73 @@ typedef struct tagICreateTypeInfo2Impl struct tagICreateTypeInfo2Impl *dual; } ICreateTypeInfo2Impl; +static inline ICreateTypeInfo2Impl *impl_from_ICreateTypeInfo2(ICreateTypeInfo2 *iface) +{ + return CONTAINING_RECORD(iface, ICreateTypeInfo2Impl, ICreateTypeInfo2_iface); +} + static inline ICreateTypeInfo2Impl *impl_from_ITypeInfo2( ITypeInfo2 *iface ) { - return (ICreateTypeInfo2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeInfo2Impl, lpVtblTypeInfo2)); + return CONTAINING_RECORD(iface, ICreateTypeInfo2Impl, ITypeInfo2_iface); } static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface); +static CyclicList *alloc_cyclic_list_item(CyclicListElementType type) +{ + CyclicList *ret = heap_alloc_zero(sizeof(CyclicList)); + if (!ret) + return NULL; + ret->type = type; + return ret; +} /*================== Internal functions ===================================*/ +static inline UINT cti2_get_var_count(const MSFT_TypeInfoBase *typeinfo) +{ + return typeinfo->cElement >> 16; +} + +static inline UINT cti2_get_func_count(const MSFT_TypeInfoBase *typeinfo) +{ + return typeinfo->cElement & 0xFFFF; +} + +static inline INT ctl2_get_record_size(const CyclicList *iter) +{ + return iter->u.data[0] & 0xFFFF; +} + +static void ctl2_update_var_size(const ICreateTypeInfo2Impl *This, CyclicList *var, int size) +{ + int old = ctl2_get_record_size(var), i; + + if (old >= size) return; + + /* initialize fields included in size but currently unused */ + for (i = old/sizeof(int); i < (size/sizeof(int) - 1); i++) + { + /* HelpContext/HelpStringContext being 0 means it's not set */ + var->u.data[i] = (i == 5 || i == 9) ? 0 : -1; + } + + var->u.data[0] += size - old; + This->typedata->next->u.val += size - old; +} + +/* NOTE: entry always assumed to be a function */ +static inline INVOKEKIND ctl2_get_invokekind(const CyclicList *func) +{ + /* INVOKEKIND uses bit flags up to 8 */ + return (func->u.data[4] >> 3) & 0xF; +} + +static inline SYSKIND ctl2_get_syskind(const ICreateTypeLib2Impl *This) +{ + return This->typelib_header.varflags & 0xF; +} + /**************************************************************************** * ctl2_init_header * @@ -229,7 +291,7 @@ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface); static void ctl2_init_header( ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */ { - This->typelib_header.magic1 = 0x5446534d; + This->typelib_header.magic1 = MSFT_SIGNATURE; This->typelib_header.magic2 = 0x00010002; This->typelib_header.posguid = -1; This->typelib_header.lcid = This->typelib_header.lcid2 = GetUserDefaultLCID(); @@ -393,7 +455,7 @@ static int ctl2_encode_name( converted_name[1] = 0x00; - value = LHashValOfNameSysA(This->typelib_header.varflags & 0x0f, This->typelib_header.lcid, converted_name + 4); + value = LHashValOfNameSysA(ctl2_get_syskind(This), This->typelib_header.lcid, converted_name + 4); converted_name[2] = value; converted_name[3] = value >> 8; @@ -467,7 +529,7 @@ static int ctl2_encode_string( * Converts string stored in typelib data to unicode. */ static void ctl2_decode_string( - char *data, /* [I] String to be decoded */ + unsigned char *data,/* [I] String to be decoded */ WCHAR **string) /* [O] Decoded string */ { int i, length; @@ -510,16 +572,16 @@ static int ctl2_alloc_segment( if (!block_size) block_size = 0x2000; This->typelib_segment_block_length[segment] = block_size; - This->typelib_segment_data[segment] = HeapAlloc(GetProcessHeap(), 0, block_size); + This->typelib_segment_data[segment] = heap_alloc(block_size); if (!This->typelib_segment_data[segment]) return -1; memset(This->typelib_segment_data[segment], 0x57, block_size); } while ((This->typelib_segdir[segment].length + size) > This->typelib_segment_block_length[segment]) { - char *block; + unsigned char *block; block_size = This->typelib_segment_block_length[segment]; - block = HeapReAlloc(GetProcessHeap(), 0, This->typelib_segment_data[segment], block_size << 1); + block = heap_realloc(This->typelib_segment_data[segment], block_size << 1); if (!block) return -1; if (segment == MSFT_SEG_TYPEINFO) { @@ -527,7 +589,7 @@ static int ctl2_alloc_segment( ICreateTypeInfo2Impl *typeinfo; for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - This->typelib_segment_data[segment]]; + typeinfo->typeinfo = (void *)&block[((unsigned char *)typeinfo->typeinfo) - This->typelib_segment_data[segment]]; } } @@ -692,14 +754,14 @@ static int ctl2_alloc_string( { int length; int offset; - char *string_space; + unsigned char *string_space; char *encoded_string; length = ctl2_encode_string(This, string, &encoded_string); for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_STRING].length; - offset += ((((This->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff) - | (This->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) { + offset += (((This->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) | + This->typelib_segment_data[MSFT_SEG_STRING][offset + 0]) + 5) & ~3) { if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset; } @@ -779,8 +841,8 @@ static int ctl2_alloc_importfile( encoded_string[0] |= 1; for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_IMPORTFILES].length; - offset += ((((((This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff00) - | (This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 5) & 0xfffc) + 0xc) { + offset += (((((This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) | + This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc]) >> 2) + 5) & 0xfffc) + 0xc) { if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset; } @@ -837,11 +899,13 @@ static HRESULT ctl2_encode_variant( mask = 0x3ffffff; if(V_UI4(&v)>0x3ffffff) break; + /* fall through */ case VT_I1: case VT_UI1: case VT_BOOL: - if(!mask) - mask = 0xff; + if(!mask) + mask = 0xff; + /* fall through */ case VT_I2: case VT_UI2: if(!mask) @@ -880,7 +944,7 @@ static HRESULT ctl2_encode_variant( case VT_BSTR: { /* Construct the data */ int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3; - char *data = HeapAlloc(GetProcessHeap(), 0, len); + char *data = heap_alloc(len); if(!data) return E_OUTOFMEMORY; @@ -900,19 +964,19 @@ static HRESULT ctl2_encode_variant( /* Check if the data was already allocated */ for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4) if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) { - HeapFree(GetProcessHeap(), 0, data); + heap_free(data); return S_OK; } /* Allocate the data */ *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0); if(*encoded_value == -1) { - HeapFree(GetProcessHeap(), 0, data); + heap_free(data); return E_OUTOFMEMORY; } memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len); - HeapFree(GetProcessHeap(), 0, data); + heap_free(data); return S_OK; } default: @@ -921,6 +985,84 @@ static HRESULT ctl2_encode_variant( } } +static int ctl2_find_custdata( + ICreateTypeLib2Impl *This, + REFGUID guid, + int offset) +{ + while (offset != -1) { + MSFT_CDGuid *cdentry = + (MSFT_CDGuid *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset]; + MSFT_GuidEntry *guidentry = + (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][cdentry->GuidOffset]; + + if (IsEqualGUID(guidentry, guid)) + return offset; + + offset = cdentry->next; + } + + return -1; +} + +/**************************************************************************** + * ctl2_decode_variant + * + * Decodes a variant + * + * RETURNS + * + * Success: S_OK + * Failure: Error code from winerror.h + */ +static HRESULT ctl2_decode_variant( + ICreateTypeLib2Impl *This, /* [I] The typelib that contains the variant */ + int data_offs, /* [I] Offset within the data array, or the encoded value itself */ + VARIANT *value) /* [O] Decoded value */ +{ + unsigned char *encoded_data; + VARTYPE type; + + if (data_offs & 0x80000000) { + /* data_offs contains the encoded value */ + V_VT(value) = (data_offs & ~0x80000000) >> 26; + V_UI4(value) = data_offs & ~0xFF000000; + return S_OK; + } + + encoded_data = &This->typelib_segment_data[MSFT_SEG_CUSTDATA][data_offs]; + type = *encoded_data; + + switch(type) { + case VT_I4: + case VT_R4: + case VT_UI4: + case VT_INT: + case VT_UINT: + case VT_HRESULT: + case VT_PTR: { + V_VT(value) = type; + V_UI4(value) = *(unsigned*)(encoded_data + 2); + return S_OK; + } + case VT_BSTR: { + unsigned len, i; + + len = *(unsigned*)(encoded_data + 2); + + V_VT(value) = type; + V_BSTR(value) = SysAllocStringByteLen(NULL, len * sizeof(OLECHAR)); + for (i = 0; i < len; ++i) + V_BSTR(value)[i] = *(encoded_data + 6 + i); + + return S_OK; + } + default: + FIXME("Don't yet have decoder for this VARTYPE: %u\n", type); + return E_NOTIMPL; + } +} + /**************************************************************************** * ctl2_set_custdata * @@ -943,6 +1085,7 @@ static HRESULT ctl2_set_custdata( int guidoffset; int custoffset; int *custdata; + BOOL new_segment = FALSE; switch(V_VT(pVarVal)) { @@ -971,14 +1114,21 @@ static HRESULT ctl2_set_custdata( if (status) return status; - custoffset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATAGUID, 12, 0); - if (custoffset == -1) return E_OUTOFMEMORY; + custoffset = ctl2_find_custdata(This, guid, *offset); + if (custoffset == -1) { + custoffset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATAGUID, 12, 0); + if (custoffset == -1) + return E_OUTOFMEMORY; + new_segment = TRUE; + } custdata = (int *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset]; custdata[0] = guidoffset; custdata[1] = dataoffset; - custdata[2] = *offset; - *offset = custoffset; + if (new_segment) { + custdata[2] = *offset; + *offset = custoffset; + } return S_OK; } @@ -1028,7 +1178,7 @@ static int ctl2_encode_typedesc( case VT_INT: *encoded_tdesc = 0x80000000 | (VT_I4 << 16) | VT_INT; - if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) { + if (ctl2_get_syskind(This) == SYS_WIN16) { *width = 2; *alignment = 2; } else { @@ -1039,7 +1189,7 @@ static int ctl2_encode_typedesc( case VT_UINT: *encoded_tdesc = 0x80000000 | (VT_UI4 << 16) | VT_UINT; - if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) { + if (ctl2_get_syskind(This) == SYS_WIN16) { *width = 2; *alignment = 2; } else { @@ -1109,7 +1259,7 @@ static int ctl2_encode_typedesc( mix_field = typedata[0]>>16; break; default: - mix_field = 0x7fff; + mix_field = ((typedata[0] >> 16) == 0x7fff) ? 0x7fff : 0x7ffe; break; } } @@ -1214,6 +1364,82 @@ static int ctl2_encode_typedesc( return 0; } +/**************************************************************************** + * ctl2_decode_typedesc + * + * Decodes a type description from an ICreateTypeLib2Impl. + * + * RETURNS + * + * Success: S_OK. + * Failure: HRESULT error code. + */ +static HRESULT ctl2_decode_typedesc( + ICreateTypeLib2Impl *This, /* [I] The type library from which to decode the TYPEDESC. */ + int encoded_tdesc, /* [I] The encoded type description. */ + TYPEDESC *tdesc) /* [O] The decoded type description. */ +{ + int *typedata, i; + HRESULT hres; + + if (encoded_tdesc & 0x80000000) { + tdesc->vt = encoded_tdesc & VT_TYPEMASK; + tdesc->u.lptdesc = NULL; + return S_OK; + } + + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][encoded_tdesc]; + + tdesc->vt = typedata[0] & 0xFFFF; + + switch(tdesc->vt) { + case VT_PTR: + case VT_SAFEARRAY: + tdesc->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC)); + if (!tdesc->u.lptdesc) + return E_OUTOFMEMORY; + + hres = ctl2_decode_typedesc(This, typedata[1], tdesc->u.lptdesc); + if (FAILED(hres)) { + heap_free(tdesc->u.lptdesc); + return hres; + } + + return S_OK; + + case VT_CARRAY: { + int arrayoffset, *arraydata, num_dims; + + arrayoffset = typedata[1]; + arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; + num_dims = arraydata[1] & 0xFFFF; + + tdesc->u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC) + sizeof(SAFEARRAYBOUND) * (num_dims - 1)); + if (!tdesc->u.lpadesc) + return E_OUTOFMEMORY; + + hres = ctl2_decode_typedesc(This, arraydata[0], &tdesc->u.lpadesc->tdescElem); + if (FAILED(hres)) { + heap_free(tdesc->u.lpadesc); + return E_OUTOFMEMORY; + } + + for (i = 0; i < num_dims; ++i) { + tdesc->u.lpadesc->rgbounds[i].cElements = arraydata[2 + i * 2]; + tdesc->u.lpadesc->rgbounds[i].lLbound = arraydata[3 + i * 2]; + } + + return S_OK; + } + case VT_USERDEFINED: + tdesc->u.hreftype = typedata[1]; + return S_OK; + default: + FIXME("unable to decode typedesc (%08x): unknown VT: %d\n", encoded_tdesc, tdesc->vt); + return E_NOTIMPL; + } +} + /**************************************************************************** * ctl2_find_nth_reference * @@ -1261,8 +1487,8 @@ static HRESULT ctl2_find_typeinfo_from_offset( for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { if (typeinfo->typeinfo == typeinfodata) { - *ppTinfo = (ITypeInfo *)&typeinfo->lpVtblTypeInfo2; - ITypeInfo2_AddRef(*ppTinfo); + *ppTinfo = (ITypeInfo *)&typeinfo->ITypeInfo2_iface; + ITypeInfo_AddRef(*ppTinfo); return S_OK; } } @@ -1295,7 +1521,7 @@ static INT funcrecord_reallochdr(INT **typedata, int need) if (hdr >= need) return 0; - *typedata = HeapReAlloc(GetProcessHeap(), 0, *typedata, need + tail); + *typedata = heap_realloc(*typedata, need + tail); if (!*typedata) return -1; @@ -1340,14 +1566,13 @@ static INT funcrecord_reallochdr(INT **typedata, int need) /****************************************************************************** * ICreateTypeInfo2_QueryInterface {OLEAUT32} * - * See IUnknown_QueryInterface. */ static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface( ICreateTypeInfo2 * iface, REFIID riid, VOID **ppvObject) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); @@ -1359,7 +1584,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface( *ppvObject = This; } else if (IsEqualIID(riid, &IID_ITypeInfo) || IsEqualIID(riid, &IID_ITypeInfo2)) { - *ppvObject = &This->lpVtblTypeInfo2; + *ppvObject = &This->ITypeInfo2_iface; } if(*ppvObject) @@ -1374,37 +1599,33 @@ static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface( /****************************************************************************** * ICreateTypeInfo2_AddRef {OLEAUT32} - * - * See IUnknown_AddRef. */ static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p)->ref was %u\n",This, ref - 1); if(ref==1 && This->typelib) - ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This->typelib); + ICreateTypeLib2_AddRef(&This->typelib->ICreateTypeLib2_iface); return ref; } /****************************************************************************** * ICreateTypeInfo2_Release {OLEAUT32} - * - * See IUnknown_Release. */ static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->(%u)\n",This, ref); if (!ref) { if (This->typelib) { - ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib); + ICreateTypeLib2_fnRelease(&This->typelib->ICreateTypeLib2_iface); /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */ /* This->typelib = NULL; */ } @@ -1420,12 +1641,10 @@ static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface) /****************************************************************************** * ICreateTypeInfo2_SetGuid {OLEAUT32} - * - * See ICreateTypeInfo_SetGuid. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); MSFT_GuidEntry guidentry; int offset; @@ -1451,12 +1670,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUI /****************************************************************************** * ICreateTypeInfo2_SetTypeFlags {OLEAUT32} - * - * See ICreateTypeInfo_SetTypeFlags. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT uTypeFlags) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); TRACE("(%p,0x%x)\n", iface, uTypeFlags); @@ -1466,7 +1683,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U This->typeinfo->typekind |= TKIND_DISPATCH; if(!This->dual) { - This->dual = HeapAlloc(GetProcessHeap(), 0, sizeof(ICreateTypeInfo2Impl)); + This->dual = heap_alloc(sizeof(ICreateTypeInfo2Impl)); if(!This->dual) return E_OUTOFMEMORY; @@ -1491,7 +1708,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U iter->next_typeinfo = This->dual; } } else - iface = (ICreateTypeInfo2*)&This->dual->lpVtbl; + iface = &This->dual->ICreateTypeInfo2_iface; } if (uTypeFlags & (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL)) { @@ -1522,14 +1739,12 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U /****************************************************************************** * ICreateTypeInfo2_SetDocString {OLEAUT32} - * - * See ICreateTypeInfo_SetDocString. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString( ICreateTypeInfo2* iface, LPOLESTR pStrDoc) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); int offset; @@ -1545,14 +1760,12 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString( /****************************************************************************** * ICreateTypeInfo2_SetHelpContext {OLEAUT32} - * - * See ICreateTypeInfo_SetHelpContext. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext( ICreateTypeInfo2* iface, DWORD dwHelpContext) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); TRACE("(%p,%d)\n", iface, dwHelpContext); @@ -1563,15 +1776,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext( /****************************************************************************** * ICreateTypeInfo2_SetVersion {OLEAUT32} - * - * See ICreateTypeInfo_SetVersion. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion( ICreateTypeInfo2* iface, WORD wMajorVerNum, WORD wMinorVerNum) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum); @@ -1581,15 +1792,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion( /****************************************************************************** * ICreateTypeInfo2_AddRefTypeInfo {OLEAUT32} - * - * See ICreateTypeInfo_AddRefTypeInfo. */ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( ICreateTypeInfo2* iface, ITypeInfo* pTInfo, HREFTYPE* phRefType) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); ITypeLib *container; UINT index; @@ -1611,7 +1820,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( return res; } - if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) { + if (container == (ITypeLib *)&This->typelib->ITypeLib2_iface) { /* Process locally defined TypeInfo */ *phRefType = This->typelib->typelib_typeinfo_offsets[index]; } else { @@ -1705,15 +1914,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( /****************************************************************************** * ICreateTypeInfo2_AddFuncDesc {OLEAUT32} - * - * See ICreateTypeInfo_AddFuncDesc. */ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( ICreateTypeInfo2* iface, UINT index, FUNCDESC* pFuncDesc) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); CyclicList *iter, *insert; int *typedata; @@ -1749,7 +1956,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( return TYPE_E_BADMODULEKIND; } - if(This->typeinfo->cElementtypeinfo) < index) return TYPE_E_ELEMENTNOTFOUND; if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && @@ -1765,30 +1972,30 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( } if (!This->typedata) { - This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + This->typedata = alloc_cyclic_list_item(CyclicListSentinel); if(!This->typedata) return E_OUTOFMEMORY; This->typedata->next = This->typedata; - This->typedata->u.val = 0; if(This->dual) This->dual->typedata = This->typedata; } /* allocate type data space for us */ - insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + insert = alloc_cyclic_list_item(CyclicListFunc); if(!insert) return E_OUTOFMEMORY; - insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int)*6+sizeof(int)*(num_defaults?4:3)*pFuncDesc->cParams); + insert->u.data = heap_alloc(FIELD_OFFSET(MSFT_FuncRecord, HelpContext) + + sizeof(int)*(num_defaults?4:3)*pFuncDesc->cParams); if(!insert->u.data) { - HeapFree(GetProcessHeap(), 0, insert); + heap_free(insert); return E_OUTOFMEMORY; } /* fill out the basic type information */ typedata = insert->u.data; - typedata[0] = 0x18 + pFuncDesc->cParams*(num_defaults?16:12); + typedata[0] = FIELD_OFFSET(MSFT_FuncRecord, HelpContext) + pFuncDesc->cParams*(num_defaults?16:12); ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size); typedata[2] = pFuncDesc->wFuncFlags; typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | (unsigned short)(pFuncDesc->oVft?pFuncDesc->oVft+1:0); @@ -1811,8 +2018,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( pFuncDesc->lprgelemdescParam[i].tdesc.vt); if(FAILED(hres)) { - HeapFree(GetProcessHeap(), 0, insert->u.data); - HeapFree(GetProcessHeap(), 0, insert); + heap_free(insert->u.data); + heap_free(insert); return hres; } } else @@ -1833,10 +2040,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( /* update the index data */ insert->indice = pFuncDesc->memid; insert->name = -1; - insert->type = CyclicListFunc; /* insert type data to list */ - if(index == This->typeinfo->cElement) { + if(index == cti2_get_func_count(This->typeinfo)) { insert->next = This->typedata->next; This->typedata->next = insert; This->typedata = insert; @@ -1853,7 +2059,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( } /* update type data size */ - This->typedata->next->u.val += 0x18 + pFuncDesc->cParams*(num_defaults?16:12); + This->typedata->next->u.val += FIELD_OFFSET(MSFT_FuncRecord, HelpContext) + pFuncDesc->cParams*(num_defaults?16:12); /* Increment the number of function elements */ This->typeinfo->cElement += 1; @@ -1863,15 +2069,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( /****************************************************************************** * ICreateTypeInfo2_AddImplType {OLEAUT32} - * - * See ICreateTypeInfo_AddImplType. */ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType( ICreateTypeInfo2* iface, UINT index, HREFTYPE hRefType) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); TRACE("(%p,%d,%d)\n", iface, index, hRefType); @@ -1932,15 +2136,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType( /****************************************************************************** * ICreateTypeInfo2_SetImplTypeFlags {OLEAUT32} - * - * See ICreateTypeInfo_SetImplTypeFlags. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags( ICreateTypeInfo2* iface, UINT index, INT implTypeFlags) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); int offset; MSFT_RefRecord *ref; @@ -1961,14 +2163,12 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags( /****************************************************************************** * ICreateTypeInfo2_SetAlignment {OLEAUT32} - * - * See ICreateTypeInfo_SetAlignment. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment( ICreateTypeInfo2* iface, WORD cbAlignment) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); TRACE("(%p,%d)\n", iface, cbAlignment); @@ -2005,8 +2205,6 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment( /****************************************************************************** * ICreateTypeInfo2_SetSchema {OLEAUT32} - * - * See ICreateTypeInfo_SetSchema. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema( ICreateTypeInfo2* iface, @@ -2018,15 +2216,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema( /****************************************************************************** * ICreateTypeInfo2_AddVarDesc {OLEAUT32} - * - * See ICreateTypeInfo_AddVarDesc. */ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( ICreateTypeInfo2* iface, UINT index, VARDESC* pVarDesc) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); HRESULT status = S_OK; CyclicList *insert; @@ -2036,36 +2232,34 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( int var_type_size; int alignment; - TRACE("(%p,%d,%p), stub!\n", iface, index, pVarDesc); + TRACE("(%p,%d,%p)\n", iface, index, pVarDesc); TRACE("%d, %p, %d, {{%x, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst, pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt, pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags, pVarDesc->wVarFlags, pVarDesc->varkind); - if ((This->typeinfo->cElement >> 16) != index) { - TRACE("Out-of-order element.\n"); + if (cti2_get_var_count(This->typeinfo) != index) return TYPE_E_ELEMENTNOTFOUND; - } if (!This->typedata) { - This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + This->typedata = alloc_cyclic_list_item(CyclicListSentinel); if(!This->typedata) return E_OUTOFMEMORY; This->typedata->next = This->typedata; - This->typedata->u.val = 0; if(This->dual) This->dual->typedata = This->typedata; } - /* allocate type data space for us */ - insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList)); + insert = alloc_cyclic_list_item(CyclicListVar); if(!insert) return E_OUTOFMEMORY; - insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[5])); + + /* allocate whole structure, it's fixed size always */ + insert->u.data = heap_alloc(sizeof(MSFT_VarRecord)); if(!insert->u.data) { - HeapFree(GetProcessHeap(), 0, insert); + heap_free(insert); return E_OUTOFMEMORY; } @@ -2076,18 +2270,19 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( if(This->dual) This->dual->typedata = This->typedata; - This->typedata->next->u.val += 0x14; + This->typedata->next->u.val += FIELD_OFFSET(MSFT_VarRecord, HelpContext); typedata = This->typedata->u.data; /* fill out the basic type information */ - typedata[0] = 0x14 | (index << 16); + + /* no optional fields initially */ + typedata[0] = FIELD_OFFSET(MSFT_VarRecord, HelpContext) | (index << 16); typedata[2] = pVarDesc->wVarFlags; typedata[3] = (sizeof(VARDESC) << 16) | pVarDesc->varkind; /* update the index data */ insert->indice = 0x40000000 + index; insert->name = -1; - insert->type = CyclicListVar; /* figure out type widths and whatnot */ ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc, @@ -2144,26 +2339,24 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( /****************************************************************************** * ICreateTypeInfo2_SetFuncAndParamNames {OLEAUT32} - * - * See ICreateTypeInfo_SetFuncAndParamNames. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( ICreateTypeInfo2* iface, UINT index, - LPOLESTR* rgszNames, + LPOLESTR* names, UINT cNames) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; - CyclicList *iter = NULL, *iter2; - int offset, len, i=0; - char *namedata; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); + CyclicList *iter, *iter2; + int offset, len, i; + unsigned char *namedata; - TRACE("(%p %d %p %d)\n", iface, index, rgszNames, cNames); + TRACE("(%p %d %p %d)\n", This, index, names, cNames); - if(!rgszNames) + if(!names) return E_INVALIDARG; - if(index >= (This->typeinfo->cElement&0xFFFF) || !cNames) + if(index >= cti2_get_func_count(This->typeinfo) || cNames == 0) return TYPE_E_ELEMENTNOTFOUND; for(iter=This->typedata->next->next, i=0; /* empty */; iter=iter->next) @@ -2172,19 +2365,23 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( break; /* cNames == cParams for put or putref accessor, cParams+1 otherwise */ - if(cNames != iter->u.data[5] + ((iter->u.data[4]>>3)&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1)) + if(cNames != iter->u.data[5] + (ctl2_get_invokekind(iter) & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1)) return TYPE_E_ELEMENTNOTFOUND; - len = ctl2_encode_name(This->typelib, rgszNames[0], &namedata); + TRACE("function name %s\n", debugstr_w(names[0])); + len = ctl2_encode_name(This->typelib, names[0], (char**)&namedata); for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { - if(iter2->name!=-1 && !memcmp(namedata, - This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len)) { - /* getters/setters can have a same name */ + + int cmp = memcmp(namedata, This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len); + if (iter2->name != -1 && cmp == 0) { if (iter2->type == CyclicListFunc) { - INT inv1 = iter2->u.data[4] >> 3; - INT inv2 = iter->u.data[4] >> 3; - if (((inv1&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && (inv2&INVOKE_PROPERTYGET)) || - ((inv2&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && (inv1&INVOKE_PROPERTYGET))) + INVOKEKIND inv1 = ctl2_get_invokekind(iter); + INVOKEKIND inv2 = ctl2_get_invokekind(iter2); + + /* it's allowed to have PUT, PUTREF and GET methods with the same name */ + if ((inv1 != inv2) && + (inv1 & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF|INVOKE_PROPERTYGET)) && + (inv2 & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF|INVOKE_PROPERTYGET))) continue; } @@ -2192,7 +2389,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( } } - offset = ctl2_alloc_name(This->typelib, rgszNames[0]); + offset = ctl2_alloc_name(This->typelib, names[0]); if(offset == -1) return E_OUTOFMEMORY; @@ -2202,10 +2399,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( if (*((INT*)namedata) == -1) *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; - len = iter->u.data[0]/4 - iter->u.data[5]*3; + len = ctl2_get_record_size(iter)/4 - iter->u.data[5]*3; for (i = 1; i < cNames; i++) { - offset = ctl2_alloc_name(This->typelib, rgszNames[i]); + offset = ctl2_alloc_name(This->typelib, names[i]); iter->u.data[len + ((i-1)*3) + 1] = offset; } @@ -2214,25 +2411,21 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( /****************************************************************************** * ICreateTypeInfo2_SetVarName {OLEAUT32} - * - * See ICreateTypeInfo_SetVarName. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( ICreateTypeInfo2* iface, UINT index, LPOLESTR szName) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); CyclicList *iter; int offset, i; - char *namedata; + unsigned char *namedata; - TRACE("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szName)); + TRACE("(%p,%d,%s)\n", This, index, debugstr_w(szName)); - if ((This->typeinfo->cElement >> 16) <= index) { - TRACE("Out-of-order element.\n"); + if (cti2_get_var_count(This->typeinfo) <= index) return TYPE_E_ELEMENTNOTFOUND; - } offset = ctl2_alloc_name(This->typelib, szName); if (offset == -1) return E_OUTOFMEMORY; @@ -2257,14 +2450,12 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( /****************************************************************************** * ICreateTypeInfo2_SetTypeDescAlias {OLEAUT32} - * - * See ICreateTypeInfo_SetTypeDescAlias. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias( ICreateTypeInfo2* iface, TYPEDESC* pTDescAlias) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); int encoded_typedesc; int width; @@ -2287,8 +2478,6 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias( /****************************************************************************** * ICreateTypeInfo2_DefineFuncAsDllEntry {OLEAUT32} - * - * See ICreateTypeInfo_DefineFuncAsDllEntry. */ static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry( ICreateTypeInfo2* iface, @@ -2302,8 +2491,6 @@ static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry( /****************************************************************************** * ICreateTypeInfo2_SetFuncDocString {OLEAUT32} - * - * See ICreateTypeInfo_SetFuncDocString. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString( ICreateTypeInfo2* iface, @@ -2316,42 +2503,56 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString( /****************************************************************************** * ICreateTypeInfo2_SetVarDocString {OLEAUT32} - * - * See ICreateTypeInfo_SetVarDocString. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString( ICreateTypeInfo2* iface, UINT index, - LPOLESTR szDocString) + LPOLESTR docstring) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); + CyclicList *iter; - FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString)); + TRACE("(%p,%d,%s)\n", This, index, debugstr_w(docstring)); - ctl2_alloc_string(This->typelib, szDocString); + if (!docstring) return E_INVALIDARG; - return E_OUTOFMEMORY; + if (cti2_get_var_count(This->typeinfo) <= index) + return TYPE_E_ELEMENTNOTFOUND; + + for (iter = This->typedata->next->next; iter != This->typedata->next; iter = iter->next) + if (iter->type == CyclicListVar) + { + if (index-- == 0) + { + int offset = ctl2_alloc_string(This->typelib, docstring); + + if (offset == -1) return E_OUTOFMEMORY; + ctl2_update_var_size(This, iter, FIELD_OFFSET(MSFT_VarRecord, res9)); + iter->u.data[6] = offset; + return S_OK; + } + } + + return TYPE_E_ELEMENTNOTFOUND; } /****************************************************************************** * ICreateTypeInfo2_SetFuncHelpContext {OLEAUT32} - * - * See ICreateTypeInfo_SetFuncHelpContext. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext( ICreateTypeInfo2* iface, UINT index, DWORD dwHelpContext) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); CyclicList *func; TRACE("(%p,%d,%d)\n", iface, index, dwHelpContext); - if(This->typeinfo->cElementtypeinfo) < index) return TYPE_E_ELEMENTNOTFOUND; - if(This->typeinfo->cElement == index && This->typedata->type == CyclicListFunc) + if(cti2_get_func_count(This->typeinfo) == index && This->typedata->type == CyclicListFunc) func = This->typedata; else for(func=This->typedata->next->next; func!=This->typedata; func=func->next) @@ -2369,22 +2570,36 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext( /****************************************************************************** * ICreateTypeInfo2_SetVarHelpContext {OLEAUT32} - * - * See ICreateTypeInfo_SetVarHelpContext. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext( ICreateTypeInfo2* iface, UINT index, - DWORD dwHelpContext) + DWORD context) { - FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpContext); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); + CyclicList *iter; + + TRACE("(%p,%d,%d)\n", This, index, context); + + if (cti2_get_var_count(This->typeinfo) <= index) + return TYPE_E_ELEMENTNOTFOUND; + + for (iter = This->typedata->next->next; iter != This->typedata->next; iter = iter->next) + if (iter->type == CyclicListVar) + { + if (index-- == 0) + { + ctl2_update_var_size(This, iter, FIELD_OFFSET(MSFT_VarRecord, HelpString)); + iter->u.data[5] = context; + return S_OK; + } + } + + return TYPE_E_ELEMENTNOTFOUND; } /****************************************************************************** * ICreateTypeInfo2_SetMops {OLEAUT32} - * - * See ICreateTypeInfo_SetMops. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetMops( ICreateTypeInfo2* iface, @@ -2397,8 +2612,6 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetMops( /****************************************************************************** * ICreateTypeInfo2_SetTypeIdldesc {OLEAUT32} - * - * See ICreateTypeInfo_SetTypeIdldesc. */ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc( ICreateTypeInfo2* iface, @@ -2410,23 +2623,21 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc( /****************************************************************************** * ICreateTypeInfo2_LayOut {OLEAUT32} - * - * See ICreateTypeInfo_LayOut. */ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( ICreateTypeInfo2* iface) { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); CyclicList *iter, *iter2, *last = NULL, **typedata; HREFTYPE hreftype; HRESULT hres; unsigned user_vft = 0; int i; - TRACE("(%p)\n", iface); + TRACE("(%p)\n", This); /* FIXME: LayOut should be run on all ImplTypes */ - if(This->typekind == TKIND_COCLASS) + if(This->typekind == TKIND_COCLASS || This->typekind == TKIND_ALIAS) return S_OK; /* Validate inheritance */ @@ -2452,7 +2663,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( ITypeInfo *cur, *next; TYPEATTR *typeattr; - hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next); + hres = ICreateTypeInfo2_QueryInterface(iface, &IID_ITypeInfo, (void**)&next); if(FAILED(hres)) return hres; @@ -2501,7 +2712,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( ITypeInfo *cur, *inherited; TYPEATTR *typeattr; - hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&cur); + hres = ICreateTypeInfo2_QueryInterface(iface, &IID_ITypeInfo, (void**)&cur); if(FAILED(hres)) return hres; @@ -2526,7 +2737,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( if(!This->typedata) return S_OK; - typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff)); + typedata = heap_alloc(sizeof(CyclicList*)*cti2_get_func_count(This->typeinfo)); if(!typedata) return E_OUTOFMEMORY; @@ -2547,13 +2758,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { if(iter == iter2) continue; if(iter2->indice == iter->indice) { - iter->indice = 0x5fffffff + This->typeinfo->cElement + i + (This->typeinfo->datatype2<<16); + iter->indice = 0x60000000 + This->typeinfo->cElement + (This->typeinfo->datatype2<<16); for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) { if(iter == iter2) continue; if(iter2->indice == iter->indice) { - HeapFree(GetProcessHeap(), 0, typedata); - return E_ACCESSDENIED; + ++iter->indice; + iter2 = This->typedata->next; } } @@ -2567,10 +2778,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( typedata[i] = iter; - iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16); + iter->u.data[0] = ctl2_get_record_size(iter) | (i<<16); if((iter->u.data[3]&1) != (user_vft&1)) { - HeapFree(GetProcessHeap(), 0, typedata); + heap_free(typedata); return TYPE_E_INVALIDID; } @@ -2579,7 +2790,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( user_vft = (iter->u.data[3]&0xffff); if((iter->u.data[3]&0xffff) < This->typeinfo->cbSizeVft) { - HeapFree(GetProcessHeap(), 0, typedata); + heap_free(typedata); return TYPE_E_INVALIDID; } } else if(This->typekind != TKIND_MODULE) { @@ -2608,18 +2819,17 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( if(user_vft) This->typeinfo->cbSizeVft = user_vft+3; - for(i=0; i<(This->typeinfo->cElement&0xffff); i++) { + for(i=0; i< cti2_get_func_count(This->typeinfo); i++) { if(typedata[i]->u.data[4]>>16 > i) { - int inv; + INVOKEKIND inv = ctl2_get_invokekind(typedata[i]); - inv = (typedata[i]->u.data[4]>>3) & 0xf; i = typedata[i]->u.data[4] >> 16; while(i > typedata[i]->u.data[4]>>16) { - int invkind = (typedata[i]->u.data[4]>>3) & 0xf; + INVOKEKIND invkind = ctl2_get_invokekind(typedata[i]); if(inv & invkind) { - HeapFree(GetProcessHeap(), 0, typedata); + heap_free(typedata); return TYPE_E_DUPLICATEID; } @@ -2628,13 +2838,13 @@ static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( } if(inv & INVOKE_FUNC) { - HeapFree(GetProcessHeap(), 0, typedata); + heap_free(typedata); return TYPE_E_INCONSISTENTPROPFUNCS; } } } - HeapFree(GetProcessHeap(), 0, typedata); + heap_free(typedata); return S_OK; } @@ -2746,7 +2956,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData( REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ VARIANT* pVarVal) /* [I] The custom data. */ { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); TRACE("(%p,%s,%p)!\n", iface, debugstr_guid(guid), pVarVal); @@ -2772,12 +2982,12 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData( REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ VARIANT* pVarVal) /* [I] The custom data. */ { - ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); CyclicList *iter; TRACE("(%p,%d,%s,%p)\n", iface, index, debugstr_guid(guid), pVarVal); - if(index >= (This->typeinfo->cElement&0xFFFF)) + if(index >= cti2_get_func_count(This->typeinfo)) return TYPE_E_ELEMENTNOTFOUND; for(iter=This->typedata->next->next; /* empty */; iter=iter->next) @@ -2866,10 +3076,15 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData( */ static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext( ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the help string context. */ - ULONG dwHelpStringContext) /* [I] The help string context. */ + ULONG helpcontext) /* [I] The help string context. */ { - FIXME("(%p,%d), stub!\n", iface, dwHelpStringContext); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = impl_from_ICreateTypeInfo2(iface); + + TRACE("(%p, %d)\n", iface, helpcontext); + + This->typelib->typelib_header.helpcontext = helpcontext; + + return S_OK; } /****************************************************************************** @@ -2944,44 +3159,36 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetName( /****************************************************************************** * ITypeInfo2_QueryInterface {OLEAUT32} - * - * See IUnknown_QueryInterface. */ static HRESULT WINAPI ITypeInfo2_fnQueryInterface(ITypeInfo2 * iface, REFIID riid, LPVOID * ppv) { ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - return ICreateTypeInfo2_QueryInterface((ICreateTypeInfo2 *)This, riid, ppv); + return ICreateTypeInfo2_QueryInterface(&This->ICreateTypeInfo2_iface, riid, ppv); } /****************************************************************************** * ITypeInfo2_AddRef {OLEAUT32} - * - * See IUnknown_AddRef. */ static ULONG WINAPI ITypeInfo2_fnAddRef(ITypeInfo2 * iface) { ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - return ICreateTypeInfo2_AddRef((ICreateTypeInfo2 *)This); + return ICreateTypeInfo2_AddRef(&This->ICreateTypeInfo2_iface); } /****************************************************************************** * ITypeInfo2_Release {OLEAUT32} - * - * See IUnknown_Release. */ static ULONG WINAPI ITypeInfo2_fnRelease(ITypeInfo2 * iface) { ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); - return ICreateTypeInfo2_Release((ICreateTypeInfo2 *)This); + return ICreateTypeInfo2_Release(&This->ICreateTypeInfo2_iface); } /****************************************************************************** * ITypeInfo2_GetTypeAttr {OLEAUT32} - * - * See ITypeInfo_GetTypeAttr. */ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( ITypeInfo2* iface, @@ -2995,11 +3202,11 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( if(!ppTypeAttr) return E_INVALIDARG; - hres = ICreateTypeInfo_LayOut((ICreateTypeInfo*)This); + hres = ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface); if(FAILED(hres)) return hres; - *ppTypeAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEATTR)); + *ppTypeAttr = heap_alloc_zero(sizeof(TYPEATTR)); if(!*ppTypeAttr) return E_OUTOFMEMORY; @@ -3013,16 +3220,16 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid; (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size; (*ppTypeAttr)->typekind = This->typekind; - (*ppTypeAttr)->cFuncs = This->typeinfo->cElement&0xffff; + (*ppTypeAttr)->cFuncs = cti2_get_func_count(This->typeinfo); if(This->typeinfo->flags&TYPEFLAG_FDUAL && This->typekind==TKIND_DISPATCH) - (*ppTypeAttr)->cFuncs += 7; - (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16; + (*ppTypeAttr)->cFuncs += sizeof(IDispatchVtbl)/sizeof(void*); + (*ppTypeAttr)->cVars = cti2_get_var_count(This->typeinfo); (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes; - (*ppTypeAttr)->cbSizeVft = This->typekind==TKIND_DISPATCH ? 7 * sizeof(void*) : This->typeinfo->cbSizeVft; + (*ppTypeAttr)->cbSizeVft = This->typekind == TKIND_DISPATCH ? sizeof(IDispatchVtbl) : This->typeinfo->cbSizeVft; (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f; (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags; - (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff; - (*ppTypeAttr)->wMinorVerNum = This->typeinfo->version>>16; + (*ppTypeAttr)->wMajorVerNum = LOWORD(This->typeinfo->version); + (*ppTypeAttr)->wMinorVerNum = HIWORD(This->typeinfo->version); if((*ppTypeAttr)->typekind == TKIND_ALIAS) FIXME("TKIND_ALIAS handling not implemented\n"); @@ -3032,8 +3239,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( /****************************************************************************** * ITypeInfo2_GetTypeComp {OLEAUT32} - * - * See ITypeInfo_GetTypeComp. */ static HRESULT WINAPI ITypeInfo2_fnGetTypeComp( ITypeInfo2* iface, @@ -3045,22 +3250,112 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeComp( /****************************************************************************** * ITypeInfo2_GetFuncDesc {OLEAUT32} - * - * See ITypeInfo_GetFuncDesc. */ static HRESULT WINAPI ITypeInfo2_fnGetFuncDesc( ITypeInfo2* iface, UINT index, FUNCDESC** ppFuncDesc) { - FIXME("(%p,%d,%p), stub!\n", iface, index, ppFuncDesc); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); + int i, *typedata, num_defaults = 0, hdr_len, tail, has_defaults; + CyclicList *desc; + HRESULT hres; + + TRACE("(%p,%d,%p), semi-stub\n", iface, index, ppFuncDesc); + + if (!ppFuncDesc) + return E_INVALIDARG; + + if (index >= cti2_get_func_count(This->typeinfo)) + return TYPE_E_ELEMENTNOTFOUND; + + hres = ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface); + if (FAILED(hres)) + return hres; + + desc = This->typedata->next; + for (i = index; i >= 0; ) { + desc = desc->next; + if (desc->type == CyclicListFunc) + --i; + } + + typedata = desc->u.data; + + *ppFuncDesc = heap_alloc_zero(sizeof(FUNCDESC)); + if (!*ppFuncDesc) + return E_OUTOFMEMORY; + + (*ppFuncDesc)->memid = desc->indice; + (*ppFuncDesc)->lprgscode = NULL; /* FIXME: Unimplemented */ + (*ppFuncDesc)->funckind = typedata[4] & 0x7; + (*ppFuncDesc)->invkind = (typedata[4] >> 3) & 0xF; + (*ppFuncDesc)->callconv = (typedata[4] >> 8) & 0xF; + (*ppFuncDesc)->cParams = typedata[5]; + (*ppFuncDesc)->cParamsOpt = 0; /* FIXME: Unimplemented*/ + (*ppFuncDesc)->oVft = typedata[3] & 0xFFFF; + if ((*ppFuncDesc)->oVft) + --(*ppFuncDesc)->oVft; + (*ppFuncDesc)->cScodes = 0; /* FIXME: Unimplemented*/ + hres = ctl2_decode_typedesc(This->typelib, typedata[1], + &(*ppFuncDesc)->elemdescFunc.tdesc); + if (FAILED(hres)) { + heap_free(*ppFuncDesc); + return hres; + } + (*ppFuncDesc)->wFuncFlags = typedata[2]; + + has_defaults = typedata[4] & 0x1000; + tail = typedata[5] * (has_defaults ? 16 : 12); + hdr_len = (ctl2_get_record_size(desc) - tail) / sizeof(int); + + if ((*ppFuncDesc)->cParams > 0) { + (*ppFuncDesc)->lprgelemdescParam = heap_alloc_zero((*ppFuncDesc)->cParams * sizeof(ELEMDESC)); + if (!(*ppFuncDesc)->lprgelemdescParam) { + heap_free(*ppFuncDesc); + return E_OUTOFMEMORY; + } + if (has_defaults) { + num_defaults = (*ppFuncDesc)->cParams; + + for (i = 0; i < num_defaults; ++i) { + if (typedata[hdr_len + i] != 0xFFFFFFFF) { + (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags |= PARAMFLAG_FHASDEFAULT; + + (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex = heap_alloc(sizeof(PARAMDESCEX)); + if (!(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex) { + ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc); + return E_OUTOFMEMORY; + } + + (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->cBytes = sizeof(PARAMDESCEX); + VariantInit(&(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); + hres = ctl2_decode_variant(This->typelib, typedata[hdr_len + i], + &(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); + if (FAILED(hres)) { + ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc); + return hres; + } + } + } + } + + for (i = 0; i < (*ppFuncDesc)->cParams; ++i) { + hres = ctl2_decode_typedesc(This->typelib, typedata[hdr_len + num_defaults + (i * 3)], + &((*ppFuncDesc)->lprgelemdescParam + i)->tdesc); + if (FAILED(hres)) { + ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc); + return hres; + } + (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags = typedata[hdr_len + num_defaults + (i * 3) + 2]; + } + } + + return S_OK; } /****************************************************************************** * ITypeInfo2_GetVarDesc {OLEAUT32} - * - * See ITypeInfo_GetVarDesc. */ static HRESULT WINAPI ITypeInfo2_fnGetVarDesc( ITypeInfo2* iface, @@ -3073,8 +3368,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetVarDesc( /****************************************************************************** * ITypeInfo2_GetNames {OLEAUT32} - * - * See ITypeInfo_GetNames. */ static HRESULT WINAPI ITypeInfo2_fnGetNames( ITypeInfo2* iface, @@ -3089,8 +3382,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetNames( /****************************************************************************** * ITypeInfo2_GetRefTypeOfImplType {OLEAUT32} - * - * See ITypeInfo_GetRefTypeOfImplType. */ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType( ITypeInfo2* iface, @@ -3113,7 +3404,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType( } if(This->typekind == TKIND_DISPATCH) - return ITypeInfo2_GetRefTypeOfImplType((ITypeInfo2*)&This->dual->lpVtblTypeInfo2, + return ITypeInfo2_GetRefTypeOfImplType(&This->dual->ITypeInfo2_iface, index, pRefType); } @@ -3136,8 +3427,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType( /****************************************************************************** * ITypeInfo2_GetImplTypeFlags {OLEAUT32} - * - * See ITypeInfo_GetImplTypeFlags. */ static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags( ITypeInfo2* iface, @@ -3172,8 +3461,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags( /****************************************************************************** * ITypeInfo2_GetIDsOfNames {OLEAUT32} - * - * See ITypeInfo_GetIDsOfNames. */ static HRESULT WINAPI ITypeInfo2_fnGetIDsOfNames( ITypeInfo2* iface, @@ -3187,8 +3474,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetIDsOfNames( /****************************************************************************** * ITypeInfo2_Invoke {OLEAUT32} - * - * See ITypeInfo_Invoke. */ static HRESULT WINAPI ITypeInfo2_fnInvoke( ITypeInfo2* iface, @@ -3206,8 +3491,6 @@ static HRESULT WINAPI ITypeInfo2_fnInvoke( /****************************************************************************** * ITypeInfo2_GetDocumentation {OLEAUT32} - * - * See ITypeInfo_GetDocumentation. */ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation( ITypeInfo2* iface, @@ -3236,7 +3519,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation( if (iter->indice == memid) { if (iter->type == CyclicListFunc) { const int *typedata = iter->u.data; - int size = typedata[0] - typedata[5]*(typedata[4]&0x1000?16:12); + int size = ctl2_get_record_size(iter) - typedata[5]*(typedata[4]&0x1000?16:12); nameoffset = iter->name; /* FIXME implement this once SetFuncDocString is implemented */ @@ -3289,7 +3572,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation( } if (pBstrHelpFile) { - status = ITypeLib_GetDocumentation((ITypeLib*)&This->typelib->lpVtblTypeLib2, + status = ITypeLib_GetDocumentation((ITypeLib*)&This->typelib->ITypeLib2_iface, -1, NULL, NULL, NULL, pBstrHelpFile); if (status) { if (pBstrName) SysFreeString(*pBstrName); @@ -3303,8 +3586,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation( /****************************************************************************** * ITypeInfo2_GetDllEntry {OLEAUT32} - * - * See ITypeInfo_GetDllEntry. */ static HRESULT WINAPI ITypeInfo2_fnGetDllEntry( ITypeInfo2* iface, @@ -3320,8 +3601,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetDllEntry( /****************************************************************************** * ITypeInfo2_GetRefTypeInfo {OLEAUT32} - * - * See ITypeInfo_GetRefTypeInfo. */ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( ITypeInfo2* iface, @@ -3336,7 +3615,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( return E_INVALIDARG; if(hRefType==-2 && This->dual) { - *ppTInfo = (ITypeInfo*)&This->dual->lpVtblTypeInfo2; + *ppTInfo = (ITypeInfo *)&This->dual->ITypeInfo2_iface; ITypeInfo_AddRef(*ppTInfo); return S_OK; } @@ -3356,7 +3635,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile]; guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid]; - ctl2_decode_string(impfile->filename, &filename); + ctl2_decode_string((unsigned char*)impfile->filename, &filename); hres = LoadTypeLib(filename, &tl); if(FAILED(hres)) @@ -3372,9 +3651,9 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) { if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) { - *ppTInfo = (ITypeInfo*)&iter->lpVtblTypeInfo2; + *ppTInfo = (ITypeInfo *)&iter->ITypeInfo2_iface; - ITypeLib_AddRef(*ppTInfo); + ITypeInfo_AddRef(*ppTInfo); return S_OK; } i++; @@ -3386,8 +3665,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( /****************************************************************************** * ITypeInfo2_AddressOfMember {OLEAUT32} - * - * See ITypeInfo_AddressOfMember. */ static HRESULT WINAPI ITypeInfo2_fnAddressOfMember( ITypeInfo2* iface, @@ -3401,8 +3678,6 @@ static HRESULT WINAPI ITypeInfo2_fnAddressOfMember( /****************************************************************************** * ITypeInfo2_CreateInstance {OLEAUT32} - * - * See ITypeInfo_CreateInstance. */ static HRESULT WINAPI ITypeInfo2_fnCreateInstance( ITypeInfo2* iface, @@ -3416,8 +3691,6 @@ static HRESULT WINAPI ITypeInfo2_fnCreateInstance( /****************************************************************************** * ITypeInfo2_GetMops {OLEAUT32} - * - * See ITypeInfo_GetMops. */ static HRESULT WINAPI ITypeInfo2_fnGetMops( ITypeInfo2* iface, @@ -3430,8 +3703,6 @@ static HRESULT WINAPI ITypeInfo2_fnGetMops( /****************************************************************************** * ITypeInfo2_GetContainingTypeLib {OLEAUT32} - * - * See ITypeInfo_GetContainingTypeLib. */ static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib( ITypeInfo2* iface, @@ -3441,18 +3712,29 @@ static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib( ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); TRACE("(%p,%p,%p)\n", iface, ppTLib, pIndex); - - *ppTLib = (ITypeLib *)&This->typelib->lpVtblTypeLib2; + + *ppTLib = (ITypeLib *)&This->typelib->ITypeLib2_iface; ICreateTypeLib_AddRef((ICreateTypeLib*)This->typelib); *pIndex = This->typeinfo->typekind >> 16; return S_OK; } +static void release_typedesc(TYPEDESC *tdesc) +{ + while (tdesc) { + TYPEDESC *next; + if (tdesc->vt == VT_USERDEFINED) + next = NULL; + else + next = tdesc->u.lptdesc; + heap_free(tdesc); + tdesc = next; + } +} + /****************************************************************************** * ITypeInfo2_ReleaseTypeAttr {OLEAUT32} - * - * See ITypeInfo_ReleaseTypeAttr. */ static void WINAPI ITypeInfo2_fnReleaseTypeAttr( ITypeInfo2* iface, @@ -3460,25 +3742,49 @@ static void WINAPI ITypeInfo2_fnReleaseTypeAttr( { TRACE("(%p,%p)\n", iface, pTypeAttr); - HeapFree(GetProcessHeap(), 0, pTypeAttr); + if (pTypeAttr->tdescAlias.vt != VT_USERDEFINED) + release_typedesc(pTypeAttr->tdescAlias.u.lptdesc); + + heap_free(pTypeAttr); } /****************************************************************************** * ITypeInfo2_ReleaseFuncDesc {OLEAUT32} - * - * See ITypeInfo_ReleaseFuncDesc. */ static void WINAPI ITypeInfo2_fnReleaseFuncDesc( ITypeInfo2* iface, FUNCDESC* pFuncDesc) { - FIXME("(%p,%p), stub!\n", iface, pFuncDesc); + int i; + + TRACE("(%p,%p)\n", iface, pFuncDesc); + + heap_free(pFuncDesc->lprgscode); + + if (pFuncDesc->lprgelemdescParam) { + for (i = 0; i < pFuncDesc->cParams; ++i) { + if (pFuncDesc->lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED) + release_typedesc(pFuncDesc->lprgelemdescParam[i].tdesc.u.lptdesc); + + if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex) + { + VariantClear(&pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); + heap_free(pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex); + } + } + heap_free(pFuncDesc->lprgelemdescParam); + } + + heap_free(pFuncDesc->elemdescFunc.u.paramdesc.pparamdescex); + + if (pFuncDesc->elemdescFunc.tdesc.vt != VT_USERDEFINED) + release_typedesc(pFuncDesc->elemdescFunc.tdesc.u.lptdesc); + + heap_free(pFuncDesc); } /****************************************************************************** * ITypeInfo2_ReleaseVarDesc {OLEAUT32} - * - * See ITypeInfo_ReleaseVarDesc. */ static void WINAPI ITypeInfo2_fnReleaseVarDesc( ITypeInfo2* iface, @@ -3577,8 +3883,23 @@ static HRESULT WINAPI ITypeInfo2_fnGetCustData( REFGUID guid, /* [I] The GUID under which the custom data is stored. */ VARIANT* pVarVal) /* [O] The custom data. */ { - FIXME("(%p,%s,%p), stub!\n", iface, debugstr_guid(guid), pVarVal); - return E_OUTOFMEMORY; + ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface); + MSFT_CDGuid *cdentry; + int offset; + + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal); + + if (!guid || !pVarVal) + return E_INVALIDARG; + + VariantClear(pVarVal); + + offset = ctl2_find_custdata(This->typelib, guid, This->typeinfo->oCustData); + if (offset == -1) + return S_OK; + + cdentry = (MSFT_CDGuid *)&This->typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset]; + return ctl2_decode_variant(This->typelib, cdentry->DataOffset, pVarVal); } /****************************************************************************** @@ -3884,11 +4205,11 @@ static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typel TRACE("Constructing ICreateTypeInfo2 for %s with tkind %d\n", debugstr_w(szName), tkind); - pCreateTypeInfo2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeInfo2Impl)); + pCreateTypeInfo2Impl = heap_alloc_zero(sizeof(ICreateTypeInfo2Impl)); if (!pCreateTypeInfo2Impl) return NULL; - pCreateTypeInfo2Impl->lpVtbl = &ctypeinfo2vt; - pCreateTypeInfo2Impl->lpVtblTypeInfo2 = &typeinfo2vt; + pCreateTypeInfo2Impl->ICreateTypeInfo2_iface.lpVtbl = &ctypeinfo2vt; + pCreateTypeInfo2Impl->ITypeInfo2_iface.lpVtbl = &typeinfo2vt; pCreateTypeInfo2Impl->ref = 1; pCreateTypeInfo2Impl->typelib = typelib; @@ -3905,7 +4226,7 @@ static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typel pCreateTypeInfo2Impl->typekind = tkind; typeinfo->typekind |= tkind | 0x20; - ICreateTypeInfo2_SetAlignment((ICreateTypeInfo2 *)pCreateTypeInfo2Impl, 4); + ICreateTypeInfo2_SetAlignment(&pCreateTypeInfo2Impl->ICreateTypeInfo2_iface, 4); switch (tkind) { case TKIND_ENUM: @@ -3940,7 +4261,7 @@ static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typel TRACE(" -- %p\n", pCreateTypeInfo2Impl); - return (ICreateTypeInfo2 *)pCreateTypeInfo2Impl; + return &pCreateTypeInfo2Impl->ICreateTypeInfo2_iface; } @@ -3948,15 +4269,13 @@ static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typel /****************************************************************************** * ICreateTypeLib2_QueryInterface {OLEAUT32} - * - * See IUnknown_QueryInterface. */ static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface( ICreateTypeLib2 * iface, REFIID riid, VOID **ppvObject) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); @@ -3968,7 +4287,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface( *ppvObject = This; } else if (IsEqualIID(riid, &IID_ITypeLib) || IsEqualIID(riid, &IID_ITypeLib2)) { - *ppvObject = &This->lpVtblTypeLib2; + *ppvObject = &This->ITypeLib2_iface; } if(*ppvObject) @@ -3983,40 +4302,36 @@ static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface( /****************************************************************************** * ICreateTypeLib2_AddRef {OLEAUT32} - * - * See IUnknown_AddRef. */ static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p)->ref was %u\n",This, ref - 1); + TRACE("(%p)->(%u)\n", This, ref); return ref; } /****************************************************************************** * ICreateTypeLib2_Release {OLEAUT32} - * - * See IUnknown_Release. */ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p)->(%u)\n",This, ref); + TRACE("(%p)->(%u)\n", This, ref); if (!ref) { int i; for (i = 0; i < MSFT_SEG_MAX; i++) { - HeapFree(GetProcessHeap(), 0, This->typelib_segment_data[i]); + heap_free(This->typelib_segment_data[i]); This->typelib_segment_data[i] = NULL; } - HeapFree(GetProcessHeap(), 0, This->filename); + SysFreeString(This->filename); This->filename = NULL; while (This->typeinfos) { @@ -4028,22 +4343,21 @@ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) rem = typeinfo->typedata->next; typeinfo->typedata->next = NULL; iter = rem->next; - HeapFree(GetProcessHeap(), 0, rem); + heap_free(rem); while(iter) { rem = iter; iter = iter->next; - HeapFree(GetProcessHeap(), 0, rem->u.data); - HeapFree(GetProcessHeap(), 0, rem); + heap_free(rem->u.data); + heap_free(rem); } } - HeapFree(GetProcessHeap(), 0, typeinfo->dual); - HeapFree(GetProcessHeap(), 0, typeinfo); + heap_free(typeinfo->dual); + heap_free(typeinfo); } - HeapFree(GetProcessHeap(),0,This); - return 0; + heap_free(This); } return ref; @@ -4052,42 +4366,38 @@ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) /****************************************************************************** * ICreateTypeLib2_CreateTypeInfo {OLEAUT32} - * - * See ICreateTypeLib_CreateTypeInfo. */ static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo( ICreateTypeLib2 * iface, LPOLESTR szName, TYPEKIND tkind, - ICreateTypeInfo **ppCTInfo) + ICreateTypeInfo **tinfo) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); char *name; - TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo); + TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, tinfo); + + if (!szName || !tinfo) return E_INVALIDARG; ctl2_encode_name(This, szName, &name); if(ctl2_find_name(This, name) != -1) return TYPE_E_NAMECONFLICT; - *ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind); - - if (!*ppCTInfo) return E_OUTOFMEMORY; + *tinfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind); + if (!*tinfo) return E_OUTOFMEMORY; return S_OK; } /****************************************************************************** * ICreateTypeLib2_SetName {OLEAUT32} - * - * See ICreateTypeLib_SetName. */ static HRESULT WINAPI ICreateTypeLib2_fnSetName( ICreateTypeLib2 * iface, LPOLESTR szName) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; - + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); int offset; TRACE("(%p,%s)\n", iface, debugstr_w(szName)); @@ -4100,12 +4410,10 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetName( /****************************************************************************** * ICreateTypeLib2_SetVersion {OLEAUT32} - * - * See ICreateTypeLib_SetVersion. */ static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD wMajorVerNum, WORD wMinorVerNum) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum); @@ -4115,13 +4423,10 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD /****************************************************************************** * ICreateTypeLib2_SetGuid {OLEAUT32} - * - * See ICreateTypeLib_SetGuid. */ static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID guid) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; - + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); MSFT_GuidEntry guidentry; int offset; @@ -4142,13 +4447,10 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID /****************************************************************************** * ICreateTypeLib2_SetDocString {OLEAUT32} - * - * See ICreateTypeLib_SetDocString. */ static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LPOLESTR szDoc) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; - + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); int offset; TRACE("(%p,%s)\n", iface, debugstr_w(szDoc)); @@ -4163,13 +4465,10 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LP /****************************************************************************** * ICreateTypeLib2_SetHelpFileName {OLEAUT32} - * - * See ICreateTypeLib_SetHelpFileName. */ static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, LPOLESTR szHelpFileName) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; - + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); int offset; TRACE("(%p,%s)\n", iface, debugstr_w(szHelpFileName)); @@ -4183,12 +4482,10 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, /****************************************************************************** * ICreateTypeLib2_SetHelpContext {OLEAUT32} - * - * See ICreateTypeLib_SetHelpContext. */ static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); TRACE("(%p,%d)\n", iface, dwHelpContext); This->typelib_header.helpcontext = dwHelpContext; @@ -4205,7 +4502,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, */ static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lcid) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); TRACE("(%p,%d)\n", iface, lcid); @@ -4218,12 +4515,10 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lc /****************************************************************************** * ICreateTypeLib2_SetLibFlags {OLEAUT32} - * - * See ICreateTypeLib_SetLibFlags. */ static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 * iface, UINT uLibFlags) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); TRACE("(%p,0x%x)\n", iface, uLibFlags); @@ -4236,6 +4531,7 @@ static int ctl2_write_chunk(HANDLE hFile, const void *segment, int length) { DWORD dwWritten; if (!WriteFile(hFile, segment, length, &dwWritten, 0)) { + TRACE("Writefile(%p, %d) failed, lasterror %d\n", segment, length, GetLastError()); CloseHandle(hFile); return 0; } @@ -4262,14 +4558,14 @@ static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize) for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { typeinfo->typeinfo->memoffset = filesize; - hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo); + hres = ICreateTypeInfo2_fnLayOut(&typeinfo->ICreateTypeInfo2_iface); if(FAILED(hres)) return hres; if (typeinfo->typedata) filesize += typeinfo->typedata->next->u.val - + ((typeinfo->typeinfo->cElement >> 16) * 12) - + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4; + + cti2_get_var_count(typeinfo->typeinfo) * 12 + + cti2_get_func_count(typeinfo->typeinfo) * 12 + 4; } return S_OK; @@ -4286,7 +4582,7 @@ static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int seg return This->typelib_segdir[segment].length; } -static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile) +static int ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile) { ICreateTypeInfo2Impl *typeinfo; @@ -4297,32 +4593,35 @@ static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile) if (!typeinfo->typedata) continue; iter = typeinfo->typedata->next; - ctl2_write_chunk(hFile, &iter->u.val, sizeof(int)); + if (!ctl2_write_chunk(hFile, &iter->u.val, sizeof(int))) + return 0; for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next) - ctl2_write_chunk(hFile, iter->u.data, iter->u.data[0] & 0xffff); + if (!ctl2_write_chunk(hFile, iter->u.data, ctl2_get_record_size(iter))) + return 0; for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) - ctl2_write_chunk(hFile, &iter->indice, sizeof(int)); + if (!ctl2_write_chunk(hFile, &iter->indice, sizeof(int))) + return 0; for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) - ctl2_write_chunk(hFile, &iter->name, sizeof(int)); + if (!ctl2_write_chunk(hFile, &iter->name, sizeof(int))) + return 0; for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) { - ctl2_write_chunk(hFile, &offset, sizeof(int)); - offset += iter->u.data[0] & 0xffff; + if (!ctl2_write_chunk(hFile, &offset, sizeof(int))) + return 0; + offset += ctl2_get_record_size(iter); } } + return 1; } /****************************************************************************** * ICreateTypeLib2_SaveAllChanges {OLEAUT32} - * - * See ICreateTypeLib_SaveAllChanges. */ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; - + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); int retval; int filepos; HANDLE hFile; @@ -4377,7 +4676,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATA )) return retval; if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATAGUID)) return retval; - ctl2_write_typeinfos(This, hFile); + if (!ctl2_write_typeinfos(This, hFile)) return retval; if (!CloseHandle(hFile)) return retval; @@ -4418,7 +4717,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetCustData( REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ VARIANT *pVarVal) /* [I] The custom data itself. */ { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal); @@ -4442,7 +4741,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 * iface, ULONG dwContext) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); TRACE("(%p,%d)\n", iface, dwContext); @@ -4467,7 +4766,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 * iface, LPOLESTR szDllName) { - ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + ICreateTypeLib2Impl *This = impl_from_ICreateTypeLib2(iface); int offset; TRACE("(%p,%s)\n", iface, debugstr_w(szDllName)); @@ -4486,44 +4785,36 @@ HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 * iface, /****************************************************************************** * ITypeLib2_QueryInterface {OLEAUT32} - * - * See IUnknown_QueryInterface. */ static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 * iface, REFIID riid, LPVOID * ppv) { ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - return ICreateTypeLib2_QueryInterface((ICreateTypeLib2 *)This, riid, ppv); + return ICreateTypeLib2_QueryInterface(&This->ICreateTypeLib2_iface, riid, ppv); } /****************************************************************************** * ITypeLib2_AddRef {OLEAUT32} - * - * See IUnknown_AddRef. */ static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 * iface) { ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - return ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This); + return ICreateTypeLib2_AddRef(&This->ICreateTypeLib2_iface); } /****************************************************************************** * ITypeLib2_Release {OLEAUT32} - * - * See IUnknown_Release. */ static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 * iface) { ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - return ICreateTypeLib2_Release((ICreateTypeLib2 *)This); + return ICreateTypeLib2_Release(&This->ICreateTypeLib2_iface); } /****************************************************************************** * ITypeLib2_GetTypeInfoCount {OLEAUT32} - * - * See ITypeLib_GetTypeInfoCount. */ static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 * iface) @@ -4537,8 +4828,6 @@ static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( /****************************************************************************** * ITypeLib2_GetTypeInfo {OLEAUT32} - * - * See ITypeLib_GetTypeInfo. */ static HRESULT WINAPI ITypeLib2_fnGetTypeInfo( ITypeLib2 * iface, @@ -4549,6 +4838,8 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfo( TRACE("(%p,%d,%p)\n", iface, index, ppTInfo); + if (!ppTInfo) return E_INVALIDARG; + if (index >= This->typelib_header.nrtypeinfos) { return TYPE_E_ELEMENTNOTFOUND; } @@ -4558,31 +4849,29 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfo( /****************************************************************************** * ITypeLib2_GetTypeInfoType {OLEAUT32} - * - * See ITypeLib_GetTypeInfoType. */ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType( ITypeLib2 * iface, UINT index, - TYPEKIND* pTKind) + TYPEKIND* kind) { ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface); - TRACE("(%p,%d,%p)\n", iface, index, pTKind); + TRACE("(%p,%d,%p)\n", iface, index, kind); + + if (!kind) return E_INVALIDARG; if (index >= This->typelib_header.nrtypeinfos) { return TYPE_E_ELEMENTNOTFOUND; } - *pTKind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 15; + *kind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 0xF; return S_OK; } /****************************************************************************** * ITypeLib2_GetTypeInfoOfGuid {OLEAUT32} - * - * See ITypeLib_GetTypeInfoOfGuid. */ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid( ITypeLib2 * iface, @@ -4607,8 +4896,6 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid( /****************************************************************************** * ITypeLib2_GetLibAttr {OLEAUT32} - * - * See ITypeLib_GetLibAttr. */ static HRESULT WINAPI ITypeLib2_fnGetLibAttr( ITypeLib2 * iface, @@ -4621,7 +4908,7 @@ static HRESULT WINAPI ITypeLib2_fnGetLibAttr( if(!ppTLibAttr) return E_INVALIDARG; - *ppTLibAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TLIBATTR)); + *ppTLibAttr = heap_alloc_zero(sizeof(TLIBATTR)); if(!*ppTLibAttr) return E_OUTOFMEMORY; @@ -4633,17 +4920,15 @@ static HRESULT WINAPI ITypeLib2_fnGetLibAttr( } (*ppTLibAttr)->lcid = This->typelib_header.lcid; - (*ppTLibAttr)->syskind = This->typelib_header.varflags&0x3; - (*ppTLibAttr)->wMajorVerNum = This->typelib_header.version&0xffff; - (*ppTLibAttr)->wMinorVerNum = This->typelib_header.version>>16; + (*ppTLibAttr)->syskind = ctl2_get_syskind(This); + (*ppTLibAttr)->wMajorVerNum = LOWORD(This->typelib_header.version); + (*ppTLibAttr)->wMinorVerNum = HIWORD(This->typelib_header.version); (*ppTLibAttr)->wLibFlags = This->typelib_header.flags; return S_OK; } /****************************************************************************** * ITypeLib2_GetTypeComp {OLEAUT32} - * - * See ITypeLib_GetTypeComp. */ static HRESULT WINAPI ITypeLib2_fnGetTypeComp( ITypeLib2 * iface, @@ -4658,8 +4943,6 @@ static HRESULT WINAPI ITypeLib2_fnGetTypeComp( /****************************************************************************** * ITypeLib2_GetDocumentation {OLEAUT32} - * - * See ITypeLib_GetDocumentation. */ static HRESULT WINAPI ITypeLib2_fnGetDocumentation( ITypeLib2 * iface, @@ -4683,7 +4966,7 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation( if(!iter) return TYPE_E_ELEMENTNOTFOUND; - return ITypeInfo_GetDocumentation((ITypeInfo*)&iter->lpVtblTypeInfo2, + return ITypeInfo2_GetDocumentation(&iter->ITypeInfo2_iface, -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); } @@ -4739,8 +5022,6 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation( /****************************************************************************** * ITypeLib2_IsName {OLEAUT32} - * - * See ITypeLib_IsName. */ static HRESULT WINAPI ITypeLib2_fnIsName( ITypeLib2 * iface, @@ -4775,8 +5056,6 @@ static HRESULT WINAPI ITypeLib2_fnIsName( /****************************************************************************** * ITypeLib2_FindName {OLEAUT32} - * - * See ITypeLib_FindName. */ static HRESULT WINAPI ITypeLib2_fnFindName( ITypeLib2 * iface, @@ -4795,16 +5074,13 @@ static HRESULT WINAPI ITypeLib2_fnFindName( /****************************************************************************** * ITypeLib2_ReleaseTLibAttr {OLEAUT32} - * - * See ITypeLib_ReleaseTLibAttr. */ static void WINAPI ITypeLib2_fnReleaseTLibAttr( ITypeLib2 * iface, - TLIBATTR* pTLibAttr) + TLIBATTR* attr) { - TRACE("(%p,%p)\n", iface, pTLibAttr); - - HeapFree(GetProcessHeap(), 0, pTLibAttr); + TRACE("(%p,%p)\n", iface, attr); + heap_free(attr); } /****************************************************************************** @@ -4949,51 +5225,58 @@ static const ITypeLib2Vtbl typelib2vt = ITypeLib2_fnGetAllCustData, }; -static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR szFile) +static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR filename) { - ICreateTypeLib2Impl *pCreateTypeLib2Impl; + ICreateTypeLib2Impl *create_tlib2; int failed = 0; - TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(szFile)); + TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(filename)); - pCreateTypeLib2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeLib2Impl)); - if (!pCreateTypeLib2Impl) return NULL; + create_tlib2 = heap_alloc_zero(sizeof(ICreateTypeLib2Impl)); + if (!create_tlib2) return NULL; - pCreateTypeLib2Impl->filename = HeapAlloc(GetProcessHeap(), 0, (strlenW(szFile) + 1) * sizeof(WCHAR)); - if (!pCreateTypeLib2Impl->filename) { - HeapFree(GetProcessHeap(), 0, pCreateTypeLib2Impl); + create_tlib2->filename = SysAllocString(filename); + if (!create_tlib2->filename) { + heap_free(create_tlib2); return NULL; } - strcpyW(pCreateTypeLib2Impl->filename, szFile); - ctl2_init_header(pCreateTypeLib2Impl); - ctl2_init_segdir(pCreateTypeLib2Impl); + ctl2_init_header(create_tlib2); + ctl2_init_segdir(create_tlib2); - pCreateTypeLib2Impl->typelib_header.varflags |= syskind; + create_tlib2->typelib_header.varflags |= syskind; /* * The following two calls return an offset or -1 if out of memory. We * specifically need an offset of 0, however, so... */ - if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; } - if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; } + if (ctl2_alloc_segment(create_tlib2, MSFT_SEG_GUIDHASH, 0x80, 0x80) == 0) + { + create_tlib2->typelib_guidhash_segment = (int *)create_tlib2->typelib_segment_data[MSFT_SEG_GUIDHASH]; + memset(create_tlib2->typelib_guidhash_segment, 0xff, 0x80); + } + else + failed = 1; - pCreateTypeLib2Impl->typelib_guidhash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_GUIDHASH]; - pCreateTypeLib2Impl->typelib_namehash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_NAMEHASH]; + if (ctl2_alloc_segment(create_tlib2, MSFT_SEG_NAMEHASH, 0x200, 0x200) == 0) + { + create_tlib2->typelib_namehash_segment = (int *)create_tlib2->typelib_segment_data[MSFT_SEG_NAMEHASH]; + memset(create_tlib2->typelib_namehash_segment, 0xff, 0x200); + } + else + failed = 1; - memset(pCreateTypeLib2Impl->typelib_guidhash_segment, 0xff, 0x80); - memset(pCreateTypeLib2Impl->typelib_namehash_segment, 0xff, 0x200); - - pCreateTypeLib2Impl->lpVtbl = &ctypelib2vt; - pCreateTypeLib2Impl->lpVtblTypeLib2 = &typelib2vt; - pCreateTypeLib2Impl->ref = 1; + create_tlib2->ICreateTypeLib2_iface.lpVtbl = &ctypelib2vt; + create_tlib2->ITypeLib2_iface.lpVtbl = &typelib2vt; + create_tlib2->ref = 1; if (failed) { - ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)pCreateTypeLib2Impl); - return 0; + ICreateTypeLib2_fnRelease(&create_tlib2->ICreateTypeLib2_iface); + heap_free(create_tlib2); + return NULL; } - return (ICreateTypeLib2 *)pCreateTypeLib2Impl; + return &create_tlib2->ICreateTypeLib2_iface; } /****************************************************************************** @@ -5045,7 +5328,7 @@ void WINAPI ClearCustData(LPCUSTDATA lpCust) VariantClear(&lpCust->prgCustData[i].varValue); /* FIXME - Should be using a per-thread IMalloc */ - HeapFree(GetProcessHeap(), 0, lpCust->prgCustData); + heap_free(lpCust->prgCustData); lpCust->prgCustData = NULL; } lpCust->cCustData = 0; diff --git a/reactos/dll/win32/oleaut32/ungif.c b/reactos/dll/win32/oleaut32/ungif.c deleted file mode 100644 index c24f387df67..00000000000 --- a/reactos/dll/win32/oleaut32/ungif.c +++ /dev/null @@ -1,999 +0,0 @@ -/* - * Gif extracting routines - derived from libungif - * - * Portions Copyright 2006 Mike McCormack - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* - * Original copyright notice: - * - * The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - */ - - -/****************************************************************************** - * "Gif-Lib" - Yet another gif library. - * - * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990 - ****************************************************************************** - * The kernel of the GIF Decoding process can be found here. - ****************************************************************************** - * History: - * 16 Jun 89 - Version 1.0 by Gershon Elber. - * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). - *****************************************************************************/ - -#include -#include -#include "ungif.h" - -#include -#include "windef.h" -#include "winbase.h" - -static void *ungif_alloc( size_t sz ) -{ - return HeapAlloc( GetProcessHeap(), 0, sz ); -} - -static void *ungif_calloc( size_t num, size_t sz ) -{ - return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, num*sz ); -} - -static void *ungif_realloc( void *ptr, size_t sz ) -{ - return HeapReAlloc( GetProcessHeap(), 0, ptr, sz ); -} - -static void ungif_free( void *ptr ) -{ - HeapFree( GetProcessHeap(), 0, ptr ); -} - -#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ -#define LZ_BITS 12 - -#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */ - -typedef struct GifFilePrivateType { - GifWord BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */ - ClearCode, /* The CLEAR LZ code. */ - EOFCode, /* The EOF LZ code. */ - RunningCode, /* The next code algorithm can generate. */ - RunningBits, /* The number of bits required to represent RunningCode. */ - MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */ - LastCode, /* The code before the current code. */ - CrntCode, /* Current algorithm code. */ - StackPtr, /* For character stack (see below). */ - CrntShiftState; /* Number of bits in CrntShiftDWord. */ - unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */ - unsigned long PixelCount; /* Number of pixels in image. */ - InputFunc Read; /* function to read gif input (TVT) */ - GifByteType Buf[256]; /* Compressed input is buffered here. */ - GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */ - GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */ - GifPrefixType Prefix[LZ_MAX_CODE + 1]; -} GifFilePrivateType; - -/* avoid extra function call in case we use fread (TVT) */ -#define READ(_gif,_buf,_len) \ - ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) - -static int DGifGetWord(GifFileType *GifFile, GifWord *Word); -static int DGifSetupDecompress(GifFileType *GifFile); -static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen); -static int DGifGetPrefixChar(const GifPrefixType *Prefix, int Code, int ClearCode); -static int DGifDecompressInput(GifFileType *GifFile, int *Code); -static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, - GifByteType *NextByte); - -static int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension); -static int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock); - -/****************************************************************************** - * Miscellaneous utility functions - *****************************************************************************/ - -/* return smallest bitfield size n will fit in */ -static int -BitSize(int n) { - - register int i; - - for (i = 1; i <= 8; i++) - if ((1 << i) >= n) - break; - return (i); -} - -/****************************************************************************** - * Color map object functions - *****************************************************************************/ - -/* - * Allocate a color map of given size; initialize with contents of - * ColorMap if that pointer is non-NULL. - */ -static ColorMapObject * -MakeMapObject(int ColorCount, - const GifColorType * ColorMap) { - - ColorMapObject *Object; - - /*** FIXME: Our ColorCount has to be a power of two. Is it necessary to - * make the user know that or should we automatically round up instead? */ - if (ColorCount != (1 << BitSize(ColorCount))) { - return NULL; - } - - Object = ungif_alloc(sizeof(ColorMapObject)); - if (Object == NULL) { - return NULL; - } - - Object->Colors = ungif_calloc(ColorCount, sizeof(GifColorType)); - if (Object->Colors == NULL) { - return NULL; - } - - Object->ColorCount = ColorCount; - Object->BitsPerPixel = BitSize(ColorCount); - - if (ColorMap) { - memcpy(Object->Colors, ColorMap, ColorCount * sizeof(GifColorType)); - } - - return (Object); -} - -/* - * Free a color map object - */ -static void -FreeMapObject(ColorMapObject * Object) { - - if (Object != NULL) { - ungif_free(Object->Colors); - ungif_free(Object); - /*** FIXME: - * When we are willing to break API we need to make this function - * FreeMapObject(ColorMapObject **Object) - * and do this assignment to NULL here: - * *Object = NULL; - */ - } -} - -static int -AddExtensionBlock(SavedImage * New, - int Len, - const unsigned char ExtData[]) { - - ExtensionBlock *ep; - - if (New->ExtensionBlocks == NULL) - New->ExtensionBlocks = ungif_alloc(sizeof(ExtensionBlock)); - else - New->ExtensionBlocks = ungif_realloc(New->ExtensionBlocks, - sizeof(ExtensionBlock) * - (New->ExtensionBlockCount + 1)); - - if (New->ExtensionBlocks == NULL) - return (GIF_ERROR); - - ep = &New->ExtensionBlocks[New->ExtensionBlockCount++]; - - ep->ByteCount=Len; - ep->Bytes = ungif_alloc(ep->ByteCount); - if (ep->Bytes == NULL) - return (GIF_ERROR); - - if (ExtData) { - memcpy(ep->Bytes, ExtData, Len); - ep->Function = New->Function; - } - - return (GIF_OK); -} - -static void -FreeExtension(SavedImage * Image) -{ - ExtensionBlock *ep; - - if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) { - return; - } - for (ep = Image->ExtensionBlocks; - ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++) - ungif_free(ep->Bytes); - ungif_free(Image->ExtensionBlocks); - Image->ExtensionBlocks = NULL; -} - -/****************************************************************************** - * Image block allocation functions -******************************************************************************/ - -static void -FreeSavedImages(GifFileType * GifFile) { - - SavedImage *sp; - - if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) { - return; - } - for (sp = GifFile->SavedImages; - sp < GifFile->SavedImages + GifFile->ImageCount; sp++) { - if (sp->ImageDesc.ColorMap) { - FreeMapObject(sp->ImageDesc.ColorMap); - sp->ImageDesc.ColorMap = NULL; - } - - ungif_free(sp->RasterBits); - - if (sp->ExtensionBlocks) - FreeExtension(sp); - } - ungif_free(GifFile->SavedImages); - GifFile->SavedImages=NULL; -} - -/****************************************************************************** - * This routine should be called before any other DGif calls. Note that - * this routine is called automatically from DGif file open routines. - *****************************************************************************/ -static int -DGifGetScreenDesc(GifFileType * GifFile) { - - int i, BitsPerPixel; - GifByteType Buf[3]; - - /* Put the screen descriptor into the file: */ - if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR || - DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR) - return GIF_ERROR; - - if (READ(GifFile, Buf, 3) != 3) { - return GIF_ERROR; - } - GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1; - BitsPerPixel = (Buf[0] & 0x07) + 1; - GifFile->SBackGroundColor = Buf[1]; - if (Buf[0] & 0x80) { /* Do we have global color map? */ - - GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL); - if (GifFile->SColorMap == NULL) { - return GIF_ERROR; - } - - /* Get the global color map: */ - for (i = 0; i < GifFile->SColorMap->ColorCount; i++) { - if (READ(GifFile, Buf, 3) != 3) { - FreeMapObject(GifFile->SColorMap); - GifFile->SColorMap = NULL; - return GIF_ERROR; - } - GifFile->SColorMap->Colors[i].Red = Buf[0]; - GifFile->SColorMap->Colors[i].Green = Buf[1]; - GifFile->SColorMap->Colors[i].Blue = Buf[2]; - } - } else { - GifFile->SColorMap = NULL; - } - - return GIF_OK; -} - -/****************************************************************************** - * This routine should be called before any attempt to read an image. - *****************************************************************************/ -static int -DGifGetRecordType(GifFileType * GifFile, - GifRecordType * Type) { - - GifByteType Buf; - - if (READ(GifFile, &Buf, 1) != 1) { - return GIF_ERROR; - } - - switch (Buf) { - case ',': - *Type = IMAGE_DESC_RECORD_TYPE; - break; - case '!': - *Type = EXTENSION_RECORD_TYPE; - break; - case ';': - *Type = TERMINATE_RECORD_TYPE; - break; - default: - *Type = UNDEFINED_RECORD_TYPE; - return GIF_ERROR; - } - - return GIF_OK; -} - -/****************************************************************************** - * This routine should be called before any attempt to read an image. - * Note it is assumed the Image desc. header (',') has been read. - *****************************************************************************/ -static int -DGifGetImageDesc(GifFileType * GifFile) { - - int i, BitsPerPixel; - GifByteType Buf[3]; - GifFilePrivateType *Private = GifFile->Private; - SavedImage *sp; - - if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR || - DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR || - DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR || - DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR) - return GIF_ERROR; - if (READ(GifFile, Buf, 1) != 1) { - return GIF_ERROR; - } - BitsPerPixel = (Buf[0] & 0x07) + 1; - GifFile->Image.Interlace = (Buf[0] & 0x40); - if (Buf[0] & 0x80) { /* Does this image have local color map? */ - - /*** FIXME: Why do we check both of these in order to do this? - * Why do we have both Image and SavedImages? */ - if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL) - FreeMapObject(GifFile->Image.ColorMap); - - GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL); - if (GifFile->Image.ColorMap == NULL) { - return GIF_ERROR; - } - - /* Get the image local color map: */ - for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) { - if (READ(GifFile, Buf, 3) != 3) { - FreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; - return GIF_ERROR; - } - GifFile->Image.ColorMap->Colors[i].Red = Buf[0]; - GifFile->Image.ColorMap->Colors[i].Green = Buf[1]; - GifFile->Image.ColorMap->Colors[i].Blue = Buf[2]; - } - } else if (GifFile->Image.ColorMap) { - FreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; - } - - if (GifFile->SavedImages) { - if ((GifFile->SavedImages = ungif_realloc(GifFile->SavedImages, - sizeof(SavedImage) * - (GifFile->ImageCount + 1))) == NULL) { - return GIF_ERROR; - } - } else { - if ((GifFile->SavedImages = ungif_alloc(sizeof(SavedImage))) == NULL) { - return GIF_ERROR; - } - } - - sp = &GifFile->SavedImages[GifFile->ImageCount]; - sp->ImageDesc = GifFile->Image; - if (GifFile->Image.ColorMap != NULL) { - sp->ImageDesc.ColorMap = MakeMapObject( - GifFile->Image.ColorMap->ColorCount, - GifFile->Image.ColorMap->Colors); - if (sp->ImageDesc.ColorMap == NULL) { - return GIF_ERROR; - } - } - sp->RasterBits = NULL; - sp->ExtensionBlockCount = 0; - sp->ExtensionBlocks = NULL; - - GifFile->ImageCount++; - - Private->PixelCount = (long)GifFile->Image.Width * - (long)GifFile->Image.Height; - - DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */ - - return GIF_OK; -} - -/****************************************************************************** - * Get one full scanned line (Line) of length LineLen from GIF file. - *****************************************************************************/ -static int -DGifGetLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - - GifByteType *Dummy; - GifFilePrivateType *Private = GifFile->Private; - - if (!LineLen) - LineLen = GifFile->Image.Width; - - if ((Private->PixelCount -= LineLen) > 0xffff0000UL) { - return GIF_ERROR; - } - - if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) { - if (Private->PixelCount == 0) { - /* We probably would not be called any more, so lets clean - * everything before we return: need to flush out all rest of - * image until empty block (size 0) detected. We use GetCodeNext. */ - do - if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR) - return GIF_ERROR; - while (Dummy != NULL) ; - } - return GIF_OK; - } else - return GIF_ERROR; -} - -/****************************************************************************** - * Get an extension block (see GIF manual) from gif file. This routine only - * returns the first data block, and DGifGetExtensionNext should be called - * after this one until NULL extension is returned. - * The Extension should NOT be freed by the user (not dynamically allocated). - * Note it is assumed the Extension desc. header ('!') has been read. - *****************************************************************************/ -static int -DGifGetExtension(GifFileType * GifFile, - int *ExtCode, - GifByteType ** Extension) { - - GifByteType Buf; - - if (READ(GifFile, &Buf, 1) != 1) { - return GIF_ERROR; - } - *ExtCode = Buf; - - return DGifGetExtensionNext(GifFile, Extension); -} - -/****************************************************************************** - * Get a following extension block (see GIF manual) from gif file. This - * routine should be called until NULL Extension is returned. - * The Extension should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ -static int -DGifGetExtensionNext(GifFileType * GifFile, - GifByteType ** Extension) { - - GifByteType Buf; - GifFilePrivateType *Private = GifFile->Private; - - if (READ(GifFile, &Buf, 1) != 1) { - return GIF_ERROR; - } - if (Buf > 0) { - *Extension = Private->Buf; /* Use private unused buffer. */ - (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ - if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) { - return GIF_ERROR; - } - } else - *Extension = NULL; - - return GIF_OK; -} - -/****************************************************************************** - * Get 2 bytes (word) from the given file: - *****************************************************************************/ -static int -DGifGetWord(GifFileType * GifFile, - GifWord *Word) { - - unsigned char c[2]; - - if (READ(GifFile, c, 2) != 2) { - return GIF_ERROR; - } - - *Word = (((unsigned int)c[1]) << 8) + c[0]; - return GIF_OK; -} - -/****************************************************************************** - * Continue to get the image code in compressed form. This routine should be - * called until NULL block is returned. - * The block should NOT be freed by the user (not dynamically allocated). - *****************************************************************************/ -static int -DGifGetCodeNext(GifFileType * GifFile, - GifByteType ** CodeBlock) { - - GifByteType Buf; - GifFilePrivateType *Private = GifFile->Private; - - if (READ(GifFile, &Buf, 1) != 1) { - return GIF_ERROR; - } - - if (Buf > 0) { - *CodeBlock = Private->Buf; /* Use private unused buffer. */ - (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */ - if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) { - return GIF_ERROR; - } - } else { - *CodeBlock = NULL; - Private->Buf[0] = 0; /* Make sure the buffer is empty! */ - Private->PixelCount = 0; /* And local info. indicate image read. */ - } - - return GIF_OK; -} - -/****************************************************************************** - * Setup the LZ decompression for this image: - *****************************************************************************/ -static int -DGifSetupDecompress(GifFileType * GifFile) { - - int i, BitsPerPixel; - GifByteType CodeSize; - GifPrefixType *Prefix; - GifFilePrivateType *Private = GifFile->Private; - - READ(GifFile, &CodeSize, 1); /* Read Code size from file. */ - BitsPerPixel = CodeSize; - - Private->Buf[0] = 0; /* Input Buffer empty. */ - Private->BitsPerPixel = BitsPerPixel; - Private->ClearCode = (1 << BitsPerPixel); - Private->EOFCode = Private->ClearCode + 1; - Private->RunningCode = Private->EOFCode + 1; - Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */ - Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */ - Private->StackPtr = 0; /* No pixels on the pixel stack. */ - Private->LastCode = NO_SUCH_CODE; - Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */ - Private->CrntShiftDWord = 0; - - Prefix = Private->Prefix; - for (i = 0; i <= LZ_MAX_CODE; i++) - Prefix[i] = NO_SUCH_CODE; - - return GIF_OK; -} - -/****************************************************************************** - * The LZ decompression routine: - * This version decompress the given gif file into Line of length LineLen. - * This routine can be called few times (one per scan line, for example), in - * order the complete the whole image. - *****************************************************************************/ -static int -DGifDecompressLine(GifFileType * GifFile, - GifPixelType * Line, - int LineLen) { - - int i = 0; - int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; - GifByteType *Stack, *Suffix; - GifPrefixType *Prefix; - GifFilePrivateType *Private = GifFile->Private; - - StackPtr = Private->StackPtr; - Prefix = Private->Prefix; - Suffix = Private->Suffix; - Stack = Private->Stack; - EOFCode = Private->EOFCode; - ClearCode = Private->ClearCode; - LastCode = Private->LastCode; - - if (StackPtr != 0) { - /* Let pop the stack off before continuing to read the gif file: */ - while (StackPtr != 0 && i < LineLen) - Line[i++] = Stack[--StackPtr]; - } - - while (i < LineLen) { /* Decode LineLen items. */ - if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR) - return GIF_ERROR; - - if (CrntCode == EOFCode) { - /* Note, however, that usually we will not be here as we will stop - * decoding as soon as we got all the pixel, or EOF code will - * not be read at all, and DGifGetLine/Pixel clean everything. */ - if (i != LineLen - 1 || Private->PixelCount != 0) { - return GIF_ERROR; - } - i++; - } else if (CrntCode == ClearCode) { - /* We need to start over again: */ - for (j = 0; j <= LZ_MAX_CODE; j++) - Prefix[j] = NO_SUCH_CODE; - Private->RunningCode = Private->EOFCode + 1; - Private->RunningBits = Private->BitsPerPixel + 1; - Private->MaxCode1 = 1 << Private->RunningBits; - LastCode = Private->LastCode = NO_SUCH_CODE; - } else { - /* It's a regular code - if in pixel range simply add it to output - * stream, otherwise trace to codes linked list until the prefix - * is in pixel range: */ - if (CrntCode < ClearCode) { - /* This is simple - its pixel scalar, so add it to output: */ - Line[i++] = CrntCode; - } else { - /* It's a code to be traced: trace the linked list - * until the prefix is a pixel, while pushing the suffix - * pixels on our stack. If we done, pop the stack in reverse - * order (that's what stack is good for!) for output. */ - if (Prefix[CrntCode] == NO_SUCH_CODE) { - /* Only allowed if CrntCode is exactly the running code: - * In that case CrntCode = XXXCode, CrntCode or the - * prefix code is last code and the suffix char is - * exactly the prefix of last code! */ - if (CrntCode == Private->RunningCode - 2) { - CrntPrefix = LastCode; - Suffix[Private->RunningCode - 2] = - Stack[StackPtr++] = DGifGetPrefixChar(Prefix, - LastCode, - ClearCode); - } else { - return GIF_ERROR; - } - } else - CrntPrefix = CrntCode; - - /* Now (if image is O.K.) we should not get a NO_SUCH_CODE - * during the trace. As we might loop forever, in case of - * defective image, we count the number of loops we trace - * and stop if we got LZ_MAX_CODE. Obviously we cannot - * loop more than that. */ - j = 0; - while (j++ <= LZ_MAX_CODE && - CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) { - Stack[StackPtr++] = Suffix[CrntPrefix]; - CrntPrefix = Prefix[CrntPrefix]; - } - if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) { - return GIF_ERROR; - } - /* Push the last character on stack: */ - Stack[StackPtr++] = CrntPrefix; - - /* Now lets pop all the stack into output: */ - while (StackPtr != 0 && i < LineLen) - Line[i++] = Stack[--StackPtr]; - } - if (LastCode != NO_SUCH_CODE) { - Prefix[Private->RunningCode - 2] = LastCode; - - if (CrntCode == Private->RunningCode - 2) { - /* Only allowed if CrntCode is exactly the running code: - * In that case CrntCode = XXXCode, CrntCode or the - * prefix code is last code and the suffix char is - * exactly the prefix of last code! */ - Suffix[Private->RunningCode - 2] = - DGifGetPrefixChar(Prefix, LastCode, ClearCode); - } else { - Suffix[Private->RunningCode - 2] = - DGifGetPrefixChar(Prefix, CrntCode, ClearCode); - } - } - LastCode = CrntCode; - } - } - - Private->LastCode = LastCode; - Private->StackPtr = StackPtr; - - return GIF_OK; -} - -/****************************************************************************** - * Routine to trace the Prefixes linked list until we get a prefix which is - * not code, but a pixel value (less than ClearCode). Returns that pixel value. - * If image is defective, we might loop here forever, so we limit the loops to - * the maximum possible if image O.k. - LZ_MAX_CODE times. - *****************************************************************************/ -static int -DGifGetPrefixChar(const GifPrefixType *Prefix, - int Code, - int ClearCode) { - - int i = 0; - - while (Code > ClearCode && i++ <= LZ_MAX_CODE) - Code = Prefix[Code]; - return Code; -} - -/****************************************************************************** - * The LZ decompression input routine: - * This routine is responsible for the decompression of the bit stream from - * 8 bits (bytes) packets, into the real codes. - * Returns GIF_OK if read successfully. - *****************************************************************************/ -static int -DGifDecompressInput(GifFileType * GifFile, - int *Code) { - - GifFilePrivateType *Private = GifFile->Private; - - GifByteType NextByte; - static const unsigned short CodeMasks[] = { - 0x0000, 0x0001, 0x0003, 0x0007, - 0x000f, 0x001f, 0x003f, 0x007f, - 0x00ff, 0x01ff, 0x03ff, 0x07ff, - 0x0fff - }; - /* The image can't contain more than LZ_BITS per code. */ - if (Private->RunningBits > LZ_BITS) { - return GIF_ERROR; - } - - while (Private->CrntShiftState < Private->RunningBits) { - /* Needs to get more bytes from input stream for next code: */ - if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) { - return GIF_ERROR; - } - Private->CrntShiftDWord |= - ((unsigned long)NextByte) << Private->CrntShiftState; - Private->CrntShiftState += 8; - } - *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits]; - - Private->CrntShiftDWord >>= Private->RunningBits; - Private->CrntShiftState -= Private->RunningBits; - - /* If code cannot fit into RunningBits bits, must raise its size. Note - * however that codes above 4095 are used for special signaling. - * If we're using LZ_BITS bits already and we're at the max code, just - * keep using the table as it is, don't increment Private->RunningCode. - */ - if (Private->RunningCode < LZ_MAX_CODE + 2 && - ++Private->RunningCode > Private->MaxCode1 && - Private->RunningBits < LZ_BITS) { - Private->MaxCode1 <<= 1; - Private->RunningBits++; - } - return GIF_OK; -} - -/****************************************************************************** - * This routines read one gif data block at a time and buffers it internally - * so that the decompression routine could access it. - * The routine returns the next byte from its internal buffer (or read next - * block in if buffer empty) and returns GIF_OK if successful. - *****************************************************************************/ -static int -DGifBufferedInput(GifFileType * GifFile, - GifByteType * Buf, - GifByteType * NextByte) { - - if (Buf[0] == 0) { - /* Needs to read the next buffer - this one is empty: */ - if (READ(GifFile, Buf, 1) != 1) { - return GIF_ERROR; - } - /* There shouldn't be any empty data blocks here as the LZW spec - * says the LZW termination code should come first. Therefore we - * shouldn't be inside this routine at that point. - */ - if (Buf[0] == 0) { - return GIF_ERROR; - } - if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) { - return GIF_ERROR; - } - *NextByte = Buf[1]; - Buf[1] = 2; /* We use now the second place as last char read! */ - Buf[0]--; - } else { - *NextByte = Buf[Buf[1]++]; - Buf[0]--; - } - - return GIF_OK; -} - -/****************************************************************************** - * This routine reads an entire GIF into core, hanging all its state info off - * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() - * first to initialize I/O. Its inverse is EGifSpew(). - ******************************************************************************/ -int -DGifSlurp(GifFileType * GifFile) { - - int ImageSize; - GifRecordType RecordType; - SavedImage *sp; - GifByteType *ExtData; - SavedImage temp_save; - - temp_save.ExtensionBlocks = NULL; - temp_save.ExtensionBlockCount = 0; - - do { - if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) - return (GIF_ERROR); - - switch (RecordType) { - case IMAGE_DESC_RECORD_TYPE: - if (DGifGetImageDesc(GifFile) == GIF_ERROR) - return (GIF_ERROR); - - sp = &GifFile->SavedImages[GifFile->ImageCount - 1]; - ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; - - sp->RasterBits = ungif_alloc(ImageSize * sizeof(GifPixelType)); - if (sp->RasterBits == NULL) { - return GIF_ERROR; - } - if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) == - GIF_ERROR) - return (GIF_ERROR); - if (temp_save.ExtensionBlocks) { - sp->ExtensionBlocks = temp_save.ExtensionBlocks; - sp->ExtensionBlockCount = temp_save.ExtensionBlockCount; - - temp_save.ExtensionBlocks = NULL; - temp_save.ExtensionBlockCount = 0; - - /* FIXME: The following is wrong. It is left in only for - * backwards compatibility. Someday it should go away. Use - * the sp->ExtensionBlocks->Function variable instead. */ - sp->Function = sp->ExtensionBlocks[0].Function; - } - break; - - case EXTENSION_RECORD_TYPE: - if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) == - GIF_ERROR) - return (GIF_ERROR); - while (ExtData != NULL) { - - /* Create an extension block with our data */ - if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1]) - == GIF_ERROR) - return (GIF_ERROR); - - if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) - return (GIF_ERROR); - temp_save.Function = 0; - } - break; - - case TERMINATE_RECORD_TYPE: - break; - - default: /* Should be trapped by DGifGetRecordType */ - break; - } - } while (RecordType != TERMINATE_RECORD_TYPE); - - /* Just in case the Gif has an extension block without an associated - * image... (Should we save this into a savefile structure with no image - * instead? Have to check if the present writing code can handle that as - * well.... */ - if (temp_save.ExtensionBlocks) - FreeExtension(&temp_save); - - return (GIF_OK); -} - -/****************************************************************************** - * GifFileType constructor with user supplied input function (TVT) - *****************************************************************************/ -GifFileType * -DGifOpen(void *userData, - InputFunc readFunc) { - - unsigned char Buf[GIF_STAMP_LEN + 1]; - GifFileType *GifFile; - GifFilePrivateType *Private; - - GifFile = ungif_alloc(sizeof(GifFileType)); - if (GifFile == NULL) { - return NULL; - } - - memset(GifFile, '\0', sizeof(GifFileType)); - - Private = ungif_alloc(sizeof(GifFilePrivateType)); - if (!Private) { - ungif_free(GifFile); - return NULL; - } - - GifFile->Private = (void*)Private; - - Private->Read = readFunc; /* TVT */ - GifFile->UserData = userData; /* TVT */ - - /* Lets see if this is a GIF file: */ - if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) { - ungif_free(Private); - ungif_free(GifFile); - return NULL; - } - - /* The GIF Version number is ignored at this time. Maybe we should do - * something more useful with it. */ - Buf[GIF_STAMP_LEN] = 0; - if (memcmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { - ungif_free(Private); - ungif_free(GifFile); - return NULL; - } - - if (DGifGetScreenDesc(GifFile) == GIF_ERROR) { - ungif_free(Private); - ungif_free(GifFile); - return NULL; - } - - return GifFile; -} - -/****************************************************************************** - * This routine should be called last, to close the GIF file. - *****************************************************************************/ -int -DGifCloseFile(GifFileType * GifFile) { - - GifFilePrivateType *Private; - - if (GifFile == NULL) - return GIF_ERROR; - - Private = GifFile->Private; - - if (GifFile->Image.ColorMap) { - FreeMapObject(GifFile->Image.ColorMap); - GifFile->Image.ColorMap = NULL; - } - - if (GifFile->SColorMap) { - FreeMapObject(GifFile->SColorMap); - GifFile->SColorMap = NULL; - } - - ungif_free(Private); - Private = NULL; - - if (GifFile->SavedImages) { - FreeSavedImages(GifFile); - GifFile->SavedImages = NULL; - } - - ungif_free(GifFile); - - return GIF_OK; -} diff --git a/reactos/dll/win32/oleaut32/ungif.h b/reactos/dll/win32/oleaut32/ungif.h deleted file mode 100644 index e71dad8b3aa..00000000000 --- a/reactos/dll/win32/oleaut32/ungif.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Gif extracting routines - derived from libungif - * - * Portions Copyright 2006 Mike McCormack - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* - * Original copyright notice: - * - * The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - */ - -/****************************************************************************** - * In order to make life a little bit easier when using the GIF file format, - * this library was written, and which does all the dirty work... - * - * Written by Gershon Elber, Jun. 1989 - * Hacks by Eric S. Raymond, Sep. 1992 - ****************************************************************************** - * History: - * 14 Jun 89 - Version 1.0 by Gershon Elber. - * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names) - * 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to support GIF slurp) - * 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support) - * 17 Dec 98 - Version 4.0 by Toshio Kuratomi (Fix extension writing code) - *****************************************************************************/ - -#ifndef _UNGIF_H_ -#define _UNGIF_H_ 1 - -#define GIF_ERROR 0 -#define GIF_OK 1 - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ - -#ifndef NULL -#define NULL 0 -#endif /* NULL */ - -#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */ -#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1 -#define GIF_VERSION_POS 3 /* Version first character in stamp. */ -#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */ -#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */ - -#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */ - -typedef int GifBooleanType; -typedef unsigned char GifPixelType; -typedef unsigned char *GifRowType; -typedef unsigned char GifByteType; -typedef unsigned int GifPrefixType; -typedef int GifWord; - -typedef struct GifColorType { - GifByteType Red, Green, Blue; -} GifColorType; - -typedef struct ColorMapObject { - int ColorCount; - int BitsPerPixel; - GifColorType *Colors; -} ColorMapObject; - -typedef struct GifImageDesc { - GifWord Left, Top, Width, Height, /* Current image dimensions. */ - Interlace; /* Sequential/Interlaced lines. */ - ColorMapObject *ColorMap; /* The local color map */ -} GifImageDesc; - -typedef struct GifFileType { - GifWord SWidth, SHeight, /* Screen dimensions. */ - SColorResolution, /* How many colors can we generate? */ - SBackGroundColor; /* I hope you understand this one... */ - ColorMapObject *SColorMap; /* NULL if not exists. */ - int ImageCount; /* Number of current image */ - GifImageDesc Image; /* Block describing current image */ - struct SavedImage *SavedImages; /* Use this to accumulate file state */ - void *UserData; /* hook to attach user data (TVT) */ - void *Private; /* Don't mess with this! */ -} GifFileType; - -typedef enum { - UNDEFINED_RECORD_TYPE, - SCREEN_DESC_RECORD_TYPE, - IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */ - EXTENSION_RECORD_TYPE, /* Begin with '!' */ - TERMINATE_RECORD_TYPE /* Begin with ';' */ -} GifRecordType; - -/* func type to read gif data from arbitrary sources (TVT) */ -typedef int (*InputFunc) (GifFileType *, GifByteType *, int); - -/* GIF89 extension function codes */ - -#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */ -#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */ -#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */ -#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */ - -/* public interface to ungif.c */ -int DGifSlurp(GifFileType * GifFile); -GifFileType *DGifOpen(void *userPtr, InputFunc readFunc); -int DGifCloseFile(GifFileType * GifFile); - -#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */ -#define D_GIF_ERR_READ_FAILED 102 -#define D_GIF_ERR_NOT_GIF_FILE 103 -#define D_GIF_ERR_NO_SCRN_DSCR 104 -#define D_GIF_ERR_NO_IMAG_DSCR 105 -#define D_GIF_ERR_NO_COLOR_MAP 106 -#define D_GIF_ERR_WRONG_RECORD 107 -#define D_GIF_ERR_DATA_TOO_BIG 108 -#define D_GIF_ERR_NOT_ENOUGH_MEM 109 -#define D_GIF_ERR_CLOSE_FAILED 110 -#define D_GIF_ERR_NOT_READABLE 111 -#define D_GIF_ERR_IMAGE_DEFECT 112 -#define D_GIF_ERR_EOF_TOO_SOON 113 - -/****************************************************************************** - * Support for the in-core structures allocation (slurp mode). - *****************************************************************************/ - -/* This is the in-core version of an extension record */ -typedef struct { - int ByteCount; - char *Bytes; - int Function; /* Holds the type of the Extension block. */ -} ExtensionBlock; - -/* This holds an image header, its unpacked raster bits, and extensions */ -typedef struct SavedImage { - GifImageDesc ImageDesc; - unsigned char *RasterBits; - int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */ - int ExtensionBlockCount; - ExtensionBlock *ExtensionBlocks; -} SavedImage; - -#endif /* _UNGIF_H_ */ diff --git a/reactos/dll/win32/oleaut32/usrmarshal.c b/reactos/dll/win32/oleaut32/usrmarshal.c index 402794ce333..2414a9ec8e3 100644 --- a/reactos/dll/win32/oleaut32/usrmarshal.c +++ b/reactos/dll/win32/oleaut32/usrmarshal.c @@ -167,11 +167,12 @@ unsigned char * WINAPI BSTR_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, if(header->len != header->len2) FIXME("len %08x != len2 %08x\n", header->len, header->len2); - SysFreeString(*pstr); - *pstr = NULL; - - if(header->byte_len != 0xffffffff) - *pstr = SysAllocStringByteLen((char*)(header + 1), header->byte_len); + if (header->byte_len == 0xffffffff) + { + SysFreeString(*pstr); + *pstr = NULL; + } + else SysReAllocStringLen( pstr, (OLECHAR *)(header + 1), header->len ); if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr)); return Buffer + sizeof(*header) + sizeof(OLECHAR) * header->len; @@ -189,7 +190,7 @@ void WINAPI BSTR_UserFree(ULONG *pFlags, BSTR *pstr) typedef struct { DWORD clSize; - DWORD rpcReserverd; + DWORD rpcReserved; USHORT vt; USHORT wReserved1; USHORT wReserved2; @@ -458,7 +459,7 @@ unsigned char * WINAPI VARIANT_UserMarshal(ULONG *pFlags, unsigned char *Buffer, header = (variant_wire_t *)Buffer; header->clSize = 0; /* fixed up at the end */ - header->rpcReserverd = 0; + header->rpcReserved = 0; header->vt = pvar->n1.n2.vt; header->wReserved1 = pvar->n1.n2.wReserved1; header->wReserved2 = pvar->n1.n2.wReserved2; @@ -898,8 +899,10 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf VARTYPE vt; SAFEARRAY *psa = *ppsa; ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); + SAFEARRAYBOUND *bound; SF_TYPE sftype; GUID guid; + INT i; sftype = SAFEARRAY_GetUnionType(psa); @@ -932,7 +935,12 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf Buffer += sizeof(guid); } - memcpy(Buffer, psa->rgsabound, sizeof(psa->rgsabound[0]) * psa->cDims); + /* bounds are marshaled in opposite order comparing to storage layout */ + bound = (SAFEARRAYBOUND*)Buffer; + for (i = 0; i < psa->cDims; i++) + { + memcpy(bound++, &psa->rgsabound[psa->cDims-i-1], sizeof(psa->rgsabound[0])); + } Buffer += sizeof(psa->rgsabound[0]) * psa->cDims; *(ULONG *)Buffer = ulCellCount; @@ -1078,7 +1086,7 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS)); /* FIXME: there should be a limit on how large wiresa->cbElements can be */ (*ppsa)->cbElements = elem_mem_size(wiresa, sftype); - (*ppsa)->cLocks = LOWORD(wiresa->cLocks); + (*ppsa)->cLocks = 0; /* SafeArrayCreateEx allocates the data for us, but * SafeArrayAllocDescriptor doesn't */ @@ -1591,8 +1599,9 @@ HRESULT CALLBACK ITypeInfo_GetNames_Proxy( UINT cMaxNames, UINT* pcNames) { - FIXME("not implemented\n"); - return E_FAIL; + TRACE("(%p, %08x, %p, %d, %p)\n", This, memid, rgBstrNames, cMaxNames, pcNames); + + return ITypeInfo_RemoteGetNames_Proxy(This, memid, rgBstrNames, cMaxNames, pcNames); } HRESULT __RPC_STUB ITypeInfo_GetNames_Stub( @@ -1602,8 +1611,9 @@ HRESULT __RPC_STUB ITypeInfo_GetNames_Stub( UINT cMaxNames, UINT* pcNames) { - FIXME("not implemented\n"); - return E_FAIL; + TRACE("(%p, %08x, %p, %d, %p)\n", This, memid, rgBstrNames, cMaxNames, pcNames); + + return ITypeInfo_GetNames(This, memid, rgBstrNames, cMaxNames, pcNames); } HRESULT CALLBACK ITypeInfo_GetIDsOfNames_Proxy( @@ -1644,74 +1654,92 @@ HRESULT __RPC_STUB ITypeInfo_Invoke_Stub( return E_FAIL; } -HRESULT CALLBACK ITypeInfo_GetDocumentation_Proxy( - ITypeInfo* This, - MEMBERID memid, - BSTR* pBstrName, - BSTR* pBstrDocString, - DWORD* pdwHelpContext, - BSTR* pBstrHelpFile) +HRESULT CALLBACK ITypeInfo_GetDocumentation_Proxy(ITypeInfo *This, MEMBERID memid, + BSTR *name, BSTR *doc_string, + DWORD *help_context, BSTR *help_file) { - DWORD help_context; - BSTR name, doc_string, help_file; + DWORD dummy_help_context, flags = 0; + BSTR dummy_name, dummy_doc_string, dummy_help_file; HRESULT hr; - TRACE("(%p, %08x, %p, %p, %p, %p)\n", This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); + TRACE("(%p, %08x, %p, %p, %p, %p)\n", This, memid, name, doc_string, help_context, help_file); - /* FIXME: presumably refPtrFlags is supposed to be a bitmask of which ptrs we actually want? */ - hr = ITypeInfo_RemoteGetDocumentation_Proxy(This, memid, 0, &name, &doc_string, &help_context, &help_file); - if(SUCCEEDED(hr)) - { - if(pBstrName) *pBstrName = name; - else SysFreeString(name); + if(!name) name = &dummy_name; + else flags = 1; - if(pBstrDocString) *pBstrDocString = doc_string; - else SysFreeString(doc_string); + if(!doc_string) doc_string = &dummy_doc_string; + else flags |= 2; - if(pBstrHelpFile) *pBstrHelpFile = help_file; - else SysFreeString(help_file); + if(!help_context) help_context = &dummy_help_context; + else flags |= 4; + + if(!help_file) help_file = &dummy_help_file; + else flags |= 8; + + hr = ITypeInfo_RemoteGetDocumentation_Proxy(This, memid, flags, name, doc_string, help_context, help_file); + + /* We don't need to free the dummy BSTRs since the stub ensures that these will be NULLs. */ - if(pdwHelpContext) *pdwHelpContext = help_context; - } return hr; } -HRESULT __RPC_STUB ITypeInfo_GetDocumentation_Stub( - ITypeInfo* This, - MEMBERID memid, - DWORD refPtrFlags, - BSTR* pBstrName, - BSTR* pBstrDocString, - DWORD* pdwHelpContext, - BSTR* pBstrHelpFile) +HRESULT __RPC_STUB ITypeInfo_GetDocumentation_Stub(ITypeInfo *This, MEMBERID memid, + DWORD flags, BSTR *name, BSTR *doc_string, + DWORD *help_context, BSTR *help_file) { - TRACE("(%p, %08x, %08x, %p, %p, %p, %p)\n", This, memid, refPtrFlags, pBstrName, pBstrDocString, - pdwHelpContext, pBstrHelpFile); - return ITypeInfo_GetDocumentation(This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); + TRACE("(%p, %08x, %08x, %p, %p, %p, %p)\n", This, memid, flags, name, doc_string, help_context, help_file); + + *name = *doc_string = *help_file = NULL; + *help_context = 0; + + if(!(flags & 1)) name = NULL; + if(!(flags & 2)) doc_string = NULL; + if(!(flags & 4)) help_context = NULL; + if(!(flags & 8)) help_file = NULL; + + return ITypeInfo_GetDocumentation(This, memid, name, doc_string, help_context, help_file); } -HRESULT CALLBACK ITypeInfo_GetDllEntry_Proxy( - ITypeInfo* This, - MEMBERID memid, - INVOKEKIND invKind, - BSTR* pBstrDllName, - BSTR* pBstrName, - WORD* pwOrdinal) +HRESULT CALLBACK ITypeInfo_GetDllEntry_Proxy(ITypeInfo *This, MEMBERID memid, + INVOKEKIND invkind, BSTR *dll_name, + BSTR* name, WORD *ordinal) { - FIXME("not implemented\n"); - return E_FAIL; + DWORD flags = 0; + BSTR dummy_dll_name, dummy_name; + WORD dummy_ordinal; + HRESULT hr; + TRACE("(%p, %08x, %x, %p, %p, %p)\n", This, memid, invkind, dll_name, name, ordinal); + + if(!dll_name) dll_name = &dummy_dll_name; + else flags = 1; + + if(!name) name = &dummy_name; + else flags |= 2; + + if(!ordinal) ordinal = &dummy_ordinal; + else flags |= 4; + + hr = ITypeInfo_RemoteGetDllEntry_Proxy(This, memid, invkind, flags, dll_name, name, ordinal); + + /* We don't need to free the dummy BSTRs since the stub ensures that these will be NULLs. */ + + return hr; } -HRESULT __RPC_STUB ITypeInfo_GetDllEntry_Stub( - ITypeInfo* This, - MEMBERID memid, - INVOKEKIND invKind, - DWORD refPtrFlags, - BSTR* pBstrDllName, - BSTR* pBstrName, - WORD* pwOrdinal) +HRESULT __RPC_STUB ITypeInfo_GetDllEntry_Stub(ITypeInfo *This, MEMBERID memid, + INVOKEKIND invkind, DWORD flags, + BSTR *dll_name, BSTR *name, + WORD *ordinal) { - FIXME("not implemented\n"); - return E_FAIL; + TRACE("(%p, %08x, %x, %p, %p, %p)\n", This, memid, invkind, dll_name, name, ordinal); + + *dll_name = *name = NULL; + *ordinal = 0; + + if(!(flags & 1)) dll_name = NULL; + if(!(flags & 2)) name = NULL; + if(!(flags & 4)) ordinal = NULL; + + return ITypeInfo_GetDllEntry(This, memid, invkind, dll_name, name, ordinal); } HRESULT CALLBACK ITypeInfo_AddressOfMember_Proxy( @@ -1852,29 +1880,46 @@ HRESULT __RPC_STUB ITypeInfo_ReleaseVarDesc_Stub( /* ITypeInfo2 */ -HRESULT CALLBACK ITypeInfo2_GetDocumentation2_Proxy( - ITypeInfo2* This, - MEMBERID memid, - LCID lcid, - BSTR* pbstrHelpString, - DWORD* pdwHelpStringContext, - BSTR* pbstrHelpStringDll) +HRESULT CALLBACK ITypeInfo2_GetDocumentation2_Proxy(ITypeInfo2 *This, MEMBERID memid, + LCID lcid, BSTR *help_string, + DWORD *help_context, BSTR *help_dll) { - FIXME("not implemented\n"); - return E_FAIL; + DWORD dummy_help_context, flags = 0; + BSTR dummy_help_string, dummy_help_dll; + HRESULT hr; + TRACE("(%p, %08x, %08x, %p, %p, %p)\n", This, memid, lcid, help_string, help_context, help_dll); + + if(!help_string) help_string = &dummy_help_string; + else flags = 1; + + if(!help_context) help_context = &dummy_help_context; + else flags |= 2; + + if(!help_dll) help_dll = &dummy_help_dll; + else flags |= 4; + + hr = ITypeInfo2_RemoteGetDocumentation2_Proxy(This, memid, lcid, flags, help_string, help_context, help_dll); + + /* We don't need to free the dummy BSTRs since the stub ensures that these will be NULLs. */ + + return hr; } -HRESULT __RPC_STUB ITypeInfo2_GetDocumentation2_Stub( - ITypeInfo2* This, - MEMBERID memid, - LCID lcid, - DWORD refPtrFlags, - BSTR* pbstrHelpString, - DWORD* pdwHelpStringContext, - BSTR* pbstrHelpStringDll) +HRESULT __RPC_STUB ITypeInfo2_GetDocumentation2_Stub(ITypeInfo2 *This, MEMBERID memid, + LCID lcid, DWORD flags, + BSTR *help_string, DWORD *help_context, + BSTR *help_dll) { - FIXME("not implemented\n"); - return E_FAIL; + TRACE("(%p, %08x, %08x, %08x, %p, %p, %p)\n", This, memid, lcid, flags, help_string, help_context, help_dll); + + *help_string = *help_dll = NULL; + *help_context = 0; + + if(!(flags & 1)) help_string = NULL; + if(!(flags & 2)) help_context = NULL; + if(!(flags & 4)) help_dll = NULL; + + return ITypeInfo2_GetDocumentation2(This, memid, lcid, help_string, help_context, help_dll); } /* ITypeLib */ @@ -1932,29 +1977,49 @@ HRESULT __RPC_STUB ITypeLib_GetLibAttr_Stub( return hr; } -HRESULT CALLBACK ITypeLib_GetDocumentation_Proxy( - ITypeLib* This, - INT index, - BSTR* pBstrName, - BSTR* pBstrDocString, - DWORD* pdwHelpContext, - BSTR* pBstrHelpFile) +HRESULT CALLBACK ITypeLib_GetDocumentation_Proxy(ITypeLib *This, INT index, BSTR *name, + BSTR *doc_string, DWORD *help_context, + BSTR *help_file) { - FIXME("not implemented\n"); - return E_FAIL; + DWORD dummy_help_context, flags = 0; + BSTR dummy_name, dummy_doc_string, dummy_help_file; + HRESULT hr; + TRACE("(%p, %d, %p, %p, %p, %p)\n", This, index, name, doc_string, help_context, help_file); + + if(!name) name = &dummy_name; + else flags = 1; + + if(!doc_string) doc_string = &dummy_doc_string; + else flags |= 2; + + if(!help_context) help_context = &dummy_help_context; + else flags |= 4; + + if(!help_file) help_file = &dummy_help_file; + else flags |= 8; + + hr = ITypeLib_RemoteGetDocumentation_Proxy(This, index, flags, name, doc_string, help_context, help_file); + + /* We don't need to free the dummy BSTRs since the stub ensures that these will be NULLs. */ + + return hr; } -HRESULT __RPC_STUB ITypeLib_GetDocumentation_Stub( - ITypeLib* This, - INT index, - DWORD refPtrFlags, - BSTR* pBstrName, - BSTR* pBstrDocString, - DWORD* pdwHelpContext, - BSTR* pBstrHelpFile) +HRESULT __RPC_STUB ITypeLib_GetDocumentation_Stub(ITypeLib *This, INT index, DWORD flags, + BSTR *name, BSTR *doc_string, + DWORD *help_context, BSTR *help_file) { - FIXME("not implemented\n"); - return E_FAIL; + TRACE("(%p, %d, %08x, %p, %p, %p, %p)\n", This, index, flags, name, doc_string, help_context, help_file); + + *name = *doc_string = *help_file = NULL; + *help_context = 0; + + if(!(flags & 1)) name = NULL; + if(!(flags & 2)) doc_string = NULL; + if(!(flags & 4)) help_context = NULL; + if(!(flags & 8)) help_file = NULL; + + return ITypeLib_GetDocumentation(This, index, name, doc_string, help_context, help_file); } HRESULT CALLBACK ITypeLib_IsName_Proxy( @@ -2039,29 +2104,45 @@ HRESULT __RPC_STUB ITypeLib2_GetLibStatistics_Stub( return E_FAIL; } -HRESULT CALLBACK ITypeLib2_GetDocumentation2_Proxy( - ITypeLib2* This, - INT index, - LCID lcid, - BSTR* pbstrHelpString, - DWORD* pdwHelpStringContext, - BSTR* pbstrHelpStringDll) +HRESULT CALLBACK ITypeLib2_GetDocumentation2_Proxy(ITypeLib2 *This, INT index, + LCID lcid, BSTR *help_string, + DWORD *help_context, BSTR *help_dll) { - FIXME("not implemented\n"); - return E_FAIL; + DWORD dummy_help_context, flags = 0; + BSTR dummy_help_string, dummy_help_dll; + HRESULT hr; + TRACE("(%p, %d, %08x, %p, %p, %p)\n", This, index, lcid, help_string, help_context, help_dll); + + if(!help_string) help_string = &dummy_help_string; + else flags = 1; + + if(!help_context) help_context = &dummy_help_context; + else flags |= 2; + + if(!help_dll) help_dll = &dummy_help_dll; + else flags |= 4; + + hr = ITypeLib2_RemoteGetDocumentation2_Proxy(This, index, lcid, flags, help_string, help_context, help_dll); + + /* We don't need to free the dummy BSTRs since the stub ensures that these will be NULLs. */ + + return hr; } -HRESULT __RPC_STUB ITypeLib2_GetDocumentation2_Stub( - ITypeLib2* This, - INT index, - LCID lcid, - DWORD refPtrFlags, - BSTR* pbstrHelpString, - DWORD* pdwHelpStringContext, - BSTR* pbstrHelpStringDll) +HRESULT __RPC_STUB ITypeLib2_GetDocumentation2_Stub(ITypeLib2 *This, INT index, LCID lcid, + DWORD flags, BSTR *help_string, + DWORD *help_context, BSTR *help_dll) { - FIXME("not implemented\n"); - return E_FAIL; + TRACE("(%p, %d, %08x, %08x, %p, %p, %p)\n", This, index, lcid, flags, help_string, help_context, help_dll); + + *help_string = *help_dll = NULL; + *help_context = 0; + + if(!(flags & 1)) help_string = NULL; + if(!(flags & 2)) help_context = NULL; + if(!(flags & 4)) help_dll = NULL; + + return ITypeLib2_GetDocumentation2(This, index, lcid, help_string, help_context, help_dll); } HRESULT CALLBACK IPropertyBag_Read_Proxy( @@ -2110,7 +2191,7 @@ HRESULT __RPC_STUB IPropertyBag_Read_Stub( DWORD varType, IUnknown *pUnkObj) { - static const WCHAR emptyWstr[1] = {0}; + static const WCHAR emptyWstr[] = {0}; IDispatch *disp; HRESULT hr; TRACE("(%p, %s, %p, %p, %x, %p)\n", This, debugstr_w(pszPropName), pVar, diff --git a/reactos/dll/win32/oleaut32/varformat.c b/reactos/dll/win32/oleaut32/varformat.c index f2976416655..351529c596e 100644 --- a/reactos/dll/win32/oleaut32/varformat.c +++ b/reactos/dll/win32/oleaut32/varformat.c @@ -263,7 +263,7 @@ typedef struct tagFMT_DATE_HEADER #define FMT_DATE_HOUR_0 0x1F /* Hours with leading 0 */ #define FMT_DATE_HOUR_12 0x20 /* Hours with no leading 0, 12 hour clock */ #define FMT_DATE_HOUR_12_0 0x21 /* Hours with leading 0, 12 hour clock */ -#define FMT_DATE_TIME_UNK2 0x23 +#define FMT_DATE_TIME_UNK2 0x23 /* same as FMT_DATE_HOUR_0, for "short time" format */ /* FIXME: probably missing some here */ #define FMT_DATE_AMPM_SYS1 0x2E /* AM/PM as defined by system settings */ #define FMT_DATE_AMPM_UPPER 0x2F /* Upper-case AM or PM */ @@ -1660,6 +1660,13 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat, pToken += 2; break; + case FMT_GEN_INLINE: + pToken += 2; + TRACE("copy %s\n", debugstr_a((LPCSTR)pToken)); + while (*pToken) + *pBuff++ = *pToken++; + break; + case FMT_DATE_TIME_SEP: TRACE("time separator\n"); localeValue = LOCALE_STIME; @@ -1725,14 +1732,14 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat, case FMT_DATE_DAY_SHORT: /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ TRACE("short day\n"); - localeValue = LOCALE_SABBREVDAYNAME1 + udate.st.wMonth - 1; + localeValue = LOCALE_SABBREVDAYNAME1 + (udate.st.wDayOfWeek + 6)%7; defaultChar = '?'; break; case FMT_DATE_DAY_LONG: /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ TRACE("long day\n"); - localeValue = LOCALE_SDAYNAME1 + udate.st.wMonth - 1; + localeValue = LOCALE_SDAYNAME1 + (udate.st.wDayOfWeek + 6)%7; defaultChar = '?'; break; @@ -1836,6 +1843,7 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat, break; case FMT_DATE_HOUR_0: + case FMT_DATE_TIME_UNK2: szPrintFmt = szPercentZeroTwo_d; dwVal = udate.st.wHour; break; @@ -2482,11 +2490,11 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading, if (nGrouping == -2) { - WCHAR nGrouping[16]; - nGrouping[2] = '\0'; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, nGrouping, - sizeof(nGrouping)/sizeof(WCHAR)); - numfmt.Grouping = nGrouping[2] == '2' ? 32 : nGrouping[0] - '0'; + WCHAR grouping[16]; + grouping[2] = '\0'; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, + sizeof(grouping)/sizeof(WCHAR)); + numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0'; } else if (nGrouping == -1) numfmt.Grouping = 3; /* 3 = "n,nnn.nn" */ diff --git a/reactos/dll/win32/oleaut32/variant.c b/reactos/dll/win32/oleaut32/variant.c index 3d8e528d731..21a27587969 100644 --- a/reactos/dll/win32/oleaut32/variant.c +++ b/reactos/dll/win32/oleaut32/variant.c @@ -526,7 +526,7 @@ static inline HRESULT VARIANT_CoerceArray(VARIANTARG* pd, VARIANTARG* ps, VARTYP return BstrFromVector(V_ARRAY(ps), &V_BSTR(pd)); if (V_VT(ps) == VT_BSTR && vt == (VT_ARRAY|VT_UI1)) - return VectorFromBstr(V_BSTR(ps), &V_ARRAY(ps)); + return VectorFromBstr(V_BSTR(ps), &V_ARRAY(pd)); if (V_VT(ps) == vt) return SafeArrayCopy(V_ARRAY(ps), &V_ARRAY(pd)); @@ -652,7 +652,7 @@ HRESULT VARIANT_ClearInd(VARIANTARG *pVarg) */ HRESULT WINAPI VariantClear(VARIANTARG* pVarg) { - HRESULT hres = S_OK; + HRESULT hres; TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg)); @@ -664,8 +664,7 @@ HRESULT WINAPI VariantClear(VARIANTARG* pVarg) { if (V_ISARRAY(pVarg) || V_VT(pVarg) == VT_SAFEARRAY) { - if (V_ARRAY(pVarg)) - hres = SafeArrayDestroy(V_ARRAY(pVarg)); + hres = SafeArrayDestroy(V_ARRAY(pVarg)); } else if (V_VT(pVarg) == VT_BSTR) { @@ -873,7 +872,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc) /* Argument checking is more lax than VariantCopy()... */ vt = V_TYPE(pvargSrc); - if (V_ISARRAY(pvargSrc) || + if (V_ISARRAY(pvargSrc) || (V_VT(pvargSrc) == (VT_RECORD|VT_BYREF)) || (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID && !(V_VT(pvargSrc) & (VT_VECTOR|VT_RESERVED)))) { @@ -1144,8 +1143,11 @@ static HRESULT VARIANT_RollUdate(UDATE *lpUd) if (iYear > 9999 || iYear < -9999) return E_INVALIDARG; /* Invalid value */ - /* Years < 100 are treated as 1900 + year */ - if (iYear > 0 && iYear < 100) + /* Year 0 to 29 are treated as 2000 + year */ + if (iYear >= 0 && iYear < 30) + iYear += 2000; + /* Remaining years < 100 are treated as 1900 + year */ + else if (iYear >= 30 && iYear < 100) iYear += 1900; iMinute += iSecond / 60; @@ -1359,7 +1361,7 @@ INT WINAPI VariantTimeToSystemTime(double dateIn, LPSYSTEMTIME lpSt) HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DATE *pDateOut) { UDATE ud; - double dateVal; + double dateVal, dateSign; TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08x,0x%08x,%p)\n", pUdateIn, pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear, @@ -1381,10 +1383,13 @@ HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DAT /* Date */ dateVal = VARIANT_DateFromJulian(VARIANT_JulianFromDMY(ud.st.wYear, ud.st.wMonth, ud.st.wDay)); + /* Sign */ + dateSign = (dateVal < 0.0) ? -1.0 : 1.0; + /* Time */ - dateVal += ud.st.wHour / 24.0; - dateVal += ud.st.wMinute / 1440.0; - dateVal += ud.st.wSecond / 86400.0; + dateVal += ud.st.wHour / 24.0 * dateSign; + dateVal += ud.st.wMinute / 1440.0 * dateSign; + dateVal += ud.st.wSecond / 86400.0 * dateSign; TRACE("Returning %g\n", dateVal); *pDateOut = dateVal; @@ -1447,7 +1452,7 @@ HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate) datePart = dateIn < 0.0 ? ceil(dateIn) : floor(dateIn); /* Compensate for int truncation (always downwards) */ - timePart = dateIn - datePart + 0.00000000001; + timePart = fabs(dateIn - datePart) + 0.00000000001; if (timePart >= 1.0) timePart -= 0.00000000001; @@ -1605,7 +1610,7 @@ static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID * from "oleauto.h". * * FIXME - * - I am unsure if this function should parse non-arabic (e.g. Thai) + * - I am unsure if this function should parse non-Arabic (e.g. Thai) * numerals, so this has not been implemented. */ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags, @@ -2183,7 +2188,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig, /* Convert the integer part of the number into a UI8 */ for (i = 0; i < wholeNumberDigits; i++) { - if (ul64 > (UI8_MAX / 10 - rgbDig[i])) + if (ul64 > UI8_MAX / 10 || (ul64 == UI8_MAX / 10 && rgbDig[i] > UI8_MAX % 10)) { TRACE("Overflow multiplying digits\n"); bOverflow = TRUE; @@ -2247,7 +2252,7 @@ HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig, } /* Zero is not a negative number */ - bNegative = pNumprs->dwOutFlags & NUMPRS_NEG && ul64 ? TRUE : FALSE; + bNegative = pNumprs->dwOutFlags & NUMPRS_NEG && ul64; TRACE("Integer value is 0x%s, bNeg %d\n", wine_dbgstr_longlong(ul64), bNegative); @@ -2622,7 +2627,7 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out) { /* Bools are handled as localized True/False strings instead of 0/-1 as in MSDN */ V_VT(&bstrvar_left) = VT_BSTR; - if (V_BOOL(left) == TRUE) + if (V_BOOL(left)) V_BSTR(&bstrvar_left) = SysAllocString(str_true); else V_BSTR(&bstrvar_left) = SysAllocString(str_false); @@ -2662,7 +2667,7 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out) { /* Bools are handled as localized True/False strings instead of 0/-1 as in MSDN */ V_VT(&bstrvar_right) = VT_BSTR; - if (V_BOOL(right) == TRUE) + if (V_BOOL(right)) V_BSTR(&bstrvar_right) = SysAllocString(str_true); else V_BSTR(&bstrvar_right) = SysAllocString(str_false); @@ -2717,15 +2722,10 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out) static HRESULT _VarChangeTypeExWrap (VARIANTARG* pvargDest, VARIANTARG* pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt) { - HRESULT res; - VARTYPE flags; + VARIANTARG vtmpsrc = *pvargSrc; - flags = V_VT(pvargSrc) & ~VT_TYPEMASK; - V_VT(pvargSrc) &= ~VT_RESERVED; - res = VariantChangeTypeEx(pvargDest,pvargSrc,lcid,wFlags,vt); - V_VT(pvargSrc) |= flags; - - return res; + V_VT(&vtmpsrc) &= ~VT_RESERVED; + return VariantChangeTypeEx(pvargDest,&vtmpsrc,lcid,wFlags,vt); } /********************************************************************** @@ -2817,7 +2817,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) if (xmask == VTBIT_BSTR) return VarBstrCmp(V_BSTR(left), V_BSTR(right), lcid, flags); - /* A BSTR and an other variant; we have to take care of VT_RESERVED */ + /* A BSTR and another variant; we have to take care of VT_RESERVED */ if (xmask & VTBIT_BSTR) { VARIANT *bstrv, *nonbv; VARTYPE nonbvt; @@ -5026,6 +5026,19 @@ HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut) pVarIn = &temp; } + if (V_VT(pVarIn) == VT_BSTR) + { + V_VT(&varIn) = VT_R8; + hRet = VarR8FromStr( V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn) ); + if (FAILED(hRet)) + { + V_VT(&varIn) = VT_BOOL; + hRet = VarBoolFromStr( V_BSTR(pVarIn), LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &V_BOOL(&varIn) ); + } + if (FAILED(hRet)) goto VarNot_Exit; + pVarIn = &varIn; + } + V_VT(pVarOut) = V_VT(pVarIn); switch (V_VT(pVarIn)) @@ -5066,12 +5079,6 @@ HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut) V_I4(pVarOut) = ~V_I4(pVarOut); V_VT(pVarOut) = VT_I4; break; - case VT_BSTR: - hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn)); - if (FAILED(hRet)) - break; - pVarIn = &varIn; - /* Fall through ... */ case VT_DATE: case VT_R8: hRet = VarI4FromR8(V_R8(pVarIn), &V_I4(pVarOut)); diff --git a/reactos/dll/win32/oleaut32/vartype.c b/reactos/dll/win32/oleaut32/vartype.c index 8f54eae2fbb..2d27f9df195 100644 --- a/reactos/dll/win32/oleaut32/vartype.c +++ b/reactos/dll/win32/oleaut32/vartype.c @@ -1655,7 +1655,7 @@ HRESULT WINAPI VarI4FromBool(VARIANT_BOOL boolIn, LONG *piOut) /************************************************************************ * VarI4FromI1 (OLEAUT32.209) * - * Convert a VT_I4 to a VT_I4. + * Convert a VT_I1 to a VT_I4. * * PARAMS * cIn [I] Source @@ -3764,7 +3764,7 @@ HRESULT WINAPI VarCyFromI8(LONG64 llIn, CY* pCyOut) */ HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut) { - if (ullIn >= (I8_MAX/CY_MULTIPLIER)) return DISP_E_OVERFLOW; + if (ullIn > (I8_MAX/CY_MULTIPLIER)) return DISP_E_OVERFLOW; pCyOut->int64 = ullIn * CY_MULTIPLIER; return S_OK; } @@ -4562,6 +4562,7 @@ HRESULT WINAPI VarDecAdd(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI /* Our decimals now have the same scale, we can add them as 96 bit integers */ ULONG overflow = 0; BYTE sign = DECIMAL_POS; + int cmp; /* Correct for the sign of the result */ if (DEC_SIGN(pDecLeft) && DEC_SIGN(pDecRight)) @@ -4572,7 +4573,7 @@ HRESULT WINAPI VarDecAdd(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI } else if (DEC_SIGN(pDecLeft) && !DEC_SIGN(pDecRight)) { - int cmp = VARIANT_DecCmp(pDecLeft, pDecRight); + cmp = VARIANT_DecCmp(pDecLeft, pDecRight); /* -x + y : Negative if x > y */ if (cmp > 0) @@ -4593,7 +4594,7 @@ VarDecAdd_AsInvertedNegative: } else if (!DEC_SIGN(pDecLeft) && DEC_SIGN(pDecRight)) { - int cmp = VARIANT_DecCmp(pDecLeft, pDecRight); + cmp = VARIANT_DecCmp(pDecLeft, pDecRight); /* x + -y : Negative if x <= y */ if (cmp <= 0) @@ -6407,7 +6408,7 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID lcid, ULONG dwFl { WCHAR *p; WCHAR numbuff[256]; - WCHAR empty[1] = {'\0'}; + WCHAR empty[] = {'\0'}; NUMBERFMTW minFormat; minFormat.NumDigits = 0; @@ -7016,7 +7017,7 @@ HRESULT WINAPI VarBstrCmp(BSTR pbstrLeft, BSTR pbstrRight, LCID lcid, DWORD dwFl } hres = CompareStringW(lcid, dwFlags, pbstrLeft, lenLeft, - pbstrRight, lenRight) - 1; + pbstrRight, lenRight) - CSTR_LESS_THAN; TRACE("%d\n", hres); return hres; } @@ -7282,7 +7283,7 @@ VARIANT_MakeDate_Start: switch (iDate) { case 0: dwTry = dwAllOrders & ~(ORDER_DMY|ORDER_YDM); break; - case 1: dwTry = dwAllOrders & ~(ORDER_MDY|ORDER_YMD|ORDER_MYD); break; + case 1: dwTry = dwAllOrders & ~(ORDER_MDY|ORDER_YDM|ORDER_MYD); break; default: dwTry = dwAllOrders & ~(ORDER_DMY|ORDER_YDM); break; } } diff --git a/reactos/dll/win32/oleaut32/version.rc b/reactos/dll/win32/oleaut32/version.rc deleted file mode 100644 index 6887af389bc..00000000000 --- a/reactos/dll/win32/oleaut32/version.rc +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2001 Dmitry Timoshkov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#define WINE_OLESELFREGISTER -#define WINE_FILEDESCRIPTION_STR "Wine OLE dll" -#define WINE_FILENAME_STR "oleaut32.dll" -#define WINE_FILEVERSION 6, 0, 6001, 18000 /* version from Vista SP1 */ -#define WINE_FILEVERSION_STR "6.0.6001.18000" - -#include "wine/wine_common_ver.rc" diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 1c20641a79f..012a512b7c3 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -132,7 +132,7 @@ reactos/dll/win32/odbc32 # Out of sync. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to Wine-1.5.19 reactos/dll/win32/ole32 # Synced to Wine-1.5.4 reactos/dll/win32/oleacc # Autosync -reactos/dll/win32/oleaut32 # Autosync +reactos/dll/win32/oleaut32 # Synced to Wine-1.5.19 reactos/dll/win32/olecli32 # Synced to Wine-1.5.19 reactos/dll/win32/oledlg # Autosync reactos/dll/win32/olepro32 # Autosync