1c2c66affSColin Finck /*
2c2c66affSColin Finck * Moniker Tests
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 2004 Robert Shearman
5c2c66affSColin Finck *
6c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck * License as published by the Free Software Foundation; either
9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck *
11c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14c2c66affSColin Finck * Lesser General Public License for more details.
15c2c66affSColin Finck *
16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck */
20c2c66affSColin Finck
2166f35ef8SAmine Khaldi #define _WIN32_DCOM
2266f35ef8SAmine Khaldi #define COBJMACROS
2366f35ef8SAmine Khaldi #define CONST_VTABLE
24c2c66affSColin Finck
2566f35ef8SAmine Khaldi #include <stdarg.h>
2666f35ef8SAmine Khaldi #include <stdio.h>
2766f35ef8SAmine Khaldi
2866f35ef8SAmine Khaldi #include "windef.h"
2966f35ef8SAmine Khaldi #include "winbase.h"
3066f35ef8SAmine Khaldi #include "objbase.h"
3166f35ef8SAmine Khaldi #include "ocidl.h"
3266f35ef8SAmine Khaldi #include "comcat.h"
3366f35ef8SAmine Khaldi #include "olectl.h"
3466f35ef8SAmine Khaldi
3566f35ef8SAmine Khaldi #include "wine/test.h"
36c2c66affSColin Finck
37c2c66affSColin Finck #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
38c2c66affSColin Finck #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
39c2c66affSColin Finck #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
40c2c66affSColin Finck
41c2c66affSColin Finck #define CHECK_EXPECTED_METHOD(method_name) \
42c2c66affSColin Finck do { \
43c2c66affSColin Finck trace("%s\n", method_name); \
44c2c66affSColin Finck ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
45c2c66affSColin Finck if (*expected_method_list) \
46c2c66affSColin Finck { \
47c2c66affSColin Finck ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
48c2c66affSColin Finck *expected_method_list, method_name); \
49c2c66affSColin Finck expected_method_list++; \
50c2c66affSColin Finck } \
51c2c66affSColin Finck } while(0)
52c2c66affSColin Finck
53c2c66affSColin Finck static char const * const *expected_method_list;
54c2c66affSColin Finck static const WCHAR wszFileName1[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
55c2c66affSColin Finck static const WCHAR wszFileName2[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
56c2c66affSColin Finck
57c2c66affSColin Finck static const CLSID CLSID_TestMoniker =
58c2c66affSColin Finck { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
59c2c66affSColin Finck 0xb306bfbc,
60c2c66affSColin Finck 0x496e,
61c2c66affSColin Finck 0x4f53,
62c2c66affSColin Finck {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
63c2c66affSColin Finck };
64c2c66affSColin Finck
65c2c66affSColin Finck static LONG cLocks;
66c2c66affSColin Finck
LockModule(void)67c2c66affSColin Finck static void LockModule(void)
68c2c66affSColin Finck {
69c2c66affSColin Finck InterlockedIncrement(&cLocks);
70c2c66affSColin Finck }
71c2c66affSColin Finck
UnlockModule(void)72c2c66affSColin Finck static void UnlockModule(void)
73c2c66affSColin Finck {
74c2c66affSColin Finck InterlockedDecrement(&cLocks);
75c2c66affSColin Finck }
76c2c66affSColin Finck
round_global_size(SIZE_T size)77c2c66affSColin Finck static SIZE_T round_global_size(SIZE_T size)
78c2c66affSColin Finck {
79c2c66affSColin Finck static SIZE_T global_size_alignment = -1;
80c2c66affSColin Finck if (global_size_alignment == -1)
81c2c66affSColin Finck {
82c2c66affSColin Finck void *p = GlobalAlloc(GMEM_FIXED, 1);
83c2c66affSColin Finck global_size_alignment = GlobalSize(p);
84c2c66affSColin Finck GlobalFree(p);
85c2c66affSColin Finck }
86c2c66affSColin Finck
87c2c66affSColin Finck return ((size + global_size_alignment - 1) & ~(global_size_alignment - 1));
88c2c66affSColin Finck }
89c2c66affSColin Finck
90c2c66affSColin Finck static DWORD external_connections;
91c2c66affSColin Finck
ExternalConnection_QueryInterface(IExternalConnection * iface,REFIID riid,void ** ppv)92c2c66affSColin Finck static HRESULT WINAPI ExternalConnection_QueryInterface(IExternalConnection *iface, REFIID riid, void **ppv)
93c2c66affSColin Finck {
94c2c66affSColin Finck ok(0, "unexpected call\n");
95c2c66affSColin Finck *ppv = NULL;
96c2c66affSColin Finck return E_NOINTERFACE;
97c2c66affSColin Finck }
98c2c66affSColin Finck
ExternalConnection_AddRef(IExternalConnection * iface)99c2c66affSColin Finck static ULONG WINAPI ExternalConnection_AddRef(IExternalConnection *iface)
100c2c66affSColin Finck {
101c2c66affSColin Finck return 2;
102c2c66affSColin Finck }
103c2c66affSColin Finck
ExternalConnection_Release(IExternalConnection * iface)104c2c66affSColin Finck static ULONG WINAPI ExternalConnection_Release(IExternalConnection *iface)
105c2c66affSColin Finck {
106c2c66affSColin Finck return 1;
107c2c66affSColin Finck }
108c2c66affSColin Finck
ExternalConnection_AddConnection(IExternalConnection * iface,DWORD extconn,DWORD reserved)109c2c66affSColin Finck static DWORD WINAPI ExternalConnection_AddConnection(IExternalConnection *iface, DWORD extconn, DWORD reserved)
110c2c66affSColin Finck {
111c2c66affSColin Finck trace("add connection\n");
112c2c66affSColin Finck
113c2c66affSColin Finck ok(extconn == EXTCONN_STRONG, "extconn = %d\n", extconn);
114c2c66affSColin Finck ok(!reserved, "reserved = %x\n", reserved);
115c2c66affSColin Finck return ++external_connections;
116c2c66affSColin Finck }
117c2c66affSColin Finck
ExternalConnection_ReleaseConnection(IExternalConnection * iface,DWORD extconn,DWORD reserved,BOOL fLastReleaseCloses)118c2c66affSColin Finck static DWORD WINAPI ExternalConnection_ReleaseConnection(IExternalConnection *iface, DWORD extconn,
119c2c66affSColin Finck DWORD reserved, BOOL fLastReleaseCloses)
120c2c66affSColin Finck {
121c2c66affSColin Finck trace("release connection\n");
122c2c66affSColin Finck
123c2c66affSColin Finck ok(extconn == EXTCONN_STRONG, "extconn = %d\n", extconn);
124c2c66affSColin Finck ok(!reserved, "reserved = %x\n", reserved);
125c2c66affSColin Finck
126c2c66affSColin Finck return --external_connections;
127c2c66affSColin Finck }
128c2c66affSColin Finck
129c2c66affSColin Finck static const IExternalConnectionVtbl ExternalConnectionVtbl = {
130c2c66affSColin Finck ExternalConnection_QueryInterface,
131c2c66affSColin Finck ExternalConnection_AddRef,
132c2c66affSColin Finck ExternalConnection_Release,
133c2c66affSColin Finck ExternalConnection_AddConnection,
134c2c66affSColin Finck ExternalConnection_ReleaseConnection
135c2c66affSColin Finck };
136c2c66affSColin Finck
137c2c66affSColin Finck static IExternalConnection ExternalConnection = { &ExternalConnectionVtbl };
138c2c66affSColin Finck
Test_IClassFactory_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID * ppvObj)139c2c66affSColin Finck static HRESULT WINAPI Test_IClassFactory_QueryInterface(
140c2c66affSColin Finck LPCLASSFACTORY iface,
141c2c66affSColin Finck REFIID riid,
142c2c66affSColin Finck LPVOID *ppvObj)
143c2c66affSColin Finck {
144c2c66affSColin Finck if (ppvObj == NULL) return E_POINTER;
145c2c66affSColin Finck
146c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown) ||
147c2c66affSColin Finck IsEqualGUID(riid, &IID_IClassFactory))
148c2c66affSColin Finck {
149c2c66affSColin Finck *ppvObj = iface;
150c2c66affSColin Finck IClassFactory_AddRef(iface);
151c2c66affSColin Finck return S_OK;
152c2c66affSColin Finck }
153c2c66affSColin Finck
154c2c66affSColin Finck if(IsEqualGUID(riid, &IID_IExternalConnection)) {
155c2c66affSColin Finck *ppvObj = &ExternalConnection;
156c2c66affSColin Finck return S_OK;
157c2c66affSColin Finck }
158c2c66affSColin Finck
159c2c66affSColin Finck *ppvObj = NULL;
160c2c66affSColin Finck return E_NOINTERFACE;
161c2c66affSColin Finck }
162c2c66affSColin Finck
Test_IClassFactory_AddRef(LPCLASSFACTORY iface)163c2c66affSColin Finck static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
164c2c66affSColin Finck {
165c2c66affSColin Finck LockModule();
166c2c66affSColin Finck return 2; /* non-heap-based object */
167c2c66affSColin Finck }
168c2c66affSColin Finck
Test_IClassFactory_Release(LPCLASSFACTORY iface)169c2c66affSColin Finck static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
170c2c66affSColin Finck {
171c2c66affSColin Finck UnlockModule();
172c2c66affSColin Finck return 1; /* non-heap-based object */
173c2c66affSColin Finck }
174c2c66affSColin Finck
Test_IClassFactory_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pUnkOuter,REFIID riid,LPVOID * ppvObj)175c2c66affSColin Finck static HRESULT WINAPI Test_IClassFactory_CreateInstance(
176c2c66affSColin Finck LPCLASSFACTORY iface,
177c2c66affSColin Finck LPUNKNOWN pUnkOuter,
178c2c66affSColin Finck REFIID riid,
179c2c66affSColin Finck LPVOID *ppvObj)
180c2c66affSColin Finck {
181c2c66affSColin Finck return E_NOTIMPL;
182c2c66affSColin Finck }
183c2c66affSColin Finck
Test_IClassFactory_LockServer(LPCLASSFACTORY iface,BOOL fLock)184c2c66affSColin Finck static HRESULT WINAPI Test_IClassFactory_LockServer(
185c2c66affSColin Finck LPCLASSFACTORY iface,
186c2c66affSColin Finck BOOL fLock)
187c2c66affSColin Finck {
188c2c66affSColin Finck return S_OK;
189c2c66affSColin Finck }
190c2c66affSColin Finck
191c2c66affSColin Finck static const IClassFactoryVtbl TestClassFactory_Vtbl =
192c2c66affSColin Finck {
193c2c66affSColin Finck Test_IClassFactory_QueryInterface,
194c2c66affSColin Finck Test_IClassFactory_AddRef,
195c2c66affSColin Finck Test_IClassFactory_Release,
196c2c66affSColin Finck Test_IClassFactory_CreateInstance,
197c2c66affSColin Finck Test_IClassFactory_LockServer
198c2c66affSColin Finck };
199c2c66affSColin Finck
200c2c66affSColin Finck static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
201c2c66affSColin Finck
202c2c66affSColin Finck typedef struct
203c2c66affSColin Finck {
204c2c66affSColin Finck IUnknown IUnknown_iface;
205c2c66affSColin Finck ULONG refs;
206c2c66affSColin Finck } HeapUnknown;
207c2c66affSColin Finck
impl_from_IUnknown(IUnknown * iface)208c2c66affSColin Finck static inline HeapUnknown *impl_from_IUnknown(IUnknown *iface)
209c2c66affSColin Finck {
210c2c66affSColin Finck return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface);
211c2c66affSColin Finck }
212c2c66affSColin Finck
HeapUnknown_QueryInterface(IUnknown * iface,REFIID riid,void ** ppv)213c2c66affSColin Finck static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
214c2c66affSColin Finck {
215c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown))
216c2c66affSColin Finck {
217c2c66affSColin Finck IUnknown_AddRef(iface);
218c2c66affSColin Finck *ppv = iface;
219c2c66affSColin Finck return S_OK;
220c2c66affSColin Finck }
221c2c66affSColin Finck *ppv = NULL;
222c2c66affSColin Finck return E_NOINTERFACE;
223c2c66affSColin Finck }
224c2c66affSColin Finck
HeapUnknown_AddRef(IUnknown * iface)225c2c66affSColin Finck static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
226c2c66affSColin Finck {
227c2c66affSColin Finck HeapUnknown *This = impl_from_IUnknown(iface);
228c2c66affSColin Finck return InterlockedIncrement((LONG*)&This->refs);
229c2c66affSColin Finck }
230c2c66affSColin Finck
HeapUnknown_Release(IUnknown * iface)231c2c66affSColin Finck static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
232c2c66affSColin Finck {
233c2c66affSColin Finck HeapUnknown *This = impl_from_IUnknown(iface);
234c2c66affSColin Finck ULONG refs = InterlockedDecrement((LONG*)&This->refs);
235c2c66affSColin Finck if (!refs) HeapFree(GetProcessHeap(), 0, This);
236c2c66affSColin Finck return refs;
237c2c66affSColin Finck }
238c2c66affSColin Finck
239c2c66affSColin Finck static const IUnknownVtbl HeapUnknown_Vtbl =
240c2c66affSColin Finck {
241c2c66affSColin Finck HeapUnknown_QueryInterface,
242c2c66affSColin Finck HeapUnknown_AddRef,
243c2c66affSColin Finck HeapUnknown_Release
244c2c66affSColin Finck };
245c2c66affSColin Finck
246c2c66affSColin Finck static HRESULT WINAPI
MonikerNoROTData_QueryInterface(IMoniker * iface,REFIID riid,void ** ppvObject)247c2c66affSColin Finck MonikerNoROTData_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
248c2c66affSColin Finck {
249c2c66affSColin Finck if (!ppvObject)
250c2c66affSColin Finck return E_INVALIDARG;
251c2c66affSColin Finck
252c2c66affSColin Finck *ppvObject = 0;
253c2c66affSColin Finck
254c2c66affSColin Finck if (IsEqualIID(&IID_IUnknown, riid) ||
255c2c66affSColin Finck IsEqualIID(&IID_IPersist, riid) ||
256c2c66affSColin Finck IsEqualIID(&IID_IPersistStream,riid) ||
257c2c66affSColin Finck IsEqualIID(&IID_IMoniker, riid))
258c2c66affSColin Finck *ppvObject = iface;
259c2c66affSColin Finck if (IsEqualIID(&IID_IROTData, riid))
260c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
261c2c66affSColin Finck
262c2c66affSColin Finck if ((*ppvObject)==0)
263c2c66affSColin Finck return E_NOINTERFACE;
264c2c66affSColin Finck
265c2c66affSColin Finck IMoniker_AddRef(iface);
266c2c66affSColin Finck
267c2c66affSColin Finck return S_OK;
268c2c66affSColin Finck }
269c2c66affSColin Finck
270c2c66affSColin Finck static ULONG WINAPI
Moniker_AddRef(IMoniker * iface)271c2c66affSColin Finck Moniker_AddRef(IMoniker* iface)
272c2c66affSColin Finck {
273c2c66affSColin Finck return 2;
274c2c66affSColin Finck }
275c2c66affSColin Finck
276c2c66affSColin Finck static ULONG WINAPI
Moniker_Release(IMoniker * iface)277c2c66affSColin Finck Moniker_Release(IMoniker* iface)
278c2c66affSColin Finck {
279c2c66affSColin Finck return 1;
280c2c66affSColin Finck }
281c2c66affSColin Finck
282c2c66affSColin Finck static HRESULT WINAPI
Moniker_GetClassID(IMoniker * iface,CLSID * pClassID)283c2c66affSColin Finck Moniker_GetClassID(IMoniker* iface, CLSID *pClassID)
284c2c66affSColin Finck {
285c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_GetClassID");
286c2c66affSColin Finck
287c2c66affSColin Finck *pClassID = CLSID_TestMoniker;
288c2c66affSColin Finck
289c2c66affSColin Finck return S_OK;
290c2c66affSColin Finck }
291c2c66affSColin Finck
292c2c66affSColin Finck static HRESULT WINAPI
Moniker_IsDirty(IMoniker * iface)293c2c66affSColin Finck Moniker_IsDirty(IMoniker* iface)
294c2c66affSColin Finck {
295c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_IsDirty");
296c2c66affSColin Finck
297c2c66affSColin Finck return S_FALSE;
298c2c66affSColin Finck }
299c2c66affSColin Finck
300c2c66affSColin Finck static HRESULT WINAPI
Moniker_Load(IMoniker * iface,IStream * pStm)301c2c66affSColin Finck Moniker_Load(IMoniker* iface, IStream* pStm)
302c2c66affSColin Finck {
303c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_Load");
304c2c66affSColin Finck return E_NOTIMPL;
305c2c66affSColin Finck }
306c2c66affSColin Finck
307c2c66affSColin Finck static HRESULT WINAPI
Moniker_Save(IMoniker * iface,IStream * pStm,BOOL fClearDirty)308c2c66affSColin Finck Moniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
309c2c66affSColin Finck {
310c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_Save");
311c2c66affSColin Finck return E_NOTIMPL;
312c2c66affSColin Finck }
313c2c66affSColin Finck
314c2c66affSColin Finck static HRESULT WINAPI
Moniker_GetSizeMax(IMoniker * iface,ULARGE_INTEGER * pcbSize)315c2c66affSColin Finck Moniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
316c2c66affSColin Finck {
317c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
318c2c66affSColin Finck return E_NOTIMPL;
319c2c66affSColin Finck }
320c2c66affSColin Finck
321c2c66affSColin Finck static HRESULT WINAPI
Moniker_BindToObject(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,REFIID riid,VOID ** ppvResult)322c2c66affSColin Finck Moniker_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
323c2c66affSColin Finck REFIID riid, VOID** ppvResult)
324c2c66affSColin Finck {
325c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_BindToObject");
326c2c66affSColin Finck return E_NOTIMPL;
327c2c66affSColin Finck }
328c2c66affSColin Finck
329c2c66affSColin Finck static HRESULT WINAPI
Moniker_BindToStorage(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,REFIID riid,VOID ** ppvObject)330c2c66affSColin Finck Moniker_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
331c2c66affSColin Finck REFIID riid, VOID** ppvObject)
332c2c66affSColin Finck {
333c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
334c2c66affSColin Finck return E_NOTIMPL;
335c2c66affSColin Finck }
336c2c66affSColin Finck
337c2c66affSColin Finck static HRESULT WINAPI
Moniker_Reduce(IMoniker * iface,IBindCtx * pbc,DWORD dwReduceHowFar,IMoniker ** ppmkToLeft,IMoniker ** ppmkReduced)338c2c66affSColin Finck Moniker_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
339c2c66affSColin Finck IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
340c2c66affSColin Finck {
341c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_Reduce");
342c2c66affSColin Finck
343c2c66affSColin Finck if (ppmkReduced==NULL)
344c2c66affSColin Finck return E_POINTER;
345c2c66affSColin Finck
346c2c66affSColin Finck IMoniker_AddRef(iface);
347c2c66affSColin Finck
348c2c66affSColin Finck *ppmkReduced=iface;
349c2c66affSColin Finck
350c2c66affSColin Finck return MK_S_REDUCED_TO_SELF;
351c2c66affSColin Finck }
352c2c66affSColin Finck
353c2c66affSColin Finck static HRESULT WINAPI
Moniker_ComposeWith(IMoniker * iface,IMoniker * pmkRight,BOOL fOnlyIfNotGeneric,IMoniker ** ppmkComposite)354c2c66affSColin Finck Moniker_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
355c2c66affSColin Finck BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
356c2c66affSColin Finck {
357c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
358c2c66affSColin Finck return E_NOTIMPL;
359c2c66affSColin Finck }
360c2c66affSColin Finck
361c2c66affSColin Finck static HRESULT WINAPI
Moniker_Enum(IMoniker * iface,BOOL fForward,IEnumMoniker ** ppenumMoniker)362c2c66affSColin Finck Moniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
363c2c66affSColin Finck {
364c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_Enum");
365c2c66affSColin Finck
366c2c66affSColin Finck if (ppenumMoniker == NULL)
367c2c66affSColin Finck return E_POINTER;
368c2c66affSColin Finck
369c2c66affSColin Finck *ppenumMoniker = NULL;
370c2c66affSColin Finck
371c2c66affSColin Finck return S_OK;
372c2c66affSColin Finck }
373c2c66affSColin Finck
374c2c66affSColin Finck static HRESULT WINAPI
Moniker_IsEqual(IMoniker * iface,IMoniker * pmkOtherMoniker)375c2c66affSColin Finck Moniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
376c2c66affSColin Finck {
377c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_IsEqual");
378c2c66affSColin Finck return E_NOTIMPL;
379c2c66affSColin Finck }
380c2c66affSColin Finck
381c2c66affSColin Finck static HRESULT WINAPI
Moniker_Hash(IMoniker * iface,DWORD * pdwHash)382c2c66affSColin Finck Moniker_Hash(IMoniker* iface,DWORD* pdwHash)
383c2c66affSColin Finck {
384c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_Hash");
385c2c66affSColin Finck return E_NOTIMPL;
386c2c66affSColin Finck }
387c2c66affSColin Finck
388c2c66affSColin Finck static HRESULT WINAPI
Moniker_IsRunning(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,IMoniker * pmkNewlyRunning)389c2c66affSColin Finck Moniker_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
390c2c66affSColin Finck IMoniker* pmkNewlyRunning)
391c2c66affSColin Finck {
392c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_IsRunning");
393c2c66affSColin Finck return E_NOTIMPL;
394c2c66affSColin Finck }
395c2c66affSColin Finck
396c2c66affSColin Finck static HRESULT WINAPI
Moniker_GetTimeOfLastChange(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,FILETIME * pFileTime)397c2c66affSColin Finck Moniker_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
398c2c66affSColin Finck IMoniker* pmkToLeft, FILETIME* pFileTime)
399c2c66affSColin Finck {
400c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
401c2c66affSColin Finck return E_NOTIMPL;
402c2c66affSColin Finck }
403c2c66affSColin Finck
404c2c66affSColin Finck static HRESULT WINAPI
Moniker_Inverse(IMoniker * iface,IMoniker ** ppmk)405c2c66affSColin Finck Moniker_Inverse(IMoniker* iface,IMoniker** ppmk)
406c2c66affSColin Finck {
407c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_Inverse");
408c2c66affSColin Finck return E_NOTIMPL;
409c2c66affSColin Finck }
410c2c66affSColin Finck
411c2c66affSColin Finck static HRESULT WINAPI
Moniker_CommonPrefixWith(IMoniker * iface,IMoniker * pmkOther,IMoniker ** ppmkPrefix)412c2c66affSColin Finck Moniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
413c2c66affSColin Finck {
414c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
415c2c66affSColin Finck return E_NOTIMPL;
416c2c66affSColin Finck }
417c2c66affSColin Finck
418c2c66affSColin Finck static HRESULT WINAPI
Moniker_RelativePathTo(IMoniker * iface,IMoniker * pmOther,IMoniker ** ppmkRelPath)419c2c66affSColin Finck Moniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
420c2c66affSColin Finck {
421c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
422c2c66affSColin Finck return E_NOTIMPL;
423c2c66affSColin Finck }
424c2c66affSColin Finck
425c2c66affSColin Finck static HRESULT WINAPI
Moniker_GetDisplayName(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,LPOLESTR * ppszDisplayName)426c2c66affSColin Finck Moniker_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
427c2c66affSColin Finck IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
428c2c66affSColin Finck {
429c2c66affSColin Finck static const WCHAR wszDisplayName[] = {'*','*','G','e','m','m','a',0};
430c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
431c2c66affSColin Finck *ppszDisplayName = CoTaskMemAlloc(sizeof(wszDisplayName));
432c2c66affSColin Finck memcpy(*ppszDisplayName, wszDisplayName, sizeof(wszDisplayName));
433c2c66affSColin Finck return S_OK;
434c2c66affSColin Finck }
435c2c66affSColin Finck
436c2c66affSColin Finck static HRESULT WINAPI
Moniker_ParseDisplayName(IMoniker * iface,IBindCtx * pbc,IMoniker * pmkToLeft,LPOLESTR pszDisplayName,ULONG * pchEaten,IMoniker ** ppmkOut)437c2c66affSColin Finck Moniker_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
438c2c66affSColin Finck LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
439c2c66affSColin Finck {
440c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
441c2c66affSColin Finck return E_NOTIMPL;
442c2c66affSColin Finck }
443c2c66affSColin Finck
444c2c66affSColin Finck static HRESULT WINAPI
Moniker_IsSystemMoniker(IMoniker * iface,DWORD * pwdMksys)445c2c66affSColin Finck Moniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
446c2c66affSColin Finck {
447c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
448c2c66affSColin Finck
449c2c66affSColin Finck if (!pwdMksys)
450c2c66affSColin Finck return E_POINTER;
451c2c66affSColin Finck
452c2c66affSColin Finck (*pwdMksys)=MKSYS_NONE;
453c2c66affSColin Finck
454c2c66affSColin Finck return S_FALSE;
455c2c66affSColin Finck }
456c2c66affSColin Finck
457c2c66affSColin Finck static const IMonikerVtbl MonikerNoROTDataVtbl =
458c2c66affSColin Finck {
459c2c66affSColin Finck MonikerNoROTData_QueryInterface,
460c2c66affSColin Finck Moniker_AddRef,
461c2c66affSColin Finck Moniker_Release,
462c2c66affSColin Finck Moniker_GetClassID,
463c2c66affSColin Finck Moniker_IsDirty,
464c2c66affSColin Finck Moniker_Load,
465c2c66affSColin Finck Moniker_Save,
466c2c66affSColin Finck Moniker_GetSizeMax,
467c2c66affSColin Finck Moniker_BindToObject,
468c2c66affSColin Finck Moniker_BindToStorage,
469c2c66affSColin Finck Moniker_Reduce,
470c2c66affSColin Finck Moniker_ComposeWith,
471c2c66affSColin Finck Moniker_Enum,
472c2c66affSColin Finck Moniker_IsEqual,
473c2c66affSColin Finck Moniker_Hash,
474c2c66affSColin Finck Moniker_IsRunning,
475c2c66affSColin Finck Moniker_GetTimeOfLastChange,
476c2c66affSColin Finck Moniker_Inverse,
477c2c66affSColin Finck Moniker_CommonPrefixWith,
478c2c66affSColin Finck Moniker_RelativePathTo,
479c2c66affSColin Finck Moniker_GetDisplayName,
480c2c66affSColin Finck Moniker_ParseDisplayName,
481c2c66affSColin Finck Moniker_IsSystemMoniker
482c2c66affSColin Finck };
483c2c66affSColin Finck
484c2c66affSColin Finck static IMoniker MonikerNoROTData = { &MonikerNoROTDataVtbl };
485c2c66affSColin Finck
486c2c66affSColin Finck static IMoniker Moniker;
487c2c66affSColin Finck
488c2c66affSColin Finck static HRESULT WINAPI
ROTData_QueryInterface(IROTData * iface,REFIID riid,VOID ** ppvObject)489c2c66affSColin Finck ROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
490c2c66affSColin Finck {
491c2c66affSColin Finck return IMoniker_QueryInterface(&Moniker, riid, ppvObject);
492c2c66affSColin Finck }
493c2c66affSColin Finck
494c2c66affSColin Finck static ULONG WINAPI
ROTData_AddRef(IROTData * iface)495c2c66affSColin Finck ROTData_AddRef(IROTData *iface)
496c2c66affSColin Finck {
497c2c66affSColin Finck return 2;
498c2c66affSColin Finck }
499c2c66affSColin Finck
500c2c66affSColin Finck static ULONG WINAPI
ROTData_Release(IROTData * iface)501c2c66affSColin Finck ROTData_Release(IROTData* iface)
502c2c66affSColin Finck {
503c2c66affSColin Finck return 1;
504c2c66affSColin Finck }
505c2c66affSColin Finck
506c2c66affSColin Finck static HRESULT WINAPI
ROTData_GetComparisonData(IROTData * iface,BYTE * pbData,ULONG cbMax,ULONG * pcbData)507c2c66affSColin Finck ROTData_GetComparisonData(IROTData* iface, BYTE* pbData,
508c2c66affSColin Finck ULONG cbMax, ULONG* pcbData)
509c2c66affSColin Finck {
510c2c66affSColin Finck CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
511c2c66affSColin Finck
512c2c66affSColin Finck *pcbData = 1;
513c2c66affSColin Finck if (cbMax < *pcbData)
514c2c66affSColin Finck return E_OUTOFMEMORY;
515c2c66affSColin Finck
516c2c66affSColin Finck *pbData = 0xde;
517c2c66affSColin Finck
518c2c66affSColin Finck return S_OK;
519c2c66affSColin Finck }
520c2c66affSColin Finck
521c2c66affSColin Finck static IROTDataVtbl ROTDataVtbl =
522c2c66affSColin Finck {
523c2c66affSColin Finck ROTData_QueryInterface,
524c2c66affSColin Finck ROTData_AddRef,
525c2c66affSColin Finck ROTData_Release,
526c2c66affSColin Finck ROTData_GetComparisonData
527c2c66affSColin Finck };
528c2c66affSColin Finck
529c2c66affSColin Finck static IROTData ROTData = { &ROTDataVtbl };
530c2c66affSColin Finck
531c2c66affSColin Finck static HRESULT WINAPI
Moniker_QueryInterface(IMoniker * iface,REFIID riid,void ** ppvObject)532c2c66affSColin Finck Moniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
533c2c66affSColin Finck {
534c2c66affSColin Finck if (!ppvObject)
535c2c66affSColin Finck return E_INVALIDARG;
536c2c66affSColin Finck
537c2c66affSColin Finck *ppvObject = 0;
538c2c66affSColin Finck
539c2c66affSColin Finck if (IsEqualIID(&IID_IUnknown, riid) ||
540c2c66affSColin Finck IsEqualIID(&IID_IPersist, riid) ||
541c2c66affSColin Finck IsEqualIID(&IID_IPersistStream,riid) ||
542c2c66affSColin Finck IsEqualIID(&IID_IMoniker, riid))
543c2c66affSColin Finck *ppvObject = iface;
544c2c66affSColin Finck if (IsEqualIID(&IID_IROTData, riid))
545c2c66affSColin Finck {
546c2c66affSColin Finck CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
547c2c66affSColin Finck *ppvObject = &ROTData;
548c2c66affSColin Finck }
549c2c66affSColin Finck
550c2c66affSColin Finck if ((*ppvObject)==0)
551c2c66affSColin Finck return E_NOINTERFACE;
552c2c66affSColin Finck
553c2c66affSColin Finck IMoniker_AddRef(iface);
554c2c66affSColin Finck
555c2c66affSColin Finck return S_OK;
556c2c66affSColin Finck }
557c2c66affSColin Finck
558c2c66affSColin Finck static const IMonikerVtbl MonikerVtbl =
559c2c66affSColin Finck {
560c2c66affSColin Finck Moniker_QueryInterface,
561c2c66affSColin Finck Moniker_AddRef,
562c2c66affSColin Finck Moniker_Release,
563c2c66affSColin Finck Moniker_GetClassID,
564c2c66affSColin Finck Moniker_IsDirty,
565c2c66affSColin Finck Moniker_Load,
566c2c66affSColin Finck Moniker_Save,
567c2c66affSColin Finck Moniker_GetSizeMax,
568c2c66affSColin Finck Moniker_BindToObject,
569c2c66affSColin Finck Moniker_BindToStorage,
570c2c66affSColin Finck Moniker_Reduce,
571c2c66affSColin Finck Moniker_ComposeWith,
572c2c66affSColin Finck Moniker_Enum,
573c2c66affSColin Finck Moniker_IsEqual,
574c2c66affSColin Finck Moniker_Hash,
575c2c66affSColin Finck Moniker_IsRunning,
576c2c66affSColin Finck Moniker_GetTimeOfLastChange,
577c2c66affSColin Finck Moniker_Inverse,
578c2c66affSColin Finck Moniker_CommonPrefixWith,
579c2c66affSColin Finck Moniker_RelativePathTo,
580c2c66affSColin Finck Moniker_GetDisplayName,
581c2c66affSColin Finck Moniker_ParseDisplayName,
582c2c66affSColin Finck Moniker_IsSystemMoniker
583c2c66affSColin Finck };
584c2c66affSColin Finck
585c2c66affSColin Finck static IMoniker Moniker = { &MonikerVtbl };
586c2c66affSColin Finck
test_ROT(void)587c2c66affSColin Finck static void test_ROT(void)
588c2c66affSColin Finck {
589c2c66affSColin Finck static const WCHAR wszFileName[] = {'B','E','2','0','E','2','F','5','-',
590c2c66affSColin Finck '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
591c2c66affSColin Finck '2','0','4','6','E','5','8','6','C','9','2','5',0};
592c2c66affSColin Finck HRESULT hr;
593c2c66affSColin Finck IMoniker *pMoniker = NULL;
594c2c66affSColin Finck IRunningObjectTable *pROT = NULL;
595c2c66affSColin Finck DWORD dwCookie;
596c2c66affSColin Finck static const char *methods_register_no_ROTData[] =
597c2c66affSColin Finck {
598c2c66affSColin Finck "Moniker_Reduce",
599c2c66affSColin Finck "Moniker_GetTimeOfLastChange",
600c2c66affSColin Finck "Moniker_QueryInterface(IID_IROTData)",
601c2c66affSColin Finck "Moniker_GetDisplayName",
602c2c66affSColin Finck "Moniker_GetClassID",
603c2c66affSColin Finck NULL
604c2c66affSColin Finck };
605c2c66affSColin Finck static const char *methods_register[] =
606c2c66affSColin Finck {
607c2c66affSColin Finck "Moniker_Reduce",
608c2c66affSColin Finck "Moniker_GetTimeOfLastChange",
609c2c66affSColin Finck "Moniker_QueryInterface(IID_IROTData)",
610c2c66affSColin Finck "ROTData_GetComparisonData",
611c2c66affSColin Finck NULL
612c2c66affSColin Finck };
613c2c66affSColin Finck static const char *methods_isrunning_no_ROTData[] =
614c2c66affSColin Finck {
615c2c66affSColin Finck "Moniker_Reduce",
616c2c66affSColin Finck "Moniker_QueryInterface(IID_IROTData)",
617c2c66affSColin Finck "Moniker_GetDisplayName",
618c2c66affSColin Finck "Moniker_GetClassID",
619c2c66affSColin Finck NULL
620c2c66affSColin Finck };
621c2c66affSColin Finck static const char *methods_isrunning[] =
622c2c66affSColin Finck {
623c2c66affSColin Finck "Moniker_Reduce",
624c2c66affSColin Finck "Moniker_QueryInterface(IID_IROTData)",
625c2c66affSColin Finck "ROTData_GetComparisonData",
626c2c66affSColin Finck NULL
627c2c66affSColin Finck };
628c2c66affSColin Finck
629c2c66affSColin Finck cLocks = 0;
630c2c66affSColin Finck
631c2c66affSColin Finck hr = GetRunningObjectTable(0, &pROT);
632c2c66affSColin Finck ok_ole_success(hr, GetRunningObjectTable);
633c2c66affSColin Finck
634c2c66affSColin Finck expected_method_list = methods_register_no_ROTData;
635c2c66affSColin Finck external_connections = 0;
636c2c66affSColin Finck /* try with our own moniker that doesn't support IROTData */
637c2c66affSColin Finck hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
638c2c66affSColin Finck (IUnknown*)&Test_ClassFactory, &MonikerNoROTData, &dwCookie);
639c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Register);
640c2c66affSColin Finck ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
641c2c66affSColin Finck ok(external_connections == 1, "external_connections = %d\n", external_connections);
642c2c66affSColin Finck
643c2c66affSColin Finck ok_more_than_one_lock();
644c2c66affSColin Finck
645c2c66affSColin Finck expected_method_list = methods_isrunning_no_ROTData;
646c2c66affSColin Finck hr = IRunningObjectTable_IsRunning(pROT, &MonikerNoROTData);
647c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_IsRunning);
648c2c66affSColin Finck ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
649c2c66affSColin Finck
650c2c66affSColin Finck hr = IRunningObjectTable_Revoke(pROT, dwCookie);
651c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Revoke);
652c2c66affSColin Finck ok(external_connections == 0, "external_connections = %d\n", external_connections);
653c2c66affSColin Finck
654c2c66affSColin Finck ok_no_locks();
655c2c66affSColin Finck
656c2c66affSColin Finck expected_method_list = methods_register;
657c2c66affSColin Finck /* try with our own moniker */
658c2c66affSColin Finck hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
659c2c66affSColin Finck (IUnknown*)&Test_ClassFactory, &Moniker, &dwCookie);
660c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Register);
661c2c66affSColin Finck ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
662c2c66affSColin Finck
663c2c66affSColin Finck ok_more_than_one_lock();
664c2c66affSColin Finck
665c2c66affSColin Finck expected_method_list = methods_isrunning;
666c2c66affSColin Finck hr = IRunningObjectTable_IsRunning(pROT, &Moniker);
667c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_IsRunning);
668c2c66affSColin Finck ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
669c2c66affSColin Finck
670c2c66affSColin Finck hr = IRunningObjectTable_Revoke(pROT, dwCookie);
671c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Revoke);
672c2c66affSColin Finck
673c2c66affSColin Finck ok_no_locks();
674c2c66affSColin Finck
675c2c66affSColin Finck hr = CreateFileMoniker(wszFileName, &pMoniker);
676c2c66affSColin Finck ok_ole_success(hr, CreateClassMoniker);
677c2c66affSColin Finck
678c2c66affSColin Finck /* test flags: 0 */
679c2c66affSColin Finck external_connections = 0;
680c2c66affSColin Finck hr = IRunningObjectTable_Register(pROT, 0, (IUnknown*)&Test_ClassFactory,
681c2c66affSColin Finck pMoniker, &dwCookie);
682c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Register);
683c2c66affSColin Finck ok(external_connections == 0, "external_connections = %d\n", external_connections);
684c2c66affSColin Finck
685c2c66affSColin Finck ok_more_than_one_lock();
686c2c66affSColin Finck
687c2c66affSColin Finck hr = IRunningObjectTable_Revoke(pROT, dwCookie);
688c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Revoke);
689c2c66affSColin Finck
690c2c66affSColin Finck ok_no_locks();
691c2c66affSColin Finck
692c2c66affSColin Finck /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
693c2c66affSColin Finck hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
694c2c66affSColin Finck (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
695c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Register);
696c2c66affSColin Finck
697c2c66affSColin Finck ok_more_than_one_lock();
698c2c66affSColin Finck
699c2c66affSColin Finck hr = IRunningObjectTable_Revoke(pROT, dwCookie);
700c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Revoke);
701c2c66affSColin Finck
702c2c66affSColin Finck ok_no_locks();
703c2c66affSColin Finck
704c2c66affSColin Finck /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
705c2c66affSColin Finck /* only succeeds when process is started by SCM and has LocalService
706c2c66affSColin Finck * or RunAs AppId values */
707c2c66affSColin Finck hr = IRunningObjectTable_Register(pROT,
708c2c66affSColin Finck ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT,
709c2c66affSColin Finck (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
710c2c66affSColin Finck todo_wine {
711c2c66affSColin Finck ok(hr == CO_E_WRONG_SERVER_IDENTITY ||
712c2c66affSColin Finck broken(hr == S_OK) /* Win9x */,
713c2c66affSColin Finck "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr);
714c2c66affSColin Finck }
715c2c66affSColin Finck if (hr == S_OK) IRunningObjectTable_Revoke(pROT, dwCookie);
716c2c66affSColin Finck
717c2c66affSColin Finck hr = IRunningObjectTable_Register(pROT, 0xdeadbeef,
718c2c66affSColin Finck (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
719c2c66affSColin Finck ok(hr == E_INVALIDARG, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr);
720c2c66affSColin Finck
721c2c66affSColin Finck IMoniker_Release(pMoniker);
722c2c66affSColin Finck
723c2c66affSColin Finck IRunningObjectTable_Release(pROT);
724c2c66affSColin Finck }
725c2c66affSColin Finck
test_ROT_multiple_entries(void)726c2c66affSColin Finck static void test_ROT_multiple_entries(void)
727c2c66affSColin Finck {
728c2c66affSColin Finck HRESULT hr;
729c2c66affSColin Finck IMoniker *pMoniker = NULL;
730c2c66affSColin Finck IRunningObjectTable *pROT = NULL;
731c2c66affSColin Finck DWORD dwCookie1, dwCookie2;
732c2c66affSColin Finck IUnknown *pObject = NULL;
733c2c66affSColin Finck static const WCHAR moniker_path[] =
734c2c66affSColin Finck {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0};
735c2c66affSColin Finck
736c2c66affSColin Finck hr = GetRunningObjectTable(0, &pROT);
737c2c66affSColin Finck ok_ole_success(hr, GetRunningObjectTable);
738c2c66affSColin Finck
739c2c66affSColin Finck hr = CreateFileMoniker(moniker_path, &pMoniker);
740c2c66affSColin Finck ok_ole_success(hr, CreateFileMoniker);
741c2c66affSColin Finck
742c2c66affSColin Finck hr = IRunningObjectTable_Register(pROT, 0, (IUnknown *)&Test_ClassFactory, pMoniker, &dwCookie1);
743c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Register);
744c2c66affSColin Finck
745c2c66affSColin Finck hr = IRunningObjectTable_Register(pROT, 0, (IUnknown *)&Test_ClassFactory, pMoniker, &dwCookie2);
746c2c66affSColin Finck ok(hr == MK_S_MONIKERALREADYREGISTERED, "IRunningObjectTable_Register should have returned MK_S_MONIKERALREADYREGISTERED instead of 0x%08x\n", hr);
747c2c66affSColin Finck
748c2c66affSColin Finck ok(dwCookie1 != dwCookie2, "cookie returned for registering duplicate object shouldn't match cookie of original object (0x%x)\n", dwCookie1);
749c2c66affSColin Finck
750c2c66affSColin Finck hr = IRunningObjectTable_GetObject(pROT, pMoniker, &pObject);
751c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_GetObject);
752c2c66affSColin Finck IUnknown_Release(pObject);
753c2c66affSColin Finck
754c2c66affSColin Finck hr = IRunningObjectTable_Revoke(pROT, dwCookie1);
755c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Revoke);
756c2c66affSColin Finck
757c2c66affSColin Finck hr = IRunningObjectTable_GetObject(pROT, pMoniker, &pObject);
758c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_GetObject);
759c2c66affSColin Finck IUnknown_Release(pObject);
760c2c66affSColin Finck
761c2c66affSColin Finck hr = IRunningObjectTable_Revoke(pROT, dwCookie2);
762c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Revoke);
763c2c66affSColin Finck
764c2c66affSColin Finck IMoniker_Release(pMoniker);
765c2c66affSColin Finck
766c2c66affSColin Finck IRunningObjectTable_Release(pROT);
767c2c66affSColin Finck }
768c2c66affSColin Finck
ParseDisplayName_QueryInterface(IParseDisplayName * iface,REFIID riid,void ** ppv)769c2c66affSColin Finck static HRESULT WINAPI ParseDisplayName_QueryInterface(IParseDisplayName *iface, REFIID riid, void **ppv)
770c2c66affSColin Finck {
771c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown) ||
772c2c66affSColin Finck IsEqualIID(riid, &IID_IParseDisplayName))
773c2c66affSColin Finck {
774c2c66affSColin Finck *ppv = iface;
775c2c66affSColin Finck IParseDisplayName_AddRef(iface);
776c2c66affSColin Finck return S_OK;
777c2c66affSColin Finck }
778c2c66affSColin Finck *ppv = NULL;
779c2c66affSColin Finck return E_NOINTERFACE;
780c2c66affSColin Finck }
781c2c66affSColin Finck
ParseDisplayName_AddRef(IParseDisplayName * iface)782c2c66affSColin Finck static ULONG WINAPI ParseDisplayName_AddRef(IParseDisplayName *iface)
783c2c66affSColin Finck {
784c2c66affSColin Finck return 2;
785c2c66affSColin Finck }
786c2c66affSColin Finck
ParseDisplayName_Release(IParseDisplayName * iface)787c2c66affSColin Finck static ULONG WINAPI ParseDisplayName_Release(IParseDisplayName *iface)
788c2c66affSColin Finck {
789c2c66affSColin Finck return 1;
790c2c66affSColin Finck }
791c2c66affSColin Finck
792c2c66affSColin Finck static LPCWSTR expected_display_name;
793c2c66affSColin Finck
ParseDisplayName_ParseDisplayName(IParseDisplayName * iface,IBindCtx * pbc,LPOLESTR pszDisplayName,ULONG * pchEaten,IMoniker ** ppmkOut)794c2c66affSColin Finck static HRESULT WINAPI ParseDisplayName_ParseDisplayName(IParseDisplayName *iface,
795c2c66affSColin Finck IBindCtx *pbc,
796c2c66affSColin Finck LPOLESTR pszDisplayName,
797c2c66affSColin Finck ULONG *pchEaten,
798c2c66affSColin Finck IMoniker **ppmkOut)
799c2c66affSColin Finck {
800c2c66affSColin Finck char display_nameA[256];
801c2c66affSColin Finck WideCharToMultiByte(CP_ACP, 0, pszDisplayName, -1, display_nameA, sizeof(display_nameA), NULL, NULL);
802c2c66affSColin Finck ok(!lstrcmpW(pszDisplayName, expected_display_name), "unexpected display name \"%s\"\n", display_nameA);
803c2c66affSColin Finck ok(pszDisplayName == expected_display_name, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
804c2c66affSColin Finck *pchEaten = lstrlenW(pszDisplayName);
805c2c66affSColin Finck return CreateAntiMoniker(ppmkOut);
806c2c66affSColin Finck }
807c2c66affSColin Finck
808c2c66affSColin Finck static const IParseDisplayNameVtbl ParseDisplayName_Vtbl =
809c2c66affSColin Finck {
810c2c66affSColin Finck ParseDisplayName_QueryInterface,
811c2c66affSColin Finck ParseDisplayName_AddRef,
812c2c66affSColin Finck ParseDisplayName_Release,
813c2c66affSColin Finck ParseDisplayName_ParseDisplayName
814c2c66affSColin Finck };
815c2c66affSColin Finck
816c2c66affSColin Finck static IParseDisplayName ParseDisplayName = { &ParseDisplayName_Vtbl };
817c2c66affSColin Finck
count_moniker_matches(IBindCtx * pbc,IEnumMoniker * spEM)818c2c66affSColin Finck static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
819c2c66affSColin Finck {
820c2c66affSColin Finck IMoniker * spMoniker;
821c2c66affSColin Finck int monCnt=0, matchCnt=0;
822c2c66affSColin Finck
823c2c66affSColin Finck while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK))
824c2c66affSColin Finck {
825c2c66affSColin Finck HRESULT hr;
826c2c66affSColin Finck WCHAR * szDisplayn;
827c2c66affSColin Finck monCnt++;
828c2c66affSColin Finck hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL, &szDisplayn);
829c2c66affSColin Finck if (SUCCEEDED(hr))
830c2c66affSColin Finck {
831c2c66affSColin Finck if (!lstrcmpiW(szDisplayn, wszFileName1) || !lstrcmpiW(szDisplayn, wszFileName2))
832c2c66affSColin Finck matchCnt++;
833c2c66affSColin Finck CoTaskMemFree(szDisplayn);
834c2c66affSColin Finck }
835c2c66affSColin Finck }
836c2c66affSColin Finck trace("Total number of monikers is %i\n", monCnt);
837c2c66affSColin Finck return matchCnt;
838c2c66affSColin Finck }
839c2c66affSColin Finck
test_MkParseDisplayName(void)840c2c66affSColin Finck static void test_MkParseDisplayName(void)
841c2c66affSColin Finck {
842c2c66affSColin Finck IBindCtx * pbc = NULL;
843c2c66affSColin Finck HRESULT hr;
844c2c66affSColin Finck IMoniker * pmk = NULL;
845c2c66affSColin Finck IMoniker * pmk1 = NULL;
846c2c66affSColin Finck IMoniker * pmk2 = NULL;
847c2c66affSColin Finck ULONG eaten;
848c2c66affSColin Finck int matchCnt;
849c2c66affSColin Finck IUnknown * object = NULL;
850c2c66affSColin Finck
851c2c66affSColin Finck IUnknown *lpEM1;
852c2c66affSColin Finck
853c2c66affSColin Finck IEnumMoniker *spEM1 = NULL;
854c2c66affSColin Finck IEnumMoniker *spEM2 = NULL;
855c2c66affSColin Finck IEnumMoniker *spEM3 = NULL;
856c2c66affSColin Finck
857c2c66affSColin Finck DWORD pdwReg1=0;
858c2c66affSColin Finck DWORD grflags=0;
859c2c66affSColin Finck DWORD pdwReg2=0;
860c2c66affSColin Finck DWORD moniker_type;
861c2c66affSColin Finck IRunningObjectTable * pprot=NULL;
862c2c66affSColin Finck
863c2c66affSColin Finck /* CLSID of My Computer */
864c2c66affSColin Finck static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
865c2c66affSColin Finck '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};
866c2c66affSColin Finck static const WCHAR wszDisplayNameClsid[] = {'c','l','s','i','d',':',0};
867c2c66affSColin Finck static const WCHAR wszNonExistentProgId[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
868c2c66affSColin Finck static const WCHAR wszDisplayNameRunning[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
869c2c66affSColin Finck static const WCHAR wszDisplayNameProgId1[] = {'S','t','d','F','o','n','t',':',0};
870c2c66affSColin Finck static const WCHAR wszDisplayNameProgId2[] = {'@','S','t','d','F','o','n','t',0};
871c2c66affSColin Finck static const WCHAR wszDisplayNameProgIdFail[] = {'S','t','d','F','o','n','t',0};
872c2c66affSColin Finck static const WCHAR wszEmpty[] = {0};
873c2c66affSColin Finck char szDisplayNameFile[256];
874c2c66affSColin Finck WCHAR wszDisplayNameFile[256];
875c2c66affSColin Finck int i, len;
876c2c66affSColin Finck
877c2c66affSColin Finck const struct
878c2c66affSColin Finck {
879c2c66affSColin Finck LPBC *ppbc;
880c2c66affSColin Finck LPCOLESTR szDisplayName;
881c2c66affSColin Finck LPDWORD pchEaten;
882c2c66affSColin Finck LPMONIKER *ppmk;
883c2c66affSColin Finck } invalid_parameters[] =
884c2c66affSColin Finck {
885c2c66affSColin Finck {NULL, NULL, NULL, NULL},
886c2c66affSColin Finck {NULL, NULL, NULL, &pmk},
887c2c66affSColin Finck {NULL, NULL, &eaten, NULL},
888c2c66affSColin Finck {NULL, NULL, &eaten, &pmk},
889c2c66affSColin Finck {NULL, wszEmpty, NULL, NULL},
890c2c66affSColin Finck {NULL, wszEmpty, NULL, &pmk},
891c2c66affSColin Finck {NULL, wszEmpty, &eaten, NULL},
892c2c66affSColin Finck {NULL, wszEmpty, &eaten, &pmk},
893c2c66affSColin Finck {&pbc, NULL, NULL, NULL},
894c2c66affSColin Finck {&pbc, NULL, NULL, &pmk},
895c2c66affSColin Finck {&pbc, NULL, &eaten, NULL},
896c2c66affSColin Finck {&pbc, NULL, &eaten, &pmk},
897c2c66affSColin Finck {&pbc, wszEmpty, NULL, NULL},
898c2c66affSColin Finck {&pbc, wszEmpty, NULL, &pmk},
899c2c66affSColin Finck {&pbc, wszEmpty, &eaten, NULL},
900c2c66affSColin Finck {&pbc, wszEmpty, &eaten, &pmk},
901c2c66affSColin Finck };
902c2c66affSColin Finck
903c2c66affSColin Finck hr = CreateBindCtx(0, &pbc);
904c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
905c2c66affSColin Finck
906*5c1bcfecSAmine Khaldi for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
907c2c66affSColin Finck {
908c2c66affSColin Finck eaten = 0xdeadbeef;
909c2c66affSColin Finck pmk = (IMoniker *)0xdeadbeef;
910c2c66affSColin Finck hr = MkParseDisplayName(invalid_parameters[i].ppbc ? *invalid_parameters[i].ppbc : NULL,
911c2c66affSColin Finck invalid_parameters[i].szDisplayName,
912c2c66affSColin Finck invalid_parameters[i].pchEaten,
913c2c66affSColin Finck invalid_parameters[i].ppmk);
914c2c66affSColin Finck ok(hr == E_INVALIDARG, "[%d] MkParseDisplayName should have failed with E_INVALIDARG instead of 0x%08x\n", i, hr);
915c2c66affSColin Finck ok(eaten == 0xdeadbeef, "[%d] Processed character count should have been 0xdeadbeef instead of %u\n", i, eaten);
916c2c66affSColin Finck ok(pmk == (IMoniker *)0xdeadbeef, "[%d] Output moniker pointer should have been 0xdeadbeef instead of %p\n", i, pmk);
917c2c66affSColin Finck }
918c2c66affSColin Finck
919c2c66affSColin Finck eaten = 0xdeadbeef;
920c2c66affSColin Finck pmk = (IMoniker *)0xdeadbeef;
921c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszNonExistentProgId, &eaten, &pmk);
922c2c66affSColin Finck ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
923c2c66affSColin Finck "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
924c2c66affSColin Finck ok(eaten == 0, "Processed character count should have been 0 instead of %u\n", eaten);
925c2c66affSColin Finck ok(pmk == NULL, "Output moniker pointer should have been NULL instead of %p\n", pmk);
926c2c66affSColin Finck
927c2c66affSColin Finck /* no special handling of "clsid:" without the string form of the clsid
928c2c66affSColin Finck * following */
929c2c66affSColin Finck eaten = 0xdeadbeef;
930c2c66affSColin Finck pmk = (IMoniker *)0xdeadbeef;
931c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszDisplayNameClsid, &eaten, &pmk);
932c2c66affSColin Finck ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
933c2c66affSColin Finck "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
934c2c66affSColin Finck ok(eaten == 0, "Processed character count should have been 0 instead of %u\n", eaten);
935c2c66affSColin Finck ok(pmk == NULL, "Output moniker pointer should have been NULL instead of %p\n", pmk);
936c2c66affSColin Finck
937c2c66affSColin Finck /* shows clsid has higher precedence than a running object */
938c2c66affSColin Finck hr = CreateFileMoniker(wszDisplayName, &pmk);
939c2c66affSColin Finck ok_ole_success(hr, CreateFileMoniker);
940c2c66affSColin Finck hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
941c2c66affSColin Finck ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
942c2c66affSColin Finck hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
943c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Register);
944c2c66affSColin Finck IMoniker_Release(pmk);
945c2c66affSColin Finck pmk = NULL;
946c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
947c2c66affSColin Finck ok_ole_success(hr, MkParseDisplayName);
948*5c1bcfecSAmine Khaldi ok(eaten == ARRAY_SIZE(wszDisplayName) - 1,
949c2c66affSColin Finck "Processed character count should have been 43 instead of %u\n", eaten);
950c2c66affSColin Finck if (pmk)
951c2c66affSColin Finck {
952c2c66affSColin Finck IMoniker_IsSystemMoniker(pmk, &moniker_type);
953c2c66affSColin Finck ok(moniker_type == MKSYS_CLASSMONIKER, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type);
954c2c66affSColin Finck IMoniker_Release(pmk);
955c2c66affSColin Finck }
956c2c66affSColin Finck hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
957c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Revoke);
958c2c66affSColin Finck IRunningObjectTable_Release(pprot);
959c2c66affSColin Finck
960c2c66affSColin Finck hr = CreateFileMoniker(wszDisplayNameRunning, &pmk);
961c2c66affSColin Finck ok_ole_success(hr, CreateFileMoniker);
962c2c66affSColin Finck hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
963c2c66affSColin Finck ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
964c2c66affSColin Finck hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
965c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Register);
966c2c66affSColin Finck IMoniker_Release(pmk);
967c2c66affSColin Finck pmk = NULL;
968c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
969c2c66affSColin Finck ok_ole_success(hr, MkParseDisplayName);
970*5c1bcfecSAmine Khaldi ok(eaten == ARRAY_SIZE(wszDisplayNameRunning) - 1,
971c2c66affSColin Finck "Processed character count should have been 15 instead of %u\n", eaten);
972c2c66affSColin Finck if (pmk)
973c2c66affSColin Finck {
974c2c66affSColin Finck IMoniker_IsSystemMoniker(pmk, &moniker_type);
975c2c66affSColin Finck ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
976c2c66affSColin Finck IMoniker_Release(pmk);
977c2c66affSColin Finck }
978c2c66affSColin Finck hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
979c2c66affSColin Finck ok_ole_success(hr, IRunningObjectTable_Revoke);
980c2c66affSColin Finck IRunningObjectTable_Release(pprot);
981c2c66affSColin Finck
982c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_StdFont, (IUnknown *)&ParseDisplayName, CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &pdwReg1);
983c2c66affSColin Finck ok_ole_success(hr, CoRegisterClassObject);
984c2c66affSColin Finck
985c2c66affSColin Finck expected_display_name = wszDisplayNameProgId1;
986c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
987c2c66affSColin Finck ok_ole_success(hr, MkParseDisplayName);
988*5c1bcfecSAmine Khaldi ok(eaten == ARRAY_SIZE(wszDisplayNameProgId1) - 1,
989c2c66affSColin Finck "Processed character count should have been 8 instead of %u\n", eaten);
990c2c66affSColin Finck if (pmk)
991c2c66affSColin Finck {
992c2c66affSColin Finck IMoniker_IsSystemMoniker(pmk, &moniker_type);
993c2c66affSColin Finck ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
994c2c66affSColin Finck IMoniker_Release(pmk);
995c2c66affSColin Finck }
996c2c66affSColin Finck
997c2c66affSColin Finck expected_display_name = wszDisplayNameProgId2;
998c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
999c2c66affSColin Finck ok_ole_success(hr, MkParseDisplayName);
1000*5c1bcfecSAmine Khaldi ok(eaten == ARRAY_SIZE(wszDisplayNameProgId2) - 1,
1001c2c66affSColin Finck "Processed character count should have been 8 instead of %u\n", eaten);
1002c2c66affSColin Finck if (pmk)
1003c2c66affSColin Finck {
1004c2c66affSColin Finck IMoniker_IsSystemMoniker(pmk, &moniker_type);
1005c2c66affSColin Finck ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
1006c2c66affSColin Finck IMoniker_Release(pmk);
1007c2c66affSColin Finck }
1008c2c66affSColin Finck
1009c2c66affSColin Finck eaten = 0xdeadbeef;
1010c2c66affSColin Finck pmk = (IMoniker *)0xdeadbeef;
1011c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszDisplayNameProgIdFail, &eaten, &pmk);
1012c2c66affSColin Finck ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
1013c2c66affSColin Finck "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
1014c2c66affSColin Finck ok(eaten == 0, "Processed character count should have been 0 instead of %u\n", eaten);
1015c2c66affSColin Finck ok(pmk == NULL, "Output moniker pointer should have been NULL instead of %p\n", pmk);
1016c2c66affSColin Finck
1017c2c66affSColin Finck hr = CoRevokeClassObject(pdwReg1);
1018c2c66affSColin Finck ok_ole_success(hr, CoRevokeClassObject);
1019c2c66affSColin Finck
1020c2c66affSColin Finck GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
1021c2c66affSColin Finck strcat(szDisplayNameFile, "\\kernel32.dll");
1022*5c1bcfecSAmine Khaldi len = MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile,
1023*5c1bcfecSAmine Khaldi ARRAY_SIZE(wszDisplayNameFile));
1024c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
1025c2c66affSColin Finck ok_ole_success(hr, MkParseDisplayName);
1026c2c66affSColin Finck ok(eaten == len - 1, "Processed character count should have been %d instead of %u\n", len - 1, eaten);
1027c2c66affSColin Finck if (pmk)
1028c2c66affSColin Finck {
1029c2c66affSColin Finck IMoniker_IsSystemMoniker(pmk, &moniker_type);
1030c2c66affSColin Finck ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
1031c2c66affSColin Finck IMoniker_Release(pmk);
1032c2c66affSColin Finck }
1033c2c66affSColin Finck
1034c2c66affSColin Finck hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
1035c2c66affSColin Finck ok_ole_success(hr, MkParseDisplayName);
1036*5c1bcfecSAmine Khaldi ok(eaten == ARRAY_SIZE(wszDisplayName) - 1,
1037*5c1bcfecSAmine Khaldi "Processed character count should have been 43 instead of %u\n", eaten);
1038c2c66affSColin Finck
1039c2c66affSColin Finck if (pmk)
1040c2c66affSColin Finck {
1041c2c66affSColin Finck hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
1042c2c66affSColin Finck ok_ole_success(hr, IMoniker_BindToObject);
1043c2c66affSColin Finck
1044c2c66affSColin Finck if (SUCCEEDED(hr))
1045c2c66affSColin Finck IUnknown_Release(object);
1046c2c66affSColin Finck IMoniker_Release(pmk);
1047c2c66affSColin Finck }
1048c2c66affSColin Finck IBindCtx_Release(pbc);
1049c2c66affSColin Finck
1050c2c66affSColin Finck /* Test the EnumMoniker interface */
1051c2c66affSColin Finck hr = CreateBindCtx(0, &pbc);
1052c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
1053c2c66affSColin Finck
1054c2c66affSColin Finck hr = CreateFileMoniker(wszFileName1, &pmk1);
1055c2c66affSColin Finck ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
1056c2c66affSColin Finck hr = CreateFileMoniker(wszFileName2, &pmk2);
1057c2c66affSColin Finck ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
1058c2c66affSColin Finck hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
1059c2c66affSColin Finck ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr);
1060c2c66affSColin Finck
1061c2c66affSColin Finck /* Check EnumMoniker before registering */
1062c2c66affSColin Finck hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
1063c2c66affSColin Finck ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
1064c2c66affSColin Finck hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
1065c2c66affSColin Finck /* Register a couple of Monikers and check is ok */
1066c2c66affSColin Finck ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1);
1067c2c66affSColin Finck
1068c2c66affSColin Finck matchCnt = count_moniker_matches(pbc, spEM1);
1069c2c66affSColin Finck trace("Number of matches is %i\n", matchCnt);
1070c2c66affSColin Finck
1071c2c66affSColin Finck grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
1072c2c66affSColin Finck hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
1073c2c66affSColin Finck ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
1074c2c66affSColin Finck hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
1075c2c66affSColin Finck
1076c2c66affSColin Finck trace("IROT::Register\n");
1077c2c66affSColin Finck grflags=0;
1078c2c66affSColin Finck grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
1079c2c66affSColin Finck hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
1080c2c66affSColin Finck ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr,
1081c2c66affSColin Finck pprot, grflags, lpEM1, pmk2, pdwReg2);
1082c2c66affSColin Finck
1083c2c66affSColin Finck hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
1084c2c66affSColin Finck ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
1085c2c66affSColin Finck
1086c2c66affSColin Finck matchCnt = count_moniker_matches(pbc, spEM2);
1087c2c66affSColin Finck ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
1088c2c66affSColin Finck
1089c2c66affSColin Finck trace("IEnumMoniker::Clone\n");
1090c2c66affSColin Finck IEnumMoniker_Clone(spEM2, &spEM3);
1091c2c66affSColin Finck
1092c2c66affSColin Finck matchCnt = count_moniker_matches(pbc, spEM3);
1093c2c66affSColin Finck ok(matchCnt==0, "Number of matches should be equal to 0 not %i\n", matchCnt);
1094c2c66affSColin Finck trace("IEnumMoniker::Reset\n");
1095c2c66affSColin Finck IEnumMoniker_Reset(spEM3);
1096c2c66affSColin Finck
1097c2c66affSColin Finck matchCnt = count_moniker_matches(pbc, spEM3);
1098c2c66affSColin Finck ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
1099c2c66affSColin Finck
1100c2c66affSColin Finck IRunningObjectTable_Revoke(pprot,pdwReg1);
1101c2c66affSColin Finck IRunningObjectTable_Revoke(pprot,pdwReg2);
1102c2c66affSColin Finck IUnknown_Release(lpEM1);
1103c2c66affSColin Finck IEnumMoniker_Release(spEM1);
1104c2c66affSColin Finck IEnumMoniker_Release(spEM2);
1105c2c66affSColin Finck IEnumMoniker_Release(spEM3);
1106c2c66affSColin Finck IMoniker_Release(pmk1);
1107c2c66affSColin Finck IMoniker_Release(pmk2);
1108c2c66affSColin Finck IRunningObjectTable_Release(pprot);
1109c2c66affSColin Finck
1110c2c66affSColin Finck IBindCtx_Release(pbc);
1111c2c66affSColin Finck }
1112c2c66affSColin Finck
1113c2c66affSColin Finck static const LARGE_INTEGER llZero;
1114c2c66affSColin Finck
1115c2c66affSColin Finck static const BYTE expected_class_moniker_marshal_data[] =
1116c2c66affSColin Finck {
1117c2c66affSColin Finck 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1118c2c66affSColin Finck 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1119c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1120c2c66affSColin Finck 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1121c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1122c2c66affSColin Finck 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1123c2c66affSColin Finck 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1124c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1125c2c66affSColin Finck 0x00,0x00,0x00,0x00,
1126c2c66affSColin Finck };
1127c2c66affSColin Finck
1128c2c66affSColin Finck static const BYTE expected_class_moniker_saved_data[] =
1129c2c66affSColin Finck {
1130c2c66affSColin Finck 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1131c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1132c2c66affSColin Finck 0x00,0x00,0x00,0x00,
1133c2c66affSColin Finck };
1134c2c66affSColin Finck
1135c2c66affSColin Finck static const BYTE expected_class_moniker_comparison_data[] =
1136c2c66affSColin Finck {
1137c2c66affSColin Finck 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1138c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1139c2c66affSColin Finck 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1140c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1141c2c66affSColin Finck };
1142c2c66affSColin Finck
1143c2c66affSColin Finck static const WCHAR expected_class_moniker_display_name[] =
1144c2c66affSColin Finck {
1145c2c66affSColin Finck 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
1146c2c66affSColin Finck '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
1147c2c66affSColin Finck '0','0','0','0','4','6',':',0
1148c2c66affSColin Finck };
1149c2c66affSColin Finck
1150c2c66affSColin Finck static const BYTE expected_item_moniker_comparison_data[] =
1151c2c66affSColin Finck {
1152c2c66affSColin Finck 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1153c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1154c2c66affSColin Finck 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1155c2c66affSColin Finck 0x54,0x00,0x00,0x00,
1156c2c66affSColin Finck };
1157c2c66affSColin Finck
1158c2c66affSColin Finck static const BYTE expected_item_moniker_saved_data[] =
1159c2c66affSColin Finck {
1160c2c66affSColin Finck 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1161c2c66affSColin Finck 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1162c2c66affSColin Finck };
1163c2c66affSColin Finck
1164c2c66affSColin Finck static const BYTE expected_item_moniker_marshal_data[] =
1165c2c66affSColin Finck {
1166c2c66affSColin Finck 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1167c2c66affSColin Finck 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1168c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1169c2c66affSColin Finck 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1170c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1171c2c66affSColin Finck 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1172c2c66affSColin Finck 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1173c2c66affSColin Finck 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1174c2c66affSColin Finck };
1175c2c66affSColin Finck
1176c2c66affSColin Finck static const BYTE expected_anti_moniker_marshal_data[] =
1177c2c66affSColin Finck {
1178c2c66affSColin Finck 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1179c2c66affSColin Finck 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1180c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1181c2c66affSColin Finck 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1182c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1183c2c66affSColin Finck 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1184c2c66affSColin Finck 0x01,0x00,0x00,0x00,
1185c2c66affSColin Finck };
1186c2c66affSColin Finck
1187c2c66affSColin Finck static const BYTE expected_anti_moniker_saved_data[] =
1188c2c66affSColin Finck {
1189c2c66affSColin Finck 0x01,0x00,0x00,0x00,
1190c2c66affSColin Finck };
1191c2c66affSColin Finck
1192c2c66affSColin Finck static const BYTE expected_anti_moniker_comparison_data[] =
1193c2c66affSColin Finck {
1194c2c66affSColin Finck 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1195c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1196c2c66affSColin Finck 0x01,0x00,0x00,0x00,
1197c2c66affSColin Finck };
1198c2c66affSColin Finck
1199c2c66affSColin Finck static const BYTE expected_gc_moniker_marshal_data[] =
1200c2c66affSColin Finck {
1201c2c66affSColin Finck 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1202c2c66affSColin Finck 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1203c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1204c2c66affSColin Finck 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1205c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1206c2c66affSColin Finck 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1207c2c66affSColin Finck 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1208c2c66affSColin Finck 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1209c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1210c2c66affSColin Finck 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1211c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1212c2c66affSColin Finck 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1213c2c66affSColin Finck 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1214c2c66affSColin Finck 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1215c2c66affSColin Finck 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1216c2c66affSColin Finck 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1217c2c66affSColin Finck 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1218c2c66affSColin Finck 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1219c2c66affSColin Finck 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1220c2c66affSColin Finck 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1221c2c66affSColin Finck 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1222c2c66affSColin Finck 0x00,0x57,0x69,0x6e,0x65,0x00,
1223c2c66affSColin Finck };
1224c2c66affSColin Finck
1225c2c66affSColin Finck static const BYTE expected_gc_moniker_saved_data[] =
1226c2c66affSColin Finck {
1227c2c66affSColin Finck 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1228c2c66affSColin Finck 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1229c2c66affSColin Finck 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1230c2c66affSColin Finck 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1231c2c66affSColin Finck 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1232c2c66affSColin Finck 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1233c2c66affSColin Finck 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1234c2c66affSColin Finck 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1235c2c66affSColin Finck 0x65,0x00,
1236c2c66affSColin Finck };
1237c2c66affSColin Finck
1238c2c66affSColin Finck static const BYTE expected_gc_moniker_comparison_data[] =
1239c2c66affSColin Finck {
1240c2c66affSColin Finck 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1241c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1242c2c66affSColin Finck 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1243c2c66affSColin Finck 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1244c2c66affSColin Finck 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1245c2c66affSColin Finck 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1246c2c66affSColin Finck 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1247c2c66affSColin Finck 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1248c2c66affSColin Finck 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1249c2c66affSColin Finck };
1250c2c66affSColin Finck
test_moniker(const char * testname,IMoniker * moniker,const BYTE * expected_moniker_marshal_data,unsigned int sizeof_expected_moniker_marshal_data,const BYTE * expected_moniker_saved_data,unsigned int sizeof_expected_moniker_saved_data,const BYTE * expected_moniker_comparison_data,unsigned int sizeof_expected_moniker_comparison_data,LPCWSTR expected_display_name)1251c2c66affSColin Finck static void test_moniker(
1252c2c66affSColin Finck const char *testname, IMoniker *moniker,
1253c2c66affSColin Finck const BYTE *expected_moniker_marshal_data, unsigned int sizeof_expected_moniker_marshal_data,
1254c2c66affSColin Finck const BYTE *expected_moniker_saved_data, unsigned int sizeof_expected_moniker_saved_data,
1255c2c66affSColin Finck const BYTE *expected_moniker_comparison_data, unsigned int sizeof_expected_moniker_comparison_data,
1256c2c66affSColin Finck LPCWSTR expected_display_name)
1257c2c66affSColin Finck {
1258c2c66affSColin Finck IStream * stream;
1259c2c66affSColin Finck IROTData * rotdata;
1260c2c66affSColin Finck HRESULT hr;
1261c2c66affSColin Finck HGLOBAL hglobal;
1262c2c66affSColin Finck LPBYTE moniker_data;
1263c2c66affSColin Finck DWORD moniker_size;
1264c2c66affSColin Finck DWORD i;
1265c2c66affSColin Finck BOOL same;
1266c2c66affSColin Finck BYTE buffer[128];
1267c2c66affSColin Finck IMoniker * moniker_proxy;
1268c2c66affSColin Finck LPOLESTR display_name;
1269c2c66affSColin Finck IBindCtx *bindctx;
1270c2c66affSColin Finck
1271c2c66affSColin Finck hr = IMoniker_IsDirty(moniker);
1272c2c66affSColin Finck ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1273c2c66affSColin Finck
1274c2c66affSColin Finck /* Display Name */
1275c2c66affSColin Finck
1276c2c66affSColin Finck hr = CreateBindCtx(0, &bindctx);
1277c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
1278c2c66affSColin Finck
1279c2c66affSColin Finck hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1280c2c66affSColin Finck ok_ole_success(hr, IMoniker_GetDisplayName);
1281c2c66affSColin Finck ok(!lstrcmpW(display_name, expected_display_name), "%s: display name wasn't what was expected\n", testname);
1282c2c66affSColin Finck
1283c2c66affSColin Finck CoTaskMemFree(display_name);
1284c2c66affSColin Finck IBindCtx_Release(bindctx);
1285c2c66affSColin Finck
1286c2c66affSColin Finck hr = IMoniker_IsDirty(moniker);
1287c2c66affSColin Finck ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1288c2c66affSColin Finck
1289c2c66affSColin Finck /* IROTData::GetComparisonData test */
1290c2c66affSColin Finck
1291c2c66affSColin Finck hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1292c2c66affSColin Finck ok_ole_success(hr, IMoniker_QueryInterface_IID_IROTData);
1293c2c66affSColin Finck
1294c2c66affSColin Finck hr = IROTData_GetComparisonData(rotdata, buffer, sizeof(buffer), &moniker_size);
1295c2c66affSColin Finck ok_ole_success(hr, IROTData_GetComparisonData);
1296c2c66affSColin Finck
1297c2c66affSColin Finck if (hr != S_OK) moniker_size = 0;
1298c2c66affSColin Finck
1299c2c66affSColin Finck /* first check we have the right amount of data */
1300c2c66affSColin Finck ok(moniker_size == sizeof_expected_moniker_comparison_data,
1301c2c66affSColin Finck "%s: Size of comparison data differs (expected %d, actual %d)\n",
1302c2c66affSColin Finck testname, sizeof_expected_moniker_comparison_data, moniker_size);
1303c2c66affSColin Finck
1304c2c66affSColin Finck /* then do a byte-by-byte comparison */
1305c2c66affSColin Finck same = TRUE;
1306c2c66affSColin Finck for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
1307c2c66affSColin Finck {
1308c2c66affSColin Finck if (expected_moniker_comparison_data[i] != buffer[i])
1309c2c66affSColin Finck {
1310c2c66affSColin Finck same = FALSE;
1311c2c66affSColin Finck break;
1312c2c66affSColin Finck }
1313c2c66affSColin Finck }
1314c2c66affSColin Finck
1315c2c66affSColin Finck ok(same, "%s: Comparison data differs\n", testname);
1316c2c66affSColin Finck if (!same)
1317c2c66affSColin Finck {
1318c2c66affSColin Finck for (i = 0; i < moniker_size; i++)
1319c2c66affSColin Finck {
1320c2c66affSColin Finck if (i % 8 == 0) printf(" ");
1321c2c66affSColin Finck printf("0x%02x,", buffer[i]);
1322c2c66affSColin Finck if (i % 8 == 7) printf("\n");
1323c2c66affSColin Finck }
1324c2c66affSColin Finck printf("\n");
1325c2c66affSColin Finck }
1326c2c66affSColin Finck
1327c2c66affSColin Finck IROTData_Release(rotdata);
1328c2c66affSColin Finck
1329c2c66affSColin Finck hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1330c2c66affSColin Finck ok_ole_success(hr, CreateStreamOnHGlobal);
1331c2c66affSColin Finck
1332c2c66affSColin Finck /* Saving */
1333c2c66affSColin Finck
1334c2c66affSColin Finck hr = IMoniker_Save(moniker, stream, TRUE);
1335c2c66affSColin Finck ok_ole_success(hr, IMoniker_Save);
1336c2c66affSColin Finck
1337c2c66affSColin Finck hr = GetHGlobalFromStream(stream, &hglobal);
1338c2c66affSColin Finck ok_ole_success(hr, GetHGlobalFromStream);
1339c2c66affSColin Finck
1340c2c66affSColin Finck moniker_size = GlobalSize(hglobal);
1341c2c66affSColin Finck
1342c2c66affSColin Finck moniker_data = GlobalLock(hglobal);
1343c2c66affSColin Finck
1344c2c66affSColin Finck /* first check we have the right amount of data */
1345c2c66affSColin Finck ok(moniker_size == round_global_size(sizeof_expected_moniker_saved_data),
1346c2c66affSColin Finck "%s: Size of saved data differs (expected %d, actual %d)\n",
1347c2c66affSColin Finck testname, (DWORD)round_global_size(sizeof_expected_moniker_saved_data), moniker_size);
1348c2c66affSColin Finck
1349c2c66affSColin Finck /* then do a byte-by-byte comparison */
1350c2c66affSColin Finck same = TRUE;
1351c2c66affSColin Finck for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_saved_data)); i++)
1352c2c66affSColin Finck {
1353c2c66affSColin Finck if (expected_moniker_saved_data[i] != moniker_data[i])
1354c2c66affSColin Finck {
1355c2c66affSColin Finck same = FALSE;
1356c2c66affSColin Finck break;
1357c2c66affSColin Finck }
1358c2c66affSColin Finck }
1359c2c66affSColin Finck
1360c2c66affSColin Finck ok(same, "%s: Saved data differs\n", testname);
1361c2c66affSColin Finck if (!same)
1362c2c66affSColin Finck {
1363c2c66affSColin Finck for (i = 0; i < moniker_size; i++)
1364c2c66affSColin Finck {
1365c2c66affSColin Finck if (i % 8 == 0) printf(" ");
1366c2c66affSColin Finck printf("0x%02x,", moniker_data[i]);
1367c2c66affSColin Finck if (i % 8 == 7) printf("\n");
1368c2c66affSColin Finck }
1369c2c66affSColin Finck printf("\n");
1370c2c66affSColin Finck }
1371c2c66affSColin Finck
1372c2c66affSColin Finck GlobalUnlock(hglobal);
1373c2c66affSColin Finck
1374c2c66affSColin Finck IStream_Release(stream);
1375c2c66affSColin Finck
1376c2c66affSColin Finck /* Marshaling tests */
1377c2c66affSColin Finck
1378c2c66affSColin Finck hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1379c2c66affSColin Finck ok_ole_success(hr, CreateStreamOnHGlobal);
1380c2c66affSColin Finck
1381c2c66affSColin Finck hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1382c2c66affSColin Finck ok_ole_success(hr, CoMarshalInterface);
1383c2c66affSColin Finck
1384c2c66affSColin Finck hr = GetHGlobalFromStream(stream, &hglobal);
1385c2c66affSColin Finck ok_ole_success(hr, GetHGlobalFromStream);
1386c2c66affSColin Finck
1387c2c66affSColin Finck moniker_size = GlobalSize(hglobal);
1388c2c66affSColin Finck
1389c2c66affSColin Finck moniker_data = GlobalLock(hglobal);
1390c2c66affSColin Finck
1391c2c66affSColin Finck /* first check we have the right amount of data */
1392c2c66affSColin Finck ok(moniker_size == round_global_size(sizeof_expected_moniker_marshal_data),
1393c2c66affSColin Finck "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1394c2c66affSColin Finck testname, (DWORD)round_global_size(sizeof_expected_moniker_marshal_data), moniker_size);
1395c2c66affSColin Finck
1396c2c66affSColin Finck /* then do a byte-by-byte comparison */
1397c2c66affSColin Finck same = TRUE;
1398c2c66affSColin Finck if (expected_moniker_marshal_data)
1399c2c66affSColin Finck {
1400c2c66affSColin Finck for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_marshal_data)); i++)
1401c2c66affSColin Finck {
1402c2c66affSColin Finck if (expected_moniker_marshal_data[i] != moniker_data[i])
1403c2c66affSColin Finck {
1404c2c66affSColin Finck same = FALSE;
1405c2c66affSColin Finck break;
1406c2c66affSColin Finck }
1407c2c66affSColin Finck }
1408c2c66affSColin Finck }
1409c2c66affSColin Finck
1410c2c66affSColin Finck ok(same, "%s: Marshaled data differs\n", testname);
1411c2c66affSColin Finck if (!same)
1412c2c66affSColin Finck {
1413c2c66affSColin Finck for (i = 0; i < moniker_size; i++)
1414c2c66affSColin Finck {
1415c2c66affSColin Finck if (i % 8 == 0) printf(" ");
1416c2c66affSColin Finck printf("0x%02x,", moniker_data[i]);
1417c2c66affSColin Finck if (i % 8 == 7) printf("\n");
1418c2c66affSColin Finck }
1419c2c66affSColin Finck printf("\n");
1420c2c66affSColin Finck }
1421c2c66affSColin Finck
1422c2c66affSColin Finck GlobalUnlock(hglobal);
1423c2c66affSColin Finck
1424c2c66affSColin Finck IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1425c2c66affSColin Finck hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
1426c2c66affSColin Finck ok_ole_success(hr, CoUnmarshalInterface);
1427c2c66affSColin Finck
1428c2c66affSColin Finck IStream_Release(stream);
1429c2c66affSColin Finck IMoniker_Release(moniker_proxy);
1430c2c66affSColin Finck }
1431c2c66affSColin Finck
test_class_moniker(void)1432c2c66affSColin Finck static void test_class_moniker(void)
1433c2c66affSColin Finck {
1434c2c66affSColin Finck HRESULT hr;
1435c2c66affSColin Finck IMoniker *moniker;
1436c2c66affSColin Finck DWORD moniker_type;
1437c2c66affSColin Finck DWORD hash;
1438c2c66affSColin Finck IBindCtx *bindctx;
1439c2c66affSColin Finck IMoniker *inverse;
1440c2c66affSColin Finck IUnknown *unknown;
1441c2c66affSColin Finck FILETIME filetime;
1442c2c66affSColin Finck
1443c2c66affSColin Finck hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
1444c2c66affSColin Finck ok_ole_success(hr, CreateClassMoniker);
1445c2c66affSColin Finck if (!moniker) return;
1446c2c66affSColin Finck
1447c2c66affSColin Finck test_moniker("class moniker", moniker,
1448c2c66affSColin Finck expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
1449c2c66affSColin Finck expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
1450c2c66affSColin Finck expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
1451c2c66affSColin Finck expected_class_moniker_display_name);
1452c2c66affSColin Finck
1453c2c66affSColin Finck /* Hashing */
1454c2c66affSColin Finck
1455c2c66affSColin Finck hr = IMoniker_Hash(moniker, &hash);
1456c2c66affSColin Finck ok_ole_success(hr, IMoniker_Hash);
1457c2c66affSColin Finck
1458c2c66affSColin Finck ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
1459c2c66affSColin Finck "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1460c2c66affSColin Finck hash);
1461c2c66affSColin Finck
1462c2c66affSColin Finck /* IsSystemMoniker test */
1463c2c66affSColin Finck
1464c2c66affSColin Finck hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1465c2c66affSColin Finck ok_ole_success(hr, IMoniker_IsSystemMoniker);
1466c2c66affSColin Finck
1467c2c66affSColin Finck ok(moniker_type == MKSYS_CLASSMONIKER,
1468c2c66affSColin Finck "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1469c2c66affSColin Finck moniker_type);
1470c2c66affSColin Finck
1471c2c66affSColin Finck hr = CreateBindCtx(0, &bindctx);
1472c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
1473c2c66affSColin Finck
1474c2c66affSColin Finck /* IsRunning test */
1475c2c66affSColin Finck hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1476c2c66affSColin Finck ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1477c2c66affSColin Finck
1478c2c66affSColin Finck hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1479c2c66affSColin Finck ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1480c2c66affSColin Finck
1481c2c66affSColin Finck hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1482c2c66affSColin Finck ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
1483c2c66affSColin Finck
1484c2c66affSColin Finck hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1485c2c66affSColin Finck ok_ole_success(hr, IMoniker_BindToObject);
1486c2c66affSColin Finck IUnknown_Release(unknown);
1487c2c66affSColin Finck
1488c2c66affSColin Finck hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1489c2c66affSColin Finck ok_ole_success(hr, IMoniker_BindToStorage);
1490c2c66affSColin Finck IUnknown_Release(unknown);
1491c2c66affSColin Finck
1492c2c66affSColin Finck IBindCtx_Release(bindctx);
1493c2c66affSColin Finck
1494c2c66affSColin Finck hr = IMoniker_Inverse(moniker, &inverse);
1495c2c66affSColin Finck ok_ole_success(hr, IMoniker_Inverse);
1496c2c66affSColin Finck IMoniker_Release(inverse);
1497c2c66affSColin Finck
1498c2c66affSColin Finck IMoniker_Release(moniker);
1499c2c66affSColin Finck }
1500c2c66affSColin Finck
test_file_moniker(WCHAR * path)1501c2c66affSColin Finck static void test_file_moniker(WCHAR* path)
1502c2c66affSColin Finck {
1503c2c66affSColin Finck IStream *stream;
1504c2c66affSColin Finck IMoniker *moniker1 = NULL, *moniker2 = NULL;
1505c2c66affSColin Finck HRESULT hr;
1506c2c66affSColin Finck
1507c2c66affSColin Finck hr = CreateFileMoniker(path, &moniker1);
1508c2c66affSColin Finck ok_ole_success(hr, CreateFileMoniker);
1509c2c66affSColin Finck
1510c2c66affSColin Finck hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1511c2c66affSColin Finck ok_ole_success(hr, CreateStreamOnHGlobal);
1512c2c66affSColin Finck
1513c2c66affSColin Finck /* Marshal */
1514c2c66affSColin Finck hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1515c2c66affSColin Finck ok_ole_success(hr, CoMarshalInterface);
1516c2c66affSColin Finck
1517c2c66affSColin Finck /* Rewind */
1518c2c66affSColin Finck hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1519c2c66affSColin Finck ok_ole_success(hr, IStream_Seek);
1520c2c66affSColin Finck
1521c2c66affSColin Finck /* Unmarshal */
1522c2c66affSColin Finck hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
1523c2c66affSColin Finck ok_ole_success(hr, CoUnmarshalInterface);
1524c2c66affSColin Finck
1525c2c66affSColin Finck hr = IMoniker_IsEqual(moniker1, moniker2);
1526c2c66affSColin Finck ok_ole_success(hr, IsEqual);
1527c2c66affSColin Finck
1528c2c66affSColin Finck IStream_Release(stream);
1529c2c66affSColin Finck if (moniker1)
1530c2c66affSColin Finck IMoniker_Release(moniker1);
1531c2c66affSColin Finck if (moniker2)
1532c2c66affSColin Finck IMoniker_Release(moniker2);
1533c2c66affSColin Finck }
1534c2c66affSColin Finck
test_file_monikers(void)1535c2c66affSColin Finck static void test_file_monikers(void)
1536c2c66affSColin Finck {
1537c2c66affSColin Finck static WCHAR wszFile[][30] = {
1538c2c66affSColin Finck {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1539c2c66affSColin Finck {'\\', '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},
1540c2c66affSColin Finck /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1541c2c66affSColin Finck {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1542c2c66affSColin Finck /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1543c2c66affSColin Finck * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1544c2c66affSColin Finck * U+0100 .. = Latin extended-A
1545c2c66affSColin Finck */
1546c2c66affSColin Finck {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1547c2c66affSColin Finck };
1548c2c66affSColin Finck
1549c2c66affSColin Finck int i;
1550c2c66affSColin Finck
1551c2c66affSColin Finck trace("ACP is %u\n", GetACP());
1552c2c66affSColin Finck
1553*5c1bcfecSAmine Khaldi for (i = 0; i < ARRAY_SIZE(wszFile); ++i)
1554c2c66affSColin Finck {
1555c2c66affSColin Finck int j ;
1556c2c66affSColin Finck if (i == 2)
1557c2c66affSColin Finck {
1558c2c66affSColin Finck BOOL used;
1559c2c66affSColin Finck WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, wszFile[i], -1, NULL, 0, NULL, &used );
1560c2c66affSColin Finck if (used)
1561c2c66affSColin Finck {
1562c2c66affSColin Finck skip("string 2 doesn't round trip in codepage %u\n", GetACP() );
1563c2c66affSColin Finck continue;
1564c2c66affSColin Finck }
1565c2c66affSColin Finck }
1566c2c66affSColin Finck for (j = lstrlenW(wszFile[i]); j > 0; --j)
1567c2c66affSColin Finck {
1568c2c66affSColin Finck wszFile[i][j] = 0;
1569c2c66affSColin Finck test_file_moniker(wszFile[i]);
1570c2c66affSColin Finck }
1571c2c66affSColin Finck }
1572c2c66affSColin Finck }
1573c2c66affSColin Finck
test_item_moniker(void)1574c2c66affSColin Finck static void test_item_moniker(void)
1575c2c66affSColin Finck {
1576c2c66affSColin Finck HRESULT hr;
1577c2c66affSColin Finck IMoniker *moniker;
1578c2c66affSColin Finck DWORD moniker_type;
1579c2c66affSColin Finck DWORD hash;
1580c2c66affSColin Finck IBindCtx *bindctx;
1581c2c66affSColin Finck IMoniker *inverse;
1582c2c66affSColin Finck IUnknown *unknown;
1583c2c66affSColin Finck static const WCHAR wszDelimiter[] = {'!',0};
1584c2c66affSColin Finck static const WCHAR wszObjectName[] = {'T','e','s','t',0};
1585c2c66affSColin Finck static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
1586c2c66affSColin Finck
1587c2c66affSColin Finck hr = CreateItemMoniker(wszDelimiter, wszObjectName, &moniker);
1588c2c66affSColin Finck ok_ole_success(hr, CreateItemMoniker);
1589c2c66affSColin Finck
1590c2c66affSColin Finck test_moniker("item moniker", moniker,
1591c2c66affSColin Finck expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
1592c2c66affSColin Finck expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
1593c2c66affSColin Finck expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
1594c2c66affSColin Finck expected_display_name);
1595c2c66affSColin Finck
1596c2c66affSColin Finck /* Hashing */
1597c2c66affSColin Finck
1598c2c66affSColin Finck hr = IMoniker_Hash(moniker, &hash);
1599c2c66affSColin Finck ok_ole_success(hr, IMoniker_Hash);
1600c2c66affSColin Finck
1601c2c66affSColin Finck ok(hash == 0x73c,
1602c2c66affSColin Finck "Hash value != 0x73c, instead was 0x%08x\n",
1603c2c66affSColin Finck hash);
1604c2c66affSColin Finck
1605c2c66affSColin Finck /* IsSystemMoniker test */
1606c2c66affSColin Finck
1607c2c66affSColin Finck hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1608c2c66affSColin Finck ok_ole_success(hr, IMoniker_IsSystemMoniker);
1609c2c66affSColin Finck
1610c2c66affSColin Finck ok(moniker_type == MKSYS_ITEMMONIKER,
1611c2c66affSColin Finck "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1612c2c66affSColin Finck moniker_type);
1613c2c66affSColin Finck
1614c2c66affSColin Finck hr = CreateBindCtx(0, &bindctx);
1615c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
1616c2c66affSColin Finck
1617c2c66affSColin Finck /* IsRunning test */
1618c2c66affSColin Finck hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1619c2c66affSColin Finck ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1620c2c66affSColin Finck
1621c2c66affSColin Finck hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1622c2c66affSColin Finck ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1623c2c66affSColin Finck
1624c2c66affSColin Finck hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1625c2c66affSColin Finck ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1626c2c66affSColin Finck
1627c2c66affSColin Finck hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1628c2c66affSColin Finck ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1629c2c66affSColin Finck
1630c2c66affSColin Finck IBindCtx_Release(bindctx);
1631c2c66affSColin Finck
1632c2c66affSColin Finck hr = IMoniker_Inverse(moniker, &inverse);
1633c2c66affSColin Finck ok_ole_success(hr, IMoniker_Inverse);
1634c2c66affSColin Finck IMoniker_Release(inverse);
1635c2c66affSColin Finck
1636c2c66affSColin Finck IMoniker_Release(moniker);
1637c2c66affSColin Finck }
1638c2c66affSColin Finck
test_anti_moniker(void)1639c2c66affSColin Finck static void test_anti_moniker(void)
1640c2c66affSColin Finck {
1641c2c66affSColin Finck HRESULT hr;
1642c2c66affSColin Finck IMoniker *moniker;
1643c2c66affSColin Finck DWORD moniker_type;
1644c2c66affSColin Finck DWORD hash;
1645c2c66affSColin Finck IBindCtx *bindctx;
1646c2c66affSColin Finck FILETIME filetime;
1647c2c66affSColin Finck IMoniker *inverse;
1648c2c66affSColin Finck IUnknown *unknown;
1649c2c66affSColin Finck static const WCHAR expected_display_name[] = { '\\','.','.',0 };
1650c2c66affSColin Finck
1651c2c66affSColin Finck hr = CreateAntiMoniker(&moniker);
1652c2c66affSColin Finck ok_ole_success(hr, CreateAntiMoniker);
1653c2c66affSColin Finck if (!moniker) return;
1654c2c66affSColin Finck
1655c2c66affSColin Finck test_moniker("anti moniker", moniker,
1656c2c66affSColin Finck expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
1657c2c66affSColin Finck expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
1658c2c66affSColin Finck expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
1659c2c66affSColin Finck expected_display_name);
1660c2c66affSColin Finck
1661c2c66affSColin Finck /* Hashing */
1662c2c66affSColin Finck hr = IMoniker_Hash(moniker, &hash);
1663c2c66affSColin Finck ok_ole_success(hr, IMoniker_Hash);
1664c2c66affSColin Finck ok(hash == 0x80000001,
1665c2c66affSColin Finck "Hash value != 0x80000001, instead was 0x%08x\n",
1666c2c66affSColin Finck hash);
1667c2c66affSColin Finck
1668c2c66affSColin Finck /* IsSystemMoniker test */
1669c2c66affSColin Finck hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1670c2c66affSColin Finck ok_ole_success(hr, IMoniker_IsSystemMoniker);
1671c2c66affSColin Finck ok(moniker_type == MKSYS_ANTIMONIKER,
1672c2c66affSColin Finck "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1673c2c66affSColin Finck moniker_type);
1674c2c66affSColin Finck
1675c2c66affSColin Finck hr = IMoniker_Inverse(moniker, &inverse);
1676c2c66affSColin Finck ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
1677c2c66affSColin Finck ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
1678c2c66affSColin Finck
1679c2c66affSColin Finck hr = CreateBindCtx(0, &bindctx);
1680c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
1681c2c66affSColin Finck
1682c2c66affSColin Finck /* IsRunning test */
1683c2c66affSColin Finck hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1684c2c66affSColin Finck ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1685c2c66affSColin Finck
1686c2c66affSColin Finck hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1687c2c66affSColin Finck ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1688c2c66affSColin Finck
1689c2c66affSColin Finck hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1690c2c66affSColin Finck ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr);
1691c2c66affSColin Finck
1692c2c66affSColin Finck hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1693c2c66affSColin Finck ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr);
1694c2c66affSColin Finck
1695c2c66affSColin Finck IBindCtx_Release(bindctx);
1696c2c66affSColin Finck
1697c2c66affSColin Finck IMoniker_Release(moniker);
1698c2c66affSColin Finck }
1699c2c66affSColin Finck
test_generic_composite_moniker(void)1700c2c66affSColin Finck static void test_generic_composite_moniker(void)
1701c2c66affSColin Finck {
1702c2c66affSColin Finck HRESULT hr;
1703c2c66affSColin Finck IMoniker *moniker;
1704c2c66affSColin Finck IMoniker *moniker1;
1705c2c66affSColin Finck IMoniker *moniker2;
1706c2c66affSColin Finck DWORD moniker_type;
1707c2c66affSColin Finck DWORD hash;
1708c2c66affSColin Finck IBindCtx *bindctx;
1709c2c66affSColin Finck FILETIME filetime;
1710c2c66affSColin Finck IMoniker *inverse;
1711c2c66affSColin Finck IUnknown *unknown;
1712c2c66affSColin Finck static const WCHAR wszDelimiter1[] = {'!',0};
1713c2c66affSColin Finck static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
1714c2c66affSColin Finck static const WCHAR wszDelimiter2[] = {'#',0};
1715c2c66affSColin Finck static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
1716c2c66affSColin Finck static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1717c2c66affSColin Finck
1718c2c66affSColin Finck hr = CreateItemMoniker(wszDelimiter1, wszObjectName1, &moniker1);
1719c2c66affSColin Finck ok_ole_success(hr, CreateItemMoniker);
1720c2c66affSColin Finck hr = CreateItemMoniker(wszDelimiter2, wszObjectName2, &moniker2);
1721c2c66affSColin Finck ok_ole_success(hr, CreateItemMoniker);
1722c2c66affSColin Finck hr = CreateGenericComposite(moniker1, moniker2, &moniker);
1723c2c66affSColin Finck ok_ole_success(hr, CreateGenericComposite);
1724c2c66affSColin Finck
1725c2c66affSColin Finck test_moniker("generic composite moniker", moniker,
1726c2c66affSColin Finck expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
1727c2c66affSColin Finck expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
1728c2c66affSColin Finck expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
1729c2c66affSColin Finck expected_display_name);
1730c2c66affSColin Finck
1731c2c66affSColin Finck /* Hashing */
1732c2c66affSColin Finck
1733c2c66affSColin Finck hr = IMoniker_Hash(moniker, &hash);
1734c2c66affSColin Finck ok_ole_success(hr, IMoniker_Hash);
1735c2c66affSColin Finck
1736c2c66affSColin Finck ok(hash == 0xd87,
1737c2c66affSColin Finck "Hash value != 0xd87, instead was 0x%08x\n",
1738c2c66affSColin Finck hash);
1739c2c66affSColin Finck
1740c2c66affSColin Finck /* IsSystemMoniker test */
1741c2c66affSColin Finck
1742c2c66affSColin Finck hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1743c2c66affSColin Finck ok_ole_success(hr, IMoniker_IsSystemMoniker);
1744c2c66affSColin Finck
1745c2c66affSColin Finck ok(moniker_type == MKSYS_GENERICCOMPOSITE,
1746c2c66affSColin Finck "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1747c2c66affSColin Finck moniker_type);
1748c2c66affSColin Finck
1749c2c66affSColin Finck hr = CreateBindCtx(0, &bindctx);
1750c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
1751c2c66affSColin Finck
1752c2c66affSColin Finck /* IsRunning test */
1753c2c66affSColin Finck hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1754c2c66affSColin Finck ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1755c2c66affSColin Finck
1756c2c66affSColin Finck hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1757c2c66affSColin Finck todo_wine
1758c2c66affSColin Finck ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1759c2c66affSColin Finck
1760c2c66affSColin Finck hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1761c2c66affSColin Finck ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);
1762c2c66affSColin Finck
1763c2c66affSColin Finck hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1764c2c66affSColin Finck todo_wine
1765c2c66affSColin Finck ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1766c2c66affSColin Finck
1767c2c66affSColin Finck hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1768c2c66affSColin Finck ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1769c2c66affSColin Finck
1770c2c66affSColin Finck IBindCtx_Release(bindctx);
1771c2c66affSColin Finck
1772c2c66affSColin Finck hr = IMoniker_Inverse(moniker, &inverse);
1773c2c66affSColin Finck ok_ole_success(hr, IMoniker_Inverse);
1774c2c66affSColin Finck IMoniker_Release(inverse);
1775c2c66affSColin Finck
1776c2c66affSColin Finck IMoniker_Release(moniker);
1777c2c66affSColin Finck }
1778c2c66affSColin Finck
test_pointer_moniker(void)1779c2c66affSColin Finck static void test_pointer_moniker(void)
1780c2c66affSColin Finck {
1781c2c66affSColin Finck HRESULT hr;
1782c2c66affSColin Finck IMoniker *moniker;
1783c2c66affSColin Finck DWORD moniker_type;
1784c2c66affSColin Finck DWORD hash;
1785c2c66affSColin Finck IBindCtx *bindctx;
1786c2c66affSColin Finck FILETIME filetime;
1787c2c66affSColin Finck IMoniker *inverse;
1788c2c66affSColin Finck IUnknown *unknown;
1789c2c66affSColin Finck IStream *stream;
1790c2c66affSColin Finck IROTData *rotdata;
1791c2c66affSColin Finck LPOLESTR display_name;
1792c2c66affSColin Finck
1793c2c66affSColin Finck cLocks = 0;
1794c2c66affSColin Finck
1795c2c66affSColin Finck hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, NULL);
1796c2c66affSColin Finck ok(hr == E_INVALIDARG, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1797c2c66affSColin Finck
1798c2c66affSColin Finck hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, &moniker);
1799c2c66affSColin Finck ok_ole_success(hr, CreatePointerMoniker);
1800c2c66affSColin Finck if (!moniker) return;
1801c2c66affSColin Finck
1802c2c66affSColin Finck ok_more_than_one_lock();
1803c2c66affSColin Finck
1804c2c66affSColin Finck /* Display Name */
1805c2c66affSColin Finck
1806c2c66affSColin Finck hr = CreateBindCtx(0, &bindctx);
1807c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
1808c2c66affSColin Finck
1809c2c66affSColin Finck hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1810c2c66affSColin Finck ok(hr == E_NOTIMPL, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1811c2c66affSColin Finck
1812c2c66affSColin Finck IBindCtx_Release(bindctx);
1813c2c66affSColin Finck
1814c2c66affSColin Finck hr = IMoniker_IsDirty(moniker);
1815c2c66affSColin Finck ok(hr == S_FALSE, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr);
1816c2c66affSColin Finck
1817c2c66affSColin Finck /* IROTData::GetComparisonData test */
1818c2c66affSColin Finck
1819c2c66affSColin Finck hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1820c2c66affSColin Finck ok(hr == E_NOINTERFACE, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
1821c2c66affSColin Finck
1822c2c66affSColin Finck /* Saving */
1823c2c66affSColin Finck
1824c2c66affSColin Finck hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1825c2c66affSColin Finck ok_ole_success(hr, CreateStreamOnHGlobal);
1826c2c66affSColin Finck
1827c2c66affSColin Finck hr = IMoniker_Save(moniker, stream, TRUE);
1828c2c66affSColin Finck ok(hr == E_NOTIMPL, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1829c2c66affSColin Finck
1830c2c66affSColin Finck IStream_Release(stream);
1831c2c66affSColin Finck
1832c2c66affSColin Finck /* Hashing */
1833c2c66affSColin Finck hr = IMoniker_Hash(moniker, &hash);
1834c2c66affSColin Finck ok_ole_success(hr, IMoniker_Hash);
1835c2c66affSColin Finck ok(hash == PtrToUlong(&Test_ClassFactory),
1836c2c66affSColin Finck "Hash value should have been 0x%08x, instead of 0x%08x\n",
1837c2c66affSColin Finck PtrToUlong(&Test_ClassFactory), hash);
1838c2c66affSColin Finck
1839c2c66affSColin Finck /* IsSystemMoniker test */
1840c2c66affSColin Finck hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1841c2c66affSColin Finck ok_ole_success(hr, IMoniker_IsSystemMoniker);
1842c2c66affSColin Finck ok(moniker_type == MKSYS_POINTERMONIKER,
1843c2c66affSColin Finck "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1844c2c66affSColin Finck moniker_type);
1845c2c66affSColin Finck
1846c2c66affSColin Finck hr = IMoniker_Inverse(moniker, &inverse);
1847c2c66affSColin Finck ok_ole_success(hr, IMoniker_Inverse);
1848c2c66affSColin Finck IMoniker_Release(inverse);
1849c2c66affSColin Finck
1850c2c66affSColin Finck hr = CreateBindCtx(0, &bindctx);
1851c2c66affSColin Finck ok_ole_success(hr, CreateBindCtx);
1852c2c66affSColin Finck
1853c2c66affSColin Finck /* IsRunning test */
1854c2c66affSColin Finck hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1855c2c66affSColin Finck ok(hr == S_OK, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr);
1856c2c66affSColin Finck
1857c2c66affSColin Finck hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1858c2c66affSColin Finck ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1859c2c66affSColin Finck
1860c2c66affSColin Finck hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1861c2c66affSColin Finck ok_ole_success(hr, IMoniker_BindToObject);
1862c2c66affSColin Finck IUnknown_Release(unknown);
1863c2c66affSColin Finck
1864c2c66affSColin Finck hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1865c2c66affSColin Finck ok_ole_success(hr, IMoniker_BindToStorage);
1866c2c66affSColin Finck IUnknown_Release(unknown);
1867c2c66affSColin Finck
1868c2c66affSColin Finck IMoniker_Release(moniker);
1869c2c66affSColin Finck
1870c2c66affSColin Finck ok_no_locks();
1871c2c66affSColin Finck
1872c2c66affSColin Finck hr = CreatePointerMoniker(NULL, &moniker);
1873c2c66affSColin Finck ok_ole_success(hr, CreatePointerMoniker);
1874c2c66affSColin Finck
1875c2c66affSColin Finck hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1876c2c66affSColin Finck ok(hr == E_UNEXPECTED, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1877c2c66affSColin Finck
1878c2c66affSColin Finck hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1879c2c66affSColin Finck ok(hr == E_UNEXPECTED, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1880c2c66affSColin Finck
1881c2c66affSColin Finck IBindCtx_Release(bindctx);
1882c2c66affSColin Finck
1883c2c66affSColin Finck IMoniker_Release(moniker);
1884c2c66affSColin Finck }
1885c2c66affSColin Finck
test_bind_context(void)1886c2c66affSColin Finck static void test_bind_context(void)
1887c2c66affSColin Finck {
1888c2c66affSColin Finck HRESULT hr;
1889c2c66affSColin Finck IBindCtx *pBindCtx;
1890c2c66affSColin Finck IEnumString *pEnumString;
1891c2c66affSColin Finck BIND_OPTS2 bind_opts;
1892c2c66affSColin Finck HeapUnknown *unknown;
1893c2c66affSColin Finck HeapUnknown *unknown2;
1894c2c66affSColin Finck IUnknown *param_obj;
1895c2c66affSColin Finck ULONG refs;
1896c2c66affSColin Finck static const WCHAR wszParamName[] = {'G','e','m','m','a',0};
1897c2c66affSColin Finck static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1898c2c66affSColin Finck
1899c2c66affSColin Finck hr = CreateBindCtx(0, NULL);
1900c2c66affSColin Finck ok(hr == E_INVALIDARG, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1901c2c66affSColin Finck
1902c2c66affSColin Finck hr = CreateBindCtx(0xdeadbeef, &pBindCtx);
1903c2c66affSColin Finck ok(hr == E_INVALIDARG, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1904c2c66affSColin Finck
1905c2c66affSColin Finck hr = CreateBindCtx(0, &pBindCtx);
1906c2c66affSColin Finck ok_ole_success(hr, "CreateBindCtx");
1907c2c66affSColin Finck
1908c2c66affSColin Finck bind_opts.cbStruct = -1;
1909c2c66affSColin Finck hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1910c2c66affSColin Finck ok_ole_success(hr, "IBindCtx_GetBindOptions");
1911c2c66affSColin Finck ok(bind_opts.cbStruct == sizeof(bind_opts) ||
1912c2c66affSColin Finck bind_opts.cbStruct == sizeof(bind_opts) + sizeof(void*), /* Vista */
1913c2c66affSColin Finck "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1914c2c66affSColin Finck
1915c2c66affSColin Finck bind_opts.cbStruct = sizeof(BIND_OPTS);
1916c2c66affSColin Finck hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1917c2c66affSColin Finck ok_ole_success(hr, "IBindCtx_GetBindOptions");
1918c2c66affSColin Finck ok(bind_opts.cbStruct == sizeof(BIND_OPTS), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1919c2c66affSColin Finck
1920c2c66affSColin Finck bind_opts.cbStruct = sizeof(bind_opts);
1921c2c66affSColin Finck hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1922c2c66affSColin Finck ok_ole_success(hr, "IBindCtx_GetBindOptions");
1923c2c66affSColin Finck ok(bind_opts.cbStruct == sizeof(bind_opts), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1924c2c66affSColin Finck ok(bind_opts.grfFlags == 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts.grfFlags);
1925c2c66affSColin Finck ok(bind_opts.grfMode == STGM_READWRITE, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts.grfMode);
1926c2c66affSColin Finck ok(bind_opts.dwTickCountDeadline == 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts.dwTickCountDeadline);
1927c2c66affSColin Finck ok(bind_opts.dwTrackFlags == 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts.dwTrackFlags);
1928c2c66affSColin Finck ok(bind_opts.dwClassContext == (CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER),
1929c2c66affSColin Finck "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts.dwClassContext);
1930c2c66affSColin Finck ok(bind_opts.locale == GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts.locale);
1931c2c66affSColin Finck ok(bind_opts.pServerInfo == NULL, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts.pServerInfo);
1932c2c66affSColin Finck
1933c2c66affSColin Finck bind_opts.cbStruct = -1;
1934c2c66affSColin Finck hr = IBindCtx_SetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1935c2c66affSColin Finck ok(hr == E_INVALIDARG, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1936c2c66affSColin Finck
1937c2c66affSColin Finck hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, NULL);
1938c2c66affSColin Finck ok(hr == E_INVALIDARG, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1939c2c66affSColin Finck
1940c2c66affSColin Finck unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1941c2c66affSColin Finck unknown->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
1942c2c66affSColin Finck unknown->refs = 1;
1943c2c66affSColin Finck hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, &unknown->IUnknown_iface);
1944c2c66affSColin Finck ok_ole_success(hr, "IBindCtx_RegisterObjectParam");
1945c2c66affSColin Finck
1946c2c66affSColin Finck hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszParamName, ¶m_obj);
1947c2c66affSColin Finck ok_ole_success(hr, "IBindCtx_GetObjectParam");
1948c2c66affSColin Finck IUnknown_Release(param_obj);
1949c2c66affSColin Finck
1950c2c66affSColin Finck hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszNonExistent, ¶m_obj);
1951c2c66affSColin Finck ok(hr == E_FAIL, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1952c2c66affSColin Finck ok(param_obj == NULL, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj);
1953c2c66affSColin Finck
1954c2c66affSColin Finck hr = IBindCtx_RevokeObjectParam(pBindCtx, (WCHAR *)wszNonExistent);
1955c2c66affSColin Finck ok(hr == E_FAIL, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1956c2c66affSColin Finck
1957c2c66affSColin Finck hr = IBindCtx_EnumObjectParam(pBindCtx, &pEnumString);
1958c2c66affSColin Finck ok(hr == E_NOTIMPL, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1959c2c66affSColin Finck ok(!pEnumString, "pEnumString should be NULL\n");
1960c2c66affSColin Finck
1961c2c66affSColin Finck hr = IBindCtx_RegisterObjectBound(pBindCtx, NULL);
1962c2c66affSColin Finck ok_ole_success(hr, "IBindCtx_RegisterObjectBound(NULL)");
1963c2c66affSColin Finck
1964c2c66affSColin Finck hr = IBindCtx_RevokeObjectBound(pBindCtx, NULL);
1965c2c66affSColin Finck ok(hr == E_INVALIDARG, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr);
1966c2c66affSColin Finck
1967c2c66affSColin Finck unknown2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1968c2c66affSColin Finck unknown2->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl;
1969c2c66affSColin Finck unknown2->refs = 1;
1970c2c66affSColin Finck hr = IBindCtx_RegisterObjectBound(pBindCtx, &unknown2->IUnknown_iface);
1971c2c66affSColin Finck ok_ole_success(hr, "IBindCtx_RegisterObjectBound");
1972c2c66affSColin Finck
1973c2c66affSColin Finck hr = IBindCtx_RevokeObjectBound(pBindCtx, &unknown2->IUnknown_iface);
1974c2c66affSColin Finck ok_ole_success(hr, "IBindCtx_RevokeObjectBound");
1975c2c66affSColin Finck
1976c2c66affSColin Finck hr = IBindCtx_RevokeObjectBound(pBindCtx, &unknown2->IUnknown_iface);
1977c2c66affSColin Finck ok(hr == MK_E_NOTBOUND, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr);
1978c2c66affSColin Finck
1979c2c66affSColin Finck IBindCtx_Release(pBindCtx);
1980c2c66affSColin Finck
1981c2c66affSColin Finck refs = IUnknown_Release(&unknown->IUnknown_iface);
1982c2c66affSColin Finck ok(!refs, "object param should have been destroyed, instead of having %d refs\n", refs);
1983c2c66affSColin Finck
1984c2c66affSColin Finck refs = IUnknown_Release(&unknown2->IUnknown_iface);
1985c2c66affSColin Finck ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
1986c2c66affSColin Finck }
1987c2c66affSColin Finck
test_save_load_filemoniker(void)1988c2c66affSColin Finck static void test_save_load_filemoniker(void)
1989c2c66affSColin Finck {
1990c2c66affSColin Finck IMoniker* pMk;
1991c2c66affSColin Finck IStream* pStm;
1992c2c66affSColin Finck HRESULT hr;
1993c2c66affSColin Finck ULARGE_INTEGER size;
1994c2c66affSColin Finck LARGE_INTEGER zero_pos, dead_pos, nulls_pos;
1995c2c66affSColin Finck DWORD some_val = 0xFEDCBA98;
1996c2c66affSColin Finck int i;
1997c2c66affSColin Finck
1998c2c66affSColin Finck /* see FileMonikerImpl_Save docs */
1999c2c66affSColin Finck zero_pos.QuadPart = 0;
2000c2c66affSColin Finck dead_pos.QuadPart = sizeof(WORD) + sizeof(DWORD) + (lstrlenW(wszFileName1) + 1) + sizeof(WORD);
2001c2c66affSColin Finck nulls_pos.QuadPart = dead_pos.QuadPart + sizeof(WORD);
2002c2c66affSColin Finck
2003c2c66affSColin Finck /* create the stream we're going to write to */
2004c2c66affSColin Finck hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm);
2005c2c66affSColin Finck ok_ole_success(hr, "CreateStreamOnHGlobal");
2006c2c66affSColin Finck
2007c2c66affSColin Finck size.u.LowPart = 128;
2008c2c66affSColin Finck hr = IStream_SetSize(pStm, size);
2009c2c66affSColin Finck ok_ole_success(hr, "IStream_SetSize");
2010c2c66affSColin Finck
2011c2c66affSColin Finck /* create and save a moniker */
2012c2c66affSColin Finck hr = CreateFileMoniker(wszFileName1, &pMk);
2013c2c66affSColin Finck ok_ole_success(hr, "CreateFileMoniker");
2014c2c66affSColin Finck
2015c2c66affSColin Finck hr = IMoniker_Save(pMk, pStm, TRUE);
2016c2c66affSColin Finck ok_ole_success(hr, "IMoniker_Save");
2017c2c66affSColin Finck IMoniker_Release(pMk);
2018c2c66affSColin Finck
2019c2c66affSColin Finck /* overwrite the constants with various values */
2020c2c66affSColin Finck hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL);
2021c2c66affSColin Finck ok_ole_success(hr, "IStream_Seek");
2022c2c66affSColin Finck hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL);
2023c2c66affSColin Finck ok_ole_success(hr, "IStream_Write");
2024c2c66affSColin Finck
2025c2c66affSColin Finck hr = IStream_Seek(pStm, dead_pos, STREAM_SEEK_SET, NULL);
2026c2c66affSColin Finck ok_ole_success(hr, "IStream_Seek");
2027c2c66affSColin Finck hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL);
2028c2c66affSColin Finck ok_ole_success(hr, "IStream_Write");
2029c2c66affSColin Finck
2030c2c66affSColin Finck hr = IStream_Seek(pStm, nulls_pos, STREAM_SEEK_SET, NULL);
2031c2c66affSColin Finck ok_ole_success(hr, "IStream_Seek");
2032c2c66affSColin Finck for(i = 0; i < 5; ++i){
2033c2c66affSColin Finck hr = IStream_Write(pStm, &some_val, sizeof(DWORD), NULL);
2034c2c66affSColin Finck ok_ole_success(hr, "IStream_Write");
2035c2c66affSColin Finck }
2036c2c66affSColin Finck
2037c2c66affSColin Finck /* go back to the start of the stream */
2038c2c66affSColin Finck hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL);
2039c2c66affSColin Finck ok_ole_success(hr, "IStream_Seek");
2040c2c66affSColin Finck
2041c2c66affSColin Finck /* create a new moniker and load into it */
2042c2c66affSColin Finck hr = CreateFileMoniker(wszFileName1, &pMk);
2043c2c66affSColin Finck ok_ole_success(hr, "CreateFileMoniker");
2044c2c66affSColin Finck
2045c2c66affSColin Finck hr = IMoniker_Load(pMk, pStm);
2046c2c66affSColin Finck ok_ole_success(hr, "IMoniker_Load");
2047c2c66affSColin Finck
2048c2c66affSColin Finck IMoniker_Release(pMk);
2049c2c66affSColin Finck IStream_Release(pStm);
2050c2c66affSColin Finck }
2051c2c66affSColin Finck
START_TEST(moniker)2052c2c66affSColin Finck START_TEST(moniker)
2053c2c66affSColin Finck {
2054c2c66affSColin Finck if (!GetProcAddress(GetModuleHandleA("ole32.dll"), "CoRegisterSurrogateEx")) {
2055c2c66affSColin Finck win_skip("skipping test on win9x\n");
2056c2c66affSColin Finck return;
2057c2c66affSColin Finck }
2058c2c66affSColin Finck
2059c2c66affSColin Finck CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2060c2c66affSColin Finck
2061c2c66affSColin Finck test_ROT();
2062c2c66affSColin Finck test_ROT_multiple_entries();
2063c2c66affSColin Finck test_MkParseDisplayName();
2064c2c66affSColin Finck test_class_moniker();
2065c2c66affSColin Finck test_file_monikers();
2066c2c66affSColin Finck test_item_moniker();
2067c2c66affSColin Finck test_anti_moniker();
2068c2c66affSColin Finck test_generic_composite_moniker();
2069c2c66affSColin Finck test_pointer_moniker();
2070c2c66affSColin Finck test_save_load_filemoniker();
2071c2c66affSColin Finck
2072c2c66affSColin Finck /* FIXME: test moniker creation funcs and parsing other moniker formats */
2073c2c66affSColin Finck
2074c2c66affSColin Finck test_bind_context();
2075c2c66affSColin Finck
2076c2c66affSColin Finck CoUninitialize();
2077c2c66affSColin Finck }
2078