[OLEAUT32]

* Sync to Wine 1.5.19.

svn path=/trunk/; revision=57889
This commit is contained in:
Amine Khaldi
2012-12-12 13:52:25 +00:00
parent 1e6bd4d298
commit e00952317b
29 changed files with 4141 additions and 4622 deletions
+8 -18
View File
@@ -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)
+32 -23
View File
@@ -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;
}
+16 -11
View File
@@ -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;
}
+192 -140
View File
@@ -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; i<n; i++)
bstr->u.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)
*/
+15 -3
View File
@@ -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"
+57
View File
@@ -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}'
}
}
}
@@ -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; }
@@ -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' }
}
}
}
@@ -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 { }
@@ -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}'
}
}
File diff suppressed because it is too large Load Diff
+195 -185
View File
@@ -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; }
+346
View File
@@ -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 <stdarg.h>
#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; i<lpParams->cPages; 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; i<lpParams->cPages; 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);
}
+37 -25
View File
@@ -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;
}
-556
View File
@@ -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 <stdarg.h>
#include <string.h>
#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;
}
+8 -7
View File
@@ -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))
{
-56
View File
@@ -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 <stdarg.h>
#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;
}
+176 -90
View File
@@ -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;i<arrsize;i++) {
hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (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 && (i<arrsize-1)) TRACE_(olerelay)(",");
@@ -916,6 +972,7 @@ deserialize_param(
}
return S_OK;
}
case VT_DATE:
case VT_I8:
case VT_UI8:
case VT_R8:
@@ -927,7 +984,6 @@ deserialize_param(
if (debugout) TRACE_(olerelay)("%x%x",arg[0],arg[1]);
return hres;
case VT_ERROR:
case VT_BOOL:
case VT_I4:
case VT_INT:
case VT_UINT:
@@ -941,6 +997,7 @@ deserialize_param(
return hres;
case VT_I2:
case VT_UI2:
case VT_BOOL:
if (readit) {
DWORD x;
hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD));
@@ -1015,7 +1072,7 @@ deserialize_param(
ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
ITypeInfo_Release(tinfo2);
}
/* read it in all cases, we need to know if we have
/* read it in all cases, we need to know if we have
* NULL pointer or not.
*/
hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie));
@@ -1086,7 +1143,7 @@ deserialize_param(
for (i=0;i<tattr->cVars;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 && (i<tattr->cVars-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;i<adesc->cDims;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;i<arrsize;i++)
deserialize_param(
tinfo,
@@ -1146,7 +1208,7 @@ deserialize_param(
debugout,
alloc,
&adesc->tdescElem,
(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");
File diff suppressed because it is too large Load Diff
+23 -17
View File
@@ -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);
File diff suppressed because it is too large Load Diff
-999
View File
@@ -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 <stdlib.h>
#include <string.h>
#include "ungif.h"
#include <stdarg.h>
#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;
}
-169
View File
@@ -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_ */
+204 -123
View File
@@ -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,
+16 -8
View File
@@ -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" */
+39 -32
View File
@@ -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));
+8 -7
View File
@@ -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;
}
}
-25
View File
@@ -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"
+1 -1
View File
@@ -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