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
26 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
27 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
28 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
29 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
31 #define CHECK_EXPECTED_METHOD(method_name) \
33 trace("%s\n", method_name); \
34 ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
35 if (*expected_method_list) \
37 ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
38 *expected_method_list, method_name); \
39 expected_method_list++; \
43 static char const * const *expected_method_list
;
44 static const WCHAR wszFileName1
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
45 static const WCHAR wszFileName2
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
47 static const CLSID CLSID_TestMoniker
=
48 { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
52 {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
57 static void LockModule(void)
59 InterlockedIncrement(&cLocks
);
62 static void UnlockModule(void)
64 InterlockedDecrement(&cLocks
);
67 static SIZE_T
round_global_size(SIZE_T size
)
69 static SIZE_T global_size_alignment
= -1;
70 if (global_size_alignment
== -1)
72 void *p
= GlobalAlloc(GMEM_FIXED
, 1);
73 global_size_alignment
= GlobalSize(p
);
77 return ((size
+ global_size_alignment
- 1) & ~(global_size_alignment
- 1));
80 static DWORD external_connections
;
82 static HRESULT WINAPI
ExternalConnection_QueryInterface(IExternalConnection
*iface
, REFIID riid
, void **ppv
)
84 ok(0, "unexpected call\n");
89 static ULONG WINAPI
ExternalConnection_AddRef(IExternalConnection
*iface
)
94 static ULONG WINAPI
ExternalConnection_Release(IExternalConnection
*iface
)
99 static DWORD WINAPI
ExternalConnection_AddConnection(IExternalConnection
*iface
, DWORD extconn
, DWORD reserved
)
101 trace("add connection\n");
103 ok(extconn
== EXTCONN_STRONG
, "extconn = %d\n", extconn
);
104 ok(!reserved
, "reserved = %x\n", reserved
);
105 return ++external_connections
;
108 static DWORD WINAPI
ExternalConnection_ReleaseConnection(IExternalConnection
*iface
, DWORD extconn
,
109 DWORD reserved
, BOOL fLastReleaseCloses
)
111 trace("release connection\n");
113 ok(extconn
== EXTCONN_STRONG
, "extconn = %d\n", extconn
);
114 ok(!reserved
, "reserved = %x\n", reserved
);
116 return --external_connections
;
119 static const IExternalConnectionVtbl ExternalConnectionVtbl
= {
120 ExternalConnection_QueryInterface
,
121 ExternalConnection_AddRef
,
122 ExternalConnection_Release
,
123 ExternalConnection_AddConnection
,
124 ExternalConnection_ReleaseConnection
127 static IExternalConnection ExternalConnection
= { &ExternalConnectionVtbl
};
129 static HRESULT WINAPI
Test_IClassFactory_QueryInterface(
130 LPCLASSFACTORY iface
,
134 if (ppvObj
== NULL
) return E_POINTER
;
136 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
137 IsEqualGUID(riid
, &IID_IClassFactory
))
140 IClassFactory_AddRef(iface
);
144 if(IsEqualGUID(riid
, &IID_IExternalConnection
)) {
145 *ppvObj
= &ExternalConnection
;
150 return E_NOINTERFACE
;
153 static ULONG WINAPI
Test_IClassFactory_AddRef(LPCLASSFACTORY iface
)
156 return 2; /* non-heap-based object */
159 static ULONG WINAPI
Test_IClassFactory_Release(LPCLASSFACTORY iface
)
162 return 1; /* non-heap-based object */
165 static HRESULT WINAPI
Test_IClassFactory_CreateInstance(
166 LPCLASSFACTORY iface
,
174 static HRESULT WINAPI
Test_IClassFactory_LockServer(
175 LPCLASSFACTORY iface
,
181 static const IClassFactoryVtbl TestClassFactory_Vtbl
=
183 Test_IClassFactory_QueryInterface
,
184 Test_IClassFactory_AddRef
,
185 Test_IClassFactory_Release
,
186 Test_IClassFactory_CreateInstance
,
187 Test_IClassFactory_LockServer
190 static IClassFactory Test_ClassFactory
= { &TestClassFactory_Vtbl
};
194 IUnknown IUnknown_iface
;
198 static inline HeapUnknown
*impl_from_IUnknown(IUnknown
*iface
)
200 return CONTAINING_RECORD(iface
, HeapUnknown
, IUnknown_iface
);
203 static HRESULT WINAPI
HeapUnknown_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
205 if (IsEqualIID(riid
, &IID_IUnknown
))
207 IUnknown_AddRef(iface
);
212 return E_NOINTERFACE
;
215 static ULONG WINAPI
HeapUnknown_AddRef(IUnknown
*iface
)
217 HeapUnknown
*This
= impl_from_IUnknown(iface
);
218 return InterlockedIncrement((LONG
*)&This
->refs
);
221 static ULONG WINAPI
HeapUnknown_Release(IUnknown
*iface
)
223 HeapUnknown
*This
= impl_from_IUnknown(iface
);
224 ULONG refs
= InterlockedDecrement((LONG
*)&This
->refs
);
225 if (!refs
) HeapFree(GetProcessHeap(), 0, This
);
229 static const IUnknownVtbl HeapUnknown_Vtbl
=
231 HeapUnknown_QueryInterface
,
236 static HRESULT WINAPI
237 MonikerNoROTData_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
244 if (IsEqualIID(&IID_IUnknown
, riid
) ||
245 IsEqualIID(&IID_IPersist
, riid
) ||
246 IsEqualIID(&IID_IPersistStream
,riid
) ||
247 IsEqualIID(&IID_IMoniker
, riid
))
249 if (IsEqualIID(&IID_IROTData
, riid
))
250 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
253 return E_NOINTERFACE
;
255 IMoniker_AddRef(iface
);
261 Moniker_AddRef(IMoniker
* iface
)
267 Moniker_Release(IMoniker
* iface
)
272 static HRESULT WINAPI
273 Moniker_GetClassID(IMoniker
* iface
, CLSID
*pClassID
)
275 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
277 *pClassID
= CLSID_TestMoniker
;
282 static HRESULT WINAPI
283 Moniker_IsDirty(IMoniker
* iface
)
285 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
290 static HRESULT WINAPI
291 Moniker_Load(IMoniker
* iface
, IStream
* pStm
)
293 CHECK_EXPECTED_METHOD("Moniker_Load");
297 static HRESULT WINAPI
298 Moniker_Save(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
)
300 CHECK_EXPECTED_METHOD("Moniker_Save");
304 static HRESULT WINAPI
305 Moniker_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
307 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
311 static HRESULT WINAPI
312 Moniker_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
313 REFIID riid
, VOID
** ppvResult
)
315 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
319 static HRESULT WINAPI
320 Moniker_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
321 REFIID riid
, VOID
** ppvObject
)
323 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
327 static HRESULT WINAPI
328 Moniker_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
329 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
331 CHECK_EXPECTED_METHOD("Moniker_Reduce");
333 if (ppmkReduced
==NULL
)
336 IMoniker_AddRef(iface
);
340 return MK_S_REDUCED_TO_SELF
;
343 static HRESULT WINAPI
344 Moniker_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
345 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
347 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
351 static HRESULT WINAPI
352 Moniker_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
354 CHECK_EXPECTED_METHOD("Moniker_Enum");
356 if (ppenumMoniker
== NULL
)
359 *ppenumMoniker
= NULL
;
364 static HRESULT WINAPI
365 Moniker_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
367 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
371 static HRESULT WINAPI
372 Moniker_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
374 CHECK_EXPECTED_METHOD("Moniker_Hash");
378 static HRESULT WINAPI
379 Moniker_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
380 IMoniker
* pmkNewlyRunning
)
382 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
386 static HRESULT WINAPI
387 Moniker_GetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
,
388 IMoniker
* pmkToLeft
, FILETIME
* pFileTime
)
390 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
394 static HRESULT WINAPI
395 Moniker_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
397 CHECK_EXPECTED_METHOD("Moniker_Inverse");
401 static HRESULT WINAPI
402 Moniker_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
404 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
408 static HRESULT WINAPI
409 Moniker_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
411 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
415 static HRESULT WINAPI
416 Moniker_GetDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
417 IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
419 static const WCHAR wszDisplayName
[] = {'*','*','G','e','m','m','a',0};
420 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
421 *ppszDisplayName
= CoTaskMemAlloc(sizeof(wszDisplayName
));
422 memcpy(*ppszDisplayName
, wszDisplayName
, sizeof(wszDisplayName
));
426 static HRESULT WINAPI
427 Moniker_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
428 LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
)
430 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
434 static HRESULT WINAPI
435 Moniker_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
437 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
442 (*pwdMksys
)=MKSYS_NONE
;
447 static const IMonikerVtbl MonikerNoROTDataVtbl
=
449 MonikerNoROTData_QueryInterface
,
457 Moniker_BindToObject
,
458 Moniker_BindToStorage
,
465 Moniker_GetTimeOfLastChange
,
467 Moniker_CommonPrefixWith
,
468 Moniker_RelativePathTo
,
469 Moniker_GetDisplayName
,
470 Moniker_ParseDisplayName
,
471 Moniker_IsSystemMoniker
474 static IMoniker MonikerNoROTData
= { &MonikerNoROTDataVtbl
};
476 static IMoniker Moniker
;
478 static HRESULT WINAPI
479 ROTData_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
481 return IMoniker_QueryInterface(&Moniker
, riid
, ppvObject
);
485 ROTData_AddRef(IROTData
*iface
)
491 ROTData_Release(IROTData
* iface
)
496 static HRESULT WINAPI
497 ROTData_GetComparisonData(IROTData
* iface
, BYTE
* pbData
,
498 ULONG cbMax
, ULONG
* pcbData
)
500 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
503 if (cbMax
< *pcbData
)
504 return E_OUTOFMEMORY
;
511 static IROTDataVtbl ROTDataVtbl
=
513 ROTData_QueryInterface
,
516 ROTData_GetComparisonData
519 static IROTData ROTData
= { &ROTDataVtbl
};
521 static HRESULT WINAPI
522 Moniker_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
529 if (IsEqualIID(&IID_IUnknown
, riid
) ||
530 IsEqualIID(&IID_IPersist
, riid
) ||
531 IsEqualIID(&IID_IPersistStream
,riid
) ||
532 IsEqualIID(&IID_IMoniker
, riid
))
534 if (IsEqualIID(&IID_IROTData
, riid
))
536 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
537 *ppvObject
= &ROTData
;
541 return E_NOINTERFACE
;
543 IMoniker_AddRef(iface
);
548 static const IMonikerVtbl MonikerVtbl
=
550 Moniker_QueryInterface
,
558 Moniker_BindToObject
,
559 Moniker_BindToStorage
,
566 Moniker_GetTimeOfLastChange
,
568 Moniker_CommonPrefixWith
,
569 Moniker_RelativePathTo
,
570 Moniker_GetDisplayName
,
571 Moniker_ParseDisplayName
,
572 Moniker_IsSystemMoniker
575 static IMoniker Moniker
= { &MonikerVtbl
};
577 static void test_ROT(void)
579 static const WCHAR wszFileName
[] = {'B','E','2','0','E','2','F','5','-',
580 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
581 '2','0','4','6','E','5','8','6','C','9','2','5',0};
583 IMoniker
*pMoniker
= NULL
;
584 IRunningObjectTable
*pROT
= NULL
;
586 static const char *methods_register_no_ROTData
[] =
589 "Moniker_GetTimeOfLastChange",
590 "Moniker_QueryInterface(IID_IROTData)",
591 "Moniker_GetDisplayName",
592 "Moniker_GetClassID",
595 static const char *methods_register
[] =
598 "Moniker_GetTimeOfLastChange",
599 "Moniker_QueryInterface(IID_IROTData)",
600 "ROTData_GetComparisonData",
603 static const char *methods_isrunning_no_ROTData
[] =
606 "Moniker_QueryInterface(IID_IROTData)",
607 "Moniker_GetDisplayName",
608 "Moniker_GetClassID",
611 static const char *methods_isrunning
[] =
614 "Moniker_QueryInterface(IID_IROTData)",
615 "ROTData_GetComparisonData",
621 hr
= GetRunningObjectTable(0, &pROT
);
622 ok_ole_success(hr
, GetRunningObjectTable
);
624 expected_method_list
= methods_register_no_ROTData
;
625 external_connections
= 0;
626 /* try with our own moniker that doesn't support IROTData */
627 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
628 (IUnknown
*)&Test_ClassFactory
, &MonikerNoROTData
, &dwCookie
);
629 ok_ole_success(hr
, IRunningObjectTable_Register
);
630 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
631 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
633 ok_more_than_one_lock();
635 expected_method_list
= methods_isrunning_no_ROTData
;
636 hr
= IRunningObjectTable_IsRunning(pROT
, &MonikerNoROTData
);
637 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
638 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
640 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
641 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
642 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
646 expected_method_list
= methods_register
;
647 /* try with our own moniker */
648 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
649 (IUnknown
*)&Test_ClassFactory
, &Moniker
, &dwCookie
);
650 ok_ole_success(hr
, IRunningObjectTable_Register
);
651 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
653 ok_more_than_one_lock();
655 expected_method_list
= methods_isrunning
;
656 hr
= IRunningObjectTable_IsRunning(pROT
, &Moniker
);
657 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
658 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
660 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
661 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
665 hr
= CreateFileMoniker(wszFileName
, &pMoniker
);
666 ok_ole_success(hr
, CreateClassMoniker
);
669 external_connections
= 0;
670 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
,
671 pMoniker
, &dwCookie
);
672 ok_ole_success(hr
, IRunningObjectTable_Register
);
673 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
675 ok_more_than_one_lock();
677 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
678 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
682 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
683 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
684 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
685 ok_ole_success(hr
, IRunningObjectTable_Register
);
687 ok_more_than_one_lock();
689 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
690 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
694 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
695 /* only succeeds when process is started by SCM and has LocalService
696 * or RunAs AppId values */
697 hr
= IRunningObjectTable_Register(pROT
,
698 ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
,
699 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
701 ok(hr
== CO_E_WRONG_SERVER_IDENTITY
||
702 broken(hr
== S_OK
) /* Win9x */,
703 "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr
);
705 if (hr
== S_OK
) IRunningObjectTable_Revoke(pROT
, dwCookie
);
707 hr
= IRunningObjectTable_Register(pROT
, 0xdeadbeef,
708 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
709 ok(hr
== E_INVALIDARG
, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
711 IMoniker_Release(pMoniker
);
713 IRunningObjectTable_Release(pROT
);
716 static void test_ROT_multiple_entries(void)
719 IMoniker
*pMoniker
= NULL
;
720 IRunningObjectTable
*pROT
= NULL
;
721 DWORD dwCookie1
, dwCookie2
;
722 IUnknown
*pObject
= NULL
;
723 static const WCHAR moniker_path
[] =
724 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0};
726 hr
= GetRunningObjectTable(0, &pROT
);
727 ok_ole_success(hr
, GetRunningObjectTable
);
729 hr
= CreateFileMoniker(moniker_path
, &pMoniker
);
730 ok_ole_success(hr
, CreateFileMoniker
);
732 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie1
);
733 ok_ole_success(hr
, IRunningObjectTable_Register
);
735 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie2
);
736 ok(hr
== MK_S_MONIKERALREADYREGISTERED
, "IRunningObjectTable_Register should have returned MK_S_MONIKERALREADYREGISTERED instead of 0x%08x\n", hr
);
738 ok(dwCookie1
!= dwCookie2
, "cookie returned for registering duplicate object shouldn't match cookie of original object (0x%x)\n", dwCookie1
);
740 hr
= IRunningObjectTable_GetObject(pROT
, pMoniker
, &pObject
);
741 ok_ole_success(hr
, IRunningObjectTable_GetObject
);
742 IUnknown_Release(pObject
);
744 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie1
);
745 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
747 hr
= IRunningObjectTable_GetObject(pROT
, pMoniker
, &pObject
);
748 ok_ole_success(hr
, IRunningObjectTable_GetObject
);
749 IUnknown_Release(pObject
);
751 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie2
);
752 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
754 IMoniker_Release(pMoniker
);
756 IRunningObjectTable_Release(pROT
);
759 static HRESULT WINAPI
ParseDisplayName_QueryInterface(IParseDisplayName
*iface
, REFIID riid
, void **ppv
)
761 if (IsEqualIID(riid
, &IID_IUnknown
) ||
762 IsEqualIID(riid
, &IID_IParseDisplayName
))
765 IParseDisplayName_AddRef(iface
);
769 return E_NOINTERFACE
;
772 static ULONG WINAPI
ParseDisplayName_AddRef(IParseDisplayName
*iface
)
777 static ULONG WINAPI
ParseDisplayName_Release(IParseDisplayName
*iface
)
782 static LPCWSTR expected_display_name
;
784 static HRESULT WINAPI
ParseDisplayName_ParseDisplayName(IParseDisplayName
*iface
,
786 LPOLESTR pszDisplayName
,
790 char display_nameA
[256];
791 WideCharToMultiByte(CP_ACP
, 0, pszDisplayName
, -1, display_nameA
, sizeof(display_nameA
), NULL
, NULL
);
792 ok(!lstrcmpW(pszDisplayName
, expected_display_name
), "unexpected display name \"%s\"\n", display_nameA
);
793 ok(pszDisplayName
== expected_display_name
, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
794 *pchEaten
= lstrlenW(pszDisplayName
);
795 return CreateAntiMoniker(ppmkOut
);
798 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl
=
800 ParseDisplayName_QueryInterface
,
801 ParseDisplayName_AddRef
,
802 ParseDisplayName_Release
,
803 ParseDisplayName_ParseDisplayName
806 static IParseDisplayName ParseDisplayName
= { &ParseDisplayName_Vtbl
};
808 static int count_moniker_matches(IBindCtx
* pbc
, IEnumMoniker
* spEM
)
810 IMoniker
* spMoniker
;
811 int monCnt
=0, matchCnt
=0;
813 while ((IEnumMoniker_Next(spEM
, 1, &spMoniker
, NULL
)==S_OK
))
818 hr
=IMoniker_GetDisplayName(spMoniker
, pbc
, NULL
, &szDisplayn
);
821 if (!lstrcmpiW(szDisplayn
, wszFileName1
) || !lstrcmpiW(szDisplayn
, wszFileName2
))
823 CoTaskMemFree(szDisplayn
);
826 trace("Total number of monikers is %i\n", monCnt
);
830 static void test_MkParseDisplayName(void)
832 IBindCtx
* pbc
= NULL
;
834 IMoniker
* pmk
= NULL
;
835 IMoniker
* pmk1
= NULL
;
836 IMoniker
* pmk2
= NULL
;
839 IUnknown
* object
= NULL
;
843 IEnumMoniker
*spEM1
= NULL
;
844 IEnumMoniker
*spEM2
= NULL
;
845 IEnumMoniker
*spEM3
= NULL
;
851 IRunningObjectTable
* pprot
=NULL
;
853 /* CLSID of My Computer */
854 static const WCHAR wszDisplayName
[] = {'c','l','s','i','d',':',
855 '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};
856 static const WCHAR wszDisplayNameClsid
[] = {'c','l','s','i','d',':',0};
857 static const WCHAR wszNonExistentProgId
[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
858 static const WCHAR wszDisplayNameRunning
[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
859 static const WCHAR wszDisplayNameProgId1
[] = {'S','t','d','F','o','n','t',':',0};
860 static const WCHAR wszDisplayNameProgId2
[] = {'@','S','t','d','F','o','n','t',0};
861 static const WCHAR wszDisplayNameProgIdFail
[] = {'S','t','d','F','o','n','t',0};
862 static const WCHAR wszEmpty
[] = {0};
863 char szDisplayNameFile
[256];
864 WCHAR wszDisplayNameFile
[256];
870 LPCOLESTR szDisplayName
;
873 } invalid_parameters
[] =
875 {NULL
, NULL
, NULL
, NULL
},
876 {NULL
, NULL
, NULL
, &pmk
},
877 {NULL
, NULL
, &eaten
, NULL
},
878 {NULL
, NULL
, &eaten
, &pmk
},
879 {NULL
, wszEmpty
, NULL
, NULL
},
880 {NULL
, wszEmpty
, NULL
, &pmk
},
881 {NULL
, wszEmpty
, &eaten
, NULL
},
882 {NULL
, wszEmpty
, &eaten
, &pmk
},
883 {&pbc
, NULL
, NULL
, NULL
},
884 {&pbc
, NULL
, NULL
, &pmk
},
885 {&pbc
, NULL
, &eaten
, NULL
},
886 {&pbc
, NULL
, &eaten
, &pmk
},
887 {&pbc
, wszEmpty
, NULL
, NULL
},
888 {&pbc
, wszEmpty
, NULL
, &pmk
},
889 {&pbc
, wszEmpty
, &eaten
, NULL
},
890 {&pbc
, wszEmpty
, &eaten
, &pmk
},
893 hr
= CreateBindCtx(0, &pbc
);
894 ok_ole_success(hr
, CreateBindCtx
);
896 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
899 pmk
= (IMoniker
*)0xdeadbeef;
900 hr
= MkParseDisplayName(invalid_parameters
[i
].ppbc
? *invalid_parameters
[i
].ppbc
: NULL
,
901 invalid_parameters
[i
].szDisplayName
,
902 invalid_parameters
[i
].pchEaten
,
903 invalid_parameters
[i
].ppmk
);
904 ok(hr
== E_INVALIDARG
, "[%d] MkParseDisplayName should have failed with E_INVALIDARG instead of 0x%08x\n", i
, hr
);
905 ok(eaten
== 0xdeadbeef, "[%d] Processed character count should have been 0xdeadbeef instead of %u\n", i
, eaten
);
906 ok(pmk
== (IMoniker
*)0xdeadbeef, "[%d] Output moniker pointer should have been 0xdeadbeef instead of %p\n", i
, pmk
);
910 pmk
= (IMoniker
*)0xdeadbeef;
911 hr
= MkParseDisplayName(pbc
, wszNonExistentProgId
, &eaten
, &pmk
);
912 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
913 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
914 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
915 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
917 /* no special handling of "clsid:" without the string form of the clsid
920 pmk
= (IMoniker
*)0xdeadbeef;
921 hr
= MkParseDisplayName(pbc
, wszDisplayNameClsid
, &eaten
, &pmk
);
922 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
923 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
924 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
925 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
927 /* shows clsid has higher precedence than a running object */
928 hr
= CreateFileMoniker(wszDisplayName
, &pmk
);
929 ok_ole_success(hr
, CreateFileMoniker
);
930 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
931 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
932 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
933 ok_ole_success(hr
, IRunningObjectTable_Register
);
934 IMoniker_Release(pmk
);
936 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
937 ok_ole_success(hr
, MkParseDisplayName
);
938 ok(eaten
== sizeof(wszDisplayName
)/sizeof(WCHAR
) - 1,
939 "Processed character count should have been 43 instead of %u\n", eaten
);
942 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
943 ok(moniker_type
== MKSYS_CLASSMONIKER
, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type
);
944 IMoniker_Release(pmk
);
946 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
947 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
948 IRunningObjectTable_Release(pprot
);
950 hr
= CreateFileMoniker(wszDisplayNameRunning
, &pmk
);
951 ok_ole_success(hr
, CreateFileMoniker
);
952 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
953 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
954 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
955 ok_ole_success(hr
, IRunningObjectTable_Register
);
956 IMoniker_Release(pmk
);
958 hr
= MkParseDisplayName(pbc
, wszDisplayNameRunning
, &eaten
, &pmk
);
959 ok_ole_success(hr
, MkParseDisplayName
);
960 ok(eaten
== sizeof(wszDisplayNameRunning
)/sizeof(WCHAR
) - 1,
961 "Processed character count should have been 15 instead of %u\n", eaten
);
964 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
965 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
966 IMoniker_Release(pmk
);
968 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
969 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
970 IRunningObjectTable_Release(pprot
);
972 hr
= CoRegisterClassObject(&CLSID_StdFont
, (IUnknown
*)&ParseDisplayName
, CLSCTX_INPROC_SERVER
, REGCLS_MULTI_SEPARATE
, &pdwReg1
);
973 ok_ole_success(hr
, CoRegisterClassObject
);
975 expected_display_name
= wszDisplayNameProgId1
;
976 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId1
, &eaten
, &pmk
);
977 ok_ole_success(hr
, MkParseDisplayName
);
978 ok(eaten
== sizeof(wszDisplayNameProgId1
)/sizeof(WCHAR
) - 1,
979 "Processed character count should have been 8 instead of %u\n", eaten
);
982 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
983 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
984 IMoniker_Release(pmk
);
987 expected_display_name
= wszDisplayNameProgId2
;
988 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId2
, &eaten
, &pmk
);
989 ok_ole_success(hr
, MkParseDisplayName
);
990 ok(eaten
== sizeof(wszDisplayNameProgId2
)/sizeof(WCHAR
) - 1,
991 "Processed character count should have been 8 instead of %u\n", eaten
);
994 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
995 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
996 IMoniker_Release(pmk
);
1000 pmk
= (IMoniker
*)0xdeadbeef;
1001 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgIdFail
, &eaten
, &pmk
);
1002 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
1003 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
1004 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
1005 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
1007 hr
= CoRevokeClassObject(pdwReg1
);
1008 ok_ole_success(hr
, CoRevokeClassObject
);
1010 GetSystemDirectoryA(szDisplayNameFile
, sizeof(szDisplayNameFile
));
1011 strcat(szDisplayNameFile
, "\\kernel32.dll");
1012 len
= MultiByteToWideChar(CP_ACP
, 0, szDisplayNameFile
, -1, wszDisplayNameFile
, sizeof(wszDisplayNameFile
)/sizeof(wszDisplayNameFile
[0]));
1013 hr
= MkParseDisplayName(pbc
, wszDisplayNameFile
, &eaten
, &pmk
);
1014 ok_ole_success(hr
, MkParseDisplayName
);
1015 ok(eaten
== len
- 1, "Processed character count should have been %d instead of %u\n", len
- 1, eaten
);
1018 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
1019 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
1020 IMoniker_Release(pmk
);
1023 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
1024 ok_ole_success(hr
, MkParseDisplayName
);
1025 ok(eaten
== sizeof(wszDisplayName
)/sizeof(WCHAR
) - 1, "Processed character count should have been 43 instead of %u\n", eaten
);
1029 hr
= IMoniker_BindToObject(pmk
, pbc
, NULL
, &IID_IUnknown
, (LPVOID
*)&object
);
1030 ok_ole_success(hr
, IMoniker_BindToObject
);
1033 IUnknown_Release(object
);
1034 IMoniker_Release(pmk
);
1036 IBindCtx_Release(pbc
);
1038 /* Test the EnumMoniker interface */
1039 hr
= CreateBindCtx(0, &pbc
);
1040 ok_ole_success(hr
, CreateBindCtx
);
1042 hr
= CreateFileMoniker(wszFileName1
, &pmk1
);
1043 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
1044 hr
= CreateFileMoniker(wszFileName2
, &pmk2
);
1045 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
1046 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
1047 ok(hr
==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr
);
1049 /* Check EnumMoniker before registering */
1050 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM1
);
1051 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
1052 hr
= IEnumMoniker_QueryInterface(spEM1
, &IID_IUnknown
, (void*) &lpEM1
);
1053 /* Register a couple of Monikers and check is ok */
1054 ok(hr
==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr
, lpEM1
);
1056 matchCnt
= count_moniker_matches(pbc
, spEM1
);
1057 trace("Number of matches is %i\n", matchCnt
);
1059 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
1060 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk1
, &pdwReg1
);
1061 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
1062 hr
, pprot
, grflags
, lpEM1
, pmk1
, pdwReg1
);
1064 trace("IROT::Register\n");
1066 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
1067 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk2
, &pdwReg2
);
1068 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr
,
1069 pprot
, grflags
, lpEM1
, pmk2
, pdwReg2
);
1071 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM2
);
1072 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
1074 matchCnt
= count_moniker_matches(pbc
, spEM2
);
1075 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
1077 trace("IEnumMoniker::Clone\n");
1078 IEnumMoniker_Clone(spEM2
, &spEM3
);
1080 matchCnt
= count_moniker_matches(pbc
, spEM3
);
1081 ok(matchCnt
==0, "Number of matches should be equal to 0 not %i\n", matchCnt
);
1082 trace("IEnumMoniker::Reset\n");
1083 IEnumMoniker_Reset(spEM3
);
1085 matchCnt
= count_moniker_matches(pbc
, spEM3
);
1086 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
1088 IRunningObjectTable_Revoke(pprot
,pdwReg1
);
1089 IRunningObjectTable_Revoke(pprot
,pdwReg2
);
1090 IUnknown_Release(lpEM1
);
1091 IEnumMoniker_Release(spEM1
);
1092 IEnumMoniker_Release(spEM2
);
1093 IEnumMoniker_Release(spEM3
);
1094 IMoniker_Release(pmk1
);
1095 IMoniker_Release(pmk2
);
1096 IRunningObjectTable_Release(pprot
);
1098 IBindCtx_Release(pbc
);
1101 static const LARGE_INTEGER llZero
;
1103 static const BYTE expected_class_moniker_marshal_data
[] =
1105 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1106 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1107 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1108 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1109 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1110 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1111 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1112 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1113 0x00,0x00,0x00,0x00,
1116 static const BYTE expected_class_moniker_saved_data
[] =
1118 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1119 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1120 0x00,0x00,0x00,0x00,
1123 static const BYTE expected_class_moniker_comparison_data
[] =
1125 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1126 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1127 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1128 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1131 static const WCHAR expected_class_moniker_display_name
[] =
1133 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
1134 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
1135 '0','0','0','0','4','6',':',0
1138 static const BYTE expected_item_moniker_comparison_data
[] =
1140 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1141 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1142 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1143 0x54,0x00,0x00,0x00,
1146 static const BYTE expected_item_moniker_saved_data
[] =
1148 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1149 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1152 static const BYTE expected_item_moniker_marshal_data
[] =
1154 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1155 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1156 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1157 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1158 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1159 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1160 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1161 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1164 static const BYTE expected_anti_moniker_marshal_data
[] =
1166 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1167 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1168 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1169 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1170 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1171 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1172 0x01,0x00,0x00,0x00,
1175 static const BYTE expected_anti_moniker_saved_data
[] =
1177 0x01,0x00,0x00,0x00,
1180 static const BYTE expected_anti_moniker_comparison_data
[] =
1182 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1183 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1184 0x01,0x00,0x00,0x00,
1187 static const BYTE expected_gc_moniker_marshal_data
[] =
1189 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1190 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1191 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1192 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1193 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1194 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1195 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1196 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1197 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1198 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1199 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1200 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1201 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1202 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1203 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1204 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1205 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1206 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1207 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1208 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1209 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1210 0x00,0x57,0x69,0x6e,0x65,0x00,
1213 static const BYTE expected_gc_moniker_saved_data
[] =
1215 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1216 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1217 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1218 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1219 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1220 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1221 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1222 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1226 static const BYTE expected_gc_moniker_comparison_data
[] =
1228 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1229 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1230 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1231 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1232 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1233 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1234 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1235 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1236 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1239 static void test_moniker(
1240 const char *testname
, IMoniker
*moniker
,
1241 const BYTE
*expected_moniker_marshal_data
, unsigned int sizeof_expected_moniker_marshal_data
,
1242 const BYTE
*expected_moniker_saved_data
, unsigned int sizeof_expected_moniker_saved_data
,
1243 const BYTE
*expected_moniker_comparison_data
, unsigned int sizeof_expected_moniker_comparison_data
,
1244 LPCWSTR expected_display_name
)
1250 LPBYTE moniker_data
;
1255 IMoniker
* moniker_proxy
;
1256 LPOLESTR display_name
;
1259 hr
= IMoniker_IsDirty(moniker
);
1260 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1264 hr
= CreateBindCtx(0, &bindctx
);
1265 ok_ole_success(hr
, CreateBindCtx
);
1267 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1268 ok_ole_success(hr
, IMoniker_GetDisplayName
);
1269 ok(!lstrcmpW(display_name
, expected_display_name
), "%s: display name wasn't what was expected\n", testname
);
1271 CoTaskMemFree(display_name
);
1272 IBindCtx_Release(bindctx
);
1274 hr
= IMoniker_IsDirty(moniker
);
1275 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1277 /* IROTData::GetComparisonData test */
1279 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1280 ok_ole_success(hr
, IMoniker_QueryInterface_IID_IROTData
);
1282 hr
= IROTData_GetComparisonData(rotdata
, buffer
, sizeof(buffer
), &moniker_size
);
1283 ok_ole_success(hr
, IROTData_GetComparisonData
);
1285 if (hr
!= S_OK
) moniker_size
= 0;
1287 /* first check we have the right amount of data */
1288 ok(moniker_size
== sizeof_expected_moniker_comparison_data
,
1289 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1290 testname
, sizeof_expected_moniker_comparison_data
, moniker_size
);
1292 /* then do a byte-by-byte comparison */
1294 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_comparison_data
); i
++)
1296 if (expected_moniker_comparison_data
[i
] != buffer
[i
])
1303 ok(same
, "%s: Comparison data differs\n", testname
);
1306 for (i
= 0; i
< moniker_size
; i
++)
1308 if (i
% 8 == 0) printf(" ");
1309 printf("0x%02x,", buffer
[i
]);
1310 if (i
% 8 == 7) printf("\n");
1315 IROTData_Release(rotdata
);
1317 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1318 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1322 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1323 ok_ole_success(hr
, IMoniker_Save
);
1325 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1326 ok_ole_success(hr
, GetHGlobalFromStream
);
1328 moniker_size
= GlobalSize(hglobal
);
1330 moniker_data
= GlobalLock(hglobal
);
1332 /* first check we have the right amount of data */
1333 ok(moniker_size
== round_global_size(sizeof_expected_moniker_saved_data
),
1334 "%s: Size of saved data differs (expected %d, actual %d)\n",
1335 testname
, (DWORD
)round_global_size(sizeof_expected_moniker_saved_data
), moniker_size
);
1337 /* then do a byte-by-byte comparison */
1339 for (i
= 0; i
< min(moniker_size
, round_global_size(sizeof_expected_moniker_saved_data
)); i
++)
1341 if (expected_moniker_saved_data
[i
] != moniker_data
[i
])
1348 ok(same
, "%s: Saved data differs\n", testname
);
1351 for (i
= 0; i
< moniker_size
; i
++)
1353 if (i
% 8 == 0) printf(" ");
1354 printf("0x%02x,", moniker_data
[i
]);
1355 if (i
% 8 == 7) printf("\n");
1360 GlobalUnlock(hglobal
);
1362 IStream_Release(stream
);
1364 /* Marshaling tests */
1366 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1367 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1369 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1370 ok_ole_success(hr
, CoMarshalInterface
);
1372 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1373 ok_ole_success(hr
, GetHGlobalFromStream
);
1375 moniker_size
= GlobalSize(hglobal
);
1377 moniker_data
= GlobalLock(hglobal
);
1379 /* first check we have the right amount of data */
1380 ok(moniker_size
== round_global_size(sizeof_expected_moniker_marshal_data
),
1381 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1382 testname
, (DWORD
)round_global_size(sizeof_expected_moniker_marshal_data
), moniker_size
);
1384 /* then do a byte-by-byte comparison */
1386 if (expected_moniker_marshal_data
)
1388 for (i
= 0; i
< min(moniker_size
, round_global_size(sizeof_expected_moniker_marshal_data
)); i
++)
1390 if (expected_moniker_marshal_data
[i
] != moniker_data
[i
])
1398 ok(same
, "%s: Marshaled data differs\n", testname
);
1401 for (i
= 0; i
< moniker_size
; i
++)
1403 if (i
% 8 == 0) printf(" ");
1404 printf("0x%02x,", moniker_data
[i
]);
1405 if (i
% 8 == 7) printf("\n");
1410 GlobalUnlock(hglobal
);
1412 IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1413 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&moniker_proxy
);
1414 ok_ole_success(hr
, CoUnmarshalInterface
);
1416 IStream_Release(stream
);
1417 IMoniker_Release(moniker_proxy
);
1420 static void test_class_moniker(void)
1431 hr
= CreateClassMoniker(&CLSID_StdComponentCategoriesMgr
, &moniker
);
1432 ok_ole_success(hr
, CreateClassMoniker
);
1433 if (!moniker
) return;
1435 test_moniker("class moniker", moniker
,
1436 expected_class_moniker_marshal_data
, sizeof(expected_class_moniker_marshal_data
),
1437 expected_class_moniker_saved_data
, sizeof(expected_class_moniker_saved_data
),
1438 expected_class_moniker_comparison_data
, sizeof(expected_class_moniker_comparison_data
),
1439 expected_class_moniker_display_name
);
1443 hr
= IMoniker_Hash(moniker
, &hash
);
1444 ok_ole_success(hr
, IMoniker_Hash
);
1446 ok(hash
== CLSID_StdComponentCategoriesMgr
.Data1
,
1447 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1450 /* IsSystemMoniker test */
1452 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1453 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1455 ok(moniker_type
== MKSYS_CLASSMONIKER
,
1456 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1459 hr
= CreateBindCtx(0, &bindctx
);
1460 ok_ole_success(hr
, CreateBindCtx
);
1462 /* IsRunning test */
1463 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1464 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1466 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1467 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1469 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1470 ok(hr
== MK_E_UNAVAILABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr
);
1472 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1473 ok_ole_success(hr
, IMoniker_BindToObject
);
1474 IUnknown_Release(unknown
);
1476 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1477 ok_ole_success(hr
, IMoniker_BindToStorage
);
1478 IUnknown_Release(unknown
);
1480 IBindCtx_Release(bindctx
);
1482 hr
= IMoniker_Inverse(moniker
, &inverse
);
1483 ok_ole_success(hr
, IMoniker_Inverse
);
1484 IMoniker_Release(inverse
);
1486 IMoniker_Release(moniker
);
1489 static void test_file_moniker(WCHAR
* path
)
1492 IMoniker
*moniker1
= NULL
, *moniker2
= NULL
;
1495 hr
= CreateFileMoniker(path
, &moniker1
);
1496 ok_ole_success(hr
, CreateFileMoniker
);
1498 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1499 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1502 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker1
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1503 ok_ole_success(hr
, CoMarshalInterface
);
1506 hr
= IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1507 ok_ole_success(hr
, IStream_Seek
);
1510 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void**)&moniker2
);
1511 ok_ole_success(hr
, CoUnmarshalInterface
);
1513 hr
= IMoniker_IsEqual(moniker1
, moniker2
);
1514 ok_ole_success(hr
, IsEqual
);
1516 IStream_Release(stream
);
1518 IMoniker_Release(moniker1
);
1520 IMoniker_Release(moniker2
);
1523 static void test_file_monikers(void)
1525 static WCHAR wszFile
[][30] = {
1526 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1527 {'\\', '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},
1528 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1529 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1530 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1531 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1532 * U+0100 .. = Latin extended-A
1534 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1539 trace("ACP is %u\n", GetACP());
1541 for (i
= 0; i
< COUNTOF(wszFile
); ++i
)
1547 WideCharToMultiByte( CP_ACP
, WC_NO_BEST_FIT_CHARS
, wszFile
[i
], -1, NULL
, 0, NULL
, &used
);
1550 skip("string 2 doesn't round trip in codepage %u\n", GetACP() );
1554 for (j
= lstrlenW(wszFile
[i
]); j
> 0; --j
)
1557 test_file_moniker(wszFile
[i
]);
1562 static void test_item_moniker(void)
1571 static const WCHAR wszDelimiter
[] = {'!',0};
1572 static const WCHAR wszObjectName
[] = {'T','e','s','t',0};
1573 static const WCHAR expected_display_name
[] = { '!','T','e','s','t',0 };
1575 hr
= CreateItemMoniker(wszDelimiter
, wszObjectName
, &moniker
);
1576 ok_ole_success(hr
, CreateItemMoniker
);
1578 test_moniker("item moniker", moniker
,
1579 expected_item_moniker_marshal_data
, sizeof(expected_item_moniker_marshal_data
),
1580 expected_item_moniker_saved_data
, sizeof(expected_item_moniker_saved_data
),
1581 expected_item_moniker_comparison_data
, sizeof(expected_item_moniker_comparison_data
),
1582 expected_display_name
);
1586 hr
= IMoniker_Hash(moniker
, &hash
);
1587 ok_ole_success(hr
, IMoniker_Hash
);
1590 "Hash value != 0x73c, instead was 0x%08x\n",
1593 /* IsSystemMoniker test */
1595 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1596 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1598 ok(moniker_type
== MKSYS_ITEMMONIKER
,
1599 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1602 hr
= CreateBindCtx(0, &bindctx
);
1603 ok_ole_success(hr
, CreateBindCtx
);
1605 /* IsRunning test */
1606 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1607 ok(hr
== E_INVALIDARG
, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr
);
1609 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1610 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1612 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1613 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1615 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1616 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1618 IBindCtx_Release(bindctx
);
1620 hr
= IMoniker_Inverse(moniker
, &inverse
);
1621 ok_ole_success(hr
, IMoniker_Inverse
);
1622 IMoniker_Release(inverse
);
1624 IMoniker_Release(moniker
);
1627 static void test_anti_moniker(void)
1637 static const WCHAR expected_display_name
[] = { '\\','.','.',0 };
1639 hr
= CreateAntiMoniker(&moniker
);
1640 ok_ole_success(hr
, CreateAntiMoniker
);
1641 if (!moniker
) return;
1643 test_moniker("anti moniker", moniker
,
1644 expected_anti_moniker_marshal_data
, sizeof(expected_anti_moniker_marshal_data
),
1645 expected_anti_moniker_saved_data
, sizeof(expected_anti_moniker_saved_data
),
1646 expected_anti_moniker_comparison_data
, sizeof(expected_anti_moniker_comparison_data
),
1647 expected_display_name
);
1650 hr
= IMoniker_Hash(moniker
, &hash
);
1651 ok_ole_success(hr
, IMoniker_Hash
);
1652 ok(hash
== 0x80000001,
1653 "Hash value != 0x80000001, instead was 0x%08x\n",
1656 /* IsSystemMoniker test */
1657 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1658 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1659 ok(moniker_type
== MKSYS_ANTIMONIKER
,
1660 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1663 hr
= IMoniker_Inverse(moniker
, &inverse
);
1664 ok(hr
== MK_E_NOINVERSE
, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr
);
1665 ok(inverse
== NULL
, "inverse should have been set to NULL instead of %p\n", inverse
);
1667 hr
= CreateBindCtx(0, &bindctx
);
1668 ok_ole_success(hr
, CreateBindCtx
);
1670 /* IsRunning test */
1671 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1672 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1674 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1675 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1677 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1678 ok(hr
== E_NOTIMPL
, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr
);
1680 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1681 ok(hr
== E_NOTIMPL
, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr
);
1683 IBindCtx_Release(bindctx
);
1685 IMoniker_Release(moniker
);
1688 static void test_generic_composite_moniker(void)
1700 static const WCHAR wszDelimiter1
[] = {'!',0};
1701 static const WCHAR wszObjectName1
[] = {'T','e','s','t',0};
1702 static const WCHAR wszDelimiter2
[] = {'#',0};
1703 static const WCHAR wszObjectName2
[] = {'W','i','n','e',0};
1704 static const WCHAR expected_display_name
[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1706 hr
= CreateItemMoniker(wszDelimiter1
, wszObjectName1
, &moniker1
);
1707 ok_ole_success(hr
, CreateItemMoniker
);
1708 hr
= CreateItemMoniker(wszDelimiter2
, wszObjectName2
, &moniker2
);
1709 ok_ole_success(hr
, CreateItemMoniker
);
1710 hr
= CreateGenericComposite(moniker1
, moniker2
, &moniker
);
1711 ok_ole_success(hr
, CreateGenericComposite
);
1713 test_moniker("generic composite moniker", moniker
,
1714 expected_gc_moniker_marshal_data
, sizeof(expected_gc_moniker_marshal_data
),
1715 expected_gc_moniker_saved_data
, sizeof(expected_gc_moniker_saved_data
),
1716 expected_gc_moniker_comparison_data
, sizeof(expected_gc_moniker_comparison_data
),
1717 expected_display_name
);
1721 hr
= IMoniker_Hash(moniker
, &hash
);
1722 ok_ole_success(hr
, IMoniker_Hash
);
1725 "Hash value != 0xd87, instead was 0x%08x\n",
1728 /* IsSystemMoniker test */
1730 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1731 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1733 ok(moniker_type
== MKSYS_GENERICCOMPOSITE
,
1734 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1737 hr
= CreateBindCtx(0, &bindctx
);
1738 ok_ole_success(hr
, CreateBindCtx
);
1740 /* IsRunning test */
1741 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1742 ok(hr
== E_INVALIDARG
, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr
);
1744 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1746 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1748 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1749 ok(hr
== MK_E_NOTBINDABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr
);
1751 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1753 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1755 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1756 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1758 IBindCtx_Release(bindctx
);
1760 hr
= IMoniker_Inverse(moniker
, &inverse
);
1761 ok_ole_success(hr
, IMoniker_Inverse
);
1762 IMoniker_Release(inverse
);
1764 IMoniker_Release(moniker
);
1767 static void test_pointer_moniker(void)
1779 LPOLESTR display_name
;
1783 hr
= CreatePointerMoniker((IUnknown
*)&Test_ClassFactory
, NULL
);
1784 ok(hr
== E_INVALIDARG
, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1786 hr
= CreatePointerMoniker((IUnknown
*)&Test_ClassFactory
, &moniker
);
1787 ok_ole_success(hr
, CreatePointerMoniker
);
1788 if (!moniker
) return;
1790 ok_more_than_one_lock();
1794 hr
= CreateBindCtx(0, &bindctx
);
1795 ok_ole_success(hr
, CreateBindCtx
);
1797 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1798 ok(hr
== E_NOTIMPL
, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1800 IBindCtx_Release(bindctx
);
1802 hr
= IMoniker_IsDirty(moniker
);
1803 ok(hr
== S_FALSE
, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr
);
1805 /* IROTData::GetComparisonData test */
1807 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1808 ok(hr
== E_NOINTERFACE
, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr
);
1812 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1813 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1815 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1816 ok(hr
== E_NOTIMPL
, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1818 IStream_Release(stream
);
1821 hr
= IMoniker_Hash(moniker
, &hash
);
1822 ok_ole_success(hr
, IMoniker_Hash
);
1823 ok(hash
== PtrToUlong(&Test_ClassFactory
),
1824 "Hash value should have been 0x%08x, instead of 0x%08x\n",
1825 PtrToUlong(&Test_ClassFactory
), hash
);
1827 /* IsSystemMoniker test */
1828 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1829 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1830 ok(moniker_type
== MKSYS_POINTERMONIKER
,
1831 "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1834 hr
= IMoniker_Inverse(moniker
, &inverse
);
1835 ok_ole_success(hr
, IMoniker_Inverse
);
1836 IMoniker_Release(inverse
);
1838 hr
= CreateBindCtx(0, &bindctx
);
1839 ok_ole_success(hr
, CreateBindCtx
);
1841 /* IsRunning test */
1842 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1843 ok(hr
== S_OK
, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr
);
1845 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1846 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1848 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1849 ok_ole_success(hr
, IMoniker_BindToObject
);
1850 IUnknown_Release(unknown
);
1852 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1853 ok_ole_success(hr
, IMoniker_BindToStorage
);
1854 IUnknown_Release(unknown
);
1856 IMoniker_Release(moniker
);
1860 hr
= CreatePointerMoniker(NULL
, &moniker
);
1861 ok_ole_success(hr
, CreatePointerMoniker
);
1863 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1864 ok(hr
== E_UNEXPECTED
, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr
);
1866 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1867 ok(hr
== E_UNEXPECTED
, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr
);
1869 IBindCtx_Release(bindctx
);
1871 IMoniker_Release(moniker
);
1874 static void test_bind_context(void)
1878 IEnumString
*pEnumString
;
1879 BIND_OPTS2 bind_opts
;
1880 HeapUnknown
*unknown
;
1881 HeapUnknown
*unknown2
;
1882 IUnknown
*param_obj
;
1884 static const WCHAR wszParamName
[] = {'G','e','m','m','a',0};
1885 static const WCHAR wszNonExistent
[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1887 hr
= CreateBindCtx(0, NULL
);
1888 ok(hr
== E_INVALIDARG
, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1890 hr
= CreateBindCtx(0xdeadbeef, &pBindCtx
);
1891 ok(hr
== E_INVALIDARG
, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1893 hr
= CreateBindCtx(0, &pBindCtx
);
1894 ok_ole_success(hr
, "CreateBindCtx");
1896 bind_opts
.cbStruct
= -1;
1897 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1898 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1899 ok(bind_opts
.cbStruct
== sizeof(bind_opts
) ||
1900 bind_opts
.cbStruct
== sizeof(bind_opts
) + sizeof(void*), /* Vista */
1901 "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1903 bind_opts
.cbStruct
= sizeof(BIND_OPTS
);
1904 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1905 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1906 ok(bind_opts
.cbStruct
== sizeof(BIND_OPTS
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1908 bind_opts
.cbStruct
= sizeof(bind_opts
);
1909 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1910 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1911 ok(bind_opts
.cbStruct
== sizeof(bind_opts
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1912 ok(bind_opts
.grfFlags
== 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts
.grfFlags
);
1913 ok(bind_opts
.grfMode
== STGM_READWRITE
, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts
.grfMode
);
1914 ok(bind_opts
.dwTickCountDeadline
== 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts
.dwTickCountDeadline
);
1915 ok(bind_opts
.dwTrackFlags
== 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts
.dwTrackFlags
);
1916 ok(bind_opts
.dwClassContext
== (CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
|CLSCTX_REMOTE_SERVER
),
1917 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts
.dwClassContext
);
1918 ok(bind_opts
.locale
== GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts
.locale
);
1919 ok(bind_opts
.pServerInfo
== NULL
, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts
.pServerInfo
);
1921 bind_opts
.cbStruct
= -1;
1922 hr
= IBindCtx_SetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1923 ok(hr
== E_INVALIDARG
, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1925 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, NULL
);
1926 ok(hr
== E_INVALIDARG
, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1928 unknown
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1929 unknown
->IUnknown_iface
.lpVtbl
= &HeapUnknown_Vtbl
;
1931 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, &unknown
->IUnknown_iface
);
1932 ok_ole_success(hr
, "IBindCtx_RegisterObjectParam");
1934 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, ¶m_obj
);
1935 ok_ole_success(hr
, "IBindCtx_GetObjectParam");
1936 IUnknown_Release(param_obj
);
1938 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
, ¶m_obj
);
1939 ok(hr
== E_FAIL
, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1940 ok(param_obj
== NULL
, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj
);
1942 hr
= IBindCtx_RevokeObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
);
1943 ok(hr
== E_FAIL
, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1945 hr
= IBindCtx_EnumObjectParam(pBindCtx
, &pEnumString
);
1946 ok(hr
== E_NOTIMPL
, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1947 ok(!pEnumString
, "pEnumString should be NULL\n");
1949 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, NULL
);
1950 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound(NULL)");
1952 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, NULL
);
1953 ok(hr
== E_INVALIDARG
, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr
);
1955 unknown2
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1956 unknown2
->IUnknown_iface
.lpVtbl
= &HeapUnknown_Vtbl
;
1958 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, &unknown2
->IUnknown_iface
);
1959 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound");
1961 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, &unknown2
->IUnknown_iface
);
1962 ok_ole_success(hr
, "IBindCtx_RevokeObjectBound");
1964 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, &unknown2
->IUnknown_iface
);
1965 ok(hr
== MK_E_NOTBOUND
, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr
);
1967 IBindCtx_Release(pBindCtx
);
1969 refs
= IUnknown_Release(&unknown
->IUnknown_iface
);
1970 ok(!refs
, "object param should have been destroyed, instead of having %d refs\n", refs
);
1972 refs
= IUnknown_Release(&unknown2
->IUnknown_iface
);
1973 ok(!refs
, "bound object should have been destroyed, instead of having %d refs\n", refs
);
1976 static void test_save_load_filemoniker(void)
1981 ULARGE_INTEGER size
;
1982 LARGE_INTEGER zero_pos
, dead_pos
, nulls_pos
;
1983 DWORD some_val
= 0xFEDCBA98;
1986 /* see FileMonikerImpl_Save docs */
1987 zero_pos
.QuadPart
= 0;
1988 dead_pos
.QuadPart
= sizeof(WORD
) + sizeof(DWORD
) + (lstrlenW(wszFileName1
) + 1) + sizeof(WORD
);
1989 nulls_pos
.QuadPart
= dead_pos
.QuadPart
+ sizeof(WORD
);
1991 /* create the stream we're going to write to */
1992 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStm
);
1993 ok_ole_success(hr
, "CreateStreamOnHGlobal");
1995 size
.u
.LowPart
= 128;
1996 hr
= IStream_SetSize(pStm
, size
);
1997 ok_ole_success(hr
, "IStream_SetSize");
1999 /* create and save a moniker */
2000 hr
= CreateFileMoniker(wszFileName1
, &pMk
);
2001 ok_ole_success(hr
, "CreateFileMoniker");
2003 hr
= IMoniker_Save(pMk
, pStm
, TRUE
);
2004 ok_ole_success(hr
, "IMoniker_Save");
2005 IMoniker_Release(pMk
);
2007 /* overwrite the constants with various values */
2008 hr
= IStream_Seek(pStm
, zero_pos
, STREAM_SEEK_SET
, NULL
);
2009 ok_ole_success(hr
, "IStream_Seek");
2010 hr
= IStream_Write(pStm
, &some_val
, sizeof(WORD
), NULL
);
2011 ok_ole_success(hr
, "IStream_Write");
2013 hr
= IStream_Seek(pStm
, dead_pos
, STREAM_SEEK_SET
, NULL
);
2014 ok_ole_success(hr
, "IStream_Seek");
2015 hr
= IStream_Write(pStm
, &some_val
, sizeof(WORD
), NULL
);
2016 ok_ole_success(hr
, "IStream_Write");
2018 hr
= IStream_Seek(pStm
, nulls_pos
, STREAM_SEEK_SET
, NULL
);
2019 ok_ole_success(hr
, "IStream_Seek");
2020 for(i
= 0; i
< 5; ++i
){
2021 hr
= IStream_Write(pStm
, &some_val
, sizeof(DWORD
), NULL
);
2022 ok_ole_success(hr
, "IStream_Write");
2025 /* go back to the start of the stream */
2026 hr
= IStream_Seek(pStm
, zero_pos
, STREAM_SEEK_SET
, NULL
);
2027 ok_ole_success(hr
, "IStream_Seek");
2029 /* create a new moniker and load into it */
2030 hr
= CreateFileMoniker(wszFileName1
, &pMk
);
2031 ok_ole_success(hr
, "CreateFileMoniker");
2033 hr
= IMoniker_Load(pMk
, pStm
);
2034 ok_ole_success(hr
, "IMoniker_Load");
2036 IMoniker_Release(pMk
);
2037 IStream_Release(pStm
);
2042 if (!GetProcAddress(GetModuleHandleA("ole32.dll"), "CoRegisterSurrogateEx")) {
2043 win_skip("skipping test on win9x\n");
2047 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2050 test_ROT_multiple_entries();
2051 test_MkParseDisplayName();
2052 test_class_moniker();
2053 test_file_monikers();
2054 test_item_moniker();
2055 test_anti_moniker();
2056 test_generic_composite_moniker();
2057 test_pointer_moniker();
2058 test_save_load_filemoniker();
2060 /* FIXME: test moniker creation funcs and parsing other moniker formats */
2062 test_bind_context();