push 460a69df99a5ad9f5823a97170ef7a215171c033
[wine/hacks.git] / dlls / ole32 / tests / moniker.c
blob34169850203cd39216893526997c1c83a5784bc2
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 = 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 ok_ole_success(hr, IRunningObjectTable_Register);
575 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
577 ok_more_than_one_lock();
579 expected_method_list = methods_isrunning_no_ROTData;
580 hr = IRunningObjectTable_IsRunning(pROT, &MonikerNoROTData);
581 ok_ole_success(hr, IRunningObjectTable_IsRunning);
582 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
584 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
585 ok_ole_success(hr, IRunningObjectTable_Revoke);
587 ok_no_locks();
589 expected_method_list = methods_register;
590 /* try with our own moniker */
591 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
592 (IUnknown*)&Test_ClassFactory, &Moniker, &dwCookie);
593 ok_ole_success(hr, IRunningObjectTable_Register);
594 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
596 ok_more_than_one_lock();
598 expected_method_list = methods_isrunning;
599 hr = IRunningObjectTable_IsRunning(pROT, &Moniker);
600 ok_ole_success(hr, IRunningObjectTable_IsRunning);
601 ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
603 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
604 ok_ole_success(hr, IRunningObjectTable_Revoke);
606 ok_no_locks();
608 hr = CreateFileMoniker(wszFileName, &pMoniker);
609 ok_ole_success(hr, CreateClassMoniker);
611 /* test flags: 0 */
612 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown*)&Test_ClassFactory,
613 pMoniker, &dwCookie);
614 ok_ole_success(hr, IRunningObjectTable_Register);
616 ok_more_than_one_lock();
618 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
619 ok_ole_success(hr, IRunningObjectTable_Revoke);
621 ok_no_locks();
623 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE */
624 hr = IRunningObjectTable_Register(pROT, ROTFLAGS_REGISTRATIONKEEPSALIVE,
625 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
626 ok_ole_success(hr, IRunningObjectTable_Register);
628 ok_more_than_one_lock();
630 hr = IRunningObjectTable_Revoke(pROT, dwCookie);
631 ok_ole_success(hr, IRunningObjectTable_Revoke);
633 ok_no_locks();
635 /* test flags: ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT */
636 /* only succeeds when process is started by SCM and has LocalService
637 * or RunAs AppId values */
638 hr = IRunningObjectTable_Register(pROT,
639 ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT,
640 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
641 todo_wine {
642 ok(hr == CO_E_WRONG_SERVER_IDENTITY, "IRunningObjectTable_Register should have returned CO_E_WRONG_SERVER_IDENTITY instead of 0x%08x\n", hr);
644 if (hr == S_OK) IRunningObjectTable_Revoke(pROT, dwCookie);
646 hr = IRunningObjectTable_Register(pROT, 0xdeadbeef,
647 (IUnknown*)&Test_ClassFactory, pMoniker, &dwCookie);
648 ok(hr == E_INVALIDARG, "IRunningObjectTable_Register should have returned E_INVALIDARG instead of 0x%08x\n", hr);
650 IMoniker_Release(pMoniker);
652 IRunningObjectTable_Release(pROT);
655 static void test_ROT_multiple_entries(void)
657 HRESULT hr;
658 IMoniker *pMoniker = NULL;
659 IRunningObjectTable *pROT = NULL;
660 DWORD dwCookie1, dwCookie2;
661 IUnknown *pObject = NULL;
662 static const WCHAR moniker_path[] =
663 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0};
665 hr = GetRunningObjectTable(0, &pROT);
666 ok_ole_success(hr, GetRunningObjectTable);
668 hr = CreateFileMoniker(moniker_path, &pMoniker);
669 ok_ole_success(hr, CreateFileMoniker);
671 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown *)&Test_ClassFactory, pMoniker, &dwCookie1);
672 ok_ole_success(hr, IRunningObjectTable_Register);
674 hr = IRunningObjectTable_Register(pROT, 0, (IUnknown *)&Test_ClassFactory, pMoniker, &dwCookie2);
675 ok(hr == MK_S_MONIKERALREADYREGISTERED, "IRunningObjectTable_Register should have returned MK_S_MONIKERALREADYREGISTERED instead of 0x%08x\n", hr);
677 ok(dwCookie1 != dwCookie2, "cookie returned for registering duplicate object shouldn't match cookie of original object (0x%x)\n", dwCookie1);
679 hr = IRunningObjectTable_GetObject(pROT, pMoniker, &pObject);
680 ok_ole_success(hr, IRunningObjectTable_GetObject);
681 IUnknown_Release(pObject);
683 hr = IRunningObjectTable_Revoke(pROT, dwCookie1);
684 ok_ole_success(hr, IRunningObjectTable_Revoke);
686 hr = IRunningObjectTable_GetObject(pROT, pMoniker, &pObject);
687 ok_ole_success(hr, IRunningObjectTable_GetObject);
688 IUnknown_Release(pObject);
690 hr = IRunningObjectTable_Revoke(pROT, dwCookie2);
691 ok_ole_success(hr, IRunningObjectTable_Revoke);
693 IMoniker_Release(pMoniker);
695 IRunningObjectTable_Release(pROT);
698 static HRESULT WINAPI ParseDisplayName_QueryInterface(IParseDisplayName *iface, REFIID riid, void **ppv)
700 if (IsEqualIID(riid, &IID_IUnknown) ||
701 IsEqualIID(riid, &IID_IParseDisplayName))
703 *ppv = iface;
704 IUnknown_AddRef(iface);
705 return S_OK;
707 *ppv = NULL;
708 return E_NOINTERFACE;
711 static ULONG WINAPI ParseDisplayName_AddRef(IParseDisplayName *iface)
713 return 2;
716 static ULONG WINAPI ParseDisplayName_Release(IParseDisplayName *iface)
718 return 1;
721 static LPCWSTR expected_display_name;
723 static HRESULT WINAPI ParseDisplayName_ParseDisplayName(IParseDisplayName *iface,
724 IBindCtx *pbc,
725 LPOLESTR pszDisplayName,
726 ULONG *pchEaten,
727 IMoniker **ppmkOut)
729 char display_nameA[256];
730 WideCharToMultiByte(CP_ACP, 0, pszDisplayName, -1, display_nameA, sizeof(display_nameA), NULL, NULL);
731 ok(!lstrcmpW(pszDisplayName, expected_display_name), "unexpected display name \"%s\"\n", display_nameA);
732 ok(pszDisplayName == expected_display_name, "pszDisplayName should be the same pointer as passed into MkParseDisplayName\n");
733 *pchEaten = lstrlenW(pszDisplayName);
734 return CreateAntiMoniker(ppmkOut);
737 static const IParseDisplayNameVtbl ParseDisplayName_Vtbl =
739 ParseDisplayName_QueryInterface,
740 ParseDisplayName_AddRef,
741 ParseDisplayName_Release,
742 ParseDisplayName_ParseDisplayName
745 static IParseDisplayName ParseDisplayName = { &ParseDisplayName_Vtbl };
747 static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
749 IMoniker * spMoniker;
750 int monCnt=0, matchCnt=0;
752 while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK))
754 HRESULT hr;
755 WCHAR * szDisplayn;
756 monCnt++;
757 hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL, &szDisplayn);
758 if (SUCCEEDED(hr))
760 if (!lstrcmpiW(szDisplayn, wszFileName1) || !lstrcmpiW(szDisplayn, wszFileName2))
761 matchCnt++;
762 CoTaskMemFree(szDisplayn);
765 trace("Total number of monikers is %i\n", monCnt);
766 return matchCnt;
769 static void test_MkParseDisplayName(void)
771 IBindCtx * pbc = NULL;
772 HRESULT hr;
773 IMoniker * pmk = NULL;
774 IMoniker * pmk1 = NULL;
775 IMoniker * pmk2 = NULL;
776 ULONG eaten;
777 int matchCnt;
778 IUnknown * object = NULL;
780 IUnknown *lpEM1;
782 IEnumMoniker *spEM1 = NULL;
783 IEnumMoniker *spEM2 = NULL;
784 IEnumMoniker *spEM3 = NULL;
786 DWORD pdwReg1=0;
787 DWORD grflags=0;
788 DWORD pdwReg2=0;
789 DWORD moniker_type;
790 IRunningObjectTable * pprot=NULL;
792 /* CLSID of My Computer */
793 static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
794 '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};
795 static const WCHAR wszDisplayNameClsid[] = {'c','l','s','i','d',':',0};
796 static const WCHAR wszNonExistentProgId[] = {'N','o','n','E','x','i','s','t','e','n','t','P','r','o','g','I','d',':',0};
797 static const WCHAR wszDisplayNameRunning[] = {'W','i','n','e','T','e','s','t','R','u','n','n','i','n','g',0};
798 static const WCHAR wszDisplayNameProgId1[] = {'S','t','d','F','o','n','t',':',0};
799 static const WCHAR wszDisplayNameProgId2[] = {'@','S','t','d','F','o','n','t',0};
800 static const WCHAR wszDisplayNameProgIdFail[] = {'S','t','d','F','o','n','t',0};
801 char szDisplayNameFile[256];
802 WCHAR wszDisplayNameFile[256];
804 hr = CreateBindCtx(0, &pbc);
805 ok_ole_success(hr, CreateBindCtx);
807 hr = MkParseDisplayName(pbc, wszNonExistentProgId, &eaten, &pmk);
808 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
809 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
811 /* no special handling of "clsid:" without the string form of the clsid
812 * following */
813 hr = MkParseDisplayName(pbc, wszDisplayNameClsid, &eaten, &pmk);
814 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
815 "MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
817 /* shows clsid has higher precedence than a running object */
818 hr = CreateFileMoniker(wszDisplayName, &pmk);
819 ok_ole_success(hr, CreateFileMoniker);
820 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
821 ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
822 hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
823 ok_ole_success(hr, IRunningObjectTable_Register);
824 IMoniker_Release(pmk);
825 pmk = NULL;
826 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
827 ok_ole_success(hr, MkParseDisplayName);
828 if (pmk)
830 IMoniker_IsSystemMoniker(pmk, &moniker_type);
831 ok(moniker_type == MKSYS_CLASSMONIKER, "moniker_type was %d instead of MKSYS_CLASSMONIKER\n", moniker_type);
832 IMoniker_Release(pmk);
834 hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
835 ok_ole_success(hr, IRunningObjectTable_Revoke);
836 IRunningObjectTable_Release(pprot);
838 hr = CreateFileMoniker(wszDisplayNameRunning, &pmk);
839 ok_ole_success(hr, CreateFileMoniker);
840 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
841 ok_ole_success(hr, IBindCtx_GetRunningObjectTable);
842 hr = IRunningObjectTable_Register(pprot, 0, (IUnknown *)&Test_ClassFactory, pmk, &pdwReg1);
843 ok_ole_success(hr, IRunningObjectTable_Register);
844 IMoniker_Release(pmk);
845 pmk = NULL;
846 hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
847 ok_ole_success(hr, MkParseDisplayName);
848 if (pmk)
850 IMoniker_IsSystemMoniker(pmk, &moniker_type);
851 ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
852 IMoniker_Release(pmk);
854 hr = IRunningObjectTable_Revoke(pprot, pdwReg1);
855 ok_ole_success(hr, IRunningObjectTable_Revoke);
856 IRunningObjectTable_Release(pprot);
858 hr = CoRegisterClassObject(&CLSID_StdFont, (IUnknown *)&ParseDisplayName, CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &pdwReg1);
859 ok_ole_success(hr, CoRegisterClassObject);
861 expected_display_name = wszDisplayNameProgId1;
862 hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
863 ok_ole_success(hr, MkParseDisplayName);
864 if (pmk)
866 IMoniker_IsSystemMoniker(pmk, &moniker_type);
867 ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
868 IMoniker_Release(pmk);
871 expected_display_name = wszDisplayNameProgId2;
872 hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
873 ok_ole_success(hr, MkParseDisplayName);
874 if (pmk)
876 IMoniker_IsSystemMoniker(pmk, &moniker_type);
877 ok(moniker_type == MKSYS_ANTIMONIKER, "moniker_type was %d instead of MKSYS_ANTIMONIKER\n", moniker_type);
878 IMoniker_Release(pmk);
881 hr = MkParseDisplayName(pbc, wszDisplayNameProgIdFail, &eaten, &pmk);
882 ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
883 "MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
885 hr = CoRevokeClassObject(pdwReg1);
886 ok_ole_success(hr, CoRevokeClassObject);
888 GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
889 strcat(szDisplayNameFile, "\\kernel32.dll");
890 MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile, sizeof(wszDisplayNameFile)/sizeof(wszDisplayNameFile[0]));
891 hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
892 ok_ole_success(hr, MkParseDisplayName);
893 if (pmk)
895 IMoniker_IsSystemMoniker(pmk, &moniker_type);
896 ok(moniker_type == MKSYS_FILEMONIKER, "moniker_type was %d instead of MKSYS_FILEMONIKER\n", moniker_type);
897 IMoniker_Release(pmk);
900 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
901 ok_ole_success(hr, MkParseDisplayName);
903 if (pmk)
905 hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
906 ok_ole_success(hr, IMoniker_BindToObject);
908 IUnknown_Release(object);
909 IMoniker_Release(pmk);
911 IBindCtx_Release(pbc);
913 /* Test the EnumMoniker interface */
914 hr = CreateBindCtx(0, &pbc);
915 ok_ole_success(hr, CreateBindCtx);
917 hr = CreateFileMoniker(wszFileName1, &pmk1);
918 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
919 hr = CreateFileMoniker(wszFileName2, &pmk2);
920 ok(hr==0, "CreateFileMoniker for file hr=%08x\n", hr);
921 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
922 ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08x\n", hr);
924 /* Check EnumMoniker before registering */
925 hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
926 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
927 hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
928 /* Register a couple of Monikers and check is ok */
929 ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1);
930 hr = MK_E_NOOBJECT;
932 matchCnt = count_moniker_matches(pbc, spEM1);
933 trace("Number of matches is %i\n", matchCnt);
935 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
936 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
937 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n",
938 hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
940 trace("IROT::Register\n");
941 grflags=0;
942 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
943 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
944 ok(hr==0, "IRunningObjectTable_Register hr=%08x %p %08x %p %p %d\n", hr,
945 pprot, grflags, lpEM1, pmk2, pdwReg2);
947 hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
948 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08x\n", hr);
950 matchCnt = count_moniker_matches(pbc, spEM2);
951 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
953 trace("IEnumMoniker::Clone\n");
954 IEnumMoniker_Clone(spEM2, &spEM3);
956 matchCnt = count_moniker_matches(pbc, spEM3);
957 ok(matchCnt==0, "Number of matches should be equal to 0 not %i\n", matchCnt);
958 trace("IEnumMoniker::Reset\n");
959 IEnumMoniker_Reset(spEM3);
961 matchCnt = count_moniker_matches(pbc, spEM3);
962 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
964 IRunningObjectTable_Revoke(pprot,pdwReg1);
965 IRunningObjectTable_Revoke(pprot,pdwReg2);
966 IUnknown_Release(lpEM1);
967 IEnumMoniker_Release(spEM1);
968 IEnumMoniker_Release(spEM2);
969 IEnumMoniker_Release(spEM3);
970 IMoniker_Release(pmk1);
971 IMoniker_Release(pmk2);
972 IRunningObjectTable_Release(pprot);
974 IBindCtx_Release(pbc);
977 static const LARGE_INTEGER llZero;
979 static const BYTE expected_class_moniker_marshal_data[] =
981 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
982 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
983 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
984 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
985 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
986 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
987 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
988 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
989 0x00,0x00,0x00,0x00,
992 static const BYTE expected_class_moniker_saved_data[] =
994 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
995 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
996 0x00,0x00,0x00,0x00,
999 static const BYTE expected_class_moniker_comparison_data[] =
1001 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1002 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1003 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
1004 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1007 static const WCHAR expected_class_moniker_display_name[] =
1009 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
1010 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
1011 '0','0','0','0','4','6',':',0
1014 static const BYTE expected_item_moniker_comparison_data[] =
1016 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1017 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1018 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1019 0x54,0x00,0x00,0x00,
1022 static const BYTE expected_item_moniker_saved_data[] =
1024 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1025 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1028 static const BYTE expected_item_moniker_marshal_data[] =
1030 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1031 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1032 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1033 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1034 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1035 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1036 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1037 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
1040 static const BYTE expected_anti_moniker_marshal_data[] =
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 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1046 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1047 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
1048 0x01,0x00,0x00,0x00,
1051 static const BYTE expected_anti_moniker_saved_data[] =
1053 0x01,0x00,0x00,0x00,
1056 static const BYTE expected_anti_moniker_comparison_data[] =
1058 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1059 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1060 0x01,0x00,0x00,0x00,
1063 static const BYTE expected_gc_moniker_marshal_data[] =
1065 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1066 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1067 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1068 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1069 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1070 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
1071 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
1072 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1073 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1074 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1075 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1076 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
1077 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
1078 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
1079 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
1080 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1081 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
1082 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
1083 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
1084 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
1085 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
1086 0x00,0x57,0x69,0x6e,0x65,0x00,
1089 static const BYTE expected_gc_moniker_saved_data[] =
1091 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1092 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1093 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
1094 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
1095 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
1096 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
1097 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
1098 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
1099 0x65,0x00,
1102 static const BYTE expected_gc_moniker_comparison_data[] =
1104 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1105 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1106 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
1107 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
1108 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
1109 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
1110 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
1111 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
1112 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
1115 static void test_moniker(
1116 const char *testname, IMoniker *moniker,
1117 const BYTE *expected_moniker_marshal_data, unsigned int sizeof_expected_moniker_marshal_data,
1118 const BYTE *expected_moniker_saved_data, unsigned int sizeof_expected_moniker_saved_data,
1119 const BYTE *expected_moniker_comparison_data, unsigned int sizeof_expected_moniker_comparison_data,
1120 LPCWSTR expected_display_name)
1122 IStream * stream;
1123 IROTData * rotdata;
1124 HRESULT hr;
1125 HGLOBAL hglobal;
1126 LPBYTE moniker_data;
1127 DWORD moniker_size;
1128 DWORD i;
1129 BOOL same = TRUE;
1130 BYTE buffer[128];
1131 IMoniker * moniker_proxy;
1132 LPOLESTR display_name;
1133 IBindCtx *bindctx;
1135 hr = IMoniker_IsDirty(moniker);
1136 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1138 /* Display Name */
1140 hr = CreateBindCtx(0, &bindctx);
1141 ok_ole_success(hr, CreateBindCtx);
1143 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1144 ok_ole_success(hr, IMoniker_GetDisplayName);
1145 ok(!lstrcmpW(display_name, expected_display_name), "%s: display name wasn't what was expected\n", testname);
1147 CoTaskMemFree(display_name);
1148 IBindCtx_Release(bindctx);
1150 hr = IMoniker_IsDirty(moniker);
1151 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", testname, hr);
1153 /* IROTData::GetComparisonData test */
1155 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1156 ok_ole_success(hr, IMoniker_QueryInterface_IID_IROTData);
1158 hr = IROTData_GetComparisonData(rotdata, buffer, sizeof(buffer), &moniker_size);
1159 ok_ole_success(hr, IROTData_GetComparisonData);
1161 if (hr != S_OK) moniker_size = 0;
1163 /* first check we have the right amount of data */
1164 ok(moniker_size == sizeof_expected_moniker_comparison_data,
1165 "%s: Size of comparison data differs (expected %d, actual %d)\n",
1166 testname, sizeof_expected_moniker_comparison_data, moniker_size);
1168 /* then do a byte-by-byte comparison */
1169 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
1171 if (expected_moniker_comparison_data[i] != buffer[i])
1173 same = FALSE;
1174 break;
1178 ok(same, "%s: Comparison data differs\n", testname);
1179 if (!same)
1181 for (i = 0; i < moniker_size; i++)
1183 if (i % 8 == 0) printf(" ");
1184 printf("0x%02x,", buffer[i]);
1185 if (i % 8 == 7) printf("\n");
1187 printf("\n");
1190 IROTData_Release(rotdata);
1192 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1194 /* Saving */
1196 hr = IMoniker_Save(moniker, stream, TRUE);
1197 ok_ole_success(hr, IMoniker_Save);
1199 hr = GetHGlobalFromStream(stream, &hglobal);
1200 ok_ole_success(hr, GetHGlobalFromStream);
1202 moniker_size = GlobalSize(hglobal);
1204 moniker_data = GlobalLock(hglobal);
1206 /* first check we have the right amount of data */
1207 ok(moniker_size == sizeof_expected_moniker_saved_data,
1208 "%s: Size of saved data differs (expected %d, actual %d)\n",
1209 testname, sizeof_expected_moniker_saved_data, moniker_size);
1211 /* then do a byte-by-byte comparison */
1212 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_saved_data); i++)
1214 if (expected_moniker_saved_data[i] != moniker_data[i])
1216 same = FALSE;
1217 break;
1221 ok(same, "%s: Saved data differs\n", testname);
1222 if (!same)
1224 for (i = 0; i < moniker_size; i++)
1226 if (i % 8 == 0) printf(" ");
1227 printf("0x%02x,", moniker_data[i]);
1228 if (i % 8 == 7) printf("\n");
1230 printf("\n");
1233 GlobalUnlock(hglobal);
1235 IStream_Release(stream);
1237 /* Marshaling tests */
1239 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1240 ok_ole_success(hr, CreateStreamOnHGlobal);
1242 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1243 ok_ole_success(hr, CoMarshalInterface);
1245 hr = GetHGlobalFromStream(stream, &hglobal);
1246 ok_ole_success(hr, GetHGlobalFromStream);
1248 moniker_size = GlobalSize(hglobal);
1250 moniker_data = GlobalLock(hglobal);
1252 /* first check we have the right amount of data */
1253 ok(moniker_size == sizeof_expected_moniker_marshal_data,
1254 "%s: Size of marshaled data differs (expected %d, actual %d)\n",
1255 testname, sizeof_expected_moniker_marshal_data, moniker_size);
1257 /* then do a byte-by-byte comparison */
1258 if (expected_moniker_marshal_data)
1260 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_marshal_data); i++)
1262 if (expected_moniker_marshal_data[i] != moniker_data[i])
1264 same = FALSE;
1265 break;
1270 ok(same, "%s: Marshaled data differs\n", testname);
1271 if (!same)
1273 for (i = 0; i < moniker_size; i++)
1275 if (i % 8 == 0) printf(" ");
1276 printf("0x%02x,", moniker_data[i]);
1277 if (i % 8 == 7) printf("\n");
1279 printf("\n");
1282 GlobalUnlock(hglobal);
1284 IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1285 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
1286 ok_ole_success(hr, CoUnmarshalInterface);
1288 IStream_Release(stream);
1289 IMoniker_Release(moniker_proxy);
1292 static void test_class_moniker(void)
1294 HRESULT hr;
1295 IMoniker *moniker;
1296 DWORD moniker_type;
1297 DWORD hash;
1298 IBindCtx *bindctx;
1299 IMoniker *inverse;
1300 IUnknown *unknown;
1301 FILETIME filetime;
1303 hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
1304 ok_ole_success(hr, CreateClassMoniker);
1305 if (!moniker) return;
1307 test_moniker("class moniker", moniker,
1308 expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
1309 expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
1310 expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
1311 expected_class_moniker_display_name);
1313 /* Hashing */
1315 hr = IMoniker_Hash(moniker, &hash);
1316 ok_ole_success(hr, IMoniker_Hash);
1318 ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
1319 "Hash value != Data1 field of clsid, instead was 0x%08x\n",
1320 hash);
1322 /* IsSystemMoniker test */
1324 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1325 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1327 ok(moniker_type == MKSYS_CLASSMONIKER,
1328 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08x\n",
1329 moniker_type);
1331 hr = CreateBindCtx(0, &bindctx);
1332 ok_ole_success(hr, CreateBindCtx);
1334 /* IsRunning test */
1335 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1336 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1338 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1339 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08x\n", hr);
1341 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1342 ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08x\n", hr);
1344 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1345 ok_ole_success(hr, IMoniker_BindToObject);
1346 IUnknown_Release(unknown);
1348 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1349 ok_ole_success(hr, IMoniker_BindToStorage);
1350 IUnknown_Release(unknown);
1352 IBindCtx_Release(bindctx);
1354 hr = IMoniker_Inverse(moniker, &inverse);
1355 ok_ole_success(hr, IMoniker_Inverse);
1356 IMoniker_Release(inverse);
1358 IMoniker_Release(moniker);
1361 static void test_file_moniker(WCHAR* path)
1363 IStream *stream;
1364 IMoniker *moniker1 = NULL, *moniker2 = NULL;
1365 HRESULT hr;
1367 hr = CreateFileMoniker(path, &moniker1);
1368 ok_ole_success(hr, CreateFileMoniker);
1370 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1372 /* Marshal */
1373 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1374 ok_ole_success(hr, CoMarshalInterface);
1376 /* Rewind */
1377 hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
1378 ok_ole_success(hr, IStream_Seek);
1380 /* Unmarshal */
1381 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
1382 ok_ole_success(hr, CoUnmarshalInterface);
1384 hr = IMoniker_IsEqual(moniker1, moniker2);
1385 ok_ole_success(hr, IsEqual);
1387 IStream_Release(stream);
1388 if (moniker1)
1389 IMoniker_Release(moniker1);
1390 if (moniker2)
1391 IMoniker_Release(moniker2);
1394 static void test_file_monikers(void)
1396 static WCHAR wszFile[][30] = {
1397 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
1398 {'\\', '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},
1399 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
1400 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
1401 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
1402 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
1403 * U+0100 .. = Latin extended-A
1405 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
1408 int i;
1410 trace("ACP is %u\n", GetACP());
1412 for (i = 0; i < COUNTOF(wszFile); ++i)
1414 int j ;
1415 for (j = lstrlenW(wszFile[i]); j > 0; --j)
1417 wszFile[i][j] = 0;
1418 test_file_moniker(wszFile[i]);
1423 static void test_item_moniker(void)
1425 HRESULT hr;
1426 IMoniker *moniker;
1427 DWORD moniker_type;
1428 DWORD hash;
1429 IBindCtx *bindctx;
1430 IMoniker *inverse;
1431 IUnknown *unknown;
1432 static const WCHAR wszDelimeter[] = {'!',0};
1433 static const WCHAR wszObjectName[] = {'T','e','s','t',0};
1434 static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
1436 hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker);
1437 ok_ole_success(hr, CreateItemMoniker);
1439 test_moniker("item moniker", moniker,
1440 expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
1441 expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
1442 expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
1443 expected_display_name);
1445 /* Hashing */
1447 hr = IMoniker_Hash(moniker, &hash);
1448 ok_ole_success(hr, IMoniker_Hash);
1450 ok(hash == 0x73c,
1451 "Hash value != 0x73c, instead was 0x%08x\n",
1452 hash);
1454 /* IsSystemMoniker test */
1456 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1457 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1459 ok(moniker_type == MKSYS_ITEMMONIKER,
1460 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08x\n",
1461 moniker_type);
1463 hr = CreateBindCtx(0, &bindctx);
1464 ok_ole_success(hr, CreateBindCtx);
1466 /* IsRunning test */
1467 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1468 todo_wine
1469 ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1471 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1472 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1474 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1475 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1477 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1478 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1480 IBindCtx_Release(bindctx);
1482 hr = IMoniker_Inverse(moniker, &inverse);
1483 ok_ole_success(hr, IMoniker_Inverse);
1484 IMoniker_Release(inverse);
1486 IMoniker_Release(moniker);
1489 static void test_anti_moniker(void)
1491 HRESULT hr;
1492 IMoniker *moniker;
1493 DWORD moniker_type;
1494 DWORD hash;
1495 IBindCtx *bindctx;
1496 FILETIME filetime;
1497 IMoniker *inverse;
1498 IUnknown *unknown;
1499 static const WCHAR expected_display_name[] = { '\\','.','.',0 };
1501 hr = CreateAntiMoniker(&moniker);
1502 ok_ole_success(hr, CreateAntiMoniker);
1503 if (!moniker) return;
1505 test_moniker("anti moniker", moniker,
1506 expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
1507 expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
1508 expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
1509 expected_display_name);
1511 /* Hashing */
1512 hr = IMoniker_Hash(moniker, &hash);
1513 ok_ole_success(hr, IMoniker_Hash);
1514 ok(hash == 0x80000001,
1515 "Hash value != 0x80000001, instead was 0x%08x\n",
1516 hash);
1518 /* IsSystemMoniker test */
1519 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1520 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1521 ok(moniker_type == MKSYS_ANTIMONIKER,
1522 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08x\n",
1523 moniker_type);
1525 hr = IMoniker_Inverse(moniker, &inverse);
1526 ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08x\n", hr);
1527 ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
1529 hr = CreateBindCtx(0, &bindctx);
1530 ok_ole_success(hr, CreateBindCtx);
1532 /* IsRunning test */
1533 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1534 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1536 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1537 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1539 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1540 ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08x\n", hr);
1542 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1543 ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08x\n", hr);
1545 IBindCtx_Release(bindctx);
1547 IMoniker_Release(moniker);
1550 static void test_generic_composite_moniker(void)
1552 HRESULT hr;
1553 IMoniker *moniker;
1554 IMoniker *moniker1;
1555 IMoniker *moniker2;
1556 DWORD moniker_type;
1557 DWORD hash;
1558 IBindCtx *bindctx;
1559 FILETIME filetime;
1560 IMoniker *inverse;
1561 IUnknown *unknown;
1562 static const WCHAR wszDelimeter1[] = {'!',0};
1563 static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
1564 static const WCHAR wszDelimeter2[] = {'#',0};
1565 static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
1566 static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
1568 hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1);
1569 ok_ole_success(hr, CreateItemMoniker);
1570 hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2);
1571 ok_ole_success(hr, CreateItemMoniker);
1572 hr = CreateGenericComposite(moniker1, moniker2, &moniker);
1573 ok_ole_success(hr, CreateGenericComposite);
1575 test_moniker("generic composite moniker", moniker,
1576 expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
1577 expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
1578 expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
1579 expected_display_name);
1581 /* Hashing */
1583 hr = IMoniker_Hash(moniker, &hash);
1584 ok_ole_success(hr, IMoniker_Hash);
1586 ok(hash == 0xd87,
1587 "Hash value != 0xd87, instead was 0x%08x\n",
1588 hash);
1590 /* IsSystemMoniker test */
1592 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1593 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1595 ok(moniker_type == MKSYS_GENERICCOMPOSITE,
1596 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08x\n",
1597 moniker_type);
1599 hr = CreateBindCtx(0, &bindctx);
1600 ok_ole_success(hr, CreateBindCtx);
1602 /* IsRunning test */
1603 hr = IMoniker_IsRunning(moniker, NULL, NULL, NULL);
1604 todo_wine
1605 ok(hr == E_INVALIDARG, "IMoniker_IsRunning should return E_INVALIDARG, not 0x%08x\n", hr);
1607 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1608 todo_wine
1609 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08x\n", hr);
1611 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1612 ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08x\n", hr);
1614 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1615 todo_wine
1616 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08x\n", hr);
1618 todo_wine
1619 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1620 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08x\n", hr);
1622 IBindCtx_Release(bindctx);
1624 hr = IMoniker_Inverse(moniker, &inverse);
1625 ok_ole_success(hr, IMoniker_Inverse);
1626 IMoniker_Release(inverse);
1628 IMoniker_Release(moniker);
1631 static void test_pointer_moniker(void)
1633 HRESULT hr;
1634 IMoniker *moniker;
1635 DWORD moniker_type;
1636 DWORD hash;
1637 IBindCtx *bindctx;
1638 FILETIME filetime;
1639 IMoniker *inverse;
1640 IUnknown *unknown;
1641 IStream *stream;
1642 IROTData *rotdata;
1643 LPOLESTR display_name;
1645 cLocks = 0;
1647 hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, NULL);
1648 ok(hr == E_INVALIDARG, "CreatePointerMoniker(x, NULL) should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1650 hr = CreatePointerMoniker((IUnknown *)&Test_ClassFactory, &moniker);
1651 ok_ole_success(hr, CreatePointerMoniker);
1652 if (!moniker) return;
1654 ok_more_than_one_lock();
1656 /* Display Name */
1658 hr = CreateBindCtx(0, &bindctx);
1659 ok_ole_success(hr, CreateBindCtx);
1661 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
1662 ok(hr == E_NOTIMPL, "IMoniker_GetDisplayName should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1664 IBindCtx_Release(bindctx);
1666 hr = IMoniker_IsDirty(moniker);
1667 ok(hr == S_FALSE, "IMoniker_IsDirty should return S_FALSE, not 0x%08x\n", hr);
1669 /* IROTData::GetComparisonData test */
1671 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
1672 ok(hr == E_NOINTERFACE, "IMoniker_QueryInterface(IID_IROTData) should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
1674 /* Saving */
1676 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1677 ok_ole_success(hr, CreateStreamOnHGlobal);
1679 hr = IMoniker_Save(moniker, stream, TRUE);
1680 ok(hr == E_NOTIMPL, "IMoniker_Save should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1682 IStream_Release(stream);
1684 /* Hashing */
1685 hr = IMoniker_Hash(moniker, &hash);
1686 ok_ole_success(hr, IMoniker_Hash);
1687 ok(hash == (DWORD)&Test_ClassFactory,
1688 "Hash value should have been 0x%08x, instead of 0x%08x\n",
1689 (DWORD)&Test_ClassFactory, hash);
1691 /* IsSystemMoniker test */
1692 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
1693 ok_ole_success(hr, IMoniker_IsSystemMoniker);
1694 ok(moniker_type == MKSYS_POINTERMONIKER,
1695 "dwMkSys != MKSYS_POINTERMONIKER, instead was 0x%08x\n",
1696 moniker_type);
1698 hr = IMoniker_Inverse(moniker, &inverse);
1699 ok_ole_success(hr, IMoniker_Inverse);
1700 IMoniker_Release(inverse);
1702 hr = CreateBindCtx(0, &bindctx);
1703 ok_ole_success(hr, CreateBindCtx);
1705 /* IsRunning test */
1706 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
1707 ok(hr == S_OK, "IMoniker_IsRunning should return S_OK, not 0x%08x\n", hr);
1709 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
1710 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08x\n", hr);
1712 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1713 ok_ole_success(hr, IMoniker_BindToObject);
1714 IUnknown_Release(unknown);
1716 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1717 ok_ole_success(hr, IMoniker_BindToStorage);
1718 IUnknown_Release(unknown);
1720 IMoniker_Release(moniker);
1722 ok_no_locks();
1724 hr = CreatePointerMoniker(NULL, &moniker);
1725 ok_ole_success(hr, CreatePointerMoniker);
1727 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1728 ok(hr == E_UNEXPECTED, "IMoniker_BindToObject should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1730 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
1731 ok(hr == E_UNEXPECTED, "IMoniker_BindToStorage should have returned E_UNEXPECTED instead of 0x%08x\n", hr);
1733 IBindCtx_Release(bindctx);
1735 IMoniker_Release(moniker);
1738 static void test_bind_context(void)
1740 HRESULT hr;
1741 IBindCtx *pBindCtx;
1742 IEnumString *pEnumString;
1743 BIND_OPTS2 bind_opts;
1744 HeapUnknown *unknown;
1745 HeapUnknown *unknown2;
1746 IUnknown *param_obj;
1747 ULONG refs;
1748 static const WCHAR wszParamName[] = {'G','e','m','m','a',0};
1749 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
1751 hr = CreateBindCtx(0, NULL);
1752 ok(hr == E_INVALIDARG, "CreateBindCtx with NULL ppbc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1754 hr = CreateBindCtx(0xdeadbeef, &pBindCtx);
1755 ok(hr == E_INVALIDARG, "CreateBindCtx with reserved value non-zero should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1757 hr = CreateBindCtx(0, &pBindCtx);
1758 ok_ole_success(hr, "CreateBindCtx");
1760 bind_opts.cbStruct = -1;
1761 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1762 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1763 ok(bind_opts.cbStruct == sizeof(bind_opts) ||
1764 bind_opts.cbStruct == sizeof(bind_opts) + sizeof(void*), /* Vista */
1765 "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1767 bind_opts.cbStruct = sizeof(BIND_OPTS);
1768 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1769 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1770 ok(bind_opts.cbStruct == sizeof(BIND_OPTS), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1772 bind_opts.cbStruct = sizeof(bind_opts);
1773 hr = IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1774 ok_ole_success(hr, "IBindCtx_GetBindOptions");
1775 ok(bind_opts.cbStruct == sizeof(bind_opts), "bind_opts.cbStruct was %d\n", bind_opts.cbStruct);
1776 ok(bind_opts.grfFlags == 0, "bind_opts.grfFlags was 0x%x instead of 0\n", bind_opts.grfFlags);
1777 ok(bind_opts.grfMode == STGM_READWRITE, "bind_opts.grfMode was 0x%x instead of STGM_READWRITE\n", bind_opts.grfMode);
1778 ok(bind_opts.dwTickCountDeadline == 0, "bind_opts.dwTickCountDeadline was %d instead of 0\n", bind_opts.dwTickCountDeadline);
1779 ok(bind_opts.dwTrackFlags == 0, "bind_opts.dwTrackFlags was 0x%x instead of 0\n", bind_opts.dwTrackFlags);
1780 ok(bind_opts.dwClassContext == (CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER),
1781 "bind_opts.dwClassContext should have been 0x15 instead of 0x%x\n", bind_opts.dwClassContext);
1782 ok(bind_opts.locale == GetThreadLocale(), "bind_opts.locale should have been 0x%x instead of 0x%x\n", GetThreadLocale(), bind_opts.locale);
1783 ok(bind_opts.pServerInfo == NULL, "bind_opts.pServerInfo should have been NULL instead of %p\n", bind_opts.pServerInfo);
1785 bind_opts.cbStruct = -1;
1786 hr = IBindCtx_SetBindOptions(pBindCtx, (BIND_OPTS *)&bind_opts);
1787 ok(hr == E_INVALIDARG, "IBindCtx_SetBindOptions with bad cbStruct should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1789 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, NULL);
1790 ok(hr == E_INVALIDARG, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1792 unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1793 unknown->lpVtbl = &HeapUnknown_Vtbl;
1794 unknown->refs = 1;
1795 hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, (IUnknown *)&unknown->lpVtbl);
1796 ok_ole_success(hr, "IBindCtx_RegisterObjectParam");
1798 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszParamName, &param_obj);
1799 ok_ole_success(hr, "IBindCtx_GetObjectParam");
1800 IUnknown_Release(param_obj);
1802 hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszNonExistent, &param_obj);
1803 ok(hr == E_FAIL, "IBindCtx_GetObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1804 ok(param_obj == NULL, "IBindCtx_GetObjectParam with nonexistent key should have set output parameter to NULL instead of %p\n", param_obj);
1806 hr = IBindCtx_RevokeObjectParam(pBindCtx, (WCHAR *)wszNonExistent);
1807 ok(hr == E_FAIL, "IBindCtx_RevokeObjectParam with nonexistent key should have failed with E_FAIL instead of 0x%08x\n", hr);
1809 hr = IBindCtx_EnumObjectParam(pBindCtx, &pEnumString);
1810 ok(hr == E_NOTIMPL, "IBindCtx_EnumObjectParam should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1811 ok(!pEnumString, "pEnumString should be NULL\n");
1813 hr = IBindCtx_RegisterObjectBound(pBindCtx, NULL);
1814 ok_ole_success(hr, "IBindCtx_RegisterObjectBound(NULL)");
1816 hr = IBindCtx_RevokeObjectBound(pBindCtx, NULL);
1817 ok(hr == E_INVALIDARG, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr);
1819 unknown2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown));
1820 unknown2->lpVtbl = &HeapUnknown_Vtbl;
1821 unknown2->refs = 1;
1822 hr = IBindCtx_RegisterObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1823 ok_ole_success(hr, "IBindCtx_RegisterObjectBound");
1825 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1826 ok_ole_success(hr, "IBindCtx_RevokeObjectBound");
1828 hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl);
1829 ok(hr == MK_E_NOTBOUND, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr);
1831 IBindCtx_Release(pBindCtx);
1833 refs = IUnknown_Release((IUnknown *)&unknown->lpVtbl);
1834 ok(!refs, "object param should have been destroyed, instead of having %d refs\n", refs);
1836 refs = IUnknown_Release((IUnknown *)&unknown2->lpVtbl);
1837 ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs);
1840 START_TEST(moniker)
1842 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1844 test_ROT();
1845 test_ROT_multiple_entries();
1846 test_MkParseDisplayName();
1847 test_class_moniker();
1848 test_file_monikers();
1849 test_item_moniker();
1850 test_anti_moniker();
1851 test_generic_composite_moniker();
1852 test_pointer_moniker();
1854 /* FIXME: test moniker creation funcs and parsing other moniker formats */
1856 test_bind_context();
1858 CoUninitialize();