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
21 #define WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
35 #define USE_COM_CONTEXT_DEF
37 //#include "objbase.h"
38 //#include "shlguid.h"
40 #include <urlmon.h> /* for CLSID_FileProtocol */
45 #include <wine/test.h>
47 extern const IID GUID_NULL
;
49 #define DEFINE_EXPECT(func) \
50 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
52 #define SET_EXPECT(func) \
53 expect_ ## func = TRUE
55 #define CHECK_EXPECT2(func) \
57 ok(expect_ ##func, "unexpected call " #func "\n"); \
58 called_ ## func = TRUE; \
61 #define CHECK_EXPECT(func) \
63 CHECK_EXPECT2(func); \
64 expect_ ## func = FALSE; \
67 #define CHECK_CALLED(func) \
69 ok(called_ ## func, "expected " #func "\n"); \
70 expect_ ## func = called_ ## func = FALSE; \
73 DEFINE_EXPECT(CreateStub
);
75 /* functions that are not present on all versions of Windows */
76 static HRESULT (WINAPI
* pCoInitializeEx
)(LPVOID lpReserved
, DWORD dwCoInit
);
77 static HRESULT (WINAPI
* pCoGetObjectContext
)(REFIID riid
, LPVOID
*ppv
);
78 static HRESULT (WINAPI
* pCoSwitchCallContext
)(IUnknown
*pObject
, IUnknown
**ppOldObject
);
79 static HRESULT (WINAPI
* pCoGetTreatAsClass
)(REFCLSID clsidOld
, LPCLSID pClsidNew
);
80 static HRESULT (WINAPI
* pCoTreatAsClass
)(REFCLSID clsidOld
, REFCLSID pClsidNew
);
81 static HRESULT (WINAPI
* pCoGetContextToken
)(ULONG_PTR
*token
);
82 static HRESULT (WINAPI
* pCoGetApartmentType
)(APTTYPE
*type
, APTTYPEQUALIFIER
*qualifier
);
83 static LONG (WINAPI
* pRegDeleteKeyExA
)(HKEY
, LPCSTR
, REGSAM
, DWORD
);
84 static LONG (WINAPI
* pRegOverridePredefKey
)(HKEY key
, HKEY override
);
86 static BOOL (WINAPI
*pActivateActCtx
)(HANDLE
,ULONG_PTR
*);
87 static HANDLE (WINAPI
*pCreateActCtxW
)(PCACTCTXW
);
88 static BOOL (WINAPI
*pDeactivateActCtx
)(DWORD
,ULONG_PTR
);
89 static BOOL (WINAPI
*pIsWow64Process
)(HANDLE
, LPBOOL
);
90 static void (WINAPI
*pReleaseActCtx
)(HANDLE
);
92 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
93 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
94 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
96 static const CLSID CLSID_non_existent
= { 0x12345678, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
97 static const CLSID CLSID_StdFont
= { 0x0be35203, 0x8f91, 0x11ce, { 0x9d, 0xe3, 0x00, 0xaa, 0x00, 0x4b, 0xb8, 0x51 } };
98 static const GUID IID_Testiface
= { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
99 static const GUID IID_Testiface2
= { 0x32222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
100 static const GUID IID_Testiface3
= { 0x42222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
101 static const GUID IID_Testiface4
= { 0x52222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
102 static const GUID IID_Testiface5
= { 0x62222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
103 static const GUID IID_Testiface6
= { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
104 static const GUID IID_TestPS
= { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
106 DEFINE_GUID(CLSID_InProcFreeMarshaler
, 0x0000033a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
107 DEFINE_GUID(CLSID_testclsid
, 0xacd014c7,0x9535,0x4fac,0x8b,0x53,0xa4,0x8c,0xa7,0xf4,0xd7,0x26);
109 static const WCHAR stdfont
[] = {'S','t','d','F','o','n','t',0};
110 static const WCHAR wszNonExistent
[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
111 static const WCHAR wszCLSID_StdFont
[] =
113 '{','0','b','e','3','5','2','0','3','-','8','f','9','1','-','1','1','c','e','-',
114 '9','d','e','3','-','0','0','a','a','0','0','4','b','b','8','5','1','}',0
116 static const WCHAR progidW
[] = {'P','r','o','g','I','d','.','P','r','o','g','I','d',0};
117 static const WCHAR cf_brokenW
[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
118 'c','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}','a',0};
120 DEFINE_GUID(IID_IWineTest
, 0x5201163f, 0x8164, 0x4fd0, 0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd);
121 DEFINE_GUID(CLSID_WineOOPTest
, 0x5201163f, 0x8164, 0x4fd0, 0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd);
125 static void LockModule(void)
127 InterlockedIncrement(&cLocks
);
130 static void UnlockModule(void)
132 InterlockedDecrement(&cLocks
);
135 static HRESULT WINAPI
Test_IClassFactory_QueryInterface(
136 LPCLASSFACTORY iface
,
140 if (ppvObj
== NULL
) return E_POINTER
;
142 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
143 IsEqualGUID(riid
, &IID_IClassFactory
))
146 IClassFactory_AddRef(iface
);
151 return E_NOINTERFACE
;
154 static ULONG WINAPI
Test_IClassFactory_AddRef(LPCLASSFACTORY iface
)
157 return 2; /* non-heap-based object */
160 static ULONG WINAPI
Test_IClassFactory_Release(LPCLASSFACTORY iface
)
163 return 1; /* non-heap-based object */
166 static IID create_instance_iid
;
167 static HRESULT WINAPI
Test_IClassFactory_CreateInstance(
168 LPCLASSFACTORY iface
,
174 create_instance_iid
= *riid
;
175 if (pUnkOuter
) return CLASS_E_NOAGGREGATION
;
176 return E_NOINTERFACE
;
179 static HRESULT WINAPI
Test_IClassFactory_LockServer(
180 LPCLASSFACTORY iface
,
186 static const IClassFactoryVtbl TestClassFactory_Vtbl
=
188 Test_IClassFactory_QueryInterface
,
189 Test_IClassFactory_AddRef
,
190 Test_IClassFactory_Release
,
191 Test_IClassFactory_CreateInstance
,
192 Test_IClassFactory_LockServer
195 static IClassFactory Test_ClassFactory
= { &TestClassFactory_Vtbl
};
197 static WCHAR manifest_path
[MAX_PATH
];
199 static BOOL
create_manifest_file(const char *filename
, const char *manifest
)
204 WCHAR path
[MAX_PATH
];
206 MultiByteToWideChar( CP_ACP
, 0, filename
, -1, path
, MAX_PATH
);
207 GetFullPathNameW(path
, sizeof(manifest_path
)/sizeof(WCHAR
), manifest_path
, NULL
);
209 manifest_len
= strlen(manifest
);
210 file
= CreateFileW(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
211 FILE_ATTRIBUTE_NORMAL
, NULL
);
212 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError());
213 if(file
== INVALID_HANDLE_VALUE
)
215 WriteFile(file
, manifest
, manifest_len
, &size
, NULL
);
221 static HANDLE
activate_context(const char *manifest
, ULONG_PTR
*cookie
)
223 WCHAR path
[MAX_PATH
];
228 if (!pCreateActCtxW
) return NULL
;
230 create_manifest_file("file.manifest", manifest
);
232 MultiByteToWideChar( CP_ACP
, 0, "file.manifest", -1, path
, MAX_PATH
);
233 memset(&actctx
, 0, sizeof(ACTCTXW
));
234 actctx
.cbSize
= sizeof(ACTCTXW
);
235 actctx
.lpSource
= path
;
237 handle
= pCreateActCtxW(&actctx
);
238 ok(handle
!= INVALID_HANDLE_VALUE
|| broken(handle
== INVALID_HANDLE_VALUE
) /* some old XP/2k3 versions */,
239 "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError());
240 if (handle
== INVALID_HANDLE_VALUE
)
242 win_skip("activation context generation failed, some tests will be skipped\n");
246 ok(actctx
.cbSize
== sizeof(ACTCTXW
), "actctx.cbSize=%d\n", actctx
.cbSize
);
247 ok(actctx
.dwFlags
== 0, "actctx.dwFlags=%d\n", actctx
.dwFlags
);
248 ok(actctx
.lpSource
== path
, "actctx.lpSource=%p\n", actctx
.lpSource
);
249 ok(actctx
.wProcessorArchitecture
== 0, "actctx.wProcessorArchitecture=%d\n", actctx
.wProcessorArchitecture
);
250 ok(actctx
.wLangId
== 0, "actctx.wLangId=%d\n", actctx
.wLangId
);
251 ok(actctx
.lpAssemblyDirectory
== NULL
, "actctx.lpAssemblyDirectory=%p\n", actctx
.lpAssemblyDirectory
);
252 ok(actctx
.lpResourceName
== NULL
, "actctx.lpResourceName=%p\n", actctx
.lpResourceName
);
253 ok(actctx
.lpApplicationName
== NULL
, "actctx.lpApplicationName=%p\n", actctx
.lpApplicationName
);
254 ok(actctx
.hModule
== NULL
, "actctx.hModule=%p\n", actctx
.hModule
);
256 DeleteFileA("file.manifest");
260 ret
= pActivateActCtx(handle
, cookie
);
261 ok(ret
, "ActivateActCtx failed: %u\n", GetLastError());
267 static const char actctx_manifest
[] =
268 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
269 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\""
270 " publicKeyToken=\"6595b6414666f1df\" />"
271 "<file name=\"testlib.dll\">"
273 " clsid=\"{0000033a-0000-0000-c000-000000000046}\""
274 " progid=\"FTMarshal\""
277 " clsid=\"{5201163f-8164-4fd0-a1a2-5d5a3654d3bd}\""
278 " progid=\"WineOOPTest\""
280 " <comClass description=\"Test com class\""
281 " clsid=\"{12345678-1234-1234-1234-56789abcdef0}\""
282 " progid=\"ProgId.ProgId\""
283 " miscStatusIcon=\"recomposeonresize\""
285 " <comClass description=\"CustomFont Description\" clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb851}\""
286 " progid=\"CustomFont\""
287 " miscStatusIcon=\"recomposeonresize\""
288 " miscStatusContent=\"insideout\""
290 " <comClass description=\"StdFont Description\" clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb852}\""
291 " progid=\"StdFont\""
293 " <comClass clsid=\"{62222222-1234-1234-1234-56789abcdef0}\" >"
294 " <progid>ProgId.ProgId.1</progid>"
296 " <comInterfaceProxyStub "
298 " iid=\"{22222222-1234-1234-1234-56789abcdef0}\""
299 " proxyStubClsid32=\"{66666666-8888-7777-6666-555555555555}\""
302 " <comInterfaceExternalProxyStub "
303 " name=\"Iifaceps2\""
304 " iid=\"{32222222-1234-1234-1234-56789abcdef0}\""
306 " <comInterfaceExternalProxyStub "
307 " name=\"Iifaceps3\""
308 " iid=\"{42222222-1234-1234-1234-56789abcdef0}\""
309 " proxyStubClsid32=\"{66666666-8888-7777-6666-555555555555}\""
311 " <comInterfaceExternalProxyStub "
312 " name=\"Iifaceps4\""
313 " iid=\"{52222222-1234-1234-1234-56789abcdef0}\""
314 " proxyStubClsid32=\"{00000000-0000-0000-0000-000000000000}\""
317 " clsid=\"{72222222-1234-1234-1234-56789abcdef0}\""
320 " <progid>clrprogid.1</progid>"
324 DEFINE_GUID(CLSID_Testclass
, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0);
326 static void test_ProgIDFromCLSID(void)
328 ULONG_PTR cookie
= 0;
333 hr
= ProgIDFromCLSID(&CLSID_StdFont
, &progid
);
334 ok(hr
== S_OK
, "ProgIDFromCLSID failed with error 0x%08x\n", hr
);
337 ok(!lstrcmpiW(progid
, stdfont
), "Didn't get expected prog ID\n");
338 CoTaskMemFree(progid
);
341 progid
= (LPWSTR
)0xdeadbeef;
342 hr
= ProgIDFromCLSID(&CLSID_non_existent
, &progid
);
343 ok(hr
== REGDB_E_CLASSNOTREG
, "ProgIDFromCLSID returned %08x\n", hr
);
344 ok(progid
== NULL
, "ProgIDFromCLSID returns with progid %p\n", progid
);
346 hr
= ProgIDFromCLSID(&CLSID_StdFont
, NULL
);
347 ok(hr
== E_INVALIDARG
, "ProgIDFromCLSID should return E_INVALIDARG instead of 0x%08x\n", hr
);
349 if ((handle
= activate_context(actctx_manifest
, &cookie
)))
351 static const WCHAR customfontW
[] = {'C','u','s','t','o','m','F','o','n','t',0};
353 hr
= ProgIDFromCLSID(&CLSID_non_existent
, &progid
);
354 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
355 ok(!lstrcmpiW(progid
, progidW
), "got %s\n", wine_dbgstr_w(progid
));
356 CoTaskMemFree(progid
);
358 /* try something registered and redirected */
360 hr
= ProgIDFromCLSID(&CLSID_StdFont
, &progid
);
361 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
362 ok(!lstrcmpiW(progid
, customfontW
), "got wrong progid %s\n", wine_dbgstr_w(progid
));
363 CoTaskMemFree(progid
);
365 /* classes without default progid, progid list is not used */
366 hr
= ProgIDFromCLSID(&IID_Testiface5
, &progid
);
367 ok(hr
== REGDB_E_CLASSNOTREG
, "got 0x%08x\n", hr
);
369 hr
= ProgIDFromCLSID(&IID_Testiface6
, &progid
);
370 ok(hr
== REGDB_E_CLASSNOTREG
, "got 0x%08x\n", hr
);
372 pDeactivateActCtx(0, cookie
);
373 pReleaseActCtx(handle
);
377 static void test_CLSIDFromProgID(void)
379 ULONG_PTR cookie
= 0;
382 HRESULT hr
= CLSIDFromProgID(stdfont
, &clsid
);
383 ok(hr
== S_OK
, "CLSIDFromProgID failed with error 0x%08x\n", hr
);
384 ok(IsEqualCLSID(&clsid
, &CLSID_StdFont
), "clsid wasn't equal to CLSID_StdFont\n");
386 hr
= CLSIDFromString(stdfont
, &clsid
);
387 ok_ole_success(hr
, "CLSIDFromString");
388 ok(IsEqualCLSID(&clsid
, &CLSID_StdFont
), "clsid wasn't equal to CLSID_StdFont\n");
390 /* test some failure cases */
392 hr
= CLSIDFromProgID(wszNonExistent
, NULL
);
393 ok(hr
== E_INVALIDARG
, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
395 hr
= CLSIDFromProgID(NULL
, &clsid
);
396 ok(hr
== E_INVALIDARG
, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
398 memset(&clsid
, 0xcc, sizeof(clsid
));
399 hr
= CLSIDFromProgID(wszNonExistent
, &clsid
);
400 ok(hr
== CO_E_CLASSSTRING
, "CLSIDFromProgID on nonexistent ProgID should have returned CO_E_CLASSSTRING instead of 0x%08x\n", hr
);
401 ok(IsEqualCLSID(&clsid
, &CLSID_NULL
), "CLSIDFromProgID should have set clsid to all-zeros on failure\n");
403 /* fails without proper context */
404 memset(&clsid
, 0xcc, sizeof(clsid
));
405 hr
= CLSIDFromProgID(progidW
, &clsid
);
406 ok(hr
== CO_E_CLASSSTRING
, "got 0x%08x\n", hr
);
407 ok(IsEqualCLSID(&clsid
, &CLSID_NULL
), "wrong clsid\n");
409 if ((handle
= activate_context(actctx_manifest
, &cookie
)))
413 memset(&clsid
, 0xcc, sizeof(clsid
));
414 hr
= CLSIDFromProgID(wszNonExistent
, &clsid
);
415 ok(hr
== CO_E_CLASSSTRING
, "got 0x%08x\n", hr
);
416 ok(IsEqualCLSID(&clsid
, &CLSID_NULL
), "should have zero CLSID on failure\n");
418 /* CLSIDFromString() doesn't check activation context */
419 hr
= CLSIDFromString(progidW
, &clsid
);
420 ok(hr
== CO_E_CLASSSTRING
, "got 0x%08x\n", hr
);
423 hr
= CLSIDFromProgID(progidW
, &clsid
);
424 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
425 /* it returns generated CLSID here */
426 ok(!IsEqualCLSID(&clsid
, &CLSID_non_existent
) && !IsEqualCLSID(&clsid
, &CLSID_NULL
),
427 "got wrong clsid %s\n", wine_dbgstr_guid(&clsid
));
429 /* duplicate progid present in context - returns generated guid here too */
431 hr
= CLSIDFromProgID(stdfont
, &clsid
);
432 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
433 clsid1
= CLSID_StdFont
;
434 /* that's where it differs from StdFont */
435 clsid1
.Data4
[7] = 0x52;
436 ok(!IsEqualCLSID(&clsid
, &CLSID_StdFont
) && !IsEqualCLSID(&clsid
, &CLSID_NULL
) && !IsEqualCLSID(&clsid
, &clsid1
),
437 "got %s\n", wine_dbgstr_guid(&clsid
));
439 pDeactivateActCtx(0, cookie
);
440 pReleaseActCtx(handle
);
444 static void test_CLSIDFromString(void)
447 WCHAR wszCLSID_Broken
[50];
450 HRESULT hr
= CLSIDFromString(wszCLSID_StdFont
, &clsid
);
451 ok_ole_success(hr
, "CLSIDFromString");
452 ok(IsEqualCLSID(&clsid
, &CLSID_StdFont
), "clsid wasn't equal to CLSID_StdFont\n");
454 memset(&clsid
, 0xab, sizeof(clsid
));
455 hr
= CLSIDFromString(NULL
, &clsid
);
456 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
457 ok(IsEqualCLSID(&clsid
, &CLSID_NULL
), "clsid wasn't equal to CLSID_NULL\n");
459 /* string is longer, but starts with a valid CLSID */
460 memset(&clsid
, 0, sizeof(clsid
));
461 hr
= CLSIDFromString(cf_brokenW
, &clsid
);
462 ok(hr
== CO_E_CLASSSTRING
, "got 0x%08x\n", hr
);
463 ok(IsEqualCLSID(&clsid
, &IID_IClassFactory
), "got %s\n", wine_dbgstr_guid(&clsid
));
465 lstrcpyW(wszCLSID_Broken
, wszCLSID_StdFont
);
466 for(i
= lstrlenW(wszCLSID_StdFont
); i
< 49; i
++)
467 wszCLSID_Broken
[i
] = 'A';
468 wszCLSID_Broken
[i
] = '\0';
470 memset(&clsid
, 0, sizeof(CLSID
));
471 hr
= CLSIDFromString(wszCLSID_Broken
, &clsid
);
472 ok(hr
== CO_E_CLASSSTRING
, "Got %08x\n", hr
);
473 ok(IsEqualCLSID(&clsid
, &CLSID_StdFont
), "clsid wasn't equal to CLSID_StdFont\n");
475 wszCLSID_Broken
[lstrlenW(wszCLSID_StdFont
)-1] = 'A';
476 memset(&clsid
, 0, sizeof(CLSID
));
477 hr
= CLSIDFromString(wszCLSID_Broken
, &clsid
);
478 ok(hr
== CO_E_CLASSSTRING
, "Got %08x\n", hr
);
479 ok(IsEqualCLSID(&clsid
, &CLSID_StdFont
), "clsid wasn't equal to CLSID_StdFont\n");
481 wszCLSID_Broken
[lstrlenW(wszCLSID_StdFont
)] = '\0';
482 memset(&clsid
, 0, sizeof(CLSID
));
483 hr
= CLSIDFromString(wszCLSID_Broken
, &clsid
);
484 ok(hr
== CO_E_CLASSSTRING
, "Got %08x\n", hr
);
485 ok(IsEqualCLSID(&clsid
, &CLSID_StdFont
), "clsid wasn't equal to CLSID_StdFont\n");
487 wszCLSID_Broken
[lstrlenW(wszCLSID_StdFont
)-1] = '\0';
488 memset(&clsid
, 0, sizeof(CLSID
));
489 hr
= CLSIDFromString(wszCLSID_Broken
, &clsid
);
490 ok(hr
== CO_E_CLASSSTRING
, "Got %08x\n", hr
);
491 ok(IsEqualCLSID(&clsid
, &CLSID_StdFont
), "clsid wasn't equal to CLSID_StdFont\n");
493 memset(&clsid
, 0xcc, sizeof(CLSID
));
494 hr
= CLSIDFromString(wszCLSID_Broken
+1, &clsid
);
495 ok(hr
== CO_E_CLASSSTRING
, "Got %08x\n", hr
);
496 ok(IsEqualCLSID(&clsid
, &CLSID_NULL
), "clsid wasn't equal to CLSID_NULL\n");
498 wszCLSID_Broken
[9] = '*';
499 memset(&clsid
, 0xcc, sizeof(CLSID
));
500 hr
= CLSIDFromString(wszCLSID_Broken
, &clsid
);
501 ok(hr
== CO_E_CLASSSTRING
, "Got %08x\n", hr
);
502 ok(clsid
.Data1
== CLSID_StdFont
.Data1
, "Got %08x\n", clsid
.Data1
);
503 ok(clsid
.Data2
== 0xcccc, "Got %04x\n", clsid
.Data2
);
505 wszCLSID_Broken
[3] = '*';
506 memset(&clsid
, 0xcc, sizeof(CLSID
));
507 hr
= CLSIDFromString(wszCLSID_Broken
, &clsid
);
508 ok(hr
== CO_E_CLASSSTRING
, "Got %08x\n", hr
);
509 ok(clsid
.Data1
== 0xb, "Got %08x\n", clsid
.Data1
);
510 ok(clsid
.Data2
== 0xcccc, "Got %04x\n", clsid
.Data2
);
512 wszCLSID_Broken
[3] = '\0';
513 memset(&clsid
, 0xcc, sizeof(CLSID
));
514 hr
= CLSIDFromString(wszCLSID_Broken
, &clsid
);
515 ok(hr
== CO_E_CLASSSTRING
, "Got %08x\n", hr
);
516 ok(clsid
.Data1
== 0xb, "Got %08x\n", clsid
.Data1
);
517 ok(clsid
.Data2
== 0xcccc, "Got %04x\n", clsid
.Data2
);
520 static void test_IIDFromString(void)
522 static const WCHAR cfW
[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
523 'c','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
524 static const WCHAR brokenW
[] = {'{','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 broken2W
[] = {'{','0','0','0','0','0','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 static const WCHAR broken3W
[] = {'b','r','o','k','e','n','0','0','1','=','0','0','0','0','-','0','0','0','0','-',
529 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
533 hr
= IIDFromString(wszCLSID_StdFont
, &iid
);
534 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
535 ok(IsEqualIID(&iid
, &CLSID_StdFont
), "got iid %s\n", wine_dbgstr_guid(&iid
));
537 memset(&iid
, 0xab, sizeof(iid
));
538 hr
= IIDFromString(NULL
, &iid
);
539 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
540 ok(IsEqualIID(&iid
, &CLSID_NULL
), "got iid %s\n", wine_dbgstr_guid(&iid
));
542 hr
= IIDFromString(cfW
, &iid
);
543 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
544 ok(IsEqualIID(&iid
, &IID_IClassFactory
), "got iid %s\n", wine_dbgstr_guid(&iid
));
546 /* string starts with a valid IID but is longer */
547 memset(&iid
, 0xab, sizeof(iid
));
548 hr
= IIDFromString(cf_brokenW
, &iid
);
549 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
550 ok(iid
.Data1
== 0xabababab, "Got %08x\n", iid
.Data1
);
552 /* invalid IID in a valid format */
553 memset(&iid
, 0xab, sizeof(iid
));
554 hr
= IIDFromString(brokenW
, &iid
);
555 ok(hr
== CO_E_IIDSTRING
, "got 0x%08x\n", hr
);
556 ok(iid
.Data1
== 0x00000001, "Got %08x\n", iid
.Data1
);
558 memset(&iid
, 0xab, sizeof(iid
));
559 hr
= IIDFromString(broken2W
, &iid
);
560 ok(hr
== CO_E_IIDSTRING
, "got 0x%08x\n", hr
);
561 ok(iid
.Data1
== 0x00000001, "Got %08x\n", iid
.Data1
);
563 /* format is broken, but string length is okay */
564 memset(&iid
, 0xab, sizeof(iid
));
565 hr
= IIDFromString(broken3W
, &iid
);
566 ok(hr
== CO_E_IIDSTRING
, "got 0x%08x\n", hr
);
567 ok(iid
.Data1
== 0xabababab, "Got %08x\n", iid
.Data1
);
570 memset(&iid
, 0xab, sizeof(iid
));
571 hr
= IIDFromString(wszNonExistent
, &iid
);
572 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
573 ok(iid
.Data1
== 0xabababab, "Got %08x\n", iid
.Data1
);
576 memset(&iid
, 0xab, sizeof(iid
));
577 hr
= IIDFromString(stdfont
, &iid
);
578 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
579 ok(iid
.Data1
== 0xabababab, "Got %08x\n", iid
.Data1
);
582 static void test_StringFromGUID2(void)
587 /* invalid pointer */
588 SetLastError(0xdeadbeef);
589 len
= StringFromGUID2(NULL
,str
,50);
590 ok(len
== 0, "len: %d (expected 0)\n", len
);
591 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %x\n", GetLastError());
593 /* Test corner cases for buffer size */
594 len
= StringFromGUID2(&CLSID_StdFont
,str
,50);
595 ok(len
== 39, "len: %d (expected 39)\n", len
);
596 ok(!lstrcmpiW(str
, wszCLSID_StdFont
),"string wasn't equal for CLSID_StdFont\n");
598 memset(str
,0,sizeof str
);
599 len
= StringFromGUID2(&CLSID_StdFont
,str
,39);
600 ok(len
== 39, "len: %d (expected 39)\n", len
);
601 ok(!lstrcmpiW(str
, wszCLSID_StdFont
),"string wasn't equal for CLSID_StdFont\n");
603 len
= StringFromGUID2(&CLSID_StdFont
,str
,38);
604 ok(len
== 0, "len: %d (expected 0)\n", len
);
606 len
= StringFromGUID2(&CLSID_StdFont
,str
,30);
607 ok(len
== 0, "len: %d (expected 0)\n", len
);
615 static DWORD CALLBACK
ole_initialize_thread(LPVOID pv
)
618 struct info
*info
= pv
;
620 hr
= pCoInitializeEx(NULL
, COINIT_MULTITHREADED
);
622 SetEvent(info
->wait
);
623 WaitForSingleObject(info
->stop
, 10000);
629 #define test_apt_type(t, q, t_t, t_q) _test_apt_type(t, q, t_t, t_q, __LINE__)
630 static void _test_apt_type(APTTYPE expected_type
, APTTYPEQUALIFIER expected_qualifier
, BOOL todo_type
,
631 BOOL todo_qualifier
, int line
)
633 APTTYPEQUALIFIER qualifier
= ~0u;
637 if (!pCoGetApartmentType
)
640 hr
= pCoGetApartmentType(&type
, &qualifier
);
641 ok_(__FILE__
, line
)(hr
== S_OK
|| hr
== CO_E_NOTINITIALIZED
, "Unexpected return code: 0x%08x\n", hr
);
642 todo_wine_if(todo_type
)
643 ok_(__FILE__
, line
)(type
== expected_type
, "Wrong apartment type %d, expected %d\n", type
, expected_type
);
644 todo_wine_if(todo_qualifier
)
645 ok_(__FILE__
, line
)(qualifier
== expected_qualifier
, "Wrong apartment qualifier %d, expected %d\n", qualifier
,
649 static void test_CoCreateInstance(void)
656 REFCLSID rclsid
= &CLSID_InternetZoneManager
;
658 pUnk
= (IUnknown
*)0xdeadbeef;
659 hr
= CoCreateInstance(rclsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&pUnk
);
660 ok(hr
== CO_E_NOTINITIALIZED
, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr
);
661 ok(pUnk
== NULL
, "CoCreateInstance should have changed the passed in pointer to NULL, instead of %p\n", pUnk
);
665 /* test errors returned for non-registered clsids */
666 hr
= CoCreateInstance(&CLSID_non_existent
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&pUnk
);
667 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance for non-registered inproc server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
668 hr
= CoCreateInstance(&CLSID_non_existent
, NULL
, CLSCTX_INPROC_HANDLER
, &IID_IUnknown
, (void **)&pUnk
);
669 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance for non-registered inproc handler should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
670 hr
= CoCreateInstance(&CLSID_non_existent
, NULL
, CLSCTX_LOCAL_SERVER
, &IID_IUnknown
, (void **)&pUnk
);
671 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance for non-registered local server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
672 hr
= CoCreateInstance(&CLSID_non_existent
, NULL
, CLSCTX_REMOTE_SERVER
, &IID_IUnknown
, (void **)&pUnk
);
673 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance for non-registered remote server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
675 hr
= CoCreateInstance(rclsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&pUnk
);
676 if(hr
== REGDB_E_CLASSNOTREG
)
678 skip("IE not installed so can't test CoCreateInstance\n");
683 ok_ole_success(hr
, "CoCreateInstance");
684 if(pUnk
) IUnknown_Release(pUnk
);
687 hr
= CoCreateInstance(rclsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&pUnk
);
688 ok(hr
== CO_E_NOTINITIALIZED
, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr
);
690 /* show that COM doesn't have to be initialized for multi-threaded apartments if another
691 thread has already done so */
693 test_apt_type(APTTYPE_CURRENT
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
695 info
.wait
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
696 ok(info
.wait
!= NULL
, "CreateEvent failed with error %d\n", GetLastError());
698 info
.stop
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
699 ok(info
.stop
!= NULL
, "CreateEvent failed with error %d\n", GetLastError());
701 thread
= CreateThread(NULL
, 0, ole_initialize_thread
, &info
, 0, &tid
);
702 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
704 ok( !WaitForSingleObject(info
.wait
, 10000 ), "wait timed out\n" );
706 test_apt_type(APTTYPE_MTA
, APTTYPEQUALIFIER_IMPLICIT_MTA
, TRUE
, TRUE
);
708 pUnk
= (IUnknown
*)0xdeadbeef;
709 hr
= CoCreateInstance(rclsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void **)&pUnk
);
710 ok(hr
== S_OK
, "CoCreateInstance should have returned S_OK instead of 0x%08x\n", hr
);
711 if (pUnk
) IUnknown_Release(pUnk
);
714 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
716 GetExitCodeThread(thread
, &exitcode
);
718 ok(hr
== S_OK
, "thread should have returned S_OK instead of 0x%08x\n", hr
);
721 CloseHandle(info
.wait
);
722 CloseHandle(info
.stop
);
724 test_apt_type(APTTYPE_CURRENT
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
727 static void test_CoGetClassObject(void)
730 HANDLE thread
, handle
;
735 REFCLSID rclsid
= &CLSID_InternetZoneManager
;
739 hr
= CoGetClassObject(rclsid
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, (void **)&pUnk
);
740 ok(hr
== CO_E_NOTINITIALIZED
, "CoGetClassObject should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr
);
741 ok(pUnk
== NULL
, "CoGetClassObject should have changed the passed in pointer to NULL, instead of %p\n", pUnk
);
743 hr
= CoGetClassObject(rclsid
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, NULL
);
744 ok(hr
== E_INVALIDARG
||
745 broken(hr
== CO_E_NOTINITIALIZED
), /* win9x */
746 "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
748 /* show that COM doesn't have to be initialized for multi-threaded apartments if another
749 thread has already done so */
751 test_apt_type(APTTYPE_CURRENT
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
753 info
.wait
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
754 ok(info
.wait
!= NULL
, "CreateEvent failed with error %d\n", GetLastError());
756 info
.stop
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
757 ok(info
.stop
!= NULL
, "CreateEvent failed with error %d\n", GetLastError());
759 thread
= CreateThread(NULL
, 0, ole_initialize_thread
, &info
, 0, &tid
);
760 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
762 ok( !WaitForSingleObject(info
.wait
, 10000), "wait timed out\n" );
764 test_apt_type(APTTYPE_MTA
, APTTYPEQUALIFIER_IMPLICIT_MTA
, TRUE
, TRUE
);
766 pUnk
= (IUnknown
*)0xdeadbeef;
767 hr
= CoGetClassObject(rclsid
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, (void **)&pUnk
);
768 if(hr
== REGDB_E_CLASSNOTREG
)
769 skip("IE not installed so can't test CoGetClassObject\n");
772 ok(hr
== S_OK
, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr
);
773 if (pUnk
) IUnknown_Release(pUnk
);
777 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
779 GetExitCodeThread(thread
, &exitcode
);
781 ok(hr
== S_OK
, "thread should have returned S_OK instead of 0x%08x\n", hr
);
784 CloseHandle(info
.wait
);
785 CloseHandle(info
.stop
);
787 test_apt_type(APTTYPE_CURRENT
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
789 if (!pRegOverridePredefKey
)
791 win_skip("RegOverridePredefKey not available\n");
795 pCoInitializeEx(NULL
, COINIT_MULTITHREADED
);
797 hr
= CoGetClassObject(rclsid
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, (void **)&pUnk
);
800 IUnknown_Release(pUnk
);
802 res
= RegCreateKeyExA(HKEY_CURRENT_USER
, "Software\\Classes", 0, NULL
, 0,
803 KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
804 ok(!res
, "RegCreateKeyEx returned %d\n", res
);
806 res
= pRegOverridePredefKey(HKEY_CLASSES_ROOT
, hkey
);
807 ok(!res
, "RegOverridePredefKey returned %d\n", res
);
809 hr
= CoGetClassObject(rclsid
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, (void **)&pUnk
);
810 ok(hr
== S_OK
, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr
);
812 res
= pRegOverridePredefKey(HKEY_CLASSES_ROOT
, NULL
);
813 ok(!res
, "RegOverridePredefKey returned %d\n", res
);
815 if (hr
== S_OK
) IUnknown_Release(pUnk
);
819 hr
= CoGetClassObject(&CLSID_InProcFreeMarshaler
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, (void **)&pUnk
);
820 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
821 IUnknown_Release(pUnk
);
823 /* context redefines FreeMarshaler CLSID */
824 if ((handle
= activate_context(actctx_manifest
, &cookie
)))
826 hr
= CoGetClassObject(&CLSID_InProcFreeMarshaler
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, (void **)&pUnk
);
827 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
828 IUnknown_Release(pUnk
);
830 pDeactivateActCtx(0, cookie
);
831 pReleaseActCtx(handle
);
837 static void test_CoCreateInstanceEx(void)
839 MULTI_QI qi_res
= { &IID_IMoniker
};
845 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
846 CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &cookie
);
847 ok_ole_success(hr
, "CoRegisterClassObject");
849 create_instance_iid
= IID_NULL
;
850 hr
= CoCreateInstanceEx(&CLSID_WineOOPTest
, NULL
, CLSCTX_INPROC_SERVER
, NULL
, 1, &qi_res
);
851 ok(hr
== E_NOINTERFACE
, "CoCreateInstanceEx failed: %08x\n", hr
);
852 ok(IsEqualGUID(&create_instance_iid
, qi_res
.pIID
), "Unexpected CreateInstance iid %s\n",
853 wine_dbgstr_guid(&create_instance_iid
));
855 hr
= CoRevokeClassObject(cookie
);
856 ok_ole_success(hr
, "CoRevokeClassObject");
861 static ATOM
register_dummy_class(void)
869 GetModuleHandleA(NULL
),
871 LoadCursorA(NULL
, (LPSTR
)IDC_ARROW
),
872 (HBRUSH
)(COLOR_BTNFACE
+1),
877 return RegisterClassA(&wc
);
880 static void test_ole_menu(void)
885 hwndFrame
= CreateWindowA((LPCSTR
)MAKEINTATOM(register_dummy_class()), "Test", 0, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, NULL
, NULL
, NULL
, NULL
);
886 hr
= OleSetMenuDescriptor(NULL
, hwndFrame
, NULL
, NULL
, NULL
);
887 todo_wine
ok_ole_success(hr
, "OleSetMenuDescriptor");
889 DestroyWindow(hwndFrame
);
893 static HRESULT WINAPI
MessageFilter_QueryInterface(IMessageFilter
*iface
, REFIID riid
, void ** ppvObj
)
895 if (ppvObj
== NULL
) return E_POINTER
;
897 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
898 IsEqualGUID(riid
, &IID_IClassFactory
))
901 IMessageFilter_AddRef(iface
);
905 return E_NOINTERFACE
;
908 static ULONG WINAPI
MessageFilter_AddRef(IMessageFilter
*iface
)
910 return 2; /* non-heap object */
913 static ULONG WINAPI
MessageFilter_Release(IMessageFilter
*iface
)
915 return 1; /* non-heap object */
918 static DWORD WINAPI
MessageFilter_HandleInComingCall(
919 IMessageFilter
*iface
,
921 HTASK threadIDCaller
,
923 LPINTERFACEINFO lpInterfaceInfo
)
925 trace("HandleInComingCall\n");
926 return SERVERCALL_ISHANDLED
;
929 static DWORD WINAPI
MessageFilter_RetryRejectedCall(
930 IMessageFilter
*iface
,
931 HTASK threadIDCallee
,
935 trace("RetryRejectedCall\n");
939 static DWORD WINAPI
MessageFilter_MessagePending(
940 IMessageFilter
*iface
,
941 HTASK threadIDCallee
,
945 trace("MessagePending\n");
946 return PENDINGMSG_WAITNOPROCESS
;
949 static const IMessageFilterVtbl MessageFilter_Vtbl
=
951 MessageFilter_QueryInterface
,
952 MessageFilter_AddRef
,
953 MessageFilter_Release
,
954 MessageFilter_HandleInComingCall
,
955 MessageFilter_RetryRejectedCall
,
956 MessageFilter_MessagePending
959 static IMessageFilter MessageFilter
= { &MessageFilter_Vtbl
};
961 static void test_CoRegisterMessageFilter(void)
964 IMessageFilter
*prev_filter
;
966 hr
= CoRegisterMessageFilter(&MessageFilter
, &prev_filter
);
967 ok(hr
== CO_E_NOT_SUPPORTED
,
968 "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
971 pCoInitializeEx(NULL
, COINIT_MULTITHREADED
);
972 prev_filter
= (IMessageFilter
*)0xdeadbeef;
973 hr
= CoRegisterMessageFilter(&MessageFilter
, &prev_filter
);
974 ok(hr
== CO_E_NOT_SUPPORTED
,
975 "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
977 ok(prev_filter
== (IMessageFilter
*)0xdeadbeef,
978 "prev_filter should have been set to %p\n", prev_filter
);
981 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
983 hr
= CoRegisterMessageFilter(NULL
, NULL
);
984 ok_ole_success(hr
, "CoRegisterMessageFilter");
986 prev_filter
= (IMessageFilter
*)0xdeadbeef;
987 hr
= CoRegisterMessageFilter(NULL
, &prev_filter
);
988 ok_ole_success(hr
, "CoRegisterMessageFilter");
989 ok(prev_filter
== NULL
, "prev_filter should have been set to NULL instead of %p\n", prev_filter
);
991 hr
= CoRegisterMessageFilter(&MessageFilter
, &prev_filter
);
992 ok_ole_success(hr
, "CoRegisterMessageFilter");
993 ok(prev_filter
== NULL
, "prev_filter should have been set to NULL instead of %p\n", prev_filter
);
995 hr
= CoRegisterMessageFilter(NULL
, NULL
);
996 ok_ole_success(hr
, "CoRegisterMessageFilter");
1001 static IUnknown Test_Unknown
;
1003 static HRESULT WINAPI
EnumOLEVERB_QueryInterface(IEnumOLEVERB
*iface
, REFIID riid
, void **ppv
)
1005 return IUnknown_QueryInterface(&Test_Unknown
, riid
, ppv
);
1008 static ULONG WINAPI
EnumOLEVERB_AddRef(IEnumOLEVERB
*iface
)
1013 static ULONG WINAPI
EnumOLEVERB_Release(IEnumOLEVERB
*iface
)
1018 static HRESULT WINAPI
EnumOLEVERB_Next(IEnumOLEVERB
*iface
, ULONG celt
, OLEVERB
*rgelt
, ULONG
*fetched
)
1020 ok(0, "unexpected call\n");
1024 static HRESULT WINAPI
EnumOLEVERB_Skip(IEnumOLEVERB
*iface
, ULONG celt
)
1026 ok(0, "unexpected call\n");
1030 static HRESULT WINAPI
EnumOLEVERB_Reset(IEnumOLEVERB
*iface
)
1032 ok(0, "unexpected call\n");
1036 static HRESULT WINAPI
EnumOLEVERB_Clone(IEnumOLEVERB
*iface
, IEnumOLEVERB
**ppenum
)
1038 ok(0, "unexpected call\n");
1042 static const IEnumOLEVERBVtbl EnumOLEVERBVtbl
= {
1043 EnumOLEVERB_QueryInterface
,
1045 EnumOLEVERB_Release
,
1052 static IEnumOLEVERB EnumOLEVERB
= { &EnumOLEVERBVtbl
};
1054 static HRESULT WINAPI
Test_IUnknown_QueryInterface(
1059 if (ppvObj
== NULL
) return E_POINTER
;
1061 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IWineTest
)) {
1063 }else if(IsEqualIID(riid
, &IID_IEnumOLEVERB
)) {
1064 *ppvObj
= &EnumOLEVERB
;
1067 return E_NOINTERFACE
;
1070 IUnknown_AddRef((IUnknown
*)*ppvObj
);
1074 static ULONG WINAPI
Test_IUnknown_AddRef(IUnknown
*iface
)
1076 return 2; /* non-heap-based object */
1079 static ULONG WINAPI
Test_IUnknown_Release(IUnknown
*iface
)
1081 return 1; /* non-heap-based object */
1084 static const IUnknownVtbl TestUnknown_Vtbl
=
1086 Test_IUnknown_QueryInterface
,
1087 Test_IUnknown_AddRef
,
1088 Test_IUnknown_Release
,
1091 static IUnknown Test_Unknown
= { &TestUnknown_Vtbl
};
1093 static IPSFactoryBuffer
*ps_factory_buffer
;
1095 static HRESULT WINAPI
PSFactoryBuffer_QueryInterface(
1096 IPSFactoryBuffer
* This
,
1097 /* [in] */ REFIID riid
,
1098 /* [iid_is][out] */ void **ppvObject
)
1100 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1101 IsEqualIID(riid
, &IID_IPSFactoryBuffer
))
1104 IPSFactoryBuffer_AddRef(This
);
1107 return E_NOINTERFACE
;
1110 static ULONG WINAPI
PSFactoryBuffer_AddRef(
1111 IPSFactoryBuffer
* This
)
1116 static ULONG WINAPI
PSFactoryBuffer_Release(
1117 IPSFactoryBuffer
* This
)
1122 static HRESULT WINAPI
PSFactoryBuffer_CreateProxy(
1123 IPSFactoryBuffer
* This
,
1124 /* [in] */ IUnknown
*pUnkOuter
,
1125 /* [in] */ REFIID riid
,
1126 /* [out] */ IRpcProxyBuffer
**ppProxy
,
1127 /* [out] */ void **ppv
)
1132 static HRESULT WINAPI
PSFactoryBuffer_CreateStub(
1133 IPSFactoryBuffer
* This
,
1134 /* [in] */ REFIID riid
,
1135 /* [unique][in] */ IUnknown
*pUnkServer
,
1136 /* [out] */ IRpcStubBuffer
**ppStub
)
1138 CHECK_EXPECT(CreateStub
);
1140 ok(pUnkServer
== (IUnknown
*)&Test_Unknown
, "unexpected pUnkServer %p\n", pUnkServer
);
1141 if(!ps_factory_buffer
)
1144 return IPSFactoryBuffer_CreateStub(ps_factory_buffer
, &IID_IEnumOLEVERB
, pUnkServer
, ppStub
);
1147 static IPSFactoryBufferVtbl PSFactoryBufferVtbl
=
1149 PSFactoryBuffer_QueryInterface
,
1150 PSFactoryBuffer_AddRef
,
1151 PSFactoryBuffer_Release
,
1152 PSFactoryBuffer_CreateProxy
,
1153 PSFactoryBuffer_CreateStub
1156 static IPSFactoryBuffer PSFactoryBuffer
= { &PSFactoryBufferVtbl
};
1158 static const CLSID CLSID_WineTestPSFactoryBuffer
=
1163 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
1164 }; /* 52011640-8164-4fd0-a1a2-5d5a3654d3bd */
1166 static void test_CoRegisterPSClsid(void)
1169 DWORD dwRegistrationKey
;
1173 hr
= CoRegisterPSClsid(&IID_IWineTest
, &CLSID_WineTestPSFactoryBuffer
);
1174 ok(hr
== CO_E_NOTINITIALIZED
, "CoRegisterPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr
);
1176 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1178 hr
= CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer
, (IUnknown
*)&PSFactoryBuffer
,
1179 CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &dwRegistrationKey
);
1180 ok_ole_success(hr
, "CoRegisterClassObject");
1182 hr
= CoRegisterPSClsid(&IID_IWineTest
, &CLSID_WineTestPSFactoryBuffer
);
1183 ok_ole_success(hr
, "CoRegisterPSClsid");
1185 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1186 ok_ole_success(hr
, "CreateStreamOnHGlobal");
1188 SET_EXPECT(CreateStub
);
1189 hr
= CoMarshalInterface(stream
, &IID_IWineTest
, &Test_Unknown
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1190 ok(hr
== E_NOTIMPL
, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1191 CHECK_CALLED(CreateStub
);
1193 hr
= CoGetPSClsid(&IID_IEnumOLEVERB
, &clsid
);
1194 ok_ole_success(hr
, "CoGetPSClsid");
1196 hr
= CoGetClassObject(&clsid
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IPSFactoryBuffer
, (void **)&ps_factory_buffer
);
1197 ok_ole_success(hr
, "CoGetClassObject");
1199 hr
= CoRegisterPSClsid(&IID_IEnumOLEVERB
, &CLSID_WineTestPSFactoryBuffer
);
1200 ok_ole_success(hr
, "CoRegisterPSClsid");
1202 SET_EXPECT(CreateStub
);
1203 hr
= CoMarshalInterface(stream
, &IID_IEnumOLEVERB
, (IUnknown
*)&EnumOLEVERB
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1204 ok(hr
== S_OK
, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1205 CHECK_CALLED(CreateStub
);
1207 hr
= CoMarshalInterface(stream
, &IID_IEnumOLEVERB
, &Test_Unknown
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1208 ok(hr
== S_OK
, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr
);
1210 IStream_Release(stream
);
1211 IPSFactoryBuffer_Release(ps_factory_buffer
);
1212 ps_factory_buffer
= NULL
;
1214 hr
= CoRevokeClassObject(dwRegistrationKey
);
1215 ok_ole_success(hr
, "CoRevokeClassObject");
1219 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1221 hr
= CoGetPSClsid(&IID_IWineTest
, &clsid
);
1222 ok(hr
== REGDB_E_IIDNOTREG
, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08x\n", hr
);
1227 static void test_CoGetPSClsid(void)
1235 const BOOL is_win64
= (sizeof(void*) != sizeof(int));
1236 BOOL is_wow64
= FALSE
;
1238 hr
= CoGetPSClsid(&IID_IClassFactory
, &clsid
);
1239 ok(hr
== CO_E_NOTINITIALIZED
,
1240 "CoGetPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n",
1243 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1245 hr
= CoGetPSClsid(&IID_IClassFactory
, &clsid
);
1246 ok_ole_success(hr
, "CoGetPSClsid");
1248 hr
= CoGetPSClsid(&IID_IWineTest
, &clsid
);
1249 ok(hr
== REGDB_E_IIDNOTREG
,
1250 "CoGetPSClsid for random IID returned 0x%08x instead of REGDB_E_IIDNOTREG\n",
1253 hr
= CoGetPSClsid(&IID_IClassFactory
, NULL
);
1254 ok(hr
== E_INVALIDARG
,
1255 "CoGetPSClsid for null clsid returned 0x%08x instead of E_INVALIDARG\n",
1258 if (!pRegOverridePredefKey
)
1260 win_skip("RegOverridePredefKey not available\n");
1264 hr
= CoGetPSClsid(&IID_IClassFactory
, &clsid
);
1265 ok_ole_success(hr
, "CoGetPSClsid");
1267 res
= RegCreateKeyExA(HKEY_CURRENT_USER
, "Software\\Classes", 0, NULL
, 0,
1268 KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
1269 ok(!res
, "RegCreateKeyEx returned %d\n", res
);
1271 res
= pRegOverridePredefKey(HKEY_CLASSES_ROOT
, hkey
);
1272 ok(!res
, "RegOverridePredefKey returned %d\n", res
);
1274 hr
= CoGetPSClsid(&IID_IClassFactory
, &clsid
);
1275 ok_ole_success(hr
, "CoGetPSClsid");
1277 res
= pRegOverridePredefKey(HKEY_CLASSES_ROOT
, NULL
);
1278 ok(!res
, "RegOverridePredefKey returned %d\n", res
);
1282 /* not registered CLSID */
1283 hr
= CoGetPSClsid(&IID_Testiface
, &clsid
);
1284 ok(hr
== REGDB_E_IIDNOTREG
, "got 0x%08x\n", hr
);
1286 if ((handle
= activate_context(actctx_manifest
, &cookie
)))
1288 memset(&clsid
, 0, sizeof(clsid
));
1289 hr
= CoGetPSClsid(&IID_Testiface
, &clsid
);
1290 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1291 ok(IsEqualGUID(&clsid
, &IID_Testiface
), "got clsid %s\n", wine_dbgstr_guid(&clsid
));
1293 memset(&clsid
, 0, sizeof(clsid
));
1294 hr
= CoGetPSClsid(&IID_Testiface2
, &clsid
);
1295 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1296 ok(IsEqualGUID(&clsid
, &IID_Testiface2
), "got clsid %s\n", wine_dbgstr_guid(&clsid
));
1298 memset(&clsid
, 0, sizeof(clsid
));
1299 hr
= CoGetPSClsid(&IID_Testiface3
, &clsid
);
1300 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1301 ok(IsEqualGUID(&clsid
, &IID_TestPS
), "got clsid %s\n", wine_dbgstr_guid(&clsid
));
1303 memset(&clsid
, 0xaa, sizeof(clsid
));
1304 hr
= CoGetPSClsid(&IID_Testiface4
, &clsid
);
1305 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1306 ok(IsEqualGUID(&clsid
, &GUID_NULL
), "got clsid %s\n", wine_dbgstr_guid(&clsid
));
1308 /* register same interface and try to get CLSID back */
1309 hr
= CoRegisterPSClsid(&IID_Testiface
, &IID_Testiface4
);
1310 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1311 memset(&clsid
, 0, sizeof(clsid
));
1312 hr
= CoGetPSClsid(&IID_Testiface
, &clsid
);
1313 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1314 ok(IsEqualGUID(&clsid
, &IID_Testiface4
), "got clsid %s\n", wine_dbgstr_guid(&clsid
));
1316 pDeactivateActCtx(0, cookie
);
1317 pReleaseActCtx(handle
);
1320 if (pRegDeleteKeyExA
&&
1322 (pIsWow64Process
&& pIsWow64Process(GetCurrentProcess(), &is_wow64
) && is_wow64
)))
1324 static GUID IID_DeadBeef
= {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
1325 static const char clsidDeadBeef
[] = "{deadbeef-dead-beef-dead-beefdeadbeef}";
1326 static const char clsidA
[] = "{66666666-8888-7777-6666-555555555555}";
1327 HKEY hkey_iface
, hkey_psclsid
;
1328 REGSAM opposite
= is_win64
? KEY_WOW64_32KEY
: KEY_WOW64_64KEY
;
1330 hr
= CoGetPSClsid(&IID_DeadBeef
, &clsid
);
1331 ok(hr
== REGDB_E_IIDNOTREG
, "got 0x%08x\n", hr
);
1333 res
= RegCreateKeyExA(HKEY_CLASSES_ROOT
, "Interface",
1334 0, NULL
, 0, KEY_ALL_ACCESS
| opposite
, NULL
, &hkey_iface
, NULL
);
1335 ok(!res
, "RegCreateKeyEx returned %d\n", res
);
1336 res
= RegCreateKeyExA(hkey_iface
, clsidDeadBeef
,
1337 0, NULL
, 0, KEY_ALL_ACCESS
| opposite
, NULL
, &hkey
, NULL
);
1338 if (res
== ERROR_ACCESS_DENIED
)
1340 win_skip("Failed to create a key, skipping some of CoGetPSClsid() tests\n");
1344 ok(!res
, "RegCreateKeyEx returned %d\n", res
);
1345 res
= RegCreateKeyExA(hkey
, "ProxyStubClsid32",
1346 0, NULL
, 0, KEY_ALL_ACCESS
| opposite
, NULL
, &hkey_psclsid
, NULL
);
1347 ok(!res
, "RegCreateKeyEx returned %d\n", res
);
1348 res
= RegSetValueExA(hkey_psclsid
, NULL
, 0, REG_SZ
, (const BYTE
*)clsidA
, strlen(clsidA
)+1);
1349 ok(!res
, "RegSetValueEx returned %d\n", res
);
1350 RegCloseKey(hkey_psclsid
);
1352 hr
= CoGetPSClsid(&IID_DeadBeef
, &clsid
);
1353 ok_ole_success(hr
, "CoGetPSClsid");
1354 ok(IsEqualGUID(&clsid
, &IID_TestPS
), "got clsid %s\n", wine_dbgstr_guid(&clsid
));
1356 res
= pRegDeleteKeyExA(hkey
, "ProxyStubClsid32", opposite
, 0);
1357 ok(!res
, "RegDeleteKeyEx returned %d\n", res
);
1359 res
= pRegDeleteKeyExA(hkey_iface
, clsidDeadBeef
, opposite
, 0);
1360 ok(!res
, "RegDeleteKeyEx returned %d\n", res
);
1363 RegCloseKey(hkey_iface
);
1369 /* basic test, mainly for invalid arguments. see marshal.c for more */
1370 static void test_CoUnmarshalInterface(void)
1376 hr
= CoUnmarshalInterface(NULL
, &IID_IUnknown
, (void **)&pProxy
);
1377 ok(hr
== E_INVALIDARG
, "CoUnmarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1379 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
1380 ok_ole_success(hr
, "CreateStreamOnHGlobal");
1382 hr
= CoUnmarshalInterface(pStream
, &IID_IUnknown
, (void **)&pProxy
);
1384 ok(hr
== CO_E_NOTINITIALIZED
, "CoUnmarshalInterface should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr
);
1386 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1388 hr
= CoUnmarshalInterface(pStream
, &IID_IUnknown
, (void **)&pProxy
);
1389 ok(hr
== STG_E_READFAULT
, "CoUnmarshalInterface should have returned STG_E_READFAULT instead of 0x%08x\n", hr
);
1393 hr
= CoUnmarshalInterface(pStream
, &IID_IUnknown
, NULL
);
1394 ok(hr
== E_INVALIDARG
, "CoUnmarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1396 IStream_Release(pStream
);
1399 static void test_CoGetInterfaceAndReleaseStream(void)
1404 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1406 hr
= CoGetInterfaceAndReleaseStream(NULL
, &IID_IUnknown
, (void**)&pUnk
);
1407 ok(hr
== E_INVALIDARG
, "hr %08x\n", hr
);
1412 /* basic test, mainly for invalid arguments. see marshal.c for more */
1413 static void test_CoMarshalInterface(void)
1417 static const LARGE_INTEGER llZero
;
1419 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1421 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
1422 ok_ole_success(hr
, "CreateStreamOnHGlobal");
1424 hr
= CoMarshalInterface(pStream
, &IID_IUnknown
, NULL
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1425 ok(hr
== E_INVALIDARG
, "CoMarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1427 hr
= CoMarshalInterface(NULL
, &IID_IUnknown
, (IUnknown
*)&Test_ClassFactory
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1428 ok(hr
== E_INVALIDARG
, "CoMarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1430 hr
= CoMarshalInterface(pStream
, &IID_IUnknown
, (IUnknown
*)&Test_ClassFactory
, MSHCTX_INPROC
, NULL
, MSHLFLAGS_NORMAL
);
1431 ok_ole_success(hr
, "CoMarshalInterface");
1433 /* stream not rewound */
1434 hr
= CoReleaseMarshalData(pStream
);
1435 ok(hr
== STG_E_READFAULT
, "CoReleaseMarshalData should have returned STG_E_READFAULT instead of 0x%08x\n", hr
);
1437 hr
= IStream_Seek(pStream
, llZero
, STREAM_SEEK_SET
, NULL
);
1438 ok_ole_success(hr
, "IStream_Seek");
1440 hr
= CoReleaseMarshalData(pStream
);
1441 ok_ole_success(hr
, "CoReleaseMarshalData");
1443 IStream_Release(pStream
);
1448 static void test_CoMarshalInterThreadInterfaceInStream(void)
1452 IClassFactory
*pProxy
;
1454 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1458 hr
= CoMarshalInterThreadInterfaceInStream(&IID_IUnknown
, (IUnknown
*)&Test_ClassFactory
, NULL
);
1459 ok(hr
== E_INVALIDARG
, "CoMarshalInterThreadInterfaceInStream should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1461 hr
= CoMarshalInterThreadInterfaceInStream(&IID_IUnknown
, NULL
, &pStream
);
1462 ok(hr
== E_INVALIDARG
, "CoMarshalInterThreadInterfaceInStream should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1466 hr
= CoMarshalInterThreadInterfaceInStream(&IID_IUnknown
, (IUnknown
*)&Test_ClassFactory
, &pStream
);
1467 ok_ole_success(hr
, "CoMarshalInterThreadInterfaceInStream");
1469 ok_more_than_one_lock();
1471 hr
= CoUnmarshalInterface(pStream
, &IID_IClassFactory
, (void **)&pProxy
);
1472 ok_ole_success(hr
, "CoUnmarshalInterface");
1474 IClassFactory_Release(pProxy
);
1475 IStream_Release(pStream
);
1482 static void test_CoRegisterClassObject(void)
1484 ULONG_PTR ctxcookie
;
1490 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1492 /* CLSCTX_INPROC_SERVER */
1493 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1494 CLSCTX_INPROC_SERVER
, REGCLS_SINGLEUSE
, &cookie
);
1495 ok_ole_success(hr
, "CoRegisterClassObject");
1496 hr
= CoRevokeClassObject(cookie
);
1497 ok_ole_success(hr
, "CoRevokeClassObject");
1499 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1500 CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &cookie
);
1501 ok_ole_success(hr
, "CoRegisterClassObject");
1502 hr
= CoRevokeClassObject(cookie
);
1503 ok_ole_success(hr
, "CoRevokeClassObject");
1505 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1506 CLSCTX_INPROC_SERVER
, REGCLS_MULTI_SEPARATE
, &cookie
);
1507 ok_ole_success(hr
, "CoRegisterClassObject");
1508 hr
= CoRevokeClassObject(cookie
);
1509 ok_ole_success(hr
, "CoRevokeClassObject");
1511 /* CLSCTX_LOCAL_SERVER */
1512 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1513 CLSCTX_LOCAL_SERVER
, REGCLS_SINGLEUSE
, &cookie
);
1514 ok_ole_success(hr
, "CoRegisterClassObject");
1515 hr
= CoRevokeClassObject(cookie
);
1516 ok_ole_success(hr
, "CoRevokeClassObject");
1518 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1519 CLSCTX_LOCAL_SERVER
, REGCLS_MULTIPLEUSE
, &cookie
);
1520 ok_ole_success(hr
, "CoRegisterClassObject");
1521 hr
= CoRevokeClassObject(cookie
);
1522 ok_ole_success(hr
, "CoRevokeClassObject");
1524 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1525 CLSCTX_LOCAL_SERVER
, REGCLS_MULTI_SEPARATE
, &cookie
);
1526 ok_ole_success(hr
, "CoRegisterClassObject");
1527 hr
= CoRevokeClassObject(cookie
);
1528 ok_ole_success(hr
, "CoRevokeClassObject");
1530 /* CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER */
1531 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1532 CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
, REGCLS_SINGLEUSE
, &cookie
);
1533 ok_ole_success(hr
, "CoRegisterClassObject");
1534 hr
= CoRevokeClassObject(cookie
);
1535 ok_ole_success(hr
, "CoRevokeClassObject");
1537 /* test whether an object that doesn't support IClassFactory can be
1538 * registered for CLSCTX_LOCAL_SERVER */
1539 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, &Test_Unknown
,
1540 CLSCTX_LOCAL_SERVER
, REGCLS_SINGLEUSE
, &cookie
);
1541 ok_ole_success(hr
, "CoRegisterClassObject");
1542 hr
= CoRevokeClassObject(cookie
);
1543 ok_ole_success(hr
, "CoRevokeClassObject");
1545 /* test whether registered class becomes invalid when apartment is destroyed */
1546 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1547 CLSCTX_INPROC_SERVER
, REGCLS_SINGLEUSE
, &cookie
);
1548 ok_ole_success(hr
, "CoRegisterClassObject");
1551 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1553 hr
= CoGetClassObject(&CLSID_WineOOPTest
, CLSCTX_INPROC_SERVER
, NULL
,
1554 &IID_IClassFactory
, (void **)&pcf
);
1555 ok(hr
== REGDB_E_CLASSNOTREG
, "object registered in an apartment shouldn't accessible after it is destroyed\n");
1557 /* crashes with at least win9x DCOM! */
1559 CoRevokeClassObject(cookie
);
1561 /* test that object is accessible */
1562 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
, CLSCTX_INPROC_SERVER
,
1563 REGCLS_MULTIPLEUSE
, &cookie
);
1564 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1566 hr
= CoGetClassObject(&CLSID_WineOOPTest
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IClassFactory
, (void**)&pcf
);
1567 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1568 IClassFactory_Release(pcf
);
1570 /* context now contains CLSID_WineOOPTest, test if registered one could still be used */
1571 if ((handle
= activate_context(actctx_manifest
, &ctxcookie
)))
1573 hr
= CoGetClassObject(&CLSID_WineOOPTest
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IClassFactory
, (void**)&pcf
);
1575 ok(hr
== HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND
), "got 0x%08x\n", hr
);
1577 pDeactivateActCtx(0, ctxcookie
);
1578 pReleaseActCtx(handle
);
1581 hr
= CoGetClassObject(&CLSID_WineOOPTest
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IClassFactory
, (void**)&pcf
);
1582 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1583 IClassFactory_Release(pcf
);
1585 hr
= CoRevokeClassObject(cookie
);
1586 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1591 static HRESULT
get_class_object(CLSCTX clsctx
)
1596 hr
= CoGetClassObject(&CLSID_WineOOPTest
, clsctx
, NULL
, &IID_IClassFactory
,
1600 IClassFactory_Release(pcf
);
1605 static DWORD CALLBACK
get_class_object_thread(LPVOID pv
)
1607 CLSCTX clsctx
= (CLSCTX
)(DWORD_PTR
)pv
;
1610 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1612 hr
= get_class_object(clsctx
);
1619 static DWORD CALLBACK
get_class_object_proxy_thread(LPVOID pv
)
1621 CLSCTX clsctx
= (CLSCTX
)(DWORD_PTR
)pv
;
1626 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1628 hr
= CoGetClassObject(&CLSID_WineOOPTest
, clsctx
, NULL
, &IID_IClassFactory
,
1633 hr
= IClassFactory_QueryInterface(pcf
, &IID_IMultiQI
, (void **)&pMQI
);
1635 IMultiQI_Release(pMQI
);
1636 IClassFactory_Release(pcf
);
1644 static DWORD CALLBACK
register_class_object_thread(LPVOID pv
)
1649 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1651 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1652 CLSCTX_INPROC_SERVER
, REGCLS_SINGLEUSE
, &cookie
);
1659 static DWORD CALLBACK
revoke_class_object_thread(LPVOID pv
)
1661 DWORD cookie
= (DWORD_PTR
)pv
;
1664 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1666 hr
= CoRevokeClassObject(cookie
);
1673 static void test_registered_object_thread_affinity(void)
1681 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1683 /* CLSCTX_INPROC_SERVER */
1685 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1686 CLSCTX_INPROC_SERVER
, REGCLS_SINGLEUSE
, &cookie
);
1687 ok_ole_success(hr
, "CoRegisterClassObject");
1689 thread
= CreateThread(NULL
, 0, get_class_object_thread
, (LPVOID
)CLSCTX_INPROC_SERVER
, 0, &tid
);
1690 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1691 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
1692 GetExitCodeThread(thread
, &exitcode
);
1694 ok(hr
== REGDB_E_CLASSNOTREG
, "CoGetClassObject on inproc object "
1695 "registered in different thread should return REGDB_E_CLASSNOTREG "
1696 "instead of 0x%08x\n", hr
);
1698 hr
= get_class_object(CLSCTX_INPROC_SERVER
);
1699 ok(hr
== S_OK
, "CoGetClassObject on inproc object registered in same "
1700 "thread should return S_OK instead of 0x%08x\n", hr
);
1702 thread
= CreateThread(NULL
, 0, register_class_object_thread
, NULL
, 0, &tid
);
1703 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1704 ok ( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
1705 GetExitCodeThread(thread
, &exitcode
);
1707 ok(hr
== S_OK
, "CoRegisterClassObject with same CLSID but in different thread should return S_OK instead of 0x%08x\n", hr
);
1709 hr
= CoRevokeClassObject(cookie
);
1710 ok_ole_success(hr
, "CoRevokeClassObject");
1712 /* CLSCTX_LOCAL_SERVER */
1714 hr
= CoRegisterClassObject(&CLSID_WineOOPTest
, (IUnknown
*)&Test_ClassFactory
,
1715 CLSCTX_LOCAL_SERVER
, REGCLS_MULTIPLEUSE
, &cookie
);
1716 ok_ole_success(hr
, "CoRegisterClassObject");
1718 thread
= CreateThread(NULL
, 0, get_class_object_proxy_thread
, (LPVOID
)CLSCTX_LOCAL_SERVER
, 0, &tid
);
1719 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1720 while (MsgWaitForMultipleObjects(1, &thread
, FALSE
, 10000, QS_ALLINPUT
) == WAIT_OBJECT_0
+ 1)
1723 while (PeekMessageA(&msg
, NULL
, 0, 0, PM_REMOVE
))
1725 TranslateMessage(&msg
);
1726 DispatchMessageA(&msg
);
1729 GetExitCodeThread(thread
, &exitcode
);
1731 ok(hr
== S_OK
, "CoGetClassObject on local server object "
1732 "registered in different thread should return S_OK "
1733 "instead of 0x%08x\n", hr
);
1735 hr
= get_class_object(CLSCTX_LOCAL_SERVER
);
1736 ok(hr
== S_OK
, "CoGetClassObject on local server object registered in same "
1737 "thread should return S_OK instead of 0x%08x\n", hr
);
1739 thread
= CreateThread(NULL
, 0, revoke_class_object_thread
, (LPVOID
)(DWORD_PTR
)cookie
, 0, &tid
);
1740 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1741 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
1742 GetExitCodeThread(thread
, &exitcode
);
1744 ok(hr
== RPC_E_WRONG_THREAD
|| broken(hr
== S_OK
) /* win8 */, "CoRevokeClassObject called from different "
1745 "thread to where registered should return RPC_E_WRONG_THREAD instead of 0x%08x\n", hr
);
1747 thread
= CreateThread(NULL
, 0, register_class_object_thread
, NULL
, 0, &tid
);
1748 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1749 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
1750 GetExitCodeThread(thread
, &exitcode
);
1752 ok(hr
== S_OK
, "CoRegisterClassObject with same CLSID but in different "
1753 "thread should return S_OK instead of 0x%08x\n", hr
);
1755 hr
= CoRevokeClassObject(cookie
);
1756 ok_ole_success(hr
, "CoRevokeClassObject");
1761 static DWORD CALLBACK
free_libraries_thread(LPVOID p
)
1763 CoFreeUnusedLibraries();
1767 static inline BOOL
is_module_loaded(const char *module
)
1769 return GetModuleHandleA(module
) != 0;
1772 static void test_CoFreeUnusedLibraries(void)
1779 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1781 ok(!is_module_loaded("urlmon.dll"), "urlmon.dll shouldn't be loaded\n");
1783 hr
= CoCreateInstance(&CLSID_FileProtocol
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IInternetProtocol
, (void **)&pUnk
);
1784 if (hr
== REGDB_E_CLASSNOTREG
)
1786 skip("IE not installed so can't run CoFreeUnusedLibraries test\n");
1790 ok_ole_success(hr
, "CoCreateInstance");
1792 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1795 broken(pUnk
== NULL
), /* win9x */
1796 "Expected a valid pointer\n");
1798 IUnknown_Release(pUnk
);
1800 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1802 thread
= CreateThread(NULL
, 0, free_libraries_thread
, NULL
, 0, &tid
);
1803 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
1804 CloseHandle(thread
);
1806 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1808 CoFreeUnusedLibraries();
1810 ok(!is_module_loaded("urlmon.dll"), "urlmon.dll shouldn't be loaded\n");
1815 static void test_CoGetObjectContext(void)
1819 IComThreadingInfo
*pComThreadingInfo
, *threadinginfo2
;
1820 IContextCallback
*pContextCallback
;
1821 IObjContext
*pObjContext
;
1826 DWORD tid
, exitcode
;
1829 if (!pCoGetObjectContext
)
1831 win_skip("CoGetObjectContext not present\n");
1835 hr
= pCoGetObjectContext(&IID_IComThreadingInfo
, (void **)&pComThreadingInfo
);
1836 ok(hr
== CO_E_NOTINITIALIZED
, "CoGetObjectContext should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr
);
1837 ok(pComThreadingInfo
== NULL
, "pComThreadingInfo should have been set to NULL\n");
1839 /* show that COM doesn't have to be initialized for multi-threaded apartments if another
1840 thread has already done so */
1842 test_apt_type(APTTYPE_CURRENT
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
1844 info
.wait
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
1845 ok(info
.wait
!= NULL
, "CreateEvent failed with error %d\n", GetLastError());
1847 info
.stop
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
1848 ok(info
.stop
!= NULL
, "CreateEvent failed with error %d\n", GetLastError());
1850 thread
= CreateThread(NULL
, 0, ole_initialize_thread
, &info
, 0, &tid
);
1851 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1853 ok( !WaitForSingleObject(info
.wait
, 10000), "wait timed out\n" );
1855 test_apt_type(APTTYPE_MTA
, APTTYPEQUALIFIER_IMPLICIT_MTA
, TRUE
, TRUE
);
1857 pComThreadingInfo
= NULL
;
1858 hr
= pCoGetObjectContext(&IID_IComThreadingInfo
, (void **)&pComThreadingInfo
);
1859 ok(hr
== S_OK
, "Expected S_OK, got 0x%08x\n", hr
);
1861 threadinginfo2
= NULL
;
1862 hr
= pCoGetObjectContext(&IID_IComThreadingInfo
, (void **)&threadinginfo2
);
1863 ok(hr
== S_OK
, "Expected S_OK, got 0x%08x\n", hr
);
1864 ok(pComThreadingInfo
== threadinginfo2
, "got different instance\n");
1865 IComThreadingInfo_Release(threadinginfo2
);
1867 hr
= IComThreadingInfo_GetCurrentLogicalThreadId(pComThreadingInfo
, NULL
);
1868 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1870 id
= id2
= GUID_NULL
;
1871 hr
= IComThreadingInfo_GetCurrentLogicalThreadId(pComThreadingInfo
, &id
);
1872 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1874 hr
= CoGetCurrentLogicalThreadId(&id2
);
1875 ok(IsEqualGUID(&id
, &id2
), "got %s, expected %s\n", wine_dbgstr_guid(&id
), wine_dbgstr_guid(&id2
));
1877 IComThreadingInfo_Release(pComThreadingInfo
);
1879 SetEvent(info
.stop
);
1880 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
1882 GetExitCodeThread(thread
, &exitcode
);
1884 ok(hr
== S_OK
, "thread should have returned S_OK instead of 0x%08x\n", hr
);
1886 CloseHandle(thread
);
1887 CloseHandle(info
.wait
);
1888 CloseHandle(info
.stop
);
1890 test_apt_type(APTTYPE_CURRENT
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
1892 pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1894 test_apt_type(APTTYPE_MAINSTA
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
1896 hr
= pCoGetObjectContext(&IID_IComThreadingInfo
, (void **)&pComThreadingInfo
);
1897 ok_ole_success(hr
, "CoGetObjectContext");
1899 hr
= IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo
, &apttype
);
1900 ok_ole_success(hr
, "IComThreadingInfo_GetCurrentApartmentType");
1901 ok(apttype
== APTTYPE_MAINSTA
, "apartment type should be APTTYPE_MAINSTA instead of %d\n", apttype
);
1903 hr
= IComThreadingInfo_GetCurrentThreadType(pComThreadingInfo
, &thdtype
);
1904 ok_ole_success(hr
, "IComThreadingInfo_GetCurrentThreadType");
1905 ok(thdtype
== THDTYPE_PROCESSMESSAGES
, "thread type should be THDTYPE_PROCESSMESSAGES instead of %d\n", thdtype
);
1907 refs
= IComThreadingInfo_Release(pComThreadingInfo
);
1908 ok(refs
== 0, "pComThreadingInfo should have 0 refs instead of %d refs\n", refs
);
1910 hr
= pCoGetObjectContext(&IID_IContextCallback
, (void **)&pContextCallback
);
1911 ok_ole_success(hr
, "CoGetObjectContext(ContextCallback)");
1913 refs
= IContextCallback_Release(pContextCallback
);
1914 ok(refs
== 0, "pContextCallback should have 0 refs instead of %d refs\n", refs
);
1918 pCoInitializeEx(NULL
, COINIT_MULTITHREADED
);
1920 hr
= pCoGetObjectContext(&IID_IComThreadingInfo
, (void **)&pComThreadingInfo
);
1921 ok_ole_success(hr
, "CoGetObjectContext");
1923 hr
= IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo
, &apttype
);
1924 ok_ole_success(hr
, "IComThreadingInfo_GetCurrentApartmentType");
1925 ok(apttype
== APTTYPE_MTA
, "apartment type should be APTTYPE_MTA instead of %d\n", apttype
);
1927 hr
= IComThreadingInfo_GetCurrentThreadType(pComThreadingInfo
, &thdtype
);
1928 ok_ole_success(hr
, "IComThreadingInfo_GetCurrentThreadType");
1929 ok(thdtype
== THDTYPE_BLOCKMESSAGES
, "thread type should be THDTYPE_BLOCKMESSAGES instead of %d\n", thdtype
);
1931 refs
= IComThreadingInfo_Release(pComThreadingInfo
);
1932 ok(refs
== 0, "pComThreadingInfo should have 0 refs instead of %d refs\n", refs
);
1934 hr
= pCoGetObjectContext(&IID_IContextCallback
, (void **)&pContextCallback
);
1935 ok_ole_success(hr
, "CoGetObjectContext(ContextCallback)");
1937 refs
= IContextCallback_Release(pContextCallback
);
1938 ok(refs
== 0, "pContextCallback should have 0 refs instead of %d refs\n", refs
);
1940 hr
= pCoGetObjectContext(&IID_IObjContext
, (void **)&pObjContext
);
1941 ok_ole_success(hr
, "CoGetObjectContext");
1943 refs
= IObjContext_Release(pObjContext
);
1944 ok(refs
== 0, "pObjContext should have 0 refs instead of %d refs\n", refs
);
1950 IUnknown IUnknown_iface
;
1954 static inline Test_CallContext
*impl_from_IUnknown(IUnknown
*iface
)
1956 return CONTAINING_RECORD(iface
, Test_CallContext
, IUnknown_iface
);
1959 static HRESULT WINAPI
Test_CallContext_QueryInterface(
1964 if (ppvObj
== NULL
) return E_POINTER
;
1966 if (IsEqualGUID(riid
, &IID_IUnknown
))
1969 IUnknown_AddRef(iface
);
1974 return E_NOINTERFACE
;
1977 static ULONG WINAPI
Test_CallContext_AddRef(IUnknown
*iface
)
1979 Test_CallContext
*This
= impl_from_IUnknown(iface
);
1980 return InterlockedIncrement(&This
->refs
);
1983 static ULONG WINAPI
Test_CallContext_Release(IUnknown
*iface
)
1985 Test_CallContext
*This
= impl_from_IUnknown(iface
);
1986 ULONG refs
= InterlockedDecrement(&This
->refs
);
1988 HeapFree(GetProcessHeap(), 0, This
);
1992 static const IUnknownVtbl TestCallContext_Vtbl
=
1994 Test_CallContext_QueryInterface
,
1995 Test_CallContext_AddRef
,
1996 Test_CallContext_Release
1999 static void test_CoGetCallContext(void)
2004 Test_CallContext
*test_object
;
2006 if (!pCoSwitchCallContext
)
2008 skip("CoSwitchCallContext not present\n");
2014 test_object
= HeapAlloc(GetProcessHeap(), 0, sizeof(Test_CallContext
));
2015 test_object
->IUnknown_iface
.lpVtbl
= &TestCallContext_Vtbl
;
2016 test_object
->refs
= 1;
2018 hr
= CoGetCallContext(&IID_IUnknown
, (void**)&pUnk
);
2019 ok(hr
== RPC_E_CALL_COMPLETE
, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr
);
2021 pUnk
= (IUnknown
*)0xdeadbeef;
2022 hr
= pCoSwitchCallContext(&test_object
->IUnknown_iface
, &pUnk
);
2023 ok_ole_success(hr
, "CoSwitchCallContext");
2024 ok(pUnk
== NULL
, "expected NULL, got %p\n", pUnk
);
2025 refs
= IUnknown_AddRef(&test_object
->IUnknown_iface
);
2026 ok(refs
== 2, "Expected refcount 2, got %d\n", refs
);
2027 IUnknown_Release(&test_object
->IUnknown_iface
);
2029 pUnk
= (IUnknown
*)0xdeadbeef;
2030 hr
= CoGetCallContext(&IID_IUnknown
, (void**)&pUnk
);
2031 ok_ole_success(hr
, "CoGetCallContext");
2032 ok(pUnk
== &test_object
->IUnknown_iface
, "expected %p, got %p\n",
2033 &test_object
->IUnknown_iface
, pUnk
);
2034 refs
= IUnknown_AddRef(&test_object
->IUnknown_iface
);
2035 ok(refs
== 3, "Expected refcount 3, got %d\n", refs
);
2036 IUnknown_Release(&test_object
->IUnknown_iface
);
2037 IUnknown_Release(pUnk
);
2039 pUnk
= (IUnknown
*)0xdeadbeef;
2040 hr
= pCoSwitchCallContext(NULL
, &pUnk
);
2041 ok_ole_success(hr
, "CoSwitchCallContext");
2042 ok(pUnk
== &test_object
->IUnknown_iface
, "expected %p, got %p\n",
2043 &test_object
->IUnknown_iface
, pUnk
);
2044 refs
= IUnknown_AddRef(&test_object
->IUnknown_iface
);
2045 ok(refs
== 2, "Expected refcount 2, got %d\n", refs
);
2046 IUnknown_Release(&test_object
->IUnknown_iface
);
2048 hr
= CoGetCallContext(&IID_IUnknown
, (void**)&pUnk
);
2049 ok(hr
== RPC_E_CALL_COMPLETE
, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr
);
2051 IUnknown_Release(&test_object
->IUnknown_iface
);
2056 static void test_CoGetContextToken(void)
2060 ULONG_PTR token
, token2
;
2064 DWORD tid
, exitcode
;
2066 if (!pCoGetContextToken
)
2068 win_skip("CoGetContextToken not present\n");
2073 hr
= pCoGetContextToken(&token
);
2074 ok(hr
== CO_E_NOTINITIALIZED
, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr
);
2075 ok(token
== 0xdeadbeef, "Expected 0, got 0x%lx\n", token
);
2077 /* show that COM doesn't have to be initialized for multi-threaded apartments if another
2078 thread has already done so */
2080 test_apt_type(APTTYPE_CURRENT
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
2082 info
.wait
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2083 ok(info
.wait
!= NULL
, "CreateEvent failed with error %d\n", GetLastError());
2085 info
.stop
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2086 ok(info
.stop
!= NULL
, "CreateEvent failed with error %d\n", GetLastError());
2088 thread
= CreateThread(NULL
, 0, ole_initialize_thread
, &info
, 0, &tid
);
2089 ok(thread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
2091 ok( !WaitForSingleObject(info
.wait
, 10000), "wait timed out\n" );
2093 test_apt_type(APTTYPE_MTA
, APTTYPEQUALIFIER_IMPLICIT_MTA
, TRUE
, TRUE
);
2096 hr
= pCoGetContextToken(&token
);
2097 ok(hr
== S_OK
, "Expected S_OK, got 0x%08x\n", hr
);
2100 hr
= pCoGetContextToken(&token2
);
2101 ok(hr
== S_OK
, "Expected S_OK, got 0x%08x\n", hr
);
2102 ok(token
== token2
, "got different token\n");
2104 SetEvent(info
.stop
);
2105 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
2107 GetExitCodeThread(thread
, &exitcode
);
2109 ok(hr
== S_OK
, "thread should have returned S_OK instead of 0x%08x\n", hr
);
2111 CloseHandle(thread
);
2112 CloseHandle(info
.wait
);
2113 CloseHandle(info
.stop
);
2115 test_apt_type(APTTYPE_CURRENT
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
2119 test_apt_type(APTTYPE_MAINSTA
, APTTYPEQUALIFIER_NONE
, FALSE
, FALSE
);
2121 hr
= pCoGetContextToken(NULL
);
2122 ok(hr
== E_POINTER
, "Expected E_POINTER, got 0x%08x\n", hr
);
2125 hr
= pCoGetContextToken(&token
);
2126 ok(hr
== S_OK
, "Expected S_OK, got 0x%08x\n", hr
);
2127 ok(token
, "Expected token != 0\n");
2130 hr
= pCoGetContextToken(&token2
);
2131 ok(hr
== S_OK
, "Expected S_OK, got 0x%08x\n", hr
);
2132 ok(token2
== token
, "got different token\n");
2134 refs
= IUnknown_AddRef((IUnknown
*)token
);
2135 ok(refs
== 1, "Expected 1, got %u\n", refs
);
2137 hr
= pCoGetObjectContext(&IID_IObjContext
, (void **)&ctx
);
2138 ok(hr
== S_OK
, "Expected S_OK, got 0x%08x\n", hr
);
2139 ok(ctx
== (IObjContext
*)token
, "Expected interface pointers to be the same\n");
2141 refs
= IObjContext_AddRef(ctx
);
2142 ok(refs
== 3, "Expected 3, got %u\n", refs
);
2144 refs
= IObjContext_Release(ctx
);
2145 ok(refs
== 2, "Expected 2, got %u\n", refs
);
2147 refs
= IUnknown_Release((IUnknown
*)token
);
2148 ok(refs
== 1, "Expected 1, got %u\n", refs
);
2150 /* CoGetContextToken does not add a reference */
2152 hr
= pCoGetContextToken(&token
);
2153 ok(hr
== S_OK
, "Expected S_OK, got 0x%08x\n", hr
);
2154 ok(token
, "Expected token != 0\n");
2155 ok(ctx
== (IObjContext
*)token
, "Expected interface pointers to be the same\n");
2157 refs
= IObjContext_AddRef(ctx
);
2158 ok(refs
== 2, "Expected 1, got %u\n", refs
);
2160 refs
= IObjContext_Release(ctx
);
2161 ok(refs
== 1, "Expected 0, got %u\n", refs
);
2163 refs
= IObjContext_Release(ctx
);
2164 ok(refs
== 0, "Expected 0, got %u\n", refs
);
2169 static void test_TreatAsClass(void)
2173 static GUID deadbeef
= {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
2174 static const char deadbeefA
[] = "{DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF}";
2175 IInternetProtocol
*pIP
= NULL
;
2176 HKEY clsidkey
, deadbeefkey
;
2179 if (!pCoGetTreatAsClass
)
2181 win_skip("CoGetTreatAsClass not present\n");
2184 hr
= pCoGetTreatAsClass(&deadbeef
,&out
);
2185 ok (hr
== S_FALSE
, "expected S_FALSE got %x\n",hr
);
2186 ok (IsEqualGUID(&out
,&deadbeef
), "expected to get same clsid back\n");
2188 lr
= RegOpenKeyExA(HKEY_CLASSES_ROOT
, "CLSID", 0, KEY_READ
, &clsidkey
);
2189 ok(!lr
, "Couldn't open CLSID key, error %d\n", lr
);
2191 lr
= RegCreateKeyExA(clsidkey
, deadbeefA
, 0, NULL
, 0, KEY_WRITE
, NULL
, &deadbeefkey
, NULL
);
2193 win_skip("CoGetTreatAsClass() tests will be skipped (failed to create a test key, error %d)\n", lr
);
2194 RegCloseKey(clsidkey
);
2198 hr
= pCoTreatAsClass(&deadbeef
, &deadbeef
);
2199 ok(hr
== REGDB_E_WRITEREGDB
, "CoTreatAsClass gave wrong error: %08x\n", hr
);
2201 hr
= pCoTreatAsClass(&deadbeef
, &CLSID_FileProtocol
);
2202 if(hr
== REGDB_E_WRITEREGDB
){
2203 win_skip("Insufficient privileges to use CoTreatAsClass\n");
2206 ok(hr
== S_OK
, "CoTreatAsClass failed: %08x\n", hr
);
2208 hr
= pCoGetTreatAsClass(&deadbeef
, &out
);
2209 ok(hr
== S_OK
, "CoGetTreatAsClass failed: %08x\n",hr
);
2210 ok(IsEqualGUID(&out
, &CLSID_FileProtocol
), "expected to get substituted clsid\n");
2212 OleInitialize(NULL
);
2214 hr
= CoCreateInstance(&deadbeef
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IInternetProtocol
, (void **)&pIP
);
2215 if(hr
== REGDB_E_CLASSNOTREG
)
2217 win_skip("IE not installed so can't test CoCreateInstance\n");
2221 ok(hr
== S_OK
, "CoCreateInstance failed: %08x\n", hr
);
2223 IInternetProtocol_Release(pIP
);
2227 hr
= pCoTreatAsClass(&deadbeef
, &CLSID_NULL
);
2228 ok(hr
== S_OK
, "CoTreatAsClass failed: %08x\n", hr
);
2230 hr
= pCoGetTreatAsClass(&deadbeef
, &out
);
2231 ok(hr
== S_FALSE
, "expected S_FALSE got %08x\n", hr
);
2232 ok(IsEqualGUID(&out
, &deadbeef
), "expected to get same clsid back\n");
2234 /* bizarrely, native's CoTreatAsClass takes some time to take effect in CoCreateInstance */
2237 hr
= CoCreateInstance(&deadbeef
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IInternetProtocol
, (void **)&pIP
);
2238 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance gave wrong error: %08x\n", hr
);
2241 IInternetProtocol_Release(pIP
);
2245 RegCloseKey(deadbeefkey
);
2246 RegDeleteKeyA(clsidkey
, deadbeefA
);
2247 RegCloseKey(clsidkey
);
2250 static void test_CoInitializeEx(void)
2254 hr
= pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2255 ok(hr
== S_OK
, "CoInitializeEx failed with error 0x%08x\n", hr
);
2257 /* Calling OleInitialize for the first time should yield S_OK even with
2258 * apartment already initialized by previous CoInitialize(Ex) calls. */
2259 hr
= OleInitialize(NULL
);
2260 ok(hr
== S_OK
, "OleInitialize failed with error 0x%08x\n", hr
);
2262 /* Subsequent calls to OleInitialize should return S_FALSE */
2263 hr
= OleInitialize(NULL
);
2264 ok(hr
== S_FALSE
, "Expected S_FALSE, hr = 0x%08x\n", hr
);
2272 static void test_OleInitialize_InitCounting(void)
2276 REFCLSID rclsid
= &CLSID_InternetZoneManager
;
2278 /* 1. OleInitialize fails but OleUninitialize is still called: apartment stays initialized */
2279 hr
= pCoInitializeEx(NULL
, COINIT_MULTITHREADED
);
2280 ok(hr
== S_OK
, "CoInitializeEx(COINIT_MULTITHREADED) failed with error 0x%08x\n", hr
);
2282 hr
= OleInitialize(NULL
);
2283 ok(hr
== RPC_E_CHANGED_MODE
, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", RPC_E_CHANGED_MODE
, hr
);
2286 pUnk
= (IUnknown
*)0xdeadbeef;
2287 hr
= CoCreateInstance(rclsid
, NULL
, 0x17, &IID_IUnknown
, (void **)&pUnk
);
2288 ok(hr
== S_OK
, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK
, hr
);
2289 if (pUnk
) IUnknown_Release(pUnk
);
2293 /* 2. Extra multiple OleUninitialize: apartment stays initialized until CoUninitialize */
2294 hr
= CoInitialize(NULL
);
2295 ok(hr
== S_OK
, "CoInitialize() failed with error 0x%08x\n", hr
);
2297 hr
= OleInitialize(NULL
);
2298 ok(hr
== S_OK
, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK
, hr
);
2303 pUnk
= (IUnknown
*)0xdeadbeef;
2304 hr
= CoCreateInstance(rclsid
, NULL
, 0x17, &IID_IUnknown
, (void **)&pUnk
);
2305 ok(hr
== S_OK
, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK
, hr
);
2306 if (pUnk
) IUnknown_Release(pUnk
);
2310 pUnk
= (IUnknown
*)0xdeadbeef;
2311 hr
= CoCreateInstance(rclsid
, NULL
, 0x17, &IID_IUnknown
, (void **)&pUnk
);
2312 ok(hr
== CO_E_NOTINITIALIZED
, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED
, hr
);
2313 if (pUnk
) IUnknown_Release(pUnk
);
2315 /* 3. CoUninitialize does not formally deinit Ole */
2316 hr
= CoInitialize(NULL
);
2317 ok(hr
== S_OK
, "CoInitialize() failed with error 0x%08x\n", hr
);
2319 hr
= OleInitialize(NULL
);
2320 ok(hr
== S_OK
, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK
, hr
);
2325 pUnk
= (IUnknown
*)0xdeadbeef;
2326 hr
= CoCreateInstance(rclsid
, NULL
, 0x17, &IID_IUnknown
, (void **)&pUnk
);
2327 ok(hr
== CO_E_NOTINITIALIZED
, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED
, hr
);
2328 /* COM is not initialized anymore */
2329 if (pUnk
) IUnknown_Release(pUnk
);
2331 hr
= OleInitialize(NULL
);
2332 ok(hr
== S_FALSE
, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_FALSE
, hr
);
2333 /* ... but native OleInit returns S_FALSE as if Ole is considered initialized */
2339 static void test_OleRegGetMiscStatus(void)
2346 hr
= OleRegGetMiscStatus(&CLSID_Testclass
, DVASPECT_ICON
, NULL
);
2347 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2349 status
= 0xdeadbeef;
2350 hr
= OleRegGetMiscStatus(&CLSID_Testclass
, DVASPECT_ICON
, &status
);
2351 ok(hr
== REGDB_E_CLASSNOTREG
, "got 0x%08x\n", hr
);
2352 ok(status
== 0, "got 0x%08x\n", status
);
2355 hr
= OleRegGetMiscStatus(&CLSID_StdFont
, DVASPECT_ICON
, &status
);
2356 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2357 ok(status
== 0, "got 0x%08x\n", status
);
2359 if ((handle
= activate_context(actctx_manifest
, &cookie
)))
2362 hr
= OleRegGetMiscStatus(&CLSID_Testclass
, DVASPECT_ICON
, &status
);
2363 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2364 ok(status
== OLEMISC_RECOMPOSEONRESIZE
, "got 0x%08x\n", status
);
2366 /* context data takes precedence over registration info */
2368 hr
= OleRegGetMiscStatus(&CLSID_StdFont
, DVASPECT_ICON
, &status
);
2369 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2370 ok(status
== OLEMISC_RECOMPOSEONRESIZE
, "got 0x%08x\n", status
);
2372 /* there's no such attribute in context */
2374 hr
= OleRegGetMiscStatus(&CLSID_Testclass
, DVASPECT_DOCPRINT
, &status
);
2375 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2376 ok(status
== 0, "got 0x%08x\n", status
);
2378 pDeactivateActCtx(0, cookie
);
2379 pReleaseActCtx(handle
);
2383 static void test_OleRegGetUserType(void)
2385 static const WCHAR stdfont_usertypeW
[] = {'S','t','a','n','d','a','r','d',' ','F','o','n','t',0};
2386 static const WCHAR stdfont2_usertypeW
[] = {'C','L','S','I','D','_','S','t','d','F','o','n','t',0};
2387 static const WCHAR clsidkeyW
[] = {'C','L','S','I','D',0};
2388 static const WCHAR defvalueW
[] = {'D','e','f','a','u','l','t',' ','N','a','m','e',0};
2389 static const WCHAR auxvalue0W
[] = {'A','u','x',' ','N','a','m','e',' ','0',0};
2390 static const WCHAR auxvalue2W
[] = {'A','u','x',' ','N','a','m','e',' ','2',0};
2391 static const WCHAR auxvalue3W
[] = {'A','u','x',' ','N','a','m','e',' ','3',0};
2392 static const WCHAR auxvalue4W
[] = {'A','u','x',' ','N','a','m','e',' ','4',0};
2394 static const char auxvalues
[][16] = {
2402 HKEY clsidhkey
, hkey
, auxhkey
, classkey
;
2403 DWORD form
, ret
, disposition
;
2411 for (form
= 0; form
<= USERCLASSTYPE_APPNAME
+1; form
++) {
2412 hr
= OleRegGetUserType(&CLSID_Testclass
, form
, NULL
);
2413 ok(hr
== E_INVALIDARG
, "form %u: got 0x%08x\n", form
, hr
);
2415 str
= (void*)0xdeadbeef;
2416 hr
= OleRegGetUserType(&CLSID_Testclass
, form
, &str
);
2417 ok(hr
== REGDB_E_CLASSNOTREG
, "form %u: got 0x%08x\n", form
, hr
);
2418 ok(str
== NULL
, "form %u: got %p\n", form
, str
);
2420 /* same string returned for StdFont for all form types */
2422 hr
= OleRegGetUserType(&CLSID_StdFont
, form
, &str
);
2423 ok(hr
== S_OK
, "form %u: got 0x%08x\n", form
, hr
);
2424 ok(!lstrcmpW(str
, stdfont_usertypeW
) || !lstrcmpW(str
, stdfont2_usertypeW
) /* winxp */,
2425 "form %u, got %s\n", form
, wine_dbgstr_w(str
));
2429 if ((handle
= activate_context(actctx_manifest
, &cookie
)))
2431 for (form
= 0; form
<= USERCLASSTYPE_APPNAME
+1; form
++) {
2432 str
= (void*)0xdeadbeef;
2433 hr
= OleRegGetUserType(&CLSID_Testclass
, form
, &str
);
2434 ok(hr
== REGDB_E_CLASSNOTREG
, "form %u: got 0x%08x\n", form
, hr
);
2435 ok(str
== NULL
, "form %u: got %s\n", form
, wine_dbgstr_w(str
));
2437 /* same string returned for StdFont for all form types */
2439 hr
= OleRegGetUserType(&CLSID_StdFont
, form
, &str
);
2440 ok(hr
== S_OK
, "form %u: got 0x%08x\n", form
, hr
);
2441 ok(!lstrcmpW(str
, stdfont_usertypeW
) || !lstrcmpW(str
, stdfont2_usertypeW
) /* winxp */,
2442 "form %u, got %s\n", form
, wine_dbgstr_w(str
));
2446 pDeactivateActCtx(0, cookie
);
2447 pReleaseActCtx(handle
);
2450 /* test using registered CLSID */
2451 StringFromGUID2(&CLSID_non_existent
, clsidW
, sizeof(clsidW
)/sizeof(clsidW
[0]));
2453 ret
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsidkeyW
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &clsidhkey
, &disposition
);
2456 ret
= RegCreateKeyExW(clsidhkey
, clsidW
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &classkey
, NULL
);
2458 RegCloseKey(clsidhkey
);
2461 if (ret
== ERROR_ACCESS_DENIED
)
2463 win_skip("Failed to create test key, skipping some of OleRegGetUserType() tests.\n");
2467 ok(!ret
, "failed to create a key, error %d\n", ret
);
2469 ret
= RegSetValueExW(classkey
, NULL
, 0, REG_SZ
, (const BYTE
*)defvalueW
, sizeof(defvalueW
));
2470 ok(!ret
, "got error %d\n", ret
);
2472 ret
= RegCreateKeyExA(classkey
, "AuxUserType", 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &auxhkey
, NULL
);
2473 ok(!ret
, "got error %d\n", ret
);
2475 /* populate AuxUserType */
2476 for (i
= 0; i
<= 4; i
++) {
2479 sprintf(name
, "AuxUserType\\%d", i
);
2480 ret
= RegCreateKeyExA(classkey
, name
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
);
2481 ok(!ret
, "got error %d\n", ret
);
2483 ret
= RegSetValueExA(hkey
, NULL
, 0, REG_SZ
, (const BYTE
*)auxvalues
[i
], strlen(auxvalues
[i
]));
2484 ok(!ret
, "got error %d\n", ret
);
2489 hr
= OleRegGetUserType(&CLSID_non_existent
, 0, &str
);
2490 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2491 ok(!lstrcmpW(str
, auxvalue0W
), "got %s\n", wine_dbgstr_w(str
));
2495 hr
= OleRegGetUserType(&CLSID_non_existent
, USERCLASSTYPE_FULL
, &str
);
2496 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2497 ok(!lstrcmpW(str
, defvalueW
), "got %s\n", wine_dbgstr_w(str
));
2501 hr
= OleRegGetUserType(&CLSID_non_existent
, USERCLASSTYPE_SHORT
, &str
);
2502 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2503 ok(!lstrcmpW(str
, auxvalue2W
), "got %s\n", wine_dbgstr_w(str
));
2507 hr
= OleRegGetUserType(&CLSID_non_existent
, USERCLASSTYPE_APPNAME
, &str
);
2508 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2509 ok(!lstrcmpW(str
, auxvalue3W
), "got %s\n", wine_dbgstr_w(str
));
2513 hr
= OleRegGetUserType(&CLSID_non_existent
, USERCLASSTYPE_APPNAME
+1, &str
);
2514 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2515 ok(!lstrcmpW(str
, auxvalue4W
), "got %s\n", wine_dbgstr_w(str
));
2519 hr
= OleRegGetUserType(&CLSID_non_existent
, USERCLASSTYPE_APPNAME
+2, &str
);
2520 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2521 ok(!lstrcmpW(str
, defvalueW
), "got %s\n", wine_dbgstr_w(str
));
2524 /* registry cleanup */
2525 for (i
= 0; i
<= 4; i
++)
2528 sprintf(name
, "%d", i
);
2529 RegDeleteKeyA(auxhkey
, name
);
2531 RegCloseKey(auxhkey
);
2532 RegDeleteKeyA(classkey
, "AuxUserType");
2533 RegCloseKey(classkey
);
2534 RegDeleteKeyW(clsidhkey
, clsidW
);
2535 RegCloseKey(clsidhkey
);
2536 if (disposition
== REG_CREATED_NEW_KEY
)
2537 RegDeleteKeyA(HKEY_CLASSES_ROOT
, "CLSID");
2540 static void test_CoCreateGuid(void)
2544 hr
= CoCreateGuid(NULL
);
2545 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2548 static void CALLBACK
apc_test_proc(ULONG_PTR param
)
2553 static DWORD CALLBACK
release_semaphore_thread( LPVOID arg
)
2555 HANDLE handle
= arg
;
2556 if (WaitForSingleObject(handle
, 200) == WAIT_TIMEOUT
)
2557 ReleaseSemaphore(handle
, 1, NULL
);
2561 static DWORD CALLBACK
send_message_thread(LPVOID arg
)
2565 SendMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2569 static DWORD CALLBACK
post_message_thread(LPVOID arg
)
2573 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2577 static const char cls_name
[] = "cowait_test_class";
2578 static DWORD CALLBACK
test_CoWaitForMultipleHandles_thread(LPVOID arg
)
2580 HANDLE
*handles
= arg
;
2587 hr
= pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2588 ok(hr
== S_OK
, "CoInitializeEx failed with error 0x%08x\n", hr
);
2590 hWnd
= CreateWindowExA(0, cls_name
, "Test (thread)", WS_TILEDWINDOW
, 0, 0, 640, 480, 0, 0, 0, 0);
2591 ok(hWnd
!= 0, "CreateWindowExA failed %u\n", GetLastError());
2594 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2595 hr
= CoWaitForMultipleHandles(0, 50, 2, handles
, &index
);
2596 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2597 ok(index
==0 || index
==0xdeadbeef/* Win 8 */, "expected index 0, got %u\n", index
);
2598 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2599 ok(!success
, "CoWaitForMultipleHandles didn't pump any messages\n");
2602 PostMessageA(hWnd
, WM_USER
, 0, 0);
2603 hr
= CoWaitForMultipleHandles(0, 50, 2, handles
, &index
);
2604 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2605 ok(index
==0 || index
==0xdeadbeef/* Win 8 */, "expected index 0, got %u\n", index
);
2606 success
= PeekMessageA(&msg
, hWnd
, WM_USER
, WM_USER
, PM_REMOVE
);
2607 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2609 DestroyWindow(hWnd
);
2614 static void test_CoWaitForMultipleHandles(void)
2616 HANDLE handles
[2], thread
;
2624 hr
= pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2625 ok(hr
== S_OK
, "CoInitializeEx failed with error 0x%08x\n", hr
);
2627 memset(&wc
, 0, sizeof(wc
));
2628 wc
.cbSize
= sizeof(wc
);
2629 wc
.style
= CS_VREDRAW
| CS_HREDRAW
;
2630 wc
.hInstance
= GetModuleHandleA(0);
2631 wc
.hCursor
= LoadCursorA(NULL
, (LPCSTR
)IDC_ARROW
);
2632 wc
.hbrBackground
= NULL
;
2633 wc
.lpszClassName
= cls_name
;
2634 wc
.lpfnWndProc
= DefWindowProcA
;
2635 success
= RegisterClassExA(&wc
) != 0;
2636 ok(success
, "RegisterClassExA failed %u\n", GetLastError());
2638 hWnd
= CreateWindowExA(0, cls_name
, "Test", WS_TILEDWINDOW
, 0, 0, 640, 480, 0, 0, 0, 0);
2639 ok(hWnd
!= 0, "CreateWindowExA failed %u\n", GetLastError());
2640 handles
[0] = CreateSemaphoreA(NULL
, 1, 1, NULL
);
2641 ok(handles
[0] != 0, "CreateSemaphoreA failed %u\n", GetLastError());
2642 handles
[1] = CreateSemaphoreA(NULL
, 1, 1, NULL
);
2643 ok(handles
[1] != 0, "CreateSemaphoreA failed %u\n", GetLastError());
2645 /* test without flags */
2647 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2648 hr
= CoWaitForMultipleHandles(0, 50, 0, handles
, NULL
);
2649 ok(hr
== E_INVALIDARG
, "expected E_INVALIDARG, got 0x%08x\n", hr
);
2650 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2651 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2654 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2655 hr
= CoWaitForMultipleHandles(0, 50, 0, NULL
, &index
);
2656 ok(hr
== E_INVALIDARG
, "expected E_INVALIDARG, got 0x%08x\n", hr
);
2657 ok(index
== 0, "expected index 0, got %u\n", index
);
2658 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2659 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2662 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2663 hr
= CoWaitForMultipleHandles(0, 50, 0, handles
, &index
);
2664 ok(hr
== RPC_E_NO_SYNC
, "expected RPC_E_NO_SYNC, got 0x%08x\n", hr
);
2665 ok(index
== 0, "expected index 0, got %u\n", index
);
2666 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2667 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2670 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2671 hr
= CoWaitForMultipleHandles(0, 50, 1, handles
, &index
);
2672 ok(hr
== S_OK
, "expected S_OK, got 0x%08x\n", hr
);
2673 ok(index
== 0, "expected index 0, got %u\n", index
);
2674 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2675 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2678 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2679 hr
= CoWaitForMultipleHandles(0, 50, 2, handles
, &index
);
2680 ok(hr
== S_OK
, "expected S_OK, got 0x%08x\n", hr
);
2681 ok(index
== 1, "expected index 1, got %u\n", index
);
2682 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2683 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2686 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2687 hr
= CoWaitForMultipleHandles(0, 50, 2, handles
, &index
);
2688 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2689 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2690 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2691 ok(!success
, "CoWaitForMultipleHandles didn't pump any messages\n");
2693 /* test PostMessageA/SendMessageA from a different thread */
2696 thread
= CreateThread(NULL
, 0, post_message_thread
, hWnd
, 0, &tid
);
2697 ok(thread
!= NULL
, "CreateThread failed, error %u\n", GetLastError());
2698 hr
= CoWaitForMultipleHandles(0, 100, 2, handles
, &index
);
2699 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2700 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2701 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2702 ok(!success
, "CoWaitForMultipleHandles didn't pump any messages\n");
2703 index
= WaitForSingleObject(thread
, 200);
2704 ok(index
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
2705 CloseHandle(thread
);
2708 thread
= CreateThread(NULL
, 0, send_message_thread
, hWnd
, 0, &tid
);
2709 ok(thread
!= NULL
, "CreateThread failed, error %u\n", GetLastError());
2710 hr
= CoWaitForMultipleHandles(0, 100, 2, handles
, &index
);
2711 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2712 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2713 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2714 ok(!success
, "CoWaitForMultipleHandles didn't pump any messages\n");
2715 index
= WaitForSingleObject(thread
, 200);
2716 ok(index
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
2717 CloseHandle(thread
);
2719 ReleaseSemaphore(handles
[0], 1, NULL
);
2720 ReleaseSemaphore(handles
[1], 1, NULL
);
2722 /* test with COWAIT_WAITALL */
2725 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2726 hr
= CoWaitForMultipleHandles(COWAIT_WAITALL
, 50, 2, handles
, &index
);
2727 ok(hr
== S_OK
, "expected S_OK, got 0x%08x\n", hr
);
2728 ok(index
== 0, "expected index 0, got %u\n", index
);
2729 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2730 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2733 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2734 hr
= CoWaitForMultipleHandles(0, 50, 2, handles
, &index
);
2735 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2736 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2737 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2738 ok(!success
, "CoWaitForMultipleHandles didn't pump any messages\n");
2740 ReleaseSemaphore(handles
[0], 1, NULL
);
2741 ReleaseSemaphore(handles
[1], 1, NULL
);
2743 /* test with COWAIT_ALERTABLE */
2746 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2747 hr
= CoWaitForMultipleHandles(COWAIT_ALERTABLE
, 50, 1, handles
, &index
);
2748 ok(hr
== S_OK
, "expected S_OK, got 0x%08x\n", hr
);
2749 ok(index
== 0, "expected index 0, got %u\n", index
);
2750 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2751 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2754 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2755 hr
= CoWaitForMultipleHandles(COWAIT_ALERTABLE
, 50, 2, handles
, &index
);
2756 ok(hr
== S_OK
, "expected S_OK, got 0x%08x\n", hr
);
2757 ok(index
== 1, "expected index 1, got %u\n", index
);
2758 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2759 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2762 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2763 hr
= CoWaitForMultipleHandles(COWAIT_ALERTABLE
, 50, 2, handles
, &index
);
2764 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2765 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2766 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2767 ok(!success
, "CoWaitForMultipleHandles didn't pump any messages\n");
2770 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2771 success
= QueueUserAPC(apc_test_proc
, GetCurrentThread(), 0);
2772 ok(success
, "QueueUserAPC failed %u\n", GetLastError());
2773 hr
= CoWaitForMultipleHandles(COWAIT_ALERTABLE
, 50, 2, handles
, &index
);
2774 ok(hr
== S_OK
, "expected S_OK, got 0x%08x\n", hr
);
2775 ok(index
== WAIT_IO_COMPLETION
, "expected index WAIT_IO_COMPLETION, got %u\n", index
);
2776 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2777 ok(success
, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2779 /* test with COWAIT_INPUTAVAILABLE (semaphores are still locked) */
2782 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2783 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_NOREMOVE
);
2784 ok(success
, "PeekMessageA returned FALSE\n");
2785 hr
= CoWaitForMultipleHandles(0, 50, 2, handles
, &index
);
2786 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2787 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2788 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2789 ok(!success
, "CoWaitForMultipleHandles didn't pump any messages\n");
2792 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2793 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_NOREMOVE
);
2794 ok(success
, "PeekMessageA returned FALSE\n");
2795 thread
= CreateThread(NULL
, 0, release_semaphore_thread
, handles
[1], 0, &tid
);
2796 ok(thread
!= NULL
, "CreateThread failed, error %u\n", GetLastError());
2797 hr
= CoWaitForMultipleHandles(COWAIT_INPUTAVAILABLE
, 50, 2, handles
, &index
);
2798 ok(hr
== RPC_S_CALLPENDING
|| broken(hr
== E_INVALIDARG
) || broken(hr
== S_OK
) /* Win 8 */,
2799 "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2800 if (hr
!= S_OK
) ReleaseSemaphore(handles
[1], 1, NULL
);
2801 ok(index
== 0 || broken(index
== 1) /* Win 8 */, "expected index 0, got %u\n", index
);
2802 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2803 ok(!success
|| broken(success
&& hr
== E_INVALIDARG
),
2804 "CoWaitForMultipleHandles didn't pump any messages\n");
2805 index
= WaitForSingleObject(thread
, 200);
2806 ok(index
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
2807 CloseHandle(thread
);
2809 /* test behaviour of WM_QUIT (semaphores are still locked) */
2811 PostMessageA(hWnd
, WM_QUIT
, 40, 0);
2812 memset(&msg
, 0, sizeof(msg
));
2813 success
= PeekMessageA(&msg
, hWnd
, WM_QUIT
, WM_QUIT
, PM_REMOVE
);
2814 ok(success
, "PeekMessageA failed, error %u\n", GetLastError());
2815 ok(msg
.message
== WM_QUIT
, "expected msg.message = WM_QUIT, got %u\n", msg
.message
);
2816 ok(msg
.wParam
== 40, "expected msg.wParam = 40, got %lu\n", msg
.wParam
);
2817 success
= PeekMessageA(&msg
, hWnd
, WM_QUIT
, WM_QUIT
, PM_REMOVE
);
2818 ok(!success
, "PeekMessageA succeeded\n");
2821 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2822 PostMessageA(hWnd
, WM_QUIT
, 41, 0);
2823 thread
= CreateThread(NULL
, 0, post_message_thread
, hWnd
, 0, &tid
);
2824 ok(thread
!= NULL
, "CreateThread failed, error %u\n", GetLastError());
2825 hr
= CoWaitForMultipleHandles(0, 100, 2, handles
, &index
);
2826 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2827 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2828 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2830 ok(success
|| broken(!success
) /* Win 2000/XP/8 */, "PeekMessageA failed, error %u\n", GetLastError());
2831 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2832 ok(!success
, "PeekMessageA succeeded\n");
2833 memset(&msg
, 0, sizeof(msg
));
2834 success
= PeekMessageA(&msg
, hWnd
, WM_QUIT
, WM_QUIT
, PM_REMOVE
);
2836 ok(!success
|| broken(success
) /* Win 2000/XP/8 */, "PeekMessageA succeeded\n");
2839 ok(msg
.message
== WM_QUIT
, "expected msg.message = WM_QUIT, got %u\n", msg
.message
);
2840 ok(msg
.wParam
== 41, "expected msg.wParam = 41, got %lu\n", msg
.wParam
);
2842 index
= WaitForSingleObject(thread
, 200);
2843 ok(index
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
2844 CloseHandle(thread
);
2847 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2848 PostMessageA(hWnd
, WM_QUIT
, 42, 0);
2849 thread
= CreateThread(NULL
, 0, send_message_thread
, hWnd
, 0, &tid
);
2850 ok(thread
!= NULL
, "CreateThread failed, error %u\n", GetLastError());
2851 hr
= CoWaitForMultipleHandles(0, 100, 2, handles
, &index
);
2852 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2853 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2854 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2855 ok(!success
, "CoWaitForMultipleHandles didn't pump all WM_DDE_FIRST messages\n");
2856 memset(&msg
, 0, sizeof(msg
));
2857 success
= PeekMessageA(&msg
, hWnd
, WM_QUIT
, WM_QUIT
, PM_REMOVE
);
2858 ok(success
, "PeekMessageA failed, error %u\n", GetLastError());
2859 ok(msg
.message
== WM_QUIT
, "expected msg.message = WM_QUIT, got %u\n", msg
.message
);
2860 ok(msg
.wParam
== 42, "expected msg.wParam = 42, got %lu\n", msg
.wParam
);
2861 index
= WaitForSingleObject(thread
, 200);
2862 ok(index
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
2863 CloseHandle(thread
);
2865 PostQuitMessage(43);
2866 memset(&msg
, 0, sizeof(msg
));
2867 success
= PeekMessageA(&msg
, hWnd
, WM_QUIT
, WM_QUIT
, PM_REMOVE
);
2868 ok(success
|| broken(!success
) /* Win 8 */, "PeekMessageA failed, error %u\n", GetLastError());
2870 win_skip("PostQuitMessage didn't queue a WM_QUIT message, skipping tests\n");
2873 ok(msg
.message
== WM_QUIT
, "expected msg.message = WM_QUIT, got %u\n", msg
.message
);
2874 ok(msg
.wParam
== 43, "expected msg.wParam = 43, got %lu\n", msg
.wParam
);
2875 success
= PeekMessageA(&msg
, hWnd
, WM_QUIT
, WM_QUIT
, PM_REMOVE
);
2876 ok(!success
, "PeekMessageA succeeded\n");
2879 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2880 PostQuitMessage(44);
2881 thread
= CreateThread(NULL
, 0, post_message_thread
, hWnd
, 0, &tid
);
2882 ok(thread
!= NULL
, "CreateThread failed, error %u\n", GetLastError());
2883 hr
= CoWaitForMultipleHandles(0, 100, 2, handles
, &index
);
2884 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2885 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2886 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2887 ok(success
, "PeekMessageA failed, error %u\n", GetLastError());
2888 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2890 ok(!success
, "PeekMessageA succeeded\n");
2891 success
= PeekMessageA(&msg
, hWnd
, WM_QUIT
, WM_QUIT
, PM_REMOVE
);
2893 ok(!success
, "CoWaitForMultipleHandles didn't remove WM_QUIT messages\n");
2894 index
= WaitForSingleObject(thread
, 200);
2895 ok(index
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
2896 CloseHandle(thread
);
2899 PostMessageA(hWnd
, WM_DDE_FIRST
, 0, 0);
2900 PostQuitMessage(45);
2901 thread
= CreateThread(NULL
, 0, send_message_thread
, hWnd
, 0, &tid
);
2902 ok(thread
!= NULL
, "CreateThread failed, error %u\n", GetLastError());
2903 hr
= CoWaitForMultipleHandles(0, 100, 2, handles
, &index
);
2904 ok(hr
== RPC_S_CALLPENDING
, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr
);
2905 ok(index
== 0 || broken(index
== 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index
);
2906 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2907 ok(success
, "PeekMessageA failed, error %u\n", GetLastError());
2908 success
= PeekMessageA(&msg
, hWnd
, WM_DDE_FIRST
, WM_DDE_FIRST
, PM_REMOVE
);
2910 ok(!success
, "PeekMessageA succeeded\n");
2911 success
= PeekMessageA(&msg
, hWnd
, WM_QUIT
, WM_QUIT
, PM_REMOVE
);
2912 ok(!success
, "CoWaitForMultipleHandles didn't remove WM_QUIT messages\n");
2913 index
= WaitForSingleObject(thread
, 200);
2914 ok(index
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
2915 CloseHandle(thread
);
2918 /* test message pumping when CoWaitForMultipleHandles is called from non main apartment thread */
2919 thread
= CreateThread(NULL
, 0, test_CoWaitForMultipleHandles_thread
, handles
, 0, &tid
);
2920 index
= WaitForSingleObject(thread
, 500);
2921 ok(index
== WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
2922 CloseHandle(thread
);
2924 CloseHandle(handles
[0]);
2925 CloseHandle(handles
[1]);
2926 DestroyWindow(hWnd
);
2928 success
= UnregisterClassA(cls_name
, GetModuleHandleA(0));
2929 ok(success
, "UnregisterClass failed %u\n", GetLastError());
2934 static void test_CoGetMalloc(void)
2939 if (0) /* crashes on native */
2940 hr
= CoGetMalloc(0, NULL
);
2942 imalloc
= (void*)0xdeadbeef;
2943 hr
= CoGetMalloc(0, &imalloc
);
2944 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2945 ok(imalloc
== NULL
, "got %p\n", imalloc
);
2947 imalloc
= (void*)0xdeadbeef;
2948 hr
= CoGetMalloc(MEMCTX_SHARED
, &imalloc
);
2949 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2950 ok(imalloc
== NULL
, "got %p\n", imalloc
);
2952 imalloc
= (void*)0xdeadbeef;
2953 hr
= CoGetMalloc(MEMCTX_MACSYSTEM
, &imalloc
);
2954 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2955 ok(imalloc
== NULL
, "got %p\n", imalloc
);
2957 imalloc
= (void*)0xdeadbeef;
2958 hr
= CoGetMalloc(MEMCTX_UNKNOWN
, &imalloc
);
2959 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2960 ok(imalloc
== NULL
, "got %p\n", imalloc
);
2962 imalloc
= (void*)0xdeadbeef;
2963 hr
= CoGetMalloc(MEMCTX_SAME
, &imalloc
);
2964 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2965 ok(imalloc
== NULL
, "got %p\n", imalloc
);
2968 hr
= CoGetMalloc(MEMCTX_TASK
, &imalloc
);
2969 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2970 ok(imalloc
!= NULL
, "got %p\n", imalloc
);
2971 IMalloc_Release(imalloc
);
2974 static void test_CoGetApartmentType(void)
2976 APTTYPEQUALIFIER qualifier
;
2980 if (!pCoGetApartmentType
)
2982 win_skip("CoGetApartmentType not present\n");
2986 hr
= pCoGetApartmentType(NULL
, NULL
);
2987 ok(hr
== E_INVALIDARG
, "CoGetApartmentType succeeded, error: 0x%08x\n", hr
);
2990 hr
= pCoGetApartmentType(&type
, NULL
);
2991 ok(hr
== E_INVALIDARG
, "CoGetApartmentType succeeded, error: 0x%08x\n", hr
);
2992 ok(type
== 0xdeadbeef, "Expected 0xdeadbeef, got %u\n", type
);
2994 qualifier
= 0xdeadbeef;
2995 hr
= pCoGetApartmentType(NULL
, &qualifier
);
2996 ok(hr
== E_INVALIDARG
, "CoGetApartmentType succeeded, error: 0x%08x\n", hr
);
2997 ok(qualifier
== 0xdeadbeef, "Expected 0xdeadbeef, got %u\n", qualifier
);
3000 qualifier
= 0xdeadbeef;
3001 hr
= pCoGetApartmentType(&type
, &qualifier
);
3002 ok(hr
== CO_E_NOTINITIALIZED
, "CoGetApartmentType succeeded, error: 0x%08x\n", hr
);
3003 ok(type
== APTTYPE_CURRENT
, "Expected APTTYPE_CURRENT, got %u\n", type
);
3004 ok(qualifier
== APTTYPEQUALIFIER_NONE
, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier
);
3007 qualifier
= 0xdeadbeef;
3008 hr
= pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
3009 ok(hr
== S_OK
, "CoInitializeEx failed, error: 0x%08x\n", hr
);
3010 hr
= pCoGetApartmentType(&type
, &qualifier
);
3011 ok(hr
== S_OK
, "CoGetApartmentType failed, error: 0x%08x\n", hr
);
3012 ok(type
== APTTYPE_MAINSTA
, "Expected APTTYPE_MAINSTA, got %u\n", type
);
3013 ok(qualifier
== APTTYPEQUALIFIER_NONE
, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier
);
3017 qualifier
= 0xdeadbeef;
3018 hr
= pCoInitializeEx(NULL
, COINIT_MULTITHREADED
);
3019 ok(hr
== S_OK
, "CoInitializeEx failed, error: 0x%08x\n", hr
);
3020 hr
= pCoGetApartmentType(&type
, &qualifier
);
3021 ok(hr
== S_OK
, "CoGetApartmentType failed, error: 0x%08x\n", hr
);
3022 ok(type
== APTTYPE_MTA
, "Expected APTTYPE_MTA, got %u\n", type
);
3023 ok(qualifier
== APTTYPEQUALIFIER_NONE
, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier
);
3027 static HRESULT WINAPI
testspy_QI(IMallocSpy
*iface
, REFIID riid
, void **obj
)
3029 if (IsEqualIID(riid
, &IID_IMallocSpy
) || IsEqualIID(riid
, &IID_IUnknown
))
3032 IMallocSpy_AddRef(iface
);
3036 return E_NOINTERFACE
;
3039 static ULONG WINAPI
testspy_AddRef(IMallocSpy
*iface
)
3044 static ULONG WINAPI
testspy_Release(IMallocSpy
*iface
)
3049 static SIZE_T WINAPI
testspy_PreAlloc(IMallocSpy
*iface
, SIZE_T cb
)
3051 ok(0, "unexpected call\n");
3055 static void* WINAPI
testspy_PostAlloc(IMallocSpy
*iface
, void *ptr
)
3057 ok(0, "unexpected call\n");
3061 static void* WINAPI
testspy_PreFree(IMallocSpy
*iface
, void *ptr
, BOOL spyed
)
3063 ok(0, "unexpected call\n");
3067 static void WINAPI
testspy_PostFree(IMallocSpy
*iface
, BOOL spyed
)
3069 ok(0, "unexpected call\n");
3072 static SIZE_T WINAPI
testspy_PreRealloc(IMallocSpy
*iface
, void *ptr
, SIZE_T cb
, void **newptr
, BOOL spyed
)
3074 ok(0, "unexpected call\n");
3078 static void* WINAPI
testspy_PostRealloc(IMallocSpy
*iface
, void *ptr
, BOOL spyed
)
3080 ok(0, "unexpected call\n");
3084 static void* WINAPI
testspy_PreGetSize(IMallocSpy
*iface
, void *ptr
, BOOL spyed
)
3086 ok(0, "unexpected call\n");
3090 static SIZE_T WINAPI
testspy_PostGetSize(IMallocSpy
*iface
, SIZE_T actual
, BOOL spyed
)
3092 ok(0, "unexpected call\n");
3096 static void* WINAPI
testspy_PreDidAlloc(IMallocSpy
*iface
, void *ptr
, BOOL spyed
)
3098 ok(0, "unexpected call\n");
3102 static int WINAPI
testspy_PostDidAlloc(IMallocSpy
*iface
, void *ptr
, BOOL spyed
, int actual
)
3104 ok(0, "unexpected call\n");
3108 static void WINAPI
testspy_PreHeapMinimize(IMallocSpy
*iface
)
3110 ok(0, "unexpected call\n");
3113 static void WINAPI
testspy_PostHeapMinimize(IMallocSpy
*iface
)
3115 ok(0, "unexpected call\n");
3118 static const IMallocSpyVtbl testspyvtbl
=
3128 testspy_PostRealloc
,
3130 testspy_PostGetSize
,
3131 testspy_PreDidAlloc
,
3132 testspy_PostDidAlloc
,
3133 testspy_PreHeapMinimize
,
3134 testspy_PostHeapMinimize
3137 static IMallocSpy testspy
= { &testspyvtbl
};
3139 static void test_IMallocSpy(void)
3144 hr
= CoRegisterMallocSpy(NULL
);
3145 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3147 hr
= CoRevokeMallocSpy();
3148 ok(hr
== CO_E_OBJNOTREG
, "got 0x%08x\n", hr
);
3150 hr
= CoRegisterMallocSpy(&testspy
);
3151 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3153 hr
= CoRegisterMallocSpy(NULL
);
3154 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3156 hr
= CoRegisterMallocSpy(&testspy
);
3157 ok(hr
== CO_E_OBJISREG
, "got 0x%08x\n", hr
);
3160 hr
= CoGetMalloc(MEMCTX_TASK
, &imalloc
);
3161 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3162 ok(imalloc
!= NULL
, "got %p\n", imalloc
);
3164 IMalloc_Free(imalloc
, NULL
);
3166 IMalloc_Release(imalloc
);
3168 hr
= CoRevokeMallocSpy();
3169 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3171 hr
= CoRevokeMallocSpy();
3172 ok(hr
== CO_E_OBJNOTREG
, "got 0x%08x\n", hr
);
3175 static void test_CoGetCurrentLogicalThreadId(void)
3180 hr
= CoGetCurrentLogicalThreadId(NULL
);
3181 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3184 hr
= CoGetCurrentLogicalThreadId(&id
);
3185 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3186 ok(!IsEqualGUID(&id
, &GUID_NULL
), "got null id\n");
3189 static HRESULT WINAPI
testinitialize_QI(IInitializeSpy
*iface
, REFIID riid
, void **obj
)
3191 if (IsEqualIID(riid
, &IID_IInitializeSpy
) || IsEqualIID(riid
, &IID_IUnknown
))
3194 IInitializeSpy_AddRef(iface
);
3199 return E_NOINTERFACE
;
3202 static ULONG WINAPI
testinitialize_AddRef(IInitializeSpy
*iface
)
3207 static ULONG WINAPI
testinitialize_Release(IInitializeSpy
*iface
)
3212 static HRESULT WINAPI
testinitialize_PreInitialize(IInitializeSpy
*iface
, DWORD coinit
, DWORD aptrefs
)
3214 ok(0, "unexpected call\n");
3218 static HRESULT WINAPI
testinitialize_PostInitialize(IInitializeSpy
*iface
, HRESULT hr
, DWORD coinit
, DWORD aptrefs
)
3220 ok(0, "unexpected call\n");
3224 static HRESULT WINAPI
testinitialize_PreUninitialize(IInitializeSpy
*iface
, DWORD aptrefs
)
3226 ok(0, "unexpected call\n");
3230 static HRESULT WINAPI
testinitialize_PostUninitialize(IInitializeSpy
*iface
, DWORD aptrefs
)
3232 ok(0, "unexpected call\n");
3236 static const IInitializeSpyVtbl testinitializevtbl
=
3239 testinitialize_AddRef
,
3240 testinitialize_Release
,
3241 testinitialize_PreInitialize
,
3242 testinitialize_PostInitialize
,
3243 testinitialize_PreUninitialize
,
3244 testinitialize_PostUninitialize
3247 static IInitializeSpy testinitialize
= { &testinitializevtbl
};
3249 static void test_IInitializeSpy(void)
3251 ULARGE_INTEGER cookie
, cookie1
, cookie2
;
3254 hr
= CoRegisterInitializeSpy(NULL
, NULL
);
3255 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3257 cookie
.QuadPart
= 1;
3258 hr
= CoRegisterInitializeSpy(NULL
, &cookie
);
3259 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3260 ok(cookie
.QuadPart
== 1, "got wrong cookie\n");
3262 hr
= CoRegisterInitializeSpy(&testinitialize
, NULL
);
3263 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3265 cookie
.HighPart
= 0;
3267 hr
= CoRegisterInitializeSpy(&testinitialize
, &cookie
);
3268 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3270 ok(cookie
.HighPart
== GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", cookie
.HighPart
,
3271 GetCurrentThreadId());
3272 ok(cookie
.LowPart
== 0, "got wrong low part 0x%x\n", cookie
.LowPart
);
3274 /* register same instance one more time */
3275 cookie1
.HighPart
= 0;
3276 cookie1
.LowPart
= 0;
3277 hr
= CoRegisterInitializeSpy(&testinitialize
, &cookie1
);
3279 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3280 ok(cookie1
.HighPart
== GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", cookie1
.HighPart
,
3281 GetCurrentThreadId());
3282 ok(cookie1
.LowPart
== 1, "got wrong low part 0x%x\n", cookie1
.LowPart
);
3284 cookie2
.HighPart
= 0;
3285 cookie2
.LowPart
= 0;
3286 hr
= CoRegisterInitializeSpy(&testinitialize
, &cookie2
);
3288 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3289 ok(cookie2
.HighPart
== GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", cookie2
.HighPart
,
3290 GetCurrentThreadId());
3291 ok(cookie2
.LowPart
== 2, "got wrong low part 0x%x\n", cookie2
.LowPart
);
3293 hr
= CoRevokeInitializeSpy(cookie1
);
3295 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3297 hr
= CoRevokeInitializeSpy(cookie1
);
3298 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3300 cookie1
.HighPart
= 0;
3301 cookie1
.LowPart
= 0;
3302 hr
= CoRegisterInitializeSpy(&testinitialize
, &cookie1
);
3304 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3305 ok(cookie1
.HighPart
== GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", cookie1
.HighPart
,
3306 GetCurrentThreadId());
3307 ok(cookie1
.LowPart
== 1, "got wrong low part 0x%x\n", cookie1
.LowPart
);
3309 hr
= CoRevokeInitializeSpy(cookie
);
3310 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3312 hr
= CoRevokeInitializeSpy(cookie1
);
3314 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3316 hr
= CoRevokeInitializeSpy(cookie2
);
3318 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3321 static HRESULT g_persistfile_qi_ret
;
3322 static HRESULT g_persistfile_load_ret
;
3323 static HRESULT WINAPI
testinstance_QI(IPersistFile
*iface
, REFIID riid
, void **obj
)
3325 if (IsEqualIID(riid
, &IID_IUnknown
)) {
3327 IUnknown_AddRef(iface
);
3331 if (IsEqualIID(riid
, &IID_IPersistFile
)) {
3332 if (SUCCEEDED(g_persistfile_qi_ret
)) {
3334 IUnknown_AddRef(iface
);
3338 return g_persistfile_qi_ret
;
3341 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid
));
3343 return E_NOINTERFACE
;
3346 static ULONG WINAPI
testinstance_AddRef(IPersistFile
*iface
)
3351 static ULONG WINAPI
testinstance_Release(IPersistFile
*iface
)
3356 static HRESULT WINAPI
testinstance_GetClassID(IPersistFile
*iface
, CLSID
*clsid
)
3358 ok(0, "unexpected call\n");
3362 static HRESULT WINAPI
testinstance_IsDirty(IPersistFile
*iface
)
3364 ok(0, "unexpected call\n");
3368 static HRESULT WINAPI
testinstance_Load(IPersistFile
*iface
, LPCOLESTR filename
, DWORD mode
)
3370 return g_persistfile_load_ret
;
3373 static HRESULT WINAPI
testinstance_Save(IPersistFile
*iface
, LPCOLESTR filename
, BOOL remember
)
3378 static HRESULT WINAPI
testinstance_SaveCompleted(IPersistFile
*iface
, LPCOLESTR filename
)
3380 ok(0, "unexpected call\n");
3384 static HRESULT WINAPI
testinstance_GetCurFile(IPersistFile
*iface
, LPOLESTR
*filename
)
3386 ok(0, "unexpected call\n");
3390 static const IPersistFileVtbl testpersistfilevtbl
= {
3392 testinstance_AddRef
,
3393 testinstance_Release
,
3394 testinstance_GetClassID
,
3395 testinstance_IsDirty
,
3398 testinstance_SaveCompleted
,
3399 testinstance_GetCurFile
3402 static IPersistFile testpersistfile
= { &testpersistfilevtbl
};
3404 static HRESULT WINAPI
getinstance_cf_QI(IClassFactory
*iface
, REFIID riid
, void **obj
)
3406 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IClassFactory
)) {
3408 IClassFactory_AddRef(iface
);
3413 return E_NOINTERFACE
;
3416 static ULONG WINAPI
getinstance_cf_AddRef(IClassFactory
*iface
)
3421 static ULONG WINAPI
getinstance_cf_Release(IClassFactory
*iface
)
3426 static HRESULT WINAPI
getinstance_cf_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
,
3427 REFIID riid
, void **obj
)
3429 if (IsEqualIID(riid
, &IID_IUnknown
)) {
3430 *obj
= &testpersistfile
;
3434 ok(0, "unexpected call, riid %s\n", wine_dbgstr_guid(riid
));
3439 static HRESULT WINAPI
getinstance_cf_LockServer(IClassFactory
*iface
, BOOL lock
)
3441 ok(0, "unexpected call\n");
3445 static const IClassFactoryVtbl getinstance_cf_vtbl
= {
3447 getinstance_cf_AddRef
,
3448 getinstance_cf_Release
,
3449 getinstance_cf_CreateInstance
,
3450 getinstance_cf_LockServer
3453 static IClassFactory getinstance_cf
= { &getinstance_cf_vtbl
};
3455 static void test_CoGetInstanceFromFile(void)
3457 static const WCHAR filenameW
[] = {'d','u','m','m','y','p','a','t','h',0};
3458 CLSID
*clsid
= (CLSID
*)&CLSID_testclsid
;
3463 hr
= pCoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
3464 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3466 /* CLSID is not specified, file does not exist */
3467 mqi
[0].pIID
= &IID_IUnknown
;
3469 mqi
[0].hr
= E_NOTIMPL
;
3470 hr
= CoGetInstanceFromFile(NULL
, NULL
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 1, mqi
);
3472 ok(hr
== MK_E_CANTOPENFILE
, "got 0x%08x\n", hr
);
3473 ok(mqi
[0].pItf
== NULL
, "got %p\n", mqi
[0].pItf
);
3474 ok(mqi
[0].hr
== E_NOINTERFACE
, "got 0x%08x\n", mqi
[0].hr
);
3476 /* class is not available */
3477 mqi
[0].pIID
= &IID_IUnknown
;
3479 mqi
[0].hr
= E_NOTIMPL
;
3480 hr
= CoGetInstanceFromFile(NULL
, clsid
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 1, mqi
);
3481 ok(hr
== REGDB_E_CLASSNOTREG
, "got 0x%08x\n", hr
);
3482 ok(mqi
[0].pItf
== NULL
, "got %p\n", mqi
[0].pItf
);
3483 ok(mqi
[0].hr
== REGDB_E_CLASSNOTREG
, "got 0x%08x\n", mqi
[0].hr
);
3485 hr
= CoRegisterClassObject(clsid
, (IUnknown
*)&getinstance_cf
, CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
,
3487 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3489 mqi
[0].pIID
= &IID_IUnknown
;
3490 mqi
[0].pItf
= (void*)0xdeadbeef;
3492 hr
= CoGetInstanceFromFile(NULL
, clsid
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 1, mqi
);
3494 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3495 ok(mqi
[0].pItf
== (void*)0xdeadbeef, "got %p\n", mqi
[0].pItf
);
3497 ok(mqi
[0].hr
== S_OK
, "got 0x%08x\n", mqi
[0].hr
);
3499 mqi
[0].pIID
= &IID_IUnknown
;
3500 mqi
[0].pItf
= (void*)0xdeadbeef;
3501 mqi
[0].hr
= E_NOTIMPL
;
3502 hr
= CoGetInstanceFromFile(NULL
, clsid
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 1, mqi
);
3504 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3505 ok(mqi
[0].pItf
== (void*)0xdeadbeef, "got %p\n", mqi
[0].pItf
);
3506 ok(mqi
[0].hr
== E_NOTIMPL
, "got 0x%08x\n", mqi
[0].hr
);
3508 mqi
[0].pIID
= &IID_IUnknown
;
3510 mqi
[0].hr
= E_NOTIMPL
;
3511 hr
= CoGetInstanceFromFile(NULL
, clsid
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 1, mqi
);
3512 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3513 ok(mqi
[0].pItf
!= NULL
, "got %p\n", mqi
[0].pItf
);
3514 ok(mqi
[0].hr
== S_OK
, "got 0x%08x\n", mqi
[0].hr
);
3516 mqi
[0].pIID
= &IID_IUnknown
;
3519 hr
= CoGetInstanceFromFile(NULL
, clsid
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 1, mqi
);
3520 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3521 ok(mqi
[0].pItf
!= NULL
, "got %p\n", mqi
[0].pItf
);
3522 ok(mqi
[0].hr
== S_OK
, "got 0x%08x\n", mqi
[0].hr
);
3524 mqi
[0].pIID
= &IID_IUnknown
;
3527 g_persistfile_qi_ret
= S_FALSE
;
3528 hr
= CoGetInstanceFromFile(NULL
, clsid
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 1, mqi
);
3529 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3530 ok(mqi
[0].pItf
!= NULL
, "got %p\n", mqi
[0].pItf
);
3531 ok(mqi
[0].hr
== S_OK
, "got 0x%08x\n", mqi
[0].hr
);
3532 g_persistfile_qi_ret
= S_OK
;
3534 mqi
[0].pIID
= &IID_IUnknown
;
3537 mqi
[1].pIID
= &IID_IUnknown
;
3540 g_persistfile_qi_ret
= 0x8000efef;
3541 hr
= CoGetInstanceFromFile(NULL
, clsid
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 2, mqi
);
3542 ok(hr
== 0x8000efef, "got 0x%08x\n", hr
);
3543 ok(mqi
[0].pItf
== NULL
, "got %p\n", mqi
[0].pItf
);
3544 ok(mqi
[0].hr
== 0x8000efef, "got 0x%08x\n", mqi
[0].hr
);
3545 ok(mqi
[1].pItf
== NULL
, "got %p\n", mqi
[1].pItf
);
3546 ok(mqi
[1].hr
== 0x8000efef, "got 0x%08x\n", mqi
[1].hr
);
3547 g_persistfile_qi_ret
= S_OK
;
3549 mqi
[0].pIID
= &IID_IUnknown
;
3552 mqi
[1].pIID
= &IID_IUnknown
;
3555 g_persistfile_load_ret
= 0x8000fefe;
3556 hr
= CoGetInstanceFromFile(NULL
, clsid
, NULL
, CLSCTX_INPROC_SERVER
, STGM_READ
, (OLECHAR
*)filenameW
, 2, mqi
);
3557 ok(hr
== 0x8000fefe, "got 0x%08x\n", hr
);
3558 ok(mqi
[0].pItf
== NULL
, "got %p\n", mqi
[0].pItf
);
3559 ok(mqi
[0].hr
== 0x8000fefe, "got 0x%08x\n", mqi
[0].hr
);
3560 ok(mqi
[1].pItf
== NULL
, "got %p\n", mqi
[1].pItf
);
3561 ok(mqi
[1].hr
== 0x8000fefe, "got 0x%08x\n", mqi
[1].hr
);
3562 g_persistfile_load_ret
= S_OK
;
3564 hr
= CoRevokeClassObject(cookie
);
3565 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3570 static void init_funcs(void)
3572 HMODULE hOle32
= GetModuleHandleA("ole32");
3573 HMODULE hAdvapi32
= GetModuleHandleA("advapi32");
3574 HMODULE hkernel32
= GetModuleHandleA("kernel32");
3576 pCoGetObjectContext
= (void*)GetProcAddress(hOle32
, "CoGetObjectContext");
3577 pCoSwitchCallContext
= (void*)GetProcAddress(hOle32
, "CoSwitchCallContext");
3578 pCoGetTreatAsClass
= (void*)GetProcAddress(hOle32
,"CoGetTreatAsClass");
3579 pCoTreatAsClass
= (void*)GetProcAddress(hOle32
,"CoTreatAsClass");
3580 pCoGetContextToken
= (void*)GetProcAddress(hOle32
, "CoGetContextToken");
3581 pCoGetApartmentType
= (void*)GetProcAddress(hOle32
, "CoGetApartmentType");
3582 pRegDeleteKeyExA
= (void*)GetProcAddress(hAdvapi32
, "RegDeleteKeyExA");
3583 pRegOverridePredefKey
= (void*)GetProcAddress(hAdvapi32
, "RegOverridePredefKey");
3584 pCoInitializeEx
= (void*)GetProcAddress(hOle32
, "CoInitializeEx");
3586 pActivateActCtx
= (void*)GetProcAddress(hkernel32
, "ActivateActCtx");
3587 pCreateActCtxW
= (void*)GetProcAddress(hkernel32
, "CreateActCtxW");
3588 pDeactivateActCtx
= (void*)GetProcAddress(hkernel32
, "DeactivateActCtx");
3589 pIsWow64Process
= (void*)GetProcAddress(hkernel32
, "IsWow64Process");
3590 pReleaseActCtx
= (void*)GetProcAddress(hkernel32
, "ReleaseActCtx");
3597 if (!pCoInitializeEx
)
3599 trace("You need DCOM95 installed to run this test\n");
3603 if (!pCreateActCtxW
)
3604 win_skip("Activation contexts are not supported, some tests will be skipped.\n");
3606 test_ProgIDFromCLSID();
3607 test_CLSIDFromProgID();
3608 test_CLSIDFromString();
3609 test_IIDFromString();
3610 test_StringFromGUID2();
3611 test_CoCreateInstance();
3613 test_CoGetClassObject();
3614 test_CoCreateInstanceEx();
3615 test_CoRegisterMessageFilter();
3616 test_CoRegisterPSClsid();
3617 test_CoGetPSClsid();
3618 test_CoUnmarshalInterface();
3619 test_CoGetInterfaceAndReleaseStream();
3620 test_CoMarshalInterface();
3621 test_CoMarshalInterThreadInterfaceInStream();
3622 test_CoRegisterClassObject();
3623 test_registered_object_thread_affinity();
3624 test_CoFreeUnusedLibraries();
3625 test_CoGetObjectContext();
3626 test_CoGetCallContext();
3627 test_CoGetContextToken();
3628 test_TreatAsClass();
3629 test_CoInitializeEx();
3630 test_OleInitialize_InitCounting();
3631 test_OleRegGetMiscStatus();
3632 test_CoCreateGuid();
3633 test_CoWaitForMultipleHandles();
3635 test_OleRegGetUserType();
3636 test_CoGetApartmentType();
3638 test_CoGetCurrentLogicalThreadId();
3639 test_IInitializeSpy();
3640 test_CoGetInstanceFromFile();