ReactOS 0.4.15-dev-8207-gd73a838
compobj.c
Go to the documentation of this file.
1/*
2 * Component Object Tests
3 *
4 * Copyright 2005 Robert Shearman
5 *
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.
10 *
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.
15 *
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
19 */
20
21#define COBJMACROS
22#define CONST_VTABLE
23
24#include <stdarg.h>
25#include <stdio.h>
26
27#include "windef.h"
28#include "winbase.h"
29#define USE_COM_CONTEXT_DEF
30#include "objbase.h"
31#include "shlguid.h"
32#include "urlmon.h" /* for CLSID_FileProtocol */
33#include "dde.h"
34#include "cguid.h"
35
36#include "ctxtcall.h"
37
38#include "wine/test.h"
39#include "initguid.h"
40
41#define DEFINE_EXPECT(func) \
42 static BOOL expect_ ## func = FALSE; static unsigned int called_ ## func = 0
43
44#define SET_EXPECT(func) \
45 expect_ ## func = TRUE
46
47#define CHECK_EXPECT2(func) \
48 do { \
49 ok(expect_ ##func, "unexpected call " #func "\n"); \
50 called_ ## func++; \
51 }while(0)
52
53#define CHECK_EXPECT(func) \
54 do { \
55 CHECK_EXPECT2(func); \
56 expect_ ## func = FALSE; \
57 }while(0)
58
59#define CHECK_CALLED(func, n) \
60 do { \
61 ok(called_ ## func == n, "expected " #func " called %u times, got %u\n", n, called_ ## func); \
62 expect_ ## func = FALSE; \
63 called_ ## func = 0; \
64 }while(0)
65
66DEFINE_EXPECT(CreateStub);
67DEFINE_EXPECT(PreInitialize);
68DEFINE_EXPECT(PostInitialize);
69DEFINE_EXPECT(PreUninitialize);
70DEFINE_EXPECT(PostUninitialize);
71
72/* functions that are not present on all versions of Windows */
73static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
74static HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv);
75static HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject);
76static HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew);
77static HRESULT (WINAPI * pCoTreatAsClass)(REFCLSID clsidOld, REFCLSID pClsidNew);
78static HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token);
79static HRESULT (WINAPI * pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
80static LONG (WINAPI * pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
81static LONG (WINAPI * pRegOverridePredefKey)(HKEY key, HKEY override);
82
83static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
84static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
85static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
86static BOOL (WINAPI *pIsWow64Process)(HANDLE, LPBOOL);
87static void (WINAPI *pReleaseActCtx)(HANDLE);
88
89#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
90#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
91#define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
92
93static const CLSID CLSID_non_existent = { 0x12345678, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
94static const CLSID CLSID_StdFont = { 0x0be35203, 0x8f91, 0x11ce, { 0x9d, 0xe3, 0x00, 0xaa, 0x00, 0x4b, 0xb8, 0x51 } };
95static const GUID IID_Testiface = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
96static const GUID IID_Testiface2 = { 0x32222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
97static const GUID IID_Testiface3 = { 0x42222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
98static const GUID IID_Testiface4 = { 0x52222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
99static const GUID IID_Testiface5 = { 0x62222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
100static const GUID IID_Testiface6 = { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
101static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
102
103DEFINE_GUID(CLSID_testclsid, 0xacd014c7,0x9535,0x4fac,0x8b,0x53,0xa4,0x8c,0xa7,0xf4,0xd7,0x26);
104
105static const WCHAR stdfont[] = {'S','t','d','F','o','n','t',0};
106static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
107static const WCHAR wszCLSID_StdFont[] =
108{
109 '{','0','b','e','3','5','2','0','3','-','8','f','9','1','-','1','1','c','e','-',
110 '9','d','e','3','-','0','0','a','a','0','0','4','b','b','8','5','1','}',0
111};
112static const WCHAR progidW[] = {'P','r','o','g','I','d','.','P','r','o','g','I','d',0};
113static const WCHAR cf_brokenW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
114 'c','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}','a',0};
115
116DEFINE_GUID(IID_IWineTest, 0x5201163f, 0x8164, 0x4fd0, 0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd);
117DEFINE_GUID(CLSID_WineOOPTest, 0x5201163f, 0x8164, 0x4fd0, 0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd);
118
120
121static void LockModule(void)
122{
124}
125
126static void UnlockModule(void)
127{
129}
130
132 LPCLASSFACTORY iface,
133 REFIID riid,
134 LPVOID *ppvObj)
135{
136 if (ppvObj == NULL) return E_POINTER;
137
140 {
141 *ppvObj = iface;
142 IClassFactory_AddRef(iface);
143 return S_OK;
144 }
145
146 *ppvObj = NULL;
147 return E_NOINTERFACE;
148}
149
150static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
151{
152 LockModule();
153 return 2; /* non-heap-based object */
154}
155
156static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
157{
158 UnlockModule();
159 return 1; /* non-heap-based object */
160}
161
164 LPCLASSFACTORY iface,
165 IUnknown *pUnkOuter,
166 REFIID riid,
167 LPVOID *ppvObj)
168{
169 *ppvObj = NULL;
171 if (pUnkOuter) return CLASS_E_NOAGGREGATION;
172 return E_NOINTERFACE;
173}
174
176 LPCLASSFACTORY iface,
177 BOOL fLock)
178{
179 return S_OK;
180}
181
182static const IClassFactoryVtbl TestClassFactory_Vtbl =
183{
189};
190
192
194
195static BOOL create_manifest_file(const char *filename, const char *manifest)
196{
197 int manifest_len;
198 DWORD size;
199 HANDLE file;
201
204
205 manifest_len = strlen(manifest);
208 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
210 return FALSE;
211 WriteFile(file, manifest, manifest_len, &size, NULL);
213
214 return TRUE;
215}
216
218{
220 ACTCTXW actctx;
222 BOOL ret;
223
224 if (!pCreateActCtxW) return NULL;
225
226 create_manifest_file("file.manifest", manifest);
227
228 MultiByteToWideChar( CP_ACP, 0, "file.manifest", -1, path, MAX_PATH );
229 memset(&actctx, 0, sizeof(ACTCTXW));
230 actctx.cbSize = sizeof(ACTCTXW);
231 actctx.lpSource = path;
232
233 handle = pCreateActCtxW(&actctx);
234 ok(handle != INVALID_HANDLE_VALUE || broken(handle == INVALID_HANDLE_VALUE) /* some old XP/2k3 versions */,
235 "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError());
237 {
238 win_skip("activation context generation failed, some tests will be skipped\n");
239 handle = NULL;
240 }
241
242 ok(actctx.cbSize == sizeof(ACTCTXW), "actctx.cbSize=%d\n", actctx.cbSize);
243 ok(actctx.dwFlags == 0, "actctx.dwFlags=%d\n", actctx.dwFlags);
244 ok(actctx.lpSource == path, "actctx.lpSource=%p\n", actctx.lpSource);
245 ok(actctx.wProcessorArchitecture == 0, "actctx.wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
246 ok(actctx.wLangId == 0, "actctx.wLangId=%d\n", actctx.wLangId);
247 ok(actctx.lpAssemblyDirectory == NULL, "actctx.lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
248 ok(actctx.lpResourceName == NULL, "actctx.lpResourceName=%p\n", actctx.lpResourceName);
249 ok(actctx.lpApplicationName == NULL, "actctx.lpApplicationName=%p\n", actctx.lpApplicationName);
250 ok(actctx.hModule == NULL, "actctx.hModule=%p\n", actctx.hModule);
251
252 DeleteFileA("file.manifest");
253
254 if (handle)
255 {
256 ret = pActivateActCtx(handle, cookie);
257 ok(ret, "ActivateActCtx failed: %u\n", GetLastError());
258 }
259
260 return handle;
261}
262
263static const char actctx_manifest[] =
264"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
265"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\""
266" publicKeyToken=\"6595b6414666f1df\" />"
267"<file name=\"testlib.dll\">"
268" <comClass"
269" clsid=\"{0000033a-0000-0000-c000-000000000046}\""
270" progid=\"FTMarshal\""
271" />"
272" <comClass"
273" clsid=\"{5201163f-8164-4fd0-a1a2-5d5a3654d3bd}\""
274" progid=\"WineOOPTest\""
275" />"
276" <comClass description=\"Test com class\""
277" clsid=\"{12345678-1234-1234-1234-56789abcdef0}\""
278" progid=\"ProgId.ProgId\""
279" miscStatusIcon=\"recomposeonresize\""
280" />"
281" <comClass description=\"CustomFont Description\" clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb851}\""
282" progid=\"CustomFont\""
283" miscStatusIcon=\"recomposeonresize\""
284" miscStatusContent=\"insideout\""
285" />"
286" <comClass description=\"StdFont Description\" clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb852}\""
287" progid=\"StdFont\""
288" />"
289" <comClass clsid=\"{62222222-1234-1234-1234-56789abcdef0}\" >"
290" <progid>ProgId.ProgId.1</progid>"
291" </comClass>"
292" <comInterfaceProxyStub "
293" name=\"Iifaceps\""
294" iid=\"{22222222-1234-1234-1234-56789abcdef0}\""
295" proxyStubClsid32=\"{66666666-8888-7777-6666-555555555555}\""
296" />"
297"</file>"
298" <comInterfaceExternalProxyStub "
299" name=\"Iifaceps2\""
300" iid=\"{32222222-1234-1234-1234-56789abcdef0}\""
301" />"
302" <comInterfaceExternalProxyStub "
303" name=\"Iifaceps3\""
304" iid=\"{42222222-1234-1234-1234-56789abcdef0}\""
305" proxyStubClsid32=\"{66666666-8888-7777-6666-555555555555}\""
306" />"
307" <comInterfaceExternalProxyStub "
308" name=\"Iifaceps4\""
309" iid=\"{52222222-1234-1234-1234-56789abcdef0}\""
310" proxyStubClsid32=\"{00000000-0000-0000-0000-000000000000}\""
311" />"
312" <clrClass "
313" clsid=\"{72222222-1234-1234-1234-56789abcdef0}\""
314" name=\"clrclass\""
315" >"
316" <progid>clrprogid.1</progid>"
317" </clrClass>"
318"</assembly>";
319
320DEFINE_GUID(CLSID_Testclass, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0);
321
322static void test_ProgIDFromCLSID(void)
323{
324 ULONG_PTR cookie = 0;
327 HRESULT hr;
328
330 ok(hr == S_OK, "ProgIDFromCLSID failed with error 0x%08x\n", hr);
331 if (hr == S_OK)
332 {
333 ok(!lstrcmpiW(progid, stdfont), "Didn't get expected prog ID\n");
335 }
336
337 progid = (LPWSTR)0xdeadbeef;
339 ok(hr == REGDB_E_CLASSNOTREG, "ProgIDFromCLSID returned %08x\n", hr);
340 ok(progid == NULL, "ProgIDFromCLSID returns with progid %p\n", progid);
341
343 ok(hr == E_INVALIDARG, "ProgIDFromCLSID should return E_INVALIDARG instead of 0x%08x\n", hr);
344
346 {
347 static const WCHAR customfontW[] = {'C','u','s','t','o','m','F','o','n','t',0};
348
350 ok(hr == S_OK, "got 0x%08x\n", hr);
351 ok(!lstrcmpiW(progid, progidW), "got %s\n", wine_dbgstr_w(progid));
353
354 /* try something registered and redirected */
355 progid = NULL;
357 ok(hr == S_OK, "got 0x%08x\n", hr);
358 ok(!lstrcmpiW(progid, customfontW), "got wrong progid %s\n", wine_dbgstr_w(progid));
360
361 /* classes without default progid, progid list is not used */
362 progid = (void *)0xdeadbeef;
364 ok(hr == REGDB_E_CLASSNOTREG && progid == NULL, "got 0x%08x, progid %p\n", hr, progid);
365
366 progid = (void *)0xdeadbeef;
368 ok(hr == REGDB_E_CLASSNOTREG && progid == NULL, "got 0x%08x, progid %p\n", hr, progid);
369
370 pDeactivateActCtx(0, cookie);
371 pReleaseActCtx(handle);
372 }
373}
374
375static void test_CLSIDFromProgID(void)
376{
377 ULONG_PTR cookie = 0;
379 CLSID clsid;
381 ok(hr == S_OK, "CLSIDFromProgID failed with error 0x%08x\n", hr);
382 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
383
385 ok_ole_success(hr, "CLSIDFromString");
386 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
387
388 /* test some failure cases */
389
391 ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr);
392
394 ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr);
395
396 memset(&clsid, 0xcc, sizeof(clsid));
398 ok(hr == CO_E_CLASSSTRING, "CLSIDFromProgID on nonexistent ProgID should have returned CO_E_CLASSSTRING instead of 0x%08x\n", hr);
399 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "CLSIDFromProgID should have set clsid to all-zeros on failure\n");
400
401 /* fails without proper context */
402 memset(&clsid, 0xcc, sizeof(clsid));
404 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
405 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "wrong clsid\n");
406
408 {
409 GUID clsid1;
410
411 memset(&clsid, 0xcc, sizeof(clsid));
413 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
414 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "should have zero CLSID on failure\n");
415
416 /* CLSIDFromString() doesn't check activation context */
418 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
419
422 ok(hr == S_OK, "got 0x%08x\n", hr);
423 /* it returns generated CLSID here */
425 "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
426
427 /* duplicate progid present in context - returns generated guid here too */
430 ok(hr == S_OK, "got 0x%08x\n", hr);
431 clsid1 = CLSID_StdFont;
432 /* that's where it differs from StdFont */
433 clsid1.Data4[7] = 0x52;
435 "got %s\n", wine_dbgstr_guid(&clsid));
436
437 pDeactivateActCtx(0, cookie);
438 pReleaseActCtx(handle);
439 }
440}
441
442static void test_CLSIDFromString(void)
443{
444 CLSID clsid;
445 WCHAR wszCLSID_Broken[50];
446 UINT i;
447
449 ok_ole_success(hr, "CLSIDFromString");
450 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
451
452 memset(&clsid, 0xab, sizeof(clsid));
454 ok(hr == S_OK, "got 0x%08x\n", hr);
455 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
456
457 /* string is longer, but starts with a valid CLSID */
458 memset(&clsid, 0, sizeof(clsid));
460 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
462
463 lstrcpyW(wszCLSID_Broken, wszCLSID_StdFont);
464 for(i = lstrlenW(wszCLSID_StdFont); i < 49; i++)
465 wszCLSID_Broken[i] = 'A';
466 wszCLSID_Broken[i] = '\0';
467
468 memset(&clsid, 0, sizeof(CLSID));
469 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
470 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
471 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
472
473 wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = 'A';
474 memset(&clsid, 0, sizeof(CLSID));
475 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
476 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
477 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
478
479 wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)] = '\0';
480 memset(&clsid, 0, sizeof(CLSID));
481 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
482 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
483 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
484
485 wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = '\0';
486 memset(&clsid, 0, sizeof(CLSID));
487 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
488 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
489 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
490
491 memset(&clsid, 0xcc, sizeof(CLSID));
492 hr = CLSIDFromString(wszCLSID_Broken+1, &clsid);
493 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
494 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
495
496 wszCLSID_Broken[9] = '*';
497 memset(&clsid, 0xcc, sizeof(CLSID));
498 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
499 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
500 ok(clsid.Data1 == CLSID_StdFont.Data1, "Got %08x\n", clsid.Data1);
501 ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
502
503 wszCLSID_Broken[3] = '*';
504 memset(&clsid, 0xcc, sizeof(CLSID));
505 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
506 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
507 ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1);
508 ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
509
510 wszCLSID_Broken[3] = '\0';
511 memset(&clsid, 0xcc, sizeof(CLSID));
512 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
513 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
514 ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1);
515 ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
516}
517
518static void test_IIDFromString(void)
519{
520 static const WCHAR cfW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
521 'c','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
522 static const WCHAR brokenW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
523 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
524 static const WCHAR broken2W[] = {'{','0','0','0','0','0','0','0','1','=','0','0','0','0','-','0','0','0','0','-',
525 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
526 static const WCHAR broken3W[] = {'b','r','o','k','e','n','0','0','1','=','0','0','0','0','-','0','0','0','0','-',
527 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
528 HRESULT hr;
529 IID iid;
530
532 ok(hr == S_OK, "got 0x%08x\n", hr);
533 ok(IsEqualIID(&iid, &CLSID_StdFont), "got iid %s\n", wine_dbgstr_guid(&iid));
534
535 memset(&iid, 0xab, sizeof(iid));
536 hr = IIDFromString(NULL, &iid);
537 ok(hr == S_OK, "got 0x%08x\n", hr);
538 ok(IsEqualIID(&iid, &CLSID_NULL), "got iid %s\n", wine_dbgstr_guid(&iid));
539
540 hr = IIDFromString(cfW, &iid);
541 ok(hr == S_OK, "got 0x%08x\n", hr);
542 ok(IsEqualIID(&iid, &IID_IClassFactory), "got iid %s\n", wine_dbgstr_guid(&iid));
543
544 /* string starts with a valid IID but is longer */
545 memset(&iid, 0xab, sizeof(iid));
546 hr = IIDFromString(cf_brokenW, &iid);
547 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
548 ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
549
550 /* invalid IID in a valid format */
551 memset(&iid, 0xab, sizeof(iid));
552 hr = IIDFromString(brokenW, &iid);
553 ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
554 ok(iid.Data1 == 0x00000001, "Got %08x\n", iid.Data1);
555
556 memset(&iid, 0xab, sizeof(iid));
557 hr = IIDFromString(broken2W, &iid);
558 ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
559 ok(iid.Data1 == 0x00000001, "Got %08x\n", iid.Data1);
560
561 /* format is broken, but string length is okay */
562 memset(&iid, 0xab, sizeof(iid));
563 hr = IIDFromString(broken3W, &iid);
564 ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
565 ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
566
567 /* invalid string */
568 memset(&iid, 0xab, sizeof(iid));
570 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
571 ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
572
573 /* valid ProgID */
574 memset(&iid, 0xab, sizeof(iid));
575 hr = IIDFromString(stdfont, &iid);
576 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
577 ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
578}
579
580static void test_StringFromGUID2(void)
581{
582 WCHAR str[50];
583 int len;
584
585 /* invalid pointer */
586 SetLastError(0xdeadbeef);
588 ok(len == 0, "len: %d (expected 0)\n", len);
589 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %x\n", GetLastError());
590
591 /* Test corner cases for buffer size */
593 ok(len == 39, "len: %d (expected 39)\n", len);
594 ok(!lstrcmpiW(str, wszCLSID_StdFont),"string wasn't equal for CLSID_StdFont\n");
595
596 memset(str,0,sizeof str);
598 ok(len == 39, "len: %d (expected 39)\n", len);
599 ok(!lstrcmpiW(str, wszCLSID_StdFont),"string wasn't equal for CLSID_StdFont\n");
600
602 ok(len == 0, "len: %d (expected 0)\n", len);
603
605 ok(len == 0, "len: %d (expected 0)\n", len);
606}
607
608#define test_apt_type(t, q) _test_apt_type(t, q, __LINE__)
609static void _test_apt_type(APTTYPE expected_type, APTTYPEQUALIFIER expected_qualifier, int line)
610{
612 APTTYPE type = ~0u;
613 HRESULT hr;
614
615 if (!pCoGetApartmentType)
616 return;
617
618 hr = pCoGetApartmentType(&type, &qualifier);
619 ok_(__FILE__, line)(hr == S_OK || hr == CO_E_NOTINITIALIZED, "Unexpected return code: 0x%08x\n", hr);
620 ok_(__FILE__, line)(type == expected_type, "Wrong apartment type %d, expected %d\n", type, expected_type);
621 ok_(__FILE__, line)(qualifier == expected_qualifier, "Wrong apartment qualifier %d, expected %d\n", qualifier,
622 expected_qualifier);
623}
624
625static void test_CoCreateInstance(void)
626{
627 HRESULT hr;
628 IUnknown *pUnk;
629 REFCLSID rclsid = &CLSID_InternetZoneManager;
630
631 pUnk = (IUnknown *)0xdeadbeef;
632 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
633 ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
634 ok(pUnk == NULL, "CoCreateInstance should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
635
637
638 /* test errors returned for non-registered clsids */
639 hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
640 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
641 hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pUnk);
642 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc handler should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
643 hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_LOCAL_SERVER, &IID_IUnknown, (void **)&pUnk);
644 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered local server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
645 hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_REMOTE_SERVER, &IID_IUnknown, (void **)&pUnk);
646 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered remote server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
647
648 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
650 {
651 skip("IE not installed so can't test CoCreateInstance\n");
653 return;
654 }
655
656 ok_ole_success(hr, "CoCreateInstance");
657 if(pUnk) IUnknown_Release(pUnk);
659
660 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
661 ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
662
663 test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE);
664}
665
666static void test_CoGetClassObject(void)
667{
668 HRESULT hr;
671 IUnknown *pUnk;
672 REFCLSID rclsid = &CLSID_InternetZoneManager;
673 HKEY hkey;
674 LONG res;
675
676 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
677 ok(hr == CO_E_NOTINITIALIZED, "CoGetClassObject should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
678 ok(pUnk == NULL, "CoGetClassObject should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
679
680 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, NULL);
681 ok(hr == E_INVALIDARG ||
682 broken(hr == CO_E_NOTINITIALIZED), /* win9x */
683 "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08x\n", hr);
684
685 test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE);
686
687 if (!pRegOverridePredefKey)
688 {
689 win_skip("RegOverridePredefKey not available\n");
690 return;
691 }
692
693 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
694
695 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
696 if (hr == S_OK)
697 {
698 IUnknown_Release(pUnk);
699
700 res = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Classes", 0, NULL, 0,
701 KEY_ALL_ACCESS, NULL, &hkey, NULL);
702 ok(!res, "RegCreateKeyEx returned %d\n", res);
703
704 res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, hkey);
705 ok(!res, "RegOverridePredefKey returned %d\n", res);
706
707 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
708 ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr);
709
710 res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
711 ok(!res, "RegOverridePredefKey returned %d\n", res);
712
713 if (hr == S_OK) IUnknown_Release(pUnk);
714 RegCloseKey(hkey);
715 }
716
717 hr = CoGetClassObject(&CLSID_InProcFreeMarshaler, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
718 ok(hr == S_OK, "got 0x%08x\n", hr);
719 IUnknown_Release(pUnk);
720
721 /* context redefines FreeMarshaler CLSID */
723 {
724 hr = CoGetClassObject(&CLSID_InProcFreeMarshaler, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
725 ok(hr == S_OK, "got 0x%08x\n", hr);
726 IUnknown_Release(pUnk);
727
728 pDeactivateActCtx(0, cookie);
729 pReleaseActCtx(handle);
730 }
731
733}
734
735static void test_CoCreateInstanceEx(void)
736{
737 MULTI_QI qi_res = { &IID_IMoniker };
739 HRESULT hr;
740
742
744 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie);
745 ok_ole_success(hr, "CoRegisterClassObject");
746
748 hr = CoCreateInstanceEx(&CLSID_WineOOPTest, NULL, CLSCTX_INPROC_SERVER, NULL, 1, &qi_res);
749 ok(hr == E_NOINTERFACE, "CoCreateInstanceEx failed: %08x\n", hr);
750 ok(IsEqualGUID(&create_instance_iid, qi_res.pIID), "Unexpected CreateInstance iid %s\n",
752
754 ok_ole_success(hr, "CoRevokeClassObject");
755
757}
758
760{
761 WNDCLASSA wc =
762 {
763 0,
765 0,
766 0,
768 NULL,
770 (HBRUSH)(COLOR_BTNFACE+1),
771 NULL,
772 "WineOleTestClass",
773 };
774
775 return RegisterClassA(&wc);
776}
777
778static void test_ole_menu(void)
779{
780 HWND hwndFrame;
781 HRESULT hr;
782
784 hr = OleSetMenuDescriptor(NULL, hwndFrame, NULL, NULL, NULL);
785 todo_wine ok_ole_success(hr, "OleSetMenuDescriptor");
786
787 DestroyWindow(hwndFrame);
788}
789
790
792{
793 if (ppvObj == NULL) return E_POINTER;
794
796 IsEqualGUID(riid, &IID_IMessageFilter))
797 {
798 *ppvObj = iface;
799 IMessageFilter_AddRef(iface);
800 return S_OK;
801 }
802
803 return E_NOINTERFACE;
804}
805
807{
808 return 2; /* non-heap object */
809}
810
812{
813 return 1; /* non-heap object */
814}
815
817 IMessageFilter *iface,
818 DWORD dwCallType,
819 HTASK threadIDCaller,
820 DWORD dwTickCount,
821 LPINTERFACEINFO lpInterfaceInfo)
822{
823 trace("HandleInComingCall\n");
824 return SERVERCALL_ISHANDLED;
825}
826
828 IMessageFilter *iface,
829 HTASK threadIDCallee,
830 DWORD dwTickCount,
831 DWORD dwRejectType)
832{
833 trace("RetryRejectedCall\n");
834 return 0;
835}
836
838 IMessageFilter *iface,
839 HTASK threadIDCallee,
840 DWORD dwTickCount,
841 DWORD dwPendingType)
842{
843 trace("MessagePending\n");
845 todo_wine ok(0, "unexpected call\n");
846 return PENDINGMSG_WAITNOPROCESS;
847}
848
849static const IMessageFilterVtbl MessageFilter_Vtbl =
850{
857};
858
860
862{
863 HRESULT hr;
864 IMessageFilter *prev_filter;
865
866 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
868 "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
869 hr);
870
871 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
872 prev_filter = (IMessageFilter *)0xdeadbeef;
873 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
875 "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
876 hr);
877 ok(prev_filter == (IMessageFilter *)0xdeadbeef,
878 "prev_filter should have been set to %p\n", prev_filter);
880
881 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
882
884 ok_ole_success(hr, "CoRegisterMessageFilter");
885
886 prev_filter = (IMessageFilter *)0xdeadbeef;
887 hr = CoRegisterMessageFilter(NULL, &prev_filter);
888 ok_ole_success(hr, "CoRegisterMessageFilter");
889 ok(prev_filter == NULL, "prev_filter should have been set to NULL instead of %p\n", prev_filter);
890
891 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
892 ok_ole_success(hr, "CoRegisterMessageFilter");
893 ok(prev_filter == NULL, "prev_filter should have been set to NULL instead of %p\n", prev_filter);
894
896 ok_ole_success(hr, "CoRegisterMessageFilter");
897
899}
900
902
904{
905 return IUnknown_QueryInterface(&Test_Unknown, riid, ppv);
906}
907
909{
910 return 2;
911}
912
914{
915 return 1;
916}
917
918static HRESULT WINAPI EnumOLEVERB_Next(IEnumOLEVERB *iface, ULONG celt, OLEVERB *rgelt, ULONG *fetched)
919{
920 ok(0, "unexpected call\n");
921 return E_NOTIMPL;
922}
923
925{
926 ok(0, "unexpected call\n");
927 return E_NOTIMPL;
928}
929
931{
932 ok(0, "unexpected call\n");
933 return E_NOTIMPL;
934}
935
937{
938 ok(0, "unexpected call\n");
939 return E_NOTIMPL;
940}
941
942static const IEnumOLEVERBVtbl EnumOLEVERBVtbl = {
950};
951
953
955 IUnknown *iface,
956 REFIID riid,
957 LPVOID *ppvObj)
958{
959 if (ppvObj == NULL) return E_POINTER;
960
962 *ppvObj = iface;
963 }else if(IsEqualIID(riid, &IID_IEnumOLEVERB)) {
964 *ppvObj = &EnumOLEVERB;
965 }else {
966 *ppvObj = NULL;
967 return E_NOINTERFACE;
968 }
969
970 IUnknown_AddRef((IUnknown*)*ppvObj);
971 return S_OK;
972}
973
975{
976 return 2; /* non-heap-based object */
977}
978
980{
981 return 1; /* non-heap-based object */
982}
983
984static const IUnknownVtbl TestUnknown_Vtbl =
985{
989};
990
992
994
997 /* [in] */ REFIID riid,
998 /* [iid_is][out] */ void **ppvObject)
999{
1000 if (IsEqualIID(riid, &IID_IUnknown) ||
1001 IsEqualIID(riid, &IID_IPSFactoryBuffer))
1002 {
1003 *ppvObject = This;
1004 IPSFactoryBuffer_AddRef(This);
1005 return S_OK;
1006 }
1007 return E_NOINTERFACE;
1008}
1009
1012{
1013 return 2;
1014}
1015
1018{
1019 return 1;
1020}
1021
1024 /* [in] */ IUnknown *pUnkOuter,
1025 /* [in] */ REFIID riid,
1026 /* [out] */ IRpcProxyBuffer **ppProxy,
1027 /* [out] */ void **ppv)
1028{
1029 return E_NOTIMPL;
1030}
1031
1034 /* [in] */ REFIID riid,
1035 /* [unique][in] */ IUnknown *pUnkServer,
1036 /* [out] */ IRpcStubBuffer **ppStub)
1037{
1038 CHECK_EXPECT(CreateStub);
1039
1040 ok(pUnkServer == &Test_Unknown, "unexpected pUnkServer %p\n", pUnkServer);
1042 return E_NOTIMPL;
1043
1044 return IPSFactoryBuffer_CreateStub(ps_factory_buffer, &IID_IEnumOLEVERB, pUnkServer, ppStub);
1045}
1046
1047static IPSFactoryBufferVtbl PSFactoryBufferVtbl =
1048{
1054};
1055
1057
1059{
1060 0x52011640,
1061 0x8164,
1062 0x4fd0,
1063 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
1064}; /* 52011640-8164-4fd0-a1a2-5d5a3654d3bd */
1065
1067{
1068 HRESULT hr;
1069 CLSID clsid = {0};
1070
1071 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1072
1074 ok_ole_success(hr, "CoGetPSClsid");
1075 ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1077
1078 /* test registering a PSClsid in an apartment which is then destroyed */
1080 ok_ole_success(hr, "CoRegisterPSClsid");
1081
1083
1084 return hr;
1085}
1086
1087static void test_CoRegisterPSClsid(void)
1088{
1089 HRESULT hr;
1090 DWORD dwRegistrationKey;
1091 IStream *stream;
1092 CLSID clsid;
1093 HANDLE thread;
1094 DWORD tid;
1095
1097 ok(hr == CO_E_NOTINITIALIZED, "CoRegisterPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1098
1099 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1100
1102 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegistrationKey);
1103 ok_ole_success(hr, "CoRegisterClassObject");
1104
1106 ok_ole_success(hr, "CoRegisterPSClsid");
1107
1109 ok_ole_success(hr, "CoGetPSClsid");
1110 ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1112
1114 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1115 ok(!WaitForSingleObject(thread, 10000), "wait timed out\n");
1117
1119 ok_ole_success(hr, "CoGetPSClsid");
1120 ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1122
1124 ok_ole_success(hr, "CreateStreamOnHGlobal");
1125
1126 SET_EXPECT(CreateStub);
1127 hr = CoMarshalInterface(stream, &IID_IWineTest, &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1128 ok(hr == E_NOTIMPL, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1129 CHECK_CALLED(CreateStub, 1);
1130
1132 ok_ole_success(hr, "CoGetPSClsid");
1133
1134 hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void **)&ps_factory_buffer);
1135 ok_ole_success(hr, "CoGetClassObject");
1136
1138 ok_ole_success(hr, "CoRegisterPSClsid");
1139
1140 SET_EXPECT(CreateStub);
1141 hr = CoMarshalInterface(stream, &IID_IEnumOLEVERB, (IUnknown*)&EnumOLEVERB, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1142 ok(hr == S_OK, "CoMarshalInterface should have returned S_OK instead of 0x%08x\n", hr);
1143 CHECK_CALLED(CreateStub, 1);
1144
1145 hr = CoMarshalInterface(stream, &IID_IEnumOLEVERB, &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1146 ok(hr == S_OK, "CoMarshalInterface should have returned S_OK instead of 0x%08x\n", hr);
1147
1148 IStream_Release(stream);
1149 IPSFactoryBuffer_Release(ps_factory_buffer);
1151
1152 hr = CoRevokeClassObject(dwRegistrationKey);
1153 ok_ole_success(hr, "CoRevokeClassObject");
1154
1156
1157 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1158
1160 ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08x\n", hr);
1161
1163 ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08x\n", hr);
1164
1166
1167 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
1168
1170 ok_ole_success(hr, "CoRegisterPSClsid");
1171
1173 ok_ole_success(hr, "CoGetPSClsid");
1174 ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1176
1178 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1179 ok(!WaitForSingleObject(thread, 10000), "wait timed out\n");
1181
1183 ok_ole_success(hr, "CoGetPSClsid");
1184 ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1186
1188}
1189
1190static void test_CoGetPSClsid(void)
1191{
1193 HANDLE handle;
1194 HRESULT hr;
1195 CLSID clsid;
1196 HKEY hkey;
1197 LONG res;
1198 const BOOL is_win64 = (sizeof(void*) != sizeof(int));
1200
1203 "CoGetPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n",
1204 hr);
1205
1206 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1207
1209 ok_ole_success(hr, "CoGetPSClsid");
1210
1213 "CoGetPSClsid for random IID returned 0x%08x instead of REGDB_E_IIDNOTREG\n",
1214 hr);
1215
1217 ok(hr == E_INVALIDARG,
1218 "CoGetPSClsid for null clsid returned 0x%08x instead of E_INVALIDARG\n",
1219 hr);
1220
1221 if (!pRegOverridePredefKey)
1222 {
1223 win_skip("RegOverridePredefKey not available\n");
1225 return;
1226 }
1228 ok_ole_success(hr, "CoGetPSClsid");
1229
1230 res = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Classes", 0, NULL, 0,
1231 KEY_ALL_ACCESS, NULL, &hkey, NULL);
1232 ok(!res, "RegCreateKeyEx returned %d\n", res);
1233
1234 res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, hkey);
1235 ok(!res, "RegOverridePredefKey returned %d\n", res);
1236
1238 ok_ole_success(hr, "CoGetPSClsid");
1239
1240 res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
1241 ok(!res, "RegOverridePredefKey returned %d\n", res);
1242
1243 RegCloseKey(hkey);
1244
1245 /* not registered CLSID */
1247 ok(hr == REGDB_E_IIDNOTREG, "got 0x%08x\n", hr);
1248
1250 {
1251 memset(&clsid, 0, sizeof(clsid));
1253 ok(hr == S_OK, "got 0x%08x\n", hr);
1254 ok(IsEqualGUID(&clsid, &IID_Testiface), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1255
1256 memset(&clsid, 0, sizeof(clsid));
1258 ok(hr == S_OK, "got 0x%08x\n", hr);
1259 ok(IsEqualGUID(&clsid, &IID_Testiface2), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1260
1261 memset(&clsid, 0, sizeof(clsid));
1263 ok(hr == S_OK, "got 0x%08x\n", hr);
1264 ok(IsEqualGUID(&clsid, &IID_TestPS), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1265
1266 memset(&clsid, 0xaa, sizeof(clsid));
1268 ok(hr == S_OK, "got 0x%08x\n", hr);
1269 ok(IsEqualGUID(&clsid, &GUID_NULL), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1270
1271 /* register same interface and try to get CLSID back */
1273 ok(hr == S_OK, "got 0x%08x\n", hr);
1274 memset(&clsid, 0, sizeof(clsid));
1276 ok(hr == S_OK, "got 0x%08x\n", hr);
1277 ok(IsEqualGUID(&clsid, &IID_Testiface4), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1278
1279 pDeactivateActCtx(0, cookie);
1280 pReleaseActCtx(handle);
1281 }
1282
1283 if (pRegDeleteKeyExA &&
1284 (is_win64 ||
1285 (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)))
1286 {
1287 static GUID IID_DeadBeef = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
1288 static const char clsidDeadBeef[] = "{deadbeef-dead-beef-dead-beefdeadbeef}";
1289 static const char clsidA[] = "{66666666-8888-7777-6666-555555555555}";
1290 HKEY hkey_iface, hkey_psclsid;
1292
1293 hr = CoGetPSClsid(&IID_DeadBeef, &clsid);
1294 ok(hr == REGDB_E_IIDNOTREG, "got 0x%08x\n", hr);
1295
1296 res = RegCreateKeyExA(HKEY_CLASSES_ROOT, "Interface",
1297 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey_iface, NULL);
1298 ok(!res, "RegCreateKeyEx returned %d\n", res);
1299 res = RegCreateKeyExA(hkey_iface, clsidDeadBeef,
1300 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey, NULL);
1301 if (res == ERROR_ACCESS_DENIED)
1302 {
1303 win_skip("Failed to create a key, skipping some of CoGetPSClsid() tests\n");
1304 goto cleanup;
1305 }
1306
1307 ok(!res, "RegCreateKeyEx returned %d\n", res);
1308 res = RegCreateKeyExA(hkey, "ProxyStubClsid32",
1309 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey_psclsid, NULL);
1310 ok(!res, "RegCreateKeyEx returned %d\n", res);
1311 res = RegSetValueExA(hkey_psclsid, NULL, 0, REG_SZ, (const BYTE *)clsidA, strlen(clsidA)+1);
1312 ok(!res, "RegSetValueEx returned %d\n", res);
1313 RegCloseKey(hkey_psclsid);
1314
1315 hr = CoGetPSClsid(&IID_DeadBeef, &clsid);
1316 ok_ole_success(hr, "CoGetPSClsid");
1317 ok(IsEqualGUID(&clsid, &IID_TestPS), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1318
1319 res = pRegDeleteKeyExA(hkey, "ProxyStubClsid32", opposite, 0);
1320 ok(!res, "RegDeleteKeyEx returned %d\n", res);
1321 RegCloseKey(hkey);
1322 res = pRegDeleteKeyExA(hkey_iface, clsidDeadBeef, opposite, 0);
1323 ok(!res, "RegDeleteKeyEx returned %d\n", res);
1324
1325 cleanup:
1326 RegCloseKey(hkey_iface);
1327 }
1328
1330}
1331
1332/* basic test, mainly for invalid arguments. see marshal.c for more */
1334{
1335 IUnknown *pProxy;
1336 IStream *pStream;
1337 HRESULT hr;
1338
1339 hr = CoUnmarshalInterface(NULL, &IID_IUnknown, (void **)&pProxy);
1340 ok(hr == E_INVALIDARG, "CoUnmarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1341
1342 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1343 ok_ole_success(hr, "CreateStreamOnHGlobal");
1344
1345 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
1346 todo_wine
1347 ok(hr == CO_E_NOTINITIALIZED, "CoUnmarshalInterface should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1348
1349 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1350
1351 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
1352 ok(hr == STG_E_READFAULT, "CoUnmarshalInterface should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1353
1355
1357 ok(hr == E_INVALIDARG, "CoUnmarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1358
1359 IStream_Release(pStream);
1360}
1361
1363{
1364 HRESULT hr;
1365 IUnknown *pUnk;
1366
1367 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1368
1370 ok(hr == E_INVALIDARG, "hr %08x\n", hr);
1371
1373}
1374
1375/* basic test, mainly for invalid arguments. see marshal.c for more */
1377{
1378 IStream *pStream;
1379 HRESULT hr;
1380 static const LARGE_INTEGER llZero;
1381
1382 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1383
1384 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1385 ok_ole_success(hr, "CreateStreamOnHGlobal");
1386
1387 hr = CoMarshalInterface(pStream, &IID_IUnknown, NULL, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1388 ok(hr == E_INVALIDARG, "CoMarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1389
1390 hr = CoMarshalInterface(NULL, &IID_IUnknown, (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1391 ok(hr == E_INVALIDARG, "CoMarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1392
1393 hr = CoMarshalInterface(pStream, &IID_IUnknown, (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1394 ok_ole_success(hr, "CoMarshalInterface");
1395
1396 /* stream not rewound */
1397 hr = CoReleaseMarshalData(pStream);
1398 ok(hr == STG_E_READFAULT, "CoReleaseMarshalData should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1399
1400 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1401 ok_ole_success(hr, "IStream_Seek");
1402
1403 hr = CoReleaseMarshalData(pStream);
1404 ok_ole_success(hr, "CoReleaseMarshalData");
1405
1406 IStream_Release(pStream);
1407
1409}
1410
1412{
1413 IStream *pStream;
1414 HRESULT hr;
1415 IClassFactory *pProxy;
1416
1417 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1418
1419 cLocks = 0;
1420
1422 ok(hr == E_INVALIDARG, "CoMarshalInterThreadInterfaceInStream should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1423
1425 ok(hr == E_INVALIDARG, "CoMarshalInterThreadInterfaceInStream should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1426
1427 ok_no_locks();
1428
1430 ok_ole_success(hr, "CoMarshalInterThreadInterfaceInStream");
1431
1433
1434 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1435 ok_ole_success(hr, "CoUnmarshalInterface");
1436
1437 IClassFactory_Release(pProxy);
1438 IStream_Release(pStream);
1439
1440 ok_no_locks();
1441
1443}
1444
1446{
1447 ULONG_PTR ctxcookie;
1448 HANDLE handle;
1449 DWORD cookie;
1450 HRESULT hr;
1451 IClassFactory *pcf;
1452
1453 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1454
1455 /* CLSCTX_INPROC_SERVER */
1457 CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1458 ok_ole_success(hr, "CoRegisterClassObject");
1460 ok_ole_success(hr, "CoRevokeClassObject");
1461
1463 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1464 ok_ole_success(hr, "CoRegisterClassObject");
1466 ok_ole_success(hr, "CoRevokeClassObject");
1467
1469 CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &cookie);
1470 ok_ole_success(hr, "CoRegisterClassObject");
1472 ok_ole_success(hr, "CoRevokeClassObject");
1473
1474 /* CLSCTX_LOCAL_SERVER */
1476 CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1477 ok_ole_success(hr, "CoRegisterClassObject");
1479 ok_ole_success(hr, "CoRevokeClassObject");
1480
1482 CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1483 ok_ole_success(hr, "CoRegisterClassObject");
1485 ok_ole_success(hr, "CoRevokeClassObject");
1486
1488 CLSCTX_LOCAL_SERVER, REGCLS_MULTI_SEPARATE, &cookie);
1489 ok_ole_success(hr, "CoRegisterClassObject");
1491 ok_ole_success(hr, "CoRevokeClassObject");
1492
1493 /* CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER */
1495 CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1496 ok_ole_success(hr, "CoRegisterClassObject");
1498 ok_ole_success(hr, "CoRevokeClassObject");
1499
1500 /* test whether an object that doesn't support IClassFactory can be
1501 * registered for CLSCTX_LOCAL_SERVER */
1503 CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1504 ok_ole_success(hr, "CoRegisterClassObject");
1506 ok_ole_success(hr, "CoRevokeClassObject");
1507
1508 /* test whether registered class becomes invalid when apartment is destroyed */
1510 CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1511 ok_ole_success(hr, "CoRegisterClassObject");
1512
1514 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1515
1516 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL,
1517 &IID_IClassFactory, (void **)&pcf);
1518 ok(hr == REGDB_E_CLASSNOTREG, "object registered in an apartment shouldn't accessible after it is destroyed\n");
1519
1520 /* crashes with at least win9x DCOM! */
1521 if (0)
1523
1524 /* test that object is accessible */
1527 ok(hr == S_OK, "got 0x%08x\n", hr);
1528
1529 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1530 ok(hr == S_OK, "got 0x%08x\n", hr);
1531 IClassFactory_Release(pcf);
1532
1533 /* context now contains CLSID_WineOOPTest, test if registered one could still be used */
1534 if ((handle = activate_context(actctx_manifest, &ctxcookie)))
1535 {
1536 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1538 ok(hr == HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND), "got 0x%08x\n", hr);
1539
1540 pDeactivateActCtx(0, ctxcookie);
1541 pReleaseActCtx(handle);
1542 }
1543
1544 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1545 ok(hr == S_OK, "got 0x%08x\n", hr);
1546 IClassFactory_Release(pcf);
1547
1549 ok(hr == S_OK, "got 0x%08x\n", hr);
1550
1552}
1553
1554static HRESULT get_class_object(CLSCTX clsctx)
1555{
1556 HRESULT hr;
1557 IClassFactory *pcf;
1558
1560 (void **)&pcf);
1561
1562 if (SUCCEEDED(hr))
1563 IClassFactory_Release(pcf);
1564
1565 return hr;
1566}
1567
1569{
1570 CLSCTX clsctx = (CLSCTX)(DWORD_PTR)pv;
1571 HRESULT hr;
1572
1573 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1574
1575 hr = get_class_object(clsctx);
1576
1578
1579 return hr;
1580}
1581
1583{
1584 CLSCTX clsctx = (CLSCTX)(DWORD_PTR)pv;
1585 HRESULT hr;
1586 IClassFactory *pcf;
1587 IMultiQI *pMQI;
1588
1589 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1590
1592 (void **)&pcf);
1593
1594 if (SUCCEEDED(hr))
1595 {
1596 hr = IClassFactory_QueryInterface(pcf, &IID_IMultiQI, (void **)&pMQI);
1597 if (SUCCEEDED(hr))
1598 IMultiQI_Release(pMQI);
1599 IClassFactory_Release(pcf);
1600 }
1601
1603
1604 return hr;
1605}
1606
1608{
1609 HRESULT hr;
1610 DWORD cookie;
1611
1612 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1613
1615 CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1616
1618
1619 return hr;
1620}
1621
1623{
1624 DWORD cookie = (DWORD_PTR)pv;
1625 HRESULT hr;
1626
1627 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1628
1630
1632
1633 return hr;
1634}
1635
1637{
1638 HRESULT hr;
1639 DWORD cookie;
1640 HANDLE thread;
1641 DWORD tid;
1642 DWORD exitcode;
1643
1644 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1645
1646 /* CLSCTX_INPROC_SERVER */
1647
1649 CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1650 ok_ole_success(hr, "CoRegisterClassObject");
1651
1652 thread = CreateThread(NULL, 0, get_class_object_thread, (LPVOID)CLSCTX_INPROC_SERVER, 0, &tid);
1653 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1654 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1655 GetExitCodeThread(thread, &exitcode);
1656 hr = exitcode;
1657 ok(hr == REGDB_E_CLASSNOTREG, "CoGetClassObject on inproc object "
1658 "registered in different thread should return REGDB_E_CLASSNOTREG "
1659 "instead of 0x%08x\n", hr);
1660
1661 hr = get_class_object(CLSCTX_INPROC_SERVER);
1662 ok(hr == S_OK, "CoGetClassObject on inproc object registered in same "
1663 "thread should return S_OK instead of 0x%08x\n", hr);
1664
1666 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1667 ok ( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1668 GetExitCodeThread(thread, &exitcode);
1669 hr = exitcode;
1670 ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different thread should return S_OK instead of 0x%08x\n", hr);
1671
1673 ok_ole_success(hr, "CoRevokeClassObject");
1674
1675 /* CLSCTX_LOCAL_SERVER */
1676
1678 CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1679 ok_ole_success(hr, "CoRegisterClassObject");
1680
1681 thread = CreateThread(NULL, 0, get_class_object_proxy_thread, (LPVOID)CLSCTX_LOCAL_SERVER, 0, &tid);
1682 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1684 {
1685 MSG msg;
1686 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
1687 {
1690 }
1691 }
1692 GetExitCodeThread(thread, &exitcode);
1693 hr = exitcode;
1694 ok(hr == S_OK, "CoGetClassObject on local server object "
1695 "registered in different thread should return S_OK "
1696 "instead of 0x%08x\n", hr);
1697
1698 hr = get_class_object(CLSCTX_LOCAL_SERVER);
1699 ok(hr == S_OK, "CoGetClassObject on local server object registered in same "
1700 "thread should return S_OK instead of 0x%08x\n", hr);
1701
1703 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1704 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1705 GetExitCodeThread(thread, &exitcode);
1706 hr = exitcode;
1707 ok(hr == RPC_E_WRONG_THREAD || broken(hr == S_OK) /* win8 */, "CoRevokeClassObject called from different "
1708 "thread to where registered should return RPC_E_WRONG_THREAD instead of 0x%08x\n", hr);
1709
1711 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1712 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1713 GetExitCodeThread(thread, &exitcode);
1714 hr = exitcode;
1715 ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different "
1716 "thread should return S_OK instead of 0x%08x\n", hr);
1717
1719 ok_ole_success(hr, "CoRevokeClassObject");
1720
1722}
1723
1725{
1727 return 0;
1728}
1729
1730static inline BOOL is_module_loaded(const char *module)
1731{
1732 return GetModuleHandleA(module) != 0;
1733}
1734
1736{
1737 HRESULT hr;
1738 IUnknown *pUnk;
1739 DWORD tid;
1740 HANDLE thread;
1741
1742 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1743
1744 ok(!is_module_loaded("urlmon.dll"), "urlmon.dll shouldn't be loaded\n");
1745
1746 hr = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pUnk);
1747 if (hr == REGDB_E_CLASSNOTREG)
1748 {
1749 skip("IE not installed so can't run CoFreeUnusedLibraries test\n");
1751 return;
1752 }
1753 ok_ole_success(hr, "CoCreateInstance");
1754
1755 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1756
1757 ok(pUnk != NULL ||
1758 broken(pUnk == NULL), /* win9x */
1759 "Expected a valid pointer\n");
1760 if (pUnk)
1761 IUnknown_Release(pUnk);
1762
1763 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1764
1766 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1768
1769 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1770
1772
1773 ok(!is_module_loaded("urlmon.dll"), "urlmon.dll shouldn't be loaded\n");
1774
1776}
1777
1779{
1780 HRESULT hr;
1781 ULONG refs;
1782 IComThreadingInfo *pComThreadingInfo, *threadinginfo2;
1783 IContextCallback *pContextCallback;
1784 IObjContext *pObjContext;
1785 APTTYPE apttype;
1786 THDTYPE thdtype;
1787 GUID id, id2;
1788
1789 if (!pCoGetObjectContext)
1790 {
1791 win_skip("CoGetObjectContext not present\n");
1792 return;
1793 }
1794
1795 hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1796 ok(hr == CO_E_NOTINITIALIZED, "CoGetObjectContext should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1797 ok(pComThreadingInfo == NULL, "pComThreadingInfo should have been set to NULL\n");
1798
1799 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1800
1802
1803 hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1804 ok_ole_success(hr, "CoGetObjectContext");
1805
1806 threadinginfo2 = NULL;
1807 hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&threadinginfo2);
1808 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
1809 ok(pComThreadingInfo == threadinginfo2, "got different instance\n");
1810 IComThreadingInfo_Release(threadinginfo2);
1811
1812 hr = IComThreadingInfo_GetCurrentLogicalThreadId(pComThreadingInfo, NULL);
1813 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1814
1815 id = id2 = GUID_NULL;
1816 hr = IComThreadingInfo_GetCurrentLogicalThreadId(pComThreadingInfo, &id);
1817 ok(hr == S_OK, "got 0x%08x\n", hr);
1818
1820 ok(IsEqualGUID(&id, &id2), "got %s, expected %s\n", wine_dbgstr_guid(&id), wine_dbgstr_guid(&id2));
1821
1822 hr = IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo, &apttype);
1823 ok_ole_success(hr, "IComThreadingInfo_GetCurrentApartmentType");
1824 ok(apttype == APTTYPE_MAINSTA, "apartment type should be APTTYPE_MAINSTA instead of %d\n", apttype);
1825
1826 hr = IComThreadingInfo_GetCurrentThreadType(pComThreadingInfo, &thdtype);
1827 ok_ole_success(hr, "IComThreadingInfo_GetCurrentThreadType");
1828 ok(thdtype == THDTYPE_PROCESSMESSAGES, "thread type should be THDTYPE_PROCESSMESSAGES instead of %d\n", thdtype);
1829
1830 refs = IComThreadingInfo_Release(pComThreadingInfo);
1831 ok(refs == 0, "pComThreadingInfo should have 0 refs instead of %d refs\n", refs);
1832
1833 hr = pCoGetObjectContext(&IID_IContextCallback, (void **)&pContextCallback);
1834 ok_ole_success(hr, "CoGetObjectContext(ContextCallback)");
1835
1836 refs = IContextCallback_Release(pContextCallback);
1837 ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs);
1838
1840
1841 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
1842
1843 hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1844 ok_ole_success(hr, "CoGetObjectContext");
1845
1846 hr = IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo, &apttype);
1847 ok_ole_success(hr, "IComThreadingInfo_GetCurrentApartmentType");
1848 ok(apttype == APTTYPE_MTA, "apartment type should be APTTYPE_MTA instead of %d\n", apttype);
1849
1850 hr = IComThreadingInfo_GetCurrentThreadType(pComThreadingInfo, &thdtype);
1851 ok_ole_success(hr, "IComThreadingInfo_GetCurrentThreadType");
1852 ok(thdtype == THDTYPE_BLOCKMESSAGES, "thread type should be THDTYPE_BLOCKMESSAGES instead of %d\n", thdtype);
1853
1854 refs = IComThreadingInfo_Release(pComThreadingInfo);
1855 ok(refs == 0, "pComThreadingInfo should have 0 refs instead of %d refs\n", refs);
1856
1857 hr = pCoGetObjectContext(&IID_IContextCallback, (void **)&pContextCallback);
1858 ok_ole_success(hr, "CoGetObjectContext(ContextCallback)");
1859
1860 refs = IContextCallback_Release(pContextCallback);
1861 ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs);
1862
1863 hr = pCoGetObjectContext(&IID_IObjContext, (void **)&pObjContext);
1864 ok_ole_success(hr, "CoGetObjectContext");
1865
1866 refs = IObjContext_Release(pObjContext);
1867 ok(refs == 0, "pObjContext should have 0 refs instead of %d refs\n", refs);
1868
1870}
1871
1872typedef struct {
1876
1878{
1879 return CONTAINING_RECORD(iface, Test_CallContext, IUnknown_iface);
1880}
1881
1883 IUnknown *iface,
1884 REFIID riid,
1885 LPVOID *ppvObj)
1886{
1887 if (ppvObj == NULL) return E_POINTER;
1888
1890 {
1891 *ppvObj = iface;
1892 IUnknown_AddRef(iface);
1893 return S_OK;
1894 }
1895
1896 *ppvObj = NULL;
1897 return E_NOINTERFACE;
1898}
1899
1901{
1903 return InterlockedIncrement(&This->refs);
1904}
1905
1907{
1909 ULONG refs = InterlockedDecrement(&This->refs);
1910 if (!refs)
1912 return refs;
1913}
1914
1915static const IUnknownVtbl TestCallContext_Vtbl =
1916{
1920};
1921
1922static void test_CoGetCallContext(void)
1923{
1924 HRESULT hr;
1925 ULONG refs;
1926 IUnknown *pUnk;
1928
1929 if (!pCoSwitchCallContext)
1930 {
1931 skip("CoSwitchCallContext not present\n");
1932 return;
1933 }
1934
1936
1938 test_object->IUnknown_iface.lpVtbl = &TestCallContext_Vtbl;
1939 test_object->refs = 1;
1940
1941 hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1942 ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr);
1943
1944 pUnk = (IUnknown*)0xdeadbeef;
1945 hr = pCoSwitchCallContext(&test_object->IUnknown_iface, &pUnk);
1946 ok_ole_success(hr, "CoSwitchCallContext");
1947 ok(pUnk == NULL, "expected NULL, got %p\n", pUnk);
1948 refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1949 ok(refs == 2, "Expected refcount 2, got %d\n", refs);
1950 IUnknown_Release(&test_object->IUnknown_iface);
1951
1952 pUnk = (IUnknown*)0xdeadbeef;
1953 hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1954 ok_ole_success(hr, "CoGetCallContext");
1955 ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n",
1956 &test_object->IUnknown_iface, pUnk);
1957 refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1958 ok(refs == 3, "Expected refcount 3, got %d\n", refs);
1959 IUnknown_Release(&test_object->IUnknown_iface);
1960 IUnknown_Release(pUnk);
1961
1962 pUnk = (IUnknown*)0xdeadbeef;
1963 hr = pCoSwitchCallContext(NULL, &pUnk);
1964 ok_ole_success(hr, "CoSwitchCallContext");
1965 ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n",
1966 &test_object->IUnknown_iface, pUnk);
1967 refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1968 ok(refs == 2, "Expected refcount 2, got %d\n", refs);
1969 IUnknown_Release(&test_object->IUnknown_iface);
1970
1971 hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1972 ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr);
1973
1974 IUnknown_Release(&test_object->IUnknown_iface);
1975
1977}
1978
1979static void test_CoGetContextToken(void)
1980{
1981 HRESULT hr;
1982 ULONG refs;
1983 ULONG_PTR token, token2;
1985
1986 if (!pCoGetContextToken)
1987 {
1988 win_skip("CoGetContextToken not present\n");
1989 return;
1990 }
1991
1992 token = 0xdeadbeef;
1993 hr = pCoGetContextToken(&token);
1994 ok(hr == CO_E_NOTINITIALIZED, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr);
1995 ok(token == 0xdeadbeef, "Expected 0, got 0x%lx\n", token);
1996
1997 test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE);
1998
2000
2002
2003 hr = pCoGetContextToken(NULL);
2004 ok(hr == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hr);
2005
2006 token = 0;
2007 hr = pCoGetContextToken(&token);
2008 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
2009 ok(token, "Expected token != 0\n");
2010
2011 token2 = 0;
2012 hr = pCoGetContextToken(&token2);
2013 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
2014 ok(token2 == token, "got different token\n");
2015
2016 refs = IUnknown_AddRef((IUnknown *)token);
2017 ok(refs == 1, "Expected 1, got %u\n", refs);
2018
2019 hr = pCoGetObjectContext(&IID_IObjContext, (void **)&ctx);
2020 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
2021 ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n");
2022
2023 refs = IObjContext_AddRef(ctx);
2024 ok(refs == 3, "Expected 3, got %u\n", refs);
2025
2026 refs = IObjContext_Release(ctx);
2027 ok(refs == 2, "Expected 2, got %u\n", refs);
2028
2029 refs = IUnknown_Release((IUnknown *)token);
2030 ok(refs == 1, "Expected 1, got %u\n", refs);
2031
2032 /* CoGetContextToken does not add a reference */
2033 token = 0;
2034 hr = pCoGetContextToken(&token);
2035 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
2036 ok(token, "Expected token != 0\n");
2037 ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n");
2038
2039 refs = IObjContext_AddRef(ctx);
2040 ok(refs == 2, "Expected 1, got %u\n", refs);
2041
2042 refs = IObjContext_Release(ctx);
2043 ok(refs == 1, "Expected 0, got %u\n", refs);
2044
2045 refs = IObjContext_Release(ctx);
2046 ok(refs == 0, "Expected 0, got %u\n", refs);
2047
2049}
2050
2051static void test_TreatAsClass(void)
2052{
2053 HRESULT hr;
2054 CLSID out;
2055 static GUID deadbeef = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
2056 static const char deadbeefA[] = "{DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF}";
2057 IInternetProtocol *pIP = NULL;
2058 HKEY clsidkey, deadbeefkey;
2059 LONG lr;
2060
2061 if (!pCoGetTreatAsClass)
2062 {
2063 win_skip("CoGetTreatAsClass not present\n");
2064 return;
2065 }
2066
2067 hr = pCoGetTreatAsClass(&deadbeef,&out);
2068 ok (hr == S_FALSE, "expected S_FALSE got %x\n",hr);
2069 ok (IsEqualGUID(&out,&deadbeef), "expected to get same clsid back\n");
2070
2071 hr = pCoGetTreatAsClass(NULL, &out);
2072 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr);
2073 ok(IsEqualGUID(&out, &deadbeef), "expected no change to the clsid\n");
2074
2075 hr = pCoGetTreatAsClass(&deadbeef, NULL);
2076 ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr);
2077
2078 lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &clsidkey);
2079 ok(!lr, "Couldn't open CLSID key, error %d\n", lr);
2080
2081 lr = RegCreateKeyExA(clsidkey, deadbeefA, 0, NULL, 0, KEY_WRITE, NULL, &deadbeefkey, NULL);
2082 if (lr) {
2083 win_skip("CoGetTreatAsClass() tests will be skipped (failed to create a test key, error %d)\n", lr);
2084 RegCloseKey(clsidkey);
2085 return;
2086 }
2087
2088 hr = pCoTreatAsClass(&deadbeef, &deadbeef);
2089 ok(hr == REGDB_E_WRITEREGDB, "CoTreatAsClass gave wrong error: %08x\n", hr);
2090
2091 hr = pCoTreatAsClass(&deadbeef, &CLSID_FileProtocol);
2092 if(hr == REGDB_E_WRITEREGDB){
2093 win_skip("Insufficient privileges to use CoTreatAsClass\n");
2094 goto exit;
2095 }
2096 ok(hr == S_OK, "CoTreatAsClass failed: %08x\n", hr);
2097
2098 hr = pCoGetTreatAsClass(&deadbeef, &out);
2099 ok(hr == S_OK, "CoGetTreatAsClass failed: %08x\n",hr);
2100 ok(IsEqualGUID(&out, &CLSID_FileProtocol), "expected to get substituted clsid\n");
2101
2103
2104 hr = CoCreateInstance(&deadbeef, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pIP);
2105 if(hr == REGDB_E_CLASSNOTREG)
2106 {
2107 win_skip("IE not installed so can't test CoCreateInstance\n");
2108 goto exit;
2109 }
2110
2111 ok(hr == S_OK, "CoCreateInstance failed: %08x\n", hr);
2112 if(pIP){
2113 IInternetProtocol_Release(pIP);
2114 pIP = NULL;
2115 }
2116
2117 hr = pCoTreatAsClass(&deadbeef, &CLSID_NULL);
2118 ok(hr == S_OK, "CoTreatAsClass failed: %08x\n", hr);
2119
2120 hr = pCoGetTreatAsClass(&deadbeef, &out);
2121 ok(hr == S_FALSE, "expected S_FALSE got %08x\n", hr);
2122 ok(IsEqualGUID(&out, &deadbeef), "expected to get same clsid back\n");
2123
2124 /* bizarrely, native's CoTreatAsClass takes some time to take effect in CoCreateInstance */
2125 Sleep(200);
2126
2127 hr = CoCreateInstance(&deadbeef, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pIP);
2128 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance gave wrong error: %08x\n", hr);
2129
2130 if(pIP)
2131 IInternetProtocol_Release(pIP);
2132
2133exit:
2135 RegCloseKey(deadbeefkey);
2136 RegDeleteKeyA(clsidkey, deadbeefA);
2137 RegCloseKey(clsidkey);
2138}
2139
2140static void test_CoInitializeEx(void)
2141{
2142 HRESULT hr;
2143
2144 hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2145 ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
2146
2147 /* Calling OleInitialize for the first time should yield S_OK even with
2148 * apartment already initialized by previous CoInitialize(Ex) calls. */
2150 ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
2151
2152 /* Subsequent calls to OleInitialize should return S_FALSE */
2154 ok(hr == S_FALSE, "Expected S_FALSE, hr = 0x%08x\n", hr);
2155
2156 /* Cleanup */
2160}
2161
2163{
2164 HRESULT hr;
2165 IUnknown *pUnk;
2166 REFCLSID rclsid = &CLSID_InternetZoneManager;
2167
2168 /* 1. OleInitialize fails but OleUninitialize is still called: apartment stays initialized */
2169 hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED);
2170 ok(hr == S_OK, "CoInitializeEx(COINIT_MULTITHREADED) failed with error 0x%08x\n", hr);
2171
2173 ok(hr == RPC_E_CHANGED_MODE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", RPC_E_CHANGED_MODE, hr);
2175
2176 pUnk = (IUnknown *)0xdeadbeef;
2177 hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
2178 ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
2179 if (pUnk) IUnknown_Release(pUnk);
2180
2182
2183 /* 2. Extra multiple OleUninitialize: apartment stays initialized until CoUninitialize */
2184 hr = CoInitialize(NULL);
2185 ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr);
2186
2188 ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
2192
2193 pUnk = (IUnknown *)0xdeadbeef;
2194 hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
2195 ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
2196 if (pUnk) IUnknown_Release(pUnk);
2197
2199
2200 pUnk = (IUnknown *)0xdeadbeef;
2201 hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
2202 ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr);
2203 if (pUnk) IUnknown_Release(pUnk);
2204
2205 /* 3. CoUninitialize does not formally deinit Ole */
2206 hr = CoInitialize(NULL);
2207 ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr);
2208
2210 ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
2211
2214
2215 pUnk = (IUnknown *)0xdeadbeef;
2216 hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
2217 ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr);
2218 /* COM is not initialized anymore */
2219 if (pUnk) IUnknown_Release(pUnk);
2220
2222 ok(hr == S_FALSE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_FALSE, hr);
2223 /* ... but native OleInit returns S_FALSE as if Ole is considered initialized */
2224
2226
2227}
2228
2230{
2232 HANDLE handle;
2233 DWORD status;
2234 HRESULT hr;
2235
2236 hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, NULL);
2237 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2238
2239 status = 0xdeadbeef;
2240 hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, &status);
2241 ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
2242 ok(status == 0, "got 0x%08x\n", status);
2243
2244 status = -1;
2245 hr = OleRegGetMiscStatus(&CLSID_StdFont, DVASPECT_ICON, &status);
2246 ok(hr == S_OK, "got 0x%08x\n", hr);
2247 ok(status == 0, "got 0x%08x\n", status);
2248
2250 {
2251 status = 0;
2252 hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, &status);
2253 ok(hr == S_OK, "got 0x%08x\n", hr);
2254 ok(status == OLEMISC_RECOMPOSEONRESIZE, "got 0x%08x\n", status);
2255
2256 /* context data takes precedence over registration info */
2257 status = 0;
2258 hr = OleRegGetMiscStatus(&CLSID_StdFont, DVASPECT_ICON, &status);
2259 ok(hr == S_OK, "got 0x%08x\n", hr);
2260 ok(status == OLEMISC_RECOMPOSEONRESIZE, "got 0x%08x\n", status);
2261
2262 /* there's no such attribute in context */
2263 status = -1;
2264 hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_DOCPRINT, &status);
2265 ok(hr == S_OK, "got 0x%08x\n", hr);
2266 ok(status == 0, "got 0x%08x\n", status);
2267
2268 pDeactivateActCtx(0, cookie);
2269 pReleaseActCtx(handle);
2270 }
2271}
2272
2273static void test_OleRegGetUserType(void)
2274{
2275 static const WCHAR stdfont_usertypeW[] = {'S','t','a','n','d','a','r','d',' ','F','o','n','t',0};
2276 static const WCHAR stdfont2_usertypeW[] = {'C','L','S','I','D','_','S','t','d','F','o','n','t',0};
2277 static const WCHAR clsidkeyW[] = {'C','L','S','I','D',0};
2278 static const WCHAR defvalueW[] = {'D','e','f','a','u','l','t',' ','N','a','m','e',0};
2279 static const WCHAR auxvalue0W[] = {'A','u','x',' ','N','a','m','e',' ','0',0};
2280 static const WCHAR auxvalue2W[] = {'A','u','x',' ','N','a','m','e',' ','2',0};
2281 static const WCHAR auxvalue3W[] = {'A','u','x',' ','N','a','m','e',' ','3',0};
2282 static const WCHAR auxvalue4W[] = {'A','u','x',' ','N','a','m','e',' ','4',0};
2283
2284 static const char auxvalues[][16] = {
2285 "Aux Name 0",
2286 "Aux Name 1",
2287 "Aux Name 2",
2288 "Aux Name 3",
2289 "Aux Name 4"
2290 };
2291
2292 HKEY clsidhkey, hkey, auxhkey, classkey;
2293 DWORD form, ret, disposition;
2294 WCHAR clsidW[39];
2296 HANDLE handle;
2297 HRESULT hr;
2298 WCHAR *str;
2299 int i;
2300
2301 for (form = 0; form <= USERCLASSTYPE_APPNAME+1; form++) {
2302 hr = OleRegGetUserType(&CLSID_Testclass, form, NULL);
2303 ok(hr == E_INVALIDARG, "form %u: got 0x%08x\n", form, hr);
2304
2305 str = (void*)0xdeadbeef;
2306 hr = OleRegGetUserType(&CLSID_Testclass, form, &str);
2307 ok(hr == REGDB_E_CLASSNOTREG, "form %u: got 0x%08x\n", form, hr);
2308 ok(str == NULL, "form %u: got %p\n", form, str);
2309
2310 /* same string returned for StdFont for all form types */
2311 str = NULL;
2313 ok(hr == S_OK, "form %u: got 0x%08x\n", form, hr);
2314 ok(!lstrcmpW(str, stdfont_usertypeW) || !lstrcmpW(str, stdfont2_usertypeW) /* winxp */,
2315 "form %u, got %s\n", form, wine_dbgstr_w(str));
2317 }
2318
2320 {
2321 for (form = 0; form <= USERCLASSTYPE_APPNAME+1; form++) {
2322 str = (void*)0xdeadbeef;
2323 hr = OleRegGetUserType(&CLSID_Testclass, form, &str);
2324 ok(hr == REGDB_E_CLASSNOTREG, "form %u: got 0x%08x\n", form, hr);
2325 ok(str == NULL, "form %u: got %s\n", form, wine_dbgstr_w(str));
2326
2327 /* same string returned for StdFont for all form types */
2328 str = NULL;
2330 ok(hr == S_OK, "form %u: got 0x%08x\n", form, hr);
2331 ok(!lstrcmpW(str, stdfont_usertypeW) || !lstrcmpW(str, stdfont2_usertypeW) /* winxp */,
2332 "form %u, got %s\n", form, wine_dbgstr_w(str));
2334 }
2335
2336 pDeactivateActCtx(0, cookie);
2337 pReleaseActCtx(handle);
2338 }
2339
2340 /* test using registered CLSID */
2342
2343 ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsidkeyW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &clsidhkey, &disposition);
2344 if (!ret)
2345 {
2346 ret = RegCreateKeyExW(clsidhkey, clsidW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &classkey, NULL);
2347 if (ret)
2348 RegCloseKey(clsidhkey);
2349 }
2350
2351 if (ret == ERROR_ACCESS_DENIED)
2352 {
2353 win_skip("Failed to create test key, skipping some of OleRegGetUserType() tests.\n");
2354 return;
2355 }
2356
2357 ok(!ret, "failed to create a key, error %d\n", ret);
2358
2359 ret = RegSetValueExW(classkey, NULL, 0, REG_SZ, (const BYTE*)defvalueW, sizeof(defvalueW));
2360 ok(!ret, "got error %d\n", ret);
2361
2362 ret = RegCreateKeyExA(classkey, "AuxUserType", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &auxhkey, NULL);
2363 ok(!ret, "got error %d\n", ret);
2364
2365 /* populate AuxUserType */
2366 for (i = 0; i <= 4; i++) {
2367 char name[16];
2368
2369 sprintf(name, "AuxUserType\\%d", i);
2370 ret = RegCreateKeyExA(classkey, name, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
2371 ok(!ret, "got error %d\n", ret);
2372
2373 ret = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE*)auxvalues[i], strlen(auxvalues[i]));
2374 ok(!ret, "got error %d\n", ret);
2375 RegCloseKey(hkey);
2376 }
2377
2378 str = NULL;
2380 ok(hr == S_OK, "got 0x%08x\n", hr);
2381 ok(!lstrcmpW(str, auxvalue0W), "got %s\n", wine_dbgstr_w(str));
2383
2384 str = NULL;
2385 hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_FULL, &str);
2386 ok(hr == S_OK, "got 0x%08x\n", hr);
2387 ok(!lstrcmpW(str, defvalueW), "got %s\n", wine_dbgstr_w(str));
2389
2390 str = NULL;
2391 hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_SHORT, &str);
2392 ok(hr == S_OK, "got 0x%08x\n", hr);
2393 ok(!lstrcmpW(str, auxvalue2W), "got %s\n", wine_dbgstr_w(str));
2395
2396 str = NULL;
2397 hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME, &str);
2398 ok(hr == S_OK, "got 0x%08x\n", hr);
2399 ok(!lstrcmpW(str, auxvalue3W), "got %s\n", wine_dbgstr_w(str));
2401
2402 str = NULL;
2403 hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME+1, &str);
2404 ok(hr == S_OK, "got 0x%08x\n", hr);
2405 ok(!lstrcmpW(str, auxvalue4W), "got %s\n", wine_dbgstr_w(str));
2407
2408 str = NULL;
2409 hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME+2, &str);
2410 ok(hr == S_OK, "got 0x%08x\n", hr);
2411 ok(!lstrcmpW(str, defvalueW), "got %s\n", wine_dbgstr_w(str));
2413
2414 /* registry cleanup */
2415 for (i = 0; i <= 4; i++)
2416 {
2417 char name[2];
2418 sprintf(name, "%d", i);
2419 RegDeleteKeyA(auxhkey, name);
2420 }
2421 RegCloseKey(auxhkey);
2422 RegDeleteKeyA(classkey, "AuxUserType");
2423 RegCloseKey(classkey);
2424 RegDeleteKeyW(clsidhkey, clsidW);
2425 RegCloseKey(clsidhkey);
2426 if (disposition == REG_CREATED_NEW_KEY)
2428}
2429
2430static void test_CoCreateGuid(void)
2431{
2432 HRESULT hr;
2433
2434 hr = CoCreateGuid(NULL);
2435 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2436}
2437
2439{
2440 /* nothing */
2441}
2442
2444{
2445 HANDLE handle = arg;
2448 return 0;
2449}
2450
2452{
2453 HWND hWnd = arg;
2454 Sleep(50);
2456 return 0;
2457}
2458
2460{
2461 HWND hwnd = arg;
2462 Sleep(30);
2463 SendMessageA(hwnd, WM_USER, 0, 0);
2464 PostMessageA(hwnd, WM_USER, 0, 0);
2465 return 0;
2466}
2467
2469{
2470 HWND hWnd = arg;
2471 Sleep(50);
2473 return 0;
2474}
2475
2476static const char cls_name[] = "cowait_test_class";
2477
2479
2480static void cowait_msgs_reset(void)
2481{
2483}
2484
2485#define cowait_msgs_expect_empty() _cowait_msgs_expect_empty(__LINE__)
2486static void _cowait_msgs_expect_empty(unsigned line)
2487{
2489 ok_(__FILE__,line)(0, "unexpected message %u\n", cowait_msgs[cowait_msgs_first]);
2491 }
2493}
2494
2495#define cowait_msgs_expect_notified(a) _cowait_msgs_expect_notified(__LINE__,a)
2496static void _cowait_msgs_expect_notified(unsigned line, UINT expected_msg)
2497{
2499 ok_(__FILE__,line)(0, "expected message %u, received none\n", expected_msg);
2500 }else {
2501 ok_(__FILE__,line)(cowait_msgs[cowait_msgs_first] == expected_msg,
2502 "expected message %u, received %u \n",
2503 expected_msg, cowait_msgs[cowait_msgs_first]);
2505 }
2506}
2507
2508#define cowait_msgs_expect_queued(a,b) _cowait_msgs_expect_queued(__LINE__,a,b)
2509static void _cowait_msgs_expect_queued(unsigned line, HWND hwnd, UINT expected_msg)
2510{
2511 MSG msg;
2512 BOOL success;
2513
2514 success = PeekMessageA(&msg, hwnd, expected_msg, expected_msg, PM_REMOVE);
2515 ok_(__FILE__,line)(success, "PeekMessageA failed: %u\n", GetLastError());
2516 if(success)
2517 ok_(__FILE__,line)(msg.message == expected_msg, "unexpected message %u, expected %u\n",
2518 msg.message, expected_msg);
2519}
2520
2521static void flush_messages(void)
2522{
2523 MSG msg;
2524 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ));
2525}
2526
2528{
2531 if(msg == WM_DDE_FIRST)
2532 return 6;
2533 return DefWindowProcA(hwnd, msg, wparam, lparam);
2534}
2535
2537{
2538 IStream *stream = arg;
2539 IEnumOLEVERB *enum_verb;
2541 IUnknown *unk;
2542 HRESULT hr;
2543
2545
2546 zero.QuadPart = 0;
2547 hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
2548 ok(hr == S_OK, "Seek failed: %08x\n", hr);
2549
2550 hr = CoUnmarshalInterface(stream, &IID_IUnknown, (void**)&unk);
2551 ok(hr == S_OK, "CoUnmarshalInterface failed: %08x\n", hr);
2552
2553 hr = IUnknown_QueryInterface(unk, &IID_IEnumOLEVERB, (void**)&enum_verb);
2554 ok(hr == S_OK, "QueryInterface failed: %08x\n", hr);
2555
2556 IEnumOLEVERB_Release(enum_verb);
2557 IUnknown_Release(unk);
2558
2560 return 0;
2561}
2562
2564{
2566 IStream *stream;
2567 BOOL success;
2568 DWORD index, tid;
2569 HRESULT hr;
2570 HWND hWnd;
2571 UINT uMSG = 0xc065;
2572 MSG msg;
2573 int ret;
2574
2575 hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2576 ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
2577
2578 hWnd = CreateWindowExA(0, cls_name, "Test (thread)", WS_TILEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
2579 ok(hWnd != 0, "CreateWindowExA failed %u\n", GetLastError());
2580
2581 index = 0xdeadbeef;
2584 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2585 ok(index==0 || index==0xdeadbeef/* Win 8 */, "expected index 0, got %u\n", index);
2587 ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2588
2589 index = 0xdeadbeef;
2590 PostMessageA(hWnd, WM_USER, 0, 0);
2592 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2593 ok(index==0 || index==0xdeadbeef/* Win 8 */, "expected index 0, got %u\n", index);
2595 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2596
2597 /* Even if CoWaitForMultipleHandles does not pump a message it peeks
2598 * at ALL of them */
2599 index = 0xdeadbeef;
2600 PostMessageA(NULL, uMSG, 0, 0);
2601
2603 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2604 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2605
2606 /* Make sure message was peeked at */
2608 ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjects returned %x\n", ret);
2609
2610 /* But not pumped */
2611 success = PeekMessageA(&msg, NULL, uMSG, uMSG, PM_REMOVE);
2612 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2613
2616
2617 hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2618 ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
2619
2621 ok(hr == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hr);
2622
2623 hr = CoMarshalInterface(stream, &IID_IUnknown, &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
2624 ok(hr == S_OK, "CoMarshalInterface should have returned S_OK instead of 0x%08x\n", hr);
2625
2626 event = CreateEventW(NULL, TRUE, FALSE, NULL);
2627
2628 PostQuitMessage(66);
2630
2632 ok(hr == S_OK, "CoRegisterMessageFilter failed: %08x\n", hr);
2633
2635 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2636 hr = CoWaitForMultipleHandles(0, 50, 1, &event, &index);
2637 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2639 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2641
2643 ok(hr == S_OK, "CoRegisterMessageFilter failed: %08x\n", hr);
2644
2645 IStream_Release(stream);
2646
2649 return 0;
2650}
2651
2653{
2654 HANDLE handles[2], thread;
2655 DWORD index, tid;
2656 WNDCLASSEXA wc;
2657 BOOL success;
2658 HRESULT hr;
2659 HWND hWnd;
2660 MSG msg;
2661
2662 hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2663 ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
2664
2665 memset(&wc, 0, sizeof(wc));
2666 wc.cbSize = sizeof(wc);
2670 wc.hbrBackground = NULL;
2673 success = RegisterClassExA(&wc) != 0;
2674 ok(success, "RegisterClassExA failed %u\n", GetLastError());
2675
2676 hWnd = CreateWindowExA(0, cls_name, "Test", WS_TILEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
2677 ok(hWnd != 0, "CreateWindowExA failed %u\n", GetLastError());
2678 handles[0] = CreateSemaphoreA(NULL, 1, 1, NULL);
2679 ok(handles[0] != 0, "CreateSemaphoreA failed %u\n", GetLastError());
2680 handles[1] = CreateSemaphoreA(NULL, 1, 1, NULL);
2681 ok(handles[1] != 0, "CreateSemaphoreA failed %u\n", GetLastError());
2682
2683 /* test without flags */
2684
2687 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
2689 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2690
2691 index = 0xdeadbeef;
2693 hr = CoWaitForMultipleHandles(0, 50, 0, NULL, &index);
2694 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
2695 ok(index == 0, "expected index 0, got %u\n", index);
2697 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2698
2699 index = 0xdeadbeef;
2702 ok(hr == RPC_E_NO_SYNC, "expected RPC_E_NO_SYNC, got 0x%08x\n", hr);
2703 ok(index == 0, "expected index 0, got %u\n", index);
2705 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2706
2707 index = 0xdeadbeef;
2710 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2711 ok(index == 0, "expected index 0, got %u\n", index);
2713 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2714
2715 index = 0xdeadbeef;
2718 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2719 ok(index == 1, "expected index 1, got %u\n", index);
2721 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2722
2723 index = 0xdeadbeef;
2726 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2727 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2729 ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2730
2731 /* test PostMessageA/SendMessageA from a different thread */
2732
2733 index = 0xdeadbeef;
2735 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2736 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2737 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2738 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2740 ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2742 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2744
2745 index = 0xdeadbeef;
2747 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2748 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2749 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2750 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2752 ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2754 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2756
2759
2760 /* test with COWAIT_WAITALL */
2761
2762 index = 0xdeadbeef;
2765 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2766 ok(index == 0, "expected index 0, got %u\n", index);
2768 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2769
2770 index = 0xdeadbeef;
2773 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2774 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2776 ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2777
2780
2781 /* test with COWAIT_ALERTABLE */
2782
2783 index = 0xdeadbeef;
2786 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2787 ok(index == 0, "expected index 0, got %u\n", index);
2789 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2790
2791 index = 0xdeadbeef;
2794 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2795 ok(index == 1, "expected index 1, got %u\n", index);
2797 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2798
2799 index = 0xdeadbeef;
2802 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2803 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2805 ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2806
2807 index = 0xdeadbeef;
2810 ok(success, "QueueUserAPC failed %u\n", GetLastError());
2812 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2813 ok(index == WAIT_IO_COMPLETION, "expected index WAIT_IO_COMPLETION, got %u\n", index);
2815 ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2816
2817 /* test with COWAIT_INPUTAVAILABLE (semaphores are still locked) */
2818
2819 index = 0xdeadbeef;
2822 ok(success, "PeekMessageA returned FALSE\n");
2824 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2825 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2827 ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2828
2829 index = 0xdeadbeef;
2832 ok(success, "PeekMessageA returned FALSE\n");
2834 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2836 ok(hr == RPC_S_CALLPENDING || broken(hr == E_INVALIDARG) || broken(hr == S_OK) /* Win 8 */,
2837 "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2838 if (hr != S_OK) ReleaseSemaphore(handles[1], 1, NULL);
2839 ok(index == 0 || broken(index == 1) /* Win 8 */, "expected index 0, got %u\n", index);
2842 "CoWaitForMultipleHandles didn't pump any messages\n");
2844 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2846
2848 PostMessageA(hWnd, 0, 0, 0);
2850 PostMessageA(hWnd, WM_USER+1, 0, 0);
2851 PostMessageA(hWnd, WM_DDE_FIRST+1, 0, 0);
2853 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2854
2855 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2856 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2857
2865
2867 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2869
2870 /* test behaviour of WM_QUIT (semaphores are still locked) */
2871
2872 PostMessageA(hWnd, WM_QUIT, 40, 0);
2873 memset(&msg, 0, sizeof(msg));
2875 ok(success, "PeekMessageA failed, error %u\n", GetLastError());
2876 ok(msg.message == WM_QUIT, "expected msg.message = WM_QUIT, got %u\n", msg.message);
2877 ok(msg.wParam == 40, "expected msg.wParam = 40, got %lu\n", msg.wParam);
2879 ok(!success, "PeekMessageA succeeded\n");
2880
2882 PostMessageA(hWnd, WM_QUIT, 40, 0);
2883 PostMessageA(hWnd, 0, 0, 0);
2885 PostMessageA(hWnd, WM_USER+1, 0, 0);
2886 PostMessageA(hWnd, WM_DDE_FIRST+1, 0, 0);
2888 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2889
2890 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2891 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2892
2899
2901 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2903
2904 index = 0xdeadbeef;
2906 PostMessageA(hWnd, WM_QUIT, 41, 0);
2908 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2909 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2910 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2911 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2913 todo_wine
2914 ok(success || broken(!success) /* Win 2000/XP/8 */, "PeekMessageA failed, error %u\n", GetLastError());
2916 ok(!success, "PeekMessageA succeeded\n");
2917 memset(&msg, 0, sizeof(msg));
2919 todo_wine
2920 ok(!success || broken(success) /* Win 2000/XP/8 */, "PeekMessageA succeeded\n");
2921 if (success)
2922 {
2923 ok(msg.message == WM_QUIT, "expected msg.message = WM_QUIT, got %u\n", msg.message);
2924 ok(msg.wParam == 41, "expected msg.wParam = 41, got %lu\n", msg.wParam);
2925 }
2927 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2929
2930 index = 0xdeadbeef;
2932 PostMessageA(hWnd, WM_QUIT, 42, 0);
2934 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2935 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2936 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2937 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2939 ok(!success, "CoWaitForMultipleHandles didn't pump all WM_DDE_FIRST messages\n");
2940 memset(&msg, 0, sizeof(msg));
2942 ok(success, "PeekMessageA failed, error %u\n", GetLastError());
2943 ok(msg.message == WM_QUIT, "expected msg.message = WM_QUIT, got %u\n", msg.message);
2944 ok(msg.wParam == 42, "expected msg.wParam = 42, got %lu\n", msg.wParam);
2946 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2948
2949 PostQuitMessage(43);
2950 memset(&msg, 0, sizeof(msg));
2952 ok(success || broken(!success) /* Win 8 */, "PeekMessageA failed, error %u\n", GetLastError());
2953 if (!success)
2954 win_skip("PostQuitMessage didn't queue a WM_QUIT message, skipping tests\n");
2955 else
2956 {
2957 ok(msg.message == WM_QUIT, "expected msg.message = WM_QUIT, got %u\n", msg.message);
2958 ok(msg.wParam == 43, "expected msg.wParam = 43, got %lu\n", msg.wParam);
2960 ok(!success, "PeekMessageA succeeded\n");
2961
2962 index = 0xdeadbeef;
2964 PostQuitMessage(44);
2966 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2967 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2968 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2969 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2971 ok(success, "PeekMessageA failed, error %u\n", GetLastError());
2973 ok(!success, "PeekMessageA succeeded\n");
2975 ok(!success, "CoWaitForMultipleHandles didn't remove WM_QUIT messages\n");
2977 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2979
2980 index = 0xdeadbeef;
2982 PostQuitMessage(45);
2984 ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2985 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2986 ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2987 ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2989 ok(success, "PeekMessageA failed, error %u\n", GetLastError());
2991 ok(!success, "PeekMessageA succeeded\n");
2993 ok(!success, "CoWaitForMultipleHandles didn't remove WM_QUIT messages\n");
2995 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2997 }
2998
2999 /* test message pumping when CoWaitForMultipleHandles is called from non main apartment thread */
3002 ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
3004
3006
3007 /* If COM was not initialized, messages are neither pumped nor peeked at */
3009 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
3010 ok(hr == RPC_S_CALLPENDING, "got %#x\n", hr);
3012 ok(success == 0, "MsgWaitForMultipleObjects returned %x\n", success);
3014 ok(success, "PeekMessage failed: %u\n", GetLastError());
3015
3016 /* same in an MTA */
3018
3020 hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
3021 ok(hr == RPC_S_CALLPENDING, "got %#x\n", hr);
3023 ok(success == 0, "MsgWaitForMultipleObjects returned %x\n", success);
3025 ok(success, "PeekMessage failed: %u\n", GetLastError());
3026
3028
3029 CloseHandle(handles[0]);
3030 CloseHandle(handles[1]);
3032
3034 ok(success, "UnregisterClass failed %u\n", GetLastError());
3035}
3036
3037static void test_CoGetMalloc(void)
3038{
3039 IMalloc *imalloc;
3040 HRESULT hr;
3041
3042 if (0) /* crashes on native */
3043 hr = CoGetMalloc(0, NULL);
3044
3045 imalloc = (void*)0xdeadbeef;
3046 hr = CoGetMalloc(0, &imalloc);
3047 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3048 ok(imalloc == NULL, "got %p\n", imalloc);
3049
3050 imalloc = (void*)0xdeadbeef;
3051 hr = CoGetMalloc(MEMCTX_SHARED, &imalloc);
3052 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3053 ok(imalloc == NULL, "got %p\n", imalloc);
3054
3055 imalloc = (void*)0xdeadbeef;
3056 hr = CoGetMalloc(MEMCTX_MACSYSTEM, &imalloc);
3057 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3058 ok(imalloc == NULL, "got %p\n", imalloc);