mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 12:23:28 +00:00
[OLEAUT32]
* Sync to Wine 1.5.19. svn path=/trunk/; revision=57889
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
+1272
-1095
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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,
|
||||
|
||||
@@ -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" */
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user