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 */
1187 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
1189 if (expected_moniker_comparison_data[i] != buffer[i])
1196 ok(same, "%s: Comparison data differs\n", testname);
1199 for (i = 0; i < moniker_size; i++)
1201 if (i % 8 == 0) printf(" ");
1202 printf("0x%02x,", buffer[i]);
1203 if (i % 8 == 7) printf("\n");
1208 IROTData_Release(rotdata);
1210 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1214 hr = IMoniker_Save(moniker, stream, TRUE);
1215 ok_ole_success(hr, IMoniker_Save);
1217 hr = GetHGlobalFromStream(stream, &hglobal);
1218 ok_ole_success(hr, GetHGlobalFromStream);
1220 moniker_size = GlobalSize(hglobal);
1222 moniker_data = GlobalLock(hglobal);
1224 /* first check we have the right amount of data */
1225 ok(moniker_size == round_global_size(sizeof_expected_moniker_saved_data),
1226 "%s: Size of saved data differs (expected %d, actual %d)\n",
1227 testname, (DWORD)round_global_size(sizeof_expected_moniker_saved_data), moniker_size);
1229 /* then do a byte-by-byte comparison */
1231 for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_saved_data)); i++)
1233 if (expected_moniker_saved_data[i] != moniker_data[i])
1240 ok(same, "%s: Saved data differs\n", testname);
1243 for (i = 0; i < moniker_size; i++)
1245 if (i % 8 == 0) printf(" ");
1246 printf("0x%02x,", moniker_data[i]);
1247 if (i % 8 == 7) printf("\n");
1252 GlobalUnlock(hglobal);
1254 IStream_Release(stream);
1256 /* Marshaling tests */
1258 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1259 ok_ole_success(hr, CreateStreamOnHGlobal);
1261 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1262 ok_ole_success(hr, CoMarshalInterface);
1264 hr = GetHGlobalFromStream(stream, &hglobal);
1265 ok_ole_success(hr, GetHGlobalFromStream);
1267 moniker_size = GlobalSize(hglobal);
1269 moniker_data = GlobalLock(hglobal);
1271 /* first check we have the right amount of data */
1272 ok(moniker_size == round_global_size(sizeof_expected_moniker_marshal_data),
1273 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1274 testname, (DWORD)round_global_size(sizeof_expected_moniker_marshal_data), moniker_size);
1276 /* then do a byte-by-byte comparison */
1278 if (expected_moniker_marshal_data)
1280 for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_marshal_data)); i++)
1282 if (expected_moniker_marshal_data[i] != moniker_data[i])
1290 ok(same, "%s: Marshaled data differs\n", testname);
1293 for (i = 0; i < moniker_size; i++)
1295 if (i % 8 == 0) printf(" ");
1296 printf("0x%02x,", moniker_data[i]);
1297 if (i % 8 == 7) printf("\n");
1302 GlobalUnlock(hglobal);
1304 IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1305 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
1306 ok_ole_success(hr, CoUnmarshalInterface);
1308 IStream_Release(stream);
1309 IMoniker_Release(moniker_proxy);
1312 static void test_class_moniker(void)
1323 hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
1324 ok_ole_success(hr, CreateClassMoniker);
1325 if (!moniker) return;
1327 test_moniker("class moniker", moniker,
1328 expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
1329 expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
1330 expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
1331 expected_class_moniker_display_name);
1335 hr = IMoniker_Hash(moniker, &hash);
1336 ok_ole_success(hr, IMoniker_Hash);
1338 ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
1339 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1342 /* IsSystemMoniker test */
1344 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1345 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1347 ok(moniker_type == MKSYS_CLASSMONIKER,
1348 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1351 hr = CreateBindCtx(0, &bindctx);
1352 ok_ole_success(hr, CreateBindCtx);
1354 /* IsRunning test */
1355 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1356 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1358 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1359 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1361 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1362 ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
1364 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1365 ok_ole_success(hr, IMoniker_BindToObject);
1366 IUnknown_Release(unknown);
1368 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1369 ok_ole_success(hr, IMoniker_BindToStorage);
1370 IUnknown_Release(unknown);
1372 IBindCtx_Release(bindctx);
1374 hr = IMoniker_Inverse(moniker, &inverse);
1375 ok_ole_success(hr, IMoniker_Inverse);
1376 IMoniker_Release(inverse);
1378 IMoniker_Release(moniker);
1381 static void test_file_moniker(WCHAR* path)
1384 IMoniker *moniker1 = NULL, *moniker2 = NULL;
1387 hr = CreateFileMoniker(path, &moniker1);
1388 ok_ole_success(hr, CreateFileMoniker);
1390 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1393 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1394 ok_ole_success(hr, CoMarshalInterface);
1397 hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1398 ok_ole_success(hr, IStream_Seek);
1401 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
1402 ok_ole_success(hr, CoUnmarshalInterface);
1404 hr = IMoniker_IsEqual(moniker1, moniker2);
1405 ok_ole_success(hr, IsEqual);
1407 IStream_Release(stream);
1409 IMoniker_Release(moniker1);
1411 IMoniker_Release(moniker2);
1414 static void test_file_monikers(void)
1416 static WCHAR wszFile[][30] = {
1417 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1418 {'\\', '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},
1419 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1420 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1421 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1422 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1423 * U+0100 .. = Latin extended-A
1425 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1430 trace("ACP is %u\n", GetACP());
1432 for (i = 0; i < COUNTOF(wszFile); ++i)
1435 for (j = lstrlenW(wszFile[i]); j > 0; --j)
1438 test_file_moniker(wszFile[i]);
1443 static void test_item_moniker(void)
1452 static const WCHAR wszDelimeter[] = {'!',0};
1453 static const WCHAR wszObjectName[] = {'T','e','s','t',0};
1454 static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
1456 hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker);
1457 ok_ole_success(hr, CreateItemMoniker);
1459 test_moniker("item moniker", moniker,
1460 expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
1461 expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
1462 expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
1463 expected_display_name);
1467 hr = IMoniker_Hash(moniker, &hash);
1468 ok_ole_success(hr, IMoniker_Hash);
1471 "Hash value != 0x73c, instead was 0x%08x\n",
1474 /* IsSystemMoniker test */
1476 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1477 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1479 ok(moniker_type == MKSYS_ITEMMONIKER,
1480 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1483 hr = CreateBindCtx(0, &bindctx);
1484 ok_ole_success(hr, CreateBindCtx);
1486 /* IsRunning test */
1487 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1489 ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1491 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1492 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1494 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1495 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1497 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1498 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1500 IBindCtx_Release(bindctx);
1502 hr = IMoniker_Inverse(moniker, &inverse);
1503 ok_ole_success(hr, IMoniker_Inverse);
1504 IMoniker_Release(inverse);
1506 IMoniker_Release(moniker);
1509 static void test_anti_moniker(void)
1519 static const WCHAR expected_display_name[] = { '\\','.','.',0 };
1521 hr = CreateAntiMoniker(&moniker);
1522 ok_ole_success(hr, CreateAntiMoniker);
1523 if (!moniker) return;
1525 test_moniker("anti moniker", moniker,
1526 expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
1527 expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
1528 expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
1529 expected_display_name);
1532 hr = IMoniker_Hash(moniker, &hash);
1533 ok_ole_success(hr, IMoniker_Hash);
1534 ok(hash == 0x80000001,
1535 "Hash value != 0x80000001, instead was 0x%08x\n",
1538 /* IsSystemMoniker test */
1539 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1540 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1541 ok(moniker_type == MKSYS_ANTIMONIKER,
1542 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1545 hr = IMoniker_Inverse(moniker, &inverse);
1546 ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
1547 ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
1549 hr = CreateBindCtx(0, &bindctx);
1550 ok_ole_success(hr, CreateBindCtx);
1552 /* IsRunning test */
1553 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1554 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1556 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1557 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1559 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1560 ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr);
1562 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1563 ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr);
1565 IBindCtx_Release(bindctx);
1567 IMoniker_Release(moniker);
1570 static void test_generic_composite_moniker(void)
1582 static const WCHAR wszDelimeter1[] = {'!',0};
1583 static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
1584 static const WCHAR wszDelimeter2[] = {'#',0};
1585 static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
1586 static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1588 hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1);
1589 ok_ole_success(hr, CreateItemMoniker);
1590 hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2);
1591 ok_ole_success(hr, CreateItemMoniker);
1592 hr = CreateGenericComposite(moniker1, moniker2, &moniker);
1593 ok_ole_success(hr, CreateGenericComposite);
1595 test_moniker("generic composite moniker", moniker,
1596 expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
1597 expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
1598 expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
1599 expected_display_name);
1603 hr = IMoniker_Hash(moniker, &hash);
1604 ok_ole_success(hr, IMoniker_Hash);
1607 "Hash value != 0xd87, instead was 0x%08x\n",
1610 /* IsSystemMoniker test */
1612 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1613 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1615 ok(moniker_type == MKSYS_GENERICCOMPOSITE,
1616 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1619 hr = CreateBindCtx(0, &bindctx);
1620 ok_ole_success(hr, CreateBindCtx);
1622 /* IsRunning test */
1623 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1625 ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1627 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1629 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1631 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1632 ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);
1634 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1636 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1639 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1640 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1642 IBindCtx_Release(bindctx);
1644 hr = IMoniker_Inverse(moniker, &inverse);
1645 ok_ole_success(hr, IMoniker_Inverse);
1646 IMoniker_Release(inverse);
1648 IMoniker_Release(moniker);
1651 static void test_pointer_moniker(void)
1663 LPOLESTR display_name;
1667 hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, NULL);
1668 ok(hr == E_INVALIDARG, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1670 hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, &moniker);
1671 ok_ole_success(hr, CreatePointerMoniker);
1672 if (!moniker) return;
1674 ok_more_than_one_lock();
1678 hr = CreateBindCtx(0, &bindctx);
1679 ok_ole_success(hr, CreateBindCtx);
1681 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1682 ok(hr == E_NOTIMPL, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1684 IBindCtx_Release(bindctx);
1686 hr = IMoniker_IsDirty(moniker);
1687 ok(hr == S_FALSE, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr);
1689 /* IROTData::GetComparisonData test */
1691 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1692 ok(hr == E_NOINTERFACE, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
1696 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1697 ok_ole_success(hr, CreateStreamOnHGlobal);
1699 hr = IMoniker_Save(moniker, stream, TRUE);
1700 ok(hr == E_NOTIMPL, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1702 IStream_Release(stream);
1705 hr = IMoniker_Hash(moniker, &hash);
1706 ok_ole_success(hr, IMoniker_Hash);
1707 ok(hash == (DWORD)&Test_ClassFactory,
1708 "Hash value should have been 0x%08x, instead of 0x%08x\n",
1709 (DWORD)&Test_ClassFactory, hash);
1711 /* IsSystemMoniker test */
1712 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1713 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1714 ok(moniker_type == MKSYS_POINTERMONIKER,
1715 "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1718 hr = IMoniker_Inverse(moniker, &inverse);
1719 ok_ole_success(hr, IMoniker_Inverse);
1720 IMoniker_Release(inverse);
1722 hr = CreateBindCtx(0, &bindctx);
1723 ok_ole_success(hr, CreateBindCtx);
1725 /* IsRunning test */
1726 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1727 ok(hr == S_OK, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr);
1729 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1730 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1732 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1733 ok_ole_success(hr, IMoniker_BindToObject);
1734 IUnknown_Release(unknown);
1736 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1737 ok_ole_success(hr, IMoniker_BindToStorage);
1738 IUnknown_Release(unknown);
1740 IMoniker_Release(moniker);
1744 hr = CreatePointerMoniker(NULL, &moniker);
1745 ok_ole_success(hr, CreatePointerMoniker);
1747 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1748 ok(hr == E_UNEXPECTED, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1750 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1751 ok(hr == E_UNEXPECTED, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1753 IBindCtx_Release(bindctx);
1755 IMoniker_Release(moniker);
1758 static void test_bind_context(void)
1762 IEnumString *pEnumString;
1763 BIND_OPTS2 bind_opts;
1764 HeapUnknown *unknown;
1765 HeapUnknown *unknown2;
1766 IUnknown *param_obj;
1768 static const WCHAR wszParamName[] = {'G','e','m','m','a',0};
1769 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1771 hr = CreateBindCtx(0, NULL);
1772 ok(hr == E_INVALIDARG, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1774 hr = CreateBindCtx(0xdeadbeef, &pBindCtx);
1775 ok(hr == E_INVALIDARG, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1777 hr = CreateBindCtx(0, &pBindCtx);
1778 ok_ole_success(hr, "CreateBindCtx");
1780 bind_opts.cbStruct = -1;
1781 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1782 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1783 ok(bind_opts.cbStruct == sizeof(bind_opts) ||
1784 bind_opts.cbStruct == sizeof(bind_opts) + sizeof(void*), /* Vista */
1785 "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1787 bind_opts.cbStruct = sizeof(BIND_OPTS);
1788 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1789 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1790 ok(bind_opts.cbStruct == sizeof(BIND_OPTS), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1792 bind_opts.cbStruct = sizeof(bind_opts);
1793 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1794 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1795 ok(bind_opts.cbStruct == sizeof(bind_opts), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1796 ok(bind_opts.grfFlags == 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts.grfFlags);
1797 ok(bind_opts.grfMode == STGM_READWRITE, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts.grfMode);
1798 ok(bind_opts.dwTickCountDeadline == 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts.dwTickCountDeadline);
1799 ok(bind_opts.dwTrackFlags == 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts.dwTrackFlags);
1800 ok(bind_opts.dwClassContext == (CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER),
1801 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts.dwClassContext);
1802 ok(bind_opts.locale == GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts.locale);
1803 ok(bind_opts.pServerInfo == NULL, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts.pServerInfo);
1805 bind_opts.cbStruct = -1;
1806 hr = IBindCtx_SetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1807 ok(hr == E_INVALIDARG, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1809 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, NULL);
1810 ok(hr == E_INVALIDARG, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1812 unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1813 unknown->lpVtbl = &HeapUnknown_Vtbl;
1815 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, (IUnknown *)&unknown->lpVtbl);
1816 ok_ole_success(hr, "IBindCtx_RegisterObjectParam");
1818 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszParamName, ¶m_obj);
1819 ok_ole_success(hr, "IBindCtx_GetObjectParam");
1820 IUnknown_Release(param_obj);
1822 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszNonExistent, ¶m_obj);
1823 ok(hr == E_FAIL, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1824 ok(param_obj == NULL, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj);
1826 hr = IBindCtx_RevokeObjectParam(pBindCtx, (WCHAR *)wszNonExistent);
1827 ok(hr == E_FAIL, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1829 hr = IBindCtx_EnumObjectParam(pBindCtx, &pEnumString);
1830 ok(hr == E_NOTIMPL, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1831 ok(!pEnumString, "pEnumString should be NULL\n");
1833 hr = IBindCtx_RegisterObjectBound(pBindCtx, NULL);
1834 ok_ole_success(hr, "IBindCtx_RegisterObjectBound(NULL)");
1836 hr = IBindCtx_RevokeObjectBound(pBindCtx, NULL);
1837 ok(hr == E_INVALIDARG, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr);
1839 unknown2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1840 unknown2->lpVtbl = &HeapUnknown_Vtbl;
1842 hr = IBindCtx_RegisterObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1843 ok_ole_success(hr, "IBindCtx_RegisterObjectBound");
1845 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1846 ok_ole_success(hr, "IBindCtx_RevokeObjectBound");
1848 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1849 ok(hr == MK_E_NOTBOUND, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr);
1851 IBindCtx_Release(pBindCtx);
1853 refs = IUnknown_Release((IUnknown *)&unknown->lpVtbl);
1854 ok(!refs, "object param should have been destroyed, instead of having %d refs\n", refs);
1856 refs = IUnknown_Release((IUnknown *)&unknown2->lpVtbl);
1857 ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
1862 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1865 test_ROT_multiple_entries();
1866 test_MkParseDisplayName();
1867 test_class_moniker();
1868 test_file_monikers();
1869 test_item_moniker();
1870 test_anti_moniker();
1871 test_generic_composite_moniker();
1872 test_pointer_moniker();
1874 /* FIXME: test moniker creation funcs and parsing other moniker formats */
1876 test_bind_context();