shlwapi/tests: Testing framework and IConnection point tests.
This commit is contained in:
parent
deef2c5ac2
commit
23cea50db2
|
@ -19,12 +19,14 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "ole2.h"
|
#include "ole2.h"
|
||||||
#include "oaidl.h"
|
#include "oaidl.h"
|
||||||
|
#include "ocidl.h"
|
||||||
|
|
||||||
/* Function ptrs for ordinal calls */
|
/* Function ptrs for ordinal calls */
|
||||||
static HMODULE hShlwapi;
|
static HMODULE hShlwapi;
|
||||||
|
@ -36,6 +38,9 @@ static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
|
||||||
static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
|
static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
|
||||||
static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
|
static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
|
||||||
static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
|
static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
|
||||||
|
static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID,DISPPARAMS*);
|
||||||
|
static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD);
|
||||||
|
static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **);
|
||||||
|
|
||||||
static void test_GetAcceptLanguagesA(void)
|
static void test_GetAcceptLanguagesA(void)
|
||||||
{ HRESULT retval;
|
{ HRESULT retval;
|
||||||
|
@ -523,6 +528,683 @@ static void test_SHPackDispParams(void)
|
||||||
ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
|
ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _disp
|
||||||
|
{
|
||||||
|
const IDispatchVtbl *vtbl;
|
||||||
|
LONG refCount;
|
||||||
|
} Disp;
|
||||||
|
|
||||||
|
typedef struct _contain
|
||||||
|
{
|
||||||
|
const IConnectionPointContainerVtbl *vtbl;
|
||||||
|
LONG refCount;
|
||||||
|
|
||||||
|
UINT ptCount;
|
||||||
|
IConnectionPoint **pt;
|
||||||
|
} Contain;
|
||||||
|
|
||||||
|
typedef struct _cntptn
|
||||||
|
{
|
||||||
|
const IConnectionPointVtbl *vtbl;
|
||||||
|
LONG refCount;
|
||||||
|
|
||||||
|
Contain *container;
|
||||||
|
GUID id;
|
||||||
|
UINT sinkCount;
|
||||||
|
IUnknown **sink;
|
||||||
|
} ConPt;
|
||||||
|
|
||||||
|
typedef struct _enum
|
||||||
|
{
|
||||||
|
const IEnumConnectionsVtbl *vtbl;
|
||||||
|
LONG refCount;
|
||||||
|
|
||||||
|
UINT idx;
|
||||||
|
ConPt *pt;
|
||||||
|
} EnumCon;
|
||||||
|
|
||||||
|
typedef struct _enumpt
|
||||||
|
{
|
||||||
|
const IEnumConnectionPointsVtbl *vtbl;
|
||||||
|
LONG refCount;
|
||||||
|
|
||||||
|
int idx;
|
||||||
|
Contain *container;
|
||||||
|
} EnumPt;
|
||||||
|
|
||||||
|
|
||||||
|
static HRESULT WINAPI Disp_QueryInterface(
|
||||||
|
IDispatch* This,
|
||||||
|
REFIID riid,
|
||||||
|
void **ppvObject)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
*ppvObject = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
|
||||||
|
{
|
||||||
|
*ppvObject = This;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ppvObject)
|
||||||
|
{
|
||||||
|
IUnknown_AddRef(This);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("no interface\n");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI Disp_AddRef(IDispatch* This)
|
||||||
|
{
|
||||||
|
Disp *iface = (Disp*)This;
|
||||||
|
return InterlockedIncrement(&iface->refCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI Disp_Release(IDispatch* This)
|
||||||
|
{
|
||||||
|
Disp *iface = (Disp*)This;
|
||||||
|
ULONG ret;
|
||||||
|
|
||||||
|
ret = InterlockedDecrement(&iface->refCount);
|
||||||
|
if (ret == 0)
|
||||||
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Disp_GetTypeInfoCount(
|
||||||
|
IDispatch* This,
|
||||||
|
UINT *pctinfo)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Disp_GetTypeInfo(
|
||||||
|
IDispatch* This,
|
||||||
|
UINT iTInfo,
|
||||||
|
LCID lcid,
|
||||||
|
ITypeInfo **ppTInfo)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Disp_GetIDsOfNames(
|
||||||
|
IDispatch* This,
|
||||||
|
REFIID riid,
|
||||||
|
LPOLESTR *rgszNames,
|
||||||
|
UINT cNames,
|
||||||
|
LCID lcid,
|
||||||
|
DISPID *rgDispId)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Disp_Invoke(
|
||||||
|
IDispatch* This,
|
||||||
|
DISPID dispIdMember,
|
||||||
|
REFIID riid,
|
||||||
|
LCID lcid,
|
||||||
|
WORD wFlags,
|
||||||
|
DISPPARAMS *pDispParams,
|
||||||
|
VARIANT *pVarResult,
|
||||||
|
EXCEPINFO *pExcepInfo,
|
||||||
|
UINT *puArgErr)
|
||||||
|
{
|
||||||
|
trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
|
||||||
|
|
||||||
|
ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n");
|
||||||
|
ok(pDispParams != NULL, "Invoked with NULL pDispParams\n");
|
||||||
|
ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags);
|
||||||
|
ok(lcid == 0,"Wrong lcid %x\n",lcid);
|
||||||
|
if (dispIdMember == 0xa0)
|
||||||
|
{
|
||||||
|
ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs);
|
||||||
|
ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
|
||||||
|
ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
|
||||||
|
ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg);
|
||||||
|
}
|
||||||
|
else if (dispIdMember == 0xa1)
|
||||||
|
{
|
||||||
|
ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs);
|
||||||
|
ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
|
||||||
|
ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
|
||||||
|
ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg));
|
||||||
|
ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg));
|
||||||
|
ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1));
|
||||||
|
ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IDispatchVtbl disp_vtbl = {
|
||||||
|
Disp_QueryInterface,
|
||||||
|
Disp_AddRef,
|
||||||
|
Disp_Release,
|
||||||
|
|
||||||
|
Disp_GetTypeInfoCount,
|
||||||
|
Disp_GetTypeInfo,
|
||||||
|
Disp_GetIDsOfNames,
|
||||||
|
Disp_Invoke
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI Enum_QueryInterface(
|
||||||
|
IEnumConnections* This,
|
||||||
|
REFIID riid,
|
||||||
|
void **ppvObject)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
*ppvObject = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections))
|
||||||
|
{
|
||||||
|
*ppvObject = This;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ppvObject)
|
||||||
|
{
|
||||||
|
IUnknown_AddRef(This);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("no interface\n");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI Enum_AddRef(IEnumConnections* This)
|
||||||
|
{
|
||||||
|
EnumCon *iface = (EnumCon*)This;
|
||||||
|
return InterlockedIncrement(&iface->refCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI Enum_Release(IEnumConnections* This)
|
||||||
|
{
|
||||||
|
EnumCon *iface = (EnumCon*)This;
|
||||||
|
ULONG ret;
|
||||||
|
|
||||||
|
ret = InterlockedDecrement(&iface->refCount);
|
||||||
|
if (ret == 0)
|
||||||
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Enum_Next(
|
||||||
|
IEnumConnections* This,
|
||||||
|
ULONG cConnections,
|
||||||
|
LPCONNECTDATA rgcd,
|
||||||
|
ULONG *pcFetched)
|
||||||
|
{
|
||||||
|
EnumCon *iface = (EnumCon*)This;
|
||||||
|
|
||||||
|
trace("\n");
|
||||||
|
if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
|
||||||
|
{
|
||||||
|
rgcd->pUnk = iface->pt->sink[iface->idx];
|
||||||
|
IUnknown_AddRef(iface->pt->sink[iface->idx]);
|
||||||
|
rgcd->dwCookie=0xff;
|
||||||
|
if (pcFetched)
|
||||||
|
*pcFetched = 1;
|
||||||
|
iface->idx++;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Enum_Skip(
|
||||||
|
IEnumConnections* This,
|
||||||
|
ULONG cConnections)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Enum_Reset(
|
||||||
|
IEnumConnections* This)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Enum_Clone(
|
||||||
|
IEnumConnections* This,
|
||||||
|
IEnumConnections **ppEnum)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IEnumConnectionsVtbl enum_vtbl = {
|
||||||
|
|
||||||
|
Enum_QueryInterface,
|
||||||
|
Enum_AddRef,
|
||||||
|
Enum_Release,
|
||||||
|
Enum_Next,
|
||||||
|
Enum_Skip,
|
||||||
|
Enum_Reset,
|
||||||
|
Enum_Clone
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConPt_QueryInterface(
|
||||||
|
IConnectionPoint* This,
|
||||||
|
REFIID riid,
|
||||||
|
void **ppvObject)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
*ppvObject = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint))
|
||||||
|
{
|
||||||
|
*ppvObject = This;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ppvObject)
|
||||||
|
{
|
||||||
|
IUnknown_AddRef(This);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("no interface\n");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI ConPt_AddRef(
|
||||||
|
IConnectionPoint* This)
|
||||||
|
{
|
||||||
|
ConPt *iface = (ConPt*)This;
|
||||||
|
return InterlockedIncrement(&iface->refCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI ConPt_Release(
|
||||||
|
IConnectionPoint* This)
|
||||||
|
{
|
||||||
|
ConPt *iface = (ConPt*)This;
|
||||||
|
ULONG ret;
|
||||||
|
|
||||||
|
ret = InterlockedDecrement(&iface->refCount);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
if (iface->sinkCount > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < iface->sinkCount; i++)
|
||||||
|
{
|
||||||
|
if (iface->sink[i])
|
||||||
|
IUnknown_Release(iface->sink[i]);
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(),0,iface->sink);
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConPt_GetConnectionInterface(
|
||||||
|
IConnectionPoint* This,
|
||||||
|
IID *pIID)
|
||||||
|
{
|
||||||
|
static int i = 0;
|
||||||
|
ConPt *iface = (ConPt*)This;
|
||||||
|
trace("\n");
|
||||||
|
if (i==0)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memcpy(pIID,&iface->id,sizeof(GUID));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConPt_GetConnectionPointContainer(
|
||||||
|
IConnectionPoint* This,
|
||||||
|
IConnectionPointContainer **ppCPC)
|
||||||
|
{
|
||||||
|
ConPt *iface = (ConPt*)This;
|
||||||
|
trace("\n");
|
||||||
|
|
||||||
|
*ppCPC = (IConnectionPointContainer*)iface->container;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConPt_Advise(
|
||||||
|
IConnectionPoint* This,
|
||||||
|
IUnknown *pUnkSink,
|
||||||
|
DWORD *pdwCookie)
|
||||||
|
{
|
||||||
|
ConPt *iface = (ConPt*)This;
|
||||||
|
trace("\n");
|
||||||
|
|
||||||
|
if (iface->sinkCount == 0)
|
||||||
|
iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
|
||||||
|
else
|
||||||
|
iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
|
||||||
|
iface->sink[iface->sinkCount] = pUnkSink;
|
||||||
|
IUnknown_AddRef(pUnkSink);
|
||||||
|
iface->sinkCount++;
|
||||||
|
*pdwCookie = iface->sinkCount;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConPt_Unadvise(
|
||||||
|
IConnectionPoint* This,
|
||||||
|
DWORD dwCookie)
|
||||||
|
{
|
||||||
|
ConPt *iface = (ConPt*)This;
|
||||||
|
trace("\n");
|
||||||
|
|
||||||
|
if (dwCookie > iface->sinkCount)
|
||||||
|
return E_FAIL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IUnknown_Release(iface->sink[dwCookie-1]);
|
||||||
|
iface->sink[dwCookie-1] = NULL;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI ConPt_EnumConnections(
|
||||||
|
IConnectionPoint* This,
|
||||||
|
IEnumConnections **ppEnum)
|
||||||
|
{
|
||||||
|
EnumCon *ec;
|
||||||
|
|
||||||
|
trace("\n");
|
||||||
|
ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
|
||||||
|
ec->vtbl = &enum_vtbl;
|
||||||
|
ec->refCount = 1;
|
||||||
|
ec->pt = (ConPt*)This;
|
||||||
|
ec->idx = 0;
|
||||||
|
*ppEnum = (IEnumConnections*)ec;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IConnectionPointVtbl point_vtbl = {
|
||||||
|
ConPt_QueryInterface,
|
||||||
|
ConPt_AddRef,
|
||||||
|
ConPt_Release,
|
||||||
|
|
||||||
|
ConPt_GetConnectionInterface,
|
||||||
|
ConPt_GetConnectionPointContainer,
|
||||||
|
ConPt_Advise,
|
||||||
|
ConPt_Unadvise,
|
||||||
|
ConPt_EnumConnections
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI EnumPt_QueryInterface(
|
||||||
|
IEnumConnectionPoints* This,
|
||||||
|
REFIID riid,
|
||||||
|
void **ppvObject)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
*ppvObject = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints))
|
||||||
|
{
|
||||||
|
*ppvObject = This;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ppvObject)
|
||||||
|
{
|
||||||
|
IUnknown_AddRef(This);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("no interface\n");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This)
|
||||||
|
{
|
||||||
|
EnumPt *iface = (EnumPt*)This;
|
||||||
|
return InterlockedIncrement(&iface->refCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This)
|
||||||
|
{
|
||||||
|
EnumPt *iface = (EnumPt*)This;
|
||||||
|
ULONG ret;
|
||||||
|
|
||||||
|
ret = InterlockedDecrement(&iface->refCount);
|
||||||
|
if (ret == 0)
|
||||||
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI EnumPt_Next(
|
||||||
|
IEnumConnectionPoints* This,
|
||||||
|
ULONG cConnections,
|
||||||
|
IConnectionPoint **rgcd,
|
||||||
|
ULONG *pcFetched)
|
||||||
|
{
|
||||||
|
EnumPt *iface = (EnumPt*)This;
|
||||||
|
|
||||||
|
trace("\n");
|
||||||
|
if (cConnections > 0 && iface->idx < iface->container->ptCount)
|
||||||
|
{
|
||||||
|
*rgcd = iface->container->pt[iface->idx];
|
||||||
|
IUnknown_AddRef(iface->container->pt[iface->idx]);
|
||||||
|
if (pcFetched)
|
||||||
|
*pcFetched = 1;
|
||||||
|
iface->idx++;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI EnumPt_Skip(
|
||||||
|
IEnumConnectionPoints* This,
|
||||||
|
ULONG cConnections)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI EnumPt_Reset(
|
||||||
|
IEnumConnectionPoints* This)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI EnumPt_Clone(
|
||||||
|
IEnumConnectionPoints* This,
|
||||||
|
IEnumConnectionPoints **ppEnumPt)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IEnumConnectionPointsVtbl enumpt_vtbl = {
|
||||||
|
|
||||||
|
EnumPt_QueryInterface,
|
||||||
|
EnumPt_AddRef,
|
||||||
|
EnumPt_Release,
|
||||||
|
EnumPt_Next,
|
||||||
|
EnumPt_Skip,
|
||||||
|
EnumPt_Reset,
|
||||||
|
EnumPt_Clone
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI Contain_QueryInterface(
|
||||||
|
IConnectionPointContainer* This,
|
||||||
|
REFIID riid,
|
||||||
|
void **ppvObject)
|
||||||
|
{
|
||||||
|
trace("\n");
|
||||||
|
*ppvObject = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer))
|
||||||
|
{
|
||||||
|
*ppvObject = This;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ppvObject)
|
||||||
|
{
|
||||||
|
IUnknown_AddRef(This);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace("no interface\n");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI Contain_AddRef(
|
||||||
|
IConnectionPointContainer* This)
|
||||||
|
{
|
||||||
|
Contain *iface = (Contain*)This;
|
||||||
|
return InterlockedIncrement(&iface->refCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI Contain_Release(
|
||||||
|
IConnectionPointContainer* This)
|
||||||
|
{
|
||||||
|
Contain *iface = (Contain*)This;
|
||||||
|
ULONG ret;
|
||||||
|
|
||||||
|
ret = InterlockedDecrement(&iface->refCount);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
if (iface->ptCount > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < iface->ptCount; i++)
|
||||||
|
IUnknown_Release(iface->pt[i]);
|
||||||
|
HeapFree(GetProcessHeap(),0,iface->pt);
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Contain_EnumConnectionPoints(
|
||||||
|
IConnectionPointContainer* This,
|
||||||
|
IEnumConnectionPoints **ppEnum)
|
||||||
|
{
|
||||||
|
EnumPt *ec;
|
||||||
|
|
||||||
|
trace("\n");
|
||||||
|
ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
|
||||||
|
ec->vtbl = &enumpt_vtbl;
|
||||||
|
ec->refCount = 1;
|
||||||
|
ec->idx= 0;
|
||||||
|
ec->container = (Contain*)This;
|
||||||
|
*ppEnum = (IEnumConnectionPoints*)ec;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Contain_FindConnectionPoint(
|
||||||
|
IConnectionPointContainer* This,
|
||||||
|
REFIID riid,
|
||||||
|
IConnectionPoint **ppCP)
|
||||||
|
{
|
||||||
|
Contain *iface = (Contain*)This;
|
||||||
|
ConPt *pt;
|
||||||
|
trace("\n");
|
||||||
|
|
||||||
|
if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
|
||||||
|
{
|
||||||
|
pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
|
||||||
|
pt->vtbl = &point_vtbl;
|
||||||
|
pt->refCount = 1;
|
||||||
|
pt->sinkCount = 0;
|
||||||
|
pt->sink = NULL;
|
||||||
|
pt->container = iface;
|
||||||
|
|
||||||
|
if (iface->ptCount == 0)
|
||||||
|
iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
|
||||||
|
else
|
||||||
|
iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
|
||||||
|
iface->pt[iface->ptCount] = (IConnectionPoint*)pt;
|
||||||
|
iface->ptCount++;
|
||||||
|
|
||||||
|
*ppCP = (IConnectionPoint*)pt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ppCP = iface->pt[0];
|
||||||
|
IUnknown_AddRef((IUnknown*)*ppCP);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IConnectionPointContainerVtbl contain_vtbl = {
|
||||||
|
Contain_QueryInterface,
|
||||||
|
Contain_AddRef,
|
||||||
|
Contain_Release,
|
||||||
|
|
||||||
|
Contain_EnumConnectionPoints,
|
||||||
|
Contain_FindConnectionPoint
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_IConnectionPoint(void)
|
||||||
|
{
|
||||||
|
HRESULT rc;
|
||||||
|
ULONG ref;
|
||||||
|
IConnectionPoint *point;
|
||||||
|
Contain *container;
|
||||||
|
Disp *dispatch;
|
||||||
|
DWORD cookie = 0xffffffff;
|
||||||
|
DISPPARAMS params;
|
||||||
|
VARIANT vars[10];
|
||||||
|
|
||||||
|
if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint)
|
||||||
|
{
|
||||||
|
win_skip("IConnectionPoint Apis not present\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain));
|
||||||
|
container->vtbl = &contain_vtbl;
|
||||||
|
container->refCount = 1;
|
||||||
|
container->ptCount = 0;
|
||||||
|
container->pt = NULL;
|
||||||
|
|
||||||
|
dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
|
||||||
|
dispatch->vtbl = &disp_vtbl;
|
||||||
|
dispatch->refCount = 1;
|
||||||
|
|
||||||
|
rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point);
|
||||||
|
ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
|
||||||
|
ok(point != NULL, "returned ConnectionPoint is NULL\n");
|
||||||
|
ok(cookie != 0xffffffff, "invalid cookie returned\n");
|
||||||
|
|
||||||
|
rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
|
||||||
|
ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
|
||||||
|
|
||||||
|
if (pSHPackDispParams)
|
||||||
|
{
|
||||||
|
memset(¶ms, 0xc0, sizeof(params));
|
||||||
|
memset(vars, 0xc0, sizeof(vars));
|
||||||
|
rc = pSHPackDispParams(¶ms, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
|
||||||
|
ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);
|
||||||
|
|
||||||
|
rc = pIConnectionPoint_SimpleInvoke(point,0xa1,¶ms);
|
||||||
|
ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
win_skip("pSHPackDispParams not present\n");
|
||||||
|
|
||||||
|
rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
|
||||||
|
ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
|
||||||
|
|
||||||
|
/* MSDN says this should be required but it crashs on XP
|
||||||
|
IUnknown_Release(point);
|
||||||
|
*/
|
||||||
|
ref = IUnknown_Release((IUnknown*)container);
|
||||||
|
ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref);
|
||||||
|
ref = IUnknown_Release((IUnknown*)dispatch);
|
||||||
|
ok(ref == 0, "leftover IDispatch reference %i\n",ref);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(ordinal)
|
START_TEST(ordinal)
|
||||||
{
|
{
|
||||||
hShlwapi = GetModuleHandleA("shlwapi.dll");
|
hShlwapi = GetModuleHandleA("shlwapi.dll");
|
||||||
|
@ -534,6 +1216,9 @@ START_TEST(ordinal)
|
||||||
pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9);
|
pSHUnlockShared=(void*)GetProcAddress(hShlwapi,(char*)9);
|
||||||
pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10);
|
pSHFreeShared=(void*)GetProcAddress(hShlwapi,(char*)10);
|
||||||
pSHPackDispParams=(void*)GetProcAddress(hShlwapi,(char*)282);
|
pSHPackDispParams=(void*)GetProcAddress(hShlwapi,(char*)282);
|
||||||
|
pIConnectionPoint_SimpleInvoke=(void*)GetProcAddress(hShlwapi,(char*)284);
|
||||||
|
pIConnectionPoint_InvokeWithCancel=(void*)GetProcAddress(hShlwapi,(char*)283);
|
||||||
|
pConnectToConnectionPoint=(void*)GetProcAddress(hShlwapi,(char*)168);
|
||||||
|
|
||||||
test_GetAcceptLanguagesA();
|
test_GetAcceptLanguagesA();
|
||||||
test_SHSearchMapInt();
|
test_SHSearchMapInt();
|
||||||
|
@ -541,4 +1226,5 @@ START_TEST(ordinal)
|
||||||
test_fdsa();
|
test_fdsa();
|
||||||
test_GetShellSecurityDescriptor();
|
test_GetShellSecurityDescriptor();
|
||||||
test_SHPackDispParams();
|
test_SHPackDispParams();
|
||||||
|
test_IConnectionPoint();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue