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
33 #include "wine/test.h"
35 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
36 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
37 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
38 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
40 #define CHECK_EXPECTED_METHOD(method_name) \
42 trace("%s\n", method_name); \
43 ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
44 if (*expected_method_list) \
46 ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
47 *expected_method_list, method_name); \
48 expected_method_list++; \
52 static char const * const *expected_method_list;
53 static const WCHAR wszFileName1[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
54 static const WCHAR wszFileName2[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
56 static const CLSID CLSID_WineTest =
57 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
61 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
64 static const CLSID CLSID_TestMoniker =
65 { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
69 {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
74 static void LockModule(void)
76 InterlockedIncrement(&cLocks);
79 static void UnlockModule(void)
81 InterlockedDecrement(&cLocks);
84 static HRESULT WINAPI Test_IClassFactory_QueryInterface(
89 if (ppvObj == NULL) return E_POINTER;
91 if (IsEqualGUID(riid, &IID_IUnknown) ||
92 IsEqualGUID(riid, &IID_IClassFactory))
94 *ppvObj = (LPVOID)iface;
95 IClassFactory_AddRef(iface);
100 return E_NOINTERFACE;
103 static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
106 return 2; /* non-heap-based object */
109 static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
112 return 1; /* non-heap-based object */
115 static HRESULT WINAPI Test_IClassFactory_CreateInstance(
116 LPCLASSFACTORY iface,
124 static HRESULT WINAPI Test_IClassFactory_LockServer(
125 LPCLASSFACTORY iface,
131 static const IClassFactoryVtbl TestClassFactory_Vtbl =
133 Test_IClassFactory_QueryInterface,
134 Test_IClassFactory_AddRef,
135 Test_IClassFactory_Release,
136 Test_IClassFactory_CreateInstance,
137 Test_IClassFactory_LockServer
140 static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
142 static HRESULT WINAPI
143 MonikerNoROTData_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
150 if (IsEqualIID(&IID_IUnknown, riid) ||
151 IsEqualIID(&IID_IPersist, riid) ||
152 IsEqualIID(&IID_IPersistStream,riid) ||
153 IsEqualIID(&IID_IMoniker, riid))
155 if (IsEqualIID(&IID_IROTData, riid))
156 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
159 return E_NOINTERFACE;
161 IMoniker_AddRef(iface);
167 Moniker_AddRef(IMoniker* iface)
173 Moniker_Release(IMoniker* iface)
178 static HRESULT WINAPI
179 Moniker_GetClassID(IMoniker* iface, CLSID *pClassID)
181 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
183 *pClassID = CLSID_TestMoniker;
188 static HRESULT WINAPI
189 Moniker_IsDirty(IMoniker* iface)
191 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
196 static HRESULT WINAPI
197 Moniker_Load(IMoniker* iface, IStream* pStm)
199 CHECK_EXPECTED_METHOD("Moniker_Load");
203 static HRESULT WINAPI
204 Moniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
206 CHECK_EXPECTED_METHOD("Moniker_Save");
210 static HRESULT WINAPI
211 Moniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
213 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
217 static HRESULT WINAPI
218 Moniker_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
219 REFIID riid, VOID** ppvResult)
221 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
225 static HRESULT WINAPI
226 Moniker_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
227 REFIID riid, VOID** ppvObject)
229 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
233 static HRESULT WINAPI
234 Moniker_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
235 IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
237 CHECK_EXPECTED_METHOD("Moniker_Reduce");
239 if (ppmkReduced==NULL)
242 IMoniker_AddRef(iface);
246 return MK_S_REDUCED_TO_SELF;
249 static HRESULT WINAPI
250 Moniker_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
251 BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
253 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
257 static HRESULT WINAPI
258 Moniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
260 CHECK_EXPECTED_METHOD("Moniker_Enum");
262 if (ppenumMoniker == NULL)
265 *ppenumMoniker = NULL;
270 static HRESULT WINAPI
271 Moniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
273 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
277 static HRESULT WINAPI
278 Moniker_Hash(IMoniker* iface,DWORD* pdwHash)
280 CHECK_EXPECTED_METHOD("Moniker_Hash");
284 static HRESULT WINAPI
285 Moniker_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
286 IMoniker* pmkNewlyRunning)
288 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
292 static HRESULT WINAPI
293 Moniker_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
294 IMoniker* pmkToLeft, FILETIME* pFileTime)
296 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
300 static HRESULT WINAPI
301 Moniker_Inverse(IMoniker* iface,IMoniker** ppmk)
303 CHECK_EXPECTED_METHOD("Moniker_Inverse");
307 static HRESULT WINAPI
308 Moniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
310 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
314 static HRESULT WINAPI
315 Moniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
317 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
321 static HRESULT WINAPI
322 Moniker_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
323 IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
325 static const WCHAR wszDisplayName[] = {'*','*','G','e','m','m','a',0};
326 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
327 *ppszDisplayName = (LPOLESTR)CoTaskMemAlloc(sizeof(wszDisplayName));
328 memcpy(*ppszDisplayName, wszDisplayName, sizeof(wszDisplayName));
332 static HRESULT WINAPI
333 Moniker_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
334 LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
336 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
340 static HRESULT WINAPI
341 Moniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
343 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
348 (*pwdMksys)=MKSYS_NONE;
353 static const IMonikerVtbl MonikerNoROTDataVtbl =
355 MonikerNoROTData_QueryInterface,
363 Moniker_BindToObject,
364 Moniker_BindToStorage,
371 Moniker_GetTimeOfLastChange,
373 Moniker_CommonPrefixWith,
374 Moniker_RelativePathTo,
375 Moniker_GetDisplayName,
376 Moniker_ParseDisplayName,
377 Moniker_IsSystemMoniker
380 static IMoniker MonikerNoROTData = { &MonikerNoROTDataVtbl };
382 static IMoniker Moniker;
384 static HRESULT WINAPI
385 ROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
387 return IMoniker_QueryInterface(&Moniker, riid, ppvObject);
391 ROTData_AddRef(IROTData *iface)
397 ROTData_Release(IROTData* iface)
402 static HRESULT WINAPI
403 ROTData_GetComparisonData(IROTData* iface, BYTE* pbData,
404 ULONG cbMax, ULONG* pcbData)
406 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
409 if (cbMax < *pcbData)
410 return E_OUTOFMEMORY;
417 static IROTDataVtbl ROTDataVtbl =
419 ROTData_QueryInterface,
422 ROTData_GetComparisonData
425 static IROTData ROTData = { &ROTDataVtbl };
427 static HRESULT WINAPI
428 Moniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
435 if (IsEqualIID(&IID_IUnknown, riid) ||
436 IsEqualIID(&IID_IPersist, riid) ||
437 IsEqualIID(&IID_IPersistStream,riid) ||
438 IsEqualIID(&IID_IMoniker, riid))
440 if (IsEqualIID(&IID_IROTData, riid))
442 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
443 *ppvObject = &ROTData;
447 return E_NOINTERFACE;
449 IMoniker_AddRef(iface);
454 static const IMonikerVtbl MonikerVtbl =
456 Moniker_QueryInterface,
464 Moniker_BindToObject,
465 Moniker_BindToStorage,
472 Moniker_GetTimeOfLastChange,
474 Moniker_CommonPrefixWith,
475 Moniker_RelativePathTo,
476 Moniker_GetDisplayName,
477 Moniker_ParseDisplayName,
478 Moniker_IsSystemMoniker
481 static IMoniker Moniker = { &MonikerVtbl };
483 static void test_ROT(void)
485 static const WCHAR wszFileName[] = {'B','E','2','0','E','2','F','5','-',
486 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
487 '2','0','4','6','E','5','8','6','C','9','2','5',0};
489 IMoniker *pMoniker = NULL;
490 IRunningObjectTable *pROT = NULL;
492 static const char *methods_register_no_ROTData[] =
495 "Moniker_GetTimeOfLastChange",
496 "Moniker_QueryInterface(IID_IROTData)",
497 "Moniker_GetDisplayName",
498 "Moniker_GetClassID",
501 static const char *methods_register[] =
504 "Moniker_GetTimeOfLastChange",
505 "Moniker_QueryInterface(IID_IROTData)",
506 "ROTData_GetComparisonData",
509 static const char *methods_isrunning_no_ROTData[] =
512 "Moniker_QueryInterface(IID_IROTData)",
513 "Moniker_GetDisplayName",
514 "Moniker_GetClassID",
517 static const char *methods_isrunning[] =
520 "Moniker_QueryInterface(IID_IROTData)",
521 "ROTData_GetComparisonData",
527 hr = GetRunningObjectTable(0, &pROT);
528 ok_ole_success(hr, GetRunningObjectTable);
530 expected_method_list = methods_register_no_ROTData;
531 /* try with our own moniker that doesn't support IROTData */
532 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
533 (IUnknown*)&Test_ClassFactory, &MonikerNoROTData, &dwCookie);
534 todo_wine { /* only fails because of lack of IMoniker marshaling */
535 ok_ole_success(hr, IRunningObjectTable_Register);
537 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
539 todo_wine { /* only fails because of lack of IMoniker marshaling */
540 ok_more_than_one_lock();
543 expected_method_list = methods_isrunning_no_ROTData;
544 hr = IRunningObjectTable_IsRunning(pROT, &MonikerNoROTData);
545 todo_wine { /* only fails because of lack of IMoniker marshaling */
546 ok_ole_success(hr, IRunningObjectTable_IsRunning);
548 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
550 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
551 todo_wine { /* only fails because of lack of IMoniker marshaling */
552 ok_ole_success(hr, IRunningObjectTable_Revoke);
557 expected_method_list = methods_register;
558 /* try with our own moniker */
559 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
560 (IUnknown*)&Test_ClassFactory, &Moniker, &dwCookie);
561 todo_wine { /* only fails because of lack of IMoniker marshaling */
562 ok_ole_success(hr, IRunningObjectTable_Register);
564 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
566 todo_wine { /* only fails because of lack of IMoniker marshaling */
567 ok_more_than_one_lock();
570 expected_method_list = methods_isrunning;
571 hr = IRunningObjectTable_IsRunning(pROT, &Moniker);
572 todo_wine { /* only fails because of lack of IMoniker marshaling */
573 ok_ole_success(hr, IRunningObjectTable_IsRunning);
575 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
577 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
578 todo_wine { /* only fails because of lack of IMoniker marshaling */
579 ok_ole_success(hr, IRunningObjectTable_Revoke);
584 hr = CreateFileMoniker(wszFileName, &pMoniker);
585 ok_ole_success(hr, CreateClassMoniker);
588 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown*)&Test_ClassFactory,
589 pMoniker, &dwCookie);
590 ok_ole_success(hr, IRunningObjectTable_Register);
591 IMoniker_Release(pMoniker);
593 ok_more_than_one_lock();
595 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
596 ok_ole_success(hr, IRunningObjectTable_Revoke);
600 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
601 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
602 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
603 ok_ole_success(hr, IRunningObjectTable_Register);
605 ok_more_than_one_lock();
607 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
608 ok_ole_success(hr, IRunningObjectTable_Revoke);
612 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
613 /* only succeeds when process is started by SCM and has LocalService
614 * or RunAs AppId values */
615 hr = IRunningObjectTable_Register(pROT,
616 ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT,
617 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
619 ok(hr == CO_E_WRONG_SERVER_IDENTITY, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr);
622 hr = IRunningObjectTable_Register(pROT, 0xdeadbeef,
623 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
624 ok(hr == E_INVALIDARG, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr);
626 IMoniker_Release(pMoniker);
628 IRunningObjectTable_Release(pROT);
631 static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
633 IMoniker * spMoniker;
634 int monCnt=0, matchCnt=0;
636 while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK))
641 hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL, &szDisplayn);
644 if (!lstrcmpW(szDisplayn, wszFileName1) || !lstrcmpW(szDisplayn, wszFileName2))
646 CoTaskMemFree(szDisplayn);
649 trace("Total number of monikers is %i\n", monCnt);
653 static void test_MkParseDisplayName(void)
655 IBindCtx * pbc = NULL;
657 IMoniker * pmk = NULL;
658 IMoniker * pmk1 = NULL;
659 IMoniker * pmk2 = NULL;
662 IUnknown * object = NULL;
666 IEnumMoniker *spEM1 = NULL;
667 IEnumMoniker *spEM2 = NULL;
668 IEnumMoniker *spEM3 = NULL;
673 IRunningObjectTable * pprot=NULL;
675 /* CLSID of My Computer */
676 static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
677 '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};
679 hr = CreateBindCtx(0, &pbc);
680 ok_ole_success(hr, CreateBindCtx);
682 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
683 todo_wine { ok_ole_success(hr, MkParseDisplayName); }
687 hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
688 ok_ole_success(hr, IMoniker_BindToObject);
690 IUnknown_Release(object);
692 IBindCtx_Release(pbc);
694 /* Test the EnumMoniker interface */
695 hr = CreateBindCtx(0, &pbc);
696 ok_ole_success(hr, CreateBindCtx);
698 hr = CreateFileMoniker(wszFileName1, &pmk1);
699 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
700 hr = CreateFileMoniker(wszFileName2, &pmk2);
701 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
702 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
703 ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr);
705 /* Check EnumMoniker before registering */
706 hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
707 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
708 hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
709 /* Register a couple of Monikers and check is ok */
710 ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1);
713 matchCnt = count_moniker_matches(pbc, spEM1);
714 trace("Number of matches is %i\n", matchCnt);
716 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
717 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
718 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
719 hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
721 trace("IROT::Register\n");
723 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
724 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
725 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr,
726 pprot, grflags, lpEM1, pmk2, pdwReg2);
728 hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
729 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
731 matchCnt = count_moniker_matches(pbc, spEM2);
732 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
734 trace("IEnumMoniker::Clone\n");
735 IEnumMoniker_Clone(spEM2, &spEM3);
737 matchCnt = count_moniker_matches(pbc, spEM3);
738 ok(matchCnt==0, "Number of matches should be equal to 0 not %i\n", matchCnt);
739 trace("IEnumMoniker::Reset\n");
740 IEnumMoniker_Reset(spEM3);
742 matchCnt = count_moniker_matches(pbc, spEM3);
743 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
745 IRunningObjectTable_Revoke(pprot,pdwReg1);
746 IRunningObjectTable_Revoke(pprot,pdwReg2);
747 IEnumMoniker_Release(spEM1);
748 IEnumMoniker_Release(spEM1);
749 IEnumMoniker_Release(spEM2);
750 IEnumMoniker_Release(spEM3);
751 IMoniker_Release(pmk1);
752 IMoniker_Release(pmk2);
753 IRunningObjectTable_Release(pprot);
755 IBindCtx_Release(pbc);
758 static const LARGE_INTEGER llZero;
760 static const BYTE expected_class_moniker_marshal_data[] =
762 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
763 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
764 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
765 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
766 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
767 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
768 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
769 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
773 static const BYTE expected_class_moniker_saved_data[] =
775 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
776 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
780 static const BYTE expected_class_moniker_comparison_data[] =
782 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
783 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
784 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
785 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
788 static const WCHAR expected_class_moniker_display_name[] =
790 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
791 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
792 '0','0','0','0','4','6',':',0
795 static const BYTE expected_item_moniker_comparison_data[] =
797 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
798 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
799 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
803 static const BYTE expected_item_moniker_saved_data[] =
805 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
806 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
809 static const BYTE expected_item_moniker_marshal_data[] =
811 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
812 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
813 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
814 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
815 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
816 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
817 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
818 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
821 static const BYTE expected_anti_moniker_marshal_data[] =
823 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
824 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
825 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
826 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
827 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
828 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
832 static const BYTE expected_anti_moniker_saved_data[] =
837 static const BYTE expected_anti_moniker_comparison_data[] =
839 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
840 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
844 static const BYTE expected_gc_moniker_marshal_data[] =
846 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
847 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
848 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
849 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
850 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
851 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
852 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
853 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
854 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
855 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
856 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
857 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
858 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
859 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
860 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
861 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
862 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
863 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
864 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
865 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
866 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
867 0x00,0x57,0x69,0x6e,0x65,0x00,
870 static const BYTE expected_gc_moniker_saved_data[] =
872 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
873 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
874 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
875 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
876 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
877 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
878 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
879 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
883 static const BYTE expected_gc_moniker_comparison_data[] =
885 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
886 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
887 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
888 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
889 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
890 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
891 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
892 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
893 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
896 static void test_moniker(
897 const char *testname, IMoniker *moniker,
898 const BYTE *expected_moniker_marshal_data, unsigned int sizeof_expected_moniker_marshal_data,
899 const BYTE *expected_moniker_saved_data, unsigned int sizeof_expected_moniker_saved_data,
900 const BYTE *expected_moniker_comparison_data, unsigned int sizeof_expected_moniker_comparison_data,
901 LPCWSTR expected_display_name)
912 IMoniker * moniker_proxy;
913 LPOLESTR display_name;
916 hr = IMoniker_IsDirty(moniker);
917 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
921 hr = CreateBindCtx(0, &bindctx);
922 ok_ole_success(hr, CreateBindCtx);
924 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
925 ok_ole_success(hr, IMoniker_GetDisplayName);
926 ok(!lstrcmpW(display_name, expected_display_name), "display name wasn't what was expected\n");
928 CoTaskMemFree(display_name);
929 IBindCtx_Release(bindctx);
931 hr = IMoniker_IsDirty(moniker);
932 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
934 /* IROTData::GetComparisonData test */
936 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
937 ok_ole_success(hr, IMoniker_QueryInterface_IID_IROTData);
939 hr = IROTData_GetComparisonData(rotdata, buffer, sizeof(buffer), &moniker_size);
940 ok_ole_success(hr, IROTData_GetComparisonData);
942 if (hr != S_OK) moniker_size = 0;
944 /* first check we have the right amount of data */
945 ok(moniker_size == sizeof_expected_moniker_comparison_data,
946 "%s: Size of comparison data differs (expected %d, actual %d)\n",
947 testname, sizeof_expected_moniker_comparison_data, moniker_size);
949 /* then do a byte-by-byte comparison */
950 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
952 if (expected_moniker_comparison_data[i] != buffer[i])
959 ok(same, "%s: Comparison data differs\n", testname);
962 for (i = 0; i < moniker_size; i++)
964 if (i % 8 == 0) printf(" ");
965 printf("0x%02x,", buffer[i]);
966 if (i % 8 == 7) printf("\n");
971 IROTData_Release(rotdata);
973 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
977 hr = IMoniker_Save(moniker, stream, TRUE);
978 ok_ole_success(hr, IMoniker_Save);
980 hr = GetHGlobalFromStream(stream, &hglobal);
981 ok_ole_success(hr, GetHGlobalFromStream);
983 moniker_size = GlobalSize(hglobal);
985 moniker_data = GlobalLock(hglobal);
987 /* first check we have the right amount of data */
988 ok(moniker_size == sizeof_expected_moniker_saved_data,
989 "%s: Size of saved data differs (expected %d, actual %d)\n",
990 testname, sizeof_expected_moniker_saved_data, moniker_size);
992 /* then do a byte-by-byte comparison */
993 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_saved_data); i++)
995 if (expected_moniker_saved_data[i] != moniker_data[i])
1002 ok(same, "%s: Saved data differs\n", testname);
1005 for (i = 0; i < moniker_size; i++)
1007 if (i % 8 == 0) printf(" ");
1008 printf("0x%02x,", moniker_data[i]);
1009 if (i % 8 == 7) printf("\n");
1014 GlobalUnlock(hglobal);
1016 IStream_Release(stream);
1018 /* Marshaling tests */
1020 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1021 ok_ole_success(hr, CreateStreamOnHGlobal);
1023 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1024 ok_ole_success(hr, CoMarshalInterface);
1026 hr = GetHGlobalFromStream(stream, &hglobal);
1027 ok_ole_success(hr, GetHGlobalFromStream);
1029 moniker_size = GlobalSize(hglobal);
1031 moniker_data = GlobalLock(hglobal);
1033 /* first check we have the right amount of data */
1034 ok(moniker_size == sizeof_expected_moniker_marshal_data,
1035 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1036 testname, sizeof_expected_moniker_marshal_data, moniker_size);
1038 /* then do a byte-by-byte comparison */
1039 if (expected_moniker_marshal_data)
1041 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_marshal_data); i++)
1043 if (expected_moniker_marshal_data[i] != moniker_data[i])
1051 ok(same, "%s: Marshaled data differs\n", testname);
1054 for (i = 0; i < moniker_size; i++)
1056 if (i % 8 == 0) printf(" ");
1057 printf("0x%02x,", moniker_data[i]);
1058 if (i % 8 == 7) printf("\n");
1063 GlobalUnlock(hglobal);
1065 IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1066 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
1067 ok_ole_success(hr, CoUnmarshalInterface);
1069 IStream_Release(stream);
1070 IMoniker_Release(moniker_proxy);
1073 static void test_class_moniker(void)
1084 hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
1085 ok_ole_success(hr, CreateClassMoniker);
1086 if (!moniker) return;
1088 test_moniker("class moniker", moniker,
1089 expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
1090 expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
1091 expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
1092 expected_class_moniker_display_name);
1096 hr = IMoniker_Hash(moniker, &hash);
1097 ok_ole_success(hr, IMoniker_Hash);
1099 ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
1100 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1103 /* IsSystemMoniker test */
1105 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1106 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1108 ok(moniker_type == MKSYS_CLASSMONIKER,
1109 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1112 hr = CreateBindCtx(0, &bindctx);
1113 ok_ole_success(hr, CreateBindCtx);
1115 /* IsRunning test */
1116 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1117 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1119 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1120 ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
1122 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1123 ok_ole_success(hr, IMoniker_BindToStorage);
1124 IUnknown_Release(unknown);
1126 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1127 ok_ole_success(hr, IMoniker_BindToStorage);
1128 IUnknown_Release(unknown);
1130 IBindCtx_Release(bindctx);
1132 hr = IMoniker_Inverse(moniker, &inverse);
1133 ok_ole_success(hr, IMoniker_Inverse);
1134 IMoniker_Release(inverse);
1136 IMoniker_Release(moniker);
1139 static void test_file_moniker(WCHAR* path)
1142 IMoniker *moniker1 = NULL, *moniker2 = NULL;
1145 hr = CreateFileMoniker(path, &moniker1);
1146 ok_ole_success(hr, CreateFileMoniker);
1148 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1151 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1152 ok_ole_success(hr, CoMarshalInterface);
1155 hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1156 ok_ole_success(hr, IStream_Seek);
1159 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
1160 ok_ole_success(hr, CoUnmarshalInterface);
1162 hr = IMoniker_IsEqual(moniker1, moniker2);
1163 ok_ole_success(hr, IsEqual);
1165 IStream_Release(stream);
1167 IMoniker_Release(moniker1);
1169 IMoniker_Release(moniker2);
1172 static void test_file_monikers(void)
1174 static WCHAR wszFile[][30] = {
1175 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1176 {'\\', '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},
1177 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1178 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1179 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1180 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1181 * U+0100 .. = Latin extended-A
1183 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1188 trace("ACP is %u\n", GetACP());
1190 for (i = 0; i < COUNTOF(wszFile); ++i)
1193 for (j = lstrlenW(wszFile[i]); j > 0; --j)
1196 test_file_moniker(wszFile[i]);
1201 static void test_item_moniker(void)
1210 static const WCHAR wszDelimeter[] = {'!',0};
1211 static const WCHAR wszObjectName[] = {'T','e','s','t',0};
1212 static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
1214 hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker);
1215 ok_ole_success(hr, CreateItemMoniker);
1217 test_moniker("item moniker", moniker,
1218 expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
1219 expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
1220 expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
1221 expected_display_name);
1225 hr = IMoniker_Hash(moniker, &hash);
1226 ok_ole_success(hr, IMoniker_Hash);
1229 "Hash value != 0x73c, instead was 0x%08x\n",
1232 /* IsSystemMoniker test */
1234 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1235 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1237 ok(moniker_type == MKSYS_ITEMMONIKER,
1238 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1241 hr = CreateBindCtx(0, &bindctx);
1242 ok_ole_success(hr, CreateBindCtx);
1244 /* IsRunning test */
1245 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1246 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1248 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1249 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1251 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1252 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1254 IBindCtx_Release(bindctx);
1256 hr = IMoniker_Inverse(moniker, &inverse);
1257 ok_ole_success(hr, IMoniker_Inverse);
1258 IMoniker_Release(inverse);
1260 IMoniker_Release(moniker);
1263 static void test_anti_moniker(void)
1273 static const WCHAR expected_display_name[] = { '\\','.','.',0 };
1275 hr = CreateAntiMoniker(&moniker);
1276 ok_ole_success(hr, CreateAntiMoniker);
1277 if (!moniker) return;
1279 test_moniker("anti moniker", moniker,
1280 expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
1281 expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
1282 expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
1283 expected_display_name);
1286 hr = IMoniker_Hash(moniker, &hash);
1287 ok_ole_success(hr, IMoniker_Hash);
1288 ok(hash == 0x80000001,
1289 "Hash value != 0x80000001, instead was 0x%08x\n",
1292 /* IsSystemMoniker test */
1293 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1294 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1295 ok(moniker_type == MKSYS_ANTIMONIKER,
1296 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1299 hr = IMoniker_Inverse(moniker, &inverse);
1300 ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
1301 ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
1303 hr = CreateBindCtx(0, &bindctx);
1304 ok_ole_success(hr, CreateBindCtx);
1306 /* IsRunning test */
1307 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1308 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1310 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1311 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1313 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1314 ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr);
1316 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1317 ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr);
1319 IBindCtx_Release(bindctx);
1321 IMoniker_Release(moniker);
1324 static void test_generic_composite_moniker(void)
1336 static const WCHAR wszDelimeter1[] = {'!',0};
1337 static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
1338 static const WCHAR wszDelimeter2[] = {'#',0};
1339 static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
1340 static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1342 hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1);
1343 ok_ole_success(hr, CreateItemMoniker);
1344 hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2);
1345 ok_ole_success(hr, CreateItemMoniker);
1346 hr = CreateGenericComposite(moniker1, moniker2, &moniker);
1347 ok_ole_success(hr, CreateGenericComposite);
1349 test_moniker("generic composite moniker", moniker,
1350 expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
1351 expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
1352 expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
1353 expected_display_name);
1357 hr = IMoniker_Hash(moniker, &hash);
1358 ok_ole_success(hr, IMoniker_Hash);
1361 "Hash value != 0xd87, instead was 0x%08x\n",
1364 /* IsSystemMoniker test */
1366 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1367 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1369 ok(moniker_type == MKSYS_GENERICCOMPOSITE,
1370 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1373 hr = CreateBindCtx(0, &bindctx);
1374 ok_ole_success(hr, CreateBindCtx);
1376 /* IsRunning test */
1377 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1379 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1381 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1382 ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);
1384 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1386 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1389 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1390 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1392 IBindCtx_Release(bindctx);
1394 hr = IMoniker_Inverse(moniker, &inverse);
1395 ok_ole_success(hr, IMoniker_Inverse);
1396 IMoniker_Release(inverse);
1398 IMoniker_Release(moniker);
1403 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1406 test_MkParseDisplayName();
1407 test_class_moniker();
1408 test_file_monikers();
1409 test_item_moniker();
1410 test_anti_moniker();
1411 test_generic_composite_moniker();
1413 /* FIXME: test moniker creation funcs and parsing other moniker formats */