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
};
144 const IUnknownVtbl
*lpVtbl
;
148 static HRESULT WINAPI
HeapUnknown_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
150 if (IsEqualIID(riid
, &IID_IUnknown
))
152 IUnknown_AddRef(iface
);
153 *ppv
= (LPVOID
)iface
;
157 return E_NOINTERFACE
;
160 static ULONG WINAPI
HeapUnknown_AddRef(IUnknown
*iface
)
162 HeapUnknown
*This
= (HeapUnknown
*)iface
;
163 return InterlockedIncrement((LONG
*)&This
->refs
);
166 static ULONG WINAPI
HeapUnknown_Release(IUnknown
*iface
)
168 HeapUnknown
*This
= (HeapUnknown
*)iface
;
169 ULONG refs
= InterlockedDecrement((LONG
*)&This
->refs
);
170 if (!refs
) HeapFree(GetProcessHeap(), 0, This
);
174 static const IUnknownVtbl HeapUnknown_Vtbl
=
176 HeapUnknown_QueryInterface
,
181 static HRESULT WINAPI
182 MonikerNoROTData_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
189 if (IsEqualIID(&IID_IUnknown
, riid
) ||
190 IsEqualIID(&IID_IPersist
, riid
) ||
191 IsEqualIID(&IID_IPersistStream
,riid
) ||
192 IsEqualIID(&IID_IMoniker
, riid
))
194 if (IsEqualIID(&IID_IROTData
, riid
))
195 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
198 return E_NOINTERFACE
;
200 IMoniker_AddRef(iface
);
206 Moniker_AddRef(IMoniker
* iface
)
212 Moniker_Release(IMoniker
* iface
)
217 static HRESULT WINAPI
218 Moniker_GetClassID(IMoniker
* iface
, CLSID
*pClassID
)
220 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
222 *pClassID
= CLSID_TestMoniker
;
227 static HRESULT WINAPI
228 Moniker_IsDirty(IMoniker
* iface
)
230 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
235 static HRESULT WINAPI
236 Moniker_Load(IMoniker
* iface
, IStream
* pStm
)
238 CHECK_EXPECTED_METHOD("Moniker_Load");
242 static HRESULT WINAPI
243 Moniker_Save(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
)
245 CHECK_EXPECTED_METHOD("Moniker_Save");
249 static HRESULT WINAPI
250 Moniker_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
252 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
256 static HRESULT WINAPI
257 Moniker_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
258 REFIID riid
, VOID
** ppvResult
)
260 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
264 static HRESULT WINAPI
265 Moniker_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
266 REFIID riid
, VOID
** ppvObject
)
268 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
272 static HRESULT WINAPI
273 Moniker_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
274 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
276 CHECK_EXPECTED_METHOD("Moniker_Reduce");
278 if (ppmkReduced
==NULL
)
281 IMoniker_AddRef(iface
);
285 return MK_S_REDUCED_TO_SELF
;
288 static HRESULT WINAPI
289 Moniker_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
290 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
292 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
296 static HRESULT WINAPI
297 Moniker_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
299 CHECK_EXPECTED_METHOD("Moniker_Enum");
301 if (ppenumMoniker
== NULL
)
304 *ppenumMoniker
= NULL
;
309 static HRESULT WINAPI
310 Moniker_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
312 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
316 static HRESULT WINAPI
317 Moniker_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
319 CHECK_EXPECTED_METHOD("Moniker_Hash");
323 static HRESULT WINAPI
324 Moniker_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
325 IMoniker
* pmkNewlyRunning
)
327 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
331 static HRESULT WINAPI
332 Moniker_GetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
,
333 IMoniker
* pmkToLeft
, FILETIME
* pFileTime
)
335 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
339 static HRESULT WINAPI
340 Moniker_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
342 CHECK_EXPECTED_METHOD("Moniker_Inverse");
346 static HRESULT WINAPI
347 Moniker_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
349 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
353 static HRESULT WINAPI
354 Moniker_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
356 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
360 static HRESULT WINAPI
361 Moniker_GetDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
362 IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
364 static const WCHAR wszDisplayName
[] = {'*','*','G','e','m','m','a',0};
365 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
366 *ppszDisplayName
= (LPOLESTR
)CoTaskMemAlloc(sizeof(wszDisplayName
));
367 memcpy(*ppszDisplayName
, wszDisplayName
, sizeof(wszDisplayName
));
371 static HRESULT WINAPI
372 Moniker_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
373 LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
)
375 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
379 static HRESULT WINAPI
380 Moniker_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
382 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
387 (*pwdMksys
)=MKSYS_NONE
;
392 static const IMonikerVtbl MonikerNoROTDataVtbl
=
394 MonikerNoROTData_QueryInterface
,
402 Moniker_BindToObject
,
403 Moniker_BindToStorage
,
410 Moniker_GetTimeOfLastChange
,
412 Moniker_CommonPrefixWith
,
413 Moniker_RelativePathTo
,
414 Moniker_GetDisplayName
,
415 Moniker_ParseDisplayName
,
416 Moniker_IsSystemMoniker
419 static IMoniker MonikerNoROTData
= { &MonikerNoROTDataVtbl
};
421 static IMoniker Moniker
;
423 static HRESULT WINAPI
424 ROTData_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
426 return IMoniker_QueryInterface(&Moniker
, riid
, ppvObject
);
430 ROTData_AddRef(IROTData
*iface
)
436 ROTData_Release(IROTData
* iface
)
441 static HRESULT WINAPI
442 ROTData_GetComparisonData(IROTData
* iface
, BYTE
* pbData
,
443 ULONG cbMax
, ULONG
* pcbData
)
445 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
448 if (cbMax
< *pcbData
)
449 return E_OUTOFMEMORY
;
456 static IROTDataVtbl ROTDataVtbl
=
458 ROTData_QueryInterface
,
461 ROTData_GetComparisonData
464 static IROTData ROTData
= { &ROTDataVtbl
};
466 static HRESULT WINAPI
467 Moniker_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
474 if (IsEqualIID(&IID_IUnknown
, riid
) ||
475 IsEqualIID(&IID_IPersist
, riid
) ||
476 IsEqualIID(&IID_IPersistStream
,riid
) ||
477 IsEqualIID(&IID_IMoniker
, riid
))
479 if (IsEqualIID(&IID_IROTData
, riid
))
481 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
482 *ppvObject
= &ROTData
;
486 return E_NOINTERFACE
;
488 IMoniker_AddRef(iface
);
493 static const IMonikerVtbl MonikerVtbl
=
495 Moniker_QueryInterface
,
503 Moniker_BindToObject
,
504 Moniker_BindToStorage
,
511 Moniker_GetTimeOfLastChange
,
513 Moniker_CommonPrefixWith
,
514 Moniker_RelativePathTo
,
515 Moniker_GetDisplayName
,
516 Moniker_ParseDisplayName
,
517 Moniker_IsSystemMoniker
520 static IMoniker Moniker
= { &MonikerVtbl
};
522 static void test_ROT(void)
524 static const WCHAR wszFileName
[] = {'B','E','2','0','E','2','F','5','-',
525 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
526 '2','0','4','6','E','5','8','6','C','9','2','5',0};
528 IMoniker
*pMoniker
= NULL
;
529 IRunningObjectTable
*pROT
= NULL
;
531 static const char *methods_register_no_ROTData
[] =
534 "Moniker_GetTimeOfLastChange",
535 "Moniker_QueryInterface(IID_IROTData)",
536 "Moniker_GetDisplayName",
537 "Moniker_GetClassID",
540 static const char *methods_register
[] =
543 "Moniker_GetTimeOfLastChange",
544 "Moniker_QueryInterface(IID_IROTData)",
545 "ROTData_GetComparisonData",
548 static const char *methods_isrunning_no_ROTData
[] =
551 "Moniker_QueryInterface(IID_IROTData)",
552 "Moniker_GetDisplayName",
553 "Moniker_GetClassID",
556 static const char *methods_isrunning
[] =
559 "Moniker_QueryInterface(IID_IROTData)",
560 "ROTData_GetComparisonData",
566 hr
= GetRunningObjectTable(0, &pROT
);
567 ok_ole_success(hr
, GetRunningObjectTable
);
569 expected_method_list
= methods_register_no_ROTData
;
570 /* try with our own moniker that doesn't support IROTData */
571 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
572 (IUnknown
*)&Test_ClassFactory
, &MonikerNoROTData
, &dwCookie
);
573 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
574 ok_ole_success(hr
, IRunningObjectTable_Register
);
576 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
578 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
579 ok_more_than_one_lock();
582 expected_method_list
= methods_isrunning_no_ROTData
;
583 hr
= IRunningObjectTable_IsRunning(pROT
, &MonikerNoROTData
);
584 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
585 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
587 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
589 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
590 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
591 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
596 expected_method_list
= methods_register
;
597 /* try with our own moniker */
598 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
599 (IUnknown
*)&Test_ClassFactory
, &Moniker
, &dwCookie
);
600 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
601 ok_ole_success(hr
, IRunningObjectTable_Register
);
603 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
605 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
606 ok_more_than_one_lock();
609 expected_method_list
= methods_isrunning
;
610 hr
= IRunningObjectTable_IsRunning(pROT
, &Moniker
);
611 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
612 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
614 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
616 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
617 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
618 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
623 hr
= CreateFileMoniker(wszFileName
, &pMoniker
);
624 ok_ole_success(hr
, CreateClassMoniker
);
627 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
,
628 pMoniker
, &dwCookie
);
629 ok_ole_success(hr
, IRunningObjectTable_Register
);
631 ok_more_than_one_lock();
633 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
634 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
638 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
639 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
640 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
641 ok_ole_success(hr
, IRunningObjectTable_Register
);
643 ok_more_than_one_lock();
645 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
646 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
650 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
651 /* only succeeds when process is started by SCM and has LocalService
652 * or RunAs AppId values */
653 hr
= IRunningObjectTable_Register(pROT
,
654 ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
,
655 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
657 ok(hr
== CO_E_WRONG_SERVER_IDENTITY
, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr
);
660 hr
= IRunningObjectTable_Register(pROT
, 0xdeadbeef,
661 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
662 ok(hr
== E_INVALIDARG
, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
664 IMoniker_Release(pMoniker
);
666 IRunningObjectTable_Release(pROT
);
669 static int count_moniker_matches(IBindCtx
* pbc
, IEnumMoniker
* spEM
)
671 IMoniker
* spMoniker
;
672 int monCnt
=0, matchCnt
=0;
674 while ((IEnumMoniker_Next(spEM
, 1, &spMoniker
, NULL
)==S_OK
))
679 hr
=IMoniker_GetDisplayName(spMoniker
, pbc
, NULL
, &szDisplayn
);
682 if (!lstrcmpW(szDisplayn
, wszFileName1
) || !lstrcmpW(szDisplayn
, wszFileName2
))
684 CoTaskMemFree(szDisplayn
);
687 trace("Total number of monikers is %i\n", monCnt
);
691 static void test_MkParseDisplayName(void)
693 IBindCtx
* pbc
= NULL
;
695 IMoniker
* pmk
= NULL
;
696 IMoniker
* pmk1
= NULL
;
697 IMoniker
* pmk2
= NULL
;
700 IUnknown
* object
= NULL
;
704 IEnumMoniker
*spEM1
= NULL
;
705 IEnumMoniker
*spEM2
= NULL
;
706 IEnumMoniker
*spEM3
= NULL
;
711 IRunningObjectTable
* pprot
=NULL
;
713 /* CLSID of My Computer */
714 static const WCHAR wszDisplayName
[] = {'c','l','s','i','d',':',
715 '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};
717 hr
= CreateBindCtx(0, &pbc
);
718 ok_ole_success(hr
, CreateBindCtx
);
720 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
721 todo_wine
{ ok_ole_success(hr
, MkParseDisplayName
); }
725 hr
= IMoniker_BindToObject(pmk
, pbc
, NULL
, &IID_IUnknown
, (LPVOID
*)&object
);
726 ok_ole_success(hr
, IMoniker_BindToObject
);
728 IUnknown_Release(object
);
730 IBindCtx_Release(pbc
);
732 /* Test the EnumMoniker interface */
733 hr
= CreateBindCtx(0, &pbc
);
734 ok_ole_success(hr
, CreateBindCtx
);
736 hr
= CreateFileMoniker(wszFileName1
, &pmk1
);
737 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
738 hr
= CreateFileMoniker(wszFileName2
, &pmk2
);
739 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
740 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
741 ok(hr
==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr
);
743 /* Check EnumMoniker before registering */
744 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM1
);
745 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
746 hr
= IEnumMoniker_QueryInterface(spEM1
, &IID_IUnknown
, (void*) &lpEM1
);
747 /* Register a couple of Monikers and check is ok */
748 ok(hr
==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr
, lpEM1
);
751 matchCnt
= count_moniker_matches(pbc
, spEM1
);
752 trace("Number of matches is %i\n", matchCnt
);
754 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
755 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk1
, &pdwReg1
);
756 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
757 hr
, pprot
, grflags
, lpEM1
, pmk1
, pdwReg1
);
759 trace("IROT::Register\n");
761 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
762 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk2
, &pdwReg2
);
763 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr
,
764 pprot
, grflags
, lpEM1
, pmk2
, pdwReg2
);
766 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM2
);
767 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
769 matchCnt
= count_moniker_matches(pbc
, spEM2
);
770 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
772 trace("IEnumMoniker::Clone\n");
773 IEnumMoniker_Clone(spEM2
, &spEM3
);
775 matchCnt
= count_moniker_matches(pbc
, spEM3
);
776 ok(matchCnt
==0, "Number of matches should be equal to 0 not %i\n", matchCnt
);
777 trace("IEnumMoniker::Reset\n");
778 IEnumMoniker_Reset(spEM3
);
780 matchCnt
= count_moniker_matches(pbc
, spEM3
);
781 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
783 IRunningObjectTable_Revoke(pprot
,pdwReg1
);
784 IRunningObjectTable_Revoke(pprot
,pdwReg2
);
785 IEnumMoniker_Release(spEM1
);
786 IEnumMoniker_Release(spEM1
);
787 IEnumMoniker_Release(spEM2
);
788 IEnumMoniker_Release(spEM3
);
789 IMoniker_Release(pmk1
);
790 IMoniker_Release(pmk2
);
791 IRunningObjectTable_Release(pprot
);
793 IBindCtx_Release(pbc
);
796 static const LARGE_INTEGER llZero
;
798 static const BYTE expected_class_moniker_marshal_data
[] =
800 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
801 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
802 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
803 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
804 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
805 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
806 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
807 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
811 static const BYTE expected_class_moniker_saved_data
[] =
813 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
814 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
818 static const BYTE expected_class_moniker_comparison_data
[] =
820 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
821 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
822 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
823 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
826 static const WCHAR expected_class_moniker_display_name
[] =
828 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
829 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
830 '0','0','0','0','4','6',':',0
833 static const BYTE expected_item_moniker_comparison_data
[] =
835 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
836 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
837 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
841 static const BYTE expected_item_moniker_saved_data
[] =
843 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
844 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
847 static const BYTE expected_item_moniker_marshal_data
[] =
849 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
850 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
851 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
852 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
853 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
854 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
855 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
856 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
859 static const BYTE expected_anti_moniker_marshal_data
[] =
861 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
862 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
863 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
864 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
865 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
866 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
870 static const BYTE expected_anti_moniker_saved_data
[] =
875 static const BYTE expected_anti_moniker_comparison_data
[] =
877 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
878 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
882 static const BYTE expected_gc_moniker_marshal_data
[] =
884 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
885 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
886 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
887 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
888 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
889 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
890 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
891 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
892 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
893 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
894 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
895 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
896 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
897 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
898 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
899 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
900 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
901 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
902 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
903 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
904 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
905 0x00,0x57,0x69,0x6e,0x65,0x00,
908 static const BYTE expected_gc_moniker_saved_data
[] =
910 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
911 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
912 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
913 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
914 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
915 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
916 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
917 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
921 static const BYTE expected_gc_moniker_comparison_data
[] =
923 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
924 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
925 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
926 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
927 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
928 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
929 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
930 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
931 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
934 static void test_moniker(
935 const char *testname
, IMoniker
*moniker
,
936 const BYTE
*expected_moniker_marshal_data
, unsigned int sizeof_expected_moniker_marshal_data
,
937 const BYTE
*expected_moniker_saved_data
, unsigned int sizeof_expected_moniker_saved_data
,
938 const BYTE
*expected_moniker_comparison_data
, unsigned int sizeof_expected_moniker_comparison_data
,
939 LPCWSTR expected_display_name
)
950 IMoniker
* moniker_proxy
;
951 LPOLESTR display_name
;
954 hr
= IMoniker_IsDirty(moniker
);
955 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
959 hr
= CreateBindCtx(0, &bindctx
);
960 ok_ole_success(hr
, CreateBindCtx
);
962 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
963 ok_ole_success(hr
, IMoniker_GetDisplayName
);
964 ok(!lstrcmpW(display_name
, expected_display_name
), "display name wasn't what was expected\n");
966 CoTaskMemFree(display_name
);
967 IBindCtx_Release(bindctx
);
969 hr
= IMoniker_IsDirty(moniker
);
970 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
972 /* IROTData::GetComparisonData test */
974 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
975 ok_ole_success(hr
, IMoniker_QueryInterface_IID_IROTData
);
977 hr
= IROTData_GetComparisonData(rotdata
, buffer
, sizeof(buffer
), &moniker_size
);
978 ok_ole_success(hr
, IROTData_GetComparisonData
);
980 if (hr
!= S_OK
) moniker_size
= 0;
982 /* first check we have the right amount of data */
983 ok(moniker_size
== sizeof_expected_moniker_comparison_data
,
984 "%s: Size of comparison data differs (expected %d, actual %d)\n",
985 testname
, sizeof_expected_moniker_comparison_data
, moniker_size
);
987 /* then do a byte-by-byte comparison */
988 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_comparison_data
); i
++)
990 if (expected_moniker_comparison_data
[i
] != buffer
[i
])
997 ok(same
, "%s: Comparison data differs\n", testname
);
1000 for (i
= 0; i
< moniker_size
; i
++)
1002 if (i
% 8 == 0) printf(" ");
1003 printf("0x%02x,", buffer
[i
]);
1004 if (i
% 8 == 7) printf("\n");
1009 IROTData_Release(rotdata
);
1011 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1015 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1016 ok_ole_success(hr
, IMoniker_Save
);
1018 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1019 ok_ole_success(hr
, GetHGlobalFromStream
);
1021 moniker_size
= GlobalSize(hglobal
);
1023 moniker_data
= GlobalLock(hglobal
);
1025 /* first check we have the right amount of data */
1026 ok(moniker_size
== sizeof_expected_moniker_saved_data
,
1027 "%s: Size of saved data differs (expected %d, actual %d)\n",
1028 testname
, sizeof_expected_moniker_saved_data
, moniker_size
);
1030 /* then do a byte-by-byte comparison */
1031 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_saved_data
); i
++)
1033 if (expected_moniker_saved_data
[i
] != moniker_data
[i
])
1040 ok(same
, "%s: Saved data differs\n", testname
);
1043 for (i
= 0; i
< moniker_size
; i
++)
1045 if (i
% 8 == 0) printf(" ");
1046 printf("0x%02x,", moniker_data
[i
]);
1047 if (i
% 8 == 7) printf("\n");
1052 GlobalUnlock(hglobal
);
1054 IStream_Release(stream
);
1056 /* Marshaling tests */
1058 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1059 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1061 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1062 ok_ole_success(hr
, CoMarshalInterface
);
1064 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1065 ok_ole_success(hr
, GetHGlobalFromStream
);
1067 moniker_size
= GlobalSize(hglobal
);
1069 moniker_data
= GlobalLock(hglobal
);
1071 /* first check we have the right amount of data */
1072 ok(moniker_size
== sizeof_expected_moniker_marshal_data
,
1073 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1074 testname
, sizeof_expected_moniker_marshal_data
, moniker_size
);
1076 /* then do a byte-by-byte comparison */
1077 if (expected_moniker_marshal_data
)
1079 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_marshal_data
); i
++)
1081 if (expected_moniker_marshal_data
[i
] != moniker_data
[i
])
1089 ok(same
, "%s: Marshaled data differs\n", testname
);
1092 for (i
= 0; i
< moniker_size
; i
++)
1094 if (i
% 8 == 0) printf(" ");
1095 printf("0x%02x,", moniker_data
[i
]);
1096 if (i
% 8 == 7) printf("\n");
1101 GlobalUnlock(hglobal
);
1103 IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1104 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&moniker_proxy
);
1105 ok_ole_success(hr
, CoUnmarshalInterface
);
1107 IStream_Release(stream
);
1108 IMoniker_Release(moniker_proxy
);
1111 static void test_class_moniker(void)
1122 hr
= CreateClassMoniker(&CLSID_StdComponentCategoriesMgr
, &moniker
);
1123 ok_ole_success(hr
, CreateClassMoniker
);
1124 if (!moniker
) return;
1126 test_moniker("class moniker", moniker
,
1127 expected_class_moniker_marshal_data
, sizeof(expected_class_moniker_marshal_data
),
1128 expected_class_moniker_saved_data
, sizeof(expected_class_moniker_saved_data
),
1129 expected_class_moniker_comparison_data
, sizeof(expected_class_moniker_comparison_data
),
1130 expected_class_moniker_display_name
);
1134 hr
= IMoniker_Hash(moniker
, &hash
);
1135 ok_ole_success(hr
, IMoniker_Hash
);
1137 ok(hash
== CLSID_StdComponentCategoriesMgr
.Data1
,
1138 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1141 /* IsSystemMoniker test */
1143 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1144 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1146 ok(moniker_type
== MKSYS_CLASSMONIKER
,
1147 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1150 hr
= CreateBindCtx(0, &bindctx
);
1151 ok_ole_success(hr
, CreateBindCtx
);
1153 /* IsRunning test */
1154 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1155 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1157 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1158 ok(hr
== MK_E_UNAVAILABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr
);
1160 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1161 ok_ole_success(hr
, IMoniker_BindToStorage
);
1162 IUnknown_Release(unknown
);
1164 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1165 ok_ole_success(hr
, IMoniker_BindToStorage
);
1166 IUnknown_Release(unknown
);
1168 IBindCtx_Release(bindctx
);
1170 hr
= IMoniker_Inverse(moniker
, &inverse
);
1171 ok_ole_success(hr
, IMoniker_Inverse
);
1172 IMoniker_Release(inverse
);
1174 IMoniker_Release(moniker
);
1177 static void test_file_moniker(WCHAR
* path
)
1180 IMoniker
*moniker1
= NULL
, *moniker2
= NULL
;
1183 hr
= CreateFileMoniker(path
, &moniker1
);
1184 ok_ole_success(hr
, CreateFileMoniker
);
1186 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1189 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker1
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1190 ok_ole_success(hr
, CoMarshalInterface
);
1193 hr
= IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1194 ok_ole_success(hr
, IStream_Seek
);
1197 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void**)&moniker2
);
1198 ok_ole_success(hr
, CoUnmarshalInterface
);
1200 hr
= IMoniker_IsEqual(moniker1
, moniker2
);
1201 ok_ole_success(hr
, IsEqual
);
1203 IStream_Release(stream
);
1205 IMoniker_Release(moniker1
);
1207 IMoniker_Release(moniker2
);
1210 static void test_file_monikers(void)
1212 static WCHAR wszFile
[][30] = {
1213 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1214 {'\\', '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},
1215 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1216 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1217 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1218 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1219 * U+0100 .. = Latin extended-A
1221 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1226 trace("ACP is %u\n", GetACP());
1228 for (i
= 0; i
< COUNTOF(wszFile
); ++i
)
1231 for (j
= lstrlenW(wszFile
[i
]); j
> 0; --j
)
1234 test_file_moniker(wszFile
[i
]);
1239 static void test_item_moniker(void)
1248 static const WCHAR wszDelimeter
[] = {'!',0};
1249 static const WCHAR wszObjectName
[] = {'T','e','s','t',0};
1250 static const WCHAR expected_display_name
[] = { '!','T','e','s','t',0 };
1252 hr
= CreateItemMoniker(wszDelimeter
, wszObjectName
, &moniker
);
1253 ok_ole_success(hr
, CreateItemMoniker
);
1255 test_moniker("item moniker", moniker
,
1256 expected_item_moniker_marshal_data
, sizeof(expected_item_moniker_marshal_data
),
1257 expected_item_moniker_saved_data
, sizeof(expected_item_moniker_saved_data
),
1258 expected_item_moniker_comparison_data
, sizeof(expected_item_moniker_comparison_data
),
1259 expected_display_name
);
1263 hr
= IMoniker_Hash(moniker
, &hash
);
1264 ok_ole_success(hr
, IMoniker_Hash
);
1267 "Hash value != 0x73c, instead was 0x%08x\n",
1270 /* IsSystemMoniker test */
1272 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1273 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1275 ok(moniker_type
== MKSYS_ITEMMONIKER
,
1276 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1279 hr
= CreateBindCtx(0, &bindctx
);
1280 ok_ole_success(hr
, CreateBindCtx
);
1282 /* IsRunning test */
1283 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1284 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1286 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1287 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1289 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1290 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1292 IBindCtx_Release(bindctx
);
1294 hr
= IMoniker_Inverse(moniker
, &inverse
);
1295 ok_ole_success(hr
, IMoniker_Inverse
);
1296 IMoniker_Release(inverse
);
1298 IMoniker_Release(moniker
);
1301 static void test_anti_moniker(void)
1311 static const WCHAR expected_display_name
[] = { '\\','.','.',0 };
1313 hr
= CreateAntiMoniker(&moniker
);
1314 ok_ole_success(hr
, CreateAntiMoniker
);
1315 if (!moniker
) return;
1317 test_moniker("anti moniker", moniker
,
1318 expected_anti_moniker_marshal_data
, sizeof(expected_anti_moniker_marshal_data
),
1319 expected_anti_moniker_saved_data
, sizeof(expected_anti_moniker_saved_data
),
1320 expected_anti_moniker_comparison_data
, sizeof(expected_anti_moniker_comparison_data
),
1321 expected_display_name
);
1324 hr
= IMoniker_Hash(moniker
, &hash
);
1325 ok_ole_success(hr
, IMoniker_Hash
);
1326 ok(hash
== 0x80000001,
1327 "Hash value != 0x80000001, instead was 0x%08x\n",
1330 /* IsSystemMoniker test */
1331 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1332 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1333 ok(moniker_type
== MKSYS_ANTIMONIKER
,
1334 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1337 hr
= IMoniker_Inverse(moniker
, &inverse
);
1338 ok(hr
== MK_E_NOINVERSE
, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr
);
1339 ok(inverse
== NULL
, "inverse should have been set to NULL instead of %p\n", inverse
);
1341 hr
= CreateBindCtx(0, &bindctx
);
1342 ok_ole_success(hr
, CreateBindCtx
);
1344 /* IsRunning test */
1345 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1346 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1348 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1349 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1351 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1352 ok(hr
== E_NOTIMPL
, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr
);
1354 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1355 ok(hr
== E_NOTIMPL
, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr
);
1357 IBindCtx_Release(bindctx
);
1359 IMoniker_Release(moniker
);
1362 static void test_generic_composite_moniker(void)
1374 static const WCHAR wszDelimeter1
[] = {'!',0};
1375 static const WCHAR wszObjectName1
[] = {'T','e','s','t',0};
1376 static const WCHAR wszDelimeter2
[] = {'#',0};
1377 static const WCHAR wszObjectName2
[] = {'W','i','n','e',0};
1378 static const WCHAR expected_display_name
[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1380 hr
= CreateItemMoniker(wszDelimeter1
, wszObjectName1
, &moniker1
);
1381 ok_ole_success(hr
, CreateItemMoniker
);
1382 hr
= CreateItemMoniker(wszDelimeter2
, wszObjectName2
, &moniker2
);
1383 ok_ole_success(hr
, CreateItemMoniker
);
1384 hr
= CreateGenericComposite(moniker1
, moniker2
, &moniker
);
1385 ok_ole_success(hr
, CreateGenericComposite
);
1387 test_moniker("generic composite moniker", moniker
,
1388 expected_gc_moniker_marshal_data
, sizeof(expected_gc_moniker_marshal_data
),
1389 expected_gc_moniker_saved_data
, sizeof(expected_gc_moniker_saved_data
),
1390 expected_gc_moniker_comparison_data
, sizeof(expected_gc_moniker_comparison_data
),
1391 expected_display_name
);
1395 hr
= IMoniker_Hash(moniker
, &hash
);
1396 ok_ole_success(hr
, IMoniker_Hash
);
1399 "Hash value != 0xd87, instead was 0x%08x\n",
1402 /* IsSystemMoniker test */
1404 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1405 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1407 ok(moniker_type
== MKSYS_GENERICCOMPOSITE
,
1408 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1411 hr
= CreateBindCtx(0, &bindctx
);
1412 ok_ole_success(hr
, CreateBindCtx
);
1414 /* IsRunning test */
1415 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1417 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1419 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1420 ok(hr
== MK_E_NOTBINDABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr
);
1422 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1424 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1427 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1428 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1430 IBindCtx_Release(bindctx
);
1432 hr
= IMoniker_Inverse(moniker
, &inverse
);
1433 ok_ole_success(hr
, IMoniker_Inverse
);
1434 IMoniker_Release(inverse
);
1436 IMoniker_Release(moniker
);
1439 static void test_bind_context(void)
1443 IEnumString
*pEnumString
;
1444 BIND_OPTS2 bind_opts
;
1445 HeapUnknown
*unknown
;
1446 HeapUnknown
*unknown2
;
1447 IUnknown
*param_obj
;
1449 static const WCHAR wszParamName
[] = {'G','e','m','m','a',0};
1450 static const WCHAR wszNonExistant
[] = {'N','o','n','E','x','i','s','t','a','n','t',0};
1452 hr
= CreateBindCtx(0, NULL
);
1453 ok(hr
== E_INVALIDARG
, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1455 hr
= CreateBindCtx(0xdeadbeef, &pBindCtx
);
1456 ok(hr
== E_INVALIDARG
, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1458 hr
= CreateBindCtx(0, &pBindCtx
);
1459 ok_ole_success(hr
, "CreateBindCtx");
1461 bind_opts
.cbStruct
= -1;
1462 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1463 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1464 ok(bind_opts
.cbStruct
== sizeof(bind_opts
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1466 bind_opts
.cbStruct
= sizeof(BIND_OPTS
);
1467 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1468 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1469 ok(bind_opts
.cbStruct
== sizeof(BIND_OPTS
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1471 bind_opts
.cbStruct
= sizeof(bind_opts
);
1472 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1473 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1474 ok(bind_opts
.cbStruct
== sizeof(bind_opts
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1475 ok(bind_opts
.grfFlags
== 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts
.grfFlags
);
1476 ok(bind_opts
.grfMode
== STGM_READWRITE
, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts
.grfMode
);
1477 ok(bind_opts
.dwTickCountDeadline
== 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts
.dwTickCountDeadline
);
1478 ok(bind_opts
.dwTrackFlags
== 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts
.dwTrackFlags
);
1479 ok(bind_opts
.dwClassContext
== (CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
|CLSCTX_REMOTE_SERVER
),
1480 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts
.dwClassContext
);
1481 ok(bind_opts
.locale
== GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts
.locale
);
1482 ok(bind_opts
.pServerInfo
== NULL
, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts
.pServerInfo
);
1484 bind_opts
.cbStruct
= -1;
1485 hr
= IBindCtx_SetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1486 ok(hr
== E_INVALIDARG
, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1488 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, NULL
);
1489 ok(hr
== E_INVALIDARG
, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1491 unknown
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1492 unknown
->lpVtbl
= &HeapUnknown_Vtbl
;
1494 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, (IUnknown
*)&unknown
->lpVtbl
);
1495 ok_ole_success(hr
, "IBindCtx_RegisterObjectParam");
1497 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, ¶m_obj
);
1498 ok_ole_success(hr
, "IBindCtx_GetObjectParam");
1499 IUnknown_Release(param_obj
);
1501 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszNonExistant
, ¶m_obj
);
1502 ok(hr
== E_FAIL
, "IBindCtx_GetObjectParam with non-existing key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1503 ok(param_obj
== NULL
, "IBindCtx_GetObjectParam with non-existing key should have set output parameter to NULL instead of %p\n", param_obj
);
1505 hr
= IBindCtx_RevokeObjectParam(pBindCtx
, (WCHAR
*)wszNonExistant
);
1506 ok(hr
== E_FAIL
, "IBindCtx_RevokeObjectParam with non-existing key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1508 hr
= IBindCtx_EnumObjectParam(pBindCtx
, &pEnumString
);
1509 ok(hr
== E_NOTIMPL
, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1510 ok(!pEnumString
, "pEnumString should be NULL\n");
1512 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, NULL
);
1513 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound(NULL)");
1515 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, NULL
);
1516 ok(hr
== E_INVALIDARG
, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr
);
1518 unknown2
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1519 unknown2
->lpVtbl
= &HeapUnknown_Vtbl
;
1521 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1522 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound");
1524 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1525 ok_ole_success(hr
, "IBindCtx_RevokeObjectBound");
1527 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1528 ok(hr
== MK_E_NOTBOUND
, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr
);
1530 IBindCtx_Release(pBindCtx
);
1532 refs
= IUnknown_Release((IUnknown
*)&unknown
->lpVtbl
);
1533 ok(!refs
, "object param should have been destroyed, instead of having %d refs\n", refs
);
1535 refs
= IUnknown_Release((IUnknown
*)&unknown2
->lpVtbl
);
1536 ok(!refs
, "bound object should have been destroyed, instead of having %d refs\n", refs
);
1541 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1544 test_MkParseDisplayName();
1545 test_class_moniker();
1546 test_file_monikers();
1547 test_item_moniker();
1548 test_anti_moniker();
1549 test_generic_composite_moniker();
1551 /* FIXME: test moniker creation funcs and parsing other moniker formats */
1553 test_bind_context();