comdlg32: Fix some alignment issues in the Dutch translation.
[wine/hramrach.git] / dlls / ole32 / tests / moniker.c
blobb4e3e2f7db45f534712967114e1c169620889256
1 /*
2 * Moniker Tests
4 * Copyright 2004 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define _WIN32_DCOM
22 #define COBJMACROS
23 #define CONST_VTABLE
25 #include <stdarg.h>
26 #include <stdio.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "objbase.h"
31 #include "initguid.h"
32 #include "comcat.h"
33 #include "olectl.h"
35 #include "wine/test.h"
37 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
38 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
39 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
40 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
42 #define CHECK_EXPECTED_METHOD(method_name) \
43 do { \
44 trace("%s\n", method_name); \
45 ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
46 if (*expected_method_list) \
47 { \
48 ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
49 *expected_method_list, method_name); \
50 expected_method_list++; \
51 } \
52 } while(0)
54 static char const * const *expected_method_list;
55 static const WCHAR wszFileName1[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
56 static const WCHAR wszFileName2[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
58 static const CLSID CLSID_WineTest =
59 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
60 0x9474ba1a,
61 0x258b,
62 0x490b,
63 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
66 static const CLSID CLSID_TestMoniker =
67 { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
68 0xb306bfbc,
69 0x496e,
70 0x4f53,
71 {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
74 static LONG cLocks;
76 static void LockModule(void)
78 InterlockedIncrement(&cLocks);
81 static void UnlockModule(void)
83 InterlockedDecrement(&cLocks);
86 static SIZE_T round_global_size(SIZE_T size)
88 static SIZE_T global_size_alignment = -1;
89 if (global_size_alignment == -1)
91 void *p = GlobalAlloc(GMEM_FIXED, 1);
92 global_size_alignment = GlobalSize(p);
93 GlobalFree(p);
96 return ((size + global_size_alignment - 1) & ~(global_size_alignment - 1));
99 static HRESULT WINAPI Test_IClassFactory_QueryInterface(
100 LPCLASSFACTORY iface,
101 REFIID riid,
102 LPVOID *ppvObj)
104 if (ppvObj == NULL) return E_POINTER;
106 if (IsEqualGUID(riid, &IID_IUnknown) ||
107 IsEqualGUID(riid, &IID_IClassFactory))
109 *ppvObj = iface;
110 IClassFactory_AddRef(iface);
111 return S_OK;
114 *ppvObj = NULL;
115 return E_NOINTERFACE;
118 static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
120 LockModule();
121 return 2; /* non-heap-based object */
124 static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
126 UnlockModule();
127 return 1; /* non-heap-based object */
130 static HRESULT WINAPI Test_IClassFactory_CreateInstance(
131 LPCLASSFACTORY iface,
132 LPUNKNOWN pUnkOuter,
133 REFIID riid,
134 LPVOID *ppvObj)
136 return E_NOTIMPL;
139 static HRESULT WINAPI Test_IClassFactory_LockServer(
140 LPCLASSFACTORY iface,
141 BOOL fLock)
143 return S_OK;
146 static const IClassFactoryVtbl TestClassFactory_Vtbl =
148 Test_IClassFactory_QueryInterface,
149 Test_IClassFactory_AddRef,
150 Test_IClassFactory_Release,
151 Test_IClassFactory_CreateInstance,
152 Test_IClassFactory_LockServer
155 static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
157 typedef struct
159 const IUnknownVtbl *lpVtbl;
160 ULONG refs;
161 } HeapUnknown;
163 static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
165 if (IsEqualIID(riid, &IID_IUnknown))
167 IUnknown_AddRef(iface);
168 *ppv = iface;
169 return S_OK;
171 *ppv = NULL;
172 return E_NOINTERFACE;
175 static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
177 HeapUnknown *This = (HeapUnknown *)iface;
178 return InterlockedIncrement((LONG*)&This->refs);
181 static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
183 HeapUnknown *This = (HeapUnknown *)iface;
184 ULONG refs = InterlockedDecrement((LONG*)&This->refs);
185 if (!refs) HeapFree(GetProcessHeap(), 0, This);
186 return refs;
189 static const IUnknownVtbl HeapUnknown_Vtbl =
191 HeapUnknown_QueryInterface,
192 HeapUnknown_AddRef,
193 HeapUnknown_Release
196 static HRESULT WINAPI
197 MonikerNoROTData_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
199 if (!ppvObject)
200 return E_INVALIDARG;
202 *ppvObject = 0;
204 if (IsEqualIID(&IID_IUnknown, riid) ||
205 IsEqualIID(&IID_IPersist, riid) ||
206 IsEqualIID(&IID_IPersistStream,riid) ||
207 IsEqualIID(&IID_IMoniker, riid))
208 *ppvObject = iface;
209 if (IsEqualIID(&IID_IROTData, riid))
210 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
212 if ((*ppvObject)==0)
213 return E_NOINTERFACE;
215 IMoniker_AddRef(iface);
217 return S_OK;
220 static ULONG WINAPI
221 Moniker_AddRef(IMoniker* iface)
223 return 2;
226 static ULONG WINAPI
227 Moniker_Release(IMoniker* iface)
229 return 1;
232 static HRESULT WINAPI
233 Moniker_GetClassID(IMoniker* iface, CLSID *pClassID)
235 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
237 *pClassID = CLSID_TestMoniker;
239 return S_OK;
242 static HRESULT WINAPI
243 Moniker_IsDirty(IMoniker* iface)
245 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
247 return S_FALSE;
250 static HRESULT WINAPI
251 Moniker_Load(IMoniker* iface, IStream* pStm)
253 CHECK_EXPECTED_METHOD("Moniker_Load");
254 return E_NOTIMPL;
257 static HRESULT WINAPI
258 Moniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
260 CHECK_EXPECTED_METHOD("Moniker_Save");
261 return E_NOTIMPL;
264 static HRESULT WINAPI
265 Moniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
267 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
268 return E_NOTIMPL;
271 static HRESULT WINAPI
272 Moniker_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
273 REFIID riid, VOID** ppvResult)
275 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
276 return E_NOTIMPL;
279 static HRESULT WINAPI
280 Moniker_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
281 REFIID riid, VOID** ppvObject)
283 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
284 return E_NOTIMPL;
287 static HRESULT WINAPI
288 Moniker_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
289 IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
291 CHECK_EXPECTED_METHOD("Moniker_Reduce");
293 if (ppmkReduced==NULL)
294 return E_POINTER;
296 IMoniker_AddRef(iface);
298 *ppmkReduced=iface;
300 return MK_S_REDUCED_TO_SELF;
303 static HRESULT WINAPI
304 Moniker_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
305 BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
307 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
308 return E_NOTIMPL;
311 static HRESULT WINAPI
312 Moniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
314 CHECK_EXPECTED_METHOD("Moniker_Enum");
316 if (ppenumMoniker == NULL)
317 return E_POINTER;
319 *ppenumMoniker = NULL;
321 return S_OK;
324 static HRESULT WINAPI
325 Moniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
327 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
328 return E_NOTIMPL;
331 static HRESULT WINAPI
332 Moniker_Hash(IMoniker* iface,DWORD* pdwHash)
334 CHECK_EXPECTED_METHOD("Moniker_Hash");
335 return E_NOTIMPL;
338 static HRESULT WINAPI
339 Moniker_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
340 IMoniker* pmkNewlyRunning)
342 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
343 return E_NOTIMPL;
346 static HRESULT WINAPI
347 Moniker_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
348 IMoniker* pmkToLeft, FILETIME* pFileTime)
350 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
351 return E_NOTIMPL;
354 static HRESULT WINAPI
355 Moniker_Inverse(IMoniker* iface,IMoniker** ppmk)
357 CHECK_EXPECTED_METHOD("Moniker_Inverse");
358 return E_NOTIMPL;
361 static HRESULT WINAPI
362 Moniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
364 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
365 return E_NOTIMPL;
368 static HRESULT WINAPI
369 Moniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
371 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
372 return E_NOTIMPL;
375 static HRESULT WINAPI
376 Moniker_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
377 IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
379 static const WCHAR wszDisplayName[] = {'*','*','G','e','m','m','a',0};
380 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
381 *ppszDisplayName = CoTaskMemAlloc(sizeof(wszDisplayName));
382 memcpy(*ppszDisplayName, wszDisplayName, sizeof(wszDisplayName));
383 return S_OK;
386 static HRESULT WINAPI
387 Moniker_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
388 LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
390 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
391 return E_NOTIMPL;
394 static HRESULT WINAPI
395 Moniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
397 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
399 if (!pwdMksys)
400 return E_POINTER;
402 (*pwdMksys)=MKSYS_NONE;
404 return S_FALSE;
407 static const IMonikerVtbl MonikerNoROTDataVtbl =
409 MonikerNoROTData_QueryInterface,
410 Moniker_AddRef,
411 Moniker_Release,
412 Moniker_GetClassID,
413 Moniker_IsDirty,
414 Moniker_Load,
415 Moniker_Save,
416 Moniker_GetSizeMax,
417 Moniker_BindToObject,
418 Moniker_BindToStorage,
419 Moniker_Reduce,
420 Moniker_ComposeWith,
421 Moniker_Enum,
422 Moniker_IsEqual,
423 Moniker_Hash,
424 Moniker_IsRunning,
425 Moniker_GetTimeOfLastChange,
426 Moniker_Inverse,
427 Moniker_CommonPrefixWith,
428 Moniker_RelativePathTo,
429 Moniker_GetDisplayName,
430 Moniker_ParseDisplayName,
431 Moniker_IsSystemMoniker
434 static IMoniker MonikerNoROTData = { &MonikerNoROTDataVtbl };
436 static IMoniker Moniker;
438 static HRESULT WINAPI
439 ROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
441 return IMoniker_QueryInterface(&Moniker, riid, ppvObject);
444 static ULONG WINAPI
445 ROTData_AddRef(IROTData *iface)
447 return 2;
450 static ULONG WINAPI
451 ROTData_Release(IROTData* iface)
453 return 1;
456 static HRESULT WINAPI
457 ROTData_GetComparisonData(IROTData* iface, BYTE* pbData,
458 ULONG cbMax, ULONG* pcbData)
460 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
462 *pcbData = 1;
463 if (cbMax < *pcbData)
464 return E_OUTOFMEMORY;
466 *pbData = 0xde;
468 return S_OK;
471 static IROTDataVtbl ROTDataVtbl =
473 ROTData_QueryInterface,
474 ROTData_AddRef,
475 ROTData_Release,
476 ROTData_GetComparisonData
479 static IROTData ROTData = { &ROTDataVtbl };
481 static HRESULT WINAPI
482 Moniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
484 if (!ppvObject)
485 return E_INVALIDARG;
487 *ppvObject = 0;
489 if (IsEqualIID(&IID_IUnknown, riid) ||
490 IsEqualIID(&IID_IPersist, riid) ||
491 IsEqualIID(&IID_IPersistStream,riid) ||
492 IsEqualIID(&IID_IMoniker, riid))
493 *ppvObject = iface;
494 if (IsEqualIID(&IID_IROTData, riid))
496 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
497 *ppvObject = &ROTData;
500 if ((*ppvObject)==0)
501 return E_NOINTERFACE;
503 IMoniker_AddRef(iface);
505 return S_OK;
508 static const IMonikerVtbl MonikerVtbl =
510 Moniker_QueryInterface,
511 Moniker_AddRef,
512 Moniker_Release,
513 Moniker_GetClassID,
514 Moniker_IsDirty,
515 Moniker_Load,
516 Moniker_Save,
517 Moniker_GetSizeMax,
518 Moniker_BindToObject,
519 Moniker_BindToStorage,
520 Moniker_Reduce,
521 Moniker_ComposeWith,
522 Moniker_Enum,
523 Moniker_IsEqual,
524 Moniker_Hash,
525 Moniker_IsRunning,
526 Moniker_GetTimeOfLastChange,
527 Moniker_Inverse,
528 Moniker_CommonPrefixWith,
529 Moniker_RelativePathTo,
530 Moniker_GetDisplayName,
531 Moniker_ParseDisplayName,
532 Moniker_IsSystemMoniker
535 static IMoniker Moniker = { &MonikerVtbl };
537 static void test_ROT(void)
539 static const WCHAR wszFileName[] = {'B','E','2','0','E','2','F','5','-',
540 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
541 '2','0','4','6','E','5','8','6','C','9','2','5',0};
542 HRESULT hr;
543 IMoniker *pMoniker = NULL;
544 IRunningObjectTable *pROT = NULL;
545 DWORD dwCookie;
546 static const char *methods_register_no_ROTData[] =
548 "Moniker_Reduce",
549 "Moniker_GetTimeOfLastChange",
550 "Moniker_QueryInterface(IID_IROTData)",
551 "Moniker_GetDisplayName",
552 "Moniker_GetClassID",
553 NULL
555 static const char *methods_register[] =
557 "Moniker_Reduce",
558 "Moniker_GetTimeOfLastChange",
559 "Moniker_QueryInterface(IID_IROTData)",
560 "ROTData_GetComparisonData",
561 NULL
563 static const char *methods_isrunning_no_ROTData[] =
565 "Moniker_Reduce",
566 "Moniker_QueryInterface(IID_IROTData)",
567 "Moniker_GetDisplayName",
568 "Moniker_GetClassID",
569 NULL
571 static const char *methods_isrunning[] =
573 "Moniker_Reduce",
574 "Moniker_QueryInterface(IID_IROTData)",
575 "ROTData_GetComparisonData",
576 NULL
579 cLocks = 0;
581 hr = GetRunningObjectTable(0, &pROT);
582 ok_ole_success(hr, GetRunningObjectTable);
584 expected_method_list = methods_register_no_ROTData;
585 /* try with our own moniker that doesn't support IROTData */
586 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
587 (IUnknown*)&Test_ClassFactory, &MonikerNoROTData, &dwCookie);
588 ok_ole_success(hr, IRunningObjectTable_Register);
589 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
591 ok_more_than_one_lock();
593 expected_method_list = methods_isrunning_no_ROTData;
594 hr = IRunningObjectTable_IsRunning(pROT, &MonikerNoROTData);
595 ok_ole_success(hr, IRunningObjectTable_IsRunning);
596 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
598 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
599 ok_ole_success(hr, IRunningObjectTable_Revoke);
601 ok_no_locks();
603 expected_method_list = methods_register;
604 /* try with our own moniker */
605 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
606 (IUnknown*)&Test_ClassFactory, &Moniker, &dwCookie);
607 ok_ole_success(hr, IRunningObjectTable_Register);
608 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
610 ok_more_than_one_lock();
612 expected_method_list = methods_isrunning;
613 hr = IRunningObjectTable_IsRunning(pROT, &Moniker);
614 ok_ole_success(hr, IRunningObjectTable_IsRunning);
615 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
617 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
618 ok_ole_success(hr, IRunningObjectTable_Revoke);
620 ok_no_locks();
622 hr = CreateFileMoniker(wszFileName, &pMoniker);
623 ok_ole_success(hr, CreateClassMoniker);
625 /* test flags: 0 */
626 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown*)&Test_ClassFactory,
627 pMoniker, &dwCookie);
628 ok_ole_success(hr, IRunningObjectTable_Register);
630 ok_more_than_one_lock();
632 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
633 ok_ole_success(hr, IRunningObjectTable_Revoke);
635 ok_no_locks();
637 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
638 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
639 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
640 ok_ole_success(hr, IRunningObjectTable_Register);
642 ok_more_than_one_lock();
644 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
645 ok_ole_success(hr, IRunningObjectTable_Revoke);
647 ok_no_locks();
649 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
650 /* only succeeds when process is started by SCM and has LocalService
651 * or RunAs AppId values */
652 hr = IRunningObjectTable_Register(pROT,
653 ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT,
654 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
655 todo_wine {
656 ok(hr == CO_E_WRONG_SERVER_IDENTITY ||
657 broken(hr == S_OK) /* Win9x */,
658 "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr);
660 if (hr == S_OK) IRunningObjectTable_Revoke(pROT, dwCookie);
662 hr = IRunningObjectTable_Register(pROT, 0xdeadbeef,
663 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
664 ok(hr == E_INVALIDARG, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr);
666 IMoniker_Release(pMoniker);
668 IRunningObjectTable_Release(pROT);
671 static void test_ROT_multiple_entries(void)
673 HRESULT hr;
674 IMoniker *pMoniker = NULL;
675 IRunningObjectTable *pROT = NULL;
676 DWORD dwCookie1, dwCookie2;
677 IUnknown *pObject = NULL;
678 static const WCHAR moniker_path[] =
679 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0};
681 hr = GetRunningObjectTable(0, &pROT);
682 ok_ole_success(hr, GetRunningObjectTable);
684 hr = CreateFileMoniker(moniker_path, &pMoniker);
685 ok_ole_success(hr, CreateFileMoniker);
687 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown *)&Test_ClassFactory, pMoniker, &dwCookie1);
688 ok_ole_success(hr, IRunningObjectTable_Register);
690 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown *)&Test_ClassFactory, pMoniker, &dwCookie2);
691 ok(hr == MK_S_MONIKERALREADYREGISTERED, "IRunningObjectTable_Register should have returned MK_S_MONIKERALREADYREGISTERED instead of 0x%08x\n", hr);
693 ok(dwCookie1 != dwCookie2, "cookie returned for registering duplicate object shouldn't match cookie of original object (0x%x)\n", dwCookie1);
695 hr = IRunningObjectTable_GetObject(pROT, pMoniker, &pObject);
696 ok_ole_success(hr, IRunningObjectTable_GetObject);
697 IUnknown_Release(pObject);
699 hr = IRunningObjectTable_Revoke(pROT, dwCookie1);
700 ok_ole_success(hr, IRunningObjectTable_Revoke);
702 hr = IRunningObjectTable_GetObject(pROT, pMoniker, &pObject);
703 ok_ole_success(hr, IRunningObjectTable_GetObject);
704 IUnknown_Release(pObject);
706 hr = IRunningObjectTable_Revoke(pROT, dwCookie2);
707 ok_ole_success(hr, IRunningObjectTable_Revoke);
709 IMoniker_Release(pMoniker);
711 IRunningObjectTable_Release(pROT);
714 static HRESULT WINAPI ParseDisplayName_QueryInterface(IParseDisplayName *iface, REFIID riid, void **ppv)
716 if (IsEqualIID(riid, &IID_IUnknown) ||
717 IsEqualIID(riid, &IID_IParseDisplayName))
719 *ppv = iface;
720 IUnknown_AddRef(iface);
721 return S_OK;
723 *ppv = NULL;
724 return E_NOINTERFACE;
727 static ULONG WINAPI ParseDisplayName_AddRef(IParseDisplayName *iface)
729 return 2;
732 static ULONG WINAPI ParseDisplayName_Release(IParseDisplayName *iface)
734 return 1;
737 static LPCWSTR expected_display_name;
739 static HRESULT WINAPI ParseDisplayName_ParseDisplayName(IParseDisplayName *iface,
740 IBindCtx *pbc,
741 LPOLESTR pszDisplayName,
742 ULONG *pchEaten,
743 IMoniker **ppmkOut)
745 char display_nameA[256];
746 WideCharToMultiByte(CP_ACP, 0, pszDisplayName, -1, display_nameA, sizeof(display_nameA), NULL, NULL);
747 ok(!lstrcmpW(pszDisplayName, expected_display_name), "unexpected display name \"%s\"\n", display_nameA);
748 ok(pszDisplayName == expected_display_name, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
749 *pchEaten = lstrlenW(pszDisplayName);
750 return CreateAntiMoniker(ppmkOut);
753 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl =
755 ParseDisplayName_QueryInterface,
756 ParseDisplayName_AddRef,
757 ParseDisplayName_Release,
758 ParseDisplayName_ParseDisplayName
761 static IParseDisplayName ParseDisplayName = { &ParseDisplayName_Vtbl };
763 static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
765 IMoniker * spMoniker;
766 int monCnt=0, matchCnt=0;
768 while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK))
770 HRESULT hr;
771 WCHAR * szDisplayn;
772 monCnt++;
773 hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL, &szDisplayn);
774 if (SUCCEEDED(hr))
776 if (!lstrcmpiW(szDisplayn, wszFileName1) || !lstrcmpiW(szDisplayn, wszFileName2))
777 matchCnt++;
778 CoTaskMemFree(szDisplayn);
781 trace("Total number of monikers is %i\n", monCnt);
782 return matchCnt;
785 static void test_MkParseDisplayName(void)
787 IBindCtx * pbc = NULL;
788 HRESULT hr;
789 IMoniker * pmk = NULL;
790 IMoniker * pmk1 = NULL;
791 IMoniker * pmk2 = NULL;
792 ULONG eaten;
793 int matchCnt;
794 IUnknown * object = NULL;
796 IUnknown *lpEM1;
798 IEnumMoniker *spEM1 = NULL;
799 IEnumMoniker *spEM2 = NULL;
800 IEnumMoniker *spEM3 = NULL;
802 DWORD pdwReg1=0;
803 DWORD grflags=0;
804 DWORD pdwReg2=0;
805 DWORD moniker_type;
806 IRunningObjectTable * pprot=NULL;
808 /* CLSID of My Computer */
809 static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
810 '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};
811 static const WCHAR wszDisplayNameClsid[] = {'c','l','s','i','d',':',0};
812 static const WCHAR wszNonExistentProgId[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
813 static const WCHAR wszDisplayNameRunning[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
814 static const WCHAR wszDisplayNameProgId1[] = {'S','t','d','F','o','n','t',':',0};
815 static const WCHAR wszDisplayNameProgId2[] = {'@','S','t','d','F','o','n','t',0};
816 static const WCHAR wszDisplayNameProgIdFail[] = {'S','t','d','F','o','n','t',0};
817 char szDisplayNameFile[256];
818 WCHAR wszDisplayNameFile[256];
820 hr = CreateBindCtx(0, &pbc);
821 ok_ole_success(hr, CreateBindCtx);
823 hr = MkParseDisplayName(pbc, wszNonExistentProgId, &eaten, &pmk);
824 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
825 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
827 /* no special handling of "clsid:" without the string form of the clsid
828 * following */
829 hr = MkParseDisplayName(pbc, wszDisplayNameClsid, &eaten, &pmk);
830 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
831 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
833 /* shows clsid has higher precedence than a running object */
834 hr = CreateFileMoniker(wszDisplayName, &pmk);
835 ok_ole_success(hr, CreateFileMoniker);
836 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
837 ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
838 hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
839 ok_ole_success(hr, IRunningObjectTable_Register);
840 IMoniker_Release(pmk);
841 pmk = NULL;
842 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
843 ok_ole_success(hr, MkParseDisplayName);
844 if (pmk)
846 IMoniker_IsSystemMoniker(pmk, &moniker_type);
847 ok(moniker_type == MKSYS_CLASSMONIKER, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type);
848 IMoniker_Release(pmk);
850 hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
851 ok_ole_success(hr, IRunningObjectTable_Revoke);
852 IRunningObjectTable_Release(pprot);
854 hr = CreateFileMoniker(wszDisplayNameRunning, &pmk);
855 ok_ole_success(hr, CreateFileMoniker);
856 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
857 ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
858 hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
859 ok_ole_success(hr, IRunningObjectTable_Register);
860 IMoniker_Release(pmk);
861 pmk = NULL;
862 hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
863 ok_ole_success(hr, MkParseDisplayName);
864 if (pmk)
866 IMoniker_IsSystemMoniker(pmk, &moniker_type);
867 ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
868 IMoniker_Release(pmk);
870 hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
871 ok_ole_success(hr, IRunningObjectTable_Revoke);
872 IRunningObjectTable_Release(pprot);
874 hr = CoRegisterClassObject(&CLSID_StdFont, (IUnknown *)&ParseDisplayName, CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &pdwReg1);
875 ok_ole_success(hr, CoRegisterClassObject);
877 expected_display_name = wszDisplayNameProgId1;
878 hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
879 ok_ole_success(hr, MkParseDisplayName);
880 if (pmk)
882 IMoniker_IsSystemMoniker(pmk, &moniker_type);
883 ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
884 IMoniker_Release(pmk);
887 expected_display_name = wszDisplayNameProgId2;
888 hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
889 ok_ole_success(hr, MkParseDisplayName);
890 if (pmk)
892 IMoniker_IsSystemMoniker(pmk, &moniker_type);
893 ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
894 IMoniker_Release(pmk);
897 hr = MkParseDisplayName(pbc, wszDisplayNameProgIdFail, &eaten, &pmk);
898 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
899 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
901 hr = CoRevokeClassObject(pdwReg1);
902 ok_ole_success(hr, CoRevokeClassObject);
904 GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
905 strcat(szDisplayNameFile, "\\kernel32.dll");
906 MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile, sizeof(wszDisplayNameFile)/sizeof(wszDisplayNameFile[0]));
907 hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
908 ok_ole_success(hr, MkParseDisplayName);
909 if (pmk)
911 IMoniker_IsSystemMoniker(pmk, &moniker_type);
912 ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
913 IMoniker_Release(pmk);
916 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
917 ok_ole_success(hr, MkParseDisplayName);
919 if (pmk)
921 hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
922 ok_ole_success(hr, IMoniker_BindToObject);
924 if (SUCCEEDED(hr))
925 IUnknown_Release(object);
926 IMoniker_Release(pmk);
928 IBindCtx_Release(pbc);
930 /* Test the EnumMoniker interface */
931 hr = CreateBindCtx(0, &pbc);
932 ok_ole_success(hr, CreateBindCtx);
934 hr = CreateFileMoniker(wszFileName1, &pmk1);
935 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
936 hr = CreateFileMoniker(wszFileName2, &pmk2);
937 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
938 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
939 ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr);
941 /* Check EnumMoniker before registering */
942 hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
943 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
944 hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
945 /* Register a couple of Monikers and check is ok */
946 ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1);
947 hr = MK_E_NOOBJECT;
949 matchCnt = count_moniker_matches(pbc, spEM1);
950 trace("Number of matches is %i\n", matchCnt);
952 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
953 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
954 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
955 hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
957 trace("IROT::Register\n");
958 grflags=0;
959 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
960 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
961 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr,
962 pprot, grflags, lpEM1, pmk2, pdwReg2);
964 hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
965 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
967 matchCnt = count_moniker_matches(pbc, spEM2);
968 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
970 trace("IEnumMoniker::Clone\n");
971 IEnumMoniker_Clone(spEM2, &spEM3);
973 matchCnt = count_moniker_matches(pbc, spEM3);
974 ok(matchCnt==0, "Number of matches should be equal to 0 not %i\n", matchCnt);
975 trace("IEnumMoniker::Reset\n");
976 IEnumMoniker_Reset(spEM3);
978 matchCnt = count_moniker_matches(pbc, spEM3);
979 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
981 IRunningObjectTable_Revoke(pprot,pdwReg1);
982 IRunningObjectTable_Revoke(pprot,pdwReg2);
983 IUnknown_Release(lpEM1);
984 IEnumMoniker_Release(spEM1);
985 IEnumMoniker_Release(spEM2);
986 IEnumMoniker_Release(spEM3);
987 IMoniker_Release(pmk1);
988 IMoniker_Release(pmk2);
989 IRunningObjectTable_Release(pprot);
991 IBindCtx_Release(pbc);
994 static const LARGE_INTEGER llZero;
996 static const BYTE expected_class_moniker_marshal_data[] =
998 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
999 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1000 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1001 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1002 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1003 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1004 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1005 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1006 0x00,0x00,0x00,0x00,
1009 static const BYTE expected_class_moniker_saved_data[] =
1011 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1012 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1013 0x00,0x00,0x00,0x00,
1016 static const BYTE expected_class_moniker_comparison_data[] =
1018 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1019 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1020 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1021 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1024 static const WCHAR expected_class_moniker_display_name[] =
1026 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
1027 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
1028 '0','0','0','0','4','6',':',0
1031 static const BYTE expected_item_moniker_comparison_data[] =
1033 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1034 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1035 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1036 0x54,0x00,0x00,0x00,
1039 static const BYTE expected_item_moniker_saved_data[] =
1041 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1042 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1045 static const BYTE expected_item_moniker_marshal_data[] =
1047 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1048 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1049 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1050 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1051 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1052 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1053 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1054 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1057 static const BYTE expected_anti_moniker_marshal_data[] =
1059 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1060 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1061 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1062 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1063 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1064 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1065 0x01,0x00,0x00,0x00,
1068 static const BYTE expected_anti_moniker_saved_data[] =
1070 0x01,0x00,0x00,0x00,
1073 static const BYTE expected_anti_moniker_comparison_data[] =
1075 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1076 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1077 0x01,0x00,0x00,0x00,
1080 static const BYTE expected_gc_moniker_marshal_data[] =
1082 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1083 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1084 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1085 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1086 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1087 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1088 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1089 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1090 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1091 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1092 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1093 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1094 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1095 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1096 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1097 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1098 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1099 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1100 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1101 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1102 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1103 0x00,0x57,0x69,0x6e,0x65,0x00,
1106 static const BYTE expected_gc_moniker_saved_data[] =
1108 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1109 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1110 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1111 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1112 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1113 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1114 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1115 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1116 0x65,0x00,
1119 static const BYTE expected_gc_moniker_comparison_data[] =
1121 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1122 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1123 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1124 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1125 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1126 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1127 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1128 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1129 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1132 static void test_moniker(
1133 const char *testname, IMoniker *moniker,
1134 const BYTE *expected_moniker_marshal_data, unsigned int sizeof_expected_moniker_marshal_data,
1135 const BYTE *expected_moniker_saved_data, unsigned int sizeof_expected_moniker_saved_data,
1136 const BYTE *expected_moniker_comparison_data, unsigned int sizeof_expected_moniker_comparison_data,
1137 LPCWSTR expected_display_name)
1139 IStream * stream;
1140 IROTData * rotdata;
1141 HRESULT hr;
1142 HGLOBAL hglobal;
1143 LPBYTE moniker_data;
1144 DWORD moniker_size;
1145 DWORD i;
1146 BOOL same;
1147 BYTE buffer[128];
1148 IMoniker * moniker_proxy;
1149 LPOLESTR display_name;
1150 IBindCtx *bindctx;
1152 hr = IMoniker_IsDirty(moniker);
1153 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1155 /* Display Name */
1157 hr = CreateBindCtx(0, &bindctx);
1158 ok_ole_success(hr, CreateBindCtx);
1160 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1161 ok_ole_success(hr, IMoniker_GetDisplayName);
1162 ok(!lstrcmpW(display_name, expected_display_name), "%s: display name wasn't what was expected\n", testname);
1164 CoTaskMemFree(display_name);
1165 IBindCtx_Release(bindctx);
1167 hr = IMoniker_IsDirty(moniker);
1168 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1170 /* IROTData::GetComparisonData test */
1172 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1173 ok_ole_success(hr, IMoniker_QueryInterface_IID_IROTData);
1175 hr = IROTData_GetComparisonData(rotdata, buffer, sizeof(buffer), &moniker_size);
1176 ok_ole_success(hr, IROTData_GetComparisonData);
1178 if (hr != S_OK) moniker_size = 0;
1180 /* first check we have the right amount of data */
1181 ok(moniker_size == sizeof_expected_moniker_comparison_data,
1182 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1183 testname, sizeof_expected_moniker_comparison_data, moniker_size);
1185 /* then do a byte-by-byte comparison */
1186 same = TRUE;
1187 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
1189 if (expected_moniker_comparison_data[i] != buffer[i])
1191 same = FALSE;
1192 break;
1196 ok(same, "%s: Comparison data differs\n", testname);
1197 if (!same)
1199 for (i = 0; i < moniker_size; i++)
1201 if (i % 8 == 0) printf(" ");
1202 printf("0x%02x,", buffer[i]);
1203 if (i % 8 == 7) printf("\n");
1205 printf("\n");
1208 IROTData_Release(rotdata);
1210 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1212 /* Saving */
1214 hr = IMoniker_Save(moniker, stream, TRUE);
1215 ok_ole_success(hr, IMoniker_Save);
1217 hr = GetHGlobalFromStream(stream, &hglobal);
1218 ok_ole_success(hr, GetHGlobalFromStream);
1220 moniker_size = GlobalSize(hglobal);
1222 moniker_data = GlobalLock(hglobal);
1224 /* first check we have the right amount of data */
1225 ok(moniker_size == round_global_size(sizeof_expected_moniker_saved_data),
1226 "%s: Size of saved data differs (expected %d, actual %d)\n",
1227 testname, (DWORD)round_global_size(sizeof_expected_moniker_saved_data), moniker_size);
1229 /* then do a byte-by-byte comparison */
1230 same = TRUE;
1231 for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_saved_data)); i++)
1233 if (expected_moniker_saved_data[i] != moniker_data[i])
1235 same = FALSE;
1236 break;
1240 ok(same, "%s: Saved data differs\n", testname);
1241 if (!same)
1243 for (i = 0; i < moniker_size; i++)
1245 if (i % 8 == 0) printf(" ");
1246 printf("0x%02x,", moniker_data[i]);
1247 if (i % 8 == 7) printf("\n");
1249 printf("\n");
1252 GlobalUnlock(hglobal);
1254 IStream_Release(stream);
1256 /* Marshaling tests */
1258 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1259 ok_ole_success(hr, CreateStreamOnHGlobal);
1261 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1262 ok_ole_success(hr, CoMarshalInterface);
1264 hr = GetHGlobalFromStream(stream, &hglobal);
1265 ok_ole_success(hr, GetHGlobalFromStream);
1267 moniker_size = GlobalSize(hglobal);
1269 moniker_data = GlobalLock(hglobal);
1271 /* first check we have the right amount of data */
1272 ok(moniker_size == round_global_size(sizeof_expected_moniker_marshal_data),
1273 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1274 testname, (DWORD)round_global_size(sizeof_expected_moniker_marshal_data), moniker_size);
1276 /* then do a byte-by-byte comparison */
1277 same = TRUE;
1278 if (expected_moniker_marshal_data)
1280 for (i = 0; i < min(moniker_size, round_global_size(sizeof_expected_moniker_marshal_data)); i++)
1282 if (expected_moniker_marshal_data[i] != moniker_data[i])
1284 same = FALSE;
1285 break;
1290 ok(same, "%s: Marshaled data differs\n", testname);
1291 if (!same)
1293 for (i = 0; i < moniker_size; i++)
1295 if (i % 8 == 0) printf(" ");
1296 printf("0x%02x,", moniker_data[i]);
1297 if (i % 8 == 7) printf("\n");
1299 printf("\n");
1302 GlobalUnlock(hglobal);
1304 IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1305 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
1306 ok_ole_success(hr, CoUnmarshalInterface);
1308 IStream_Release(stream);
1309 IMoniker_Release(moniker_proxy);
1312 static void test_class_moniker(void)
1314 HRESULT hr;
1315 IMoniker *moniker;
1316 DWORD moniker_type;
1317 DWORD hash;
1318 IBindCtx *bindctx;
1319 IMoniker *inverse;
1320 IUnknown *unknown;
1321 FILETIME filetime;
1323 hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
1324 ok_ole_success(hr, CreateClassMoniker);
1325 if (!moniker) return;
1327 test_moniker("class moniker", moniker,
1328 expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
1329 expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
1330 expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
1331 expected_class_moniker_display_name);
1333 /* Hashing */
1335 hr = IMoniker_Hash(moniker, &hash);
1336 ok_ole_success(hr, IMoniker_Hash);
1338 ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
1339 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1340 hash);
1342 /* IsSystemMoniker test */
1344 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1345 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1347 ok(moniker_type == MKSYS_CLASSMONIKER,
1348 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1349 moniker_type);
1351 hr = CreateBindCtx(0, &bindctx);
1352 ok_ole_success(hr, CreateBindCtx);
1354 /* IsRunning test */
1355 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1356 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1358 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1359 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1361 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1362 ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
1364 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1365 ok_ole_success(hr, IMoniker_BindToObject);
1366 IUnknown_Release(unknown);
1368 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1369 ok_ole_success(hr, IMoniker_BindToStorage);
1370 IUnknown_Release(unknown);
1372 IBindCtx_Release(bindctx);
1374 hr = IMoniker_Inverse(moniker, &inverse);
1375 ok_ole_success(hr, IMoniker_Inverse);
1376 IMoniker_Release(inverse);
1378 IMoniker_Release(moniker);
1381 static void test_file_moniker(WCHAR* path)
1383 IStream *stream;
1384 IMoniker *moniker1 = NULL, *moniker2 = NULL;
1385 HRESULT hr;
1387 hr = CreateFileMoniker(path, &moniker1);
1388 ok_ole_success(hr, CreateFileMoniker);
1390 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1392 /* Marshal */
1393 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1394 ok_ole_success(hr, CoMarshalInterface);
1396 /* Rewind */
1397 hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1398 ok_ole_success(hr, IStream_Seek);
1400 /* Unmarshal */
1401 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
1402 ok_ole_success(hr, CoUnmarshalInterface);
1404 hr = IMoniker_IsEqual(moniker1, moniker2);
1405 ok_ole_success(hr, IsEqual);
1407 IStream_Release(stream);
1408 if (moniker1)
1409 IMoniker_Release(moniker1);
1410 if (moniker2)
1411 IMoniker_Release(moniker2);
1414 static void test_file_monikers(void)
1416 static WCHAR wszFile[][30] = {
1417 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1418 {'\\', '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},
1419 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1420 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1421 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1422 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1423 * U+0100 .. = Latin extended-A
1425 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1428 int i;
1430 trace("ACP is %u\n", GetACP());
1432 for (i = 0; i < COUNTOF(wszFile); ++i)
1434 int j ;
1435 if (i == 2)
1437 BOOL used;
1438 WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, wszFile[i], -1, NULL, 0, NULL, &used );
1439 if (used)
1441 skip("string 2 doesn't round trip in codepage %u\n", GetACP() );
1442 continue;
1445 for (j = lstrlenW(wszFile[i]); j > 0; --j)
1447 wszFile[i][j] = 0;
1448 test_file_moniker(wszFile[i]);
1453 static void test_item_moniker(void)
1455 HRESULT hr;
1456 IMoniker *moniker;
1457 DWORD moniker_type;
1458 DWORD hash;
1459 IBindCtx *bindctx;
1460 IMoniker *inverse;
1461 IUnknown *unknown;
1462 static const WCHAR wszDelimeter[] = {'!',0};
1463 static const WCHAR wszObjectName[] = {'T','e','s','t',0};
1464 static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
1466 hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker);
1467 ok_ole_success(hr, CreateItemMoniker);
1469 test_moniker("item moniker", moniker,
1470 expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
1471 expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
1472 expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
1473 expected_display_name);
1475 /* Hashing */
1477 hr = IMoniker_Hash(moniker, &hash);
1478 ok_ole_success(hr, IMoniker_Hash);
1480 ok(hash == 0x73c,
1481 "Hash value != 0x73c, instead was 0x%08x\n",
1482 hash);
1484 /* IsSystemMoniker test */
1486 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1487 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1489 ok(moniker_type == MKSYS_ITEMMONIKER,
1490 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1491 moniker_type);
1493 hr = CreateBindCtx(0, &bindctx);
1494 ok_ole_success(hr, CreateBindCtx);
1496 /* IsRunning test */
1497 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1498 ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1500 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1501 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1503 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1504 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1506 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1507 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1509 IBindCtx_Release(bindctx);
1511 hr = IMoniker_Inverse(moniker, &inverse);
1512 ok_ole_success(hr, IMoniker_Inverse);
1513 IMoniker_Release(inverse);
1515 IMoniker_Release(moniker);
1518 static void test_anti_moniker(void)
1520 HRESULT hr;
1521 IMoniker *moniker;
1522 DWORD moniker_type;
1523 DWORD hash;
1524 IBindCtx *bindctx;
1525 FILETIME filetime;
1526 IMoniker *inverse;
1527 IUnknown *unknown;
1528 static const WCHAR expected_display_name[] = { '\\','.','.',0 };
1530 hr = CreateAntiMoniker(&moniker);
1531 ok_ole_success(hr, CreateAntiMoniker);
1532 if (!moniker) return;
1534 test_moniker("anti moniker", moniker,
1535 expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
1536 expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
1537 expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
1538 expected_display_name);
1540 /* Hashing */
1541 hr = IMoniker_Hash(moniker, &hash);
1542 ok_ole_success(hr, IMoniker_Hash);
1543 ok(hash == 0x80000001,
1544 "Hash value != 0x80000001, instead was 0x%08x\n",
1545 hash);
1547 /* IsSystemMoniker test */
1548 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1549 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1550 ok(moniker_type == MKSYS_ANTIMONIKER,
1551 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1552 moniker_type);
1554 hr = IMoniker_Inverse(moniker, &inverse);
1555 ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
1556 ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
1558 hr = CreateBindCtx(0, &bindctx);
1559 ok_ole_success(hr, CreateBindCtx);
1561 /* IsRunning test */
1562 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1563 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1565 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1566 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1568 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1569 ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr);
1571 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1572 ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr);
1574 IBindCtx_Release(bindctx);
1576 IMoniker_Release(moniker);
1579 static void test_generic_composite_moniker(void)
1581 HRESULT hr;
1582 IMoniker *moniker;
1583 IMoniker *moniker1;
1584 IMoniker *moniker2;
1585 DWORD moniker_type;
1586 DWORD hash;
1587 IBindCtx *bindctx;
1588 FILETIME filetime;
1589 IMoniker *inverse;
1590 IUnknown *unknown;
1591 static const WCHAR wszDelimeter1[] = {'!',0};
1592 static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
1593 static const WCHAR wszDelimeter2[] = {'#',0};
1594 static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
1595 static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1597 hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1);
1598 ok_ole_success(hr, CreateItemMoniker);
1599 hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2);
1600 ok_ole_success(hr, CreateItemMoniker);
1601 hr = CreateGenericComposite(moniker1, moniker2, &moniker);
1602 ok_ole_success(hr, CreateGenericComposite);
1604 test_moniker("generic composite moniker", moniker,
1605 expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
1606 expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
1607 expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
1608 expected_display_name);
1610 /* Hashing */
1612 hr = IMoniker_Hash(moniker, &hash);
1613 ok_ole_success(hr, IMoniker_Hash);
1615 ok(hash == 0xd87,
1616 "Hash value != 0xd87, instead was 0x%08x\n",
1617 hash);
1619 /* IsSystemMoniker test */
1621 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1622 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1624 ok(moniker_type == MKSYS_GENERICCOMPOSITE,
1625 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1626 moniker_type);
1628 hr = CreateBindCtx(0, &bindctx);
1629 ok_ole_success(hr, CreateBindCtx);
1631 /* IsRunning test */
1632 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1633 ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1635 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1636 todo_wine
1637 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1639 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1640 ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);
1642 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1643 todo_wine
1644 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1646 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1647 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1649 IBindCtx_Release(bindctx);
1651 hr = IMoniker_Inverse(moniker, &inverse);
1652 ok_ole_success(hr, IMoniker_Inverse);
1653 IMoniker_Release(inverse);
1655 IMoniker_Release(moniker);
1658 static void test_pointer_moniker(void)
1660 HRESULT hr;
1661 IMoniker *moniker;
1662 DWORD moniker_type;
1663 DWORD hash;
1664 IBindCtx *bindctx;
1665 FILETIME filetime;
1666 IMoniker *inverse;
1667 IUnknown *unknown;
1668 IStream *stream;
1669 IROTData *rotdata;
1670 LPOLESTR display_name;
1672 cLocks = 0;
1674 hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, NULL);
1675 ok(hr == E_INVALIDARG, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1677 hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, &moniker);
1678 ok_ole_success(hr, CreatePointerMoniker);
1679 if (!moniker) return;
1681 ok_more_than_one_lock();
1683 /* Display Name */
1685 hr = CreateBindCtx(0, &bindctx);
1686 ok_ole_success(hr, CreateBindCtx);
1688 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1689 ok(hr == E_NOTIMPL, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1691 IBindCtx_Release(bindctx);
1693 hr = IMoniker_IsDirty(moniker);
1694 ok(hr == S_FALSE, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr);
1696 /* IROTData::GetComparisonData test */
1698 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1699 ok(hr == E_NOINTERFACE, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
1701 /* Saving */
1703 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1704 ok_ole_success(hr, CreateStreamOnHGlobal);
1706 hr = IMoniker_Save(moniker, stream, TRUE);
1707 ok(hr == E_NOTIMPL, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1709 IStream_Release(stream);
1711 /* Hashing */
1712 hr = IMoniker_Hash(moniker, &hash);
1713 ok_ole_success(hr, IMoniker_Hash);
1714 ok(hash == (DWORD)&Test_ClassFactory,
1715 "Hash value should have been 0x%08x, instead of 0x%08x\n",
1716 (DWORD)&Test_ClassFactory, hash);
1718 /* IsSystemMoniker test */
1719 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1720 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1721 ok(moniker_type == MKSYS_POINTERMONIKER,
1722 "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1723 moniker_type);
1725 hr = IMoniker_Inverse(moniker, &inverse);
1726 ok_ole_success(hr, IMoniker_Inverse);
1727 IMoniker_Release(inverse);
1729 hr = CreateBindCtx(0, &bindctx);
1730 ok_ole_success(hr, CreateBindCtx);
1732 /* IsRunning test */
1733 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1734 ok(hr == S_OK, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr);
1736 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1737 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1739 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1740 ok_ole_success(hr, IMoniker_BindToObject);
1741 IUnknown_Release(unknown);
1743 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1744 ok_ole_success(hr, IMoniker_BindToStorage);
1745 IUnknown_Release(unknown);
1747 IMoniker_Release(moniker);
1749 ok_no_locks();
1751 hr = CreatePointerMoniker(NULL, &moniker);
1752 ok_ole_success(hr, CreatePointerMoniker);
1754 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1755 ok(hr == E_UNEXPECTED, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1757 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1758 ok(hr == E_UNEXPECTED, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1760 IBindCtx_Release(bindctx);
1762 IMoniker_Release(moniker);
1765 static void test_bind_context(void)
1767 HRESULT hr;
1768 IBindCtx *pBindCtx;
1769 IEnumString *pEnumString;
1770 BIND_OPTS2 bind_opts;
1771 HeapUnknown *unknown;
1772 HeapUnknown *unknown2;
1773 IUnknown *param_obj;
1774 ULONG refs;
1775 static const WCHAR wszParamName[] = {'G','e','m','m','a',0};
1776 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1778 hr = CreateBindCtx(0, NULL);
1779 ok(hr == E_INVALIDARG, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1781 hr = CreateBindCtx(0xdeadbeef, &pBindCtx);
1782 ok(hr == E_INVALIDARG, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1784 hr = CreateBindCtx(0, &pBindCtx);
1785 ok_ole_success(hr, "CreateBindCtx");
1787 bind_opts.cbStruct = -1;
1788 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1789 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1790 ok(bind_opts.cbStruct == sizeof(bind_opts) ||
1791 bind_opts.cbStruct == sizeof(bind_opts) + sizeof(void*), /* Vista */
1792 "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1794 bind_opts.cbStruct = sizeof(BIND_OPTS);
1795 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1796 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1797 ok(bind_opts.cbStruct == sizeof(BIND_OPTS), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1799 bind_opts.cbStruct = sizeof(bind_opts);
1800 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1801 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1802 ok(bind_opts.cbStruct == sizeof(bind_opts), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1803 ok(bind_opts.grfFlags == 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts.grfFlags);
1804 ok(bind_opts.grfMode == STGM_READWRITE, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts.grfMode);
1805 ok(bind_opts.dwTickCountDeadline == 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts.dwTickCountDeadline);
1806 ok(bind_opts.dwTrackFlags == 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts.dwTrackFlags);
1807 ok(bind_opts.dwClassContext == (CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER),
1808 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts.dwClassContext);
1809 ok(bind_opts.locale == GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts.locale);
1810 ok(bind_opts.pServerInfo == NULL, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts.pServerInfo);
1812 bind_opts.cbStruct = -1;
1813 hr = IBindCtx_SetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1814 ok(hr == E_INVALIDARG, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1816 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, NULL);
1817 ok(hr == E_INVALIDARG, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1819 unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1820 unknown->lpVtbl = &HeapUnknown_Vtbl;
1821 unknown->refs = 1;
1822 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, (IUnknown *)&unknown->lpVtbl);
1823 ok_ole_success(hr, "IBindCtx_RegisterObjectParam");
1825 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszParamName, &param_obj);
1826 ok_ole_success(hr, "IBindCtx_GetObjectParam");
1827 IUnknown_Release(param_obj);
1829 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszNonExistent, &param_obj);
1830 ok(hr == E_FAIL, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1831 ok(param_obj == NULL, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj);
1833 hr = IBindCtx_RevokeObjectParam(pBindCtx, (WCHAR *)wszNonExistent);
1834 ok(hr == E_FAIL, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1836 hr = IBindCtx_EnumObjectParam(pBindCtx, &pEnumString);
1837 ok(hr == E_NOTIMPL, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1838 ok(!pEnumString, "pEnumString should be NULL\n");
1840 hr = IBindCtx_RegisterObjectBound(pBindCtx, NULL);
1841 ok_ole_success(hr, "IBindCtx_RegisterObjectBound(NULL)");
1843 hr = IBindCtx_RevokeObjectBound(pBindCtx, NULL);
1844 ok(hr == E_INVALIDARG, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr);
1846 unknown2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1847 unknown2->lpVtbl = &HeapUnknown_Vtbl;
1848 unknown2->refs = 1;
1849 hr = IBindCtx_RegisterObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1850 ok_ole_success(hr, "IBindCtx_RegisterObjectBound");
1852 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1853 ok_ole_success(hr, "IBindCtx_RevokeObjectBound");
1855 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1856 ok(hr == MK_E_NOTBOUND, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr);
1858 IBindCtx_Release(pBindCtx);
1860 refs = IUnknown_Release((IUnknown *)&unknown->lpVtbl);
1861 ok(!refs, "object param should have been destroyed, instead of having %d refs\n", refs);
1863 refs = IUnknown_Release((IUnknown *)&unknown2->lpVtbl);
1864 ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
1867 static void test_save_load_filemoniker(void)
1869 IMoniker* pMk;
1870 IStream* pStm;
1871 HRESULT hr;
1872 ULARGE_INTEGER size;
1873 LARGE_INTEGER zero_pos, dead_pos, nulls_pos;
1874 DWORD some_val = 0xFEDCBA98;
1875 int i;
1877 /* see FileMonikerImpl_Save docs */
1878 zero_pos.QuadPart = 0;
1879 dead_pos.QuadPart = sizeof(WORD) + sizeof(DWORD) + (lstrlenW(wszFileName1) + 1) + sizeof(WORD);
1880 nulls_pos.QuadPart = dead_pos.QuadPart + sizeof(WORD);
1882 /* create the stream we're going to write to */
1883 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm);
1884 ok_ole_success(hr, "CreateStreamOnHGlobal");
1886 size.u.LowPart = 128;
1887 hr = IStream_SetSize(pStm, size);
1888 ok_ole_success(hr, "IStream_SetSize");
1890 /* create and save a moniker */
1891 hr = CreateFileMoniker(wszFileName1, &pMk);
1892 ok_ole_success(hr, "CreateFileMoniker");
1894 hr = IMoniker_Save(pMk, pStm, TRUE);
1895 ok_ole_success(hr, "IMoniker_Save");
1897 hr = IMoniker_Release(pMk);
1898 ok_ole_success(hr, "IMoniker_Release");
1900 /* overwrite the constants with various values */
1901 hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL);
1902 ok_ole_success(hr, "IStream_Seek");
1903 hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL);
1904 ok_ole_success(hr, "IStream_Write");
1906 hr = IStream_Seek(pStm, dead_pos, STREAM_SEEK_SET, NULL);
1907 ok_ole_success(hr, "IStream_Seek");
1908 hr = IStream_Write(pStm, &some_val, sizeof(WORD), NULL);
1909 ok_ole_success(hr, "IStream_Write");
1911 hr = IStream_Seek(pStm, nulls_pos, STREAM_SEEK_SET, NULL);
1912 ok_ole_success(hr, "IStream_Seek");
1913 for(i = 0; i < 5; ++i){
1914 hr = IStream_Write(pStm, &some_val, sizeof(DWORD), NULL);
1915 ok_ole_success(hr, "IStream_Write");
1918 /* go back to the start of the stream */
1919 hr = IStream_Seek(pStm, zero_pos, STREAM_SEEK_SET, NULL);
1920 ok_ole_success(hr, "IStream_Seek");
1922 /* create a new moniker and load into it */
1923 hr = CreateFileMoniker(wszFileName1, &pMk);
1924 ok_ole_success(hr, "CreateFileMoniker");
1926 hr = IMoniker_Load(pMk, pStm);
1927 ok_ole_success(hr, "IMoniker_Load");
1929 hr = IMoniker_Release(pMk);
1930 ok_ole_success(hr, "IMoniker_Release");
1932 hr = IStream_Release(pStm);
1933 ok_ole_success(hr, "IStream_Release");
1936 START_TEST(moniker)
1938 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1940 test_ROT();
1941 test_ROT_multiple_entries();
1942 test_MkParseDisplayName();
1943 test_class_moniker();
1944 test_file_monikers();
1945 test_item_moniker();
1946 test_anti_moniker();
1947 test_generic_composite_moniker();
1948 test_pointer_moniker();
1949 test_save_load_filemoniker();
1951 /* FIXME: test moniker creation funcs and parsing other moniker formats */
1953 test_bind_context();
1955 CoUninitialize();