2 * Component Object Tests
4 * Copyright 2005 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
31 #include "wine/test.h"
33 /* functions that are not present on all versions of Windows */
34 HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
36 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
38 static const CLSID CLSID_non_existent = { 0x12345678, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
39 static const CLSID CLSID_CDeviceMoniker = { 0x4315d437, 0x5b8c, 0x11d0, { 0xbd, 0x3b, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86 } };
40 static const WCHAR devicedotone[] = {'d','e','v','i','c','e','.','1',0};
41 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
42 static const WCHAR wszCLSID_CDeviceMoniker[] =
45 '4','3','1','5','d','4','3','7','-',
49 '0','0','a','0','c','9','1','1','c','e','8','6',
53 static const IID IID_IWineTest =
58 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
59 }; /* 5201163f-8164-4fd0-a1a2-5d5a3654d3bd */
62 static void test_ProgIDFromCLSID(void)
65 HRESULT hr = ProgIDFromCLSID(&CLSID_CDeviceMoniker, &progid);
66 ok(hr == S_OK, "ProgIDFromCLSID failed with error 0x%08x\n", hr);
69 ok(!lstrcmpiW(progid, devicedotone), "Didn't get expected prog ID\n");
70 CoTaskMemFree(progid);
73 progid = (LPWSTR)0xdeadbeef;
74 hr = ProgIDFromCLSID(&CLSID_non_existent, &progid);
75 ok(hr == REGDB_E_CLASSNOTREG, "ProgIDFromCLSID returned %08x\n", hr);
76 ok(progid == NULL, "ProgIDFromCLSID returns with progid %p\n", progid);
78 hr = ProgIDFromCLSID(&CLSID_CDeviceMoniker, NULL);
79 ok(hr == E_INVALIDARG, "ProgIDFromCLSID should return E_INVALIDARG instead of 0x%08x\n", hr);
82 static void test_CLSIDFromProgID(void)
85 HRESULT hr = CLSIDFromProgID(devicedotone, &clsid);
86 ok(hr == S_OK, "CLSIDFromProgID failed with error 0x%08x\n", hr);
87 ok(IsEqualCLSID(&clsid, &CLSID_CDeviceMoniker), "clsid wasn't equal to CLSID_CDeviceMoniker\n");
89 hr = CLSIDFromString((LPOLESTR)devicedotone, &clsid);
90 ok_ole_success(hr, "CLSIDFromString");
91 ok(IsEqualCLSID(&clsid, &CLSID_CDeviceMoniker), "clsid wasn't equal to CLSID_CDeviceMoniker\n");
93 /* test some failure cases */
95 hr = CLSIDFromProgID(wszNonExistent, NULL);
96 ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr);
98 hr = CLSIDFromProgID(NULL, &clsid);
99 ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr);
101 memset(&clsid, 0xcc, sizeof(clsid));
102 hr = CLSIDFromProgID(wszNonExistent, &clsid);
103 ok(hr == CO_E_CLASSSTRING, "CLSIDFromProgID on nonexistent ProgID should have returned CO_E_CLASSSTRING instead of 0x%08x\n", hr);
104 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "CLSIDFromProgID should have set clsid to all-zeros on failure\n");
107 static void test_CLSIDFromString(void)
110 HRESULT hr = CLSIDFromString((LPOLESTR)wszCLSID_CDeviceMoniker, &clsid);
111 ok_ole_success(hr, "CLSIDFromString");
112 ok(IsEqualCLSID(&clsid, &CLSID_CDeviceMoniker), "clsid wasn't equal to CLSID_CDeviceMoniker\n");
114 hr = CLSIDFromString(NULL, &clsid);
115 ok_ole_success(hr, "CLSIDFromString");
116 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
119 static void test_CoCreateInstance(void)
121 REFCLSID rclsid = &CLSID_MyComputer;
122 IUnknown *pUnk = (IUnknown *)0xdeadbeef;
123 HRESULT hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
124 ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
125 ok(pUnk == NULL, "CoCreateInstance should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
128 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
129 ok_ole_success(hr, "CoCreateInstance");
130 IUnknown_Release(pUnk);
133 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
134 ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
137 static void test_CoGetClassObject(void)
139 IUnknown *pUnk = (IUnknown *)0xdeadbeef;
140 HRESULT hr = CoGetClassObject(&CLSID_MyComputer, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
141 ok(hr == CO_E_NOTINITIALIZED, "CoGetClassObject should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
142 ok(pUnk == NULL, "CoGetClassObject should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
144 hr = CoGetClassObject(&CLSID_MyComputer, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, NULL);
145 ok(hr == E_INVALIDARG, "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08x\n", hr);
148 static ATOM register_dummy_class(void)
156 GetModuleHandle(NULL),
158 LoadCursor(NULL, IDC_ARROW),
159 (HBRUSH)(COLOR_BTNFACE+1),
161 TEXT("WineOleTestClass"),
164 return RegisterClass(&wc);
167 static void test_ole_menu(void)
172 hwndFrame = CreateWindow(MAKEINTATOM(register_dummy_class()), "Test", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
173 hr = OleSetMenuDescriptor(NULL, hwndFrame, NULL, NULL, NULL);
174 todo_wine ok_ole_success(hr, "OleSetMenuDescriptor");
176 DestroyWindow(hwndFrame);
180 static HRESULT WINAPI MessageFilter_QueryInterface(IMessageFilter *iface, REFIID riid, void ** ppvObj)
182 if (ppvObj == NULL) return E_POINTER;
184 if (IsEqualGUID(riid, &IID_IUnknown) ||
185 IsEqualGUID(riid, &IID_IClassFactory))
187 *ppvObj = (LPVOID)iface;
188 IMessageFilter_AddRef(iface);
192 return E_NOINTERFACE;
195 static ULONG WINAPI MessageFilter_AddRef(IMessageFilter *iface)
197 return 2; /* non-heap object */
200 static ULONG WINAPI MessageFilter_Release(IMessageFilter *iface)
202 return 1; /* non-heap object */
205 static DWORD WINAPI MessageFilter_HandleInComingCall(
206 IMessageFilter *iface,
208 HTASK threadIDCaller,
210 LPINTERFACEINFO lpInterfaceInfo)
212 trace("HandleInComingCall\n");
213 return SERVERCALL_ISHANDLED;
216 static DWORD WINAPI MessageFilter_RetryRejectedCall(
217 IMessageFilter *iface,
218 HTASK threadIDCallee,
222 trace("RetryRejectedCall\n");
226 static DWORD WINAPI MessageFilter_MessagePending(
227 IMessageFilter *iface,
228 HTASK threadIDCallee,
232 trace("MessagePending\n");
233 return PENDINGMSG_WAITNOPROCESS;
236 static const IMessageFilterVtbl MessageFilter_Vtbl =
238 MessageFilter_QueryInterface,
239 MessageFilter_AddRef,
240 MessageFilter_Release,
241 MessageFilter_HandleInComingCall,
242 MessageFilter_RetryRejectedCall,
243 MessageFilter_MessagePending
246 static IMessageFilter MessageFilter = { &MessageFilter_Vtbl };
248 static void test_CoRegisterMessageFilter(void)
251 IMessageFilter *prev_filter;
253 #if 0 /* crashes without an apartment! */
254 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
257 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
258 prev_filter = (IMessageFilter *)0xdeadbeef;
259 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
260 ok(hr == CO_E_NOT_SUPPORTED,
261 "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
263 ok(prev_filter == (IMessageFilter *)0xdeadbeef,
264 "prev_filter should have been set to %p\n", prev_filter);
267 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
269 hr = CoRegisterMessageFilter(NULL, NULL);
270 ok_ole_success(hr, "CoRegisterMessageFilter");
272 prev_filter = (IMessageFilter *)0xdeadbeef;
273 hr = CoRegisterMessageFilter(NULL, &prev_filter);
274 ok_ole_success(hr, "CoRegisterMessageFilter");
275 ok(prev_filter == NULL, "prev_filter should have been set to NULL instead of %p\n", prev_filter);
277 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
278 ok_ole_success(hr, "CoRegisterMessageFilter");
279 ok(prev_filter == NULL, "prev_filter should have been set to NULL instead of %p\n", prev_filter);
281 hr = CoRegisterMessageFilter(NULL, NULL);
282 ok_ole_success(hr, "CoRegisterMessageFilter");
287 static HRESULT WINAPI Test_IUnknown_QueryInterface(
292 if (ppvObj == NULL) return E_POINTER;
294 if (IsEqualIID(riid, &IID_IUnknown) ||
295 IsEqualIID(riid, &IID_IWineTest))
297 *ppvObj = (LPVOID)iface;
298 IUnknown_AddRef(iface);
303 return E_NOINTERFACE;
306 static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
308 return 2; /* non-heap-based object */
311 static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
313 return 1; /* non-heap-based object */
316 static const IUnknownVtbl TestUnknown_Vtbl =
318 Test_IUnknown_QueryInterface,
319 Test_IUnknown_AddRef,
320 Test_IUnknown_Release,
323 static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
325 static HRESULT WINAPI PSFactoryBuffer_QueryInterface(
326 IPSFactoryBuffer * This,
327 /* [in] */ REFIID riid,
328 /* [iid_is][out] */ void **ppvObject)
330 if (IsEqualIID(riid, &IID_IUnknown) ||
331 IsEqualIID(riid, &IID_IPSFactoryBuffer))
334 IPSFactoryBuffer_AddRef(This);
337 return E_NOINTERFACE;
340 static ULONG WINAPI PSFactoryBuffer_AddRef(
341 IPSFactoryBuffer * This)
346 static ULONG WINAPI PSFactoryBuffer_Release(
347 IPSFactoryBuffer * This)
352 static HRESULT WINAPI PSFactoryBuffer_CreateProxy(
353 IPSFactoryBuffer * This,
354 /* [in] */ IUnknown *pUnkOuter,
355 /* [in] */ REFIID riid,
356 /* [out] */ IRpcProxyBuffer **ppProxy,
357 /* [out] */ void **ppv)
362 static HRESULT WINAPI PSFactoryBuffer_CreateStub(
363 IPSFactoryBuffer * This,
364 /* [in] */ REFIID riid,
365 /* [unique][in] */ IUnknown *pUnkServer,
366 /* [out] */ IRpcStubBuffer **ppStub)
371 static IPSFactoryBufferVtbl PSFactoryBufferVtbl =
373 PSFactoryBuffer_QueryInterface,
374 PSFactoryBuffer_AddRef,
375 PSFactoryBuffer_Release,
376 PSFactoryBuffer_CreateProxy,
377 PSFactoryBuffer_CreateStub
380 static IPSFactoryBuffer PSFactoryBuffer = { &PSFactoryBufferVtbl };
382 static const CLSID CLSID_WineTestPSFactoryBuffer =
387 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
388 }; /* 52011640-8164-4fd0-a1a2-5d5a3654d3bd */
390 static void test_CoRegisterPSClsid(void)
393 DWORD dwRegistrationKey;
397 hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
398 ok(hr == CO_E_NOTINITIALIZED, "CoRegisterPSClsid should have returened CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
400 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
402 hr = CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer, (IUnknown *)&PSFactoryBuffer,
403 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegistrationKey);
404 ok_ole_success(hr, "CoRegisterClassObject");
406 hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
407 ok_ole_success(hr, "CoRegisterPSClsid");
409 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
410 ok_ole_success(hr, "CreateStreamOnHGlobal");
412 hr = CoMarshalInterface(stream, &IID_IWineTest, (IUnknown *)&Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
413 ok(hr == E_NOTIMPL, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr);
414 IStream_Release(stream);
416 hr = CoRevokeClassObject(dwRegistrationKey);
417 ok_ole_success(hr, "CoRevokeClassObject");
421 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
423 hr = CoGetPSClsid(&IID_IWineTest, &clsid);
424 ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08x\n", hr);
429 static void test_CoGetPSClsid(void)
434 hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
435 ok(hr == CO_E_NOTINITIALIZED,
436 "CoGetPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n",
439 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
441 hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
442 ok_ole_success(hr, "CoGetPSClsid");
444 hr = CoGetPSClsid(&IID_IWineTest, &clsid);
445 ok(hr == REGDB_E_IIDNOTREG,
446 "CoGetPSClsid for random IID returned 0x%08x instead of REGDB_E_IIDNOTREG\n",
449 hr = CoGetPSClsid(&IID_IClassFactory, NULL);
450 ok(hr == E_INVALIDARG,
451 "CoGetPSClsid for null clsid returned 0x%08x instead of E_INVALIDARG\n",
460 HMODULE hOle32 = GetModuleHandle("ole32");
461 if (!(pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx")))
463 trace("You need DCOM95 installed to run this test\n");
467 test_ProgIDFromCLSID();
468 test_CLSIDFromProgID();
469 test_CLSIDFromString();
470 test_CoCreateInstance();
472 test_CoGetClassObject();
473 test_CoRegisterMessageFilter();
474 test_CoRegisterPSClsid();