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
);
592 ok_more_than_one_lock();
594 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
595 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
599 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
600 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
601 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
602 ok_ole_success(hr
, IRunningObjectTable_Register
);
604 ok_more_than_one_lock();
606 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
607 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
611 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
612 /* only succeeds when process is started by SCM and has LocalService
613 * or RunAs AppId values */
614 hr
= IRunningObjectTable_Register(pROT
,
615 ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
,
616 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
618 ok(hr
== CO_E_WRONG_SERVER_IDENTITY
, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr
);
621 hr
= IRunningObjectTable_Register(pROT
, 0xdeadbeef,
622 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
623 ok(hr
== E_INVALIDARG
, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
625 IMoniker_Release(pMoniker
);
627 IRunningObjectTable_Release(pROT
);
630 static int count_moniker_matches(IBindCtx
* pbc
, IEnumMoniker
* spEM
)
632 IMoniker
* spMoniker
;
633 int monCnt
=0, matchCnt
=0;
635 while ((IEnumMoniker_Next(spEM
, 1, &spMoniker
, NULL
)==S_OK
))
640 hr
=IMoniker_GetDisplayName(spMoniker
, pbc
, NULL
, &szDisplayn
);
643 if (!lstrcmpW(szDisplayn
, wszFileName1
) || !lstrcmpW(szDisplayn
, wszFileName2
))
645 CoTaskMemFree(szDisplayn
);
648 trace("Total number of monikers is %i\n", monCnt
);
652 static void test_MkParseDisplayName(void)
654 IBindCtx
* pbc
= NULL
;
656 IMoniker
* pmk
= NULL
;
657 IMoniker
* pmk1
= NULL
;
658 IMoniker
* pmk2
= NULL
;
661 IUnknown
* object
= NULL
;
665 IEnumMoniker
*spEM1
= NULL
;
666 IEnumMoniker
*spEM2
= NULL
;
667 IEnumMoniker
*spEM3
= NULL
;
672 IRunningObjectTable
* pprot
=NULL
;
674 /* CLSID of My Computer */
675 static const WCHAR wszDisplayName
[] = {'c','l','s','i','d',':',
676 '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};
678 hr
= CreateBindCtx(0, &pbc
);
679 ok_ole_success(hr
, CreateBindCtx
);
681 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
682 todo_wine
{ ok_ole_success(hr
, MkParseDisplayName
); }
686 hr
= IMoniker_BindToObject(pmk
, pbc
, NULL
, &IID_IUnknown
, (LPVOID
*)&object
);
687 ok_ole_success(hr
, IMoniker_BindToObject
);
689 IUnknown_Release(object
);
691 IBindCtx_Release(pbc
);
693 /* Test the EnumMoniker interface */
694 hr
= CreateBindCtx(0, &pbc
);
695 ok_ole_success(hr
, CreateBindCtx
);
697 hr
= CreateFileMoniker(wszFileName1
, &pmk1
);
698 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
699 hr
= CreateFileMoniker(wszFileName2
, &pmk2
);
700 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
701 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
702 ok(hr
==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr
);
704 /* Check EnumMoniker before registering */
705 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM1
);
706 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
707 hr
= IEnumMoniker_QueryInterface(spEM1
, &IID_IUnknown
, (void*) &lpEM1
);
708 /* Register a couple of Monikers and check is ok */
709 ok(hr
==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr
, lpEM1
);
712 matchCnt
= count_moniker_matches(pbc
, spEM1
);
713 trace("Number of matches is %i\n", matchCnt
);
715 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
716 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk1
, &pdwReg1
);
717 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
718 hr
, pprot
, grflags
, lpEM1
, pmk1
, pdwReg1
);
720 trace("IROT::Register\n");
722 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
723 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk2
, &pdwReg2
);
724 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr
,
725 pprot
, grflags
, lpEM1
, pmk2
, pdwReg2
);
727 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM2
);
728 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
730 matchCnt
= count_moniker_matches(pbc
, spEM2
);
731 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
733 trace("IEnumMoniker::Clone\n");
734 IEnumMoniker_Clone(spEM2
, &spEM3
);
736 matchCnt
= count_moniker_matches(pbc
, spEM3
);
737 ok(matchCnt
==0, "Number of matches should be equal to 0 not %i\n", matchCnt
);
738 trace("IEnumMoniker::Reset\n");
739 IEnumMoniker_Reset(spEM3
);
741 matchCnt
= count_moniker_matches(pbc
, spEM3
);
742 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
744 IRunningObjectTable_Revoke(pprot
,pdwReg1
);
745 IRunningObjectTable_Revoke(pprot
,pdwReg2
);
746 IEnumMoniker_Release(spEM1
);
747 IEnumMoniker_Release(spEM1
);
748 IEnumMoniker_Release(spEM2
);
749 IEnumMoniker_Release(spEM3
);
750 IMoniker_Release(pmk1
);
751 IMoniker_Release(pmk2
);
752 IRunningObjectTable_Release(pprot
);
754 IBindCtx_Release(pbc
);
757 static const LARGE_INTEGER llZero
;
759 static const BYTE expected_class_moniker_marshal_data
[] =
761 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
762 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
763 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
764 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
765 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
766 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
767 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
768 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
772 static const BYTE expected_class_moniker_saved_data
[] =
774 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
775 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
779 static const BYTE expected_class_moniker_comparison_data
[] =
781 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
782 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
783 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
784 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
787 static const WCHAR expected_class_moniker_display_name
[] =
789 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
790 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
791 '0','0','0','0','4','6',':',0
794 static const BYTE expected_item_moniker_comparison_data
[] =
796 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
797 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
798 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
802 static const BYTE expected_item_moniker_saved_data
[] =
804 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
805 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
808 static const BYTE expected_item_moniker_marshal_data
[] =
810 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
811 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
812 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
813 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
814 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
815 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
816 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
817 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
820 static const BYTE expected_anti_moniker_marshal_data
[] =
822 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
823 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
824 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
825 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
826 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
827 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
831 static const BYTE expected_anti_moniker_saved_data
[] =
836 static const BYTE expected_anti_moniker_comparison_data
[] =
838 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
839 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
843 static const BYTE expected_gc_moniker_marshal_data
[] =
845 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
846 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
847 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
848 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
849 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
850 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
851 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
852 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
853 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
854 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
855 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
856 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
857 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
858 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
859 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
860 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
861 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
862 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
863 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
864 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
865 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
866 0x00,0x57,0x69,0x6e,0x65,0x00,
869 static const BYTE expected_gc_moniker_saved_data
[] =
871 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
872 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
873 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
874 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
875 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
876 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
877 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
878 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
882 static const BYTE expected_gc_moniker_comparison_data
[] =
884 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
885 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
886 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
887 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
888 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
889 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
890 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
891 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
892 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
895 static void test_moniker(
896 const char *testname
, IMoniker
*moniker
,
897 const BYTE
*expected_moniker_marshal_data
, unsigned int sizeof_expected_moniker_marshal_data
,
898 const BYTE
*expected_moniker_saved_data
, unsigned int sizeof_expected_moniker_saved_data
,
899 const BYTE
*expected_moniker_comparison_data
, unsigned int sizeof_expected_moniker_comparison_data
,
900 LPCWSTR expected_display_name
)
911 IMoniker
* moniker_proxy
;
912 LPOLESTR display_name
;
915 hr
= IMoniker_IsDirty(moniker
);
916 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
920 hr
= CreateBindCtx(0, &bindctx
);
921 ok_ole_success(hr
, CreateBindCtx
);
923 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
924 ok_ole_success(hr
, IMoniker_GetDisplayName
);
925 ok(!lstrcmpW(display_name
, expected_display_name
), "display name wasn't what was expected\n");
927 CoTaskMemFree(display_name
);
928 IBindCtx_Release(bindctx
);
930 hr
= IMoniker_IsDirty(moniker
);
931 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
933 /* IROTData::GetComparisonData test */
935 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
936 ok_ole_success(hr
, IMoniker_QueryInterface_IID_IROTData
);
938 hr
= IROTData_GetComparisonData(rotdata
, buffer
, sizeof(buffer
), &moniker_size
);
939 ok_ole_success(hr
, IROTData_GetComparisonData
);
941 if (hr
!= S_OK
) moniker_size
= 0;
943 /* first check we have the right amount of data */
944 ok(moniker_size
== sizeof_expected_moniker_comparison_data
,
945 "%s: Size of comparison data differs (expected %d, actual %d)\n",
946 testname
, sizeof_expected_moniker_comparison_data
, moniker_size
);
948 /* then do a byte-by-byte comparison */
949 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_comparison_data
); i
++)
951 if (expected_moniker_comparison_data
[i
] != buffer
[i
])
958 ok(same
, "%s: Comparison data differs\n", testname
);
961 for (i
= 0; i
< moniker_size
; i
++)
963 if (i
% 8 == 0) printf(" ");
964 printf("0x%02x,", buffer
[i
]);
965 if (i
% 8 == 7) printf("\n");
970 IROTData_Release(rotdata
);
972 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
976 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
977 ok_ole_success(hr
, IMoniker_Save
);
979 hr
= GetHGlobalFromStream(stream
, &hglobal
);
980 ok_ole_success(hr
, GetHGlobalFromStream
);
982 moniker_size
= GlobalSize(hglobal
);
984 moniker_data
= GlobalLock(hglobal
);
986 /* first check we have the right amount of data */
987 ok(moniker_size
== sizeof_expected_moniker_saved_data
,
988 "%s: Size of saved data differs (expected %d, actual %d)\n",
989 testname
, sizeof_expected_moniker_saved_data
, moniker_size
);
991 /* then do a byte-by-byte comparison */
992 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_saved_data
); i
++)
994 if (expected_moniker_saved_data
[i
] != moniker_data
[i
])
1001 ok(same
, "%s: Saved data differs\n", testname
);
1004 for (i
= 0; i
< moniker_size
; i
++)
1006 if (i
% 8 == 0) printf(" ");
1007 printf("0x%02x,", moniker_data
[i
]);
1008 if (i
% 8 == 7) printf("\n");
1013 GlobalUnlock(hglobal
);
1015 IStream_Release(stream
);
1017 /* Marshaling tests */
1019 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1020 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1022 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1023 ok_ole_success(hr
, CoMarshalInterface
);
1025 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1026 ok_ole_success(hr
, GetHGlobalFromStream
);
1028 moniker_size
= GlobalSize(hglobal
);
1030 moniker_data
= GlobalLock(hglobal
);
1032 /* first check we have the right amount of data */
1033 ok(moniker_size
== sizeof_expected_moniker_marshal_data
,
1034 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1035 testname
, sizeof_expected_moniker_marshal_data
, moniker_size
);
1037 /* then do a byte-by-byte comparison */
1038 if (expected_moniker_marshal_data
)
1040 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_marshal_data
); i
++)
1042 if (expected_moniker_marshal_data
[i
] != moniker_data
[i
])
1050 ok(same
, "%s: Marshaled data differs\n", testname
);
1053 for (i
= 0; i
< moniker_size
; i
++)
1055 if (i
% 8 == 0) printf(" ");
1056 printf("0x%02x,", moniker_data
[i
]);
1057 if (i
% 8 == 7) printf("\n");
1062 GlobalUnlock(hglobal
);
1064 IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1065 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&moniker_proxy
);
1066 ok_ole_success(hr
, CoUnmarshalInterface
);
1068 IStream_Release(stream
);
1069 IMoniker_Release(moniker_proxy
);
1072 static void test_class_moniker(void)
1083 hr
= CreateClassMoniker(&CLSID_StdComponentCategoriesMgr
, &moniker
);
1084 ok_ole_success(hr
, CreateClassMoniker
);
1085 if (!moniker
) return;
1087 test_moniker("class moniker", moniker
,
1088 expected_class_moniker_marshal_data
, sizeof(expected_class_moniker_marshal_data
),
1089 expected_class_moniker_saved_data
, sizeof(expected_class_moniker_saved_data
),
1090 expected_class_moniker_comparison_data
, sizeof(expected_class_moniker_comparison_data
),
1091 expected_class_moniker_display_name
);
1095 hr
= IMoniker_Hash(moniker
, &hash
);
1096 ok_ole_success(hr
, IMoniker_Hash
);
1098 ok(hash
== CLSID_StdComponentCategoriesMgr
.Data1
,
1099 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1102 /* IsSystemMoniker test */
1104 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1105 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1107 ok(moniker_type
== MKSYS_CLASSMONIKER
,
1108 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1111 hr
= CreateBindCtx(0, &bindctx
);
1112 ok_ole_success(hr
, CreateBindCtx
);
1114 /* IsRunning test */
1115 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1116 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1118 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1119 ok(hr
== MK_E_UNAVAILABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr
);
1121 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1122 ok_ole_success(hr
, IMoniker_BindToStorage
);
1123 IUnknown_Release(unknown
);
1125 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1126 ok_ole_success(hr
, IMoniker_BindToStorage
);
1127 IUnknown_Release(unknown
);
1129 IBindCtx_Release(bindctx
);
1131 hr
= IMoniker_Inverse(moniker
, &inverse
);
1132 ok_ole_success(hr
, IMoniker_Inverse
);
1133 IMoniker_Release(inverse
);
1135 IMoniker_Release(moniker
);
1138 static void test_file_moniker(WCHAR
* path
)
1141 IMoniker
*moniker1
= NULL
, *moniker2
= NULL
;
1144 hr
= CreateFileMoniker(path
, &moniker1
);
1145 ok_ole_success(hr
, CreateFileMoniker
);
1147 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1150 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker1
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1151 ok_ole_success(hr
, CoMarshalInterface
);
1154 hr
= IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1155 ok_ole_success(hr
, IStream_Seek
);
1158 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void**)&moniker2
);
1159 ok_ole_success(hr
, CoUnmarshalInterface
);
1161 hr
= IMoniker_IsEqual(moniker1
, moniker2
);
1162 ok_ole_success(hr
, IsEqual
);
1164 IStream_Release(stream
);
1166 IMoniker_Release(moniker1
);
1168 IMoniker_Release(moniker2
);
1171 static void test_file_monikers(void)
1173 static WCHAR wszFile
[][30] = {
1174 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1175 {'\\', '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},
1176 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1177 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1178 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1179 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1180 * U+0100 .. = Latin extended-A
1182 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1187 trace("ACP is %u\n", GetACP());
1189 for (i
= 0; i
< COUNTOF(wszFile
); ++i
)
1192 for (j
= lstrlenW(wszFile
[i
]); j
> 0; --j
)
1195 test_file_moniker(wszFile
[i
]);
1200 static void test_item_moniker(void)
1209 static const WCHAR wszDelimeter
[] = {'!',0};
1210 static const WCHAR wszObjectName
[] = {'T','e','s','t',0};
1211 static const WCHAR expected_display_name
[] = { '!','T','e','s','t',0 };
1213 hr
= CreateItemMoniker(wszDelimeter
, wszObjectName
, &moniker
);
1214 ok_ole_success(hr
, CreateItemMoniker
);
1216 test_moniker("item moniker", moniker
,
1217 expected_item_moniker_marshal_data
, sizeof(expected_item_moniker_marshal_data
),
1218 expected_item_moniker_saved_data
, sizeof(expected_item_moniker_saved_data
),
1219 expected_item_moniker_comparison_data
, sizeof(expected_item_moniker_comparison_data
),
1220 expected_display_name
);
1224 hr
= IMoniker_Hash(moniker
, &hash
);
1225 ok_ole_success(hr
, IMoniker_Hash
);
1228 "Hash value != 0x73c, instead was 0x%08x\n",
1231 /* IsSystemMoniker test */
1233 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1234 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1236 ok(moniker_type
== MKSYS_ITEMMONIKER
,
1237 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1240 hr
= CreateBindCtx(0, &bindctx
);
1241 ok_ole_success(hr
, CreateBindCtx
);
1243 /* IsRunning test */
1244 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1245 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1247 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1248 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1250 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1251 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1253 IBindCtx_Release(bindctx
);
1255 hr
= IMoniker_Inverse(moniker
, &inverse
);
1256 ok_ole_success(hr
, IMoniker_Inverse
);
1257 IMoniker_Release(inverse
);
1259 IMoniker_Release(moniker
);
1262 static void test_anti_moniker(void)
1272 static const WCHAR expected_display_name
[] = { '\\','.','.',0 };
1274 hr
= CreateAntiMoniker(&moniker
);
1275 ok_ole_success(hr
, CreateAntiMoniker
);
1276 if (!moniker
) return;
1278 test_moniker("anti moniker", moniker
,
1279 expected_anti_moniker_marshal_data
, sizeof(expected_anti_moniker_marshal_data
),
1280 expected_anti_moniker_saved_data
, sizeof(expected_anti_moniker_saved_data
),
1281 expected_anti_moniker_comparison_data
, sizeof(expected_anti_moniker_comparison_data
),
1282 expected_display_name
);
1285 hr
= IMoniker_Hash(moniker
, &hash
);
1286 ok_ole_success(hr
, IMoniker_Hash
);
1287 ok(hash
== 0x80000001,
1288 "Hash value != 0x80000001, instead was 0x%08x\n",
1291 /* IsSystemMoniker test */
1292 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1293 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1294 ok(moniker_type
== MKSYS_ANTIMONIKER
,
1295 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1298 hr
= IMoniker_Inverse(moniker
, &inverse
);
1299 ok(hr
== MK_E_NOINVERSE
, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr
);
1300 ok(inverse
== NULL
, "inverse should have been set to NULL instead of %p\n", inverse
);
1302 hr
= CreateBindCtx(0, &bindctx
);
1303 ok_ole_success(hr
, CreateBindCtx
);
1305 /* IsRunning test */
1306 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1307 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1309 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1310 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1312 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1313 ok(hr
== E_NOTIMPL
, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr
);
1315 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1316 ok(hr
== E_NOTIMPL
, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr
);
1318 IBindCtx_Release(bindctx
);
1320 IMoniker_Release(moniker
);
1323 static void test_generic_composite_moniker(void)
1335 static const WCHAR wszDelimeter1
[] = {'!',0};
1336 static const WCHAR wszObjectName1
[] = {'T','e','s','t',0};
1337 static const WCHAR wszDelimeter2
[] = {'#',0};
1338 static const WCHAR wszObjectName2
[] = {'W','i','n','e',0};
1339 static const WCHAR expected_display_name
[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1341 hr
= CreateItemMoniker(wszDelimeter1
, wszObjectName1
, &moniker1
);
1342 ok_ole_success(hr
, CreateItemMoniker
);
1343 hr
= CreateItemMoniker(wszDelimeter2
, wszObjectName2
, &moniker2
);
1344 ok_ole_success(hr
, CreateItemMoniker
);
1345 hr
= CreateGenericComposite(moniker1
, moniker2
, &moniker
);
1346 ok_ole_success(hr
, CreateGenericComposite
);
1348 test_moniker("generic composite moniker", moniker
,
1349 expected_gc_moniker_marshal_data
, sizeof(expected_gc_moniker_marshal_data
),
1350 expected_gc_moniker_saved_data
, sizeof(expected_gc_moniker_saved_data
),
1351 expected_gc_moniker_comparison_data
, sizeof(expected_gc_moniker_comparison_data
),
1352 expected_display_name
);
1356 hr
= IMoniker_Hash(moniker
, &hash
);
1357 ok_ole_success(hr
, IMoniker_Hash
);
1360 "Hash value != 0xd87, instead was 0x%08x\n",
1363 /* IsSystemMoniker test */
1365 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1366 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1368 ok(moniker_type
== MKSYS_GENERICCOMPOSITE
,
1369 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1372 hr
= CreateBindCtx(0, &bindctx
);
1373 ok_ole_success(hr
, CreateBindCtx
);
1375 /* IsRunning test */
1376 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1378 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1380 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1381 ok(hr
== MK_E_NOTBINDABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr
);
1383 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1385 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1388 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1389 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1391 IBindCtx_Release(bindctx
);
1393 hr
= IMoniker_Inverse(moniker
, &inverse
);
1394 ok_ole_success(hr
, IMoniker_Inverse
);
1395 IMoniker_Release(inverse
);
1397 IMoniker_Release(moniker
);
1402 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1405 test_MkParseDisplayName();
1406 test_class_moniker();
1407 test_file_monikers();
1408 test_item_moniker();
1409 test_anti_moniker();
1410 test_generic_composite_moniker();
1412 /* FIXME: test moniker creation funcs and parsing other moniker formats */