Update the address of the Free Software Foundation.
[wine.git] / dlls / ole32 / tests / moniker.c
blob58f70a15a2b076aa7e568532770cb1611010c836
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
24 #include <stdarg.h>
25 #include <stdio.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "objbase.h"
30 #include "comcat.h"
32 #include "wine/test.h"
34 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08lx\n", hr)
35 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
37 static const WCHAR wszFileName1[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
38 static const WCHAR wszFileName2[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
40 static int count_moniker_matches(IBindCtx * pbc, IEnumMoniker * spEM)
42 IMoniker * spMoniker;
43 int monCnt=0, matchCnt=0;
45 while ((IEnumMoniker_Next(spEM, 1, &spMoniker, NULL)==S_OK))
47 HRESULT hr;
48 WCHAR * szDisplayn;
49 monCnt++;
50 hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL, &szDisplayn);
51 if (SUCCEEDED(hr))
53 if (!lstrcmpW(szDisplayn, wszFileName1) || !lstrcmpW(szDisplayn, wszFileName2))
54 matchCnt++;
55 CoTaskMemFree(szDisplayn);
58 trace("Total number of monikers is %i\n", monCnt);
59 return matchCnt;
62 static void test_MkParseDisplayName(void)
64 IBindCtx * pbc = NULL;
65 HRESULT hr;
66 IMoniker * pmk = NULL;
67 IMoniker * pmk1 = NULL;
68 IMoniker * pmk2 = NULL;
69 ULONG eaten;
70 int matchCnt;
71 IUnknown * object = NULL;
73 IUnknown *lpEM1;
75 IEnumMoniker *spEM1 = NULL;
76 IEnumMoniker *spEM2 = NULL;
77 IEnumMoniker *spEM3 = NULL;
79 DWORD pdwReg1=0;
80 DWORD grflags=0;
81 DWORD pdwReg2=0;
82 IRunningObjectTable * pprot=NULL;
84 /* CLSID of My Computer */
85 static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
86 '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};
88 hr = CreateBindCtx(0, &pbc);
89 ok_ole_success(hr, CreateBindCtx);
91 hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
92 todo_wine { ok_ole_success(hr, MkParseDisplayName); }
94 if (object)
96 hr = IMoniker_BindToObject(pmk, pbc, NULL, &IID_IUnknown, (LPVOID*)&object);
97 ok_ole_success(hr, IMoniker_BindToObject);
99 IUnknown_Release(object);
101 IBindCtx_Release(pbc);
103 /* Test the EnumMoniker interface */
104 hr = CreateBindCtx(0, &pbc);
105 ok_ole_success(hr, CreateBindCtx);
107 hr = CreateFileMoniker(wszFileName1, &pmk1);
108 ok(hr==0, "CreateFileMoniker for file hr=%08lx\n", hr);
109 hr = CreateFileMoniker(wszFileName2, &pmk2);
110 ok(hr==0, "CreateFileMoniker for file hr=%08lx\n", hr);
111 hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
112 ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08lx\n", hr);
114 /* Check EnumMoniker before registering */
115 hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
116 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08lx\n", hr);
117 hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
118 /* Register a couple of Monikers and check is ok */
119 ok(hr==0, "IEnumMoniker_QueryInterface hr %08lx %p\n", hr, lpEM1);
120 hr = MK_E_NOOBJECT;
122 matchCnt = count_moniker_matches(pbc, spEM1);
123 trace("Number of matches is %i\n", matchCnt);
125 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
126 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
127 ok(hr==0, "IRunningObjectTable_Register hr=%08lx %p %08lx %p %p %ld\n",
128 hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
130 trace("IROT::Register\n");
131 grflags=0;
132 grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
133 hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
134 ok(hr==0, "IRunningObjectTable_Register hr=%08lx %p %08lx %p %p %ld\n", hr,
135 pprot, grflags, lpEM1, pmk2, pdwReg2);
137 hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
138 ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08lx\n", hr);
140 matchCnt = count_moniker_matches(pbc, spEM2);
141 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
143 trace("IEnumMoniker::Clone\n");
144 IEnumMoniker_Clone(spEM2, &spEM3);
146 matchCnt = count_moniker_matches(pbc, spEM3);
147 ok(matchCnt==0, "Number of matches should be equal to 0 not %i\n", matchCnt);
148 trace("IEnumMoniker::Reset\n");
149 IEnumMoniker_Reset(spEM3);
151 matchCnt = count_moniker_matches(pbc, spEM3);
152 ok(matchCnt==2, "Number of matches should be equal to 2 not %i\n", matchCnt);
154 IRunningObjectTable_Revoke(pprot,pdwReg1);
155 IRunningObjectTable_Revoke(pprot,pdwReg2);
156 IEnumMoniker_Release(spEM1);
157 IEnumMoniker_Release(spEM1);
158 IEnumMoniker_Release(spEM2);
159 IEnumMoniker_Release(spEM3);
160 IMoniker_Release(pmk1);
161 IMoniker_Release(pmk2);
162 IRunningObjectTable_Release(pprot);
164 IBindCtx_Release(pbc);
167 static const LARGE_INTEGER llZero;
169 static const BYTE expected_class_moniker_marshal_data[] =
171 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
172 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
173 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
174 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
175 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
176 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
177 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
178 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
179 0x00,0x00,0x00,0x00,
182 static const BYTE expected_class_moniker_saved_data[] =
184 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
185 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
186 0x00,0x00,0x00,0x00,
189 static const BYTE expected_class_moniker_comparison_data[] =
191 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
192 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
193 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
194 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
197 static const WCHAR expected_class_moniker_display_name[] =
199 'c','l','s','i','d',':','0','0','0','2','E','0','0','5','-','0','0','0',
200 '0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0',
201 '0','0','0','0','4','6',':',0
204 static const BYTE expected_item_moniker_comparison_data[] =
206 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
207 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
208 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
209 0x54,0x00,0x00,0x00,
212 static const BYTE expected_item_moniker_saved_data[] =
214 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
215 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
218 static const BYTE expected_item_moniker_marshal_data[] =
220 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
221 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
222 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
223 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
224 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
225 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
226 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
227 0x00,0x00,0x54,0x65,0x73,0x74,0x00,
230 static const BYTE expected_anti_moniker_marshal_data[] =
232 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
233 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
234 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
235 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
236 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
237 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
238 0x01,0x00,0x00,0x00,
241 static const BYTE expected_anti_moniker_saved_data[] =
243 0x01,0x00,0x00,0x00,
246 static const BYTE expected_anti_moniker_comparison_data[] =
248 0x05,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
249 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
250 0x01,0x00,0x00,0x00,
253 static const BYTE expected_gc_moniker_marshal_data[] =
255 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
256 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
257 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
258 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
259 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
260 0x00,0x00,0x00,0x00,0x2c,0x01,0x00,0x00,
261 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
262 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
263 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
264 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
265 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
266 0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,
267 0x02,0x00,0x00,0x00,0x21,0x00,0x05,0x00,
268 0x00,0x00,0x54,0x65,0x73,0x74,0x00,0x4d,
269 0x45,0x4f,0x57,0x04,0x00,0x00,0x00,0x0f,
270 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
271 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x04,
272 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,
273 0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,
274 0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,
275 0x00,0x00,0x00,0x23,0x00,0x05,0x00,0x00,
276 0x00,0x57,0x69,0x6e,0x65,0x00,
279 static const BYTE expected_gc_moniker_saved_data[] =
281 0x02,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
282 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
283 0x00,0x00,0x00,0x46,0x02,0x00,0x00,0x00,
284 0x21,0x00,0x05,0x00,0x00,0x00,0x54,0x65,
285 0x73,0x74,0x00,0x04,0x03,0x00,0x00,0x00,
286 0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,
287 0x00,0x00,0x46,0x02,0x00,0x00,0x00,0x23,
288 0x00,0x05,0x00,0x00,0x00,0x57,0x69,0x6e,
289 0x65,0x00,
292 static const BYTE expected_gc_moniker_comparison_data[] =
294 0x09,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
295 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
296 0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
297 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
298 0x21,0x00,0x54,0x00,0x45,0x00,0x53,0x00,
299 0x54,0x00,0x00,0x00,0x04,0x03,0x00,0x00,
300 0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,
301 0x00,0x00,0x00,0x46,0x23,0x00,0x57,0x00,
302 0x49,0x00,0x4e,0x00,0x45,0x00,0x00,0x00,
305 static void test_moniker(
306 const char *testname, IMoniker *moniker,
307 const BYTE *expected_moniker_marshal_data, size_t sizeof_expected_moniker_marshal_data,
308 const BYTE *expected_moniker_saved_data, size_t sizeof_expected_moniker_saved_data,
309 const BYTE *expected_moniker_comparison_data, size_t sizeof_expected_moniker_comparison_data,
310 LPCWSTR expected_display_name)
312 IStream * stream;
313 IROTData * rotdata;
314 HRESULT hr;
315 HGLOBAL hglobal;
316 LPBYTE moniker_data;
317 DWORD moniker_size;
318 DWORD i;
319 BOOL same = TRUE;
320 BYTE buffer[128];
321 IMoniker * moniker_proxy;
322 LPOLESTR display_name;
323 IBindCtx *bindctx;
325 hr = IMoniker_IsDirty(moniker);
326 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08lx\n", testname, hr);
328 /* Display Name */
330 hr = CreateBindCtx(0, &bindctx);
331 ok_ole_success(hr, CreateBindCtx);
333 hr = IMoniker_GetDisplayName(moniker, bindctx, NULL, &display_name);
334 ok_ole_success(hr, IMoniker_GetDisplayName);
335 ok(!lstrcmpW(display_name, expected_display_name), "display name wasn't what was expected\n");
337 CoTaskMemFree(display_name);
338 IBindCtx_Release(bindctx);
340 hr = IMoniker_IsDirty(moniker);
341 ok(hr == S_FALSE, "%s: IMoniker_IsDirty should return S_FALSE, not 0x%08lx\n", testname, hr);
343 /* IROTData::GetComparisonData test */
345 hr = IMoniker_QueryInterface(moniker, &IID_IROTData, (void **)&rotdata);
346 ok_ole_success(hr, IMoniker_QueryInterface(IID_IROTData));
348 hr = IROTData_GetComparisonData(rotdata, buffer, sizeof(buffer), &moniker_size);
349 ok_ole_success(hr, IROTData_GetComparisonData);
351 if (hr != S_OK) moniker_size = 0;
353 /* first check we have the right amount of data */
354 ok(moniker_size == sizeof_expected_moniker_comparison_data,
355 "%s: Size of comparison data differs (expected %d, actual %ld)\n",
356 testname, sizeof_expected_moniker_comparison_data, moniker_size);
358 /* then do a byte-by-byte comparison */
359 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_comparison_data); i++)
361 if (expected_moniker_comparison_data[i] != buffer[i])
363 same = FALSE;
364 break;
368 ok(same, "%s: Comparison data differs\n", testname);
369 if (!same)
371 for (i = 0; i < moniker_size; i++)
373 if (i % 8 == 0) printf(" ");
374 printf("0x%02x,", buffer[i]);
375 if (i % 8 == 7) printf("\n");
377 printf("\n");
380 IROTData_Release(rotdata);
382 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
384 /* Saving */
386 hr = IMoniker_Save(moniker, stream, TRUE);
387 ok_ole_success(hr, IMoniker_Save);
389 hr = GetHGlobalFromStream(stream, &hglobal);
390 ok_ole_success(hr, GetHGlobalFromStream);
392 moniker_size = GlobalSize(hglobal);
394 moniker_data = GlobalLock(hglobal);
396 /* first check we have the right amount of data */
397 ok(moniker_size == sizeof_expected_moniker_saved_data,
398 "%s: Size of saved data differs (expected %d, actual %ld)\n",
399 testname, sizeof_expected_moniker_saved_data, moniker_size);
401 /* then do a byte-by-byte comparison */
402 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_saved_data); i++)
404 if (expected_moniker_saved_data[i] != moniker_data[i])
406 same = FALSE;
407 break;
411 ok(same, "%s: Saved data differs\n", testname);
412 if (!same)
414 for (i = 0; i < moniker_size; i++)
416 if (i % 8 == 0) printf(" ");
417 printf("0x%02x,", moniker_data[i]);
418 if (i % 8 == 7) printf("\n");
420 printf("\n");
423 GlobalUnlock(hglobal);
425 IStream_Release(stream);
427 /* Marshaling tests */
429 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
430 ok_ole_success(hr, CreateStreamOnHGlobal);
432 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
433 ok_ole_success(hr, CoMarshalInterface);
435 hr = GetHGlobalFromStream(stream, &hglobal);
436 ok_ole_success(hr, GetHGlobalFromStream);
438 moniker_size = GlobalSize(hglobal);
440 moniker_data = GlobalLock(hglobal);
442 /* first check we have the right amount of data */
443 ok(moniker_size == sizeof_expected_moniker_marshal_data,
444 "%s: Size of marshaled data differs (expected %d, actual %ld)\n",
445 testname, sizeof_expected_moniker_marshal_data, moniker_size);
447 /* then do a byte-by-byte comparison */
448 if (expected_moniker_marshal_data)
450 for (i = 0; i < min(moniker_size, sizeof_expected_moniker_marshal_data); i++)
452 if (expected_moniker_marshal_data[i] != moniker_data[i])
454 same = FALSE;
455 break;
460 ok(same, "%s: Marshaled data differs\n", testname);
461 if (!same)
463 for (i = 0; i < moniker_size; i++)
465 if (i % 8 == 0) printf(" ");
466 printf("0x%02x,", moniker_data[i]);
467 if (i % 8 == 7) printf("\n");
469 printf("\n");
472 GlobalUnlock(hglobal);
474 IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
475 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void **)&moniker_proxy);
476 ok_ole_success(hr, CoUnmarshalInterface);
478 IStream_Release(stream);
479 IMoniker_Release(moniker_proxy);
482 static void test_class_moniker(void)
484 HRESULT hr;
485 IMoniker *moniker;
486 DWORD moniker_type;
487 DWORD hash;
488 IBindCtx *bindctx;
489 IMoniker *inverse;
490 IUnknown *unknown;
491 FILETIME filetime;
493 hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
494 ok_ole_success(hr, CreateClassMoniker);
495 if (!moniker) return;
497 test_moniker("class moniker", moniker,
498 expected_class_moniker_marshal_data, sizeof(expected_class_moniker_marshal_data),
499 expected_class_moniker_saved_data, sizeof(expected_class_moniker_saved_data),
500 expected_class_moniker_comparison_data, sizeof(expected_class_moniker_comparison_data),
501 expected_class_moniker_display_name);
503 /* Hashing */
505 hr = IMoniker_Hash(moniker, &hash);
506 ok_ole_success(hr, IMoniker_Hash);
508 ok(hash == CLSID_StdComponentCategoriesMgr.Data1,
509 "Hash value != Data1 field of clsid, instead was 0x%08lx\n",
510 hash);
512 /* IsSystemMoniker test */
514 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
515 ok_ole_success(hr, IMoniker_IsSystemMoniker);
517 ok(moniker_type == MKSYS_CLASSMONIKER,
518 "dwMkSys != MKSYS_CLASSMONIKER, instead was 0x%08lx\n",
519 moniker_type);
521 hr = CreateBindCtx(0, &bindctx);
522 ok_ole_success(hr, CreateBindCtx);
524 /* IsRunning test */
525 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
526 ok(hr == E_NOTIMPL, "IMoniker_IsRunning should return E_NOTIMPL, not 0x%08lx\n", hr);
528 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
529 ok(hr == MK_E_UNAVAILABLE, "IMoniker_GetTimeOfLastChange should return MK_E_UNAVAILABLE, not 0x%08lx\n", hr);
531 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
532 ok_ole_success(hr, IMoniker_BindToStorage);
533 IUnknown_Release(unknown);
535 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
536 ok_ole_success(hr, IMoniker_BindToStorage);
537 IUnknown_Release(unknown);
539 IBindCtx_Release(bindctx);
541 hr = IMoniker_Inverse(moniker, &inverse);
542 ok_ole_success(hr, IMoniker_Inverse);
543 IMoniker_Release(inverse);
545 IMoniker_Release(moniker);
548 static void test_file_moniker(WCHAR* path)
550 IStream *stream;
551 IMoniker *moniker1 = NULL, *moniker2 = NULL;
552 HRESULT hr;
554 hr = CreateFileMoniker(path, &moniker1);
555 ok_ole_success(hr, CreateFileMoniker);
557 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
559 /* Marshal */
560 hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
561 ok_ole_success(hr, CoMarshalInterface);
563 /* Rewind */
564 hr = IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
565 ok_ole_success(hr, IStream_Seek);
567 /* Unmarshal */
568 hr = CoUnmarshalInterface(stream, &IID_IMoniker, (void**)&moniker2);
569 ok_ole_success(hr, CoUnmarshalInterface);
571 hr = IMoniker_IsEqual(moniker1, moniker2);
572 ok_ole_success(hr, IsEqual);
574 IStream_Release(stream);
575 if (moniker1)
576 IMoniker_Release(moniker1);
577 if (moniker2)
578 IMoniker_Release(moniker2);
581 static void test_file_monikers(void)
583 static WCHAR wszFile[][30] = {
584 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
585 {'\\', '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},
586 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
587 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
588 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
589 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
590 * U+0100 .. = Latin extended-A
592 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
595 int i;
597 trace("ACP is %u\n", GetACP());
599 for (i = 0; i < COUNTOF(wszFile); ++i)
601 int j ;
602 for (j = lstrlenW(wszFile[i]); j > 0; --j)
604 wszFile[i][j] = 0;
605 test_file_moniker(wszFile[i]);
610 static void test_item_moniker(void)
612 HRESULT hr;
613 IMoniker *moniker;
614 DWORD moniker_type;
615 DWORD hash;
616 IBindCtx *bindctx;
617 IMoniker *inverse;
618 IUnknown *unknown;
619 static const WCHAR wszDelimeter[] = {'!',0};
620 static const WCHAR wszObjectName[] = {'T','e','s','t',0};
621 static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 };
623 hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker);
624 ok_ole_success(hr, CreateItemMoniker);
626 test_moniker("item moniker", moniker,
627 expected_item_moniker_marshal_data, sizeof(expected_item_moniker_marshal_data),
628 expected_item_moniker_saved_data, sizeof(expected_item_moniker_saved_data),
629 expected_item_moniker_comparison_data, sizeof(expected_item_moniker_comparison_data),
630 expected_display_name);
632 /* Hashing */
634 hr = IMoniker_Hash(moniker, &hash);
635 ok_ole_success(hr, IMoniker_Hash);
637 ok(hash == 0x73c,
638 "Hash value != 0x73c, instead was 0x%08lx\n",
639 hash);
641 /* IsSystemMoniker test */
643 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
644 ok_ole_success(hr, IMoniker_IsSystemMoniker);
646 ok(moniker_type == MKSYS_ITEMMONIKER,
647 "dwMkSys != MKSYS_ITEMMONIKER, instead was 0x%08lx\n",
648 moniker_type);
650 hr = CreateBindCtx(0, &bindctx);
651 ok_ole_success(hr, CreateBindCtx);
653 /* IsRunning test */
654 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
655 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08lx\n", hr);
657 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
658 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08lx\n", hr);
660 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
661 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08lx\n", hr);
663 IBindCtx_Release(bindctx);
665 hr = IMoniker_Inverse(moniker, &inverse);
666 ok_ole_success(hr, IMoniker_Inverse);
667 IMoniker_Release(inverse);
669 IMoniker_Release(moniker);
672 static void test_anti_moniker(void)
674 HRESULT hr;
675 IMoniker *moniker;
676 DWORD moniker_type;
677 DWORD hash;
678 IBindCtx *bindctx;
679 FILETIME filetime;
680 IMoniker *inverse;
681 IUnknown *unknown;
682 static const WCHAR expected_display_name[] = { '\\','.','.',0 };
684 hr = CreateAntiMoniker(&moniker);
685 ok_ole_success(hr, CreateAntiMoniker);
686 if (!moniker) return;
688 test_moniker("anti moniker", moniker,
689 expected_anti_moniker_marshal_data, sizeof(expected_anti_moniker_marshal_data),
690 expected_anti_moniker_saved_data, sizeof(expected_anti_moniker_saved_data),
691 expected_anti_moniker_comparison_data, sizeof(expected_anti_moniker_comparison_data),
692 expected_display_name);
694 /* Hashing */
695 hr = IMoniker_Hash(moniker, &hash);
696 ok_ole_success(hr, IMoniker_Hash);
697 ok(hash == 0x80000001,
698 "Hash value != 0x80000001, instead was 0x%08lx\n",
699 hash);
701 /* IsSystemMoniker test */
702 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
703 ok_ole_success(hr, IMoniker_IsSystemMoniker);
704 ok(moniker_type == MKSYS_ANTIMONIKER,
705 "dwMkSys != MKSYS_ANTIMONIKER, instead was 0x%08lx\n",
706 moniker_type);
708 hr = IMoniker_Inverse(moniker, &inverse);
709 ok(hr == MK_E_NOINVERSE, "IMoniker_Inverse should have returned MK_E_NOINVERSE instead of 0x%08lx\n", hr);
710 ok(inverse == NULL, "inverse should have been set to NULL instead of %p\n", inverse);
712 hr = CreateBindCtx(0, &bindctx);
713 ok_ole_success(hr, CreateBindCtx);
715 /* IsRunning test */
716 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
717 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08lx\n", hr);
719 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
720 ok(hr == E_NOTIMPL, "IMoniker_GetTimeOfLastChange should return E_NOTIMPL, not 0x%08lx\n", hr);
722 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
723 ok(hr == E_NOTIMPL, "IMoniker_BindToObject should return E_NOTIMPL, not 0x%08lx\n", hr);
725 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
726 ok(hr == E_NOTIMPL, "IMoniker_BindToStorage should return E_NOTIMPL, not 0x%08lx\n", hr);
728 IBindCtx_Release(bindctx);
730 IMoniker_Release(moniker);
733 static void test_generic_composite_moniker(void)
735 HRESULT hr;
736 IMoniker *moniker;
737 IMoniker *moniker1;
738 IMoniker *moniker2;
739 DWORD moniker_type;
740 DWORD hash;
741 IBindCtx *bindctx;
742 FILETIME filetime;
743 IMoniker *inverse;
744 IUnknown *unknown;
745 static const WCHAR wszDelimeter1[] = {'!',0};
746 static const WCHAR wszObjectName1[] = {'T','e','s','t',0};
747 static const WCHAR wszDelimeter2[] = {'#',0};
748 static const WCHAR wszObjectName2[] = {'W','i','n','e',0};
749 static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 };
751 hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1);
752 ok_ole_success(hr, CreateItemMoniker);
753 hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2);
754 ok_ole_success(hr, CreateItemMoniker);
755 hr = CreateGenericComposite(moniker1, moniker2, &moniker);
756 ok_ole_success(hr, CreateGenericComposite);
758 test_moniker("generic composite moniker", moniker,
759 expected_gc_moniker_marshal_data, sizeof(expected_gc_moniker_marshal_data),
760 expected_gc_moniker_saved_data, sizeof(expected_gc_moniker_saved_data),
761 expected_gc_moniker_comparison_data, sizeof(expected_gc_moniker_comparison_data),
762 expected_display_name);
764 /* Hashing */
766 hr = IMoniker_Hash(moniker, &hash);
767 ok_ole_success(hr, IMoniker_Hash);
769 ok(hash == 0xd87,
770 "Hash value != 0xd87, instead was 0x%08lx\n",
771 hash);
773 /* IsSystemMoniker test */
775 hr = IMoniker_IsSystemMoniker(moniker, &moniker_type);
776 ok_ole_success(hr, IMoniker_IsSystemMoniker);
778 ok(moniker_type == MKSYS_GENERICCOMPOSITE,
779 "dwMkSys != MKSYS_GENERICCOMPOSITE, instead was 0x%08lx\n",
780 moniker_type);
782 hr = CreateBindCtx(0, &bindctx);
783 ok_ole_success(hr, CreateBindCtx);
785 /* IsRunning test */
786 hr = IMoniker_IsRunning(moniker, bindctx, NULL, NULL);
787 todo_wine
788 ok(hr == S_FALSE, "IMoniker_IsRunning should return S_FALSE, not 0x%08lx\n", hr);
790 hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, NULL, &filetime);
791 ok(hr == MK_E_NOTBINDABLE, "IMoniker_GetTimeOfLastChange should return MK_E_NOTBINDABLE, not 0x%08lx\n", hr);
793 hr = IMoniker_BindToObject(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
794 todo_wine
795 ok(hr == E_INVALIDARG, "IMoniker_BindToObject should return E_INVALIDARG, not 0x%08lx\n", hr);
797 todo_wine
798 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IUnknown, (void **)&unknown);
799 ok(hr == E_INVALIDARG, "IMoniker_BindToStorage should return E_INVALIDARG, not 0x%08lx\n", hr);
801 IBindCtx_Release(bindctx);
803 hr = IMoniker_Inverse(moniker, &inverse);
804 ok_ole_success(hr, IMoniker_Inverse);
805 IMoniker_Release(inverse);
807 IMoniker_Release(moniker);
810 START_TEST(moniker)
812 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
814 test_MkParseDisplayName();
815 test_class_moniker();
816 test_file_monikers();
817 test_item_moniker();
818 test_anti_moniker();
819 test_generic_composite_moniker();
821 /* FIXME: test moniker creation funcs and parsing other moniker formats */
823 CoUninitialize();