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
21 #define WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
36 //#include "objbase.h"
38 //#include "initguid.h"
42 #include <wine/test.h>
44 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
45 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
46 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
47 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
49 #define CHECK_EXPECTED_METHOD(method_name) \
51 trace("%s\n", method_name); \
52 ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
53 if (*expected_method_list) \
55 ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
56 *expected_method_list, method_name); \
57 expected_method_list++; \
61 static char const * const *expected_method_list
;
62 static const WCHAR wszFileName1
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
63 static const WCHAR wszFileName2
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
65 static const CLSID CLSID_TestMoniker
=
66 { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
70 {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
75 static void LockModule(void)
77 InterlockedIncrement(&cLocks
);
80 static void UnlockModule(void)
82 InterlockedDecrement(&cLocks
);
85 static SIZE_T
round_global_size(SIZE_T size
)
87 static SIZE_T global_size_alignment
= -1;
88 if (global_size_alignment
== -1)
90 void *p
= GlobalAlloc(GMEM_FIXED
, 1);
91 global_size_alignment
= GlobalSize(p
);
95 return ((size
+ global_size_alignment
- 1) & ~(global_size_alignment
- 1));
98 static DWORD external_connections
;
100 static HRESULT WINAPI
ExternalConnection_QueryInterface(IExternalConnection
*iface
, REFIID riid
, void **ppv
)
102 ok(0, "unexpected call\n");
104 return E_NOINTERFACE
;
107 static ULONG WINAPI
ExternalConnection_AddRef(IExternalConnection
*iface
)
112 static ULONG WINAPI
ExternalConnection_Release(IExternalConnection
*iface
)
117 static DWORD WINAPI
ExternalConnection_AddConnection(IExternalConnection
*iface
, DWORD extconn
, DWORD reserved
)
119 trace("add connection\n");
121 ok(extconn
== EXTCONN_STRONG
, "extconn = %d\n", extconn
);
122 ok(!reserved
, "reserved = %x\n", reserved
);
123 return ++external_connections
;
126 static DWORD WINAPI
ExternalConnection_ReleaseConnection(IExternalConnection
*iface
, DWORD extconn
,
127 DWORD reserved
, BOOL fLastReleaseCloses
)
129 trace("release connection\n");
131 ok(extconn
== EXTCONN_STRONG
, "extconn = %d\n", extconn
);
132 ok(!reserved
, "reserved = %x\n", reserved
);
134 return --external_connections
;
137 static const IExternalConnectionVtbl ExternalConnectionVtbl
= {
138 ExternalConnection_QueryInterface
,
139 ExternalConnection_AddRef
,
140 ExternalConnection_Release
,
141 ExternalConnection_AddConnection
,
142 ExternalConnection_ReleaseConnection
145 static IExternalConnection ExternalConnection
= { &ExternalConnectionVtbl
};
147 static HRESULT WINAPI
Test_IClassFactory_QueryInterface(
148 LPCLASSFACTORY iface
,
152 if (ppvObj
== NULL
) return E_POINTER
;
154 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
155 IsEqualGUID(riid
, &IID_IClassFactory
))
158 IClassFactory_AddRef(iface
);
162 if(IsEqualGUID(riid
, &IID_IExternalConnection
)) {
163 *ppvObj
= &ExternalConnection
;
168 return E_NOINTERFACE
;
171 static ULONG WINAPI
Test_IClassFactory_AddRef(LPCLASSFACTORY iface
)
174 return 2; /* non-heap-based object */
177 static ULONG WINAPI
Test_IClassFactory_Release(LPCLASSFACTORY iface
)
180 return 1; /* non-heap-based object */
183 static HRESULT WINAPI
Test_IClassFactory_CreateInstance(
184 LPCLASSFACTORY iface
,
192 static HRESULT WINAPI
Test_IClassFactory_LockServer(
193 LPCLASSFACTORY iface
,
199 static const IClassFactoryVtbl TestClassFactory_Vtbl
=
201 Test_IClassFactory_QueryInterface
,
202 Test_IClassFactory_AddRef
,
203 Test_IClassFactory_Release
,
204 Test_IClassFactory_CreateInstance
,
205 Test_IClassFactory_LockServer
208 static IClassFactory Test_ClassFactory
= { &TestClassFactory_Vtbl
};
212 IUnknown IUnknown_iface
;
216 static inline HeapUnknown
*impl_from_IUnknown(IUnknown
*iface
)
218 return CONTAINING_RECORD(iface
, HeapUnknown
, IUnknown_iface
);
221 static HRESULT WINAPI
HeapUnknown_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
223 if (IsEqualIID(riid
, &IID_IUnknown
))
225 IUnknown_AddRef(iface
);
230 return E_NOINTERFACE
;
233 static ULONG WINAPI
HeapUnknown_AddRef(IUnknown
*iface
)
235 HeapUnknown
*This
= impl_from_IUnknown(iface
);
236 return InterlockedIncrement((LONG
*)&This
->refs
);
239 static ULONG WINAPI
HeapUnknown_Release(IUnknown
*iface
)
241 HeapUnknown
*This
= impl_from_IUnknown(iface
);
242 ULONG refs
= InterlockedDecrement((LONG
*)&This
->refs
);
243 if (!refs
) HeapFree(GetProcessHeap(), 0, This
);
247 static const IUnknownVtbl HeapUnknown_Vtbl
=
249 HeapUnknown_QueryInterface
,
254 static HRESULT WINAPI
255 MonikerNoROTData_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
262 if (IsEqualIID(&IID_IUnknown
, riid
) ||
263 IsEqualIID(&IID_IPersist
, riid
) ||
264 IsEqualIID(&IID_IPersistStream
,riid
) ||
265 IsEqualIID(&IID_IMoniker
, riid
))
267 if (IsEqualIID(&IID_IROTData
, riid
))
268 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
271 return E_NOINTERFACE
;
273 IMoniker_AddRef(iface
);
279 Moniker_AddRef(IMoniker
* iface
)
285 Moniker_Release(IMoniker
* iface
)
290 static HRESULT WINAPI
291 Moniker_GetClassID(IMoniker
* iface
, CLSID
*pClassID
)
293 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
295 *pClassID
= CLSID_TestMoniker
;
300 static HRESULT WINAPI
301 Moniker_IsDirty(IMoniker
* iface
)
303 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
308 static HRESULT WINAPI
309 Moniker_Load(IMoniker
* iface
, IStream
* pStm
)
311 CHECK_EXPECTED_METHOD("Moniker_Load");
315 static HRESULT WINAPI
316 Moniker_Save(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
)
318 CHECK_EXPECTED_METHOD("Moniker_Save");
322 static HRESULT WINAPI
323 Moniker_GetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
325 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
329 static HRESULT WINAPI
330 Moniker_BindToObject(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
331 REFIID riid
, VOID
** ppvResult
)
333 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
337 static HRESULT WINAPI
338 Moniker_BindToStorage(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
339 REFIID riid
, VOID
** ppvObject
)
341 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
345 static HRESULT WINAPI
346 Moniker_Reduce(IMoniker
* iface
, IBindCtx
* pbc
, DWORD dwReduceHowFar
,
347 IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
349 CHECK_EXPECTED_METHOD("Moniker_Reduce");
351 if (ppmkReduced
==NULL
)
354 IMoniker_AddRef(iface
);
358 return MK_S_REDUCED_TO_SELF
;
361 static HRESULT WINAPI
362 Moniker_ComposeWith(IMoniker
* iface
, IMoniker
* pmkRight
,
363 BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
365 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
369 static HRESULT WINAPI
370 Moniker_Enum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
372 CHECK_EXPECTED_METHOD("Moniker_Enum");
374 if (ppenumMoniker
== NULL
)
377 *ppenumMoniker
= NULL
;
382 static HRESULT WINAPI
383 Moniker_IsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
385 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
389 static HRESULT WINAPI
390 Moniker_Hash(IMoniker
* iface
,DWORD
* pdwHash
)
392 CHECK_EXPECTED_METHOD("Moniker_Hash");
396 static HRESULT WINAPI
397 Moniker_IsRunning(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
398 IMoniker
* pmkNewlyRunning
)
400 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
404 static HRESULT WINAPI
405 Moniker_GetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
,
406 IMoniker
* pmkToLeft
, FILETIME
* pFileTime
)
408 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
412 static HRESULT WINAPI
413 Moniker_Inverse(IMoniker
* iface
,IMoniker
** ppmk
)
415 CHECK_EXPECTED_METHOD("Moniker_Inverse");
419 static HRESULT WINAPI
420 Moniker_CommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
,IMoniker
** ppmkPrefix
)
422 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
426 static HRESULT WINAPI
427 Moniker_RelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
429 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
433 static HRESULT WINAPI
434 Moniker_GetDisplayName(IMoniker
* iface
, IBindCtx
* pbc
,
435 IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
437 static const WCHAR wszDisplayName
[] = {'*','*','G','e','m','m','a',0};
438 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
439 *ppszDisplayName
= CoTaskMemAlloc(sizeof(wszDisplayName
));
440 memcpy(*ppszDisplayName
, wszDisplayName
, sizeof(wszDisplayName
));
444 static HRESULT WINAPI
445 Moniker_ParseDisplayName(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
,
446 LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
)
448 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
452 static HRESULT WINAPI
453 Moniker_IsSystemMoniker(IMoniker
* iface
,DWORD
* pwdMksys
)
455 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
460 (*pwdMksys
)=MKSYS_NONE
;
465 static const IMonikerVtbl MonikerNoROTDataVtbl
=
467 MonikerNoROTData_QueryInterface
,
475 Moniker_BindToObject
,
476 Moniker_BindToStorage
,
483 Moniker_GetTimeOfLastChange
,
485 Moniker_CommonPrefixWith
,
486 Moniker_RelativePathTo
,
487 Moniker_GetDisplayName
,
488 Moniker_ParseDisplayName
,
489 Moniker_IsSystemMoniker
492 static IMoniker MonikerNoROTData
= { &MonikerNoROTDataVtbl
};
494 static IMoniker Moniker
;
496 static HRESULT WINAPI
497 ROTData_QueryInterface(IROTData
*iface
,REFIID riid
,VOID
** ppvObject
)
499 return IMoniker_QueryInterface(&Moniker
, riid
, ppvObject
);
503 ROTData_AddRef(IROTData
*iface
)
509 ROTData_Release(IROTData
* iface
)
514 static HRESULT WINAPI
515 ROTData_GetComparisonData(IROTData
* iface
, BYTE
* pbData
,
516 ULONG cbMax
, ULONG
* pcbData
)
518 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
521 if (cbMax
< *pcbData
)
522 return E_OUTOFMEMORY
;
529 static IROTDataVtbl ROTDataVtbl
=
531 ROTData_QueryInterface
,
534 ROTData_GetComparisonData
537 static IROTData ROTData
= { &ROTDataVtbl
};
539 static HRESULT WINAPI
540 Moniker_QueryInterface(IMoniker
* iface
,REFIID riid
,void** ppvObject
)
547 if (IsEqualIID(&IID_IUnknown
, riid
) ||
548 IsEqualIID(&IID_IPersist
, riid
) ||
549 IsEqualIID(&IID_IPersistStream
,riid
) ||
550 IsEqualIID(&IID_IMoniker
, riid
))
552 if (IsEqualIID(&IID_IROTData
, riid
))
554 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
555 *ppvObject
= &ROTData
;
559 return E_NOINTERFACE
;
561 IMoniker_AddRef(iface
);
566 static const IMonikerVtbl MonikerVtbl
=
568 Moniker_QueryInterface
,
576 Moniker_BindToObject
,
577 Moniker_BindToStorage
,
584 Moniker_GetTimeOfLastChange
,
586 Moniker_CommonPrefixWith
,
587 Moniker_RelativePathTo
,
588 Moniker_GetDisplayName
,
589 Moniker_ParseDisplayName
,
590 Moniker_IsSystemMoniker
593 static IMoniker Moniker
= { &MonikerVtbl
};
595 static void test_ROT(void)
597 static const WCHAR wszFileName
[] = {'B','E','2','0','E','2','F','5','-',
598 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
599 '2','0','4','6','E','5','8','6','C','9','2','5',0};
601 IMoniker
*pMoniker
= NULL
;
602 IRunningObjectTable
*pROT
= NULL
;
604 static const char *methods_register_no_ROTData
[] =
607 "Moniker_GetTimeOfLastChange",
608 "Moniker_QueryInterface(IID_IROTData)",
609 "Moniker_GetDisplayName",
610 "Moniker_GetClassID",
613 static const char *methods_register
[] =
616 "Moniker_GetTimeOfLastChange",
617 "Moniker_QueryInterface(IID_IROTData)",
618 "ROTData_GetComparisonData",
621 static const char *methods_isrunning_no_ROTData
[] =
624 "Moniker_QueryInterface(IID_IROTData)",
625 "Moniker_GetDisplayName",
626 "Moniker_GetClassID",
629 static const char *methods_isrunning
[] =
632 "Moniker_QueryInterface(IID_IROTData)",
633 "ROTData_GetComparisonData",
639 hr
= GetRunningObjectTable(0, &pROT
);
640 ok_ole_success(hr
, GetRunningObjectTable
);
642 expected_method_list
= methods_register_no_ROTData
;
643 external_connections
= 0;
644 /* try with our own moniker that doesn't support IROTData */
645 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
646 (IUnknown
*)&Test_ClassFactory
, &MonikerNoROTData
, &dwCookie
);
647 ok_ole_success(hr
, IRunningObjectTable_Register
);
648 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
649 ok(external_connections
== 1, "external_connections = %d\n", external_connections
);
651 ok_more_than_one_lock();
653 expected_method_list
= methods_isrunning_no_ROTData
;
654 hr
= IRunningObjectTable_IsRunning(pROT
, &MonikerNoROTData
);
655 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
656 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
658 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
659 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
660 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
664 expected_method_list
= methods_register
;
665 /* try with our own moniker */
666 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
667 (IUnknown
*)&Test_ClassFactory
, &Moniker
, &dwCookie
);
668 ok_ole_success(hr
, IRunningObjectTable_Register
);
669 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
671 ok_more_than_one_lock();
673 expected_method_list
= methods_isrunning
;
674 hr
= IRunningObjectTable_IsRunning(pROT
, &Moniker
);
675 ok_ole_success(hr
, IRunningObjectTable_IsRunning
);
676 ok(!*expected_method_list
, "Method sequence starting from %s not called\n", *expected_method_list
);
678 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
679 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
683 hr
= CreateFileMoniker(wszFileName
, &pMoniker
);
684 ok_ole_success(hr
, CreateClassMoniker
);
687 external_connections
= 0;
688 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
,
689 pMoniker
, &dwCookie
);
690 ok_ole_success(hr
, IRunningObjectTable_Register
);
691 ok(external_connections
== 0, "external_connections = %d\n", external_connections
);
693 ok_more_than_one_lock();
695 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
696 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
700 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
701 hr
= IRunningObjectTable_Register(pROT
, ROTFLAGS_REGISTRATIONKEEPSALIVE
,
702 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
703 ok_ole_success(hr
, IRunningObjectTable_Register
);
705 ok_more_than_one_lock();
707 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie
);
708 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
712 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
713 /* only succeeds when process is started by SCM and has LocalService
714 * or RunAs AppId values */
715 hr
= IRunningObjectTable_Register(pROT
,
716 ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
,
717 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
719 ok(hr
== CO_E_WRONG_SERVER_IDENTITY
||
720 broken(hr
== S_OK
) /* Win9x */,
721 "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr
);
723 if (hr
== S_OK
) IRunningObjectTable_Revoke(pROT
, dwCookie
);
725 hr
= IRunningObjectTable_Register(pROT
, 0xdeadbeef,
726 (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie
);
727 ok(hr
== E_INVALIDARG
, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
729 IMoniker_Release(pMoniker
);
731 IRunningObjectTable_Release(pROT
);
734 static void test_ROT_multiple_entries(void)
737 IMoniker
*pMoniker
= NULL
;
738 IRunningObjectTable
*pROT
= NULL
;
739 DWORD dwCookie1
, dwCookie2
;
740 IUnknown
*pObject
= NULL
;
741 static const WCHAR moniker_path
[] =
742 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0};
744 hr
= GetRunningObjectTable(0, &pROT
);
745 ok_ole_success(hr
, GetRunningObjectTable
);
747 hr
= CreateFileMoniker(moniker_path
, &pMoniker
);
748 ok_ole_success(hr
, CreateFileMoniker
);
750 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie1
);
751 ok_ole_success(hr
, IRunningObjectTable_Register
);
753 hr
= IRunningObjectTable_Register(pROT
, 0, (IUnknown
*)&Test_ClassFactory
, pMoniker
, &dwCookie2
);
754 ok(hr
== MK_S_MONIKERALREADYREGISTERED
, "IRunningObjectTable_Register should have returned MK_S_MONIKERALREADYREGISTERED instead of 0x%08x\n", hr
);
756 ok(dwCookie1
!= dwCookie2
, "cookie returned for registering duplicate object shouldn't match cookie of original object (0x%x)\n", dwCookie1
);
758 hr
= IRunningObjectTable_GetObject(pROT
, pMoniker
, &pObject
);
759 ok_ole_success(hr
, IRunningObjectTable_GetObject
);
760 IUnknown_Release(pObject
);
762 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie1
);
763 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
765 hr
= IRunningObjectTable_GetObject(pROT
, pMoniker
, &pObject
);
766 ok_ole_success(hr
, IRunningObjectTable_GetObject
);
767 IUnknown_Release(pObject
);
769 hr
= IRunningObjectTable_Revoke(pROT
, dwCookie2
);
770 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
772 IMoniker_Release(pMoniker
);
774 IRunningObjectTable_Release(pROT
);
777 static HRESULT WINAPI
ParseDisplayName_QueryInterface(IParseDisplayName
*iface
, REFIID riid
, void **ppv
)
779 if (IsEqualIID(riid
, &IID_IUnknown
) ||
780 IsEqualIID(riid
, &IID_IParseDisplayName
))
783 IParseDisplayName_AddRef(iface
);
787 return E_NOINTERFACE
;
790 static ULONG WINAPI
ParseDisplayName_AddRef(IParseDisplayName
*iface
)
795 static ULONG WINAPI
ParseDisplayName_Release(IParseDisplayName
*iface
)
800 static LPCWSTR expected_display_name
;
802 static HRESULT WINAPI
ParseDisplayName_ParseDisplayName(IParseDisplayName
*iface
,
804 LPOLESTR pszDisplayName
,
808 char display_nameA
[256];
809 WideCharToMultiByte(CP_ACP
, 0, pszDisplayName
, -1, display_nameA
, sizeof(display_nameA
), NULL
, NULL
);
810 ok(!lstrcmpW(pszDisplayName
, expected_display_name
), "unexpected display name \"%s\"\n", display_nameA
);
811 ok(pszDisplayName
== expected_display_name
, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
812 *pchEaten
= lstrlenW(pszDisplayName
);
813 return CreateAntiMoniker(ppmkOut
);
816 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl
=
818 ParseDisplayName_QueryInterface
,
819 ParseDisplayName_AddRef
,
820 ParseDisplayName_Release
,
821 ParseDisplayName_ParseDisplayName
824 static IParseDisplayName ParseDisplayName
= { &ParseDisplayName_Vtbl
};
826 static int count_moniker_matches(IBindCtx
* pbc
, IEnumMoniker
* spEM
)
828 IMoniker
* spMoniker
;
829 int monCnt
=0, matchCnt
=0;
831 while ((IEnumMoniker_Next(spEM
, 1, &spMoniker
, NULL
)==S_OK
))
836 hr
=IMoniker_GetDisplayName(spMoniker
, pbc
, NULL
, &szDisplayn
);
839 if (!lstrcmpiW(szDisplayn
, wszFileName1
) || !lstrcmpiW(szDisplayn
, wszFileName2
))
841 CoTaskMemFree(szDisplayn
);
844 trace("Total number of monikers is %i\n", monCnt
);
848 static void test_MkParseDisplayName(void)
850 IBindCtx
* pbc
= NULL
;
852 IMoniker
* pmk
= NULL
;
853 IMoniker
* pmk1
= NULL
;
854 IMoniker
* pmk2
= NULL
;
857 IUnknown
* object
= NULL
;
861 IEnumMoniker
*spEM1
= NULL
;
862 IEnumMoniker
*spEM2
= NULL
;
863 IEnumMoniker
*spEM3
= NULL
;
869 IRunningObjectTable
* pprot
=NULL
;
871 /* CLSID of My Computer */
872 static const WCHAR wszDisplayName
[] = {'c','l','s','i','d',':',
873 '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};
874 static const WCHAR wszDisplayNameClsid
[] = {'c','l','s','i','d',':',0};
875 static const WCHAR wszNonExistentProgId
[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
876 static const WCHAR wszDisplayNameRunning
[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
877 static const WCHAR wszDisplayNameProgId1
[] = {'S','t','d','F','o','n','t',':',0};
878 static const WCHAR wszDisplayNameProgId2
[] = {'@','S','t','d','F','o','n','t',0};
879 static const WCHAR wszDisplayNameProgIdFail
[] = {'S','t','d','F','o','n','t',0};
880 static const WCHAR wszEmpty
[] = {0};
881 char szDisplayNameFile
[256];
882 WCHAR wszDisplayNameFile
[256];
888 LPCOLESTR szDisplayName
;
891 } invalid_parameters
[] =
893 {NULL
, NULL
, NULL
, NULL
},
894 {NULL
, NULL
, NULL
, &pmk
},
895 {NULL
, NULL
, &eaten
, NULL
},
896 {NULL
, NULL
, &eaten
, &pmk
},
897 {NULL
, wszEmpty
, NULL
, NULL
},
898 {NULL
, wszEmpty
, NULL
, &pmk
},
899 {NULL
, wszEmpty
, &eaten
, NULL
},
900 {NULL
, wszEmpty
, &eaten
, &pmk
},
901 {&pbc
, NULL
, NULL
, NULL
},
902 {&pbc
, NULL
, NULL
, &pmk
},
903 {&pbc
, NULL
, &eaten
, NULL
},
904 {&pbc
, NULL
, &eaten
, &pmk
},
905 {&pbc
, wszEmpty
, NULL
, NULL
},
906 {&pbc
, wszEmpty
, NULL
, &pmk
},
907 {&pbc
, wszEmpty
, &eaten
, NULL
},
908 {&pbc
, wszEmpty
, &eaten
, &pmk
},
911 hr
= CreateBindCtx(0, &pbc
);
912 ok_ole_success(hr
, CreateBindCtx
);
914 for (i
= 0; i
< sizeof(invalid_parameters
)/sizeof(invalid_parameters
[0]); i
++)
917 pmk
= (IMoniker
*)0xdeadbeef;
918 hr
= MkParseDisplayName(invalid_parameters
[i
].ppbc
? *invalid_parameters
[i
].ppbc
: NULL
,
919 invalid_parameters
[i
].szDisplayName
,
920 invalid_parameters
[i
].pchEaten
,
921 invalid_parameters
[i
].ppmk
);
922 ok(hr
== E_INVALIDARG
, "[%d] MkParseDisplayName should have failed with E_INVALIDARG instead of 0x%08x\n", i
, hr
);
923 ok(eaten
== 0xdeadbeef, "[%d] Processed character count should have been 0xdeadbeef instead of %u\n", i
, eaten
);
924 ok(pmk
== (IMoniker
*)0xdeadbeef, "[%d] Output moniker pointer should have been 0xdeadbeef instead of %p\n", i
, pmk
);
928 pmk
= (IMoniker
*)0xdeadbeef;
929 hr
= MkParseDisplayName(pbc
, wszNonExistentProgId
, &eaten
, &pmk
);
930 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
931 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
932 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
933 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
935 /* no special handling of "clsid:" without the string form of the clsid
938 pmk
= (IMoniker
*)0xdeadbeef;
939 hr
= MkParseDisplayName(pbc
, wszDisplayNameClsid
, &eaten
, &pmk
);
940 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
941 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
942 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
943 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
945 /* shows clsid has higher precedence than a running object */
946 hr
= CreateFileMoniker(wszDisplayName
, &pmk
);
947 ok_ole_success(hr
, CreateFileMoniker
);
948 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
949 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
950 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
951 ok_ole_success(hr
, IRunningObjectTable_Register
);
952 IMoniker_Release(pmk
);
954 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
955 ok_ole_success(hr
, MkParseDisplayName
);
956 ok(eaten
== sizeof(wszDisplayName
)/sizeof(WCHAR
) - 1,
957 "Processed character count should have been 43 instead of %u\n", eaten
);
960 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
961 ok(moniker_type
== MKSYS_CLASSMONIKER
, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type
);
962 IMoniker_Release(pmk
);
964 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
965 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
966 IRunningObjectTable_Release(pprot
);
968 hr
= CreateFileMoniker(wszDisplayNameRunning
, &pmk
);
969 ok_ole_success(hr
, CreateFileMoniker
);
970 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
971 ok_ole_success(hr
, IBindCtx_GetRunningObjectTable
);
972 hr
= IRunningObjectTable_Register(pprot
, 0, (IUnknown
*)&Test_ClassFactory
, pmk
, &pdwReg1
);
973 ok_ole_success(hr
, IRunningObjectTable_Register
);
974 IMoniker_Release(pmk
);
976 hr
= MkParseDisplayName(pbc
, wszDisplayNameRunning
, &eaten
, &pmk
);
977 ok_ole_success(hr
, MkParseDisplayName
);
978 ok(eaten
== sizeof(wszDisplayNameRunning
)/sizeof(WCHAR
) - 1,
979 "Processed character count should have been 15 instead of %u\n", eaten
);
982 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
983 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
984 IMoniker_Release(pmk
);
986 hr
= IRunningObjectTable_Revoke(pprot
, pdwReg1
);
987 ok_ole_success(hr
, IRunningObjectTable_Revoke
);
988 IRunningObjectTable_Release(pprot
);
990 hr
= CoRegisterClassObject(&CLSID_StdFont
, (IUnknown
*)&ParseDisplayName
, CLSCTX_INPROC_SERVER
, REGCLS_MULTI_SEPARATE
, &pdwReg1
);
991 ok_ole_success(hr
, CoRegisterClassObject
);
993 expected_display_name
= wszDisplayNameProgId1
;
994 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId1
, &eaten
, &pmk
);
995 ok_ole_success(hr
, MkParseDisplayName
);
996 ok(eaten
== sizeof(wszDisplayNameProgId1
)/sizeof(WCHAR
) - 1,
997 "Processed character count should have been 8 instead of %u\n", eaten
);
1000 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
1001 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
1002 IMoniker_Release(pmk
);
1005 expected_display_name
= wszDisplayNameProgId2
;
1006 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgId2
, &eaten
, &pmk
);
1007 ok_ole_success(hr
, MkParseDisplayName
);
1008 ok(eaten
== sizeof(wszDisplayNameProgId2
)/sizeof(WCHAR
) - 1,
1009 "Processed character count should have been 8 instead of %u\n", eaten
);
1012 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
1013 ok(moniker_type
== MKSYS_ANTIMONIKER
, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type
);
1014 IMoniker_Release(pmk
);
1018 pmk
= (IMoniker
*)0xdeadbeef;
1019 hr
= MkParseDisplayName(pbc
, wszDisplayNameProgIdFail
, &eaten
, &pmk
);
1020 ok(hr
== MK_E_SYNTAX
|| hr
== MK_E_CANTOPENFILE
/* Win9x */,
1021 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr
);
1022 ok(eaten
== 0, "Processed character count should have been 0 instead of %u\n", eaten
);
1023 ok(pmk
== NULL
, "Output moniker pointer should have been NULL instead of %p\n", pmk
);
1025 hr
= CoRevokeClassObject(pdwReg1
);
1026 ok_ole_success(hr
, CoRevokeClassObject
);
1028 GetSystemDirectoryA(szDisplayNameFile
, sizeof(szDisplayNameFile
));
1029 strcat(szDisplayNameFile
, "\\kernel32.dll");
1030 len
= MultiByteToWideChar(CP_ACP
, 0, szDisplayNameFile
, -1, wszDisplayNameFile
, sizeof(wszDisplayNameFile
)/sizeof(wszDisplayNameFile
[0]));
1031 hr
= MkParseDisplayName(pbc
, wszDisplayNameFile
, &eaten
, &pmk
);
1032 ok_ole_success(hr
, MkParseDisplayName
);
1033 ok(eaten
== len
- 1, "Processed character count should have been %d instead of %u\n", len
- 1, eaten
);
1036 IMoniker_IsSystemMoniker(pmk
, &moniker_type
);
1037 ok(moniker_type
== MKSYS_FILEMONIKER
, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type
);
1038 IMoniker_Release(pmk
);
1041 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
1042 ok_ole_success(hr
, MkParseDisplayName
);
1043 ok(eaten
== sizeof(wszDisplayName
)/sizeof(WCHAR
) - 1, "Processed character count should have been 43 instead of %u\n", eaten
);
1047 hr
= IMoniker_BindToObject(pmk
, pbc
, NULL
, &IID_IUnknown
, (LPVOID
*)&object
);
1048 ok_ole_success(hr
, IMoniker_BindToObject
);
1051 IUnknown_Release(object
);
1052 IMoniker_Release(pmk
);
1054 IBindCtx_Release(pbc
);
1056 /* Test the EnumMoniker interface */
1057 hr
= CreateBindCtx(0, &pbc
);
1058 ok_ole_success(hr
, CreateBindCtx
);
1060 hr
= CreateFileMoniker(wszFileName1
, &pmk1
);
1061 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
1062 hr
= CreateFileMoniker(wszFileName2
, &pmk2
);
1063 ok(hr
==0, "CreateFileMoniker for file hr=%08x\n", hr
);
1064 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
1065 ok(hr
==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr
);
1067 /* Check EnumMoniker before registering */
1068 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM1
);
1069 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
1070 hr
= IEnumMoniker_QueryInterface(spEM1
, &IID_IUnknown
, (void*) &lpEM1
);
1071 /* Register a couple of Monikers and check is ok */
1072 ok(hr
==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr
, lpEM1
);
1074 matchCnt
= count_moniker_matches(pbc
, spEM1
);
1075 trace("Number of matches is %i\n", matchCnt
);
1077 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
1078 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk1
, &pdwReg1
);
1079 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
1080 hr
, pprot
, grflags
, lpEM1
, pmk1
, pdwReg1
);
1082 trace("IROT::Register\n");
1084 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
1085 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk2
, &pdwReg2
);
1086 ok(hr
==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr
,
1087 pprot
, grflags
, lpEM1
, pmk2
, pdwReg2
);
1089 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM2
);
1090 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr
);
1092 matchCnt
= count_moniker_matches(pbc
, spEM2
);
1093 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
1095 trace("IEnumMoniker::Clone\n");
1096 IEnumMoniker_Clone(spEM2
, &spEM3
);
1098 matchCnt
= count_moniker_matches(pbc
, spEM3
);
1099 ok(matchCnt
==0, "Number of matches should be equal to 0 not %i\n", matchCnt
);
1100 trace("IEnumMoniker::Reset\n");
1101 IEnumMoniker_Reset(spEM3
);
1103 matchCnt
= count_moniker_matches(pbc
, spEM3
);
1104 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
1106 IRunningObjectTable_Revoke(pprot
,pdwReg1
);
1107 IRunningObjectTable_Revoke(pprot
,pdwReg2
);
1108 IUnknown_Release(lpEM1
);
1109 IEnumMoniker_Release(spEM1
);
1110 IEnumMoniker_Release(spEM2
);
1111 IEnumMoniker_Release(spEM3
);
1112 IMoniker_Release(pmk1
);
1113 IMoniker_Release(pmk2
);
1114 IRunningObjectTable_Release(pprot
);
1116 IBindCtx_Release(pbc
);
1119 static const LARGE_INTEGER llZero
;
1121 static const BYTE expected_class_moniker_marshal_data
[] =
1123 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1124 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1125 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1126 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1127 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1128 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1129 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1130 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1131 0x00,0x00,0x00,0x00,
1134 static const BYTE expected_class_moniker_saved_data
[] =
1136 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1137 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1138 0x00,0x00,0x00,0x00,
1141 static const BYTE expected_class_moniker_comparison_data
[] =
1143 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1144 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1145 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1146 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1149 static const WCHAR expected_class_moniker_display_name
[] =
1151 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
1152 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
1153 '0','0','0','0','4','6',':',0
1156 static const BYTE expected_item_moniker_comparison_data
[] =
1158 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1159 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1160 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1161 0x54,0x00,0x00,0x00,
1164 static const BYTE expected_item_moniker_saved_data
[] =
1166 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1167 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1170 static const BYTE expected_item_moniker_marshal_data
[] =
1172 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1173 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1174 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1175 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1176 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1177 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1178 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1179 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1182 static const BYTE expected_anti_moniker_marshal_data
[] =
1184 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1185 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1186 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1187 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1188 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1189 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1190 0x01,0x00,0x00,0x00,
1193 static const BYTE expected_anti_moniker_saved_data
[] =
1195 0x01,0x00,0x00,0x00,
1198 static const BYTE expected_anti_moniker_comparison_data
[] =
1200 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1201 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1202 0x01,0x00,0x00,0x00,
1205 static const BYTE expected_gc_moniker_marshal_data
[] =
1207 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1208 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1209 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1210 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1211 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1212 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1213 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1214 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1215 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1216 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1217 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1218 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1219 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1220 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1221 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1222 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1223 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1224 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1225 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1226 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1227 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1228 0x00,0x57,0x69,0x6e,0x65,0x00,
1231 static const BYTE expected_gc_moniker_saved_data
[] =
1233 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1234 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1235 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1236 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1237 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1238 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1239 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1240 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1244 static const BYTE expected_gc_moniker_comparison_data
[] =
1246 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1247 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1248 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1249 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1250 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1251 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1252 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1253 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1254 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1257 static void test_moniker(
1258 const char *testname
, IMoniker
*moniker
,
1259 const BYTE
*expected_moniker_marshal_data
, unsigned int sizeof_expected_moniker_marshal_data
,
1260 const BYTE
*expected_moniker_saved_data
, unsigned int sizeof_expected_moniker_saved_data
,
1261 const BYTE
*expected_moniker_comparison_data
, unsigned int sizeof_expected_moniker_comparison_data
,
1262 LPCWSTR expected_display_name
)
1268 LPBYTE moniker_data
;
1273 IMoniker
* moniker_proxy
;
1274 LPOLESTR display_name
;
1277 hr
= IMoniker_IsDirty(moniker
);
1278 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1282 hr
= CreateBindCtx(0, &bindctx
);
1283 ok_ole_success(hr
, CreateBindCtx
);
1285 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1286 ok_ole_success(hr
, IMoniker_GetDisplayName
);
1287 ok(!lstrcmpW(display_name
, expected_display_name
), "%s: display name wasn't what was expected\n", testname
);
1289 CoTaskMemFree(display_name
);
1290 IBindCtx_Release(bindctx
);
1292 hr
= IMoniker_IsDirty(moniker
);
1293 ok(hr
== S_FALSE
, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname
, hr
);
1295 /* IROTData::GetComparisonData test */
1297 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1298 ok_ole_success(hr
, IMoniker_QueryInterface_IID_IROTData
);
1300 hr
= IROTData_GetComparisonData(rotdata
, buffer
, sizeof(buffer
), &moniker_size
);
1301 ok_ole_success(hr
, IROTData_GetComparisonData
);
1303 if (hr
!= S_OK
) moniker_size
= 0;
1305 /* first check we have the right amount of data */
1306 ok(moniker_size
== sizeof_expected_moniker_comparison_data
,
1307 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1308 testname
, sizeof_expected_moniker_comparison_data
, moniker_size
);
1310 /* then do a byte-by-byte comparison */
1312 for (i
= 0; i
< min(moniker_size
, sizeof_expected_moniker_comparison_data
); i
++)
1314 if (expected_moniker_comparison_data
[i
] != buffer
[i
])
1321 ok(same
, "%s: Comparison data differs\n", testname
);
1324 for (i
= 0; i
< moniker_size
; i
++)
1326 if (i
% 8 == 0) printf(" ");
1327 printf("0x%02x,", buffer
[i
]);
1328 if (i
% 8 == 7) printf("\n");
1333 IROTData_Release(rotdata
);
1335 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1336 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1340 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1341 ok_ole_success(hr
, IMoniker_Save
);
1343 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1344 ok_ole_success(hr
, GetHGlobalFromStream
);
1346 moniker_size
= GlobalSize(hglobal
);
1348 moniker_data
= GlobalLock(hglobal
);
1350 /* first check we have the right amount of data */
1351 ok(moniker_size
== round_global_size(sizeof_expected_moniker_saved_data
),
1352 "%s: Size of saved data differs (expected %d, actual %d)\n",
1353 testname
, (DWORD
)round_global_size(sizeof_expected_moniker_saved_data
), moniker_size
);
1355 /* then do a byte-by-byte comparison */
1357 for (i
= 0; i
< min(moniker_size
, round_global_size(sizeof_expected_moniker_saved_data
)); i
++)
1359 if (expected_moniker_saved_data
[i
] != moniker_data
[i
])
1366 ok(same
, "%s: Saved data differs\n", testname
);
1369 for (i
= 0; i
< moniker_size
; i
++)
1371 if (i
% 8 == 0) printf(" ");
1372 printf("0x%02x,", moniker_data
[i
]);
1373 if (i
% 8 == 7) printf("\n");
1378 GlobalUnlock(hglobal
);
1380 IStream_Release(stream
);
1382 /* Marshaling tests */
1384 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1385 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1387 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1388 ok_ole_success(hr
, CoMarshalInterface
);
1390 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1391 ok_ole_success(hr
, GetHGlobalFromStream
);
1393 moniker_size
= GlobalSize(hglobal
);
1395 moniker_data
= GlobalLock(hglobal
);
1397 /* first check we have the right amount of data */
1398 ok(moniker_size
== round_global_size(sizeof_expected_moniker_marshal_data
),
1399 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1400 testname
, (DWORD
)round_global_size(sizeof_expected_moniker_marshal_data
), moniker_size
);
1402 /* then do a byte-by-byte comparison */
1404 if (expected_moniker_marshal_data
)
1406 for (i
= 0; i
< min(moniker_size
, round_global_size(sizeof_expected_moniker_marshal_data
)); i
++)
1408 if (expected_moniker_marshal_data
[i
] != moniker_data
[i
])
1416 ok(same
, "%s: Marshaled data differs\n", testname
);
1419 for (i
= 0; i
< moniker_size
; i
++)
1421 if (i
% 8 == 0) printf(" ");
1422 printf("0x%02x,", moniker_data
[i
]);
1423 if (i
% 8 == 7) printf("\n");
1428 GlobalUnlock(hglobal
);
1430 IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1431 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&moniker_proxy
);
1432 ok_ole_success(hr
, CoUnmarshalInterface
);
1434 IStream_Release(stream
);
1435 IMoniker_Release(moniker_proxy
);
1438 static void test_class_moniker(void)
1449 hr
= CreateClassMoniker(&CLSID_StdComponentCategoriesMgr
, &moniker
);
1450 ok_ole_success(hr
, CreateClassMoniker
);
1451 if (!moniker
) return;
1453 test_moniker("class moniker", moniker
,
1454 expected_class_moniker_marshal_data
, sizeof(expected_class_moniker_marshal_data
),
1455 expected_class_moniker_saved_data
, sizeof(expected_class_moniker_saved_data
),
1456 expected_class_moniker_comparison_data
, sizeof(expected_class_moniker_comparison_data
),
1457 expected_class_moniker_display_name
);
1461 hr
= IMoniker_Hash(moniker
, &hash
);
1462 ok_ole_success(hr
, IMoniker_Hash
);
1464 ok(hash
== CLSID_StdComponentCategoriesMgr
.Data1
,
1465 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1468 /* IsSystemMoniker test */
1470 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1471 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1473 ok(moniker_type
== MKSYS_CLASSMONIKER
,
1474 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1477 hr
= CreateBindCtx(0, &bindctx
);
1478 ok_ole_success(hr
, CreateBindCtx
);
1480 /* IsRunning test */
1481 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1482 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1484 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1485 ok(hr
== E_NOTIMPL
, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr
);
1487 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1488 ok(hr
== MK_E_UNAVAILABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr
);
1490 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1491 ok_ole_success(hr
, IMoniker_BindToObject
);
1492 IUnknown_Release(unknown
);
1494 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1495 ok_ole_success(hr
, IMoniker_BindToStorage
);
1496 IUnknown_Release(unknown
);
1498 IBindCtx_Release(bindctx
);
1500 hr
= IMoniker_Inverse(moniker
, &inverse
);
1501 ok_ole_success(hr
, IMoniker_Inverse
);
1502 IMoniker_Release(inverse
);
1504 IMoniker_Release(moniker
);
1507 static void test_file_moniker(WCHAR
* path
)
1510 IMoniker
*moniker1
= NULL
, *moniker2
= NULL
;
1513 hr
= CreateFileMoniker(path
, &moniker1
);
1514 ok_ole_success(hr
, CreateFileMoniker
);
1516 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1517 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1520 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker1
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1521 ok_ole_success(hr
, CoMarshalInterface
);
1524 hr
= IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
1525 ok_ole_success(hr
, IStream_Seek
);
1528 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void**)&moniker2
);
1529 ok_ole_success(hr
, CoUnmarshalInterface
);
1531 hr
= IMoniker_IsEqual(moniker1
, moniker2
);
1532 ok_ole_success(hr
, IsEqual
);
1534 IStream_Release(stream
);
1536 IMoniker_Release(moniker1
);
1538 IMoniker_Release(moniker2
);
1541 static void test_file_monikers(void)
1543 static WCHAR wszFile
[][30] = {
1544 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1545 {'\\', '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},
1546 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1547 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1548 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1549 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1550 * U+0100 .. = Latin extended-A
1552 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1557 trace("ACP is %u\n", GetACP());
1559 for (i
= 0; i
< COUNTOF(wszFile
); ++i
)
1565 WideCharToMultiByte( CP_ACP
, WC_NO_BEST_FIT_CHARS
, wszFile
[i
], -1, NULL
, 0, NULL
, &used
);
1568 skip("string 2 doesn't round trip in codepage %u\n", GetACP() );
1572 for (j
= lstrlenW(wszFile
[i
]); j
> 0; --j
)
1575 test_file_moniker(wszFile
[i
]);
1580 static void test_item_moniker(void)
1589 static const WCHAR wszDelimeter
[] = {'!',0};
1590 static const WCHAR wszObjectName
[] = {'T','e','s','t',0};
1591 static const WCHAR expected_display_name
[] = { '!','T','e','s','t',0 };
1593 hr
= CreateItemMoniker(wszDelimeter
, wszObjectName
, &moniker
);
1594 ok_ole_success(hr
, CreateItemMoniker
);
1596 test_moniker("item moniker", moniker
,
1597 expected_item_moniker_marshal_data
, sizeof(expected_item_moniker_marshal_data
),
1598 expected_item_moniker_saved_data
, sizeof(expected_item_moniker_saved_data
),
1599 expected_item_moniker_comparison_data
, sizeof(expected_item_moniker_comparison_data
),
1600 expected_display_name
);
1604 hr
= IMoniker_Hash(moniker
, &hash
);
1605 ok_ole_success(hr
, IMoniker_Hash
);
1608 "Hash value != 0x73c, instead was 0x%08x\n",
1611 /* IsSystemMoniker test */
1613 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1614 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1616 ok(moniker_type
== MKSYS_ITEMMONIKER
,
1617 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1620 hr
= CreateBindCtx(0, &bindctx
);
1621 ok_ole_success(hr
, CreateBindCtx
);
1623 /* IsRunning test */
1624 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1625 ok(hr
== E_INVALIDARG
, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr
);
1627 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1628 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1630 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1631 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1633 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1634 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1636 IBindCtx_Release(bindctx
);
1638 hr
= IMoniker_Inverse(moniker
, &inverse
);
1639 ok_ole_success(hr
, IMoniker_Inverse
);
1640 IMoniker_Release(inverse
);
1642 IMoniker_Release(moniker
);
1645 static void test_anti_moniker(void)
1655 static const WCHAR expected_display_name
[] = { '\\','.','.',0 };
1657 hr
= CreateAntiMoniker(&moniker
);
1658 ok_ole_success(hr
, CreateAntiMoniker
);
1659 if (!moniker
) return;
1661 test_moniker("anti moniker", moniker
,
1662 expected_anti_moniker_marshal_data
, sizeof(expected_anti_moniker_marshal_data
),
1663 expected_anti_moniker_saved_data
, sizeof(expected_anti_moniker_saved_data
),
1664 expected_anti_moniker_comparison_data
, sizeof(expected_anti_moniker_comparison_data
),
1665 expected_display_name
);
1668 hr
= IMoniker_Hash(moniker
, &hash
);
1669 ok_ole_success(hr
, IMoniker_Hash
);
1670 ok(hash
== 0x80000001,
1671 "Hash value != 0x80000001, instead was 0x%08x\n",
1674 /* IsSystemMoniker test */
1675 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1676 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1677 ok(moniker_type
== MKSYS_ANTIMONIKER
,
1678 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1681 hr
= IMoniker_Inverse(moniker
, &inverse
);
1682 ok(hr
== MK_E_NOINVERSE
, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr
);
1683 ok(inverse
== NULL
, "inverse should have been set to NULL instead of %p\n", inverse
);
1685 hr
= CreateBindCtx(0, &bindctx
);
1686 ok_ole_success(hr
, CreateBindCtx
);
1688 /* IsRunning test */
1689 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1690 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1692 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1693 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1695 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1696 ok(hr
== E_NOTIMPL
, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr
);
1698 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1699 ok(hr
== E_NOTIMPL
, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr
);
1701 IBindCtx_Release(bindctx
);
1703 IMoniker_Release(moniker
);
1706 static void test_generic_composite_moniker(void)
1718 static const WCHAR wszDelimeter1
[] = {'!',0};
1719 static const WCHAR wszObjectName1
[] = {'T','e','s','t',0};
1720 static const WCHAR wszDelimeter2
[] = {'#',0};
1721 static const WCHAR wszObjectName2
[] = {'W','i','n','e',0};
1722 static const WCHAR expected_display_name
[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1724 hr
= CreateItemMoniker(wszDelimeter1
, wszObjectName1
, &moniker1
);
1725 ok_ole_success(hr
, CreateItemMoniker
);
1726 hr
= CreateItemMoniker(wszDelimeter2
, wszObjectName2
, &moniker2
);
1727 ok_ole_success(hr
, CreateItemMoniker
);
1728 hr
= CreateGenericComposite(moniker1
, moniker2
, &moniker
);
1729 ok_ole_success(hr
, CreateGenericComposite
);
1731 test_moniker("generic composite moniker", moniker
,
1732 expected_gc_moniker_marshal_data
, sizeof(expected_gc_moniker_marshal_data
),
1733 expected_gc_moniker_saved_data
, sizeof(expected_gc_moniker_saved_data
),
1734 expected_gc_moniker_comparison_data
, sizeof(expected_gc_moniker_comparison_data
),
1735 expected_display_name
);
1739 hr
= IMoniker_Hash(moniker
, &hash
);
1740 ok_ole_success(hr
, IMoniker_Hash
);
1743 "Hash value != 0xd87, instead was 0x%08x\n",
1746 /* IsSystemMoniker test */
1748 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1749 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1751 ok(moniker_type
== MKSYS_GENERICCOMPOSITE
,
1752 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1755 hr
= CreateBindCtx(0, &bindctx
);
1756 ok_ole_success(hr
, CreateBindCtx
);
1758 /* IsRunning test */
1759 hr
= IMoniker_IsRunning(moniker
, NULL
, NULL
, NULL
);
1760 ok(hr
== E_INVALIDARG
, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr
);
1762 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1764 ok(hr
== S_FALSE
, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr
);
1766 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1767 ok(hr
== MK_E_NOTBINDABLE
, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr
);
1769 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1771 ok(hr
== E_INVALIDARG
, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr
);
1773 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1774 ok(hr
== E_INVALIDARG
, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr
);
1776 IBindCtx_Release(bindctx
);
1778 hr
= IMoniker_Inverse(moniker
, &inverse
);
1779 ok_ole_success(hr
, IMoniker_Inverse
);
1780 IMoniker_Release(inverse
);
1782 IMoniker_Release(moniker
);
1785 static void test_pointer_moniker(void)
1797 LPOLESTR display_name
;
1801 hr
= CreatePointerMoniker((IUnknown
*)&Test_ClassFactory
, NULL
);
1802 ok(hr
== E_INVALIDARG
, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1804 hr
= CreatePointerMoniker((IUnknown
*)&Test_ClassFactory
, &moniker
);
1805 ok_ole_success(hr
, CreatePointerMoniker
);
1806 if (!moniker
) return;
1808 ok_more_than_one_lock();
1812 hr
= CreateBindCtx(0, &bindctx
);
1813 ok_ole_success(hr
, CreateBindCtx
);
1815 hr
= IMoniker_GetDisplayName(moniker
, bindctx
, NULL
, &display_name
);
1816 ok(hr
== E_NOTIMPL
, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1818 IBindCtx_Release(bindctx
);
1820 hr
= IMoniker_IsDirty(moniker
);
1821 ok(hr
== S_FALSE
, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr
);
1823 /* IROTData::GetComparisonData test */
1825 hr
= IMoniker_QueryInterface(moniker
, &IID_IROTData
, (void **)&rotdata
);
1826 ok(hr
== E_NOINTERFACE
, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr
);
1830 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1831 ok_ole_success(hr
, CreateStreamOnHGlobal
);
1833 hr
= IMoniker_Save(moniker
, stream
, TRUE
);
1834 ok(hr
== E_NOTIMPL
, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1836 IStream_Release(stream
);
1839 hr
= IMoniker_Hash(moniker
, &hash
);
1840 ok_ole_success(hr
, IMoniker_Hash
);
1841 ok(hash
== PtrToUlong(&Test_ClassFactory
),
1842 "Hash value should have been 0x%08x, instead of 0x%08x\n",
1843 PtrToUlong(&Test_ClassFactory
), hash
);
1845 /* IsSystemMoniker test */
1846 hr
= IMoniker_IsSystemMoniker(moniker
, &moniker_type
);
1847 ok_ole_success(hr
, IMoniker_IsSystemMoniker
);
1848 ok(moniker_type
== MKSYS_POINTERMONIKER
,
1849 "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1852 hr
= IMoniker_Inverse(moniker
, &inverse
);
1853 ok_ole_success(hr
, IMoniker_Inverse
);
1854 IMoniker_Release(inverse
);
1856 hr
= CreateBindCtx(0, &bindctx
);
1857 ok_ole_success(hr
, CreateBindCtx
);
1859 /* IsRunning test */
1860 hr
= IMoniker_IsRunning(moniker
, bindctx
, NULL
, NULL
);
1861 ok(hr
== S_OK
, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr
);
1863 hr
= IMoniker_GetTimeOfLastChange(moniker
, bindctx
, NULL
, &filetime
);
1864 ok(hr
== E_NOTIMPL
, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr
);
1866 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1867 ok_ole_success(hr
, IMoniker_BindToObject
);
1868 IUnknown_Release(unknown
);
1870 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1871 ok_ole_success(hr
, IMoniker_BindToStorage
);
1872 IUnknown_Release(unknown
);
1874 IMoniker_Release(moniker
);
1878 hr
= CreatePointerMoniker(NULL
, &moniker
);
1879 ok_ole_success(hr
, CreatePointerMoniker
);
1881 hr
= IMoniker_BindToObject(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1882 ok(hr
== E_UNEXPECTED
, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr
);
1884 hr
= IMoniker_BindToStorage(moniker
, bindctx
, NULL
, &IID_IUnknown
, (void **)&unknown
);
1885 ok(hr
== E_UNEXPECTED
, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr
);
1887 IBindCtx_Release(bindctx
);
1889 IMoniker_Release(moniker
);
1892 static void test_bind_context(void)
1896 IEnumString
*pEnumString
;
1897 BIND_OPTS2 bind_opts
;
1898 HeapUnknown
*unknown
;
1899 HeapUnknown
*unknown2
;
1900 IUnknown
*param_obj
;
1902 static const WCHAR wszParamName
[] = {'G','e','m','m','a',0};
1903 static const WCHAR wszNonExistent
[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1905 hr
= CreateBindCtx(0, NULL
);
1906 ok(hr
== E_INVALIDARG
, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1908 hr
= CreateBindCtx(0xdeadbeef, &pBindCtx
);
1909 ok(hr
== E_INVALIDARG
, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1911 hr
= CreateBindCtx(0, &pBindCtx
);
1912 ok_ole_success(hr
, "CreateBindCtx");
1914 bind_opts
.cbStruct
= -1;
1915 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1916 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1917 ok(bind_opts
.cbStruct
== sizeof(bind_opts
) ||
1918 bind_opts
.cbStruct
== sizeof(bind_opts
) + sizeof(void*), /* Vista */
1919 "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1921 bind_opts
.cbStruct
= sizeof(BIND_OPTS
);
1922 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1923 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1924 ok(bind_opts
.cbStruct
== sizeof(BIND_OPTS
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1926 bind_opts
.cbStruct
= sizeof(bind_opts
);
1927 hr
= IBindCtx_GetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1928 ok_ole_success(hr
, "IBindCtx_GetBindOptions");
1929 ok(bind_opts
.cbStruct
== sizeof(bind_opts
), "bind_opts.cbStruct was %d\n", bind_opts
.cbStruct
);
1930 ok(bind_opts
.grfFlags
== 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts
.grfFlags
);
1931 ok(bind_opts
.grfMode
== STGM_READWRITE
, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts
.grfMode
);
1932 ok(bind_opts
.dwTickCountDeadline
== 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts
.dwTickCountDeadline
);
1933 ok(bind_opts
.dwTrackFlags
== 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts
.dwTrackFlags
);
1934 ok(bind_opts
.dwClassContext
== (CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
|CLSCTX_REMOTE_SERVER
),
1935 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts
.dwClassContext
);
1936 ok(bind_opts
.locale
== GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts
.locale
);
1937 ok(bind_opts
.pServerInfo
== NULL
, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts
.pServerInfo
);
1939 bind_opts
.cbStruct
= -1;
1940 hr
= IBindCtx_SetBindOptions(pBindCtx
, (BIND_OPTS
*)&bind_opts
);
1941 ok(hr
== E_INVALIDARG
, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1943 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, NULL
);
1944 ok(hr
== E_INVALIDARG
, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1946 unknown
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1947 unknown
->IUnknown_iface
.lpVtbl
= &HeapUnknown_Vtbl
;
1949 hr
= IBindCtx_RegisterObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, &unknown
->IUnknown_iface
);
1950 ok_ole_success(hr
, "IBindCtx_RegisterObjectParam");
1952 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszParamName
, ¶m_obj
);
1953 ok_ole_success(hr
, "IBindCtx_GetObjectParam");
1954 IUnknown_Release(param_obj
);
1956 hr
= IBindCtx_GetObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
, ¶m_obj
);
1957 ok(hr
== E_FAIL
, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1958 ok(param_obj
== NULL
, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj
);
1960 hr
= IBindCtx_RevokeObjectParam(pBindCtx
, (WCHAR
*)wszNonExistent
);
1961 ok(hr
== E_FAIL
, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr
);
1963 hr
= IBindCtx_EnumObjectParam(pBindCtx
, &pEnumString
);
1964 ok(hr
== E_NOTIMPL
, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1965 ok(!pEnumString
, "pEnumString should be NULL\n");
1967 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, NULL
);
1968 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound(NULL)");
1970 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, NULL
);
1971 ok(hr
== E_INVALIDARG
, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr
);
1973 unknown2
= HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown
));
1974 unknown2
->IUnknown_iface
.lpVtbl
= &HeapUnknown_Vtbl
;
1976 hr
= IBindCtx_RegisterObjectBound(pBindCtx
, &unknown2
->IUnknown_iface
);
1977 ok_ole_success(hr
, "IBindCtx_RegisterObjectBound");
1979 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, &unknown2
->IUnknown_iface
);
1980 ok_ole_success(hr
, "IBindCtx_RevokeObjectBound");
1982 hr
= IBindCtx_RevokeObjectBound(pBindCtx
, &unknown2
->IUnknown_iface
);
1983 ok(hr
== MK_E_NOTBOUND
, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr
);
1985 IBindCtx_Release(pBindCtx
);
1987 refs
= IUnknown_Release(&unknown
->IUnknown_iface
);
1988 ok(!refs
, "object param should have been destroyed, instead of having %d refs\n", refs
);
1990 refs
= IUnknown_Release(&unknown2
->IUnknown_iface
);
1991 ok(!refs
, "bound object should have been destroyed, instead of having %d refs\n", refs
);
1994 static void test_save_load_filemoniker(void)
1999 ULARGE_INTEGER size
;
2000 LARGE_INTEGER zero_pos
, dead_pos
, nulls_pos
;
2001 DWORD some_val
= 0xFEDCBA98;
2004 /* see FileMonikerImpl_Save docs */
2005 zero_pos
.QuadPart
= 0;
2006 dead_pos
.QuadPart
= sizeof(WORD
) + sizeof(DWORD
) + (lstrlenW(wszFileName1
) + 1) + sizeof(WORD
);
2007 nulls_pos
.QuadPart
= dead_pos
.QuadPart
+ sizeof(WORD
);
2009 /* create the stream we're going to write to */
2010 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStm
);
2011 ok_ole_success(hr
, "CreateStreamOnHGlobal");
2013 size
.u
.LowPart
= 128;
2014 hr
= IStream_SetSize(pStm
, size
);
2015 ok_ole_success(hr
, "IStream_SetSize");
2017 /* create and save a moniker */
2018 hr
= CreateFileMoniker(wszFileName1
, &pMk
);
2019 ok_ole_success(hr
, "CreateFileMoniker");
2021 hr
= IMoniker_Save(pMk
, pStm
, TRUE
);
2022 ok_ole_success(hr
, "IMoniker_Save");
2023 IMoniker_Release(pMk
);
2025 /* overwrite the constants with various values */
2026 hr
= IStream_Seek(pStm
, zero_pos
, STREAM_SEEK_SET
, NULL
);
2027 ok_ole_success(hr
, "IStream_Seek");
2028 hr
= IStream_Write(pStm
, &some_val
, sizeof(WORD
), NULL
);
2029 ok_ole_success(hr
, "IStream_Write");
2031 hr
= IStream_Seek(pStm
, dead_pos
, STREAM_SEEK_SET
, NULL
);
2032 ok_ole_success(hr
, "IStream_Seek");
2033 hr
= IStream_Write(pStm
, &some_val
, sizeof(WORD
), NULL
);
2034 ok_ole_success(hr
, "IStream_Write");
2036 hr
= IStream_Seek(pStm
, nulls_pos
, STREAM_SEEK_SET
, NULL
);
2037 ok_ole_success(hr
, "IStream_Seek");
2038 for(i
= 0; i
< 5; ++i
){
2039 hr
= IStream_Write(pStm
, &some_val
, sizeof(DWORD
), NULL
);
2040 ok_ole_success(hr
, "IStream_Write");
2043 /* go back to the start of the stream */
2044 hr
= IStream_Seek(pStm
, zero_pos
, STREAM_SEEK_SET
, NULL
);
2045 ok_ole_success(hr
, "IStream_Seek");
2047 /* create a new moniker and load into it */
2048 hr
= CreateFileMoniker(wszFileName1
, &pMk
);
2049 ok_ole_success(hr
, "CreateFileMoniker");
2051 hr
= IMoniker_Load(pMk
, pStm
);
2052 ok_ole_success(hr
, "IMoniker_Load");
2054 IMoniker_Release(pMk
);
2055 IStream_Release(pStm
);
2060 if (!GetProcAddress(GetModuleHandleA("ole32.dll"), "CoRegisterSurrogateEx")) {
2061 win_skip("skipping test on win9x\n");
2065 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2068 test_ROT_multiple_entries();
2069 test_MkParseDisplayName();
2070 test_class_moniker();
2071 test_file_monikers();
2072 test_item_moniker();
2073 test_anti_moniker();
2074 test_generic_composite_moniker();
2075 test_pointer_moniker();
2076 test_save_load_filemoniker();
2078 /* FIXME: test moniker creation funcs and parsing other moniker formats */
2080 test_bind_context();