4 * Copyright 2004 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
35 #include "wine/test.h"
37 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
38 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
39 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
40 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
42 #define CHECK_EXPECTED_METHOD(method_name) \
44 trace("%s\n", method_name); \
45 ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
46 if (*expected_method_list) \
48 ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
49 *expected_method_list, method_name); \
50 expected_method_list++; \
54 static char const * const *expected_method_list;
55 static const WCHAR wszFileName1[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
56 static const WCHAR wszFileName2[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
58 static const CLSID CLSID_WineTest =
59 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
63 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
66 static const CLSID CLSID_TestMoniker =
67 { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
71 {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
76 static void LockModule(void)
78 InterlockedIncrement(&cLocks);
81 static void UnlockModule(void)
83 InterlockedDecrement(&cLocks);
86 static SIZE_T round_global_size(SIZE_T size)
88 static SIZE_T global_size_alignment = -1;
89 if (global_size_alignment == -1)
91 void *p = GlobalAlloc(GMEM_FIXED, 1);
92 global_size_alignment = GlobalSize(p);
96 return ((size + global_size_alignment - 1) & ~(global_size_alignment - 1));
99 static HRESULT WINAPI Test_IClassFactory_QueryInterface(
100 LPCLASSFACTORY iface,
104 if (ppvObj == NULL) return E_POINTER;
106 if (IsEqualGUID(riid, &IID_IUnknown) ||
107 IsEqualGUID(riid, &IID_IClassFactory))
110 IClassFactory_AddRef(iface);
115 return E_NOINTERFACE;
118 static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
121 return 2; /* non-heap-based object */
124 static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
127 return 1; /* non-heap-based object */
130 static HRESULT WINAPI Test_IClassFactory_CreateInstance(
131 LPCLASSFACTORY iface,
139 static HRESULT WINAPI Test_IClassFactory_LockServer(
140 LPCLASSFACTORY iface,
146 static const IClassFactoryVtbl TestClassFactory_Vtbl =
148 Test_IClassFactory_QueryInterface,
149 Test_IClassFactory_AddRef,
150 Test_IClassFactory_Release,
151 Test_IClassFactory_CreateInstance,
152 Test_IClassFactory_LockServer
155 static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
159 const IUnknownVtbl *lpVtbl;
163 static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
165 if (IsEqualIID(riid, &IID_IUnknown))
167 IUnknown_AddRef(iface);
172 return E_NOINTERFACE;
175 static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
177 HeapUnknown *This = (HeapUnknown *)iface;
178 return InterlockedIncrement((LONG*)&This->refs);
181 static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
183 HeapUnknown *This = (HeapUnknown *)iface;
184 ULONG refs = InterlockedDecrement((LONG*)&This->refs);
185 if (!refs) HeapFree(GetProcessHeap(), 0, This);
189 static const IUnknownVtbl HeapUnknown_Vtbl =
191 HeapUnknown_QueryInterface,
196 static HRESULT WINAPI
197 MonikerNoROTData_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
204 if (IsEqualIID(&IID_IUnknown, riid) ||
205 IsEqualIID(&IID_IPersist, riid) ||
206 IsEqualIID(&IID_IPersistStream,riid) ||
207 IsEqualIID(&IID_IMoniker, riid))
209 if (IsEqualIID(&IID_IROTData, riid))
210 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
213 return E_NOINTERFACE;
215 IMoniker_AddRef(iface);
221 Moniker_AddRef(IMoniker* iface)
227 Moniker_Release(IMoniker* iface)
232 static HRESULT WINAPI
233 Moniker_GetClassID(IMoniker* iface, CLSID *pClassID)
235 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
237 *pClassID = CLSID_TestMoniker;
242 static HRESULT WINAPI
243 Moniker_IsDirty(IMoniker* iface)
245 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
250 static HRESULT WINAPI
251 Moniker_Load(IMoniker* iface, IStream* pStm)
253 CHECK_EXPECTED_METHOD("Moniker_Load");
257 static HRESULT WINAPI
258 Moniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
260 CHECK_EXPECTED_METHOD("Moniker_Save");
264 static HRESULT WINAPI
265 Moniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
267 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
271 static HRESULT WINAPI
272 Moniker_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
273 REFIID riid, VOID** ppvResult)
275 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
279 static HRESULT WINAPI
280 Moniker_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
281 REFIID riid, VOID** ppvObject)
283 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
287 static HRESULT WINAPI
288 Moniker_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
289 IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
291 CHECK_EXPECTED_METHOD("Moniker_Reduce");
293 if (ppmkReduced==NULL)
296 IMoniker_AddRef(iface);
300 return MK_S_REDUCED_TO_SELF;
303 static HRESULT WINAPI
304 Moniker_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
305 BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
307 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
311 static HRESULT WINAPI
312 Moniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
314 CHECK_EXPECTED_METHOD("Moniker_Enum");
316 if (ppenumMoniker == NULL)
319 *ppenumMoniker = NULL;
324 static HRESULT WINAPI
325 Moniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
327 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
331 static HRESULT WINAPI
332 Moniker_Hash(IMoniker* iface,DWORD* pdwHash)
334 CHECK_EXPECTED_METHOD("Moniker_Hash");
338 static HRESULT WINAPI
339 Moniker_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
340 IMoniker* pmkNewlyRunning)
342 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
346 static HRESULT WINAPI
347 Moniker_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
348 IMoniker* pmkToLeft, FILETIME* pFileTime)
350 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
354 static HRESULT WINAPI
355 Moniker_Inverse(IMoniker* iface,IMoniker** ppmk)
357 CHECK_EXPECTED_METHOD("Moniker_Inverse");
361 static HRESULT WINAPI
362 Moniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
364 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
368 static HRESULT WINAPI
369 Moniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
371 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
375 static HRESULT WINAPI
376 Moniker_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
377 IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
379 static const WCHAR wszDisplayName[] = {'*','*','G','e','m','m','a',0};
380 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
381 *ppszDisplayName = CoTaskMemAlloc(sizeof(wszDisplayName));
382 memcpy(*ppszDisplayName, wszDisplayName, sizeof(wszDisplayName));
386 static HRESULT WINAPI
387 Moniker_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
388 LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
390 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
394 static HRESULT WINAPI
395 Moniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
397 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
402 (*pwdMksys)=MKSYS_NONE;
407 static const IMonikerVtbl MonikerNoROTDataVtbl =
409 MonikerNoROTData_QueryInterface,
417 Moniker_BindToObject,
418 Moniker_BindToStorage,
425 Moniker_GetTimeOfLastChange,
427 Moniker_CommonPrefixWith,
428 Moniker_RelativePathTo,
429 Moniker_GetDisplayName,
430 Moniker_ParseDisplayName,
431 Moniker_IsSystemMoniker
434 static IMoniker MonikerNoROTData = { &MonikerNoROTDataVtbl };
436 static IMoniker Moniker;
438 static HRESULT WINAPI
439 ROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
441 return IMoniker_QueryInterface(&Moniker, riid, ppvObject);
445 ROTData_AddRef(IROTData *iface)
451 ROTData_Release(IROTData* iface)
456 static HRESULT WINAPI
457 ROTData_GetComparisonData(IROTData* iface, BYTE* pbData,
458 ULONG cbMax, ULONG* pcbData)
460 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
463 if (cbMax < *pcbData)
464 return E_OUTOFMEMORY;
471 static IROTDataVtbl ROTDataVtbl =
473 ROTData_QueryInterface,
476 ROTData_GetComparisonData
479 static IROTData ROTData = { &ROTDataVtbl };
481 static HRESULT WINAPI
482 Moniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
489 if (IsEqualIID(&IID_IUnknown, riid) ||
490 IsEqualIID(&IID_IPersist, riid) ||
491 IsEqualIID(&IID_IPersistStream,riid) ||
492 IsEqualIID(&IID_IMoniker, riid))
494 if (IsEqualIID(&IID_IROTData, riid))
496 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
497 *ppvObject = &ROTData;
501 return E_NOINTERFACE;
503 IMoniker_AddRef(iface);
508 static const IMonikerVtbl MonikerVtbl =
510 Moniker_QueryInterface,
518 Moniker_BindToObject,
519 Moniker_BindToStorage,
526 Moniker_GetTimeOfLastChange,
528 Moniker_CommonPrefixWith,
529 Moniker_RelativePathTo,
530 Moniker_GetDisplayName,
531 Moniker_ParseDisplayName,
532 Moniker_IsSystemMoniker
535 static IMoniker Moniker = { &MonikerVtbl };
537 static void test_ROT(void)
539 static const WCHAR wszFileName[] = {'B','E','2','0','E','2','F','5','-',
540 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
541 '2','0','4','6','E','5','8','6','C','9','2','5',0};
543 IMoniker *pMoniker = NULL;
544 IRunningObjectTable *pROT = NULL;
546 static const char *methods_register_no_ROTData[] =
549 "Moniker_GetTimeOfLastChange",
550 "Moniker_QueryInterface(IID_IROTData)",
551 "Moniker_GetDisplayName",
552 "Moniker_GetClassID",
555 static const char *methods_register[] =
558 "Moniker_GetTimeOfLastChange",
559 "Moniker_QueryInterface(IID_IROTData)",
560 "ROTData_GetComparisonData",
563 static const char *methods_isrunning_no_ROTData[] =
566 "Moniker_QueryInterface(IID_IROTData)",
567 "Moniker_GetDisplayName",
568 "Moniker_GetClassID",
571 static const char *methods_isrunning[] =
574 "Moniker_QueryInterface(IID_IROTData)",
575 "ROTData_GetComparisonData",
581 hr = GetRunningObjectTable(0, &pROT);
582 ok_ole_success(hr, GetRunningObjectTable);
584 expected_method_list = methods_register_no_ROTData;
585 /* try with our own moniker that doesn't support IROTData */
586 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
587 (IUnknown*)&Test_ClassFactory, &MonikerNoROTData, &dwCookie);
588 ok_ole_success(hr, IRunningObjectTable_Register);
589 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
591 ok_more_than_one_lock();
593 expected_method_list = methods_isrunning_no_ROTData;
594 hr = IRunningObjectTable_IsRunning(pROT, &MonikerNoROTData);
595 ok_ole_success(hr, IRunningObjectTable_IsRunning);
596 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
598 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
599 ok_ole_success(hr, IRunningObjectTable_Revoke);
603 expected_method_list = methods_register;
604 /* try with our own moniker */
605 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
606 (IUnknown*)&Test_ClassFactory, &Moniker, &dwCookie);
607 ok_ole_success(hr, IRunningObjectTable_Register);
608 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
610 ok_more_than_one_lock();
612 expected_method_list = methods_isrunning;
613 hr = IRunningObjectTable_IsRunning(pROT, &Moniker);
614 ok_ole_success(hr, IRunningObjectTable_IsRunning);
615 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
617 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
618 ok_ole_success(hr, IRunningObjectTable_Revoke);
622 hr = CreateFileMoniker(wszFileName, &pMoniker);
623 ok_ole_success(hr, CreateClassMoniker);
626 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown*)&Test_ClassFactory,
627 pMoniker, &dwCookie);
628 ok_ole_success(hr, IRunningObjectTable_Register);
630 ok_more_than_one_lock();
632 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
633 ok_ole_success(hr, IRunningObjectTable_Revoke);
637 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
638 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
639 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
640 ok_ole_success(hr, IRunningObjectTable_Register);
642 ok_more_than_one_lock();
644 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
645 ok_ole_success(hr, IRunningObjectTable_Revoke);
649 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
650 /* only succeeds when process is started by SCM and has LocalService
651 * or RunAs AppId values */
652 hr = IRunningObjectTable_Register(pROT,
653 ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT,
654 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
656 ok(hr == CO_E_WRONG_SERVER_IDENTITY ||
657 broken(hr == S_OK) /* Win9x */,
658 "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr);
660 if (hr == S_OK) IRunningObjectTable_Revoke(pROT, dwCookie);
662 hr = IRunningObjectTable_Register(pROT, 0xdeadbeef,
663 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
664 ok(hr == E_INVALIDARG, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr);
666 IMoniker_Release(pMoniker);
668 IRunningObjectTable_Release(pROT);
671 static void test_ROT_multiple_entries(void)
674 IMoniker *pMoniker = NULL;
675 IRunningObjectTable *pROT = NULL;
676 DWORD dwCookie1, dwCookie2;
677 IUnknown *pObject = NULL;
678 static const WCHAR moniker_path[] =
679 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0};
681 hr = GetRunningObjectTable(0, &pROT);
682 ok_ole_success(hr, GetRunningObjectTable);
684 hr = CreateFileMoniker(moniker_path, &pMoniker);
685 ok_ole_success(hr, CreateFileMoniker);
687 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown *)&Test_ClassFactory, pMoniker, &dwCookie1);
688 ok_ole_success(hr, IRunningObjectTable_Register);
690 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown *)&Test_ClassFactory, pMoniker, &dwCookie2);
691 ok(hr == MK_S_MONIKERALREADYREGISTERED, "IRunningObjectTable_Register should have returned MK_S_MONIKERALREADYREGISTERED instead of 0x%08x\n", hr);
693 ok(dwCookie1 != dwCookie2, "cookie returned for registering duplicate object shouldn't match cookie of original object (0x%x)\n", dwCookie1);
695 hr = IRunningObjectTable_GetObject(pROT, pMoniker, &pObject);
696 ok_ole_success(hr, IRunningObjectTable_GetObject);
697 IUnknown_Release(pObject);
699 hr = IRunningObjectTable_Revoke(pROT, dwCookie1);
700 ok_ole_success(hr, IRunningObjectTable_Revoke);
702 hr = IRunningObjectTable_GetObject(pROT, pMoniker, &pObject);
703 ok_ole_success(hr, IRunningObjectTable_GetObject);
704 IUnknown_Release(pObject);
706 hr = IRunningObjectTable_Revoke(pROT, dwCookie2);
707 ok_ole_success(hr, IRunningObjectTable_Revoke);
709 IMoniker_Release(pMoniker);
711 IRunningObjectTable_Release(pROT);
714 static HRESULT WINAPI ParseDisplayName_QueryInterface(IParseDisplayName *iface, REFIID riid, void **ppv)
716 if (IsEqualIID(riid, &IID_IUnknown) ||
717 IsEqualIID(riid, &IID_IParseDisplayName))
720 IUnknown_AddRef(iface);
724 return E_NOINTERFACE;
727 static ULONG WINAPI ParseDisplayName_AddRef(IParseDisplayName *iface)
732 static ULONG WINAPI ParseDisplayName_Release(IParseDisplayName *iface)
737 static LPCWSTR expected_display_name;
739 static HRESULT WINAPI ParseDisplayName_ParseDisplayName(IParseDisplayName *iface,
741 LPOLESTR pszDisplayName,
745 char display_nameA[256];
746 WideCharToMultiByte(CP_ACP, 0, pszDisplayName, -1, display_nameA, sizeof(display_nameA), NULL, NULL);
747 ok(!lstrcmpW(pszDisplayName, expected_display_name), "unexpected display name \"%s\"\n", display_nameA);
748 ok(pszDisplayName == expected_display_name, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
749 *pchEaten = lstrlenW(pszDisplayName);
750 return CreateAntiMoniker(ppmkOut);
753 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl =
755 ParseDisplayName_QueryInterface,
756 ParseDisplayName_AddRef,
757 ParseDisplayName_Release,
758 ParseDisplayName_ParseDisplayName
761 static IParseDisplayName ParseDisplayName = { &ParseDisplayName_Vtbl };
763 static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
765 IMoniker * spMoniker;
766 int monCnt=0, matchCnt=0;
768 while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK))
773 hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL, &szDisplayn);
776 if (!lstrcmpiW(szDisplayn, wszFileName1) || !lstrcmpiW(szDisplayn, wszFileName2))
778 CoTaskMemFree(szDisplayn);
781 trace("Total number of monikers is %i\n", monCnt);
785 static void test_MkParseDisplayName(void)
787 IBindCtx * pbc = NULL;
789 IMoniker * pmk = NULL;
790 IMoniker * pmk1 = NULL;
791 IMoniker * pmk2 = NULL;
794 IUnknown * object = NULL;
798 IEnumMoniker *spEM1 = NULL;
799 IEnumMoniker *spEM2 = NULL;
800 IEnumMoniker *spEM3 = NULL;
806 IRunningObjectTable * pprot=NULL;
808 /* CLSID of My Computer */
809 static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
810 '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
811 static const WCHAR wszDisplayNameClsid[] = {'c','l','s','i','d',':',0};
812 static const WCHAR wszNonExistentProgId[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
813 static const WCHAR wszDisplayNameRunning[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
814 static const WCHAR wszDisplayNameProgId1[] = {'S','t','d','F','o','n','t',':',0};
815 static const WCHAR wszDisplayNameProgId2[] = {'@','S','t','d','F','o','n','t',0};
816 static const WCHAR wszDisplayNameProgIdFail[] = {'S','t','d','F','o','n','t',0};
817 char szDisplayNameFile[256];
818 WCHAR wszDisplayNameFile[256];
820 hr = CreateBindCtx(0, &pbc);
821 ok_ole_success(hr, CreateBindCtx);
823 hr = MkParseDisplayName(pbc, wszNonExistentProgId, &eaten, &pmk);
824 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
825 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
827 /* no special handling of "clsid:" without the string form of the clsid
829 hr = MkParseDisplayName(pbc, wszDisplayNameClsid, &eaten, &pmk);
830 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
831 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
833 /* shows clsid has higher precedence than a running object */
834 hr = CreateFileMoniker(wszDisplayName, &pmk);
835 ok_ole_success(hr, CreateFileMoniker);
836 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
837 ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
838 hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
839 ok_ole_success(hr, IRunningObjectTable_Register);
840 IMoniker_Release(pmk);
842 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
843 ok_ole_success(hr, MkParseDisplayName);
846 IMoniker_IsSystemMoniker(pmk, &moniker_type);
847 ok(moniker_type == MKSYS_CLASSMONIKER, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type);
848 IMoniker_Release(pmk);
850 hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
851 ok_ole_success(hr, IRunningObjectTable_Revoke);
852 IRunningObjectTable_Release(pprot);
854 hr = CreateFileMoniker(wszDisplayNameRunning, &pmk);
855 ok_ole_success(hr, CreateFileMoniker);
856 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
857 ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
858 hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
859 ok_ole_success(hr, IRunningObjectTable_Register);
860 IMoniker_Release(pmk);
862 hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
863 ok_ole_success(hr, MkParseDisplayName);
866 IMoniker_IsSystemMoniker(pmk, &moniker_type);
867 ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
868 IMoniker_Release(pmk);
870 hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
871 ok_ole_success(hr, IRunningObjectTable_Revoke);
872 IRunningObjectTable_Release(pprot);
874 hr = CoRegisterClassObject(&CLSID_StdFont, (IUnknown *)&ParseDisplayName, CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &pdwReg1);
875 ok_ole_success(hr, CoRegisterClassObject);
877 expected_display_name = wszDisplayNameProgId1;
878 hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
879 ok_ole_success(hr, MkParseDisplayName);
882 IMoniker_IsSystemMoniker(pmk, &moniker_type);
883 ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
884 IMoniker_Release(pmk);
887 expected_display_name = wszDisplayNameProgId2;
888 hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
889 ok_ole_success(hr, MkParseDisplayName);
892 IMoniker_IsSystemMoniker(pmk, &moniker_type);
893 ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
894 IMoniker_Release(pmk);
897 hr = MkParseDisplayName(pbc, wszDisplayNameProgIdFail, &eaten, &pmk);
898 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
899 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
901 hr = CoRevokeClassObject(pdwReg1);
902 ok_ole_success(hr, CoRevokeClassObject);
904 GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
905 strcat(szDisplayNameFile, "\\kernel32.dll");
906 MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile, sizeof(wszDisplayNameFile)/sizeof(wszDisplayNameFile[0]));
907 hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
908 ok_ole_success(hr, MkParseDisplayName);
911 IMoniker_IsSystemMoniker(pmk, &moniker_type);
912 ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
913 IMoniker_Release(pmk);
916 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
917 ok_ole_success(hr, MkParseDisplayName);
921 hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
922 ok_ole_success(hr, IMoniker_BindToObject);
925 IUnknown_Release(object);
926 IMoniker_Release(pmk);
928 IBindCtx_Release(pbc);
930 /* Test the EnumMoniker interface */
931 hr = CreateBindCtx(0, &pbc);
932 ok_ole_success(hr, CreateBindCtx);
934 hr = CreateFileMoniker(wszFileName1, &pmk1);
935 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
936 hr = CreateFileMoniker(wszFileName2, &pmk2);
937 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
938 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
939 ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr);
941 /* Check EnumMoniker before registering */
942 hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
943 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
944 hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
945 /* Register a couple of Monikers and check is ok */
946 ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1);
949 matchCnt = count_moniker_matches(pbc, spEM1);
950 trace("Number of matches is %i\n", matchCnt);
952 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
953 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
954 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
955 hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
957 trace("IROT::Register\n");
959 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
960 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
961 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr,
962 pprot, grflags, lpEM1, pmk2, pdwReg2);
964 hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
965 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
967 matchCnt = count_moniker_matches(pbc, spEM2);
968 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
970 trace("IEnumMoniker::Clone\n");
971 IEnumMoniker_Clone(spEM2, &spEM3);
973 matchCnt = count_moniker_matches(pbc, spEM3);
974 ok(matchCnt==0, "Number of matches should be equal to 0 not %i\n", matchCnt);
975 trace("IEnumMoniker::Reset\n");
976 IEnumMoniker_Reset(spEM3);
978 matchCnt = count_moniker_matches(pbc, spEM3);
979 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
981 IRunningObjectTable_Revoke(pprot,pdwReg1);
982 IRunningObjectTable_Revoke(pprot,pdwReg2);
983 IUnknown_Release(lpEM1);
984 IEnumMoniker_Release(spEM1);
985 IEnumMoniker_Release(spEM2);
986 IEnumMoniker_Release(spEM3);
987 IMoniker_Release(pmk1);
988 IMoniker_Release(pmk2);
989 IRunningObjectTable_Release(pprot);
991 IBindCtx_Release(pbc);
994 static const LARGE_INTEGER llZero;
996 static const BYTE expected_class_moniker_marshal_data[] =
998 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
999 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1000 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1001 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1002 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1003 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1004 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1005 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1006 0x00,0x00,0x00,0x00,
1009 static const BYTE expected_class_moniker_saved_data[] =
1011 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1012 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1013 0x00,0x00,0x00,0x00,
1016 static const BYTE expected_class_moniker_comparison_data[] =
1018 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1019 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1020 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1021 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1024 static const WCHAR expected_class_moniker_display_name[] =
1026 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
1027 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
1028 '0','0','0','0','4','6',':',0
1031 static const BYTE expected_item_moniker_comparison_data[] =
1033 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1034 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1035 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1036 0x54,0x00,0x00,0x00,
1039 static const BYTE expected_item_moniker_saved_data[] =
1041 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1042 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1045 static const BYTE expected_item_moniker_marshal_data[] =
1047 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1048 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1049 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1050 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1051 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1052 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1053 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1054 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1057 static const BYTE expected_anti_moniker_marshal_data[] =
1059 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1060 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1061 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1062 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1063 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1064 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1065 0x01,0x00,0x00,0x00,
1068 static const BYTE expected_anti_moniker_saved_data[] =
1070 0x01,0x00,0x00,0x00,
1073 static const BYTE expected_anti_moniker_comparison_data[] =
1075 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1076 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1077 0x01,0x00,0x00,0x00,
1080 static const BYTE expected_gc_moniker_marshal_data[] =
1082 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1083 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1084 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1085 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1086 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1087 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1088 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1089 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1090 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1091 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1092 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1093 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1094 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1095 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1096 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1097 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1098 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1099 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1100 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1101 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1102 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1103 0x00,0x57,0x69,0x6e,0x65,0x00,
1106 static const BYTE expected_gc_moniker_saved_data[] =
1108 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1109 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1110 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1111 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1112 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1113 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1114 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1115 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1119 static const BYTE expected_gc_moniker_comparison_data[] =
1121 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1122 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1123 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1124 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1125 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1126 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1127 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1128 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1129 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1132 static void test_moniker(
1133 const char *testname, IMoniker *moniker,
1134 const BYTE *expected_moniker_marshal_data, unsigned int sizeof_expected_moniker_marshal_data,
1135 const BYTE *expected_moniker_saved_data, unsigned int sizeof_expected_moniker_saved_data,
1136 const BYTE *expected_moniker_comparison_data, unsigned int sizeof_expected_moniker_comparison_data,
1137 LPCWSTR expected_display_name)
1143 LPBYTE moniker_data;
1148 IMoniker * moniker_proxy;
1149 LPOLESTR display_name;
1152 hr = IMoniker_IsDirty(moniker);
1153 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1157 hr = CreateBindCtx(0, &bindctx);
1158 ok_ole_success(hr, CreateBindCtx);
1160 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1161 ok_ole_success(hr, IMoniker_GetDisplayName);
1162 ok(!lstrcmpW(display_name, expected_display_name), "%s: display name wasn't what was expected\n", testname);
1164 CoTaskMemFree(display_name);
1165 IBindCtx_Release(bindctx);
1167 hr = IMoniker_IsDirty(moniker);
1168 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1170 /* IROTData::GetComparisonData test */
1172 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1173 ok_ole_success(hr, IMoniker_QueryInterface_IID_IROTData);
1175 hr = IROTData_GetComparisonData(rotdata, buffer, sizeof(buffer), &moniker_size);
1176 ok_ole_success(hr, IROTData_GetComparisonData);
1178 if (hr != S_OK) moniker_size = 0;
1180 /* first check we have the right amount of data */
1181 ok(moniker_size == sizeof_expected_moniker_comparison_data,
1182 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1183 testname, sizeof_expected_moniker_comparison_data, moniker_size);
1185 /* then do a byte-by-byte comparison */
1186 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
1188 if (expected_moniker_comparison_data[i] != buffer[i])
1195 ok(same, "%s: Comparison data differs\n", testname);
1198 for (i = 0; i < moniker_size; i++)
1200 if (i % 8 == 0) printf(" ");
1201 printf("0x%02x,", buffer[i]);
1202 if (i % 8 == 7) printf("\n");
1207 IROTData_Release(rotdata);
1209 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1213 hr = IMoniker_Save(moniker, stream, TRUE);
1214 ok_ole_success(hr, IMoniker_Save);
1216 hr = GetHGlobalFromStream(stream, &hglobal);
1217 ok_ole_success(hr, GetHGlobalFromStream);
1219 moniker_size = GlobalSize(hglobal);
1221 moniker_data = GlobalLock(hglobal);
1223 /* first check we have the right amount of data */
1224 ok(moniker_size == round_global_size(sizeof_expected_moniker_saved_data),
1225 "%s: Size of saved data differs (expected %d, actual %d)\n",
1226 testname, (DWORD)round_global_size(sizeof_expected_moniker_saved_data), moniker_size);
1228 /* then do a byte-by-byte comparison */
1229 for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_saved_data)); i++)
1231 if (expected_moniker_saved_data[i] != moniker_data[i])
1238 ok(same, "%s: Saved data differs\n", testname);
1241 for (i = 0; i < moniker_size; i++)
1243 if (i % 8 == 0) printf(" ");
1244 printf("0x%02x,", moniker_data[i]);
1245 if (i % 8 == 7) printf("\n");
1250 GlobalUnlock(hglobal);
1252 IStream_Release(stream);
1254 /* Marshaling tests */
1256 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1257 ok_ole_success(hr, CreateStreamOnHGlobal);
1259 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1260 ok_ole_success(hr, CoMarshalInterface);
1262 hr = GetHGlobalFromStream(stream, &hglobal);
1263 ok_ole_success(hr, GetHGlobalFromStream);
1265 moniker_size = GlobalSize(hglobal);
1267 moniker_data = GlobalLock(hglobal);
1269 /* first check we have the right amount of data */
1270 ok(moniker_size == round_global_size(sizeof_expected_moniker_marshal_data),
1271 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1272 testname, (DWORD)round_global_size(sizeof_expected_moniker_marshal_data), moniker_size);
1274 /* then do a byte-by-byte comparison */
1275 if (expected_moniker_marshal_data)
1277 for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_marshal_data)); i++)
1279 if (expected_moniker_marshal_data[i] != moniker_data[i])
1287 ok(same, "%s: Marshaled data differs\n", testname);
1290 for (i = 0; i < moniker_size; i++)
1292 if (i % 8 == 0) printf(" ");
1293 printf("0x%02x,", moniker_data[i]);
1294 if (i % 8 == 7) printf("\n");
1299 GlobalUnlock(hglobal);
1301 IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1302 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
1303 ok_ole_success(hr, CoUnmarshalInterface);
1305 IStream_Release(stream);
1306 IMoniker_Release(moniker_proxy);
1309 static void test_class_moniker(void)
1320 hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
1321 ok_ole_success(hr, CreateClassMoniker);
1322 if (!moniker) return;
1324 test_moniker("class moniker", moniker,
1325 expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
1326 expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
1327 expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
1328 expected_class_moniker_display_name);
1332 hr = IMoniker_Hash(moniker, &hash);
1333 ok_ole_success(hr, IMoniker_Hash);
1335 ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
1336 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1339 /* IsSystemMoniker test */
1341 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1342 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1344 ok(moniker_type == MKSYS_CLASSMONIKER,
1345 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1348 hr = CreateBindCtx(0, &bindctx);
1349 ok_ole_success(hr, CreateBindCtx);
1351 /* IsRunning test */
1352 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1353 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1355 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1356 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1358 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1359 ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
1361 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1362 ok_ole_success(hr, IMoniker_BindToObject);
1363 IUnknown_Release(unknown);
1365 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1366 ok_ole_success(hr, IMoniker_BindToStorage);
1367 IUnknown_Release(unknown);
1369 IBindCtx_Release(bindctx);
1371 hr = IMoniker_Inverse(moniker, &inverse);
1372 ok_ole_success(hr, IMoniker_Inverse);
1373 IMoniker_Release(inverse);
1375 IMoniker_Release(moniker);
1378 static void test_file_moniker(WCHAR* path)
1381 IMoniker *moniker1 = NULL, *moniker2 = NULL;
1384 hr = CreateFileMoniker(path, &moniker1);
1385 ok_ole_success(hr, CreateFileMoniker);
1387 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1390 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1391 ok_ole_success(hr, CoMarshalInterface);
1394 hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1395 ok_ole_success(hr, IStream_Seek);
1398 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
1399 ok_ole_success(hr, CoUnmarshalInterface);
1401 hr = IMoniker_IsEqual(moniker1, moniker2);
1402 ok_ole_success(hr, IsEqual);
1404 IStream_Release(stream);
1406 IMoniker_Release(moniker1);
1408 IMoniker_Release(moniker2);
1411 static void test_file_monikers(void)
1413 static WCHAR wszFile[][30] = {
1414 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1415 {'\\', 'a','b','c','d','e','f','g','\\','h','i','j','k','l','\\','m','n','o','p','q','r','s','t','u','.','m','n','o',0},
1416 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1417 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1418 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1419 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1420 * U+0100 .. = Latin extended-A
1422 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1427 trace("ACP is %u\n", GetACP());
1429 for (i = 0; i < COUNTOF(wszFile); ++i)
1432 for (j = lstrlenW(wszFile[i]); j > 0; --j)
1435 test_file_moniker(wszFile[i]);
1440 static void test_item_moniker(void)
1449 static const WCHAR wszDelimeter[] = {'!',0};
1450 static const WCHAR wszObjectName[] = {'T','e','s','t',0};
1451 static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
1453 hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker);
1454 ok_ole_success(hr, CreateItemMoniker);
1456 test_moniker("item moniker", moniker,
1457 expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
1458 expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
1459 expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
1460 expected_display_name);
1464 hr = IMoniker_Hash(moniker, &hash);
1465 ok_ole_success(hr, IMoniker_Hash);
1468 "Hash value != 0x73c, instead was 0x%08x\n",
1471 /* IsSystemMoniker test */
1473 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1474 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1476 ok(moniker_type == MKSYS_ITEMMONIKER,
1477 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1480 hr = CreateBindCtx(0, &bindctx);
1481 ok_ole_success(hr, CreateBindCtx);
1483 /* IsRunning test */
1484 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1486 ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1488 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1489 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1491 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1492 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1494 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1495 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1497 IBindCtx_Release(bindctx);
1499 hr = IMoniker_Inverse(moniker, &inverse);
1500 ok_ole_success(hr, IMoniker_Inverse);
1501 IMoniker_Release(inverse);
1503 IMoniker_Release(moniker);
1506 static void test_anti_moniker(void)
1516 static const WCHAR expected_display_name[] = { '\\','.','.',0 };
1518 hr = CreateAntiMoniker(&moniker);
1519 ok_ole_success(hr, CreateAntiMoniker);
1520 if (!moniker) return;
1522 test_moniker("anti moniker", moniker,
1523 expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
1524 expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
1525 expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
1526 expected_display_name);
1529 hr = IMoniker_Hash(moniker, &hash);
1530 ok_ole_success(hr, IMoniker_Hash);
1531 ok(hash == 0x80000001,
1532 "Hash value != 0x80000001, instead was 0x%08x\n",
1535 /* IsSystemMoniker test */
1536 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1537 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1538 ok(moniker_type == MKSYS_ANTIMONIKER,
1539 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1542 hr = IMoniker_Inverse(moniker, &inverse);
1543 ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
1544 ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
1546 hr = CreateBindCtx(0, &bindctx);
1547 ok_ole_success(hr, CreateBindCtx);
1549 /* IsRunning test */
1550 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1551 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1553 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1554 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1556 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1557 ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr);
1559 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1560 ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr);
1562 IBindCtx_Release(bindctx);
1564 IMoniker_Release(moniker);
1567 static void test_generic_composite_moniker(void)
1579 static const WCHAR wszDelimeter1[] = {'!',0};
1580 static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
1581 static const WCHAR wszDelimeter2[] = {'#',0};
1582 static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
1583 static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1585 hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1);
1586 ok_ole_success(hr, CreateItemMoniker);
1587 hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2);
1588 ok_ole_success(hr, CreateItemMoniker);
1589 hr = CreateGenericComposite(moniker1, moniker2, &moniker);
1590 ok_ole_success(hr, CreateGenericComposite);
1592 test_moniker("generic composite moniker", moniker,
1593 expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
1594 expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
1595 expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
1596 expected_display_name);
1600 hr = IMoniker_Hash(moniker, &hash);
1601 ok_ole_success(hr, IMoniker_Hash);
1604 "Hash value != 0xd87, instead was 0x%08x\n",
1607 /* IsSystemMoniker test */
1609 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1610 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1612 ok(moniker_type == MKSYS_GENERICCOMPOSITE,
1613 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1616 hr = CreateBindCtx(0, &bindctx);
1617 ok_ole_success(hr, CreateBindCtx);
1619 /* IsRunning test */
1620 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1622 ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1624 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1626 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1628 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1629 ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);
1631 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1633 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1636 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1637 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1639 IBindCtx_Release(bindctx);
1641 hr = IMoniker_Inverse(moniker, &inverse);
1642 ok_ole_success(hr, IMoniker_Inverse);
1643 IMoniker_Release(inverse);
1645 IMoniker_Release(moniker);
1648 static void test_pointer_moniker(void)
1660 LPOLESTR display_name;
1664 hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, NULL);
1665 ok(hr == E_INVALIDARG, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1667 hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, &moniker);
1668 ok_ole_success(hr, CreatePointerMoniker);
1669 if (!moniker) return;
1671 ok_more_than_one_lock();
1675 hr = CreateBindCtx(0, &bindctx);
1676 ok_ole_success(hr, CreateBindCtx);
1678 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1679 ok(hr == E_NOTIMPL, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1681 IBindCtx_Release(bindctx);
1683 hr = IMoniker_IsDirty(moniker);
1684 ok(hr == S_FALSE, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr);
1686 /* IROTData::GetComparisonData test */
1688 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1689 ok(hr == E_NOINTERFACE, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
1693 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1694 ok_ole_success(hr, CreateStreamOnHGlobal);
1696 hr = IMoniker_Save(moniker, stream, TRUE);
1697 ok(hr == E_NOTIMPL, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1699 IStream_Release(stream);
1702 hr = IMoniker_Hash(moniker, &hash);
1703 ok_ole_success(hr, IMoniker_Hash);
1704 ok(hash == (DWORD)&Test_ClassFactory,
1705 "Hash value should have been 0x%08x, instead of 0x%08x\n",
1706 (DWORD)&Test_ClassFactory, hash);
1708 /* IsSystemMoniker test */
1709 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1710 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1711 ok(moniker_type == MKSYS_POINTERMONIKER,
1712 "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1715 hr = IMoniker_Inverse(moniker, &inverse);
1716 ok_ole_success(hr, IMoniker_Inverse);
1717 IMoniker_Release(inverse);
1719 hr = CreateBindCtx(0, &bindctx);
1720 ok_ole_success(hr, CreateBindCtx);
1722 /* IsRunning test */
1723 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1724 ok(hr == S_OK, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr);
1726 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1727 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1729 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1730 ok_ole_success(hr, IMoniker_BindToObject);
1731 IUnknown_Release(unknown);
1733 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1734 ok_ole_success(hr, IMoniker_BindToStorage);
1735 IUnknown_Release(unknown);
1737 IMoniker_Release(moniker);
1741 hr = CreatePointerMoniker(NULL, &moniker);
1742 ok_ole_success(hr, CreatePointerMoniker);
1744 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1745 ok(hr == E_UNEXPECTED, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1747 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1748 ok(hr == E_UNEXPECTED, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1750 IBindCtx_Release(bindctx);
1752 IMoniker_Release(moniker);
1755 static void test_bind_context(void)
1759 IEnumString *pEnumString;
1760 BIND_OPTS2 bind_opts;
1761 HeapUnknown *unknown;
1762 HeapUnknown *unknown2;
1763 IUnknown *param_obj;
1765 static const WCHAR wszParamName[] = {'G','e','m','m','a',0};
1766 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1768 hr = CreateBindCtx(0, NULL);
1769 ok(hr == E_INVALIDARG, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1771 hr = CreateBindCtx(0xdeadbeef, &pBindCtx);
1772 ok(hr == E_INVALIDARG, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1774 hr = CreateBindCtx(0, &pBindCtx);
1775 ok_ole_success(hr, "CreateBindCtx");
1777 bind_opts.cbStruct = -1;
1778 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1779 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1780 ok(bind_opts.cbStruct == sizeof(bind_opts) ||
1781 bind_opts.cbStruct == sizeof(bind_opts) + sizeof(void*), /* Vista */
1782 "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1784 bind_opts.cbStruct = sizeof(BIND_OPTS);
1785 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1786 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1787 ok(bind_opts.cbStruct == sizeof(BIND_OPTS), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1789 bind_opts.cbStruct = sizeof(bind_opts);
1790 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1791 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1792 ok(bind_opts.cbStruct == sizeof(bind_opts), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1793 ok(bind_opts.grfFlags == 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts.grfFlags);
1794 ok(bind_opts.grfMode == STGM_READWRITE, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts.grfMode);
1795 ok(bind_opts.dwTickCountDeadline == 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts.dwTickCountDeadline);
1796 ok(bind_opts.dwTrackFlags == 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts.dwTrackFlags);
1797 ok(bind_opts.dwClassContext == (CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER),
1798 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts.dwClassContext);
1799 ok(bind_opts.locale == GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts.locale);
1800 ok(bind_opts.pServerInfo == NULL, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts.pServerInfo);
1802 bind_opts.cbStruct = -1;
1803 hr = IBindCtx_SetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1804 ok(hr == E_INVALIDARG, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1806 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, NULL);
1807 ok(hr == E_INVALIDARG, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1809 unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1810 unknown->lpVtbl = &HeapUnknown_Vtbl;
1812 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, (IUnknown *)&unknown->lpVtbl);
1813 ok_ole_success(hr, "IBindCtx_RegisterObjectParam");
1815 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszParamName, ¶m_obj);
1816 ok_ole_success(hr, "IBindCtx_GetObjectParam");
1817 IUnknown_Release(param_obj);
1819 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszNonExistent, ¶m_obj);
1820 ok(hr == E_FAIL, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1821 ok(param_obj == NULL, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj);
1823 hr = IBindCtx_RevokeObjectParam(pBindCtx, (WCHAR *)wszNonExistent);
1824 ok(hr == E_FAIL, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1826 hr = IBindCtx_EnumObjectParam(pBindCtx, &pEnumString);
1827 ok(hr == E_NOTIMPL, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1828 ok(!pEnumString, "pEnumString should be NULL\n");
1830 hr = IBindCtx_RegisterObjectBound(pBindCtx, NULL);
1831 ok_ole_success(hr, "IBindCtx_RegisterObjectBound(NULL)");
1833 hr = IBindCtx_RevokeObjectBound(pBindCtx, NULL);
1834 ok(hr == E_INVALIDARG, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr);
1836 unknown2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1837 unknown2->lpVtbl = &HeapUnknown_Vtbl;
1839 hr = IBindCtx_RegisterObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1840 ok_ole_success(hr, "IBindCtx_RegisterObjectBound");
1842 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1843 ok_ole_success(hr, "IBindCtx_RevokeObjectBound");
1845 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1846 ok(hr == MK_E_NOTBOUND, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr);
1848 IBindCtx_Release(pBindCtx);
1850 refs = IUnknown_Release((IUnknown *)&unknown->lpVtbl);
1851 ok(!refs, "object param should have been destroyed, instead of having %d refs\n", refs);
1853 refs = IUnknown_Release((IUnknown *)&unknown2->lpVtbl);
1854 ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
1859 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1862 test_ROT_multiple_entries();
1863 test_MkParseDisplayName();
1864 test_class_moniker();
1865 test_file_monikers();
1866 test_item_moniker();
1867 test_anti_moniker();
1868 test_generic_composite_moniker();
1869 test_pointer_moniker();
1871 /* FIXME: test moniker creation funcs and parsing other moniker formats */
1873 test_bind_context();