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);
587 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
588 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
589 ok_ole_success(hr, IRunningObjectTable_Register);
591 ok_more_than_one_lock();
593 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
594 ok_ole_success(hr, IRunningObjectTable_Revoke);
598 /* only succeeds when process is started by SCM and has LocalService
599 * or RunAs AppId values */
600 hr = IRunningObjectTable_Register(pROT,
601 ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT,
602 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
604 ok(hr == CO_E_WRONG_SERVER_IDENTITY, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr);
607 hr = IRunningObjectTable_Register(pROT, 0xdeadbeef,
608 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
609 ok(hr == E_INVALIDARG, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr);
611 IMoniker_Release(pMoniker);
613 IRunningObjectTable_Release(pROT);
616 static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
618 IMoniker * spMoniker;
619 int monCnt=0, matchCnt=0;
621 while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK))
626 hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL, &szDisplayn);
629 if (!lstrcmpW(szDisplayn, wszFileName1) || !lstrcmpW(szDisplayn, wszFileName2))
631 CoTaskMemFree(szDisplayn);
634 trace("Total number of monikers is %i\n", monCnt);
638 static void test_MkParseDisplayName(void)
640 IBindCtx * pbc = NULL;
642 IMoniker * pmk = NULL;
643 IMoniker * pmk1 = NULL;
644 IMoniker * pmk2 = NULL;
647 IUnknown * object = NULL;
651 IEnumMoniker *spEM1 = NULL;
652 IEnumMoniker *spEM2 = NULL;
653 IEnumMoniker *spEM3 = NULL;
658 IRunningObjectTable * pprot=NULL;
660 /* CLSID of My Computer */
661 static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
662 '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};
664 hr = CreateBindCtx(0, &pbc);
665 ok_ole_success(hr, CreateBindCtx);
667 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
668 todo_wine { ok_ole_success(hr, MkParseDisplayName); }
672 hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
673 ok_ole_success(hr, IMoniker_BindToObject);
675 IUnknown_Release(object);
677 IBindCtx_Release(pbc);
679 /* Test the EnumMoniker interface */
680 hr = CreateBindCtx(0, &pbc);
681 ok_ole_success(hr, CreateBindCtx);
683 hr = CreateFileMoniker(wszFileName1, &pmk1);
684 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
685 hr = CreateFileMoniker(wszFileName2, &pmk2);
686 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
687 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
688 ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr);
690 /* Check EnumMoniker before registering */
691 hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
692 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
693 hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
694 /* Register a couple of Monikers and check is ok */
695 ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1);
698 matchCnt = count_moniker_matches(pbc, spEM1);
699 trace("Number of matches is %i\n", matchCnt);
701 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
702 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
703 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
704 hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
706 trace("IROT::Register\n");
708 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
709 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
710 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr,
711 pprot, grflags, lpEM1, pmk2, pdwReg2);
713 hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
714 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
716 matchCnt = count_moniker_matches(pbc, spEM2);
717 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
719 trace("IEnumMoniker::Clone\n");
720 IEnumMoniker_Clone(spEM2, &spEM3);
722 matchCnt = count_moniker_matches(pbc, spEM3);
723 ok(matchCnt==0, "Number of matches should be equal to 0 not %i\n", matchCnt);
724 trace("IEnumMoniker::Reset\n");
725 IEnumMoniker_Reset(spEM3);
727 matchCnt = count_moniker_matches(pbc, spEM3);
728 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
730 IRunningObjectTable_Revoke(pprot,pdwReg1);
731 IRunningObjectTable_Revoke(pprot,pdwReg2);
732 IEnumMoniker_Release(spEM1);
733 IEnumMoniker_Release(spEM1);
734 IEnumMoniker_Release(spEM2);
735 IEnumMoniker_Release(spEM3);
736 IMoniker_Release(pmk1);
737 IMoniker_Release(pmk2);
738 IRunningObjectTable_Release(pprot);
740 IBindCtx_Release(pbc);
743 static const LARGE_INTEGER llZero;
745 static const BYTE expected_class_moniker_marshal_data[] =
747 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
748 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
749 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
750 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
751 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
752 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
753 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
754 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
758 static const BYTE expected_class_moniker_saved_data[] =
760 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
761 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
765 static const BYTE expected_class_moniker_comparison_data[] =
767 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
768 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
769 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
770 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
773 static const WCHAR expected_class_moniker_display_name[] =
775 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
776 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
777 '0','0','0','0','4','6',':',0
780 static const BYTE expected_item_moniker_comparison_data[] =
782 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
783 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
784 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
788 static const BYTE expected_item_moniker_saved_data[] =
790 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
791 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
794 static const BYTE expected_item_moniker_marshal_data[] =
796 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
797 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
798 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
799 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
800 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
801 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
802 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
803 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
806 static const BYTE expected_anti_moniker_marshal_data[] =
808 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
809 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
810 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
811 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
812 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
813 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
817 static const BYTE expected_anti_moniker_saved_data[] =
822 static const BYTE expected_anti_moniker_comparison_data[] =
824 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
825 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
829 static const BYTE expected_gc_moniker_marshal_data[] =
831 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
832 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
833 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
834 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
835 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
836 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
837 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
838 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
839 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
840 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
841 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
842 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
843 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
844 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
845 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
846 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
847 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
848 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
849 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
850 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
851 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
852 0x00,0x57,0x69,0x6e,0x65,0x00,
855 static const BYTE expected_gc_moniker_saved_data[] =
857 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
858 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
859 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
860 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
861 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
862 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
863 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
864 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
868 static const BYTE expected_gc_moniker_comparison_data[] =
870 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
871 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
872 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
873 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
874 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
875 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
876 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
877 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
878 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
881 static void test_moniker(
882 const char *testname, IMoniker *moniker,
883 const BYTE *expected_moniker_marshal_data, unsigned int sizeof_expected_moniker_marshal_data,
884 const BYTE *expected_moniker_saved_data, unsigned int sizeof_expected_moniker_saved_data,
885 const BYTE *expected_moniker_comparison_data, unsigned int sizeof_expected_moniker_comparison_data,
886 LPCWSTR expected_display_name)
897 IMoniker * moniker_proxy;
898 LPOLESTR display_name;
901 hr = IMoniker_IsDirty(moniker);
902 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
906 hr = CreateBindCtx(0, &bindctx);
907 ok_ole_success(hr, CreateBindCtx);
909 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
910 ok_ole_success(hr, IMoniker_GetDisplayName);
911 ok(!lstrcmpW(display_name, expected_display_name), "display name wasn't what was expected\n");
913 CoTaskMemFree(display_name);
914 IBindCtx_Release(bindctx);
916 hr = IMoniker_IsDirty(moniker);
917 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
919 /* IROTData::GetComparisonData test */
921 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
922 ok_ole_success(hr, IMoniker_QueryInterface_IID_IROTData);
924 hr = IROTData_GetComparisonData(rotdata, buffer, sizeof(buffer), &moniker_size);
925 ok_ole_success(hr, IROTData_GetComparisonData);
927 if (hr != S_OK) moniker_size = 0;
929 /* first check we have the right amount of data */
930 ok(moniker_size == sizeof_expected_moniker_comparison_data,
931 "%s: Size of comparison data differs (expected %d, actual %d)\n",
932 testname, sizeof_expected_moniker_comparison_data, moniker_size);
934 /* then do a byte-by-byte comparison */
935 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
937 if (expected_moniker_comparison_data[i] != buffer[i])
944 ok(same, "%s: Comparison data differs\n", testname);
947 for (i = 0; i < moniker_size; i++)
949 if (i % 8 == 0) printf(" ");
950 printf("0x%02x,", buffer[i]);
951 if (i % 8 == 7) printf("\n");
956 IROTData_Release(rotdata);
958 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
962 hr = IMoniker_Save(moniker, stream, TRUE);
963 ok_ole_success(hr, IMoniker_Save);
965 hr = GetHGlobalFromStream(stream, &hglobal);
966 ok_ole_success(hr, GetHGlobalFromStream);
968 moniker_size = GlobalSize(hglobal);
970 moniker_data = GlobalLock(hglobal);
972 /* first check we have the right amount of data */
973 ok(moniker_size == sizeof_expected_moniker_saved_data,
974 "%s: Size of saved data differs (expected %d, actual %d)\n",
975 testname, sizeof_expected_moniker_saved_data, moniker_size);
977 /* then do a byte-by-byte comparison */
978 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_saved_data); i++)
980 if (expected_moniker_saved_data[i] != moniker_data[i])
987 ok(same, "%s: Saved data differs\n", testname);
990 for (i = 0; i < moniker_size; i++)
992 if (i % 8 == 0) printf(" ");
993 printf("0x%02x,", moniker_data[i]);
994 if (i % 8 == 7) printf("\n");
999 GlobalUnlock(hglobal);
1001 IStream_Release(stream);
1003 /* Marshaling tests */
1005 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1006 ok_ole_success(hr, CreateStreamOnHGlobal);
1008 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1009 ok_ole_success(hr, CoMarshalInterface);
1011 hr = GetHGlobalFromStream(stream, &hglobal);
1012 ok_ole_success(hr, GetHGlobalFromStream);
1014 moniker_size = GlobalSize(hglobal);
1016 moniker_data = GlobalLock(hglobal);
1018 /* first check we have the right amount of data */
1019 ok(moniker_size == sizeof_expected_moniker_marshal_data,
1020 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1021 testname, sizeof_expected_moniker_marshal_data, moniker_size);
1023 /* then do a byte-by-byte comparison */
1024 if (expected_moniker_marshal_data)
1026 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_marshal_data); i++)
1028 if (expected_moniker_marshal_data[i] != moniker_data[i])
1036 ok(same, "%s: Marshaled data differs\n", testname);
1039 for (i = 0; i < moniker_size; i++)
1041 if (i % 8 == 0) printf(" ");
1042 printf("0x%02x,", moniker_data[i]);
1043 if (i % 8 == 7) printf("\n");
1048 GlobalUnlock(hglobal);
1050 IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1051 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
1052 ok_ole_success(hr, CoUnmarshalInterface);
1054 IStream_Release(stream);
1055 IMoniker_Release(moniker_proxy);
1058 static void test_class_moniker(void)
1069 hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
1070 ok_ole_success(hr, CreateClassMoniker);
1071 if (!moniker) return;
1073 test_moniker("class moniker", moniker,
1074 expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
1075 expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
1076 expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
1077 expected_class_moniker_display_name);
1081 hr = IMoniker_Hash(moniker, &hash);
1082 ok_ole_success(hr, IMoniker_Hash);
1084 ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
1085 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1088 /* IsSystemMoniker test */
1090 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1091 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1093 ok(moniker_type == MKSYS_CLASSMONIKER,
1094 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1097 hr = CreateBindCtx(0, &bindctx);
1098 ok_ole_success(hr, CreateBindCtx);
1100 /* IsRunning test */
1101 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1102 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1104 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1105 ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
1107 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1108 ok_ole_success(hr, IMoniker_BindToStorage);
1109 IUnknown_Release(unknown);
1111 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1112 ok_ole_success(hr, IMoniker_BindToStorage);
1113 IUnknown_Release(unknown);
1115 IBindCtx_Release(bindctx);
1117 hr = IMoniker_Inverse(moniker, &inverse);
1118 ok_ole_success(hr, IMoniker_Inverse);
1119 IMoniker_Release(inverse);
1121 IMoniker_Release(moniker);
1124 static void test_file_moniker(WCHAR* path)
1127 IMoniker *moniker1 = NULL, *moniker2 = NULL;
1130 hr = CreateFileMoniker(path, &moniker1);
1131 ok_ole_success(hr, CreateFileMoniker);
1133 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1136 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1137 ok_ole_success(hr, CoMarshalInterface);
1140 hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1141 ok_ole_success(hr, IStream_Seek);
1144 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
1145 ok_ole_success(hr, CoUnmarshalInterface);
1147 hr = IMoniker_IsEqual(moniker1, moniker2);
1148 ok_ole_success(hr, IsEqual);
1150 IStream_Release(stream);
1152 IMoniker_Release(moniker1);
1154 IMoniker_Release(moniker2);
1157 static void test_file_monikers(void)
1159 static WCHAR wszFile[][30] = {
1160 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1161 {'\\', '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},
1162 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1163 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1164 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1165 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1166 * U+0100 .. = Latin extended-A
1168 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1173 trace("ACP is %u\n", GetACP());
1175 for (i = 0; i < COUNTOF(wszFile); ++i)
1178 for (j = lstrlenW(wszFile[i]); j > 0; --j)
1181 test_file_moniker(wszFile[i]);
1186 static void test_item_moniker(void)
1195 static const WCHAR wszDelimeter[] = {'!',0};
1196 static const WCHAR wszObjectName[] = {'T','e','s','t',0};
1197 static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
1199 hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker);
1200 ok_ole_success(hr, CreateItemMoniker);
1202 test_moniker("item moniker", moniker,
1203 expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
1204 expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
1205 expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
1206 expected_display_name);
1210 hr = IMoniker_Hash(moniker, &hash);
1211 ok_ole_success(hr, IMoniker_Hash);
1214 "Hash value != 0x73c, instead was 0x%08x\n",
1217 /* IsSystemMoniker test */
1219 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1220 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1222 ok(moniker_type == MKSYS_ITEMMONIKER,
1223 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1226 hr = CreateBindCtx(0, &bindctx);
1227 ok_ole_success(hr, CreateBindCtx);
1229 /* IsRunning test */
1230 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1231 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1233 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1234 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1236 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1237 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1239 IBindCtx_Release(bindctx);
1241 hr = IMoniker_Inverse(moniker, &inverse);
1242 ok_ole_success(hr, IMoniker_Inverse);
1243 IMoniker_Release(inverse);
1245 IMoniker_Release(moniker);
1248 static void test_anti_moniker(void)
1258 static const WCHAR expected_display_name[] = { '\\','.','.',0 };
1260 hr = CreateAntiMoniker(&moniker);
1261 ok_ole_success(hr, CreateAntiMoniker);
1262 if (!moniker) return;
1264 test_moniker("anti moniker", moniker,
1265 expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
1266 expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
1267 expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
1268 expected_display_name);
1271 hr = IMoniker_Hash(moniker, &hash);
1272 ok_ole_success(hr, IMoniker_Hash);
1273 ok(hash == 0x80000001,
1274 "Hash value != 0x80000001, instead was 0x%08x\n",
1277 /* IsSystemMoniker test */
1278 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1279 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1280 ok(moniker_type == MKSYS_ANTIMONIKER,
1281 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1284 hr = IMoniker_Inverse(moniker, &inverse);
1285 ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
1286 ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
1288 hr = CreateBindCtx(0, &bindctx);
1289 ok_ole_success(hr, CreateBindCtx);
1291 /* IsRunning test */
1292 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1293 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1295 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1296 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1298 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1299 ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr);
1301 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1302 ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr);
1304 IBindCtx_Release(bindctx);
1306 IMoniker_Release(moniker);
1309 static void test_generic_composite_moniker(void)
1321 static const WCHAR wszDelimeter1[] = {'!',0};
1322 static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
1323 static const WCHAR wszDelimeter2[] = {'#',0};
1324 static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
1325 static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1327 hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1);
1328 ok_ole_success(hr, CreateItemMoniker);
1329 hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2);
1330 ok_ole_success(hr, CreateItemMoniker);
1331 hr = CreateGenericComposite(moniker1, moniker2, &moniker);
1332 ok_ole_success(hr, CreateGenericComposite);
1334 test_moniker("generic composite moniker", moniker,
1335 expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
1336 expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
1337 expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
1338 expected_display_name);
1342 hr = IMoniker_Hash(moniker, &hash);
1343 ok_ole_success(hr, IMoniker_Hash);
1346 "Hash value != 0xd87, instead was 0x%08x\n",
1349 /* IsSystemMoniker test */
1351 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1352 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1354 ok(moniker_type == MKSYS_GENERICCOMPOSITE,
1355 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1358 hr = CreateBindCtx(0, &bindctx);
1359 ok_ole_success(hr, CreateBindCtx);
1361 /* IsRunning test */
1362 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1364 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1366 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1367 ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);
1369 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1371 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1374 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1375 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1377 IBindCtx_Release(bindctx);
1379 hr = IMoniker_Inverse(moniker, &inverse);
1380 ok_ole_success(hr, IMoniker_Inverse);
1381 IMoniker_Release(inverse);
1383 IMoniker_Release(moniker);
1388 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1391 test_MkParseDisplayName();
1392 test_class_moniker();
1393 test_file_monikers();
1394 test_item_moniker();
1395 test_anti_moniker();
1396 test_generic_composite_moniker();
1398 /* FIXME: test moniker creation funcs and parsing other moniker formats */