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
34 #include "wine/test.h"
36 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
37 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
38 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
39 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
41 #define CHECK_EXPECTED_METHOD(method_name) \
43 trace("%s\n", method_name); \
44 ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
45 if (*expected_method_list) \
47 ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
48 *expected_method_list, method_name); \
49 expected_method_list++; \
53 static char const * const *expected_method_list
;
54 static const WCHAR wszFileName1
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
55 static const WCHAR wszFileName2
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
57 static const CLSID CLSID_WineTest
=
58 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
62 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
65 static const CLSID CLSID_TestMoniker
=
66 { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
70 {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
75 static void LockModule(void)
77 InterlockedIncrement(&cLocks
);
80 static void UnlockModule(void)
82 InterlockedDecrement(&cLocks
);
85 static SIZE_T
round_heap_size(SIZE_T size
)
87 static SIZE_T heap_size_alignment
= -1;
88 if (heap_size_alignment
== -1)
90 void *p
= HeapAlloc(GetProcessHeap(), 0, 1);
91 heap_size_alignment
= HeapSize(GetProcessHeap(), 0, p
);
92 HeapFree(GetProcessHeap(), 0, p
);
95 return ((size
+ heap_size_alignment
- 1) & ~(heap_size_alignment
- 1));
98 static HRESULT WINAPI
Test_IClassFactory_QueryInterface(
103 if (ppvObj
== NULL
) return E_POINTER
;
105 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
106 IsEqualGUID(riid
, &IID_IClassFactory
))
109 IClassFactory_AddRef(iface
);
114 return E_NOINTERFACE
;
117 static ULONG WINAPI
Test_IClassFactory_AddRef(LPCLASSFACTORY iface
)
120 return 2; /* non-heap-based object */
123 static ULONG WINAPI
Test_IClassFactory_Release(LPCLASSFACTORY iface
)
126 return 1; /* non-heap-based object */
129 static HRESULT WINAPI
Test_IClassFactory_CreateInstance(
130 LPCLASSFACTORY iface
,
138 static HRESULT WINAPI
Test_IClassFactory_LockServer(
139 LPCLASSFACTORY iface
,
145 static const IClassFactoryVtbl TestClassFactory_Vtbl
=
147 Test_IClassFactory_QueryInterface
,
148 Test_IClassFactory_AddRef
,
149 Test_IClassFactory_Release
,
150 Test_IClassFactory_CreateInstance
,
151 Test_IClassFactory_LockServer
154 static IClassFactory Test_ClassFactory
= { &TestClassFactory_Vtbl
};
158 const IUnknownVtbl
*lpVtbl
;
162 static HRESULT WINAPI
HeapUnknown_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
164 if (IsEqualIID(riid
, &IID_IUnknown
))
166 IUnknown_AddRef(iface
);
171 return E_NOINTERFACE
;
174 static ULONG WINAPI
HeapUnknown_AddRef(IUnknown
*iface
)
176 HeapUnknown
*This
= (HeapUnknown
*)iface
;
177 return InterlockedIncrement((LONG
*)&This
->refs
);
180 static ULONG WINAPI
HeapUnknown_Release(IUnknown
*iface
)
182 HeapUnknown
*This
= (HeapUnknown
*)iface
;
183 ULONG refs
= InterlockedDecrement((LONG
*)&This
->refs
);
184 if (!refs
) HeapFree(GetProcessHeap(), 0, This
);
188 static const IUnknownVtbl HeapUnknown_Vtbl
=
190 HeapUnknown_QueryInterface
,
195 static HRESULT WINAPI
196 MonikerNoROTData_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
203 if (IsEqualIID(&IID_IUnknown
, riid
) ||
204 IsEqualIID(&IID_IPersist
, riid
) ||
205 IsEqualIID(&IID_IPersistStream
,riid
) ||
206 IsEqualIID(&IID_IMoniker
, riid
))
208 if (IsEqualIID(&IID_IROTData
, riid
))
209 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
212 return E_NOINTERFACE
;
214 IMoniker_AddRef(iface
);
220 Moniker_AddRef(IMoniker
* iface
)
226 Moniker_Release(IMoniker
* iface
)
231 static HRESULT WINAPI
232 Moniker_GetClassID(IMoniker
* iface
, CLSID
*pClassID
)
234 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
236 *pClassID
= CLSID_TestMoniker
;
241 static HRESULT WINAPI
242 Moniker_IsDirty(IMoniker
* iface
)
244 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
249 static HRESULT WINAPI
250 Moniker_Load(IMoniker
* iface
, IStream
* pStm
)
252 CHECK_EXPECTED_METHOD("Moniker_Load");
256 static HRESULT WINAPI
257 Moniker_Save(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
)
259 CHECK_EXPECTED_METHOD("Moniker_Save");
263 static HRESULT WINAPI
264 Moniker_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
266 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
270 static HRESULT WINAPI
271 Moniker_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
272 REFIID riid
, VOID
** ppvResult
)
274 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
278 static HRESULT WINAPI
279 Moniker_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
280 REFIID riid
, VOID
** ppvObject
)
282 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
286 static HRESULT WINAPI
287 Moniker_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
288 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
290 CHECK_EXPECTED_METHOD("Moniker_Reduce");
292 if (ppmkReduced
==NULL
)
295 IMoniker_AddRef(iface
);
299 return MK_S_REDUCED_TO_SELF
;
302 static HRESULT WINAPI
303 Moniker_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
304 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
306 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
310 static HRESULT WINAPI
311 Moniker_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
313 CHECK_EXPECTED_METHOD("Moniker_Enum");
315 if (ppenumMoniker
== NULL
)
318 *ppenumMoniker
= NULL
;
323 static HRESULT WINAPI
324 Moniker_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
326 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
330 static HRESULT WINAPI
331 Moniker_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
333 CHECK_EXPECTED_METHOD("Moniker_Hash");
337 static HRESULT WINAPI
338 Moniker_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
339 IMoniker
* pmkNewlyRunning
)
341 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
345 static HRESULT WINAPI
346 Moniker_GetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
,
347 IMoniker
* pmkToLeft
, FILETIME
* pFileTime
)
349 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
353 static HRESULT WINAPI
354 Moniker_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
356 CHECK_EXPECTED_METHOD("Moniker_Inverse");
360 static HRESULT WINAPI
361 Moniker_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
363 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
367 static HRESULT WINAPI
368 Moniker_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
370 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
374 static HRESULT WINAPI
375 Moniker_GetDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
376 IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
378 static const WCHAR wszDisplayName
[] = {'*','*','G','e','m','m','a',0};
379 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
380 *ppszDisplayName
= CoTaskMemAlloc(sizeof(wszDisplayName
));
381 memcpy(*ppszDisplayName
, wszDisplayName
, sizeof(wszDisplayName
));
385 static HRESULT WINAPI
386 Moniker_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
387 LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
)
389 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
393 static HRESULT WINAPI
394 Moniker_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
396 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
401 (*pwdMksys
)=MKSYS_NONE
;
406 static const IMonikerVtbl MonikerNoROTDataVtbl
=
408 MonikerNoROTData_QueryInterface
,
416 Moniker_BindToObject
,
417 Moniker_BindToStorage
,
424 Moniker_GetTimeOfLastChange
,
426 Moniker_CommonPrefixWith
,
427 Moniker_RelativePathTo
,
428 Moniker_GetDisplayName
,
429 Moniker_ParseDisplayName
,
430 Moniker_IsSystemMoniker
433 static IMoniker MonikerNoROTData
= { &MonikerNoROTDataVtbl
};
435 static IMoniker Moniker
;
437 static HRESULT WINAPI
438 ROTData_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
440 return IMoniker_QueryInterface(&Moniker
, riid
, ppvObject
);
444 ROTData_AddRef(IROTData
*iface
)
450 ROTData_Release(IROTData
* iface
)
455 static HRESULT WINAPI
456 ROTData_GetComparisonData(IROTData
* iface
, BYTE
* pbData
,
457 ULONG cbMax
, ULONG
* pcbData
)
459 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
462 if (cbMax
< *pcbData
)
463 return E_OUTOFMEMORY
;
470 static IROTDataVtbl ROTDataVtbl
=
472 ROTData_QueryInterface
,
475 ROTData_GetComparisonData
478 static IROTData ROTData
= { &ROTDataVtbl
};
480 static HRESULT WINAPI
481 Moniker_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
488 if (IsEqualIID(&IID_IUnknown
, riid
) ||
489 IsEqualIID(&IID_IPersist
, riid
) ||
490 IsEqualIID(&IID_IPersistStream
,riid
) ||
491 IsEqualIID(&IID_IMoniker
, riid
))
493 if (IsEqualIID(&IID_IROTData
, riid
))
495 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
496 *ppvObject
= &ROTData
;
500 return E_NOINTERFACE
;
502 IMoniker_AddRef(iface
);
507 static const IMonikerVtbl MonikerVtbl
=
509 Moniker_QueryInterface
,
517 Moniker_BindToObject
,
518 Moniker_BindToStorage
,
525 Moniker_GetTimeOfLastChange
,
527 Moniker_CommonPrefixWith
,
528 Moniker_RelativePathTo
,
529 Moniker_GetDisplayName
,
530 Moniker_ParseDisplayName
,
531 Moniker_IsSystemMoniker
534 static IMoniker Moniker
= { &MonikerVtbl
};
536 static void test_ROT(void)
538 static const WCHAR wszFileName
[] = {'B','E','2','0','E','2','F','5','-',
539 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
540 '2','0','4','6','E','5','8','6','C','9','2','5',0};
542 IMoniker
*pMoniker
= NULL
;
543 IRunningObjectTable
*pROT
= NULL
;
545 static const char *methods_register_no_ROTData
[] =
548 "Moniker_GetTimeOfLastChange",
549 "Moniker_QueryInterface(IID_IROTData)",
550 "Moniker_GetDisplayName",
551 "Moniker_GetClassID",
554 static const char *methods_register
[] =
557 "Moniker_GetTimeOfLastChange",
558 "Moniker_QueryInterface(IID_IROTData)",
559 "ROTData_GetComparisonData",
562 static const char *methods_isrunning_no_ROTData
[] =
565 "Moniker_QueryInterface(IID_IROTData)",
566 "Moniker_GetDisplayName",
567 "Moniker_GetClassID",
570 static const char *methods_isrunning
[] =
573 "Moniker_QueryInterface(IID_IROTData)",
574 "ROTData_GetComparisonData",
580 hr
= GetRunningObjectTable(0, &pROT
);
581 ok_ole_success(hr
, GetRunningObjectTable
);
583 expected_method_list
= methods_register_no_ROTData
;
584 /* try with our own moniker that doesn't support IROTData */
585 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
586 (IUnknown
*)&Test_ClassFactory
, &MonikerNoROTData
, &dwCookie
);
587 ok_ole_success(hr
, IRunningObjectTable_Register
);
588 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
590 ok_more_than_one_lock();
592 expected_method_list
= methods_isrunning_no_ROTData
;
593 hr
= IRunningObjectTable_IsRunning(pROT
, &MonikerNoROTData
);
594 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
595 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
597 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
598 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
602 expected_method_list
= methods_register
;
603 /* try with our own moniker */
604 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
605 (IUnknown
*)&Test_ClassFactory
, &Moniker
, &dwCookie
);
606 ok_ole_success(hr
, IRunningObjectTable_Register
);
607 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
609 ok_more_than_one_lock();
611 expected_method_list
= methods_isrunning
;
612 hr
= IRunningObjectTable_IsRunning(pROT
, &Moniker
);
613 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 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
621 hr
= CreateFileMoniker(wszFileName
, &pMoniker
);
622 ok_ole_success(hr
, CreateClassMoniker
);
625 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
,
626 pMoniker
, &dwCookie
);
627 ok_ole_success(hr
, IRunningObjectTable_Register
);
629 ok_more_than_one_lock();
631 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
632 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
636 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
637 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
638 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
639 ok_ole_success(hr
, IRunningObjectTable_Register
);
641 ok_more_than_one_lock();
643 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
644 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
648 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
649 /* only succeeds when process is started by SCM and has LocalService
650 * or RunAs AppId values */
651 hr
= IRunningObjectTable_Register(pROT
,
652 ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
,
653 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
655 ok(hr
== CO_E_WRONG_SERVER_IDENTITY
, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr
);
657 if (hr
== S_OK
) IRunningObjectTable_Revoke(pROT
, dwCookie
);
659 hr
= IRunningObjectTable_Register(pROT
, 0xdeadbeef,
660 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
661 ok(hr
== E_INVALIDARG
, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
663 IMoniker_Release(pMoniker
);
665 IRunningObjectTable_Release(pROT
);
668 static void test_ROT_multiple_entries(void)
671 IMoniker
*pMoniker
= NULL
;
672 IRunningObjectTable
*pROT
= NULL
;
673 DWORD dwCookie1
, dwCookie2
;
674 IUnknown
*pObject
= NULL
;
675 static const WCHAR moniker_path
[] =
676 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0};
678 hr
= GetRunningObjectTable(0, &pROT
);
679 ok_ole_success(hr
, GetRunningObjectTable
);
681 hr
= CreateFileMoniker(moniker_path
, &pMoniker
);
682 ok_ole_success(hr
, CreateFileMoniker
);
684 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie1
);
685 ok_ole_success(hr
, IRunningObjectTable_Register
);
687 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie2
);
688 ok(hr
== MK_S_MONIKERALREADYREGISTERED
, "IRunningObjectTable_Register should have returned MK_S_MONIKERALREADYREGISTERED instead of 0x%08x\n", hr
);
690 ok(dwCookie1
!= dwCookie2
, "cookie returned for registering duplicate object shouldn't match cookie of original object (0x%x)\n", dwCookie1
);
692 hr
= IRunningObjectTable_GetObject(pROT
, pMoniker
, &pObject
);
693 ok_ole_success(hr
, IRunningObjectTable_GetObject
);
694 IUnknown_Release(pObject
);
696 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie1
);
697 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
699 hr
= IRunningObjectTable_GetObject(pROT
, pMoniker
, &pObject
);
700 ok_ole_success(hr
, IRunningObjectTable_GetObject
);
701 IUnknown_Release(pObject
);
703 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie2
);
704 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
706 IMoniker_Release(pMoniker
);
708 IRunningObjectTable_Release(pROT
);
711 static HRESULT WINAPI
ParseDisplayName_QueryInterface(IParseDisplayName
*iface
, REFIID riid
, void **ppv
)
713 if (IsEqualIID(riid
, &IID_IUnknown
) ||
714 IsEqualIID(riid
, &IID_IParseDisplayName
))
717 IUnknown_AddRef(iface
);
721 return E_NOINTERFACE
;
724 static ULONG WINAPI
ParseDisplayName_AddRef(IParseDisplayName
*iface
)
729 static ULONG WINAPI
ParseDisplayName_Release(IParseDisplayName
*iface
)
734 static LPCWSTR expected_display_name
;
736 static HRESULT WINAPI
ParseDisplayName_ParseDisplayName(IParseDisplayName
*iface
,
738 LPOLESTR pszDisplayName
,
742 char display_nameA
[256];
743 WideCharToMultiByte(CP_ACP
, 0, pszDisplayName
, -1, display_nameA
, sizeof(display_nameA
), NULL
, NULL
);
744 ok(!lstrcmpW(pszDisplayName
, expected_display_name
), "unexpected display name \"%s\"\n", display_nameA
);
745 ok(pszDisplayName
== expected_display_name
, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
746 *pchEaten
= lstrlenW(pszDisplayName
);
747 return CreateAntiMoniker(ppmkOut
);
750 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl
=
752 ParseDisplayName_QueryInterface
,
753 ParseDisplayName_AddRef
,
754 ParseDisplayName_Release
,
755 ParseDisplayName_ParseDisplayName
758 static IParseDisplayName ParseDisplayName
= { &ParseDisplayName_Vtbl
};
760 static int count_moniker_matches(IBindCtx
* pbc
, IEnumMoniker
* spEM
)
762 IMoniker
* spMoniker
;
763 int monCnt
=0, matchCnt
=0;
765 while ((IEnumMoniker_Next(spEM
, 1, &spMoniker
, NULL
)==S_OK
))
770 hr
=IMoniker_GetDisplayName(spMoniker
, pbc
, NULL
, &szDisplayn
);
773 if (!lstrcmpiW(szDisplayn
, wszFileName1
) || !lstrcmpiW(szDisplayn
, wszFileName2
))
775 CoTaskMemFree(szDisplayn
);
778 trace("Total number of monikers is %i\n", monCnt
);
782 static void test_MkParseDisplayName(void)
784 IBindCtx
* pbc
= NULL
;
786 IMoniker
* pmk
= NULL
;
787 IMoniker
* pmk1
= NULL
;
788 IMoniker
* pmk2
= NULL
;
791 IUnknown
* object
= NULL
;
795 IEnumMoniker
*spEM1
= NULL
;
796 IEnumMoniker
*spEM2
= NULL
;
797 IEnumMoniker
*spEM3
= NULL
;
803 IRunningObjectTable
* pprot
=NULL
;
805 /* CLSID of My Computer */
806 static const WCHAR wszDisplayName
[] = {'c','l','s','i','d',':',
807 '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};
808 static const WCHAR wszDisplayNameClsid
[] = {'c','l','s','i','d',':',0};
809 static const WCHAR wszNonExistentProgId
[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
810 static const WCHAR wszDisplayNameRunning
[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
811 static const WCHAR wszDisplayNameProgId1
[] = {'S','t','d','F','o','n','t',':',0};
812 static const WCHAR wszDisplayNameProgId2
[] = {'@','S','t','d','F','o','n','t',0};
813 static const WCHAR wszDisplayNameProgIdFail
[] = {'S','t','d','F','o','n','t',0};
814 char szDisplayNameFile
[256];
815 WCHAR wszDisplayNameFile
[256];
817 hr
= CreateBindCtx(0, &pbc
);
818 ok_ole_success(hr
, CreateBindCtx
);
820 hr
= MkParseDisplayName(pbc
, wszNonExistentProgId
, &eaten
, &pmk
);
821 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
822 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
824 /* no special handling of "clsid:" without the string form of the clsid
826 hr
= MkParseDisplayName(pbc
, wszDisplayNameClsid
, &eaten
, &pmk
);
827 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
828 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
830 /* shows clsid has higher precedence than a running object */
831 hr
= CreateFileMoniker(wszDisplayName
, &pmk
);
832 ok_ole_success(hr
, CreateFileMoniker
);
833 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
834 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
835 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
836 ok_ole_success(hr
, IRunningObjectTable_Register
);
837 IMoniker_Release(pmk
);
839 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
840 ok_ole_success(hr
, MkParseDisplayName
);
843 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
844 ok(moniker_type
== MKSYS_CLASSMONIKER
, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type
);
845 IMoniker_Release(pmk
);
847 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
848 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
849 IRunningObjectTable_Release(pprot
);
851 hr
= CreateFileMoniker(wszDisplayNameRunning
, &pmk
);
852 ok_ole_success(hr
, CreateFileMoniker
);
853 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
854 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
855 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
856 ok_ole_success(hr
, IRunningObjectTable_Register
);
857 IMoniker_Release(pmk
);
859 hr
= MkParseDisplayName(pbc
, wszDisplayNameRunning
, &eaten
, &pmk
);
860 ok_ole_success(hr
, MkParseDisplayName
);
863 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
864 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
865 IMoniker_Release(pmk
);
867 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
868 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
869 IRunningObjectTable_Release(pprot
);
871 hr
= CoRegisterClassObject(&CLSID_StdFont
, (IUnknown
*)&ParseDisplayName
, CLSCTX_INPROC_SERVER
, REGCLS_MULTI_SEPARATE
, &pdwReg1
);
872 ok_ole_success(hr
, CoRegisterClassObject
);
874 expected_display_name
= wszDisplayNameProgId1
;
875 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId1
, &eaten
, &pmk
);
876 ok_ole_success(hr
, MkParseDisplayName
);
879 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
880 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
881 IMoniker_Release(pmk
);
884 expected_display_name
= wszDisplayNameProgId2
;
885 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId2
, &eaten
, &pmk
);
886 ok_ole_success(hr
, MkParseDisplayName
);
889 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
890 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
891 IMoniker_Release(pmk
);
894 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgIdFail
, &eaten
, &pmk
);
895 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
896 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
898 hr
= CoRevokeClassObject(pdwReg1
);
899 ok_ole_success(hr
, CoRevokeClassObject
);
901 GetSystemDirectoryA(szDisplayNameFile
, sizeof(szDisplayNameFile
));
902 strcat(szDisplayNameFile
, "\\kernel32.dll");
903 MultiByteToWideChar(CP_ACP
, 0, szDisplayNameFile
, -1, wszDisplayNameFile
, sizeof(wszDisplayNameFile
)/sizeof(wszDisplayNameFile
[0]));
904 hr
= MkParseDisplayName(pbc
, wszDisplayNameFile
, &eaten
, &pmk
);
905 ok_ole_success(hr
, MkParseDisplayName
);
908 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
909 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
910 IMoniker_Release(pmk
);
913 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
914 ok_ole_success(hr
, MkParseDisplayName
);
918 hr
= IMoniker_BindToObject(pmk
, pbc
, NULL
, &IID_IUnknown
, (LPVOID
*)&object
);
919 ok_ole_success(hr
, IMoniker_BindToObject
);
921 IUnknown_Release(object
);
922 IMoniker_Release(pmk
);
924 IBindCtx_Release(pbc
);
926 /* Test the EnumMoniker interface */
927 hr
= CreateBindCtx(0, &pbc
);
928 ok_ole_success(hr
, CreateBindCtx
);
930 hr
= CreateFileMoniker(wszFileName1
, &pmk1
);
931 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
932 hr
= CreateFileMoniker(wszFileName2
, &pmk2
);
933 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
934 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
935 ok(hr
==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr
);
937 /* Check EnumMoniker before registering */
938 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM1
);
939 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
940 hr
= IEnumMoniker_QueryInterface(spEM1
, &IID_IUnknown
, (void*) &lpEM1
);
941 /* Register a couple of Monikers and check is ok */
942 ok(hr
==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr
, lpEM1
);
945 matchCnt
= count_moniker_matches(pbc
, spEM1
);
946 trace("Number of matches is %i\n", matchCnt
);
948 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
949 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk1
, &pdwReg1
);
950 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
951 hr
, pprot
, grflags
, lpEM1
, pmk1
, pdwReg1
);
953 trace("IROT::Register\n");
955 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
956 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk2
, &pdwReg2
);
957 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr
,
958 pprot
, grflags
, lpEM1
, pmk2
, pdwReg2
);
960 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM2
);
961 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
963 matchCnt
= count_moniker_matches(pbc
, spEM2
);
964 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
966 trace("IEnumMoniker::Clone\n");
967 IEnumMoniker_Clone(spEM2
, &spEM3
);
969 matchCnt
= count_moniker_matches(pbc
, spEM3
);
970 ok(matchCnt
==0, "Number of matches should be equal to 0 not %i\n", matchCnt
);
971 trace("IEnumMoniker::Reset\n");
972 IEnumMoniker_Reset(spEM3
);
974 matchCnt
= count_moniker_matches(pbc
, spEM3
);
975 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
977 IRunningObjectTable_Revoke(pprot
,pdwReg1
);
978 IRunningObjectTable_Revoke(pprot
,pdwReg2
);
979 IUnknown_Release(lpEM1
);
980 IEnumMoniker_Release(spEM1
);
981 IEnumMoniker_Release(spEM2
);
982 IEnumMoniker_Release(spEM3
);
983 IMoniker_Release(pmk1
);
984 IMoniker_Release(pmk2
);
985 IRunningObjectTable_Release(pprot
);
987 IBindCtx_Release(pbc
);
990 static const LARGE_INTEGER llZero
;
992 static const BYTE expected_class_moniker_marshal_data
[] =
994 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
995 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
996 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
997 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
998 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
999 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1000 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1001 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1002 0x00,0x00,0x00,0x00,
1005 static const BYTE expected_class_moniker_saved_data
[] =
1007 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1008 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1009 0x00,0x00,0x00,0x00,
1012 static const BYTE expected_class_moniker_comparison_data
[] =
1014 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1015 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1016 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1017 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1020 static const WCHAR expected_class_moniker_display_name
[] =
1022 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
1023 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
1024 '0','0','0','0','4','6',':',0
1027 static const BYTE expected_item_moniker_comparison_data
[] =
1029 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1030 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1031 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1032 0x54,0x00,0x00,0x00,
1035 static const BYTE expected_item_moniker_saved_data
[] =
1037 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1038 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1041 static const BYTE expected_item_moniker_marshal_data
[] =
1043 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1044 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1045 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1046 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1047 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1048 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1049 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1050 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1053 static const BYTE expected_anti_moniker_marshal_data
[] =
1055 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1056 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1057 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1058 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1059 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1060 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1061 0x01,0x00,0x00,0x00,
1064 static const BYTE expected_anti_moniker_saved_data
[] =
1066 0x01,0x00,0x00,0x00,
1069 static const BYTE expected_anti_moniker_comparison_data
[] =
1071 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1072 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1073 0x01,0x00,0x00,0x00,
1076 static const BYTE expected_gc_moniker_marshal_data
[] =
1078 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1079 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1080 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1081 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1082 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1083 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1084 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1085 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1086 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1087 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1088 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1089 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1090 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1091 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1092 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1093 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1094 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1095 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1096 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1097 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1098 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1099 0x00,0x57,0x69,0x6e,0x65,0x00,
1102 static const BYTE expected_gc_moniker_saved_data
[] =
1104 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1105 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1106 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1107 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1108 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1109 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1110 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1111 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1115 static const BYTE expected_gc_moniker_comparison_data
[] =
1117 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1118 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1119 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1120 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1121 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1122 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1123 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1124 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1125 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1128 static void test_moniker(
1129 const char *testname
, IMoniker
*moniker
,
1130 const BYTE
*expected_moniker_marshal_data
, unsigned int sizeof_expected_moniker_marshal_data
,
1131 const BYTE
*expected_moniker_saved_data
, unsigned int sizeof_expected_moniker_saved_data
,
1132 const BYTE
*expected_moniker_comparison_data
, unsigned int sizeof_expected_moniker_comparison_data
,
1133 LPCWSTR expected_display_name
)
1139 LPBYTE moniker_data
;
1144 IMoniker
* moniker_proxy
;
1145 LPOLESTR display_name
;
1148 hr
= IMoniker_IsDirty(moniker
);
1149 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1153 hr
= CreateBindCtx(0, &bindctx
);
1154 ok_ole_success(hr
, CreateBindCtx
);
1156 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1157 ok_ole_success(hr
, IMoniker_GetDisplayName
);
1158 ok(!lstrcmpW(display_name
, expected_display_name
), "%s: display name wasn't what was expected\n", testname
);
1160 CoTaskMemFree(display_name
);
1161 IBindCtx_Release(bindctx
);
1163 hr
= IMoniker_IsDirty(moniker
);
1164 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1166 /* IROTData::GetComparisonData test */
1168 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1169 ok_ole_success(hr
, IMoniker_QueryInterface_IID_IROTData
);
1171 hr
= IROTData_GetComparisonData(rotdata
, buffer
, sizeof(buffer
), &moniker_size
);
1172 ok_ole_success(hr
, IROTData_GetComparisonData
);
1174 if (hr
!= S_OK
) moniker_size
= 0;
1176 /* first check we have the right amount of data */
1177 ok(moniker_size
== sizeof_expected_moniker_comparison_data
,
1178 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1179 testname
, sizeof_expected_moniker_comparison_data
, moniker_size
);
1181 /* then do a byte-by-byte comparison */
1182 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_comparison_data
); i
++)
1184 if (expected_moniker_comparison_data
[i
] != buffer
[i
])
1191 ok(same
, "%s: Comparison data differs\n", testname
);
1194 for (i
= 0; i
< moniker_size
; i
++)
1196 if (i
% 8 == 0) printf(" ");
1197 printf("0x%02x,", buffer
[i
]);
1198 if (i
% 8 == 7) printf("\n");
1203 IROTData_Release(rotdata
);
1205 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1209 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1210 ok_ole_success(hr
, IMoniker_Save
);
1212 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1213 ok_ole_success(hr
, GetHGlobalFromStream
);
1215 moniker_size
= GlobalSize(hglobal
);
1217 moniker_data
= GlobalLock(hglobal
);
1219 /* first check we have the right amount of data */
1220 ok(moniker_size
== round_heap_size(sizeof_expected_moniker_saved_data
),
1221 "%s: Size of saved data differs (expected %d, actual %d)\n",
1222 testname
, (DWORD
)round_heap_size(sizeof_expected_moniker_saved_data
), moniker_size
);
1224 /* then do a byte-by-byte comparison */
1225 for (i
= 0; i
< min(moniker_size
, round_heap_size(sizeof_expected_moniker_saved_data
)); i
++)
1227 if (expected_moniker_saved_data
[i
] != moniker_data
[i
])
1234 ok(same
, "%s: Saved data differs\n", testname
);
1237 for (i
= 0; i
< moniker_size
; i
++)
1239 if (i
% 8 == 0) printf(" ");
1240 printf("0x%02x,", moniker_data
[i
]);
1241 if (i
% 8 == 7) printf("\n");
1246 GlobalUnlock(hglobal
);
1248 IStream_Release(stream
);
1250 /* Marshaling tests */
1252 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1253 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1255 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1256 ok_ole_success(hr
, CoMarshalInterface
);
1258 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1259 ok_ole_success(hr
, GetHGlobalFromStream
);
1261 moniker_size
= GlobalSize(hglobal
);
1263 moniker_data
= GlobalLock(hglobal
);
1265 /* first check we have the right amount of data */
1266 ok(moniker_size
== round_heap_size(sizeof_expected_moniker_marshal_data
),
1267 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1268 testname
, (DWORD
)round_heap_size(sizeof_expected_moniker_marshal_data
), moniker_size
);
1270 /* then do a byte-by-byte comparison */
1271 if (expected_moniker_marshal_data
)
1273 for (i
= 0; i
< min(moniker_size
, round_heap_size(sizeof_expected_moniker_marshal_data
)); i
++)
1275 if (expected_moniker_marshal_data
[i
] != moniker_data
[i
])
1283 ok(same
, "%s: Marshaled data differs\n", testname
);
1286 for (i
= 0; i
< moniker_size
; i
++)
1288 if (i
% 8 == 0) printf(" ");
1289 printf("0x%02x,", moniker_data
[i
]);
1290 if (i
% 8 == 7) printf("\n");
1295 GlobalUnlock(hglobal
);
1297 IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1298 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&moniker_proxy
);
1299 ok_ole_success(hr
, CoUnmarshalInterface
);
1301 IStream_Release(stream
);
1302 IMoniker_Release(moniker_proxy
);
1305 static void test_class_moniker(void)
1316 hr
= CreateClassMoniker(&CLSID_StdComponentCategoriesMgr
, &moniker
);
1317 ok_ole_success(hr
, CreateClassMoniker
);
1318 if (!moniker
) return;
1320 test_moniker("class moniker", moniker
,
1321 expected_class_moniker_marshal_data
, sizeof(expected_class_moniker_marshal_data
),
1322 expected_class_moniker_saved_data
, sizeof(expected_class_moniker_saved_data
),
1323 expected_class_moniker_comparison_data
, sizeof(expected_class_moniker_comparison_data
),
1324 expected_class_moniker_display_name
);
1328 hr
= IMoniker_Hash(moniker
, &hash
);
1329 ok_ole_success(hr
, IMoniker_Hash
);
1331 ok(hash
== CLSID_StdComponentCategoriesMgr
.Data1
,
1332 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1335 /* IsSystemMoniker test */
1337 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1338 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1340 ok(moniker_type
== MKSYS_CLASSMONIKER
,
1341 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1344 hr
= CreateBindCtx(0, &bindctx
);
1345 ok_ole_success(hr
, CreateBindCtx
);
1347 /* IsRunning test */
1348 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1349 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1351 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1352 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1354 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1355 ok(hr
== MK_E_UNAVAILABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr
);
1357 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1358 ok_ole_success(hr
, IMoniker_BindToObject
);
1359 IUnknown_Release(unknown
);
1361 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1362 ok_ole_success(hr
, IMoniker_BindToStorage
);
1363 IUnknown_Release(unknown
);
1365 IBindCtx_Release(bindctx
);
1367 hr
= IMoniker_Inverse(moniker
, &inverse
);
1368 ok_ole_success(hr
, IMoniker_Inverse
);
1369 IMoniker_Release(inverse
);
1371 IMoniker_Release(moniker
);
1374 static void test_file_moniker(WCHAR
* path
)
1377 IMoniker
*moniker1
= NULL
, *moniker2
= NULL
;
1380 hr
= CreateFileMoniker(path
, &moniker1
);
1381 ok_ole_success(hr
, CreateFileMoniker
);
1383 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1386 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker1
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1387 ok_ole_success(hr
, CoMarshalInterface
);
1390 hr
= IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1391 ok_ole_success(hr
, IStream_Seek
);
1394 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void**)&moniker2
);
1395 ok_ole_success(hr
, CoUnmarshalInterface
);
1397 hr
= IMoniker_IsEqual(moniker1
, moniker2
);
1398 ok_ole_success(hr
, IsEqual
);
1400 IStream_Release(stream
);
1402 IMoniker_Release(moniker1
);
1404 IMoniker_Release(moniker2
);
1407 static void test_file_monikers(void)
1409 static WCHAR wszFile
[][30] = {
1410 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1411 {'\\', '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},
1412 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1413 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1414 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1415 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1416 * U+0100 .. = Latin extended-A
1418 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1423 trace("ACP is %u\n", GetACP());
1425 for (i
= 0; i
< COUNTOF(wszFile
); ++i
)
1428 for (j
= lstrlenW(wszFile
[i
]); j
> 0; --j
)
1431 test_file_moniker(wszFile
[i
]);
1436 static void test_item_moniker(void)
1445 static const WCHAR wszDelimeter
[] = {'!',0};
1446 static const WCHAR wszObjectName
[] = {'T','e','s','t',0};
1447 static const WCHAR expected_display_name
[] = { '!','T','e','s','t',0 };
1449 hr
= CreateItemMoniker(wszDelimeter
, wszObjectName
, &moniker
);
1450 ok_ole_success(hr
, CreateItemMoniker
);
1452 test_moniker("item moniker", moniker
,
1453 expected_item_moniker_marshal_data
, sizeof(expected_item_moniker_marshal_data
),
1454 expected_item_moniker_saved_data
, sizeof(expected_item_moniker_saved_data
),
1455 expected_item_moniker_comparison_data
, sizeof(expected_item_moniker_comparison_data
),
1456 expected_display_name
);
1460 hr
= IMoniker_Hash(moniker
, &hash
);
1461 ok_ole_success(hr
, IMoniker_Hash
);
1464 "Hash value != 0x73c, instead was 0x%08x\n",
1467 /* IsSystemMoniker test */
1469 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1470 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1472 ok(moniker_type
== MKSYS_ITEMMONIKER
,
1473 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1476 hr
= CreateBindCtx(0, &bindctx
);
1477 ok_ole_success(hr
, CreateBindCtx
);
1479 /* IsRunning test */
1480 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1482 ok(hr
== E_INVALIDARG
, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr
);
1484 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1485 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1487 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1488 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1490 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1491 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1493 IBindCtx_Release(bindctx
);
1495 hr
= IMoniker_Inverse(moniker
, &inverse
);
1496 ok_ole_success(hr
, IMoniker_Inverse
);
1497 IMoniker_Release(inverse
);
1499 IMoniker_Release(moniker
);
1502 static void test_anti_moniker(void)
1512 static const WCHAR expected_display_name
[] = { '\\','.','.',0 };
1514 hr
= CreateAntiMoniker(&moniker
);
1515 ok_ole_success(hr
, CreateAntiMoniker
);
1516 if (!moniker
) return;
1518 test_moniker("anti moniker", moniker
,
1519 expected_anti_moniker_marshal_data
, sizeof(expected_anti_moniker_marshal_data
),
1520 expected_anti_moniker_saved_data
, sizeof(expected_anti_moniker_saved_data
),
1521 expected_anti_moniker_comparison_data
, sizeof(expected_anti_moniker_comparison_data
),
1522 expected_display_name
);
1525 hr
= IMoniker_Hash(moniker
, &hash
);
1526 ok_ole_success(hr
, IMoniker_Hash
);
1527 ok(hash
== 0x80000001,
1528 "Hash value != 0x80000001, instead was 0x%08x\n",
1531 /* IsSystemMoniker test */
1532 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1533 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1534 ok(moniker_type
== MKSYS_ANTIMONIKER
,
1535 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1538 hr
= IMoniker_Inverse(moniker
, &inverse
);
1539 ok(hr
== MK_E_NOINVERSE
, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr
);
1540 ok(inverse
== NULL
, "inverse should have been set to NULL instead of %p\n", inverse
);
1542 hr
= CreateBindCtx(0, &bindctx
);
1543 ok_ole_success(hr
, CreateBindCtx
);
1545 /* IsRunning test */
1546 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1547 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1549 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1550 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1552 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1553 ok(hr
== E_NOTIMPL
, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr
);
1555 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1556 ok(hr
== E_NOTIMPL
, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr
);
1558 IBindCtx_Release(bindctx
);
1560 IMoniker_Release(moniker
);
1563 static void test_generic_composite_moniker(void)
1575 static const WCHAR wszDelimeter1
[] = {'!',0};
1576 static const WCHAR wszObjectName1
[] = {'T','e','s','t',0};
1577 static const WCHAR wszDelimeter2
[] = {'#',0};
1578 static const WCHAR wszObjectName2
[] = {'W','i','n','e',0};
1579 static const WCHAR expected_display_name
[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1581 hr
= CreateItemMoniker(wszDelimeter1
, wszObjectName1
, &moniker1
);
1582 ok_ole_success(hr
, CreateItemMoniker
);
1583 hr
= CreateItemMoniker(wszDelimeter2
, wszObjectName2
, &moniker2
);
1584 ok_ole_success(hr
, CreateItemMoniker
);
1585 hr
= CreateGenericComposite(moniker1
, moniker2
, &moniker
);
1586 ok_ole_success(hr
, CreateGenericComposite
);
1588 test_moniker("generic composite moniker", moniker
,
1589 expected_gc_moniker_marshal_data
, sizeof(expected_gc_moniker_marshal_data
),
1590 expected_gc_moniker_saved_data
, sizeof(expected_gc_moniker_saved_data
),
1591 expected_gc_moniker_comparison_data
, sizeof(expected_gc_moniker_comparison_data
),
1592 expected_display_name
);
1596 hr
= IMoniker_Hash(moniker
, &hash
);
1597 ok_ole_success(hr
, IMoniker_Hash
);
1600 "Hash value != 0xd87, instead was 0x%08x\n",
1603 /* IsSystemMoniker test */
1605 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1606 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1608 ok(moniker_type
== MKSYS_GENERICCOMPOSITE
,
1609 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1612 hr
= CreateBindCtx(0, &bindctx
);
1613 ok_ole_success(hr
, CreateBindCtx
);
1615 /* IsRunning test */
1616 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1618 ok(hr
== E_INVALIDARG
, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr
);
1620 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1622 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1624 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1625 ok(hr
== MK_E_NOTBINDABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr
);
1627 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1629 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1632 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1633 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1635 IBindCtx_Release(bindctx
);
1637 hr
= IMoniker_Inverse(moniker
, &inverse
);
1638 ok_ole_success(hr
, IMoniker_Inverse
);
1639 IMoniker_Release(inverse
);
1641 IMoniker_Release(moniker
);
1644 static void test_pointer_moniker(void)
1656 LPOLESTR display_name
;
1660 hr
= CreatePointerMoniker((IUnknown
*)&Test_ClassFactory
, NULL
);
1661 ok(hr
== E_INVALIDARG
, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1663 hr
= CreatePointerMoniker((IUnknown
*)&Test_ClassFactory
, &moniker
);
1664 ok_ole_success(hr
, CreatePointerMoniker
);
1665 if (!moniker
) return;
1667 ok_more_than_one_lock();
1671 hr
= CreateBindCtx(0, &bindctx
);
1672 ok_ole_success(hr
, CreateBindCtx
);
1674 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1675 ok(hr
== E_NOTIMPL
, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1677 IBindCtx_Release(bindctx
);
1679 hr
= IMoniker_IsDirty(moniker
);
1680 ok(hr
== S_FALSE
, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr
);
1682 /* IROTData::GetComparisonData test */
1684 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1685 ok(hr
== E_NOINTERFACE
, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr
);
1689 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1690 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1692 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1693 ok(hr
== E_NOTIMPL
, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1695 IStream_Release(stream
);
1698 hr
= IMoniker_Hash(moniker
, &hash
);
1699 ok_ole_success(hr
, IMoniker_Hash
);
1700 ok(hash
== (DWORD
)&Test_ClassFactory
,
1701 "Hash value should have been 0x%08x, instead of 0x%08x\n",
1702 (DWORD
)&Test_ClassFactory
, hash
);
1704 /* IsSystemMoniker test */
1705 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1706 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1707 ok(moniker_type
== MKSYS_POINTERMONIKER
,
1708 "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1711 hr
= IMoniker_Inverse(moniker
, &inverse
);
1712 ok_ole_success(hr
, IMoniker_Inverse
);
1713 IMoniker_Release(inverse
);
1715 hr
= CreateBindCtx(0, &bindctx
);
1716 ok_ole_success(hr
, CreateBindCtx
);
1718 /* IsRunning test */
1719 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1720 ok(hr
== S_OK
, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr
);
1722 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1723 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1725 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1726 ok_ole_success(hr
, IMoniker_BindToObject
);
1727 IUnknown_Release(unknown
);
1729 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1730 ok_ole_success(hr
, IMoniker_BindToStorage
);
1731 IUnknown_Release(unknown
);
1733 IMoniker_Release(moniker
);
1737 hr
= CreatePointerMoniker(NULL
, &moniker
);
1738 ok_ole_success(hr
, CreatePointerMoniker
);
1740 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1741 ok(hr
== E_UNEXPECTED
, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr
);
1743 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1744 ok(hr
== E_UNEXPECTED
, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr
);
1746 IBindCtx_Release(bindctx
);
1748 IMoniker_Release(moniker
);
1751 static void test_bind_context(void)
1755 IEnumString
*pEnumString
;
1756 BIND_OPTS2 bind_opts
;
1757 HeapUnknown
*unknown
;
1758 HeapUnknown
*unknown2
;
1759 IUnknown
*param_obj
;
1761 static const WCHAR wszParamName
[] = {'G','e','m','m','a',0};
1762 static const WCHAR wszNonExistent
[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1764 hr
= CreateBindCtx(0, NULL
);
1765 ok(hr
== E_INVALIDARG
, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1767 hr
= CreateBindCtx(0xdeadbeef, &pBindCtx
);
1768 ok(hr
== E_INVALIDARG
, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1770 hr
= CreateBindCtx(0, &pBindCtx
);
1771 ok_ole_success(hr
, "CreateBindCtx");
1773 bind_opts
.cbStruct
= -1;
1774 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1775 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1776 ok(bind_opts
.cbStruct
== sizeof(bind_opts
) ||
1777 bind_opts
.cbStruct
== sizeof(bind_opts
) + sizeof(void*), /* Vista */
1778 "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1780 bind_opts
.cbStruct
= sizeof(BIND_OPTS
);
1781 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1782 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1783 ok(bind_opts
.cbStruct
== sizeof(BIND_OPTS
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1785 bind_opts
.cbStruct
= sizeof(bind_opts
);
1786 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1787 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1788 ok(bind_opts
.cbStruct
== sizeof(bind_opts
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1789 ok(bind_opts
.grfFlags
== 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts
.grfFlags
);
1790 ok(bind_opts
.grfMode
== STGM_READWRITE
, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts
.grfMode
);
1791 ok(bind_opts
.dwTickCountDeadline
== 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts
.dwTickCountDeadline
);
1792 ok(bind_opts
.dwTrackFlags
== 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts
.dwTrackFlags
);
1793 ok(bind_opts
.dwClassContext
== (CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
|CLSCTX_REMOTE_SERVER
),
1794 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts
.dwClassContext
);
1795 ok(bind_opts
.locale
== GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts
.locale
);
1796 ok(bind_opts
.pServerInfo
== NULL
, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts
.pServerInfo
);
1798 bind_opts
.cbStruct
= -1;
1799 hr
= IBindCtx_SetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1800 ok(hr
== E_INVALIDARG
, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1802 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, NULL
);
1803 ok(hr
== E_INVALIDARG
, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1805 unknown
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1806 unknown
->lpVtbl
= &HeapUnknown_Vtbl
;
1808 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, (IUnknown
*)&unknown
->lpVtbl
);
1809 ok_ole_success(hr
, "IBindCtx_RegisterObjectParam");
1811 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, ¶m_obj
);
1812 ok_ole_success(hr
, "IBindCtx_GetObjectParam");
1813 IUnknown_Release(param_obj
);
1815 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
, ¶m_obj
);
1816 ok(hr
== E_FAIL
, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1817 ok(param_obj
== NULL
, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj
);
1819 hr
= IBindCtx_RevokeObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
);
1820 ok(hr
== E_FAIL
, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1822 hr
= IBindCtx_EnumObjectParam(pBindCtx
, &pEnumString
);
1823 ok(hr
== E_NOTIMPL
, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1824 ok(!pEnumString
, "pEnumString should be NULL\n");
1826 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, NULL
);
1827 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound(NULL)");
1829 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, NULL
);
1830 ok(hr
== E_INVALIDARG
, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr
);
1832 unknown2
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1833 unknown2
->lpVtbl
= &HeapUnknown_Vtbl
;
1835 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1836 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound");
1838 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1839 ok_ole_success(hr
, "IBindCtx_RevokeObjectBound");
1841 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1842 ok(hr
== MK_E_NOTBOUND
, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr
);
1844 IBindCtx_Release(pBindCtx
);
1846 refs
= IUnknown_Release((IUnknown
*)&unknown
->lpVtbl
);
1847 ok(!refs
, "object param should have been destroyed, instead of having %d refs\n", refs
);
1849 refs
= IUnknown_Release((IUnknown
*)&unknown2
->lpVtbl
);
1850 ok(!refs
, "bound object should have been destroyed, instead of having %d refs\n", refs
);
1855 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1858 test_ROT_multiple_entries();
1859 test_MkParseDisplayName();
1860 test_class_moniker();
1861 test_file_monikers();
1862 test_item_moniker();
1863 test_anti_moniker();
1864 test_generic_composite_moniker();
1865 test_pointer_moniker();
1867 /* FIXME: test moniker creation funcs and parsing other moniker formats */
1869 test_bind_context();