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
35 #include "wine/test.h"
37 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
38 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
39 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
40 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
42 #define CHECK_EXPECTED_METHOD(method_name) \
44 trace("%s\n", method_name); \
45 ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
46 if (*expected_method_list) \
48 ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
49 *expected_method_list, method_name); \
50 expected_method_list++; \
54 static char const * const *expected_method_list
;
55 static const WCHAR wszFileName1
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
56 static const WCHAR wszFileName2
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
58 static const CLSID CLSID_WineTest
=
59 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
63 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
66 static const CLSID CLSID_TestMoniker
=
67 { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
71 {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
76 static void LockModule(void)
78 InterlockedIncrement(&cLocks
);
81 static void UnlockModule(void)
83 InterlockedDecrement(&cLocks
);
86 static SIZE_T
round_global_size(SIZE_T size
)
88 static SIZE_T global_size_alignment
= -1;
89 if (global_size_alignment
== -1)
91 void *p
= GlobalAlloc(GMEM_FIXED
, 1);
92 global_size_alignment
= GlobalSize(p
);
96 return ((size
+ global_size_alignment
- 1) & ~(global_size_alignment
- 1));
99 static HRESULT WINAPI
Test_IClassFactory_QueryInterface(
100 LPCLASSFACTORY iface
,
104 if (ppvObj
== NULL
) return E_POINTER
;
106 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
107 IsEqualGUID(riid
, &IID_IClassFactory
))
110 IClassFactory_AddRef(iface
);
115 return E_NOINTERFACE
;
118 static ULONG WINAPI
Test_IClassFactory_AddRef(LPCLASSFACTORY iface
)
121 return 2; /* non-heap-based object */
124 static ULONG WINAPI
Test_IClassFactory_Release(LPCLASSFACTORY iface
)
127 return 1; /* non-heap-based object */
130 static HRESULT WINAPI
Test_IClassFactory_CreateInstance(
131 LPCLASSFACTORY iface
,
139 static HRESULT WINAPI
Test_IClassFactory_LockServer(
140 LPCLASSFACTORY iface
,
146 static const IClassFactoryVtbl TestClassFactory_Vtbl
=
148 Test_IClassFactory_QueryInterface
,
149 Test_IClassFactory_AddRef
,
150 Test_IClassFactory_Release
,
151 Test_IClassFactory_CreateInstance
,
152 Test_IClassFactory_LockServer
155 static IClassFactory Test_ClassFactory
= { &TestClassFactory_Vtbl
};
159 const IUnknownVtbl
*lpVtbl
;
163 static HRESULT WINAPI
HeapUnknown_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
165 if (IsEqualIID(riid
, &IID_IUnknown
))
167 IUnknown_AddRef(iface
);
172 return E_NOINTERFACE
;
175 static ULONG WINAPI
HeapUnknown_AddRef(IUnknown
*iface
)
177 HeapUnknown
*This
= (HeapUnknown
*)iface
;
178 return InterlockedIncrement((LONG
*)&This
->refs
);
181 static ULONG WINAPI
HeapUnknown_Release(IUnknown
*iface
)
183 HeapUnknown
*This
= (HeapUnknown
*)iface
;
184 ULONG refs
= InterlockedDecrement((LONG
*)&This
->refs
);
185 if (!refs
) HeapFree(GetProcessHeap(), 0, This
);
189 static const IUnknownVtbl HeapUnknown_Vtbl
=
191 HeapUnknown_QueryInterface
,
196 static HRESULT WINAPI
197 MonikerNoROTData_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
204 if (IsEqualIID(&IID_IUnknown
, riid
) ||
205 IsEqualIID(&IID_IPersist
, riid
) ||
206 IsEqualIID(&IID_IPersistStream
,riid
) ||
207 IsEqualIID(&IID_IMoniker
, riid
))
209 if (IsEqualIID(&IID_IROTData
, riid
))
210 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
213 return E_NOINTERFACE
;
215 IMoniker_AddRef(iface
);
221 Moniker_AddRef(IMoniker
* iface
)
227 Moniker_Release(IMoniker
* iface
)
232 static HRESULT WINAPI
233 Moniker_GetClassID(IMoniker
* iface
, CLSID
*pClassID
)
235 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
237 *pClassID
= CLSID_TestMoniker
;
242 static HRESULT WINAPI
243 Moniker_IsDirty(IMoniker
* iface
)
245 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
250 static HRESULT WINAPI
251 Moniker_Load(IMoniker
* iface
, IStream
* pStm
)
253 CHECK_EXPECTED_METHOD("Moniker_Load");
257 static HRESULT WINAPI
258 Moniker_Save(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
)
260 CHECK_EXPECTED_METHOD("Moniker_Save");
264 static HRESULT WINAPI
265 Moniker_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
267 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
271 static HRESULT WINAPI
272 Moniker_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
273 REFIID riid
, VOID
** ppvResult
)
275 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
279 static HRESULT WINAPI
280 Moniker_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
281 REFIID riid
, VOID
** ppvObject
)
283 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
287 static HRESULT WINAPI
288 Moniker_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
289 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
291 CHECK_EXPECTED_METHOD("Moniker_Reduce");
293 if (ppmkReduced
==NULL
)
296 IMoniker_AddRef(iface
);
300 return MK_S_REDUCED_TO_SELF
;
303 static HRESULT WINAPI
304 Moniker_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
305 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
307 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
311 static HRESULT WINAPI
312 Moniker_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
314 CHECK_EXPECTED_METHOD("Moniker_Enum");
316 if (ppenumMoniker
== NULL
)
319 *ppenumMoniker
= NULL
;
324 static HRESULT WINAPI
325 Moniker_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
327 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
331 static HRESULT WINAPI
332 Moniker_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
334 CHECK_EXPECTED_METHOD("Moniker_Hash");
338 static HRESULT WINAPI
339 Moniker_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
340 IMoniker
* pmkNewlyRunning
)
342 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
346 static HRESULT WINAPI
347 Moniker_GetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
,
348 IMoniker
* pmkToLeft
, FILETIME
* pFileTime
)
350 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
354 static HRESULT WINAPI
355 Moniker_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
357 CHECK_EXPECTED_METHOD("Moniker_Inverse");
361 static HRESULT WINAPI
362 Moniker_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
364 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
368 static HRESULT WINAPI
369 Moniker_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
371 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
375 static HRESULT WINAPI
376 Moniker_GetDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
377 IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
379 static const WCHAR wszDisplayName
[] = {'*','*','G','e','m','m','a',0};
380 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
381 *ppszDisplayName
= CoTaskMemAlloc(sizeof(wszDisplayName
));
382 memcpy(*ppszDisplayName
, wszDisplayName
, sizeof(wszDisplayName
));
386 static HRESULT WINAPI
387 Moniker_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
388 LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
)
390 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
394 static HRESULT WINAPI
395 Moniker_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
397 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
402 (*pwdMksys
)=MKSYS_NONE
;
407 static const IMonikerVtbl MonikerNoROTDataVtbl
=
409 MonikerNoROTData_QueryInterface
,
417 Moniker_BindToObject
,
418 Moniker_BindToStorage
,
425 Moniker_GetTimeOfLastChange
,
427 Moniker_CommonPrefixWith
,
428 Moniker_RelativePathTo
,
429 Moniker_GetDisplayName
,
430 Moniker_ParseDisplayName
,
431 Moniker_IsSystemMoniker
434 static IMoniker MonikerNoROTData
= { &MonikerNoROTDataVtbl
};
436 static IMoniker Moniker
;
438 static HRESULT WINAPI
439 ROTData_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
441 return IMoniker_QueryInterface(&Moniker
, riid
, ppvObject
);
445 ROTData_AddRef(IROTData
*iface
)
451 ROTData_Release(IROTData
* iface
)
456 static HRESULT WINAPI
457 ROTData_GetComparisonData(IROTData
* iface
, BYTE
* pbData
,
458 ULONG cbMax
, ULONG
* pcbData
)
460 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
463 if (cbMax
< *pcbData
)
464 return E_OUTOFMEMORY
;
471 static IROTDataVtbl ROTDataVtbl
=
473 ROTData_QueryInterface
,
476 ROTData_GetComparisonData
479 static IROTData ROTData
= { &ROTDataVtbl
};
481 static HRESULT WINAPI
482 Moniker_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
489 if (IsEqualIID(&IID_IUnknown
, riid
) ||
490 IsEqualIID(&IID_IPersist
, riid
) ||
491 IsEqualIID(&IID_IPersistStream
,riid
) ||
492 IsEqualIID(&IID_IMoniker
, riid
))
494 if (IsEqualIID(&IID_IROTData
, riid
))
496 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
497 *ppvObject
= &ROTData
;
501 return E_NOINTERFACE
;
503 IMoniker_AddRef(iface
);
508 static const IMonikerVtbl MonikerVtbl
=
510 Moniker_QueryInterface
,
518 Moniker_BindToObject
,
519 Moniker_BindToStorage
,
526 Moniker_GetTimeOfLastChange
,
528 Moniker_CommonPrefixWith
,
529 Moniker_RelativePathTo
,
530 Moniker_GetDisplayName
,
531 Moniker_ParseDisplayName
,
532 Moniker_IsSystemMoniker
535 static IMoniker Moniker
= { &MonikerVtbl
};
537 static void test_ROT(void)
539 static const WCHAR wszFileName
[] = {'B','E','2','0','E','2','F','5','-',
540 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
541 '2','0','4','6','E','5','8','6','C','9','2','5',0};
543 IMoniker
*pMoniker
= NULL
;
544 IRunningObjectTable
*pROT
= NULL
;
546 static const char *methods_register_no_ROTData
[] =
549 "Moniker_GetTimeOfLastChange",
550 "Moniker_QueryInterface(IID_IROTData)",
551 "Moniker_GetDisplayName",
552 "Moniker_GetClassID",
555 static const char *methods_register
[] =
558 "Moniker_GetTimeOfLastChange",
559 "Moniker_QueryInterface(IID_IROTData)",
560 "ROTData_GetComparisonData",
563 static const char *methods_isrunning_no_ROTData
[] =
566 "Moniker_QueryInterface(IID_IROTData)",
567 "Moniker_GetDisplayName",
568 "Moniker_GetClassID",
571 static const char *methods_isrunning
[] =
574 "Moniker_QueryInterface(IID_IROTData)",
575 "ROTData_GetComparisonData",
581 hr
= GetRunningObjectTable(0, &pROT
);
582 ok_ole_success(hr
, GetRunningObjectTable
);
584 expected_method_list
= methods_register_no_ROTData
;
585 /* try with our own moniker that doesn't support IROTData */
586 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
587 (IUnknown
*)&Test_ClassFactory
, &MonikerNoROTData
, &dwCookie
);
588 ok_ole_success(hr
, IRunningObjectTable_Register
);
589 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
591 ok_more_than_one_lock();
593 expected_method_list
= methods_isrunning_no_ROTData
;
594 hr
= IRunningObjectTable_IsRunning(pROT
, &MonikerNoROTData
);
595 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
596 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
598 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
599 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
603 expected_method_list
= methods_register
;
604 /* try with our own moniker */
605 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
606 (IUnknown
*)&Test_ClassFactory
, &Moniker
, &dwCookie
);
607 ok_ole_success(hr
, IRunningObjectTable_Register
);
608 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
610 ok_more_than_one_lock();
612 expected_method_list
= methods_isrunning
;
613 hr
= IRunningObjectTable_IsRunning(pROT
, &Moniker
);
614 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
615 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
617 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
618 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
622 hr
= CreateFileMoniker(wszFileName
, &pMoniker
);
623 ok_ole_success(hr
, CreateClassMoniker
);
626 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
,
627 pMoniker
, &dwCookie
);
628 ok_ole_success(hr
, IRunningObjectTable_Register
);
630 ok_more_than_one_lock();
632 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
633 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
637 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
638 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
639 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
640 ok_ole_success(hr
, IRunningObjectTable_Register
);
642 ok_more_than_one_lock();
644 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
645 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
649 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
650 /* only succeeds when process is started by SCM and has LocalService
651 * or RunAs AppId values */
652 hr
= IRunningObjectTable_Register(pROT
,
653 ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
,
654 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
656 ok(hr
== CO_E_WRONG_SERVER_IDENTITY
||
657 broken(hr
== S_OK
) /* Win9x */,
658 "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr
);
660 if (hr
== S_OK
) IRunningObjectTable_Revoke(pROT
, dwCookie
);
662 hr
= IRunningObjectTable_Register(pROT
, 0xdeadbeef,
663 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
664 ok(hr
== E_INVALIDARG
, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
666 IMoniker_Release(pMoniker
);
668 IRunningObjectTable_Release(pROT
);
671 static void test_ROT_multiple_entries(void)
674 IMoniker
*pMoniker
= NULL
;
675 IRunningObjectTable
*pROT
= NULL
;
676 DWORD dwCookie1
, dwCookie2
;
677 IUnknown
*pObject
= NULL
;
678 static const WCHAR moniker_path
[] =
679 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0};
681 hr
= GetRunningObjectTable(0, &pROT
);
682 ok_ole_success(hr
, GetRunningObjectTable
);
684 hr
= CreateFileMoniker(moniker_path
, &pMoniker
);
685 ok_ole_success(hr
, CreateFileMoniker
);
687 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie1
);
688 ok_ole_success(hr
, IRunningObjectTable_Register
);
690 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie2
);
691 ok(hr
== MK_S_MONIKERALREADYREGISTERED
, "IRunningObjectTable_Register should have returned MK_S_MONIKERALREADYREGISTERED instead of 0x%08x\n", hr
);
693 ok(dwCookie1
!= dwCookie2
, "cookie returned for registering duplicate object shouldn't match cookie of original object (0x%x)\n", dwCookie1
);
695 hr
= IRunningObjectTable_GetObject(pROT
, pMoniker
, &pObject
);
696 ok_ole_success(hr
, IRunningObjectTable_GetObject
);
697 IUnknown_Release(pObject
);
699 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie1
);
700 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
702 hr
= IRunningObjectTable_GetObject(pROT
, pMoniker
, &pObject
);
703 ok_ole_success(hr
, IRunningObjectTable_GetObject
);
704 IUnknown_Release(pObject
);
706 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie2
);
707 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
709 IMoniker_Release(pMoniker
);
711 IRunningObjectTable_Release(pROT
);
714 static HRESULT WINAPI
ParseDisplayName_QueryInterface(IParseDisplayName
*iface
, REFIID riid
, void **ppv
)
716 if (IsEqualIID(riid
, &IID_IUnknown
) ||
717 IsEqualIID(riid
, &IID_IParseDisplayName
))
720 IUnknown_AddRef(iface
);
724 return E_NOINTERFACE
;
727 static ULONG WINAPI
ParseDisplayName_AddRef(IParseDisplayName
*iface
)
732 static ULONG WINAPI
ParseDisplayName_Release(IParseDisplayName
*iface
)
737 static LPCWSTR expected_display_name
;
739 static HRESULT WINAPI
ParseDisplayName_ParseDisplayName(IParseDisplayName
*iface
,
741 LPOLESTR pszDisplayName
,
745 char display_nameA
[256];
746 WideCharToMultiByte(CP_ACP
, 0, pszDisplayName
, -1, display_nameA
, sizeof(display_nameA
), NULL
, NULL
);
747 ok(!lstrcmpW(pszDisplayName
, expected_display_name
), "unexpected display name \"%s\"\n", display_nameA
);
748 ok(pszDisplayName
== expected_display_name
, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
749 *pchEaten
= lstrlenW(pszDisplayName
);
750 return CreateAntiMoniker(ppmkOut
);
753 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl
=
755 ParseDisplayName_QueryInterface
,
756 ParseDisplayName_AddRef
,
757 ParseDisplayName_Release
,
758 ParseDisplayName_ParseDisplayName
761 static IParseDisplayName ParseDisplayName
= { &ParseDisplayName_Vtbl
};
763 static int count_moniker_matches(IBindCtx
* pbc
, IEnumMoniker
* spEM
)
765 IMoniker
* spMoniker
;
766 int monCnt
=0, matchCnt
=0;
768 while ((IEnumMoniker_Next(spEM
, 1, &spMoniker
, NULL
)==S_OK
))
773 hr
=IMoniker_GetDisplayName(spMoniker
, pbc
, NULL
, &szDisplayn
);
776 if (!lstrcmpiW(szDisplayn
, wszFileName1
) || !lstrcmpiW(szDisplayn
, wszFileName2
))
778 CoTaskMemFree(szDisplayn
);
781 trace("Total number of monikers is %i\n", monCnt
);
785 static void test_MkParseDisplayName(void)
787 IBindCtx
* pbc
= NULL
;
789 IMoniker
* pmk
= NULL
;
790 IMoniker
* pmk1
= NULL
;
791 IMoniker
* pmk2
= NULL
;
794 IUnknown
* object
= NULL
;
798 IEnumMoniker
*spEM1
= NULL
;
799 IEnumMoniker
*spEM2
= NULL
;
800 IEnumMoniker
*spEM3
= NULL
;
806 IRunningObjectTable
* pprot
=NULL
;
808 /* CLSID of My Computer */
809 static const WCHAR wszDisplayName
[] = {'c','l','s','i','d',':',
810 '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};
811 static const WCHAR wszDisplayNameClsid
[] = {'c','l','s','i','d',':',0};
812 static const WCHAR wszNonExistentProgId
[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
813 static const WCHAR wszDisplayNameRunning
[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
814 static const WCHAR wszDisplayNameProgId1
[] = {'S','t','d','F','o','n','t',':',0};
815 static const WCHAR wszDisplayNameProgId2
[] = {'@','S','t','d','F','o','n','t',0};
816 static const WCHAR wszDisplayNameProgIdFail
[] = {'S','t','d','F','o','n','t',0};
817 static const WCHAR wszEmpty
[] = {0};
818 char szDisplayNameFile
[256];
819 WCHAR wszDisplayNameFile
[256];
825 LPCOLESTR szDisplayName
;
828 } invalid_parameters
[] =
830 {NULL
, NULL
, NULL
, NULL
},
831 {NULL
, NULL
, NULL
, &pmk
},
832 {NULL
, NULL
, &eaten
, NULL
},
833 {NULL
, NULL
, &eaten
, &pmk
},
834 {NULL
, wszEmpty
, NULL
, NULL
},
835 {NULL
, wszEmpty
, NULL
, &pmk
},
836 {NULL
, wszEmpty
, &eaten
, NULL
},
837 {NULL
, wszEmpty
, &eaten
, &pmk
},
838 {&pbc
, NULL
, NULL
, NULL
},
839 {&pbc
, NULL
, NULL
, &pmk
},
840 {&pbc
, NULL
, &eaten
, NULL
},
841 {&pbc
, NULL
, &eaten
, &pmk
},
842 {&pbc
, wszEmpty
, NULL
, NULL
},
843 {&pbc
, wszEmpty
, NULL
, &pmk
},
844 {&pbc
, wszEmpty
, &eaten
, NULL
},
845 {&pbc
, wszEmpty
, &eaten
, &pmk
},
848 hr
= CreateBindCtx(0, &pbc
);
849 ok_ole_success(hr
, CreateBindCtx
);
851 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
854 pmk
= (IMoniker
*)0xdeadbeef;
855 hr
= MkParseDisplayName(invalid_parameters
[i
].ppbc
? *invalid_parameters
[i
].ppbc
: NULL
,
856 invalid_parameters
[i
].szDisplayName
,
857 invalid_parameters
[i
].pchEaten
,
858 invalid_parameters
[i
].ppmk
);
859 ok(hr
== E_INVALIDARG
, "[%d] MkParseDisplayName should have failed with E_INVALIDARG instead of 0x%08x\n", i
, hr
);
860 ok(eaten
== 0xdeadbeef, "[%d] Processed character count should have been 0xdeadbeef instead of %u\n", i
, eaten
);
861 ok(pmk
== (IMoniker
*)0xdeadbeef, "[%d] Output moniker pointer should have been 0xdeadbeef instead of %p\n", i
, pmk
);
865 pmk
= (IMoniker
*)0xdeadbeef;
866 hr
= MkParseDisplayName(pbc
, wszNonExistentProgId
, &eaten
, &pmk
);
867 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
868 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
869 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
870 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
872 /* no special handling of "clsid:" without the string form of the clsid
875 pmk
= (IMoniker
*)0xdeadbeef;
876 hr
= MkParseDisplayName(pbc
, wszDisplayNameClsid
, &eaten
, &pmk
);
877 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
878 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
879 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
880 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
882 /* shows clsid has higher precedence than a running object */
883 hr
= CreateFileMoniker(wszDisplayName
, &pmk
);
884 ok_ole_success(hr
, CreateFileMoniker
);
885 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
886 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
887 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
888 ok_ole_success(hr
, IRunningObjectTable_Register
);
889 IMoniker_Release(pmk
);
891 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
892 ok_ole_success(hr
, MkParseDisplayName
);
893 ok(eaten
== sizeof(wszDisplayName
)/sizeof(WCHAR
) - 1,
894 "Processed character count should have been 43 instead of %u\n", eaten
);
897 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
898 ok(moniker_type
== MKSYS_CLASSMONIKER
, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type
);
899 IMoniker_Release(pmk
);
901 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
902 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
903 IRunningObjectTable_Release(pprot
);
905 hr
= CreateFileMoniker(wszDisplayNameRunning
, &pmk
);
906 ok_ole_success(hr
, CreateFileMoniker
);
907 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
908 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
909 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
910 ok_ole_success(hr
, IRunningObjectTable_Register
);
911 IMoniker_Release(pmk
);
913 hr
= MkParseDisplayName(pbc
, wszDisplayNameRunning
, &eaten
, &pmk
);
914 ok_ole_success(hr
, MkParseDisplayName
);
915 ok(eaten
== sizeof(wszDisplayNameRunning
)/sizeof(WCHAR
) - 1,
916 "Processed character count should have been 15 instead of %u\n", eaten
);
919 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
920 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
921 IMoniker_Release(pmk
);
923 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
924 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
925 IRunningObjectTable_Release(pprot
);
927 hr
= CoRegisterClassObject(&CLSID_StdFont
, (IUnknown
*)&ParseDisplayName
, CLSCTX_INPROC_SERVER
, REGCLS_MULTI_SEPARATE
, &pdwReg1
);
928 ok_ole_success(hr
, CoRegisterClassObject
);
930 expected_display_name
= wszDisplayNameProgId1
;
931 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId1
, &eaten
, &pmk
);
932 ok_ole_success(hr
, MkParseDisplayName
);
933 ok(eaten
== sizeof(wszDisplayNameProgId1
)/sizeof(WCHAR
) - 1,
934 "Processed character count should have been 8 instead of %u\n", eaten
);
937 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
938 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
939 IMoniker_Release(pmk
);
942 expected_display_name
= wszDisplayNameProgId2
;
943 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId2
, &eaten
, &pmk
);
944 ok_ole_success(hr
, MkParseDisplayName
);
945 ok(eaten
== sizeof(wszDisplayNameProgId2
)/sizeof(WCHAR
) - 1,
946 "Processed character count should have been 8 instead of %u\n", eaten
);
949 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
950 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
951 IMoniker_Release(pmk
);
955 pmk
= (IMoniker
*)0xdeadbeef;
956 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgIdFail
, &eaten
, &pmk
);
957 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
958 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
959 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
960 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
962 hr
= CoRevokeClassObject(pdwReg1
);
963 ok_ole_success(hr
, CoRevokeClassObject
);
965 GetSystemDirectoryA(szDisplayNameFile
, sizeof(szDisplayNameFile
));
966 strcat(szDisplayNameFile
, "\\kernel32.dll");
967 len
= MultiByteToWideChar(CP_ACP
, 0, szDisplayNameFile
, -1, wszDisplayNameFile
, sizeof(wszDisplayNameFile
)/sizeof(wszDisplayNameFile
[0]));
968 hr
= MkParseDisplayName(pbc
, wszDisplayNameFile
, &eaten
, &pmk
);
969 ok_ole_success(hr
, MkParseDisplayName
);
970 ok(eaten
== len
- 1, "Processed character count should have been %d instead of %u\n", len
- 1, eaten
);
973 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
974 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
975 IMoniker_Release(pmk
);
978 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
979 ok_ole_success(hr
, MkParseDisplayName
);
980 ok(eaten
== sizeof(wszDisplayName
)/sizeof(WCHAR
) - 1, "Processed character count should have been 43 instead of %u\n", eaten
);
984 hr
= IMoniker_BindToObject(pmk
, pbc
, NULL
, &IID_IUnknown
, (LPVOID
*)&object
);
985 ok_ole_success(hr
, IMoniker_BindToObject
);
988 IUnknown_Release(object
);
989 IMoniker_Release(pmk
);
991 IBindCtx_Release(pbc
);
993 /* Test the EnumMoniker interface */
994 hr
= CreateBindCtx(0, &pbc
);
995 ok_ole_success(hr
, CreateBindCtx
);
997 hr
= CreateFileMoniker(wszFileName1
, &pmk1
);
998 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
999 hr
= CreateFileMoniker(wszFileName2
, &pmk2
);
1000 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
1001 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
1002 ok(hr
==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr
);
1004 /* Check EnumMoniker before registering */
1005 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM1
);
1006 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
1007 hr
= IEnumMoniker_QueryInterface(spEM1
, &IID_IUnknown
, (void*) &lpEM1
);
1008 /* Register a couple of Monikers and check is ok */
1009 ok(hr
==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr
, lpEM1
);
1012 matchCnt
= count_moniker_matches(pbc
, spEM1
);
1013 trace("Number of matches is %i\n", matchCnt
);
1015 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
1016 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk1
, &pdwReg1
);
1017 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
1018 hr
, pprot
, grflags
, lpEM1
, pmk1
, pdwReg1
);
1020 trace("IROT::Register\n");
1022 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
1023 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk2
, &pdwReg2
);
1024 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr
,
1025 pprot
, grflags
, lpEM1
, pmk2
, pdwReg2
);
1027 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM2
);
1028 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
1030 matchCnt
= count_moniker_matches(pbc
, spEM2
);
1031 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
1033 trace("IEnumMoniker::Clone\n");
1034 IEnumMoniker_Clone(spEM2
, &spEM3
);
1036 matchCnt
= count_moniker_matches(pbc
, spEM3
);
1037 ok(matchCnt
==0, "Number of matches should be equal to 0 not %i\n", matchCnt
);
1038 trace("IEnumMoniker::Reset\n");
1039 IEnumMoniker_Reset(spEM3
);
1041 matchCnt
= count_moniker_matches(pbc
, spEM3
);
1042 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
1044 IRunningObjectTable_Revoke(pprot
,pdwReg1
);
1045 IRunningObjectTable_Revoke(pprot
,pdwReg2
);
1046 IUnknown_Release(lpEM1
);
1047 IEnumMoniker_Release(spEM1
);
1048 IEnumMoniker_Release(spEM2
);
1049 IEnumMoniker_Release(spEM3
);
1050 IMoniker_Release(pmk1
);
1051 IMoniker_Release(pmk2
);
1052 IRunningObjectTable_Release(pprot
);
1054 IBindCtx_Release(pbc
);
1057 static const LARGE_INTEGER llZero
;
1059 static const BYTE expected_class_moniker_marshal_data
[] =
1061 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1062 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1063 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1064 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1065 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1066 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1067 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1068 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1069 0x00,0x00,0x00,0x00,
1072 static const BYTE expected_class_moniker_saved_data
[] =
1074 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1075 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1076 0x00,0x00,0x00,0x00,
1079 static const BYTE expected_class_moniker_comparison_data
[] =
1081 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1082 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1083 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1084 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1087 static const WCHAR expected_class_moniker_display_name
[] =
1089 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
1090 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
1091 '0','0','0','0','4','6',':',0
1094 static const BYTE expected_item_moniker_comparison_data
[] =
1096 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1097 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1098 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1099 0x54,0x00,0x00,0x00,
1102 static const BYTE expected_item_moniker_saved_data
[] =
1104 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1105 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1108 static const BYTE expected_item_moniker_marshal_data
[] =
1110 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1111 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1112 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1113 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1114 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1115 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1116 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1117 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1120 static const BYTE expected_anti_moniker_marshal_data
[] =
1122 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1123 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1124 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1125 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1126 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1127 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1128 0x01,0x00,0x00,0x00,
1131 static const BYTE expected_anti_moniker_saved_data
[] =
1133 0x01,0x00,0x00,0x00,
1136 static const BYTE expected_anti_moniker_comparison_data
[] =
1138 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1139 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1140 0x01,0x00,0x00,0x00,
1143 static const BYTE expected_gc_moniker_marshal_data
[] =
1145 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1146 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1147 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1148 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1149 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1150 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1151 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1152 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1153 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1154 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1155 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1156 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1157 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1158 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1159 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1160 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1161 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1162 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1163 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1164 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1165 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1166 0x00,0x57,0x69,0x6e,0x65,0x00,
1169 static const BYTE expected_gc_moniker_saved_data
[] =
1171 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1172 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1173 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1174 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1175 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1176 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1177 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1178 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1182 static const BYTE expected_gc_moniker_comparison_data
[] =
1184 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1185 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1186 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1187 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1188 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1189 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1190 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1191 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1192 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1195 static void test_moniker(
1196 const char *testname
, IMoniker
*moniker
,
1197 const BYTE
*expected_moniker_marshal_data
, unsigned int sizeof_expected_moniker_marshal_data
,
1198 const BYTE
*expected_moniker_saved_data
, unsigned int sizeof_expected_moniker_saved_data
,
1199 const BYTE
*expected_moniker_comparison_data
, unsigned int sizeof_expected_moniker_comparison_data
,
1200 LPCWSTR expected_display_name
)
1206 LPBYTE moniker_data
;
1211 IMoniker
* moniker_proxy
;
1212 LPOLESTR display_name
;
1215 hr
= IMoniker_IsDirty(moniker
);
1216 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1220 hr
= CreateBindCtx(0, &bindctx
);
1221 ok_ole_success(hr
, CreateBindCtx
);
1223 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1224 ok_ole_success(hr
, IMoniker_GetDisplayName
);
1225 ok(!lstrcmpW(display_name
, expected_display_name
), "%s: display name wasn't what was expected\n", testname
);
1227 CoTaskMemFree(display_name
);
1228 IBindCtx_Release(bindctx
);
1230 hr
= IMoniker_IsDirty(moniker
);
1231 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1233 /* IROTData::GetComparisonData test */
1235 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1236 ok_ole_success(hr
, IMoniker_QueryInterface_IID_IROTData
);
1238 hr
= IROTData_GetComparisonData(rotdata
, buffer
, sizeof(buffer
), &moniker_size
);
1239 ok_ole_success(hr
, IROTData_GetComparisonData
);
1241 if (hr
!= S_OK
) moniker_size
= 0;
1243 /* first check we have the right amount of data */
1244 ok(moniker_size
== sizeof_expected_moniker_comparison_data
,
1245 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1246 testname
, sizeof_expected_moniker_comparison_data
, moniker_size
);
1248 /* then do a byte-by-byte comparison */
1250 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_comparison_data
); i
++)
1252 if (expected_moniker_comparison_data
[i
] != buffer
[i
])
1259 ok(same
, "%s: Comparison data differs\n", testname
);
1262 for (i
= 0; i
< moniker_size
; i
++)
1264 if (i
% 8 == 0) printf(" ");
1265 printf("0x%02x,", buffer
[i
]);
1266 if (i
% 8 == 7) printf("\n");
1271 IROTData_Release(rotdata
);
1273 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1277 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1278 ok_ole_success(hr
, IMoniker_Save
);
1280 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1281 ok_ole_success(hr
, GetHGlobalFromStream
);
1283 moniker_size
= GlobalSize(hglobal
);
1285 moniker_data
= GlobalLock(hglobal
);
1287 /* first check we have the right amount of data */
1288 ok(moniker_size
== round_global_size(sizeof_expected_moniker_saved_data
),
1289 "%s: Size of saved data differs (expected %d, actual %d)\n",
1290 testname
, (DWORD
)round_global_size(sizeof_expected_moniker_saved_data
), moniker_size
);
1292 /* then do a byte-by-byte comparison */
1294 for (i
= 0; i
< min(moniker_size
, round_global_size(sizeof_expected_moniker_saved_data
)); i
++)
1296 if (expected_moniker_saved_data
[i
] != moniker_data
[i
])
1303 ok(same
, "%s: Saved data differs\n", testname
);
1306 for (i
= 0; i
< moniker_size
; i
++)
1308 if (i
% 8 == 0) printf(" ");
1309 printf("0x%02x,", moniker_data
[i
]);
1310 if (i
% 8 == 7) printf("\n");
1315 GlobalUnlock(hglobal
);
1317 IStream_Release(stream
);
1319 /* Marshaling tests */
1321 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1322 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1324 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1325 ok_ole_success(hr
, CoMarshalInterface
);
1327 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1328 ok_ole_success(hr
, GetHGlobalFromStream
);
1330 moniker_size
= GlobalSize(hglobal
);
1332 moniker_data
= GlobalLock(hglobal
);
1334 /* first check we have the right amount of data */
1335 ok(moniker_size
== round_global_size(sizeof_expected_moniker_marshal_data
),
1336 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1337 testname
, (DWORD
)round_global_size(sizeof_expected_moniker_marshal_data
), moniker_size
);
1339 /* then do a byte-by-byte comparison */
1341 if (expected_moniker_marshal_data
)
1343 for (i
= 0; i
< min(moniker_size
, round_global_size(sizeof_expected_moniker_marshal_data
)); i
++)
1345 if (expected_moniker_marshal_data
[i
] != moniker_data
[i
])
1353 ok(same
, "%s: Marshaled data differs\n", testname
);
1356 for (i
= 0; i
< moniker_size
; i
++)
1358 if (i
% 8 == 0) printf(" ");
1359 printf("0x%02x,", moniker_data
[i
]);
1360 if (i
% 8 == 7) printf("\n");
1365 GlobalUnlock(hglobal
);
1367 IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1368 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&moniker_proxy
);
1369 ok_ole_success(hr
, CoUnmarshalInterface
);
1371 IStream_Release(stream
);
1372 IMoniker_Release(moniker_proxy
);
1375 static void test_class_moniker(void)
1386 hr
= CreateClassMoniker(&CLSID_StdComponentCategoriesMgr
, &moniker
);
1387 ok_ole_success(hr
, CreateClassMoniker
);
1388 if (!moniker
) return;
1390 test_moniker("class moniker", moniker
,
1391 expected_class_moniker_marshal_data
, sizeof(expected_class_moniker_marshal_data
),
1392 expected_class_moniker_saved_data
, sizeof(expected_class_moniker_saved_data
),
1393 expected_class_moniker_comparison_data
, sizeof(expected_class_moniker_comparison_data
),
1394 expected_class_moniker_display_name
);
1398 hr
= IMoniker_Hash(moniker
, &hash
);
1399 ok_ole_success(hr
, IMoniker_Hash
);
1401 ok(hash
== CLSID_StdComponentCategoriesMgr
.Data1
,
1402 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1405 /* IsSystemMoniker test */
1407 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1408 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1410 ok(moniker_type
== MKSYS_CLASSMONIKER
,
1411 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1414 hr
= CreateBindCtx(0, &bindctx
);
1415 ok_ole_success(hr
, CreateBindCtx
);
1417 /* IsRunning test */
1418 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1419 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1421 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1422 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1424 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1425 ok(hr
== MK_E_UNAVAILABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr
);
1427 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1428 ok_ole_success(hr
, IMoniker_BindToObject
);
1429 IUnknown_Release(unknown
);
1431 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1432 ok_ole_success(hr
, IMoniker_BindToStorage
);
1433 IUnknown_Release(unknown
);
1435 IBindCtx_Release(bindctx
);
1437 hr
= IMoniker_Inverse(moniker
, &inverse
);
1438 ok_ole_success(hr
, IMoniker_Inverse
);
1439 IMoniker_Release(inverse
);
1441 IMoniker_Release(moniker
);
1444 static void test_file_moniker(WCHAR
* path
)
1447 IMoniker
*moniker1
= NULL
, *moniker2
= NULL
;
1450 hr
= CreateFileMoniker(path
, &moniker1
);
1451 ok_ole_success(hr
, CreateFileMoniker
);
1453 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1456 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker1
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1457 ok_ole_success(hr
, CoMarshalInterface
);
1460 hr
= IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1461 ok_ole_success(hr
, IStream_Seek
);
1464 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void**)&moniker2
);
1465 ok_ole_success(hr
, CoUnmarshalInterface
);
1467 hr
= IMoniker_IsEqual(moniker1
, moniker2
);
1468 ok_ole_success(hr
, IsEqual
);
1470 IStream_Release(stream
);
1472 IMoniker_Release(moniker1
);
1474 IMoniker_Release(moniker2
);
1477 static void test_file_monikers(void)
1479 static WCHAR wszFile
[][30] = {
1480 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1481 {'\\', '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},
1482 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1483 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1484 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1485 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1486 * U+0100 .. = Latin extended-A
1488 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1493 trace("ACP is %u\n", GetACP());
1495 for (i
= 0; i
< COUNTOF(wszFile
); ++i
)
1501 WideCharToMultiByte( CP_ACP
, WC_NO_BEST_FIT_CHARS
, wszFile
[i
], -1, NULL
, 0, NULL
, &used
);
1504 skip("string 2 doesn't round trip in codepage %u\n", GetACP() );
1508 for (j
= lstrlenW(wszFile
[i
]); j
> 0; --j
)
1511 test_file_moniker(wszFile
[i
]);
1516 static void test_item_moniker(void)
1525 static const WCHAR wszDelimeter
[] = {'!',0};
1526 static const WCHAR wszObjectName
[] = {'T','e','s','t',0};
1527 static const WCHAR expected_display_name
[] = { '!','T','e','s','t',0 };
1529 hr
= CreateItemMoniker(wszDelimeter
, wszObjectName
, &moniker
);
1530 ok_ole_success(hr
, CreateItemMoniker
);
1532 test_moniker("item moniker", moniker
,
1533 expected_item_moniker_marshal_data
, sizeof(expected_item_moniker_marshal_data
),
1534 expected_item_moniker_saved_data
, sizeof(expected_item_moniker_saved_data
),
1535 expected_item_moniker_comparison_data
, sizeof(expected_item_moniker_comparison_data
),
1536 expected_display_name
);
1540 hr
= IMoniker_Hash(moniker
, &hash
);
1541 ok_ole_success(hr
, IMoniker_Hash
);
1544 "Hash value != 0x73c, instead was 0x%08x\n",
1547 /* IsSystemMoniker test */
1549 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1550 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1552 ok(moniker_type
== MKSYS_ITEMMONIKER
,
1553 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1556 hr
= CreateBindCtx(0, &bindctx
);
1557 ok_ole_success(hr
, CreateBindCtx
);
1559 /* IsRunning test */
1560 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1561 ok(hr
== E_INVALIDARG
, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr
);
1563 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1564 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1566 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1567 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1569 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1570 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1572 IBindCtx_Release(bindctx
);
1574 hr
= IMoniker_Inverse(moniker
, &inverse
);
1575 ok_ole_success(hr
, IMoniker_Inverse
);
1576 IMoniker_Release(inverse
);
1578 IMoniker_Release(moniker
);
1581 static void test_anti_moniker(void)
1591 static const WCHAR expected_display_name
[] = { '\\','.','.',0 };
1593 hr
= CreateAntiMoniker(&moniker
);
1594 ok_ole_success(hr
, CreateAntiMoniker
);
1595 if (!moniker
) return;
1597 test_moniker("anti moniker", moniker
,
1598 expected_anti_moniker_marshal_data
, sizeof(expected_anti_moniker_marshal_data
),
1599 expected_anti_moniker_saved_data
, sizeof(expected_anti_moniker_saved_data
),
1600 expected_anti_moniker_comparison_data
, sizeof(expected_anti_moniker_comparison_data
),
1601 expected_display_name
);
1604 hr
= IMoniker_Hash(moniker
, &hash
);
1605 ok_ole_success(hr
, IMoniker_Hash
);
1606 ok(hash
== 0x80000001,
1607 "Hash value != 0x80000001, instead was 0x%08x\n",
1610 /* IsSystemMoniker test */
1611 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1612 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1613 ok(moniker_type
== MKSYS_ANTIMONIKER
,
1614 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1617 hr
= IMoniker_Inverse(moniker
, &inverse
);
1618 ok(hr
== MK_E_NOINVERSE
, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr
);
1619 ok(inverse
== NULL
, "inverse should have been set to NULL instead of %p\n", inverse
);
1621 hr
= CreateBindCtx(0, &bindctx
);
1622 ok_ole_success(hr
, CreateBindCtx
);
1624 /* IsRunning test */
1625 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1626 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1628 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1629 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1631 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1632 ok(hr
== E_NOTIMPL
, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr
);
1634 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1635 ok(hr
== E_NOTIMPL
, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr
);
1637 IBindCtx_Release(bindctx
);
1639 IMoniker_Release(moniker
);
1642 static void test_generic_composite_moniker(void)
1654 static const WCHAR wszDelimeter1
[] = {'!',0};
1655 static const WCHAR wszObjectName1
[] = {'T','e','s','t',0};
1656 static const WCHAR wszDelimeter2
[] = {'#',0};
1657 static const WCHAR wszObjectName2
[] = {'W','i','n','e',0};
1658 static const WCHAR expected_display_name
[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1660 hr
= CreateItemMoniker(wszDelimeter1
, wszObjectName1
, &moniker1
);
1661 ok_ole_success(hr
, CreateItemMoniker
);
1662 hr
= CreateItemMoniker(wszDelimeter2
, wszObjectName2
, &moniker2
);
1663 ok_ole_success(hr
, CreateItemMoniker
);
1664 hr
= CreateGenericComposite(moniker1
, moniker2
, &moniker
);
1665 ok_ole_success(hr
, CreateGenericComposite
);
1667 test_moniker("generic composite moniker", moniker
,
1668 expected_gc_moniker_marshal_data
, sizeof(expected_gc_moniker_marshal_data
),
1669 expected_gc_moniker_saved_data
, sizeof(expected_gc_moniker_saved_data
),
1670 expected_gc_moniker_comparison_data
, sizeof(expected_gc_moniker_comparison_data
),
1671 expected_display_name
);
1675 hr
= IMoniker_Hash(moniker
, &hash
);
1676 ok_ole_success(hr
, IMoniker_Hash
);
1679 "Hash value != 0xd87, instead was 0x%08x\n",
1682 /* IsSystemMoniker test */
1684 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1685 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1687 ok(moniker_type
== MKSYS_GENERICCOMPOSITE
,
1688 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1691 hr
= CreateBindCtx(0, &bindctx
);
1692 ok_ole_success(hr
, CreateBindCtx
);
1694 /* IsRunning test */
1695 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1696 ok(hr
== E_INVALIDARG
, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr
);
1698 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1700 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1702 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1703 ok(hr
== MK_E_NOTBINDABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr
);
1705 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1707 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1709 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1710 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1712 IBindCtx_Release(bindctx
);
1714 hr
= IMoniker_Inverse(moniker
, &inverse
);
1715 ok_ole_success(hr
, IMoniker_Inverse
);
1716 IMoniker_Release(inverse
);
1718 IMoniker_Release(moniker
);
1721 static void test_pointer_moniker(void)
1733 LPOLESTR display_name
;
1737 hr
= CreatePointerMoniker((IUnknown
*)&Test_ClassFactory
, NULL
);
1738 ok(hr
== E_INVALIDARG
, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1740 hr
= CreatePointerMoniker((IUnknown
*)&Test_ClassFactory
, &moniker
);
1741 ok_ole_success(hr
, CreatePointerMoniker
);
1742 if (!moniker
) return;
1744 ok_more_than_one_lock();
1748 hr
= CreateBindCtx(0, &bindctx
);
1749 ok_ole_success(hr
, CreateBindCtx
);
1751 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1752 ok(hr
== E_NOTIMPL
, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1754 IBindCtx_Release(bindctx
);
1756 hr
= IMoniker_IsDirty(moniker
);
1757 ok(hr
== S_FALSE
, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr
);
1759 /* IROTData::GetComparisonData test */
1761 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1762 ok(hr
== E_NOINTERFACE
, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr
);
1766 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1767 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1769 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1770 ok(hr
== E_NOTIMPL
, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1772 IStream_Release(stream
);
1775 hr
= IMoniker_Hash(moniker
, &hash
);
1776 ok_ole_success(hr
, IMoniker_Hash
);
1777 ok(hash
== (DWORD
)&Test_ClassFactory
,
1778 "Hash value should have been 0x%08x, instead of 0x%08x\n",
1779 (DWORD
)&Test_ClassFactory
, hash
);
1781 /* IsSystemMoniker test */
1782 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1783 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1784 ok(moniker_type
== MKSYS_POINTERMONIKER
,
1785 "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1788 hr
= IMoniker_Inverse(moniker
, &inverse
);
1789 ok_ole_success(hr
, IMoniker_Inverse
);
1790 IMoniker_Release(inverse
);
1792 hr
= CreateBindCtx(0, &bindctx
);
1793 ok_ole_success(hr
, CreateBindCtx
);
1795 /* IsRunning test */
1796 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1797 ok(hr
== S_OK
, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr
);
1799 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1800 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1802 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1803 ok_ole_success(hr
, IMoniker_BindToObject
);
1804 IUnknown_Release(unknown
);
1806 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1807 ok_ole_success(hr
, IMoniker_BindToStorage
);
1808 IUnknown_Release(unknown
);
1810 IMoniker_Release(moniker
);
1814 hr
= CreatePointerMoniker(NULL
, &moniker
);
1815 ok_ole_success(hr
, CreatePointerMoniker
);
1817 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1818 ok(hr
== E_UNEXPECTED
, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr
);
1820 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1821 ok(hr
== E_UNEXPECTED
, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr
);
1823 IBindCtx_Release(bindctx
);
1825 IMoniker_Release(moniker
);
1828 static void test_bind_context(void)
1832 IEnumString
*pEnumString
;
1833 BIND_OPTS2 bind_opts
;
1834 HeapUnknown
*unknown
;
1835 HeapUnknown
*unknown2
;
1836 IUnknown
*param_obj
;
1838 static const WCHAR wszParamName
[] = {'G','e','m','m','a',0};
1839 static const WCHAR wszNonExistent
[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1841 hr
= CreateBindCtx(0, NULL
);
1842 ok(hr
== E_INVALIDARG
, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1844 hr
= CreateBindCtx(0xdeadbeef, &pBindCtx
);
1845 ok(hr
== E_INVALIDARG
, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1847 hr
= CreateBindCtx(0, &pBindCtx
);
1848 ok_ole_success(hr
, "CreateBindCtx");
1850 bind_opts
.cbStruct
= -1;
1851 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1852 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1853 ok(bind_opts
.cbStruct
== sizeof(bind_opts
) ||
1854 bind_opts
.cbStruct
== sizeof(bind_opts
) + sizeof(void*), /* Vista */
1855 "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1857 bind_opts
.cbStruct
= sizeof(BIND_OPTS
);
1858 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1859 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1860 ok(bind_opts
.cbStruct
== sizeof(BIND_OPTS
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1862 bind_opts
.cbStruct
= sizeof(bind_opts
);
1863 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1864 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1865 ok(bind_opts
.cbStruct
== sizeof(bind_opts
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1866 ok(bind_opts
.grfFlags
== 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts
.grfFlags
);
1867 ok(bind_opts
.grfMode
== STGM_READWRITE
, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts
.grfMode
);
1868 ok(bind_opts
.dwTickCountDeadline
== 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts
.dwTickCountDeadline
);
1869 ok(bind_opts
.dwTrackFlags
== 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts
.dwTrackFlags
);
1870 ok(bind_opts
.dwClassContext
== (CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
|CLSCTX_REMOTE_SERVER
),
1871 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts
.dwClassContext
);
1872 ok(bind_opts
.locale
== GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts
.locale
);
1873 ok(bind_opts
.pServerInfo
== NULL
, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts
.pServerInfo
);
1875 bind_opts
.cbStruct
= -1;
1876 hr
= IBindCtx_SetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1877 ok(hr
== E_INVALIDARG
, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1879 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, NULL
);
1880 ok(hr
== E_INVALIDARG
, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1882 unknown
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1883 unknown
->lpVtbl
= &HeapUnknown_Vtbl
;
1885 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, (IUnknown
*)&unknown
->lpVtbl
);
1886 ok_ole_success(hr
, "IBindCtx_RegisterObjectParam");
1888 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, ¶m_obj
);
1889 ok_ole_success(hr
, "IBindCtx_GetObjectParam");
1890 IUnknown_Release(param_obj
);
1892 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
, ¶m_obj
);
1893 ok(hr
== E_FAIL
, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1894 ok(param_obj
== NULL
, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj
);
1896 hr
= IBindCtx_RevokeObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
);
1897 ok(hr
== E_FAIL
, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1899 hr
= IBindCtx_EnumObjectParam(pBindCtx
, &pEnumString
);
1900 ok(hr
== E_NOTIMPL
, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1901 ok(!pEnumString
, "pEnumString should be NULL\n");
1903 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, NULL
);
1904 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound(NULL)");
1906 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, NULL
);
1907 ok(hr
== E_INVALIDARG
, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr
);
1909 unknown2
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1910 unknown2
->lpVtbl
= &HeapUnknown_Vtbl
;
1912 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1913 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound");
1915 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1916 ok_ole_success(hr
, "IBindCtx_RevokeObjectBound");
1918 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1919 ok(hr
== MK_E_NOTBOUND
, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr
);
1921 IBindCtx_Release(pBindCtx
);
1923 refs
= IUnknown_Release((IUnknown
*)&unknown
->lpVtbl
);
1924 ok(!refs
, "object param should have been destroyed, instead of having %d refs\n", refs
);
1926 refs
= IUnknown_Release((IUnknown
*)&unknown2
->lpVtbl
);
1927 ok(!refs
, "bound object should have been destroyed, instead of having %d refs\n", refs
);
1930 static void test_save_load_filemoniker(void)
1935 ULARGE_INTEGER size
;
1936 LARGE_INTEGER zero_pos
, dead_pos
, nulls_pos
;
1937 DWORD some_val
= 0xFEDCBA98;
1940 /* see FileMonikerImpl_Save docs */
1941 zero_pos
.QuadPart
= 0;
1942 dead_pos
.QuadPart
= sizeof(WORD
) + sizeof(DWORD
) + (lstrlenW(wszFileName1
) + 1) + sizeof(WORD
);
1943 nulls_pos
.QuadPart
= dead_pos
.QuadPart
+ sizeof(WORD
);
1945 /* create the stream we're going to write to */
1946 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStm
);
1947 ok_ole_success(hr
, "CreateStreamOnHGlobal");
1949 size
.u
.LowPart
= 128;
1950 hr
= IStream_SetSize(pStm
, size
);
1951 ok_ole_success(hr
, "IStream_SetSize");
1953 /* create and save a moniker */
1954 hr
= CreateFileMoniker(wszFileName1
, &pMk
);
1955 ok_ole_success(hr
, "CreateFileMoniker");
1957 hr
= IMoniker_Save(pMk
, pStm
, TRUE
);
1958 ok_ole_success(hr
, "IMoniker_Save");
1960 hr
= IMoniker_Release(pMk
);
1961 ok_ole_success(hr
, "IMoniker_Release");
1963 /* overwrite the constants with various values */
1964 hr
= IStream_Seek(pStm
, zero_pos
, STREAM_SEEK_SET
, NULL
);
1965 ok_ole_success(hr
, "IStream_Seek");
1966 hr
= IStream_Write(pStm
, &some_val
, sizeof(WORD
), NULL
);
1967 ok_ole_success(hr
, "IStream_Write");
1969 hr
= IStream_Seek(pStm
, dead_pos
, STREAM_SEEK_SET
, NULL
);
1970 ok_ole_success(hr
, "IStream_Seek");
1971 hr
= IStream_Write(pStm
, &some_val
, sizeof(WORD
), NULL
);
1972 ok_ole_success(hr
, "IStream_Write");
1974 hr
= IStream_Seek(pStm
, nulls_pos
, STREAM_SEEK_SET
, NULL
);
1975 ok_ole_success(hr
, "IStream_Seek");
1976 for(i
= 0; i
< 5; ++i
){
1977 hr
= IStream_Write(pStm
, &some_val
, sizeof(DWORD
), NULL
);
1978 ok_ole_success(hr
, "IStream_Write");
1981 /* go back to the start of the stream */
1982 hr
= IStream_Seek(pStm
, zero_pos
, STREAM_SEEK_SET
, NULL
);
1983 ok_ole_success(hr
, "IStream_Seek");
1985 /* create a new moniker and load into it */
1986 hr
= CreateFileMoniker(wszFileName1
, &pMk
);
1987 ok_ole_success(hr
, "CreateFileMoniker");
1989 hr
= IMoniker_Load(pMk
, pStm
);
1990 ok_ole_success(hr
, "IMoniker_Load");
1992 hr
= IMoniker_Release(pMk
);
1993 ok_ole_success(hr
, "IMoniker_Release");
1995 hr
= IStream_Release(pStm
);
1996 ok_ole_success(hr
, "IStream_Release");
2001 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2004 test_ROT_multiple_entries();
2005 test_MkParseDisplayName();
2006 test_class_moniker();
2007 test_file_monikers();
2008 test_item_moniker();
2009 test_anti_moniker();
2010 test_generic_composite_moniker();
2011 test_pointer_moniker();
2012 test_save_load_filemoniker();
2014 /* FIXME: test moniker creation funcs and parsing other moniker formats */
2016 test_bind_context();