[PATCH 7/7] ole32: Add some tests for the running object table.
Robert Shearman
rob at codeweavers.com
Wed Dec 27 20:42:06 CST 2006
The tests show the behaviour when the IROTData interface is not
available from the moniker. They also show the flags that are accepted
into IRunningObjectTable::Register.
---
dlls/ole32/tests/moniker.c | 577
++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 577 insertions(+), 0 deletions(-)
-------------- next part --------------
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index ac2a9c4..2195750 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -20,6 +20,7 @@
#define _WIN32_DCOM
#define COBJMACROS
+#define CONST_VTABLE
#include <stdarg.h>
#include <stdio.h>
@@ -31,12 +32,587 @@ #include "comcat.h"
#include "wine/test.h"
+#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
+#define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
+#define CHECK_EXPECTED_METHOD(method_name) \
+do { \
+ trace("%s\n", method_name); \
+ ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
+ if (*expected_method_list) \
+ { \
+ ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
+ *expected_method_list, method_name); \
+ expected_method_list++; \
+ } \
+} while(0)
+
+static char const * const *expected_method_list;
static const WCHAR wszFileName1[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
static const WCHAR wszFileName2[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
+static const CLSID CLSID_WineTest =
+{ /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
+ 0x9474ba1a,
+ 0x258b,
+ 0x490b,
+ {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
+};
+
+static const CLSID CLSID_TestMoniker =
+{ /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
+ 0xb306bfbc,
+ 0x496e,
+ 0x4f53,
+ {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
+};
+
+static LONG cLocks;
+
+static void LockModule(void)
+{
+ InterlockedIncrement(&cLocks);
+}
+
+static void UnlockModule(void)
+{
+ InterlockedDecrement(&cLocks);
+}
+
+static HRESULT WINAPI Test_IClassFactory_QueryInterface(
+ LPCLASSFACTORY iface,
+ REFIID riid,
+ LPVOID *ppvObj)
+{
+ if (ppvObj == NULL) return E_POINTER;
+
+ if (IsEqualGUID(riid, &IID_IUnknown) ||
+ IsEqualGUID(riid, &IID_IClassFactory))
+ {
+ *ppvObj = (LPVOID)iface;
+ IClassFactory_AddRef(iface);
+ return S_OK;
+ }
+
+ *ppvObj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
+{
+ LockModule();
+ return 2; /* non-heap-based object */
+}
+
+static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
+{
+ UnlockModule();
+ return 1; /* non-heap-based object */
+}
+
+static HRESULT WINAPI Test_IClassFactory_CreateInstance(
+ LPCLASSFACTORY iface,
+ LPUNKNOWN pUnkOuter,
+ REFIID riid,
+ LPVOID *ppvObj)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI Test_IClassFactory_LockServer(
+ LPCLASSFACTORY iface,
+ BOOL fLock)
+{
+ return S_OK;
+}
+
+static const IClassFactoryVtbl TestClassFactory_Vtbl =
+{
+ Test_IClassFactory_QueryInterface,
+ Test_IClassFactory_AddRef,
+ Test_IClassFactory_Release,
+ Test_IClassFactory_CreateInstance,
+ Test_IClassFactory_LockServer
+};
+
+static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
+
+static HRESULT WINAPI
+MonikerNoROTData_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
+{
+ if (!ppvObject)
+ return E_INVALIDARG;
+
+ *ppvObject = 0;
+
+ if (IsEqualIID(&IID_IUnknown, riid) ||
+ IsEqualIID(&IID_IPersist, riid) ||
+ IsEqualIID(&IID_IPersistStream,riid) ||
+ IsEqualIID(&IID_IMoniker, riid))
+ *ppvObject = iface;
+ if (IsEqualIID(&IID_IROTData, riid))
+ CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
+
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
+
+ IMoniker_AddRef(iface);
+
+ return S_OK;
+}
+
+static ULONG WINAPI
+Moniker_AddRef(IMoniker* iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI
+Moniker_Release(IMoniker* iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI
+Moniker_GetClassID(IMoniker* iface, CLSID *pClassID)
+{
+ CHECK_EXPECTED_METHOD("Moniker_GetClassID");
+
+ *pClassID = CLSID_TestMoniker;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+Moniker_IsDirty(IMoniker* iface)
+{
+ CHECK_EXPECTED_METHOD("Moniker_IsDirty");
+
+ return S_FALSE;
+}
+
+static HRESULT WINAPI
+Moniker_Load(IMoniker* iface, IStream* pStm)
+{
+ CHECK_EXPECTED_METHOD("Moniker_Load");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
+{
+ CHECK_EXPECTED_METHOD("Moniker_Save");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
+{
+ CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
+ REFIID riid, VOID** ppvResult)
+{
+ CHECK_EXPECTED_METHOD("Moniker_BindToObject");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
+ REFIID riid, VOID** ppvObject)
+{
+ CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
+ IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
+{
+ CHECK_EXPECTED_METHOD("Moniker_Reduce");
+
+ if (ppmkReduced==NULL)
+ return E_POINTER;
+
+ IMoniker_AddRef(iface);
+
+ *ppmkReduced=iface;
+
+ return MK_S_REDUCED_TO_SELF;
+}
+
+static HRESULT WINAPI
+Moniker_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
+ BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
+{
+ CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
+{
+ CHECK_EXPECTED_METHOD("Moniker_Enum");
+
+ if (ppenumMoniker == NULL)
+ return E_POINTER;
+
+ *ppenumMoniker = NULL;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+Moniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
+{
+ CHECK_EXPECTED_METHOD("Moniker_IsEqual");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_Hash(IMoniker* iface,DWORD* pdwHash)
+{
+ CHECK_EXPECTED_METHOD("Moniker_Hash");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
+ IMoniker* pmkNewlyRunning)
+{
+ CHECK_EXPECTED_METHOD("Moniker_IsRunning");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
+ IMoniker* pmkToLeft, FILETIME* pFileTime)
+{
+ CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_Inverse(IMoniker* iface,IMoniker** ppmk)
+{
+ CHECK_EXPECTED_METHOD("Moniker_Inverse");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
+{
+ CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
+{
+ CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
+ IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
+{
+ static const WCHAR wszDisplayName[] = {'*','*','G','e','m','m','a',0};
+ CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
+ *ppszDisplayName = (LPOLESTR)CoTaskMemAlloc(sizeof(wszDisplayName));
+ memcpy(*ppszDisplayName, wszDisplayName, sizeof(wszDisplayName));
+ return S_OK;
+}
+
+static HRESULT WINAPI
+Moniker_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
+ LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
+{
+ CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+Moniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
+{
+ CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
+
+ if (!pwdMksys)
+ return E_POINTER;
+
+ (*pwdMksys)=MKSYS_NONE;
+
+ return S_FALSE;
+}
+
+static const IMonikerVtbl MonikerNoROTDataVtbl =
+{
+ MonikerNoROTData_QueryInterface,
+ Moniker_AddRef,
+ Moniker_Release,
+ Moniker_GetClassID,
+ Moniker_IsDirty,
+ Moniker_Load,
+ Moniker_Save,
+ Moniker_GetSizeMax,
+ Moniker_BindToObject,
+ Moniker_BindToStorage,
+ Moniker_Reduce,
+ Moniker_ComposeWith,
+ Moniker_Enum,
+ Moniker_IsEqual,
+ Moniker_Hash,
+ Moniker_IsRunning,
+ Moniker_GetTimeOfLastChange,
+ Moniker_Inverse,
+ Moniker_CommonPrefixWith,
+ Moniker_RelativePathTo,
+ Moniker_GetDisplayName,
+ Moniker_ParseDisplayName,
+ Moniker_IsSystemMoniker
+};
+
+static IMoniker MonikerNoROTData = { &MonikerNoROTDataVtbl };
+
+static IMoniker Moniker;
+
+static HRESULT WINAPI
+ROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
+{
+ return IMoniker_QueryInterface(&Moniker, riid, ppvObject);
+}
+
+static ULONG WINAPI
+ROTData_AddRef(IROTData *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI
+ROTData_Release(IROTData* iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI
+ROTData_GetComparisonData(IROTData* iface, BYTE* pbData,
+ ULONG cbMax, ULONG* pcbData)
+{
+ CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
+
+ *pcbData = 1;
+ if (cbMax < *pcbData)
+ return E_OUTOFMEMORY;
+
+ *pbData = 0xde;
+
+ return S_OK;
+}
+
+static IROTDataVtbl ROTDataVtbl =
+{
+ ROTData_QueryInterface,
+ ROTData_AddRef,
+ ROTData_Release,
+ ROTData_GetComparisonData
+};
+
+static IROTData ROTData = { &ROTDataVtbl };
+
+static HRESULT WINAPI
+Moniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
+{
+ if (!ppvObject)
+ return E_INVALIDARG;
+
+ *ppvObject = 0;
+
+ if (IsEqualIID(&IID_IUnknown, riid) ||
+ IsEqualIID(&IID_IPersist, riid) ||
+ IsEqualIID(&IID_IPersistStream,riid) ||
+ IsEqualIID(&IID_IMoniker, riid))
+ *ppvObject = iface;
+ if (IsEqualIID(&IID_IROTData, riid))
+ {
+ CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
+ *ppvObject = &ROTData;
+ }
+
+ if ((*ppvObject)==0)
+ return E_NOINTERFACE;
+
+ IMoniker_AddRef(iface);
+
+ return S_OK;
+}
+
+static const IMonikerVtbl MonikerVtbl =
+{
+ Moniker_QueryInterface,
+ Moniker_AddRef,
+ Moniker_Release,
+ Moniker_GetClassID,
+ Moniker_IsDirty,
+ Moniker_Load,
+ Moniker_Save,
+ Moniker_GetSizeMax,
+ Moniker_BindToObject,
+ Moniker_BindToStorage,
+ Moniker_Reduce,
+ Moniker_ComposeWith,
+ Moniker_Enum,
+ Moniker_IsEqual,
+ Moniker_Hash,
+ Moniker_IsRunning,
+ Moniker_GetTimeOfLastChange,
+ Moniker_Inverse,
+ Moniker_CommonPrefixWith,
+ Moniker_RelativePathTo,
+ Moniker_GetDisplayName,
+ Moniker_ParseDisplayName,
+ Moniker_IsSystemMoniker
+};
+
+static IMoniker Moniker = { &MonikerVtbl };
+
+static void test_ROT(void)
+{
+ static const WCHAR wszFileName[] = {'B','E','2','0','E','2','F','5','-',
+ '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
+ '2','0','4','6','E','5','8','6','C','9','2','5',0};
+ HRESULT hr;
+ IMoniker *pMoniker = NULL;
+ IRunningObjectTable *pROT = NULL;
+ DWORD dwCookie;
+ static const char *methods_register_no_ROTData[] =
+ {
+ "Moniker_Reduce",
+ "Moniker_GetTimeOfLastChange",
+ "Moniker_QueryInterface(IID_IROTData)",
+ "Moniker_GetDisplayName",
+ "Moniker_GetClassID",
+ NULL
+ };
+ static const char *methods_register[] =
+ {
+ "Moniker_Reduce",
+ "Moniker_GetTimeOfLastChange",
+ "Moniker_QueryInterface(IID_IROTData)",
+ "ROTData_GetComparisonData",
+ NULL
+ };
+ static const char *methods_isrunning_no_ROTData[] =
+ {
+ "Moniker_Reduce",
+ "Moniker_QueryInterface(IID_IROTData)",
+ "Moniker_GetDisplayName",
+ "Moniker_GetClassID",
+ NULL
+ };
+ static const char *methods_isrunning[] =
+ {
+ "Moniker_Reduce",
+ "Moniker_QueryInterface(IID_IROTData)",
+ "ROTData_GetComparisonData",
+ NULL
+ };
+
+ cLocks = 0;
+
+ hr = GetRunningObjectTable(0, &pROT);
+ ok_ole_success(hr, GetRunningObjectTable);
+
+ expected_method_list = methods_register_no_ROTData;
+ /* try with our own moniker that doesn't support IROTData */
+ hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
+ (IUnknown*)&Test_ClassFactory, &MonikerNoROTData, &dwCookie);
+ todo_wine { /* only fails because of lack of IMoniker marshaling */
+ ok_ole_success(hr, IRunningObjectTable_Register);
+ }
+ ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
+
+ todo_wine { /* only fails because of lack of IMoniker marshaling */
+ ok_more_than_one_lock();
+ }
+
+ expected_method_list = methods_isrunning_no_ROTData;
+ hr = IRunningObjectTable_IsRunning(pROT, &MonikerNoROTData);
+ todo_wine { /* only fails because of lack of IMoniker marshaling */
+ ok_ole_success(hr, IRunningObjectTable_IsRunning);
+ }
+ ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
+
+ hr = IRunningObjectTable_Revoke(pROT, dwCookie);
+ todo_wine { /* only fails because of lack of IMoniker marshaling */
+ ok_ole_success(hr, IRunningObjectTable_Revoke);
+ }
+
+ ok_no_locks();
+
+ expected_method_list = methods_register;
+ /* try with our own moniker */
+ hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
+ (IUnknown*)&Test_ClassFactory, &Moniker, &dwCookie);
+ todo_wine { /* only fails because of lack of IMoniker marshaling */
+ ok_ole_success(hr, IRunningObjectTable_Register);
+ }
+ ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
+
+ todo_wine { /* only fails because of lack of IMoniker marshaling */
+ ok_more_than_one_lock();
+ }
+
+ expected_method_list = methods_isrunning;
+ hr = IRunningObjectTable_IsRunning(pROT, &Moniker);
+ todo_wine { /* only fails because of lack of IMoniker marshaling */
+ ok_ole_success(hr, IRunningObjectTable_IsRunning);
+ }
+ ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
+
+ hr = IRunningObjectTable_Revoke(pROT, dwCookie);
+ todo_wine { /* only fails because of lack of IMoniker marshaling */
+ ok_ole_success(hr, IRunningObjectTable_Revoke);
+ }
+
+ ok_no_locks();
+
+ hr = CreateFileMoniker(wszFileName, &pMoniker);
+ ok_ole_success(hr, CreateClassMoniker);
+
+ hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
+ (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
+ ok_ole_success(hr, IRunningObjectTable_Register);
+
+ ok_more_than_one_lock();
+
+ hr = IRunningObjectTable_Revoke(pROT, dwCookie);
+ ok_ole_success(hr, IRunningObjectTable_Revoke);
+
+ ok_no_locks();
+
+ /* only succeeds when process is started by SCM and has LocalService
+ * or RunAs AppId values */
+ hr = IRunningObjectTable_Register(pROT,
+ ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT,
+ (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
+ todo_wine {
+ ok(hr == CO_E_WRONG_SERVER_IDENTITY, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr);
+ }
+
+ hr = IRunningObjectTable_Register(pROT, 0xdeadbeef,
+ (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
+ ok(hr == E_INVALIDARG, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr);
+
+ IMoniker_Release(pMoniker);
+
+ IRunningObjectTable_Release(pROT);
+}
+
static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
{
IMoniker * spMoniker;
@@ -811,6 +1387,7 @@ START_TEST(moniker)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ test_ROT();
test_MkParseDisplayName();
test_class_moniker();
test_file_monikers();
More information about the wine-patches
mailing list