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, &param_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, &param_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