gdiplus: Brush tests.
[wine/gsoc-2012-control.git] / dlls / ole32 / tests / moniker.c
blob14f50184f24fb9598a3efe569bdc1e4680e01590
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 "comcat.h"
32 #include "olectl.h"
34 #include "wine/test.h"
36 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
37 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
38 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
39 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
41 #define CHECK_EXPECTED_METHOD(method_name) \
42 do { \
43 trace("%s\n", method_name); \
44 ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
45 if (*expected_method_list) \
46 { \
47 ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
48 *expected_method_list, method_name); \
49 expected_method_list++; \
50 } \
51 } while(0)
53 static char const * const *expected_method_list;
54 static const WCHAR wszFileName1[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
55 static const WCHAR wszFileName2[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
57 static const CLSID CLSID_WineTest =
58 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
59 0x9474ba1a,
60 0x258b,
61 0x490b,
62 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
65 static const CLSID CLSID_TestMoniker =
66 { /* b306bfbc-496e-4f53-b93e-2ff9c83223d7 */
67 0xb306bfbc,
68 0x496e,
69 0x4f53,
70 {0xb9, 0x3e, 0x2f, 0xf9, 0xc8, 0x32, 0x23, 0xd7}
73 static LONG cLocks;
75 static void LockModule(void)
77 InterlockedIncrement(&cLocks);
80 static void UnlockModule(void)
82 InterlockedDecrement(&cLocks);
85 static HRESULT WINAPI Test_IClassFactory_QueryInterface(
86 LPCLASSFACTORY iface,
87 REFIID riid,
88 LPVOID *ppvObj)
90 if (ppvObj == NULL) return E_POINTER;
92 if (IsEqualGUID(riid, &IID_IUnknown) ||
93 IsEqualGUID(riid, &IID_IClassFactory))
95 *ppvObj = (LPVOID)iface;
96 IClassFactory_AddRef(iface);
97 return S_OK;
100 *ppvObj = NULL;
101 return E_NOINTERFACE;
104 static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
106 LockModule();
107 return 2; /* non-heap-based object */
110 static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
112 UnlockModule();
113 return 1; /* non-heap-based object */
116 static HRESULT WINAPI Test_IClassFactory_CreateInstance(
117 LPCLASSFACTORY iface,
118 LPUNKNOWN pUnkOuter,
119 REFIID riid,
120 LPVOID *ppvObj)
122 return E_NOTIMPL;
125 static HRESULT WINAPI Test_IClassFactory_LockServer(
126 LPCLASSFACTORY iface,
127 BOOL fLock)
129 return S_OK;
132 static const IClassFactoryVtbl TestClassFactory_Vtbl =
134 Test_IClassFactory_QueryInterface,
135 Test_IClassFactory_AddRef,
136 Test_IClassFactory_Release,
137 Test_IClassFactory_CreateInstance,
138 Test_IClassFactory_LockServer
141 static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
143 typedef struct
145 const IUnknownVtbl *lpVtbl;
146 ULONG refs;
147 } HeapUnknown;
149 static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
151 if (IsEqualIID(riid, &IID_IUnknown))
153 IUnknown_AddRef(iface);
154 *ppv = (LPVOID)iface;
155 return S_OK;
157 *ppv = NULL;
158 return E_NOINTERFACE;
161 static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface)
163 HeapUnknown *This = (HeapUnknown *)iface;
164 return InterlockedIncrement((LONG*)&This->refs);
167 static ULONG WINAPI HeapUnknown_Release(IUnknown *iface)
169 HeapUnknown *This = (HeapUnknown *)iface;
170 ULONG refs = InterlockedDecrement((LONG*)&This->refs);
171 if (!refs) HeapFree(GetProcessHeap(), 0, This);
172 return refs;
175 static const IUnknownVtbl HeapUnknown_Vtbl =
177 HeapUnknown_QueryInterface,
178 HeapUnknown_AddRef,
179 HeapUnknown_Release
182 static HRESULT WINAPI
183 MonikerNoROTData_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
185 if (!ppvObject)
186 return E_INVALIDARG;
188 *ppvObject = 0;
190 if (IsEqualIID(&IID_IUnknown, riid) ||
191 IsEqualIID(&IID_IPersist, riid) ||
192 IsEqualIID(&IID_IPersistStream,riid) ||
193 IsEqualIID(&IID_IMoniker, riid))
194 *ppvObject = iface;
195 if (IsEqualIID(&IID_IROTData, riid))
196 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
198 if ((*ppvObject)==0)
199 return E_NOINTERFACE;
201 IMoniker_AddRef(iface);
203 return S_OK;
206 static ULONG WINAPI
207 Moniker_AddRef(IMoniker* iface)
209 return 2;
212 static ULONG WINAPI
213 Moniker_Release(IMoniker* iface)
215 return 1;
218 static HRESULT WINAPI
219 Moniker_GetClassID(IMoniker* iface, CLSID *pClassID)
221 CHECK_EXPECTED_METHOD("Moniker_GetClassID");
223 *pClassID = CLSID_TestMoniker;
225 return S_OK;
228 static HRESULT WINAPI
229 Moniker_IsDirty(IMoniker* iface)
231 CHECK_EXPECTED_METHOD("Moniker_IsDirty");
233 return S_FALSE;
236 static HRESULT WINAPI
237 Moniker_Load(IMoniker* iface, IStream* pStm)
239 CHECK_EXPECTED_METHOD("Moniker_Load");
240 return E_NOTIMPL;
243 static HRESULT WINAPI
244 Moniker_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
246 CHECK_EXPECTED_METHOD("Moniker_Save");
247 return E_NOTIMPL;
250 static HRESULT WINAPI
251 Moniker_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
253 CHECK_EXPECTED_METHOD("Moniker_GetSizeMax");
254 return E_NOTIMPL;
257 static HRESULT WINAPI
258 Moniker_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
259 REFIID riid, VOID** ppvResult)
261 CHECK_EXPECTED_METHOD("Moniker_BindToObject");
262 return E_NOTIMPL;
265 static HRESULT WINAPI
266 Moniker_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
267 REFIID riid, VOID** ppvObject)
269 CHECK_EXPECTED_METHOD("Moniker_BindToStorage");
270 return E_NOTIMPL;
273 static HRESULT WINAPI
274 Moniker_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
275 IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
277 CHECK_EXPECTED_METHOD("Moniker_Reduce");
279 if (ppmkReduced==NULL)
280 return E_POINTER;
282 IMoniker_AddRef(iface);
284 *ppmkReduced=iface;
286 return MK_S_REDUCED_TO_SELF;
289 static HRESULT WINAPI
290 Moniker_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
291 BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
293 CHECK_EXPECTED_METHOD("Moniker_ComposeWith");
294 return E_NOTIMPL;
297 static HRESULT WINAPI
298 Moniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
300 CHECK_EXPECTED_METHOD("Moniker_Enum");
302 if (ppenumMoniker == NULL)
303 return E_POINTER;
305 *ppenumMoniker = NULL;
307 return S_OK;
310 static HRESULT WINAPI
311 Moniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
313 CHECK_EXPECTED_METHOD("Moniker_IsEqual");
314 return E_NOTIMPL;
317 static HRESULT WINAPI
318 Moniker_Hash(IMoniker* iface,DWORD* pdwHash)
320 CHECK_EXPECTED_METHOD("Moniker_Hash");
321 return E_NOTIMPL;
324 static HRESULT WINAPI
325 Moniker_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
326 IMoniker* pmkNewlyRunning)
328 CHECK_EXPECTED_METHOD("Moniker_IsRunning");
329 return E_NOTIMPL;
332 static HRESULT WINAPI
333 Moniker_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
334 IMoniker* pmkToLeft, FILETIME* pFileTime)
336 CHECK_EXPECTED_METHOD("Moniker_GetTimeOfLastChange");
337 return E_NOTIMPL;
340 static HRESULT WINAPI
341 Moniker_Inverse(IMoniker* iface,IMoniker** ppmk)
343 CHECK_EXPECTED_METHOD("Moniker_Inverse");
344 return E_NOTIMPL;
347 static HRESULT WINAPI
348 Moniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
350 CHECK_EXPECTED_METHOD("Moniker_CommonPrefixWith");
351 return E_NOTIMPL;
354 static HRESULT WINAPI
355 Moniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
357 CHECK_EXPECTED_METHOD("Moniker_RelativePathTo");
358 return E_NOTIMPL;
361 static HRESULT WINAPI
362 Moniker_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
363 IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
365 static const WCHAR wszDisplayName[] = {'*','*','G','e','m','m','a',0};
366 CHECK_EXPECTED_METHOD("Moniker_GetDisplayName");
367 *ppszDisplayName = (LPOLESTR)CoTaskMemAlloc(sizeof(wszDisplayName));
368 memcpy(*ppszDisplayName, wszDisplayName, sizeof(wszDisplayName));
369 return S_OK;
372 static HRESULT WINAPI
373 Moniker_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
374 LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
376 CHECK_EXPECTED_METHOD("Moniker_ParseDisplayName");
377 return E_NOTIMPL;
380 static HRESULT WINAPI
381 Moniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
383 CHECK_EXPECTED_METHOD("Moniker_IsSystemMoniker");
385 if (!pwdMksys)
386 return E_POINTER;
388 (*pwdMksys)=MKSYS_NONE;
390 return S_FALSE;
393 static const IMonikerVtbl MonikerNoROTDataVtbl =
395 MonikerNoROTData_QueryInterface,
396 Moniker_AddRef,
397 Moniker_Release,
398 Moniker_GetClassID,
399 Moniker_IsDirty,
400 Moniker_Load,
401 Moniker_Save,
402 Moniker_GetSizeMax,
403 Moniker_BindToObject,
404 Moniker_BindToStorage,
405 Moniker_Reduce,
406 Moniker_ComposeWith,
407 Moniker_Enum,
408 Moniker_IsEqual,
409 Moniker_Hash,
410 Moniker_IsRunning,
411 Moniker_GetTimeOfLastChange,
412 Moniker_Inverse,
413 Moniker_CommonPrefixWith,
414 Moniker_RelativePathTo,
415 Moniker_GetDisplayName,
416 Moniker_ParseDisplayName,
417 Moniker_IsSystemMoniker
420 static IMoniker MonikerNoROTData = { &MonikerNoROTDataVtbl };
422 static IMoniker Moniker;
424 static HRESULT WINAPI
425 ROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
427 return IMoniker_QueryInterface(&Moniker, riid, ppvObject);
430 static ULONG WINAPI
431 ROTData_AddRef(IROTData *iface)
433 return 2;
436 static ULONG WINAPI
437 ROTData_Release(IROTData* iface)
439 return 1;
442 static HRESULT WINAPI
443 ROTData_GetComparisonData(IROTData* iface, BYTE* pbData,
444 ULONG cbMax, ULONG* pcbData)
446 CHECK_EXPECTED_METHOD("ROTData_GetComparisonData");
448 *pcbData = 1;
449 if (cbMax < *pcbData)
450 return E_OUTOFMEMORY;
452 *pbData = 0xde;
454 return S_OK;
457 static IROTDataVtbl ROTDataVtbl =
459 ROTData_QueryInterface,
460 ROTData_AddRef,
461 ROTData_Release,
462 ROTData_GetComparisonData
465 static IROTData ROTData = { &ROTDataVtbl };
467 static HRESULT WINAPI
468 Moniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
470 if (!ppvObject)
471 return E_INVALIDARG;
473 *ppvObject = 0;
475 if (IsEqualIID(&IID_IUnknown, riid) ||
476 IsEqualIID(&IID_IPersist, riid) ||
477 IsEqualIID(&IID_IPersistStream,riid) ||
478 IsEqualIID(&IID_IMoniker, riid))
479 *ppvObject = iface;
480 if (IsEqualIID(&IID_IROTData, riid))
482 CHECK_EXPECTED_METHOD("Moniker_QueryInterface(IID_IROTData)");
483 *ppvObject = &ROTData;
486 if ((*ppvObject)==0)
487 return E_NOINTERFACE;
489 IMoniker_AddRef(iface);
491 return S_OK;
494 static const IMonikerVtbl MonikerVtbl =
496 Moniker_QueryInterface,
497 Moniker_AddRef,
498 Moniker_Release,
499 Moniker_GetClassID,
500 Moniker_IsDirty,
501 Moniker_Load,
502 Moniker_Save,
503 Moniker_GetSizeMax,
504 Moniker_BindToObject,
505 Moniker_BindToStorage,
506 Moniker_Reduce,
507 Moniker_ComposeWith,
508 Moniker_Enum,
509 Moniker_IsEqual,
510 Moniker_Hash,
511 Moniker_IsRunning,
512 Moniker_GetTimeOfLastChange,
513 Moniker_Inverse,
514 Moniker_CommonPrefixWith,
515 Moniker_RelativePathTo,
516 Moniker_GetDisplayName,
517 Moniker_ParseDisplayName,
518 Moniker_IsSystemMoniker
521 static IMoniker Moniker = { &MonikerVtbl };
523 static void test_ROT(void)
525 static const WCHAR wszFileName[] = {'B','E','2','0','E','2','F','5','-',
526 '1','9','0','3','-','4','A','A','E','-','B','1','A','F','-',
527 '2','0','4','6','E','5','8','6','C','9','2','5',0};
528 HRESULT hr;
529 IMoniker *pMoniker = NULL;
530 IRunningObjectTable *pROT = NULL;
531 DWORD dwCookie;
532 static const char *methods_register_no_ROTData[] =
534 "Moniker_Reduce",
535 "Moniker_GetTimeOfLastChange",
536 "Moniker_QueryInterface(IID_IROTData)",
537 "Moniker_GetDisplayName",
538 "Moniker_GetClassID",
539 NULL
541 static const char *methods_register[] =
543 "Moniker_Reduce",
544 "Moniker_GetTimeOfLastChange",
545 "Moniker_QueryInterface(IID_IROTData)",
546 "ROTData_GetComparisonData",
547 NULL
549 static const char *methods_isrunning_no_ROTData[] =
551 "Moniker_Reduce",
552 "Moniker_QueryInterface(IID_IROTData)",
553 "Moniker_GetDisplayName",
554 "Moniker_GetClassID",
555 NULL
557 static const char *methods_isrunning[] =
559 "Moniker_Reduce",
560 "Moniker_QueryInterface(IID_IROTData)",
561 "ROTData_GetComparisonData",
562 NULL
565 cLocks = 0;
567 hr = GetRunningObjectTable(0, &pROT);
568 ok_ole_success(hr, GetRunningObjectTable);
570 expected_method_list = methods_register_no_ROTData;
571 /* try with our own moniker that doesn't support IROTData */
572 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
573 (IUnknown*)&Test_ClassFactory, &MonikerNoROTData, &dwCookie);
574 todo_wine { /* only fails because of lack of IMoniker marshaling */
575 ok_ole_success(hr, IRunningObjectTable_Register);
577 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
579 todo_wine { /* only fails because of lack of IMoniker marshaling */
580 ok_more_than_one_lock();
583 expected_method_list = methods_isrunning_no_ROTData;
584 hr = IRunningObjectTable_IsRunning(pROT, &MonikerNoROTData);
585 todo_wine { /* only fails because of lack of IMoniker marshaling */
586 ok_ole_success(hr, IRunningObjectTable_IsRunning);
588 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
590 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
591 todo_wine { /* only fails because of lack of IMoniker marshaling */
592 ok_ole_success(hr, IRunningObjectTable_Revoke);
595 ok_no_locks();
597 expected_method_list = methods_register;
598 /* try with our own moniker */
599 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
600 (IUnknown*)&Test_ClassFactory, &Moniker, &dwCookie);
601 todo_wine { /* only fails because of lack of IMoniker marshaling */
602 ok_ole_success(hr, IRunningObjectTable_Register);
604 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
606 todo_wine { /* only fails because of lack of IMoniker marshaling */
607 ok_more_than_one_lock();
610 expected_method_list = methods_isrunning;
611 hr = IRunningObjectTable_IsRunning(pROT, &Moniker);
612 todo_wine { /* only fails because of lack of IMoniker marshaling */
613 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 todo_wine { /* only fails because of lack of IMoniker marshaling */
619 ok_ole_success(hr, IRunningObjectTable_Revoke);
622 ok_no_locks();
624 hr = CreateFileMoniker(wszFileName, &pMoniker);
625 ok_ole_success(hr, CreateClassMoniker);
627 /* test flags: 0 */
628 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown*)&Test_ClassFactory,
629 pMoniker, &dwCookie);
630 ok_ole_success(hr, IRunningObjectTable_Register);
632 ok_more_than_one_lock();
634 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
635 ok_ole_success(hr, IRunningObjectTable_Revoke);
637 ok_no_locks();
639 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
640 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
641 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
642 ok_ole_success(hr, IRunningObjectTable_Register);
644 ok_more_than_one_lock();
646 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
647 ok_ole_success(hr, IRunningObjectTable_Revoke);
649 ok_no_locks();
651 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
652 /* only succeeds when process is started by SCM and has LocalService
653 * or RunAs AppId values */
654 hr = IRunningObjectTable_Register(pROT,
655 ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT,
656 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
657 todo_wine {
658 ok(hr == CO_E_WRONG_SERVER_IDENTITY, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr);
661 hr = IRunningObjectTable_Register(pROT, 0xdeadbeef,
662 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
663 ok(hr == E_INVALIDARG, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr);
665 IMoniker_Release(pMoniker);
667 IRunningObjectTable_Release(pROT);
670 static HRESULT WINAPI ParseDisplayName_QueryInterface(IParseDisplayName *iface, REFIID riid, void **ppv)
672 if (IsEqualIID(riid, &IID_IUnknown) ||
673 IsEqualIID(riid, &IID_IParseDisplayName))
675 *ppv = iface;
676 IUnknown_AddRef(iface);
677 return S_OK;
679 *ppv = NULL;
680 return E_NOINTERFACE;
683 static ULONG WINAPI ParseDisplayName_AddRef(IParseDisplayName *iface)
685 return 2;
688 static ULONG WINAPI ParseDisplayName_Release(IParseDisplayName *iface)
690 return 1;
693 static LPCWSTR expected_display_name;
695 static HRESULT WINAPI ParseDisplayName_ParseDisplayName(IParseDisplayName *iface,
696 IBindCtx *pbc,
697 LPOLESTR pszDisplayName,
698 ULONG *pchEaten,
699 IMoniker **ppmkOut)
701 char display_nameA[256];
702 WideCharToMultiByte(CP_ACP, 0, pszDisplayName, -1, display_nameA, sizeof(display_nameA), NULL, NULL);
703 ok(!lstrcmpW(pszDisplayName, expected_display_name), "unexpected display name \"%s\"\n", display_nameA);
704 ok(pszDisplayName == expected_display_name, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
705 *pchEaten = lstrlenW(pszDisplayName);
706 return CreateAntiMoniker(ppmkOut);
709 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl =
711 ParseDisplayName_QueryInterface,
712 ParseDisplayName_AddRef,
713 ParseDisplayName_Release,
714 ParseDisplayName_ParseDisplayName
717 static IParseDisplayName ParseDisplayName = { &ParseDisplayName_Vtbl };
719 static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
721 IMoniker * spMoniker;
722 int monCnt=0, matchCnt=0;
724 while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK))
726 HRESULT hr;
727 WCHAR * szDisplayn;
728 monCnt++;
729 hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL, &szDisplayn);
730 if (SUCCEEDED(hr))
732 if (!lstrcmpiW(szDisplayn, wszFileName1) || !lstrcmpiW(szDisplayn, wszFileName2))
733 matchCnt++;
734 CoTaskMemFree(szDisplayn);
737 trace("Total number of monikers is %i\n", monCnt);
738 return matchCnt;
741 static void test_MkParseDisplayName(void)
743 IBindCtx * pbc = NULL;
744 HRESULT hr;
745 IMoniker * pmk = NULL;
746 IMoniker * pmk1 = NULL;
747 IMoniker * pmk2 = NULL;
748 ULONG eaten;
749 int matchCnt;
750 IUnknown * object = NULL;
752 IUnknown *lpEM1;
754 IEnumMoniker *spEM1 = NULL;
755 IEnumMoniker *spEM2 = NULL;
756 IEnumMoniker *spEM3 = NULL;
758 DWORD pdwReg1=0;
759 DWORD grflags=0;
760 DWORD pdwReg2=0;
761 DWORD moniker_type;
762 IRunningObjectTable * pprot=NULL;
764 /* CLSID of My Computer */
765 static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
766 '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};
767 static const WCHAR wszDisplayNameClsid[] = {'c','l','s','i','d',':',0};
768 static const WCHAR wszNonExistentProgId[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
769 static const WCHAR wszDisplayNameRunning[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
770 static const WCHAR wszDisplayNameProgId1[] = {'S','t','d','F','o','n','t',':',0};
771 static const WCHAR wszDisplayNameProgId2[] = {'@','S','t','d','F','o','n','t',0};
772 static const WCHAR wszDisplayNameProgIdFail[] = {'S','t','d','F','o','n','t',0};
773 char szDisplayNameFile[256];
774 WCHAR wszDisplayNameFile[256];
776 hr = CreateBindCtx(0, &pbc);
777 ok_ole_success(hr, CreateBindCtx);
779 hr = MkParseDisplayName(pbc, wszNonExistentProgId, &eaten, &pmk);
780 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
781 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
783 /* no special handling of "clsid:" without the string form of the clsid
784 * following */
785 hr = MkParseDisplayName(pbc, wszDisplayNameClsid, &eaten, &pmk);
786 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
787 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
789 /* shows clsid has higher precedence than a running object */
790 hr = CreateFileMoniker(wszDisplayName, &pmk);
791 ok_ole_success(hr, CreateFileMoniker);
792 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
793 ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
794 hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
795 ok_ole_success(hr, IRunningObjectTable_Register);
796 IMoniker_Release(pmk);
797 pmk = NULL;
798 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
799 ok_ole_success(hr, MkParseDisplayName);
800 if (pmk)
802 IMoniker_IsSystemMoniker(pmk, &moniker_type);
803 ok(moniker_type == MKSYS_CLASSMONIKER, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type);
804 IMoniker_Release(pmk);
806 hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
807 ok_ole_success(hr, IRunningObjectTable_Revoke);
808 IRunningObjectTable_Release(pprot);
810 hr = CreateFileMoniker(wszDisplayNameRunning, &pmk);
811 ok_ole_success(hr, CreateFileMoniker);
812 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
813 ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
814 hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
815 ok_ole_success(hr, IRunningObjectTable_Register);
816 IMoniker_Release(pmk);
817 pmk = NULL;
818 hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
819 ok_ole_success(hr, MkParseDisplayName);
820 if (pmk)
822 IMoniker_IsSystemMoniker(pmk, &moniker_type);
823 ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
824 IMoniker_Release(pmk);
826 hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
827 ok_ole_success(hr, IRunningObjectTable_Revoke);
828 IRunningObjectTable_Release(pprot);
830 hr = CoRegisterClassObject(&CLSID_StdFont, (IUnknown *)&ParseDisplayName, CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &pdwReg1);
831 ok_ole_success(hr, CoRegisterClassObject);
833 expected_display_name = wszDisplayNameProgId1;
834 hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
835 ok_ole_success(hr, MkParseDisplayName);
836 if (pmk)
838 IMoniker_IsSystemMoniker(pmk, &moniker_type);
839 ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
840 IMoniker_Release(pmk);
843 expected_display_name = wszDisplayNameProgId2;
844 hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
845 ok_ole_success(hr, MkParseDisplayName);
846 if (pmk)
848 IMoniker_IsSystemMoniker(pmk, &moniker_type);
849 ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
850 IMoniker_Release(pmk);
853 hr = MkParseDisplayName(pbc, wszDisplayNameProgIdFail, &eaten, &pmk);
854 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
855 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
857 hr = CoRevokeClassObject(pdwReg1);
858 ok_ole_success(hr, CoRevokeClassObject);
860 GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
861 strcat(szDisplayNameFile, "\\kernel32.dll");
862 MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile, sizeof(wszDisplayNameFile)/sizeof(wszDisplayNameFile[0]));
863 hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
864 ok_ole_success(hr, MkParseDisplayName);
865 if (pmk)
867 IMoniker_IsSystemMoniker(pmk, &moniker_type);
868 ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
869 IMoniker_Release(pmk);
872 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
873 ok_ole_success(hr, MkParseDisplayName);
875 if (pmk)
877 hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
878 ok_ole_success(hr, IMoniker_BindToObject);
880 IUnknown_Release(object);
882 IBindCtx_Release(pbc);
884 /* Test the EnumMoniker interface */
885 hr = CreateBindCtx(0, &pbc);
886 ok_ole_success(hr, CreateBindCtx);
888 hr = CreateFileMoniker(wszFileName1, &pmk1);
889 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
890 hr = CreateFileMoniker(wszFileName2, &pmk2);
891 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
892 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
893 ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr);
895 /* Check EnumMoniker before registering */
896 hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
897 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
898 hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
899 /* Register a couple of Monikers and check is ok */
900 ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1);
901 hr = MK_E_NOOBJECT;
903 matchCnt = count_moniker_matches(pbc, spEM1);
904 trace("Number of matches is %i\n", matchCnt);
906 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
907 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
908 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
909 hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
911 trace("IROT::Register\n");
912 grflags=0;
913 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
914 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
915 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr,
916 pprot, grflags, lpEM1, pmk2, pdwReg2);
918 hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
919 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
921 matchCnt = count_moniker_matches(pbc, spEM2);
922 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
924 trace("IEnumMoniker::Clone\n");
925 IEnumMoniker_Clone(spEM2, &spEM3);
927 matchCnt = count_moniker_matches(pbc, spEM3);
928 ok(matchCnt==0, "Number of matches should be equal to 0 not %i\n", matchCnt);
929 trace("IEnumMoniker::Reset\n");
930 IEnumMoniker_Reset(spEM3);
932 matchCnt = count_moniker_matches(pbc, spEM3);
933 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
935 IRunningObjectTable_Revoke(pprot,pdwReg1);
936 IRunningObjectTable_Revoke(pprot,pdwReg2);
937 IEnumMoniker_Release(spEM1);
938 IEnumMoniker_Release(spEM1);
939 IEnumMoniker_Release(spEM2);
940 IEnumMoniker_Release(spEM3);
941 IMoniker_Release(pmk1);
942 IMoniker_Release(pmk2);
943 IRunningObjectTable_Release(pprot);
945 IBindCtx_Release(pbc);
948 static const LARGE_INTEGER llZero;
950 static const BYTE expected_class_moniker_marshal_data[] =
952 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
953 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
954 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
955 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
956 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
957 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
958 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
959 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
960 0x00,0x00,0x00,0x00,
963 static const BYTE expected_class_moniker_saved_data[] =
965 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
966 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
967 0x00,0x00,0x00,0x00,
970 static const BYTE expected_class_moniker_comparison_data[] =
972 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
973 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
974 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
975 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
978 static const WCHAR expected_class_moniker_display_name[] =
980 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
981 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
982 '0','0','0','0','4','6',':',0
985 static const BYTE expected_item_moniker_comparison_data[] =
987 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
988 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
989 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
990 0x54,0x00,0x00,0x00,
993 static const BYTE expected_item_moniker_saved_data[] =
995 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
996 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
999 static const BYTE expected_item_moniker_marshal_data[] =
1001 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1002 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1003 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1004 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1005 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1006 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1007 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1008 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1011 static const BYTE expected_anti_moniker_marshal_data[] =
1013 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1014 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1015 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1016 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1017 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1018 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1019 0x01,0x00,0x00,0x00,
1022 static const BYTE expected_anti_moniker_saved_data[] =
1024 0x01,0x00,0x00,0x00,
1027 static const BYTE expected_anti_moniker_comparison_data[] =
1029 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1030 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1031 0x01,0x00,0x00,0x00,
1034 static const BYTE expected_gc_moniker_marshal_data[] =
1036 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1037 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1038 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1039 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1040 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1041 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1042 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1043 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1044 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1045 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1046 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1047 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1048 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1049 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1050 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1051 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1052 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1053 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1054 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1055 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1056 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1057 0x00,0x57,0x69,0x6e,0x65,0x00,
1060 static const BYTE expected_gc_moniker_saved_data[] =
1062 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1063 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1064 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1065 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1066 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1067 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1068 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1069 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1070 0x65,0x00,
1073 static const BYTE expected_gc_moniker_comparison_data[] =
1075 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1076 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1077 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1078 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1079 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1080 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1081 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1082 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1083 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1086 static void test_moniker(
1087 const char *testname, IMoniker *moniker,
1088 const BYTE *expected_moniker_marshal_data, unsigned int sizeof_expected_moniker_marshal_data,
1089 const BYTE *expected_moniker_saved_data, unsigned int sizeof_expected_moniker_saved_data,
1090 const BYTE *expected_moniker_comparison_data, unsigned int sizeof_expected_moniker_comparison_data,
1091 LPCWSTR expected_display_name)
1093 IStream * stream;
1094 IROTData * rotdata;
1095 HRESULT hr;
1096 HGLOBAL hglobal;
1097 LPBYTE moniker_data;
1098 DWORD moniker_size;
1099 DWORD i;
1100 BOOL same = TRUE;
1101 BYTE buffer[128];
1102 IMoniker * moniker_proxy;
1103 LPOLESTR display_name;
1104 IBindCtx *bindctx;
1106 hr = IMoniker_IsDirty(moniker);
1107 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1109 /* Display Name */
1111 hr = CreateBindCtx(0, &bindctx);
1112 ok_ole_success(hr, CreateBindCtx);
1114 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1115 ok_ole_success(hr, IMoniker_GetDisplayName);
1116 ok(!lstrcmpW(display_name, expected_display_name), "%s: display name wasn't what was expected\n", testname);
1118 CoTaskMemFree(display_name);
1119 IBindCtx_Release(bindctx);
1121 hr = IMoniker_IsDirty(moniker);
1122 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1124 /* IROTData::GetComparisonData test */
1126 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1127 ok_ole_success(hr, IMoniker_QueryInterface_IID_IROTData);
1129 hr = IROTData_GetComparisonData(rotdata, buffer, sizeof(buffer), &moniker_size);
1130 ok_ole_success(hr, IROTData_GetComparisonData);
1132 if (hr != S_OK) moniker_size = 0;
1134 /* first check we have the right amount of data */
1135 ok(moniker_size == sizeof_expected_moniker_comparison_data,
1136 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1137 testname, sizeof_expected_moniker_comparison_data, moniker_size);
1139 /* then do a byte-by-byte comparison */
1140 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
1142 if (expected_moniker_comparison_data[i] != buffer[i])
1144 same = FALSE;
1145 break;
1149 ok(same, "%s: Comparison data differs\n", testname);
1150 if (!same)
1152 for (i = 0; i < moniker_size; i++)
1154 if (i % 8 == 0) printf(" ");
1155 printf("0x%02x,", buffer[i]);
1156 if (i % 8 == 7) printf("\n");
1158 printf("\n");
1161 IROTData_Release(rotdata);
1163 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1165 /* Saving */
1167 hr = IMoniker_Save(moniker, stream, TRUE);
1168 ok_ole_success(hr, IMoniker_Save);
1170 hr = GetHGlobalFromStream(stream, &hglobal);
1171 ok_ole_success(hr, GetHGlobalFromStream);
1173 moniker_size = GlobalSize(hglobal);
1175 moniker_data = GlobalLock(hglobal);
1177 /* first check we have the right amount of data */
1178 ok(moniker_size == sizeof_expected_moniker_saved_data,
1179 "%s: Size of saved data differs (expected %d, actual %d)\n",
1180 testname, sizeof_expected_moniker_saved_data, moniker_size);
1182 /* then do a byte-by-byte comparison */
1183 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_saved_data); i++)
1185 if (expected_moniker_saved_data[i] != moniker_data[i])
1187 same = FALSE;
1188 break;
1192 ok(same, "%s: Saved data differs\n", testname);
1193 if (!same)
1195 for (i = 0; i < moniker_size; i++)
1197 if (i % 8 == 0) printf(" ");
1198 printf("0x%02x,", moniker_data[i]);
1199 if (i % 8 == 7) printf("\n");
1201 printf("\n");
1204 GlobalUnlock(hglobal);
1206 IStream_Release(stream);
1208 /* Marshaling tests */
1210 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1211 ok_ole_success(hr, CreateStreamOnHGlobal);
1213 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1214 ok_ole_success(hr, CoMarshalInterface);
1216 hr = GetHGlobalFromStream(stream, &hglobal);
1217 ok_ole_success(hr, GetHGlobalFromStream);
1219 moniker_size = GlobalSize(hglobal);
1221 moniker_data = GlobalLock(hglobal);
1223 /* first check we have the right amount of data */
1224 ok(moniker_size == sizeof_expected_moniker_marshal_data,
1225 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1226 testname, sizeof_expected_moniker_marshal_data, moniker_size);
1228 /* then do a byte-by-byte comparison */
1229 if (expected_moniker_marshal_data)
1231 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_marshal_data); i++)
1233 if (expected_moniker_marshal_data[i] != moniker_data[i])
1235 same = FALSE;
1236 break;
1241 ok(same, "%s: Marshaled data differs\n", testname);
1242 if (!same)
1244 for (i = 0; i < moniker_size; i++)
1246 if (i % 8 == 0) printf(" ");
1247 printf("0x%02x,", moniker_data[i]);
1248 if (i % 8 == 7) printf("\n");
1250 printf("\n");
1253 GlobalUnlock(hglobal);
1255 IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1256 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
1257 ok_ole_success(hr, CoUnmarshalInterface);
1259 IStream_Release(stream);
1260 IMoniker_Release(moniker_proxy);
1263 static void test_class_moniker(void)
1265 HRESULT hr;
1266 IMoniker *moniker;
1267 DWORD moniker_type;
1268 DWORD hash;
1269 IBindCtx *bindctx;
1270 IMoniker *inverse;
1271 IUnknown *unknown;
1272 FILETIME filetime;
1274 hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
1275 ok_ole_success(hr, CreateClassMoniker);
1276 if (!moniker) return;
1278 test_moniker("class moniker", moniker,
1279 expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
1280 expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
1281 expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
1282 expected_class_moniker_display_name);
1284 /* Hashing */
1286 hr = IMoniker_Hash(moniker, &hash);
1287 ok_ole_success(hr, IMoniker_Hash);
1289 ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
1290 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1291 hash);
1293 /* IsSystemMoniker test */
1295 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1296 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1298 ok(moniker_type == MKSYS_CLASSMONIKER,
1299 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1300 moniker_type);
1302 hr = CreateBindCtx(0, &bindctx);
1303 ok_ole_success(hr, CreateBindCtx);
1305 /* IsRunning test */
1306 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1307 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1309 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1310 ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
1312 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1313 ok_ole_success(hr, IMoniker_BindToStorage);
1314 IUnknown_Release(unknown);
1316 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1317 ok_ole_success(hr, IMoniker_BindToStorage);
1318 IUnknown_Release(unknown);
1320 IBindCtx_Release(bindctx);
1322 hr = IMoniker_Inverse(moniker, &inverse);
1323 ok_ole_success(hr, IMoniker_Inverse);
1324 IMoniker_Release(inverse);
1326 IMoniker_Release(moniker);
1329 static void test_file_moniker(WCHAR* path)
1331 IStream *stream;
1332 IMoniker *moniker1 = NULL, *moniker2 = NULL;
1333 HRESULT hr;
1335 hr = CreateFileMoniker(path, &moniker1);
1336 ok_ole_success(hr, CreateFileMoniker);
1338 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1340 /* Marshal */
1341 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1342 ok_ole_success(hr, CoMarshalInterface);
1344 /* Rewind */
1345 hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1346 ok_ole_success(hr, IStream_Seek);
1348 /* Unmarshal */
1349 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
1350 ok_ole_success(hr, CoUnmarshalInterface);
1352 hr = IMoniker_IsEqual(moniker1, moniker2);
1353 ok_ole_success(hr, IsEqual);
1355 IStream_Release(stream);
1356 if (moniker1)
1357 IMoniker_Release(moniker1);
1358 if (moniker2)
1359 IMoniker_Release(moniker2);
1362 static void test_file_monikers(void)
1364 static WCHAR wszFile[][30] = {
1365 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1366 {'\\', '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},
1367 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1368 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1369 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1370 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1371 * U+0100 .. = Latin extended-A
1373 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1376 int i;
1378 trace("ACP is %u\n", GetACP());
1380 for (i = 0; i < COUNTOF(wszFile); ++i)
1382 int j ;
1383 for (j = lstrlenW(wszFile[i]); j > 0; --j)
1385 wszFile[i][j] = 0;
1386 test_file_moniker(wszFile[i]);
1391 static void test_item_moniker(void)
1393 HRESULT hr;
1394 IMoniker *moniker;
1395 DWORD moniker_type;
1396 DWORD hash;
1397 IBindCtx *bindctx;
1398 IMoniker *inverse;
1399 IUnknown *unknown;
1400 static const WCHAR wszDelimeter[] = {'!',0};
1401 static const WCHAR wszObjectName[] = {'T','e','s','t',0};
1402 static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
1404 hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker);
1405 ok_ole_success(hr, CreateItemMoniker);
1407 test_moniker("item moniker", moniker,
1408 expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
1409 expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
1410 expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
1411 expected_display_name);
1413 /* Hashing */
1415 hr = IMoniker_Hash(moniker, &hash);
1416 ok_ole_success(hr, IMoniker_Hash);
1418 ok(hash == 0x73c,
1419 "Hash value != 0x73c, instead was 0x%08x\n",
1420 hash);
1422 /* IsSystemMoniker test */
1424 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1425 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1427 ok(moniker_type == MKSYS_ITEMMONIKER,
1428 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1429 moniker_type);
1431 hr = CreateBindCtx(0, &bindctx);
1432 ok_ole_success(hr, CreateBindCtx);
1434 /* IsRunning test */
1435 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1436 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1438 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1439 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1441 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1442 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1444 IBindCtx_Release(bindctx);
1446 hr = IMoniker_Inverse(moniker, &inverse);
1447 ok_ole_success(hr, IMoniker_Inverse);
1448 IMoniker_Release(inverse);
1450 IMoniker_Release(moniker);
1453 static void test_anti_moniker(void)
1455 HRESULT hr;
1456 IMoniker *moniker;
1457 DWORD moniker_type;
1458 DWORD hash;
1459 IBindCtx *bindctx;
1460 FILETIME filetime;
1461 IMoniker *inverse;
1462 IUnknown *unknown;
1463 static const WCHAR expected_display_name[] = { '\\','.','.',0 };
1465 hr = CreateAntiMoniker(&moniker);
1466 ok_ole_success(hr, CreateAntiMoniker);
1467 if (!moniker) return;
1469 test_moniker("anti moniker", moniker,
1470 expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
1471 expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
1472 expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
1473 expected_display_name);
1475 /* Hashing */
1476 hr = IMoniker_Hash(moniker, &hash);
1477 ok_ole_success(hr, IMoniker_Hash);
1478 ok(hash == 0x80000001,
1479 "Hash value != 0x80000001, instead was 0x%08x\n",
1480 hash);
1482 /* IsSystemMoniker test */
1483 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1484 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1485 ok(moniker_type == MKSYS_ANTIMONIKER,
1486 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1487 moniker_type);
1489 hr = IMoniker_Inverse(moniker, &inverse);
1490 ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
1491 ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
1493 hr = CreateBindCtx(0, &bindctx);
1494 ok_ole_success(hr, CreateBindCtx);
1496 /* IsRunning test */
1497 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1498 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1500 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1501 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1503 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1504 ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr);
1506 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1507 ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr);
1509 IBindCtx_Release(bindctx);
1511 IMoniker_Release(moniker);
1514 static void test_generic_composite_moniker(void)
1516 HRESULT hr;
1517 IMoniker *moniker;
1518 IMoniker *moniker1;
1519 IMoniker *moniker2;
1520 DWORD moniker_type;
1521 DWORD hash;
1522 IBindCtx *bindctx;
1523 FILETIME filetime;
1524 IMoniker *inverse;
1525 IUnknown *unknown;
1526 static const WCHAR wszDelimeter1[] = {'!',0};
1527 static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
1528 static const WCHAR wszDelimeter2[] = {'#',0};
1529 static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
1530 static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1532 hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1);
1533 ok_ole_success(hr, CreateItemMoniker);
1534 hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2);
1535 ok_ole_success(hr, CreateItemMoniker);
1536 hr = CreateGenericComposite(moniker1, moniker2, &moniker);
1537 ok_ole_success(hr, CreateGenericComposite);
1539 test_moniker("generic composite moniker", moniker,
1540 expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
1541 expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
1542 expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
1543 expected_display_name);
1545 /* Hashing */
1547 hr = IMoniker_Hash(moniker, &hash);
1548 ok_ole_success(hr, IMoniker_Hash);
1550 ok(hash == 0xd87,
1551 "Hash value != 0xd87, instead was 0x%08x\n",
1552 hash);
1554 /* IsSystemMoniker test */
1556 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1557 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1559 ok(moniker_type == MKSYS_GENERICCOMPOSITE,
1560 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1561 moniker_type);
1563 hr = CreateBindCtx(0, &bindctx);
1564 ok_ole_success(hr, CreateBindCtx);
1566 /* IsRunning test */
1567 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1568 todo_wine
1569 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1571 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1572 ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);
1574 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1575 todo_wine
1576 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1578 todo_wine
1579 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1580 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1582 IBindCtx_Release(bindctx);
1584 hr = IMoniker_Inverse(moniker, &inverse);
1585 ok_ole_success(hr, IMoniker_Inverse);
1586 IMoniker_Release(inverse);
1588 IMoniker_Release(moniker);
1591 static void test_bind_context(void)
1593 HRESULT hr;
1594 IBindCtx *pBindCtx;
1595 IEnumString *pEnumString;
1596 BIND_OPTS2 bind_opts;
1597 HeapUnknown *unknown;
1598 HeapUnknown *unknown2;
1599 IUnknown *param_obj;
1600 ULONG refs;
1601 static const WCHAR wszParamName[] = {'G','e','m','m','a',0};
1602 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1604 hr = CreateBindCtx(0, NULL);
1605 ok(hr == E_INVALIDARG, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1607 hr = CreateBindCtx(0xdeadbeef, &pBindCtx);
1608 ok(hr == E_INVALIDARG, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1610 hr = CreateBindCtx(0, &pBindCtx);
1611 ok_ole_success(hr, "CreateBindCtx");
1613 bind_opts.cbStruct = -1;
1614 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1615 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1616 ok(bind_opts.cbStruct == sizeof(bind_opts), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1618 bind_opts.cbStruct = sizeof(BIND_OPTS);
1619 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1620 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1621 ok(bind_opts.cbStruct == sizeof(BIND_OPTS), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1623 bind_opts.cbStruct = sizeof(bind_opts);
1624 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1625 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1626 ok(bind_opts.cbStruct == sizeof(bind_opts), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1627 ok(bind_opts.grfFlags == 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts.grfFlags);
1628 ok(bind_opts.grfMode == STGM_READWRITE, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts.grfMode);
1629 ok(bind_opts.dwTickCountDeadline == 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts.dwTickCountDeadline);
1630 ok(bind_opts.dwTrackFlags == 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts.dwTrackFlags);
1631 ok(bind_opts.dwClassContext == (CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER),
1632 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts.dwClassContext);
1633 ok(bind_opts.locale == GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts.locale);
1634 ok(bind_opts.pServerInfo == NULL, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts.pServerInfo);
1636 bind_opts.cbStruct = -1;
1637 hr = IBindCtx_SetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1638 ok(hr == E_INVALIDARG, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1640 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, NULL);
1641 ok(hr == E_INVALIDARG, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1643 unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1644 unknown->lpVtbl = &HeapUnknown_Vtbl;
1645 unknown->refs = 1;
1646 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, (IUnknown *)&unknown->lpVtbl);
1647 ok_ole_success(hr, "IBindCtx_RegisterObjectParam");
1649 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszParamName, &param_obj);
1650 ok_ole_success(hr, "IBindCtx_GetObjectParam");
1651 IUnknown_Release(param_obj);
1653 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszNonExistent, &param_obj);
1654 ok(hr == E_FAIL, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1655 ok(param_obj == NULL, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj);
1657 hr = IBindCtx_RevokeObjectParam(pBindCtx, (WCHAR *)wszNonExistent);
1658 ok(hr == E_FAIL, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1660 hr = IBindCtx_EnumObjectParam(pBindCtx, &pEnumString);
1661 ok(hr == E_NOTIMPL, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1662 ok(!pEnumString, "pEnumString should be NULL\n");
1664 hr = IBindCtx_RegisterObjectBound(pBindCtx, NULL);
1665 ok_ole_success(hr, "IBindCtx_RegisterObjectBound(NULL)");
1667 hr = IBindCtx_RevokeObjectBound(pBindCtx, NULL);
1668 ok(hr == E_INVALIDARG, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr);
1670 unknown2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1671 unknown2->lpVtbl = &HeapUnknown_Vtbl;
1672 unknown2->refs = 1;
1673 hr = IBindCtx_RegisterObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1674 ok_ole_success(hr, "IBindCtx_RegisterObjectBound");
1676 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1677 ok_ole_success(hr, "IBindCtx_RevokeObjectBound");
1679 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1680 ok(hr == MK_E_NOTBOUND, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr);
1682 IBindCtx_Release(pBindCtx);
1684 refs = IUnknown_Release((IUnknown *)&unknown->lpVtbl);
1685 ok(!refs, "object param should have been destroyed, instead of having %d refs\n", refs);
1687 refs = IUnknown_Release((IUnknown *)&unknown2->lpVtbl);
1688 ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
1691 START_TEST(moniker)
1693 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1695 test_ROT();
1696 test_MkParseDisplayName();
1697 test_class_moniker();
1698 test_file_monikers();
1699 test_item_moniker();
1700 test_anti_moniker();
1701 test_generic_composite_moniker();
1703 /* FIXME: test moniker creation funcs and parsing other moniker formats */
1705 test_bind_context();
1707 CoUninitialize();