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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/test.h"
33 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08lx\n", hr)
34 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
36 static const WCHAR wszFileName1
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
37 static const WCHAR wszFileName2
[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
39 static int count_moniker_matches(IBindCtx
* pbc
, IEnumMoniker
* spEM
)
42 int monCnt
=0, matchCnt
=0;
44 while ((IEnumMoniker_Next(spEM
, 1, &spMoniker
, NULL
)==S_OK
))
49 hr
=IMoniker_GetDisplayName(spMoniker
, pbc
, NULL
, &szDisplayn
);
52 if (!lstrcmpW(szDisplayn
, wszFileName1
) || !lstrcmpW(szDisplayn
, wszFileName2
))
54 CoTaskMemFree(szDisplayn
);
57 trace("Total number of monikers is %i\n", monCnt
);
61 static void test_MkParseDisplayName()
63 IBindCtx
* pbc
= NULL
;
65 IMoniker
* pmk
= NULL
;
66 IMoniker
* pmk1
= NULL
;
67 IMoniker
* pmk2
= NULL
;
70 IUnknown
* object
= NULL
;
74 IEnumMoniker
*spEM1
= NULL
;
75 IEnumMoniker
*spEM2
= NULL
;
76 IEnumMoniker
*spEM3
= NULL
;
81 IRunningObjectTable
* pprot
=NULL
;
83 /* CLSID of My Computer */
84 static const WCHAR wszDisplayName
[] = {'c','l','s','i','d',':',
85 '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};
87 hr
= CreateBindCtx(0, &pbc
);
88 ok_ole_success(hr
, CreateBindCtx
);
90 hr
= MkParseDisplayName(pbc
, wszDisplayName
, &eaten
, &pmk
);
91 todo_wine
{ ok_ole_success(hr
, MkParseDisplayName
); }
95 hr
= IMoniker_BindToObject(pmk
, pbc
, NULL
, &IID_IUnknown
, (LPVOID
*)&object
);
96 ok_ole_success(hr
, IMoniker_BindToObject
);
98 IUnknown_Release(object
);
100 IBindCtx_Release(pbc
);
102 /* Test the EnumMoniker interface */
103 hr
= CreateBindCtx(0, &pbc
);
104 ok_ole_success(hr
, CreateBindCtx
);
106 hr
= CreateFileMoniker(wszFileName1
, &pmk1
);
107 ok(hr
==0, "CreateFileMoniker for file hr=%08lx\n", hr
);
108 hr
= CreateFileMoniker(wszFileName2
, &pmk2
);
109 ok(hr
==0, "CreateFileMoniker for file hr=%08lx\n", hr
);
110 hr
= IBindCtx_GetRunningObjectTable(pbc
, &pprot
);
111 ok(hr
==0, "IBindCtx_GetRunningObjectTable hr=%08lx\n", hr
);
113 /* Check EnumMoniker before registering */
114 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM1
);
115 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08lx\n", hr
);
116 hr
= IEnumMoniker_QueryInterface(spEM1
, &IID_IUnknown
, (void*) &lpEM1
);
117 /* Register a couple of Monikers and check is ok */
118 ok(hr
==0, "IEnumMoniker_QueryInterface hr %08lx %p\n", hr
, lpEM1
);
121 matchCnt
= count_moniker_matches(pbc
, spEM1
);
122 trace("Number of matches is %i\n", matchCnt
);
124 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
125 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk1
, &pdwReg1
);
126 ok(hr
==0, "IRunningObjectTable_Register hr=%08lx %p %08lx %p %p %ld\n",
127 hr
, pprot
, grflags
, lpEM1
, pmk1
, pdwReg1
);
129 trace("IROT::Register\n");
131 grflags
= grflags
| ROTFLAGS_REGISTRATIONKEEPSALIVE
;
132 hr
= IRunningObjectTable_Register(pprot
, grflags
, lpEM1
, pmk2
, &pdwReg2
);
133 ok(hr
==0, "IRunningObjectTable_Register hr=%08lx %p %08lx %p %p %ld\n", hr
,
134 pprot
, grflags
, lpEM1
, pmk2
, pdwReg2
);
136 hr
= IRunningObjectTable_EnumRunning(pprot
, &spEM2
);
137 ok(hr
==0, "IRunningObjectTable_EnumRunning hr=%08lx\n", hr
);
139 matchCnt
= count_moniker_matches(pbc
, spEM2
);
140 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
142 trace("IEnumMoniker::Clone\n");
143 IEnumMoniker_Clone(spEM2
, &spEM3
);
145 matchCnt
= count_moniker_matches(pbc
, spEM3
);
146 ok(matchCnt
==0, "Number of matches should be equal to 0 not %i\n", matchCnt
);
147 trace("IEnumMoniker::Reset\n");
148 IEnumMoniker_Reset(spEM3
);
150 matchCnt
= count_moniker_matches(pbc
, spEM3
);
151 ok(matchCnt
==2, "Number of matches should be equal to 2 not %i\n", matchCnt
);
153 IRunningObjectTable_Revoke(pprot
,pdwReg1
);
154 IRunningObjectTable_Revoke(pprot
,pdwReg2
);
155 IEnumMoniker_Release(spEM1
);
156 IEnumMoniker_Release(spEM1
);
157 IEnumMoniker_Release(spEM2
);
158 IEnumMoniker_Release(spEM3
);
159 IMoniker_Release(pmk1
);
160 IMoniker_Release(pmk2
);
161 IRunningObjectTable_Release(pprot
);
163 IBindCtx_Release(pbc
);
166 static const BYTE expected_moniker_data
[] =
168 0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
169 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
171 0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
172 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
173 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
174 0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
175 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
179 static const LARGE_INTEGER llZero
;
181 static void test_class_moniker()
192 hr
= CreateClassMoniker(&CLSID_StdComponentCategoriesMgr
, &moniker
);
193 todo_wine
{ ok_ole_success(hr
, CreateClassMoniker
); }
195 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
197 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
198 todo_wine
{ ok_ole_success(hr
, CoMarshalInterface
); }
200 hr
= GetHGlobalFromStream(stream
, &hglobal
);
201 ok_ole_success(hr
, GetHGlobalFromStream
);
203 moniker_size
= GlobalSize(hglobal
);
205 moniker_data
= GlobalLock(hglobal
);
207 /* first check we have the right amount of data */
209 ok(moniker_size
== sizeof(expected_moniker_data
),
210 "Size of marshaled data differs (expected %d, actual %ld)\n",
211 sizeof(expected_moniker_data
), moniker_size
);
214 /* then do a byte-by-byte comparison */
215 for (i
= 0; i
< min(moniker_size
, sizeof(expected_moniker_data
)); i
++)
217 if (expected_moniker_data
[i
] != moniker_data
[i
])
224 ok(same
, "Marshaled data differs\n");
227 trace("Dumping marshaled moniker data:\n");
228 for (i
= 0; i
< moniker_size
; i
++)
230 trace("0x%02x,", moniker_data
[i
]);
231 if (i
% 8 == 7) trace("\n");
232 if (i
% 8 == 0) trace(" ");
236 GlobalUnlock(hglobal
);
238 IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
239 hr
= CoReleaseMarshalData(stream
);
240 todo_wine
{ ok_ole_success(hr
, CoReleaseMarshalData
); }
242 IStream_Release(stream
);
243 if (moniker
) IMoniker_Release(moniker
);
246 static void test_file_moniker(WCHAR
* path
)
249 IMoniker
*moniker1
= NULL
, *moniker2
= NULL
;
252 hr
= CreateFileMoniker(path
, &moniker1
);
253 ok_ole_success(hr
, CreateFileMoniker
);
255 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
258 hr
= CoMarshalInterface(stream
, &IID_IMoniker
, (IUnknown
*)moniker1
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
259 ok_ole_success(hr
, CoMarshalInterface
);
262 hr
= IStream_Seek(stream
, llZero
, STREAM_SEEK_SET
, NULL
);
263 ok_ole_success(hr
, IStream_Seek
);
266 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void**)&moniker2
);
267 ok_ole_success(hr
, CoUnmarshalInterface
);
269 hr
= IMoniker_IsEqual(moniker1
, moniker2
);
270 ok_ole_success(hr
, IsEqual
);
272 IStream_Release(stream
);
274 IMoniker_Release(moniker1
);
276 IMoniker_Release(moniker2
);
279 static void test_file_monikers(void)
281 static WCHAR wszFile
[][30] = {
282 {'\\', 'w','i','n','d','o','w','s','\\','s','y','s','t','e','m','\\','t','e','s','t','1','.','d','o','c',0},
283 {'\\', '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},
284 /* These map to themselves in Windows-1252 & 932 (Shift-JIS) */
285 {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0},
286 /* U+2020 = DAGGER = 0x86 (1252) = 0x813f (932)
287 * U+20AC = EURO SIGN = 0x80 (1252) = undef (932)
288 * U+0100 .. = Latin extended-A
290 {0x20ac, 0x2020, 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0},
295 trace("ACP is %u\n", GetACP());
297 for (i
= 0; i
< COUNTOF(wszFile
); ++i
)
300 for (j
= lstrlenW(wszFile
[i
]); j
> 0; --j
)
303 test_file_moniker(wszFile
[i
]);
310 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
312 test_MkParseDisplayName();
313 test_class_moniker();
314 test_file_monikers();
316 /* FIXME: test moniker creation funcs and parsing other moniker formats */