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 HRESULT WINAPI
Test_IClassFactory_QueryInterface(
90 if (ppvObj
== NULL
) return E_POINTER
;
92 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
93 IsEqualGUID(riid
, &IID_IClassFactory
))
95 *ppvObj
= (LPVOID
)iface
;
96 IClassFactory_AddRef(iface
);
101 return E_NOINTERFACE
;
104 static ULONG WINAPI
Test_IClassFactory_AddRef(LPCLASSFACTORY iface
)
107 return 2; /* non-heap-based object */
110 static ULONG WINAPI
Test_IClassFactory_Release(LPCLASSFACTORY iface
)
113 return 1; /* non-heap-based object */
116 static HRESULT WINAPI
Test_IClassFactory_CreateInstance(
117 LPCLASSFACTORY iface
,
125 static HRESULT WINAPI
Test_IClassFactory_LockServer(
126 LPCLASSFACTORY iface
,
132 static const IClassFactoryVtbl TestClassFactory_Vtbl
=
134 Test_IClassFactory_QueryInterface
,
135 Test_IClassFactory_AddRef
,
136 Test_IClassFactory_Release
,
137 Test_IClassFactory_CreateInstance
,
138 Test_IClassFactory_LockServer
141 static IClassFactory Test_ClassFactory
= { &TestClassFactory_Vtbl
};
145 const IUnknownVtbl
*lpVtbl
;
149 static HRESULT WINAPI
HeapUnknown_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
151 if (IsEqualIID(riid
, &IID_IUnknown
))
153 IUnknown_AddRef(iface
);
154 *ppv
= (LPVOID
)iface
;
158 return E_NOINTERFACE
;
161 static ULONG WINAPI
HeapUnknown_AddRef(IUnknown
*iface
)
163 HeapUnknown
*This
= (HeapUnknown
*)iface
;
164 return InterlockedIncrement((LONG
*)&This
->refs
);
167 static ULONG WINAPI
HeapUnknown_Release(IUnknown
*iface
)
169 HeapUnknown
*This
= (HeapUnknown
*)iface
;
170 ULONG refs
= InterlockedDecrement((LONG
*)&This
->refs
);
171 if (!refs
) HeapFree(GetProcessHeap(), 0, This
);
175 static const IUnknownVtbl HeapUnknown_Vtbl
=
177 HeapUnknown_QueryInterface
,
182 static HRESULT WINAPI
183 MonikerNoROTData_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
190 if (IsEqualIID(&IID_IUnknown
, riid
) ||
191 IsEqualIID(&IID_IPersist
, riid
) ||
192 IsEqualIID(&IID_IPersistStream
,riid
) ||
193 IsEqualIID(&IID_IMoniker
, riid
))
195 if (IsEqualIID(&IID_IROTData
, riid
))
196 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
199 return E_NOINTERFACE
;
201 IMoniker_AddRef(iface
);
207 Moniker_AddRef(IMoniker
* iface
)
213 Moniker_Release(IMoniker
* iface
)
218 static HRESULT WINAPI
219 Moniker_GetClassID(IMoniker
* iface
, CLSID
*pClassID
)
221 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
223 *pClassID
= CLSID_TestMoniker
;
228 static HRESULT WINAPI
229 Moniker_IsDirty(IMoniker
* iface
)
231 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
236 static HRESULT WINAPI
237 Moniker_Load(IMoniker
* iface
, IStream
* pStm
)
239 CHECK_EXPECTED_METHOD("Moniker_Load");
243 static HRESULT WINAPI
244 Moniker_Save(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
)
246 CHECK_EXPECTED_METHOD("Moniker_Save");
250 static HRESULT WINAPI
251 Moniker_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
253 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
257 static HRESULT WINAPI
258 Moniker_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
259 REFIID riid
, VOID
** ppvResult
)
261 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
265 static HRESULT WINAPI
266 Moniker_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
267 REFIID riid
, VOID
** ppvObject
)
269 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
273 static HRESULT WINAPI
274 Moniker_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
275 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
277 CHECK_EXPECTED_METHOD("Moniker_Reduce");
279 if (ppmkReduced
==NULL
)
282 IMoniker_AddRef(iface
);
286 return MK_S_REDUCED_TO_SELF
;
289 static HRESULT WINAPI
290 Moniker_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
291 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
293 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
297 static HRESULT WINAPI
298 Moniker_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
300 CHECK_EXPECTED_METHOD("Moniker_Enum");
302 if (ppenumMoniker
== NULL
)
305 *ppenumMoniker
= NULL
;
310 static HRESULT WINAPI
311 Moniker_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
313 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
317 static HRESULT WINAPI
318 Moniker_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
320 CHECK_EXPECTED_METHOD("Moniker_Hash");
324 static HRESULT WINAPI
325 Moniker_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
326 IMoniker
* pmkNewlyRunning
)
328 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
332 static HRESULT WINAPI
333 Moniker_GetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
,
334 IMoniker
* pmkToLeft
, FILETIME
* pFileTime
)
336 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
340 static HRESULT WINAPI
341 Moniker_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
343 CHECK_EXPECTED_METHOD("Moniker_Inverse");
347 static HRESULT WINAPI
348 Moniker_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
350 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
354 static HRESULT WINAPI
355 Moniker_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
357 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
361 static HRESULT WINAPI
362 Moniker_GetDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
363 IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
365 static const WCHAR wszDisplayName
[] = {'*','*','G','e','m','m','a',0};
366 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
367 *ppszDisplayName
= (LPOLESTR
)CoTaskMemAlloc(sizeof(wszDisplayName
));
368 memcpy(*ppszDisplayName
, wszDisplayName
, sizeof(wszDisplayName
));
372 static HRESULT WINAPI
373 Moniker_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
374 LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
)
376 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
380 static HRESULT WINAPI
381 Moniker_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
383 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
388 (*pwdMksys
)=MKSYS_NONE
;
393 static const IMonikerVtbl MonikerNoROTDataVtbl
=
395 MonikerNoROTData_QueryInterface
,
403 Moniker_BindToObject
,
404 Moniker_BindToStorage
,
411 Moniker_GetTimeOfLastChange
,
413 Moniker_CommonPrefixWith
,
414 Moniker_RelativePathTo
,
415 Moniker_GetDisplayName
,
416 Moniker_ParseDisplayName
,
417 Moniker_IsSystemMoniker
420 static IMoniker MonikerNoROTData
= { &MonikerNoROTDataVtbl
};
422 static IMoniker Moniker
;
424 static HRESULT WINAPI
425 ROTData_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
427 return IMoniker_QueryInterface(&Moniker
, riid
, ppvObject
);
431 ROTData_AddRef(IROTData
*iface
)
437 ROTData_Release(IROTData
* iface
)
442 static HRESULT WINAPI
443 ROTData_GetComparisonData(IROTData
* iface
, BYTE
* pbData
,
444 ULONG cbMax
, ULONG
* pcbData
)
446 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
449 if (cbMax
< *pcbData
)
450 return E_OUTOFMEMORY
;
457 static IROTDataVtbl ROTDataVtbl
=
459 ROTData_QueryInterface
,
462 ROTData_GetComparisonData
465 static IROTData ROTData
= { &ROTDataVtbl
};
467 static HRESULT WINAPI
468 Moniker_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
475 if (IsEqualIID(&IID_IUnknown
, riid
) ||
476 IsEqualIID(&IID_IPersist
, riid
) ||
477 IsEqualIID(&IID_IPersistStream
,riid
) ||
478 IsEqualIID(&IID_IMoniker
, riid
))
480 if (IsEqualIID(&IID_IROTData
, riid
))
482 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
483 *ppvObject
= &ROTData
;
487 return E_NOINTERFACE
;
489 IMoniker_AddRef(iface
);
494 static const IMonikerVtbl MonikerVtbl
=
496 Moniker_QueryInterface
,
504 Moniker_BindToObject
,
505 Moniker_BindToStorage
,
512 Moniker_GetTimeOfLastChange
,
514 Moniker_CommonPrefixWith
,
515 Moniker_RelativePathTo
,
516 Moniker_GetDisplayName
,
517 Moniker_ParseDisplayName
,
518 Moniker_IsSystemMoniker
521 static IMoniker Moniker
= { &MonikerVtbl
};
523 static void test_ROT(void)
525 static const WCHAR wszFileName
[] = {'B','E','2','0','E','2','F','5','-',
526 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
527 '2','0','4','6','E','5','8','6','C','9','2','5',0};
529 IMoniker
*pMoniker
= NULL
;
530 IRunningObjectTable
*pROT
= NULL
;
532 static const char *methods_register_no_ROTData
[] =
535 "Moniker_GetTimeOfLastChange",
536 "Moniker_QueryInterface(IID_IROTData)",
537 "Moniker_GetDisplayName",
538 "Moniker_GetClassID",
541 static const char *methods_register
[] =
544 "Moniker_GetTimeOfLastChange",
545 "Moniker_QueryInterface(IID_IROTData)",
546 "ROTData_GetComparisonData",
549 static const char *methods_isrunning_no_ROTData
[] =
552 "Moniker_QueryInterface(IID_IROTData)",
553 "Moniker_GetDisplayName",
554 "Moniker_GetClassID",
557 static const char *methods_isrunning
[] =
560 "Moniker_QueryInterface(IID_IROTData)",
561 "ROTData_GetComparisonData",
567 hr
= GetRunningObjectTable(0, &pROT
);
568 ok_ole_success(hr
, GetRunningObjectTable
);
570 expected_method_list
= methods_register_no_ROTData
;
571 /* try with our own moniker that doesn't support IROTData */
572 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
573 (IUnknown
*)&Test_ClassFactory
, &MonikerNoROTData
, &dwCookie
);
574 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
575 ok_ole_success(hr
, IRunningObjectTable_Register
);
577 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
579 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
580 ok_more_than_one_lock();
583 expected_method_list
= methods_isrunning_no_ROTData
;
584 hr
= IRunningObjectTable_IsRunning(pROT
, &MonikerNoROTData
);
585 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
586 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
588 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
590 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
591 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
592 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
597 expected_method_list
= methods_register
;
598 /* try with our own moniker */
599 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
600 (IUnknown
*)&Test_ClassFactory
, &Moniker
, &dwCookie
);
601 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
602 ok_ole_success(hr
, IRunningObjectTable_Register
);
604 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
606 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
607 ok_more_than_one_lock();
610 expected_method_list
= methods_isrunning
;
611 hr
= IRunningObjectTable_IsRunning(pROT
, &Moniker
);
612 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
613 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 todo_wine
{ /* only fails because of lack of IMoniker marshaling */
619 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
624 hr
= CreateFileMoniker(wszFileName
, &pMoniker
);
625 ok_ole_success(hr
, CreateClassMoniker
);
628 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
,
629 pMoniker
, &dwCookie
);
630 ok_ole_success(hr
, IRunningObjectTable_Register
);
632 ok_more_than_one_lock();
634 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
635 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
639 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
640 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
641 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
642 ok_ole_success(hr
, IRunningObjectTable_Register
);
644 ok_more_than_one_lock();
646 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
647 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
651 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
652 /* only succeeds when process is started by SCM and has LocalService
653 * or RunAs AppId values */
654 hr
= IRunningObjectTable_Register(pROT
,
655 ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
,
656 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
658 ok(hr
== CO_E_WRONG_SERVER_IDENTITY
, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr
);
661 hr
= IRunningObjectTable_Register(pROT
, 0xdeadbeef,
662 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
663 ok(hr
== E_INVALIDARG
, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
665 IMoniker_Release(pMoniker
);
667 IRunningObjectTable_Release(pROT
);
670 static HRESULT WINAPI
ParseDisplayName_QueryInterface(IParseDisplayName
*iface
, REFIID riid
, void **ppv
)
672 if (IsEqualIID(riid
, &IID_IUnknown
) ||
673 IsEqualIID(riid
, &IID_IParseDisplayName
))
676 IUnknown_AddRef(iface
);
680 return E_NOINTERFACE
;
683 static ULONG WINAPI
ParseDisplayName_AddRef(IParseDisplayName
*iface
)
688 static ULONG WINAPI
ParseDisplayName_Release(IParseDisplayName
*iface
)
693 static LPCWSTR expected_display_name
;
695 static HRESULT WINAPI
ParseDisplayName_ParseDisplayName(IParseDisplayName
*iface
,
697 LPOLESTR pszDisplayName
,
701 char display_nameA
[256];
702 WideCharToMultiByte(CP_ACP
, 0, pszDisplayName
, -1, display_nameA
, sizeof(display_nameA
), NULL
, NULL
);
703 ok(!lstrcmpW(pszDisplayName
, expected_display_name
), "unexpected display name \"%s\"\n", display_nameA
);
704 ok(pszDisplayName
== expected_display_name
, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
705 *pchEaten
= lstrlenW(pszDisplayName
);
706 return CreateAntiMoniker(ppmkOut
);
709 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl
=
711 ParseDisplayName_QueryInterface
,
712 ParseDisplayName_AddRef
,
713 ParseDisplayName_Release
,
714 ParseDisplayName_ParseDisplayName
717 static IParseDisplayName ParseDisplayName
= { &ParseDisplayName_Vtbl
};
719 static int count_moniker_matches(IBindCtx
* pbc
, IEnumMoniker
* spEM
)
721 IMoniker
* spMoniker
;
722 int monCnt
=0, matchCnt
=0;
724 while ((IEnumMoniker_Next(spEM
, 1, &spMoniker
, NULL
)==S_OK
))
729 hr
=IMoniker_GetDisplayName(spMoniker
, pbc
, NULL
, &szDisplayn
);
732 if (!lstrcmpiW(szDisplayn
, wszFileName1
) || !lstrcmpiW(szDisplayn
, wszFileName2
))
734 CoTaskMemFree(szDisplayn
);
737 trace("Total number of monikers is %i\n", monCnt
);
741 static void test_MkParseDisplayName(void)
743 IBindCtx
* pbc
= NULL
;
745 IMoniker
* pmk
= NULL
;
746 IMoniker
* pmk1
= NULL
;
747 IMoniker
* pmk2
= NULL
;
750 IUnknown
* object
= NULL
;
754 IEnumMoniker
*spEM1
= NULL
;
755 IEnumMoniker
*spEM2
= NULL
;
756 IEnumMoniker
*spEM3
= NULL
;
762 IRunningObjectTable
* pprot
=NULL
;
764 /* CLSID of My Computer */
765 static const WCHAR wszDisplayName
[] = {'c','l','s','i','d',':',
766 '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};
767 static const WCHAR wszDisplayNameClsid
[] = {'c','l','s','i','d',':',0};
768 static const WCHAR wszNonExistentProgId
[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
769 static const WCHAR wszDisplayNameRunning
[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
770 static const WCHAR wszDisplayNameProgId1
[] = {'S','t','d','F','o','n','t',':',0};
771 static const WCHAR wszDisplayNameProgId2
[] = {'@','S','t','d','F','o','n','t',0};
772 static const WCHAR wszDisplayNameProgIdFail
[] = {'S','t','d','F','o','n','t',0};
773 char szDisplayNameFile
[256];
774 WCHAR wszDisplayNameFile
[256];
776 hr
= CreateBindCtx(0, &pbc
);
777 ok_ole_success(hr
, CreateBindCtx
);
779 hr
= MkParseDisplayName(pbc
, wszNonExistentProgId
, &eaten
, &pmk
);
780 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
781 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
783 /* no special handling of "clsid:" without the string form of the clsid
785 hr
= MkParseDisplayName(pbc
, wszDisplayNameClsid
, &eaten
, &pmk
);
786 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
787 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
789 /* shows clsid has higher precedence than a running object */
790 hr
= CreateFileMoniker(wszDisplayName
, &pmk
);
791 ok_ole_success(hr
, CreateFileMoniker
);
792 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
793 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
794 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
795 ok_ole_success(hr
, IRunningObjectTable_Register
);
796 IMoniker_Release(pmk
);
798 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
799 ok_ole_success(hr
, MkParseDisplayName
);
802 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
803 ok(moniker_type
== MKSYS_CLASSMONIKER
, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type
);
804 IMoniker_Release(pmk
);
806 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
807 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
808 IRunningObjectTable_Release(pprot
);
810 hr
= CreateFileMoniker(wszDisplayNameRunning
, &pmk
);
811 ok_ole_success(hr
, CreateFileMoniker
);
812 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
813 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
814 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
815 ok_ole_success(hr
, IRunningObjectTable_Register
);
816 IMoniker_Release(pmk
);
818 hr
= MkParseDisplayName(pbc
, wszDisplayNameRunning
, &eaten
, &pmk
);
819 ok_ole_success(hr
, MkParseDisplayName
);
822 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
823 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
824 IMoniker_Release(pmk
);
826 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
827 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
828 IRunningObjectTable_Release(pprot
);
830 hr
= CoRegisterClassObject(&CLSID_StdFont
, (IUnknown
*)&ParseDisplayName
, CLSCTX_INPROC_SERVER
, REGCLS_MULTI_SEPARATE
, &pdwReg1
);
831 ok_ole_success(hr
, CoRegisterClassObject
);
833 expected_display_name
= wszDisplayNameProgId1
;
834 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId1
, &eaten
, &pmk
);
835 ok_ole_success(hr
, MkParseDisplayName
);
838 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
839 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
840 IMoniker_Release(pmk
);
843 expected_display_name
= wszDisplayNameProgId2
;
844 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId2
, &eaten
, &pmk
);
845 ok_ole_success(hr
, MkParseDisplayName
);
848 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
849 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
850 IMoniker_Release(pmk
);
853 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgIdFail
, &eaten
, &pmk
);
854 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
855 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
857 hr
= CoRevokeClassObject(pdwReg1
);
858 ok_ole_success(hr
, CoRevokeClassObject
);
860 GetSystemDirectoryA(szDisplayNameFile
, sizeof(szDisplayNameFile
));
861 strcat(szDisplayNameFile
, "\\kernel32.dll");
862 MultiByteToWideChar(CP_ACP
, 0, szDisplayNameFile
, -1, wszDisplayNameFile
, sizeof(wszDisplayNameFile
)/sizeof(wszDisplayNameFile
[0]));
863 hr
= MkParseDisplayName(pbc
, wszDisplayNameFile
, &eaten
, &pmk
);
864 ok_ole_success(hr
, MkParseDisplayName
);
867 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
868 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
869 IMoniker_Release(pmk
);
872 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
873 ok_ole_success(hr
, MkParseDisplayName
);
877 hr
= IMoniker_BindToObject(pmk
, pbc
, NULL
, &IID_IUnknown
, (LPVOID
*)&object
);
878 ok_ole_success(hr
, IMoniker_BindToObject
);
880 IUnknown_Release(object
);
882 IBindCtx_Release(pbc
);
884 /* Test the EnumMoniker interface */
885 hr
= CreateBindCtx(0, &pbc
);
886 ok_ole_success(hr
, CreateBindCtx
);
888 hr
= CreateFileMoniker(wszFileName1
, &pmk1
);
889 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
890 hr
= CreateFileMoniker(wszFileName2
, &pmk2
);
891 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
892 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
893 ok(hr
==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr
);
895 /* Check EnumMoniker before registering */
896 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM1
);
897 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
898 hr
= IEnumMoniker_QueryInterface(spEM1
, &IID_IUnknown
, (void*) &lpEM1
);
899 /* Register a couple of Monikers and check is ok */
900 ok(hr
==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr
, lpEM1
);
903 matchCnt
= count_moniker_matches(pbc
, spEM1
);
904 trace("Number of matches is %i\n", matchCnt
);
906 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
907 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk1
, &pdwReg1
);
908 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
909 hr
, pprot
, grflags
, lpEM1
, pmk1
, pdwReg1
);
911 trace("IROT::Register\n");
913 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
914 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk2
, &pdwReg2
);
915 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr
,
916 pprot
, grflags
, lpEM1
, pmk2
, pdwReg2
);
918 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM2
);
919 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
921 matchCnt
= count_moniker_matches(pbc
, spEM2
);
922 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
924 trace("IEnumMoniker::Clone\n");
925 IEnumMoniker_Clone(spEM2
, &spEM3
);
927 matchCnt
= count_moniker_matches(pbc
, spEM3
);
928 ok(matchCnt
==0, "Number of matches should be equal to 0 not %i\n", matchCnt
);
929 trace("IEnumMoniker::Reset\n");
930 IEnumMoniker_Reset(spEM3
);
932 matchCnt
= count_moniker_matches(pbc
, spEM3
);
933 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
935 IRunningObjectTable_Revoke(pprot
,pdwReg1
);
936 IRunningObjectTable_Revoke(pprot
,pdwReg2
);
937 IEnumMoniker_Release(spEM1
);
938 IEnumMoniker_Release(spEM1
);
939 IEnumMoniker_Release(spEM2
);
940 IEnumMoniker_Release(spEM3
);
941 IMoniker_Release(pmk1
);
942 IMoniker_Release(pmk2
);
943 IRunningObjectTable_Release(pprot
);
945 IBindCtx_Release(pbc
);
948 static const LARGE_INTEGER llZero
;
950 static const BYTE expected_class_moniker_marshal_data
[] =
952 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
953 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
954 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
955 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
956 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
957 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
958 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
959 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
963 static const BYTE expected_class_moniker_saved_data
[] =
965 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
966 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
970 static const BYTE expected_class_moniker_comparison_data
[] =
972 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
973 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
974 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
975 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
978 static const WCHAR expected_class_moniker_display_name
[] =
980 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
981 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
982 '0','0','0','0','4','6',':',0
985 static const BYTE expected_item_moniker_comparison_data
[] =
987 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
988 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
989 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
993 static const BYTE expected_item_moniker_saved_data
[] =
995 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
996 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
999 static const BYTE expected_item_moniker_marshal_data
[] =
1001 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1002 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1003 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1004 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1005 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1006 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1007 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1008 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1011 static const BYTE expected_anti_moniker_marshal_data
[] =
1013 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1014 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1015 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1016 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1017 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1018 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1019 0x01,0x00,0x00,0x00,
1022 static const BYTE expected_anti_moniker_saved_data
[] =
1024 0x01,0x00,0x00,0x00,
1027 static const BYTE expected_anti_moniker_comparison_data
[] =
1029 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1030 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1031 0x01,0x00,0x00,0x00,
1034 static const BYTE expected_gc_moniker_marshal_data
[] =
1036 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1037 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1038 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1039 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1040 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1041 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1042 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1043 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1044 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1045 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1046 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1047 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1048 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1049 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1050 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1051 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1052 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1053 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1054 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1055 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1056 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1057 0x00,0x57,0x69,0x6e,0x65,0x00,
1060 static const BYTE expected_gc_moniker_saved_data
[] =
1062 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1063 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1064 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1065 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1066 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1067 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1068 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1069 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1073 static const BYTE expected_gc_moniker_comparison_data
[] =
1075 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1076 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1077 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1078 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1079 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1080 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1081 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1082 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1083 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1086 static void test_moniker(
1087 const char *testname
, IMoniker
*moniker
,
1088 const BYTE
*expected_moniker_marshal_data
, unsigned int sizeof_expected_moniker_marshal_data
,
1089 const BYTE
*expected_moniker_saved_data
, unsigned int sizeof_expected_moniker_saved_data
,
1090 const BYTE
*expected_moniker_comparison_data
, unsigned int sizeof_expected_moniker_comparison_data
,
1091 LPCWSTR expected_display_name
)
1097 LPBYTE moniker_data
;
1102 IMoniker
* moniker_proxy
;
1103 LPOLESTR display_name
;
1106 hr
= IMoniker_IsDirty(moniker
);
1107 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1111 hr
= CreateBindCtx(0, &bindctx
);
1112 ok_ole_success(hr
, CreateBindCtx
);
1114 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1115 ok_ole_success(hr
, IMoniker_GetDisplayName
);
1116 ok(!lstrcmpW(display_name
, expected_display_name
), "%s: display name wasn't what was expected\n", testname
);
1118 CoTaskMemFree(display_name
);
1119 IBindCtx_Release(bindctx
);
1121 hr
= IMoniker_IsDirty(moniker
);
1122 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1124 /* IROTData::GetComparisonData test */
1126 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1127 ok_ole_success(hr
, IMoniker_QueryInterface_IID_IROTData
);
1129 hr
= IROTData_GetComparisonData(rotdata
, buffer
, sizeof(buffer
), &moniker_size
);
1130 ok_ole_success(hr
, IROTData_GetComparisonData
);
1132 if (hr
!= S_OK
) moniker_size
= 0;
1134 /* first check we have the right amount of data */
1135 ok(moniker_size
== sizeof_expected_moniker_comparison_data
,
1136 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1137 testname
, sizeof_expected_moniker_comparison_data
, moniker_size
);
1139 /* then do a byte-by-byte comparison */
1140 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_comparison_data
); i
++)
1142 if (expected_moniker_comparison_data
[i
] != buffer
[i
])
1149 ok(same
, "%s: Comparison data differs\n", testname
);
1152 for (i
= 0; i
< moniker_size
; i
++)
1154 if (i
% 8 == 0) printf(" ");
1155 printf("0x%02x,", buffer
[i
]);
1156 if (i
% 8 == 7) printf("\n");
1161 IROTData_Release(rotdata
);
1163 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1167 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1168 ok_ole_success(hr
, IMoniker_Save
);
1170 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1171 ok_ole_success(hr
, GetHGlobalFromStream
);
1173 moniker_size
= GlobalSize(hglobal
);
1175 moniker_data
= GlobalLock(hglobal
);
1177 /* first check we have the right amount of data */
1178 ok(moniker_size
== sizeof_expected_moniker_saved_data
,
1179 "%s: Size of saved data differs (expected %d, actual %d)\n",
1180 testname
, sizeof_expected_moniker_saved_data
, moniker_size
);
1182 /* then do a byte-by-byte comparison */
1183 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_saved_data
); i
++)
1185 if (expected_moniker_saved_data
[i
] != moniker_data
[i
])
1192 ok(same
, "%s: Saved data differs\n", testname
);
1195 for (i
= 0; i
< moniker_size
; i
++)
1197 if (i
% 8 == 0) printf(" ");
1198 printf("0x%02x,", moniker_data
[i
]);
1199 if (i
% 8 == 7) printf("\n");
1204 GlobalUnlock(hglobal
);
1206 IStream_Release(stream
);
1208 /* Marshaling tests */
1210 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1211 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1213 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1214 ok_ole_success(hr
, CoMarshalInterface
);
1216 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1217 ok_ole_success(hr
, GetHGlobalFromStream
);
1219 moniker_size
= GlobalSize(hglobal
);
1221 moniker_data
= GlobalLock(hglobal
);
1223 /* first check we have the right amount of data */
1224 ok(moniker_size
== sizeof_expected_moniker_marshal_data
,
1225 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1226 testname
, sizeof_expected_moniker_marshal_data
, moniker_size
);
1228 /* then do a byte-by-byte comparison */
1229 if (expected_moniker_marshal_data
)
1231 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_marshal_data
); i
++)
1233 if (expected_moniker_marshal_data
[i
] != moniker_data
[i
])
1241 ok(same
, "%s: Marshaled data differs\n", testname
);
1244 for (i
= 0; i
< moniker_size
; i
++)
1246 if (i
% 8 == 0) printf(" ");
1247 printf("0x%02x,", moniker_data
[i
]);
1248 if (i
% 8 == 7) printf("\n");
1253 GlobalUnlock(hglobal
);
1255 IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1256 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&moniker_proxy
);
1257 ok_ole_success(hr
, CoUnmarshalInterface
);
1259 IStream_Release(stream
);
1260 IMoniker_Release(moniker_proxy
);
1263 static void test_class_moniker(void)
1274 hr
= CreateClassMoniker(&CLSID_StdComponentCategoriesMgr
, &moniker
);
1275 ok_ole_success(hr
, CreateClassMoniker
);
1276 if (!moniker
) return;
1278 test_moniker("class moniker", moniker
,
1279 expected_class_moniker_marshal_data
, sizeof(expected_class_moniker_marshal_data
),
1280 expected_class_moniker_saved_data
, sizeof(expected_class_moniker_saved_data
),
1281 expected_class_moniker_comparison_data
, sizeof(expected_class_moniker_comparison_data
),
1282 expected_class_moniker_display_name
);
1286 hr
= IMoniker_Hash(moniker
, &hash
);
1287 ok_ole_success(hr
, IMoniker_Hash
);
1289 ok(hash
== CLSID_StdComponentCategoriesMgr
.Data1
,
1290 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1293 /* IsSystemMoniker test */
1295 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1296 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1298 ok(moniker_type
== MKSYS_CLASSMONIKER
,
1299 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1302 hr
= CreateBindCtx(0, &bindctx
);
1303 ok_ole_success(hr
, CreateBindCtx
);
1305 /* IsRunning test */
1306 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1307 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1309 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1310 ok(hr
== MK_E_UNAVAILABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr
);
1312 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1313 ok_ole_success(hr
, IMoniker_BindToStorage
);
1314 IUnknown_Release(unknown
);
1316 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1317 ok_ole_success(hr
, IMoniker_BindToStorage
);
1318 IUnknown_Release(unknown
);
1320 IBindCtx_Release(bindctx
);
1322 hr
= IMoniker_Inverse(moniker
, &inverse
);
1323 ok_ole_success(hr
, IMoniker_Inverse
);
1324 IMoniker_Release(inverse
);
1326 IMoniker_Release(moniker
);
1329 static void test_file_moniker(WCHAR
* path
)
1332 IMoniker
*moniker1
= NULL
, *moniker2
= NULL
;
1335 hr
= CreateFileMoniker(path
, &moniker1
);
1336 ok_ole_success(hr
, CreateFileMoniker
);
1338 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1341 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker1
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1342 ok_ole_success(hr
, CoMarshalInterface
);
1345 hr
= IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1346 ok_ole_success(hr
, IStream_Seek
);
1349 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void**)&moniker2
);
1350 ok_ole_success(hr
, CoUnmarshalInterface
);
1352 hr
= IMoniker_IsEqual(moniker1
, moniker2
);
1353 ok_ole_success(hr
, IsEqual
);
1355 IStream_Release(stream
);
1357 IMoniker_Release(moniker1
);
1359 IMoniker_Release(moniker2
);
1362 static void test_file_monikers(void)
1364 static WCHAR wszFile
[][30] = {
1365 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1366 {'\\', '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},
1367 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1368 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1369 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1370 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1371 * U+0100 .. = Latin extended-A
1373 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1378 trace("ACP is %u\n", GetACP());
1380 for (i
= 0; i
< COUNTOF(wszFile
); ++i
)
1383 for (j
= lstrlenW(wszFile
[i
]); j
> 0; --j
)
1386 test_file_moniker(wszFile
[i
]);
1391 static void test_item_moniker(void)
1400 static const WCHAR wszDelimeter
[] = {'!',0};
1401 static const WCHAR wszObjectName
[] = {'T','e','s','t',0};
1402 static const WCHAR expected_display_name
[] = { '!','T','e','s','t',0 };
1404 hr
= CreateItemMoniker(wszDelimeter
, wszObjectName
, &moniker
);
1405 ok_ole_success(hr
, CreateItemMoniker
);
1407 test_moniker("item moniker", moniker
,
1408 expected_item_moniker_marshal_data
, sizeof(expected_item_moniker_marshal_data
),
1409 expected_item_moniker_saved_data
, sizeof(expected_item_moniker_saved_data
),
1410 expected_item_moniker_comparison_data
, sizeof(expected_item_moniker_comparison_data
),
1411 expected_display_name
);
1415 hr
= IMoniker_Hash(moniker
, &hash
);
1416 ok_ole_success(hr
, IMoniker_Hash
);
1419 "Hash value != 0x73c, instead was 0x%08x\n",
1422 /* IsSystemMoniker test */
1424 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1425 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1427 ok(moniker_type
== MKSYS_ITEMMONIKER
,
1428 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1431 hr
= CreateBindCtx(0, &bindctx
);
1432 ok_ole_success(hr
, CreateBindCtx
);
1434 /* IsRunning test */
1435 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1436 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1438 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1439 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1441 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1442 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1444 IBindCtx_Release(bindctx
);
1446 hr
= IMoniker_Inverse(moniker
, &inverse
);
1447 ok_ole_success(hr
, IMoniker_Inverse
);
1448 IMoniker_Release(inverse
);
1450 IMoniker_Release(moniker
);
1453 static void test_anti_moniker(void)
1463 static const WCHAR expected_display_name
[] = { '\\','.','.',0 };
1465 hr
= CreateAntiMoniker(&moniker
);
1466 ok_ole_success(hr
, CreateAntiMoniker
);
1467 if (!moniker
) return;
1469 test_moniker("anti moniker", moniker
,
1470 expected_anti_moniker_marshal_data
, sizeof(expected_anti_moniker_marshal_data
),
1471 expected_anti_moniker_saved_data
, sizeof(expected_anti_moniker_saved_data
),
1472 expected_anti_moniker_comparison_data
, sizeof(expected_anti_moniker_comparison_data
),
1473 expected_display_name
);
1476 hr
= IMoniker_Hash(moniker
, &hash
);
1477 ok_ole_success(hr
, IMoniker_Hash
);
1478 ok(hash
== 0x80000001,
1479 "Hash value != 0x80000001, instead was 0x%08x\n",
1482 /* IsSystemMoniker test */
1483 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1484 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1485 ok(moniker_type
== MKSYS_ANTIMONIKER
,
1486 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1489 hr
= IMoniker_Inverse(moniker
, &inverse
);
1490 ok(hr
== MK_E_NOINVERSE
, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr
);
1491 ok(inverse
== NULL
, "inverse should have been set to NULL instead of %p\n", inverse
);
1493 hr
= CreateBindCtx(0, &bindctx
);
1494 ok_ole_success(hr
, CreateBindCtx
);
1496 /* IsRunning test */
1497 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1498 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1500 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1501 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1503 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1504 ok(hr
== E_NOTIMPL
, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr
);
1506 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1507 ok(hr
== E_NOTIMPL
, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr
);
1509 IBindCtx_Release(bindctx
);
1511 IMoniker_Release(moniker
);
1514 static void test_generic_composite_moniker(void)
1526 static const WCHAR wszDelimeter1
[] = {'!',0};
1527 static const WCHAR wszObjectName1
[] = {'T','e','s','t',0};
1528 static const WCHAR wszDelimeter2
[] = {'#',0};
1529 static const WCHAR wszObjectName2
[] = {'W','i','n','e',0};
1530 static const WCHAR expected_display_name
[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1532 hr
= CreateItemMoniker(wszDelimeter1
, wszObjectName1
, &moniker1
);
1533 ok_ole_success(hr
, CreateItemMoniker
);
1534 hr
= CreateItemMoniker(wszDelimeter2
, wszObjectName2
, &moniker2
);
1535 ok_ole_success(hr
, CreateItemMoniker
);
1536 hr
= CreateGenericComposite(moniker1
, moniker2
, &moniker
);
1537 ok_ole_success(hr
, CreateGenericComposite
);
1539 test_moniker("generic composite moniker", moniker
,
1540 expected_gc_moniker_marshal_data
, sizeof(expected_gc_moniker_marshal_data
),
1541 expected_gc_moniker_saved_data
, sizeof(expected_gc_moniker_saved_data
),
1542 expected_gc_moniker_comparison_data
, sizeof(expected_gc_moniker_comparison_data
),
1543 expected_display_name
);
1547 hr
= IMoniker_Hash(moniker
, &hash
);
1548 ok_ole_success(hr
, IMoniker_Hash
);
1551 "Hash value != 0xd87, instead was 0x%08x\n",
1554 /* IsSystemMoniker test */
1556 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1557 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1559 ok(moniker_type
== MKSYS_GENERICCOMPOSITE
,
1560 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1563 hr
= CreateBindCtx(0, &bindctx
);
1564 ok_ole_success(hr
, CreateBindCtx
);
1566 /* IsRunning test */
1567 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1569 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1571 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1572 ok(hr
== MK_E_NOTBINDABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr
);
1574 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1576 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1579 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1580 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1582 IBindCtx_Release(bindctx
);
1584 hr
= IMoniker_Inverse(moniker
, &inverse
);
1585 ok_ole_success(hr
, IMoniker_Inverse
);
1586 IMoniker_Release(inverse
);
1588 IMoniker_Release(moniker
);
1591 static void test_bind_context(void)
1595 IEnumString
*pEnumString
;
1596 BIND_OPTS2 bind_opts
;
1597 HeapUnknown
*unknown
;
1598 HeapUnknown
*unknown2
;
1599 IUnknown
*param_obj
;
1601 static const WCHAR wszParamName
[] = {'G','e','m','m','a',0};
1602 static const WCHAR wszNonExistent
[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1604 hr
= CreateBindCtx(0, NULL
);
1605 ok(hr
== E_INVALIDARG
, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1607 hr
= CreateBindCtx(0xdeadbeef, &pBindCtx
);
1608 ok(hr
== E_INVALIDARG
, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1610 hr
= CreateBindCtx(0, &pBindCtx
);
1611 ok_ole_success(hr
, "CreateBindCtx");
1613 bind_opts
.cbStruct
= -1;
1614 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1615 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1616 ok(bind_opts
.cbStruct
== sizeof(bind_opts
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1618 bind_opts
.cbStruct
= sizeof(BIND_OPTS
);
1619 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1620 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1621 ok(bind_opts
.cbStruct
== sizeof(BIND_OPTS
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1623 bind_opts
.cbStruct
= sizeof(bind_opts
);
1624 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1625 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1626 ok(bind_opts
.cbStruct
== sizeof(bind_opts
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1627 ok(bind_opts
.grfFlags
== 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts
.grfFlags
);
1628 ok(bind_opts
.grfMode
== STGM_READWRITE
, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts
.grfMode
);
1629 ok(bind_opts
.dwTickCountDeadline
== 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts
.dwTickCountDeadline
);
1630 ok(bind_opts
.dwTrackFlags
== 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts
.dwTrackFlags
);
1631 ok(bind_opts
.dwClassContext
== (CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
|CLSCTX_REMOTE_SERVER
),
1632 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts
.dwClassContext
);
1633 ok(bind_opts
.locale
== GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts
.locale
);
1634 ok(bind_opts
.pServerInfo
== NULL
, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts
.pServerInfo
);
1636 bind_opts
.cbStruct
= -1;
1637 hr
= IBindCtx_SetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1638 ok(hr
== E_INVALIDARG
, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1640 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, NULL
);
1641 ok(hr
== E_INVALIDARG
, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1643 unknown
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1644 unknown
->lpVtbl
= &HeapUnknown_Vtbl
;
1646 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, (IUnknown
*)&unknown
->lpVtbl
);
1647 ok_ole_success(hr
, "IBindCtx_RegisterObjectParam");
1649 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, ¶m_obj
);
1650 ok_ole_success(hr
, "IBindCtx_GetObjectParam");
1651 IUnknown_Release(param_obj
);
1653 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
, ¶m_obj
);
1654 ok(hr
== E_FAIL
, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1655 ok(param_obj
== NULL
, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj
);
1657 hr
= IBindCtx_RevokeObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
);
1658 ok(hr
== E_FAIL
, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1660 hr
= IBindCtx_EnumObjectParam(pBindCtx
, &pEnumString
);
1661 ok(hr
== E_NOTIMPL
, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1662 ok(!pEnumString
, "pEnumString should be NULL\n");
1664 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, NULL
);
1665 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound(NULL)");
1667 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, NULL
);
1668 ok(hr
== E_INVALIDARG
, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr
);
1670 unknown2
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1671 unknown2
->lpVtbl
= &HeapUnknown_Vtbl
;
1673 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1674 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound");
1676 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1677 ok_ole_success(hr
, "IBindCtx_RevokeObjectBound");
1679 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, (IUnknown
*)&unknown2
->lpVtbl
);
1680 ok(hr
== MK_E_NOTBOUND
, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr
);
1682 IBindCtx_Release(pBindCtx
);
1684 refs
= IUnknown_Release((IUnknown
*)&unknown
->lpVtbl
);
1685 ok(!refs
, "object param should have been destroyed, instead of having %d refs\n", refs
);
1687 refs
= IUnknown_Release((IUnknown
*)&unknown2
->lpVtbl
);
1688 ok(!refs
, "bound object should have been destroyed, instead of having %d refs\n", refs
);
1693 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1696 test_MkParseDisplayName();
1697 test_class_moniker();
1698 test_file_monikers();
1699 test_item_moniker();
1700 test_anti_moniker();
1701 test_generic_composite_moniker();
1703 /* FIXME: test moniker creation funcs and parsing other moniker formats */
1705 test_bind_context();