~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ole32/tests/moniker.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.