1c2c66affSColin Finck /*
2c2c66affSColin Finck * Component Object Tests
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 2005 Robert Shearman
5c2c66affSColin Finck *
6c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck * License as published by the Free Software Foundation; either
9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck *
11c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14c2c66affSColin Finck * Lesser General Public License for more details.
15c2c66affSColin Finck *
16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck */
20c2c66affSColin Finck
2166f35ef8SAmine Khaldi #define COBJMACROS
2266f35ef8SAmine Khaldi #define CONST_VTABLE
23c2c66affSColin Finck
2466f35ef8SAmine Khaldi #include <stdarg.h>
2566f35ef8SAmine Khaldi #include <stdio.h>
2666f35ef8SAmine Khaldi
2766f35ef8SAmine Khaldi #include "windef.h"
2866f35ef8SAmine Khaldi #include "winbase.h"
2966f35ef8SAmine Khaldi #define USE_COM_CONTEXT_DEF
3066f35ef8SAmine Khaldi #include "objbase.h"
3166f35ef8SAmine Khaldi #include "shlguid.h"
3266f35ef8SAmine Khaldi #include "urlmon.h" /* for CLSID_FileProtocol */
3366f35ef8SAmine Khaldi #include "dde.h"
3466f35ef8SAmine Khaldi #include "cguid.h"
3566f35ef8SAmine Khaldi
3666f35ef8SAmine Khaldi #include "ctxtcall.h"
3766f35ef8SAmine Khaldi
3866f35ef8SAmine Khaldi #include "wine/test.h"
395c1bcfecSAmine Khaldi #include "initguid.h"
40c2c66affSColin Finck
41c2c66affSColin Finck #define DEFINE_EXPECT(func) \
42fc6e4ed5SAmine Khaldi static BOOL expect_ ## func = FALSE; static unsigned int called_ ## func = 0
43c2c66affSColin Finck
44c2c66affSColin Finck #define SET_EXPECT(func) \
45c2c66affSColin Finck expect_ ## func = TRUE
46c2c66affSColin Finck
47c2c66affSColin Finck #define CHECK_EXPECT2(func) \
48c2c66affSColin Finck do { \
49c2c66affSColin Finck ok(expect_ ##func, "unexpected call " #func "\n"); \
50fc6e4ed5SAmine Khaldi called_ ## func++; \
51c2c66affSColin Finck }while(0)
52c2c66affSColin Finck
53c2c66affSColin Finck #define CHECK_EXPECT(func) \
54c2c66affSColin Finck do { \
55c2c66affSColin Finck CHECK_EXPECT2(func); \
56c2c66affSColin Finck expect_ ## func = FALSE; \
57c2c66affSColin Finck }while(0)
58c2c66affSColin Finck
59fc6e4ed5SAmine Khaldi #define CHECK_CALLED(func, n) \
60c2c66affSColin Finck do { \
61fc6e4ed5SAmine Khaldi ok(called_ ## func == n, "expected " #func " called %u times, got %u\n", n, called_ ## func); \
62fc6e4ed5SAmine Khaldi expect_ ## func = FALSE; \
63fc6e4ed5SAmine Khaldi called_ ## func = 0; \
64c2c66affSColin Finck }while(0)
65c2c66affSColin Finck
66c2c66affSColin Finck DEFINE_EXPECT(CreateStub);
67fc6e4ed5SAmine Khaldi DEFINE_EXPECT(PreInitialize);
68fc6e4ed5SAmine Khaldi DEFINE_EXPECT(PostInitialize);
69fc6e4ed5SAmine Khaldi DEFINE_EXPECT(PreUninitialize);
70fc6e4ed5SAmine Khaldi DEFINE_EXPECT(PostUninitialize);
71c2c66affSColin Finck
72c2c66affSColin Finck /* functions that are not present on all versions of Windows */
73c2c66affSColin Finck static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
74c2c66affSColin Finck static HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv);
75c2c66affSColin Finck static HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject);
76c2c66affSColin Finck static HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew);
77c2c66affSColin Finck static HRESULT (WINAPI * pCoTreatAsClass)(REFCLSID clsidOld, REFCLSID pClsidNew);
78c2c66affSColin Finck static HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token);
79c2c66affSColin Finck static HRESULT (WINAPI * pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
80c2c66affSColin Finck static LONG (WINAPI * pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
81c2c66affSColin Finck static LONG (WINAPI * pRegOverridePredefKey)(HKEY key, HKEY override);
82c2c66affSColin Finck
83c2c66affSColin Finck static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
84c2c66affSColin Finck static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
85c2c66affSColin Finck static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
86c2c66affSColin Finck static BOOL (WINAPI *pIsWow64Process)(HANDLE, LPBOOL);
87c2c66affSColin Finck static void (WINAPI *pReleaseActCtx)(HANDLE);
88c2c66affSColin Finck
89c2c66affSColin Finck #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
90c2c66affSColin Finck #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
91c2c66affSColin Finck #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
92c2c66affSColin Finck
93c2c66affSColin Finck static const CLSID CLSID_non_existent = { 0x12345678, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
94c2c66affSColin Finck static const CLSID CLSID_StdFont = { 0x0be35203, 0x8f91, 0x11ce, { 0x9d, 0xe3, 0x00, 0xaa, 0x00, 0x4b, 0xb8, 0x51 } };
95c2c66affSColin Finck static const GUID IID_Testiface = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
96c2c66affSColin Finck static const GUID IID_Testiface2 = { 0x32222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
97c2c66affSColin Finck static const GUID IID_Testiface3 = { 0x42222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
98c2c66affSColin Finck static const GUID IID_Testiface4 = { 0x52222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
99c2c66affSColin Finck static const GUID IID_Testiface5 = { 0x62222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
100c2c66affSColin Finck static const GUID IID_Testiface6 = { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
101c2c66affSColin Finck static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
102c2c66affSColin Finck
103c2c66affSColin Finck DEFINE_GUID(CLSID_testclsid, 0xacd014c7,0x9535,0x4fac,0x8b,0x53,0xa4,0x8c,0xa7,0xf4,0xd7,0x26);
104c2c66affSColin Finck
105c2c66affSColin Finck static const WCHAR stdfont[] = {'S','t','d','F','o','n','t',0};
106c2c66affSColin Finck static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
107c2c66affSColin Finck static const WCHAR wszCLSID_StdFont[] =
108c2c66affSColin Finck {
109c2c66affSColin Finck '{','0','b','e','3','5','2','0','3','-','8','f','9','1','-','1','1','c','e','-',
110c2c66affSColin Finck '9','d','e','3','-','0','0','a','a','0','0','4','b','b','8','5','1','}',0
111c2c66affSColin Finck };
112c2c66affSColin Finck static const WCHAR progidW[] = {'P','r','o','g','I','d','.','P','r','o','g','I','d',0};
113c2c66affSColin Finck static const WCHAR cf_brokenW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
114c2c66affSColin Finck 'c','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}','a',0};
115c2c66affSColin Finck
116c2c66affSColin Finck DEFINE_GUID(IID_IWineTest, 0x5201163f, 0x8164, 0x4fd0, 0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd);
117c2c66affSColin Finck DEFINE_GUID(CLSID_WineOOPTest, 0x5201163f, 0x8164, 0x4fd0, 0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd);
118c2c66affSColin Finck
119c2c66affSColin Finck static LONG cLocks;
120c2c66affSColin Finck
LockModule(void)121c2c66affSColin Finck static void LockModule(void)
122c2c66affSColin Finck {
123c2c66affSColin Finck InterlockedIncrement(&cLocks);
124c2c66affSColin Finck }
125c2c66affSColin Finck
UnlockModule(void)126c2c66affSColin Finck static void UnlockModule(void)
127c2c66affSColin Finck {
128c2c66affSColin Finck InterlockedDecrement(&cLocks);
129c2c66affSColin Finck }
130c2c66affSColin Finck
Test_IClassFactory_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID * ppvObj)131c2c66affSColin Finck static HRESULT WINAPI Test_IClassFactory_QueryInterface(
132c2c66affSColin Finck LPCLASSFACTORY iface,
133c2c66affSColin Finck REFIID riid,
134c2c66affSColin Finck LPVOID *ppvObj)
135c2c66affSColin Finck {
136c2c66affSColin Finck if (ppvObj == NULL) return E_POINTER;
137c2c66affSColin Finck
138c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown) ||
139c2c66affSColin Finck IsEqualGUID(riid, &IID_IClassFactory))
140c2c66affSColin Finck {
141c2c66affSColin Finck *ppvObj = iface;
142c2c66affSColin Finck IClassFactory_AddRef(iface);
143c2c66affSColin Finck return S_OK;
144c2c66affSColin Finck }
145c2c66affSColin Finck
146c2c66affSColin Finck *ppvObj = NULL;
147c2c66affSColin Finck return E_NOINTERFACE;
148c2c66affSColin Finck }
149c2c66affSColin Finck
Test_IClassFactory_AddRef(LPCLASSFACTORY iface)150c2c66affSColin Finck static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
151c2c66affSColin Finck {
152c2c66affSColin Finck LockModule();
153c2c66affSColin Finck return 2; /* non-heap-based object */
154c2c66affSColin Finck }
155c2c66affSColin Finck
Test_IClassFactory_Release(LPCLASSFACTORY iface)156c2c66affSColin Finck static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
157c2c66affSColin Finck {
158c2c66affSColin Finck UnlockModule();
159c2c66affSColin Finck return 1; /* non-heap-based object */
160c2c66affSColin Finck }
161c2c66affSColin Finck
162c2c66affSColin Finck static IID create_instance_iid;
Test_IClassFactory_CreateInstance(LPCLASSFACTORY iface,IUnknown * pUnkOuter,REFIID riid,LPVOID * ppvObj)163c2c66affSColin Finck static HRESULT WINAPI Test_IClassFactory_CreateInstance(
164c2c66affSColin Finck LPCLASSFACTORY iface,
165c2c66affSColin Finck IUnknown *pUnkOuter,
166c2c66affSColin Finck REFIID riid,
167c2c66affSColin Finck LPVOID *ppvObj)
168c2c66affSColin Finck {
169c2c66affSColin Finck *ppvObj = NULL;
170c2c66affSColin Finck create_instance_iid = *riid;
171c2c66affSColin Finck if (pUnkOuter) return CLASS_E_NOAGGREGATION;
172c2c66affSColin Finck return E_NOINTERFACE;
173c2c66affSColin Finck }
174c2c66affSColin Finck
Test_IClassFactory_LockServer(LPCLASSFACTORY iface,BOOL fLock)175c2c66affSColin Finck static HRESULT WINAPI Test_IClassFactory_LockServer(
176c2c66affSColin Finck LPCLASSFACTORY iface,
177c2c66affSColin Finck BOOL fLock)
178c2c66affSColin Finck {
179c2c66affSColin Finck return S_OK;
180c2c66affSColin Finck }
181c2c66affSColin Finck
182c2c66affSColin Finck static const IClassFactoryVtbl TestClassFactory_Vtbl =
183c2c66affSColin Finck {
184c2c66affSColin Finck Test_IClassFactory_QueryInterface,
185c2c66affSColin Finck Test_IClassFactory_AddRef,
186c2c66affSColin Finck Test_IClassFactory_Release,
187c2c66affSColin Finck Test_IClassFactory_CreateInstance,
188c2c66affSColin Finck Test_IClassFactory_LockServer
189c2c66affSColin Finck };
190c2c66affSColin Finck
191c2c66affSColin Finck static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
192c2c66affSColin Finck
193c2c66affSColin Finck static WCHAR manifest_path[MAX_PATH];
194c2c66affSColin Finck
create_manifest_file(const char * filename,const char * manifest)195c2c66affSColin Finck static BOOL create_manifest_file(const char *filename, const char *manifest)
196c2c66affSColin Finck {
197c2c66affSColin Finck int manifest_len;
198c2c66affSColin Finck DWORD size;
199c2c66affSColin Finck HANDLE file;
200c2c66affSColin Finck WCHAR path[MAX_PATH];
201c2c66affSColin Finck
202c2c66affSColin Finck MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
2035c1bcfecSAmine Khaldi GetFullPathNameW(path, ARRAY_SIZE(manifest_path), manifest_path, NULL);
204c2c66affSColin Finck
205c2c66affSColin Finck manifest_len = strlen(manifest);
206c2c66affSColin Finck file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
207c2c66affSColin Finck FILE_ATTRIBUTE_NORMAL, NULL);
208c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
209c2c66affSColin Finck if(file == INVALID_HANDLE_VALUE)
210c2c66affSColin Finck return FALSE;
211c2c66affSColin Finck WriteFile(file, manifest, manifest_len, &size, NULL);
212c2c66affSColin Finck CloseHandle(file);
213c2c66affSColin Finck
214c2c66affSColin Finck return TRUE;
215c2c66affSColin Finck }
216c2c66affSColin Finck
activate_context(const char * manifest,ULONG_PTR * cookie)217c2c66affSColin Finck static HANDLE activate_context(const char *manifest, ULONG_PTR *cookie)
218c2c66affSColin Finck {
219c2c66affSColin Finck WCHAR path[MAX_PATH];
220c2c66affSColin Finck ACTCTXW actctx;
221c2c66affSColin Finck HANDLE handle;
222c2c66affSColin Finck BOOL ret;
223c2c66affSColin Finck
224c2c66affSColin Finck if (!pCreateActCtxW) return NULL;
225c2c66affSColin Finck
226c2c66affSColin Finck create_manifest_file("file.manifest", manifest);
227c2c66affSColin Finck
228c2c66affSColin Finck MultiByteToWideChar( CP_ACP, 0, "file.manifest", -1, path, MAX_PATH );
229c2c66affSColin Finck memset(&actctx, 0, sizeof(ACTCTXW));
230c2c66affSColin Finck actctx.cbSize = sizeof(ACTCTXW);
231c2c66affSColin Finck actctx.lpSource = path;
232c2c66affSColin Finck
233c2c66affSColin Finck handle = pCreateActCtxW(&actctx);
234c2c66affSColin Finck ok(handle != INVALID_HANDLE_VALUE || broken(handle == INVALID_HANDLE_VALUE) /* some old XP/2k3 versions */,
235c2c66affSColin Finck "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError());
236c2c66affSColin Finck if (handle == INVALID_HANDLE_VALUE)
237c2c66affSColin Finck {
238c2c66affSColin Finck win_skip("activation context generation failed, some tests will be skipped\n");
239c2c66affSColin Finck handle = NULL;
240c2c66affSColin Finck }
241c2c66affSColin Finck
242c2c66affSColin Finck ok(actctx.cbSize == sizeof(ACTCTXW), "actctx.cbSize=%d\n", actctx.cbSize);
243c2c66affSColin Finck ok(actctx.dwFlags == 0, "actctx.dwFlags=%d\n", actctx.dwFlags);
244c2c66affSColin Finck ok(actctx.lpSource == path, "actctx.lpSource=%p\n", actctx.lpSource);
245c2c66affSColin Finck ok(actctx.wProcessorArchitecture == 0, "actctx.wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
246c2c66affSColin Finck ok(actctx.wLangId == 0, "actctx.wLangId=%d\n", actctx.wLangId);
247c2c66affSColin Finck ok(actctx.lpAssemblyDirectory == NULL, "actctx.lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
248c2c66affSColin Finck ok(actctx.lpResourceName == NULL, "actctx.lpResourceName=%p\n", actctx.lpResourceName);
249c2c66affSColin Finck ok(actctx.lpApplicationName == NULL, "actctx.lpApplicationName=%p\n", actctx.lpApplicationName);
250c2c66affSColin Finck ok(actctx.hModule == NULL, "actctx.hModule=%p\n", actctx.hModule);
251c2c66affSColin Finck
252c2c66affSColin Finck DeleteFileA("file.manifest");
253c2c66affSColin Finck
254c2c66affSColin Finck if (handle)
255c2c66affSColin Finck {
256c2c66affSColin Finck ret = pActivateActCtx(handle, cookie);
257c2c66affSColin Finck ok(ret, "ActivateActCtx failed: %u\n", GetLastError());
258c2c66affSColin Finck }
259c2c66affSColin Finck
260c2c66affSColin Finck return handle;
261c2c66affSColin Finck }
262c2c66affSColin Finck
263c2c66affSColin Finck static const char actctx_manifest[] =
264c2c66affSColin Finck "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
265c2c66affSColin Finck "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\""
266c2c66affSColin Finck " publicKeyToken=\"6595b6414666f1df\" />"
267c2c66affSColin Finck "<file name=\"testlib.dll\">"
268c2c66affSColin Finck " <comClass"
269c2c66affSColin Finck " clsid=\"{0000033a-0000-0000-c000-000000000046}\""
270c2c66affSColin Finck " progid=\"FTMarshal\""
271c2c66affSColin Finck " />"
272c2c66affSColin Finck " <comClass"
273c2c66affSColin Finck " clsid=\"{5201163f-8164-4fd0-a1a2-5d5a3654d3bd}\""
274c2c66affSColin Finck " progid=\"WineOOPTest\""
275c2c66affSColin Finck " />"
276c2c66affSColin Finck " <comClass description=\"Test com class\""
277c2c66affSColin Finck " clsid=\"{12345678-1234-1234-1234-56789abcdef0}\""
278c2c66affSColin Finck " progid=\"ProgId.ProgId\""
279c2c66affSColin Finck " miscStatusIcon=\"recomposeonresize\""
280c2c66affSColin Finck " />"
281c2c66affSColin Finck " <comClass description=\"CustomFont Description\" clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb851}\""
282c2c66affSColin Finck " progid=\"CustomFont\""
283c2c66affSColin Finck " miscStatusIcon=\"recomposeonresize\""
284c2c66affSColin Finck " miscStatusContent=\"insideout\""
285c2c66affSColin Finck " />"
286c2c66affSColin Finck " <comClass description=\"StdFont Description\" clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb852}\""
287c2c66affSColin Finck " progid=\"StdFont\""
288c2c66affSColin Finck " />"
289c2c66affSColin Finck " <comClass clsid=\"{62222222-1234-1234-1234-56789abcdef0}\" >"
290c2c66affSColin Finck " <progid>ProgId.ProgId.1</progid>"
291c2c66affSColin Finck " </comClass>"
292c2c66affSColin Finck " <comInterfaceProxyStub "
293c2c66affSColin Finck " name=\"Iifaceps\""
294c2c66affSColin Finck " iid=\"{22222222-1234-1234-1234-56789abcdef0}\""
295c2c66affSColin Finck " proxyStubClsid32=\"{66666666-8888-7777-6666-555555555555}\""
296c2c66affSColin Finck " />"
297c2c66affSColin Finck "</file>"
298c2c66affSColin Finck " <comInterfaceExternalProxyStub "
299c2c66affSColin Finck " name=\"Iifaceps2\""
300c2c66affSColin Finck " iid=\"{32222222-1234-1234-1234-56789abcdef0}\""
301c2c66affSColin Finck " />"
302c2c66affSColin Finck " <comInterfaceExternalProxyStub "
303c2c66affSColin Finck " name=\"Iifaceps3\""
304c2c66affSColin Finck " iid=\"{42222222-1234-1234-1234-56789abcdef0}\""
305c2c66affSColin Finck " proxyStubClsid32=\"{66666666-8888-7777-6666-555555555555}\""
306c2c66affSColin Finck " />"
307c2c66affSColin Finck " <comInterfaceExternalProxyStub "
308c2c66affSColin Finck " name=\"Iifaceps4\""
309c2c66affSColin Finck " iid=\"{52222222-1234-1234-1234-56789abcdef0}\""
310c2c66affSColin Finck " proxyStubClsid32=\"{00000000-0000-0000-0000-000000000000}\""
311c2c66affSColin Finck " />"
312c2c66affSColin Finck " <clrClass "
313c2c66affSColin Finck " clsid=\"{72222222-1234-1234-1234-56789abcdef0}\""
314c2c66affSColin Finck " name=\"clrclass\""
315c2c66affSColin Finck " >"
316c2c66affSColin Finck " <progid>clrprogid.1</progid>"
317c2c66affSColin Finck " </clrClass>"
318c2c66affSColin Finck "</assembly>";
319c2c66affSColin Finck
320c2c66affSColin Finck DEFINE_GUID(CLSID_Testclass, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0);
321c2c66affSColin Finck
test_ProgIDFromCLSID(void)322c2c66affSColin Finck static void test_ProgIDFromCLSID(void)
323c2c66affSColin Finck {
324c2c66affSColin Finck ULONG_PTR cookie = 0;
325c2c66affSColin Finck LPWSTR progid;
326c2c66affSColin Finck HANDLE handle;
327c2c66affSColin Finck HRESULT hr;
328c2c66affSColin Finck
329c2c66affSColin Finck hr = ProgIDFromCLSID(&CLSID_StdFont, &progid);
330c2c66affSColin Finck ok(hr == S_OK, "ProgIDFromCLSID failed with error 0x%08x\n", hr);
331c2c66affSColin Finck if (hr == S_OK)
332c2c66affSColin Finck {
333c2c66affSColin Finck ok(!lstrcmpiW(progid, stdfont), "Didn't get expected prog ID\n");
334c2c66affSColin Finck CoTaskMemFree(progid);
335c2c66affSColin Finck }
336c2c66affSColin Finck
337c2c66affSColin Finck progid = (LPWSTR)0xdeadbeef;
338c2c66affSColin Finck hr = ProgIDFromCLSID(&CLSID_non_existent, &progid);
339c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "ProgIDFromCLSID returned %08x\n", hr);
340c2c66affSColin Finck ok(progid == NULL, "ProgIDFromCLSID returns with progid %p\n", progid);
341c2c66affSColin Finck
342c2c66affSColin Finck hr = ProgIDFromCLSID(&CLSID_StdFont, NULL);
343c2c66affSColin Finck ok(hr == E_INVALIDARG, "ProgIDFromCLSID should return E_INVALIDARG instead of 0x%08x\n", hr);
344c2c66affSColin Finck
345c2c66affSColin Finck if ((handle = activate_context(actctx_manifest, &cookie)))
346c2c66affSColin Finck {
347c2c66affSColin Finck static const WCHAR customfontW[] = {'C','u','s','t','o','m','F','o','n','t',0};
348c2c66affSColin Finck
349c2c66affSColin Finck hr = ProgIDFromCLSID(&CLSID_non_existent, &progid);
350c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
351c2c66affSColin Finck ok(!lstrcmpiW(progid, progidW), "got %s\n", wine_dbgstr_w(progid));
352c2c66affSColin Finck CoTaskMemFree(progid);
353c2c66affSColin Finck
354c2c66affSColin Finck /* try something registered and redirected */
355c2c66affSColin Finck progid = NULL;
356c2c66affSColin Finck hr = ProgIDFromCLSID(&CLSID_StdFont, &progid);
357c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
358c2c66affSColin Finck ok(!lstrcmpiW(progid, customfontW), "got wrong progid %s\n", wine_dbgstr_w(progid));
359c2c66affSColin Finck CoTaskMemFree(progid);
360c2c66affSColin Finck
361c2c66affSColin Finck /* classes without default progid, progid list is not used */
362c2c66affSColin Finck progid = (void *)0xdeadbeef;
363c2c66affSColin Finck hr = ProgIDFromCLSID(&IID_Testiface5, &progid);
364c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG && progid == NULL, "got 0x%08x, progid %p\n", hr, progid);
365c2c66affSColin Finck
366c2c66affSColin Finck progid = (void *)0xdeadbeef;
367c2c66affSColin Finck hr = ProgIDFromCLSID(&IID_Testiface6, &progid);
368c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG && progid == NULL, "got 0x%08x, progid %p\n", hr, progid);
369c2c66affSColin Finck
370c2c66affSColin Finck pDeactivateActCtx(0, cookie);
371c2c66affSColin Finck pReleaseActCtx(handle);
372c2c66affSColin Finck }
373c2c66affSColin Finck }
374c2c66affSColin Finck
test_CLSIDFromProgID(void)375c2c66affSColin Finck static void test_CLSIDFromProgID(void)
376c2c66affSColin Finck {
377c2c66affSColin Finck ULONG_PTR cookie = 0;
378c2c66affSColin Finck HANDLE handle;
379c2c66affSColin Finck CLSID clsid;
380c2c66affSColin Finck HRESULT hr = CLSIDFromProgID(stdfont, &clsid);
381c2c66affSColin Finck ok(hr == S_OK, "CLSIDFromProgID failed with error 0x%08x\n", hr);
382c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
383c2c66affSColin Finck
384c2c66affSColin Finck hr = CLSIDFromString(stdfont, &clsid);
385c2c66affSColin Finck ok_ole_success(hr, "CLSIDFromString");
386c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
387c2c66affSColin Finck
388c2c66affSColin Finck /* test some failure cases */
389c2c66affSColin Finck
390c2c66affSColin Finck hr = CLSIDFromProgID(wszNonExistent, NULL);
391c2c66affSColin Finck ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr);
392c2c66affSColin Finck
393c2c66affSColin Finck hr = CLSIDFromProgID(NULL, &clsid);
394c2c66affSColin Finck ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr);
395c2c66affSColin Finck
396c2c66affSColin Finck memset(&clsid, 0xcc, sizeof(clsid));
397c2c66affSColin Finck hr = CLSIDFromProgID(wszNonExistent, &clsid);
398c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "CLSIDFromProgID on nonexistent ProgID should have returned CO_E_CLASSSTRING instead of 0x%08x\n", hr);
399c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_NULL), "CLSIDFromProgID should have set clsid to all-zeros on failure\n");
400c2c66affSColin Finck
401c2c66affSColin Finck /* fails without proper context */
402c2c66affSColin Finck memset(&clsid, 0xcc, sizeof(clsid));
403c2c66affSColin Finck hr = CLSIDFromProgID(progidW, &clsid);
404c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
405c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_NULL), "wrong clsid\n");
406c2c66affSColin Finck
407c2c66affSColin Finck if ((handle = activate_context(actctx_manifest, &cookie)))
408c2c66affSColin Finck {
409c2c66affSColin Finck GUID clsid1;
410c2c66affSColin Finck
411c2c66affSColin Finck memset(&clsid, 0xcc, sizeof(clsid));
412c2c66affSColin Finck hr = CLSIDFromProgID(wszNonExistent, &clsid);
413c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
414c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_NULL), "should have zero CLSID on failure\n");
415c2c66affSColin Finck
416c2c66affSColin Finck /* CLSIDFromString() doesn't check activation context */
417c2c66affSColin Finck hr = CLSIDFromString(progidW, &clsid);
418c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
419c2c66affSColin Finck
420c2c66affSColin Finck clsid = CLSID_NULL;
421c2c66affSColin Finck hr = CLSIDFromProgID(progidW, &clsid);
422c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
423c2c66affSColin Finck /* it returns generated CLSID here */
424c2c66affSColin Finck ok(!IsEqualCLSID(&clsid, &CLSID_non_existent) && !IsEqualCLSID(&clsid, &CLSID_NULL),
425c2c66affSColin Finck "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
426c2c66affSColin Finck
427c2c66affSColin Finck /* duplicate progid present in context - returns generated guid here too */
428c2c66affSColin Finck clsid = CLSID_NULL;
429c2c66affSColin Finck hr = CLSIDFromProgID(stdfont, &clsid);
430c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
431c2c66affSColin Finck clsid1 = CLSID_StdFont;
432c2c66affSColin Finck /* that's where it differs from StdFont */
433c2c66affSColin Finck clsid1.Data4[7] = 0x52;
434c2c66affSColin Finck ok(!IsEqualCLSID(&clsid, &CLSID_StdFont) && !IsEqualCLSID(&clsid, &CLSID_NULL) && !IsEqualCLSID(&clsid, &clsid1),
435c2c66affSColin Finck "got %s\n", wine_dbgstr_guid(&clsid));
436c2c66affSColin Finck
437c2c66affSColin Finck pDeactivateActCtx(0, cookie);
438c2c66affSColin Finck pReleaseActCtx(handle);
439c2c66affSColin Finck }
440c2c66affSColin Finck }
441c2c66affSColin Finck
test_CLSIDFromString(void)442c2c66affSColin Finck static void test_CLSIDFromString(void)
443c2c66affSColin Finck {
444c2c66affSColin Finck CLSID clsid;
445c2c66affSColin Finck WCHAR wszCLSID_Broken[50];
446c2c66affSColin Finck UINT i;
447c2c66affSColin Finck
448c2c66affSColin Finck HRESULT hr = CLSIDFromString(wszCLSID_StdFont, &clsid);
449c2c66affSColin Finck ok_ole_success(hr, "CLSIDFromString");
450c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
451c2c66affSColin Finck
452c2c66affSColin Finck memset(&clsid, 0xab, sizeof(clsid));
453c2c66affSColin Finck hr = CLSIDFromString(NULL, &clsid);
454c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
455c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
456c2c66affSColin Finck
457c2c66affSColin Finck /* string is longer, but starts with a valid CLSID */
458c2c66affSColin Finck memset(&clsid, 0, sizeof(clsid));
459c2c66affSColin Finck hr = CLSIDFromString(cf_brokenW, &clsid);
460c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
461c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &IID_IClassFactory), "got %s\n", wine_dbgstr_guid(&clsid));
462c2c66affSColin Finck
463c2c66affSColin Finck lstrcpyW(wszCLSID_Broken, wszCLSID_StdFont);
464c2c66affSColin Finck for(i = lstrlenW(wszCLSID_StdFont); i < 49; i++)
465c2c66affSColin Finck wszCLSID_Broken[i] = 'A';
466c2c66affSColin Finck wszCLSID_Broken[i] = '\0';
467c2c66affSColin Finck
468c2c66affSColin Finck memset(&clsid, 0, sizeof(CLSID));
469c2c66affSColin Finck hr = CLSIDFromString(wszCLSID_Broken, &clsid);
470c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
471c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
472c2c66affSColin Finck
473c2c66affSColin Finck wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = 'A';
474c2c66affSColin Finck memset(&clsid, 0, sizeof(CLSID));
475c2c66affSColin Finck hr = CLSIDFromString(wszCLSID_Broken, &clsid);
476c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
477c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
478c2c66affSColin Finck
479c2c66affSColin Finck wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)] = '\0';
480c2c66affSColin Finck memset(&clsid, 0, sizeof(CLSID));
481c2c66affSColin Finck hr = CLSIDFromString(wszCLSID_Broken, &clsid);
482c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
483c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
484c2c66affSColin Finck
485c2c66affSColin Finck wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = '\0';
486c2c66affSColin Finck memset(&clsid, 0, sizeof(CLSID));
487c2c66affSColin Finck hr = CLSIDFromString(wszCLSID_Broken, &clsid);
488c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
489c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
490c2c66affSColin Finck
491c2c66affSColin Finck memset(&clsid, 0xcc, sizeof(CLSID));
492c2c66affSColin Finck hr = CLSIDFromString(wszCLSID_Broken+1, &clsid);
493c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
494c2c66affSColin Finck ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
495c2c66affSColin Finck
496c2c66affSColin Finck wszCLSID_Broken[9] = '*';
497c2c66affSColin Finck memset(&clsid, 0xcc, sizeof(CLSID));
498c2c66affSColin Finck hr = CLSIDFromString(wszCLSID_Broken, &clsid);
499c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
500c2c66affSColin Finck ok(clsid.Data1 == CLSID_StdFont.Data1, "Got %08x\n", clsid.Data1);
501c2c66affSColin Finck ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
502c2c66affSColin Finck
503c2c66affSColin Finck wszCLSID_Broken[3] = '*';
504c2c66affSColin Finck memset(&clsid, 0xcc, sizeof(CLSID));
505c2c66affSColin Finck hr = CLSIDFromString(wszCLSID_Broken, &clsid);
506c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
507c2c66affSColin Finck ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1);
508c2c66affSColin Finck ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
509c2c66affSColin Finck
510c2c66affSColin Finck wszCLSID_Broken[3] = '\0';
511c2c66affSColin Finck memset(&clsid, 0xcc, sizeof(CLSID));
512c2c66affSColin Finck hr = CLSIDFromString(wszCLSID_Broken, &clsid);
513c2c66affSColin Finck ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
514c2c66affSColin Finck ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1);
515c2c66affSColin Finck ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
516c2c66affSColin Finck }
517c2c66affSColin Finck
test_IIDFromString(void)518c2c66affSColin Finck static void test_IIDFromString(void)
519c2c66affSColin Finck {
520c2c66affSColin Finck static const WCHAR cfW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
521c2c66affSColin Finck 'c','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
522c2c66affSColin Finck static const WCHAR brokenW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
523c2c66affSColin Finck 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
524c2c66affSColin Finck static const WCHAR broken2W[] = {'{','0','0','0','0','0','0','0','1','=','0','0','0','0','-','0','0','0','0','-',
525c2c66affSColin Finck 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
526c2c66affSColin Finck static const WCHAR broken3W[] = {'b','r','o','k','e','n','0','0','1','=','0','0','0','0','-','0','0','0','0','-',
527c2c66affSColin Finck 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
528c2c66affSColin Finck HRESULT hr;
529c2c66affSColin Finck IID iid;
530c2c66affSColin Finck
531c2c66affSColin Finck hr = IIDFromString(wszCLSID_StdFont, &iid);
532c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
533c2c66affSColin Finck ok(IsEqualIID(&iid, &CLSID_StdFont), "got iid %s\n", wine_dbgstr_guid(&iid));
534c2c66affSColin Finck
535c2c66affSColin Finck memset(&iid, 0xab, sizeof(iid));
536c2c66affSColin Finck hr = IIDFromString(NULL, &iid);
537c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
538c2c66affSColin Finck ok(IsEqualIID(&iid, &CLSID_NULL), "got iid %s\n", wine_dbgstr_guid(&iid));
539c2c66affSColin Finck
540c2c66affSColin Finck hr = IIDFromString(cfW, &iid);
541c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
542c2c66affSColin Finck ok(IsEqualIID(&iid, &IID_IClassFactory), "got iid %s\n", wine_dbgstr_guid(&iid));
543c2c66affSColin Finck
544c2c66affSColin Finck /* string starts with a valid IID but is longer */
545c2c66affSColin Finck memset(&iid, 0xab, sizeof(iid));
546c2c66affSColin Finck hr = IIDFromString(cf_brokenW, &iid);
547c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
548c2c66affSColin Finck ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
549c2c66affSColin Finck
550c2c66affSColin Finck /* invalid IID in a valid format */
551c2c66affSColin Finck memset(&iid, 0xab, sizeof(iid));
552c2c66affSColin Finck hr = IIDFromString(brokenW, &iid);
553c2c66affSColin Finck ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
554c2c66affSColin Finck ok(iid.Data1 == 0x00000001, "Got %08x\n", iid.Data1);
555c2c66affSColin Finck
556c2c66affSColin Finck memset(&iid, 0xab, sizeof(iid));
557c2c66affSColin Finck hr = IIDFromString(broken2W, &iid);
558c2c66affSColin Finck ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
559c2c66affSColin Finck ok(iid.Data1 == 0x00000001, "Got %08x\n", iid.Data1);
560c2c66affSColin Finck
561c2c66affSColin Finck /* format is broken, but string length is okay */
562c2c66affSColin Finck memset(&iid, 0xab, sizeof(iid));
563c2c66affSColin Finck hr = IIDFromString(broken3W, &iid);
564c2c66affSColin Finck ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
565c2c66affSColin Finck ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
566c2c66affSColin Finck
567c2c66affSColin Finck /* invalid string */
568c2c66affSColin Finck memset(&iid, 0xab, sizeof(iid));
569c2c66affSColin Finck hr = IIDFromString(wszNonExistent, &iid);
570c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
571c2c66affSColin Finck ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
572c2c66affSColin Finck
573c2c66affSColin Finck /* valid ProgID */
574c2c66affSColin Finck memset(&iid, 0xab, sizeof(iid));
575c2c66affSColin Finck hr = IIDFromString(stdfont, &iid);
576c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
577c2c66affSColin Finck ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
578c2c66affSColin Finck }
579c2c66affSColin Finck
test_StringFromGUID2(void)580c2c66affSColin Finck static void test_StringFromGUID2(void)
581c2c66affSColin Finck {
582c2c66affSColin Finck WCHAR str[50];
583c2c66affSColin Finck int len;
584c2c66affSColin Finck
585c2c66affSColin Finck /* invalid pointer */
586c2c66affSColin Finck SetLastError(0xdeadbeef);
587c2c66affSColin Finck len = StringFromGUID2(NULL,str,50);
588c2c66affSColin Finck ok(len == 0, "len: %d (expected 0)\n", len);
589c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %x\n", GetLastError());
590c2c66affSColin Finck
591c2c66affSColin Finck /* Test corner cases for buffer size */
592c2c66affSColin Finck len = StringFromGUID2(&CLSID_StdFont,str,50);
593c2c66affSColin Finck ok(len == 39, "len: %d (expected 39)\n", len);
594c2c66affSColin Finck ok(!lstrcmpiW(str, wszCLSID_StdFont),"string wasn't equal for CLSID_StdFont\n");
595c2c66affSColin Finck
596c2c66affSColin Finck memset(str,0,sizeof str);
597c2c66affSColin Finck len = StringFromGUID2(&CLSID_StdFont,str,39);
598c2c66affSColin Finck ok(len == 39, "len: %d (expected 39)\n", len);
599c2c66affSColin Finck ok(!lstrcmpiW(str, wszCLSID_StdFont),"string wasn't equal for CLSID_StdFont\n");
600c2c66affSColin Finck
601c2c66affSColin Finck len = StringFromGUID2(&CLSID_StdFont,str,38);
602c2c66affSColin Finck ok(len == 0, "len: %d (expected 0)\n", len);
603c2c66affSColin Finck
604c2c66affSColin Finck len = StringFromGUID2(&CLSID_StdFont,str,30);
605c2c66affSColin Finck ok(len == 0, "len: %d (expected 0)\n", len);
606c2c66affSColin Finck }
607c2c66affSColin Finck
608a6cdf4ffSAmine Khaldi #define test_apt_type(t, q) _test_apt_type(t, q, __LINE__)
_test_apt_type(APTTYPE expected_type,APTTYPEQUALIFIER expected_qualifier,int line)609a6cdf4ffSAmine Khaldi static void _test_apt_type(APTTYPE expected_type, APTTYPEQUALIFIER expected_qualifier, int line)
610c2c66affSColin Finck {
611c2c66affSColin Finck APTTYPEQUALIFIER qualifier = ~0u;
612c2c66affSColin Finck APTTYPE type = ~0u;
613c2c66affSColin Finck HRESULT hr;
614c2c66affSColin Finck
615c2c66affSColin Finck if (!pCoGetApartmentType)
616c2c66affSColin Finck return;
617c2c66affSColin Finck
618c2c66affSColin Finck hr = pCoGetApartmentType(&type, &qualifier);
619c2c66affSColin Finck ok_(__FILE__, line)(hr == S_OK || hr == CO_E_NOTINITIALIZED, "Unexpected return code: 0x%08x\n", hr);
620c2c66affSColin Finck ok_(__FILE__, line)(type == expected_type, "Wrong apartment type %d, expected %d\n", type, expected_type);
621c2c66affSColin Finck ok_(__FILE__, line)(qualifier == expected_qualifier, "Wrong apartment qualifier %d, expected %d\n", qualifier,
622c2c66affSColin Finck expected_qualifier);
623c2c66affSColin Finck }
624c2c66affSColin Finck
test_CoCreateInstance(void)625c2c66affSColin Finck static void test_CoCreateInstance(void)
626c2c66affSColin Finck {
627c2c66affSColin Finck HRESULT hr;
628c2c66affSColin Finck IUnknown *pUnk;
629c2c66affSColin Finck REFCLSID rclsid = &CLSID_InternetZoneManager;
630c2c66affSColin Finck
631c2c66affSColin Finck pUnk = (IUnknown *)0xdeadbeef;
632c2c66affSColin Finck hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
633c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
634c2c66affSColin Finck ok(pUnk == NULL, "CoCreateInstance should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
635c2c66affSColin Finck
636c2c66affSColin Finck OleInitialize(NULL);
637c2c66affSColin Finck
638c2c66affSColin Finck /* test errors returned for non-registered clsids */
639c2c66affSColin Finck hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
640c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
641c2c66affSColin Finck hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pUnk);
642c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc handler should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
643c2c66affSColin Finck hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_LOCAL_SERVER, &IID_IUnknown, (void **)&pUnk);
644c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered local server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
645c2c66affSColin Finck hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_REMOTE_SERVER, &IID_IUnknown, (void **)&pUnk);
646c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered remote server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
647c2c66affSColin Finck
648c2c66affSColin Finck hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
649c2c66affSColin Finck if(hr == REGDB_E_CLASSNOTREG)
650c2c66affSColin Finck {
651c2c66affSColin Finck skip("IE not installed so can't test CoCreateInstance\n");
652c2c66affSColin Finck OleUninitialize();
653c2c66affSColin Finck return;
654c2c66affSColin Finck }
655c2c66affSColin Finck
656c2c66affSColin Finck ok_ole_success(hr, "CoCreateInstance");
657c2c66affSColin Finck if(pUnk) IUnknown_Release(pUnk);
658c2c66affSColin Finck OleUninitialize();
659c2c66affSColin Finck
660c2c66affSColin Finck hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
661c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
662c2c66affSColin Finck
663a6cdf4ffSAmine Khaldi test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE);
664c2c66affSColin Finck }
665c2c66affSColin Finck
test_CoGetClassObject(void)666c2c66affSColin Finck static void test_CoGetClassObject(void)
667c2c66affSColin Finck {
668c2c66affSColin Finck HRESULT hr;
669a6cdf4ffSAmine Khaldi HANDLE handle;
670c2c66affSColin Finck ULONG_PTR cookie;
671c2c66affSColin Finck IUnknown *pUnk;
672c2c66affSColin Finck REFCLSID rclsid = &CLSID_InternetZoneManager;
673c2c66affSColin Finck HKEY hkey;
674c2c66affSColin Finck LONG res;
675c2c66affSColin Finck
676c2c66affSColin Finck hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
677c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoGetClassObject should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
678c2c66affSColin Finck ok(pUnk == NULL, "CoGetClassObject should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
679c2c66affSColin Finck
680c2c66affSColin Finck hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, NULL);
681c2c66affSColin Finck ok(hr == E_INVALIDARG ||
682c2c66affSColin Finck broken(hr == CO_E_NOTINITIALIZED), /* win9x */
683c2c66affSColin Finck "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08x\n", hr);
684c2c66affSColin Finck
685a6cdf4ffSAmine Khaldi test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE);
686c2c66affSColin Finck
687c2c66affSColin Finck if (!pRegOverridePredefKey)
688c2c66affSColin Finck {
689c2c66affSColin Finck win_skip("RegOverridePredefKey not available\n");
690c2c66affSColin Finck return;
691c2c66affSColin Finck }
692c2c66affSColin Finck
693c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_MULTITHREADED);
694c2c66affSColin Finck
695c2c66affSColin Finck hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
696c2c66affSColin Finck if (hr == S_OK)
697c2c66affSColin Finck {
698c2c66affSColin Finck IUnknown_Release(pUnk);
699c2c66affSColin Finck
700c2c66affSColin Finck res = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Classes", 0, NULL, 0,
701c2c66affSColin Finck KEY_ALL_ACCESS, NULL, &hkey, NULL);
702c2c66affSColin Finck ok(!res, "RegCreateKeyEx returned %d\n", res);
703c2c66affSColin Finck
704c2c66affSColin Finck res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, hkey);
705c2c66affSColin Finck ok(!res, "RegOverridePredefKey returned %d\n", res);
706c2c66affSColin Finck
707c2c66affSColin Finck hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
708c2c66affSColin Finck ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr);
709c2c66affSColin Finck
710c2c66affSColin Finck res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
711c2c66affSColin Finck ok(!res, "RegOverridePredefKey returned %d\n", res);
712c2c66affSColin Finck
713c2c66affSColin Finck if (hr == S_OK) IUnknown_Release(pUnk);
714c2c66affSColin Finck RegCloseKey(hkey);
715c2c66affSColin Finck }
716c2c66affSColin Finck
717c2c66affSColin Finck hr = CoGetClassObject(&CLSID_InProcFreeMarshaler, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
718c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
719c2c66affSColin Finck IUnknown_Release(pUnk);
720c2c66affSColin Finck
721c2c66affSColin Finck /* context redefines FreeMarshaler CLSID */
722c2c66affSColin Finck if ((handle = activate_context(actctx_manifest, &cookie)))
723c2c66affSColin Finck {
724c2c66affSColin Finck hr = CoGetClassObject(&CLSID_InProcFreeMarshaler, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
725c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
726c2c66affSColin Finck IUnknown_Release(pUnk);
727c2c66affSColin Finck
728c2c66affSColin Finck pDeactivateActCtx(0, cookie);
729c2c66affSColin Finck pReleaseActCtx(handle);
730c2c66affSColin Finck }
731c2c66affSColin Finck
732c2c66affSColin Finck CoUninitialize();
733c2c66affSColin Finck }
734c2c66affSColin Finck
test_CoCreateInstanceEx(void)735c2c66affSColin Finck static void test_CoCreateInstanceEx(void)
736c2c66affSColin Finck {
737c2c66affSColin Finck MULTI_QI qi_res = { &IID_IMoniker };
738c2c66affSColin Finck DWORD cookie;
739c2c66affSColin Finck HRESULT hr;
740c2c66affSColin Finck
741c2c66affSColin Finck CoInitialize(NULL);
742c2c66affSColin Finck
743c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
744c2c66affSColin Finck CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie);
745c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
746c2c66affSColin Finck
747c2c66affSColin Finck create_instance_iid = IID_NULL;
748c2c66affSColin Finck hr = CoCreateInstanceEx(&CLSID_WineOOPTest, NULL, CLSCTX_INPROC_SERVER, NULL, 1, &qi_res);
749c2c66affSColin Finck ok(hr == E_NOINTERFACE, "CoCreateInstanceEx failed: %08x\n", hr);
750c2c66affSColin Finck ok(IsEqualGUID(&create_instance_iid, qi_res.pIID), "Unexpected CreateInstance iid %s\n",
751c2c66affSColin Finck wine_dbgstr_guid(&create_instance_iid));
752c2c66affSColin Finck
753c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
754c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
755c2c66affSColin Finck
756c2c66affSColin Finck CoUninitialize();
757c2c66affSColin Finck }
758c2c66affSColin Finck
register_dummy_class(void)759c2c66affSColin Finck static ATOM register_dummy_class(void)
760c2c66affSColin Finck {
761c2c66affSColin Finck WNDCLASSA wc =
762c2c66affSColin Finck {
763c2c66affSColin Finck 0,
764c2c66affSColin Finck DefWindowProcA,
765c2c66affSColin Finck 0,
766c2c66affSColin Finck 0,
767c2c66affSColin Finck GetModuleHandleA(NULL),
768c2c66affSColin Finck NULL,
769c2c66affSColin Finck LoadCursorA(NULL, (LPSTR)IDC_ARROW),
770c2c66affSColin Finck (HBRUSH)(COLOR_BTNFACE+1),
771c2c66affSColin Finck NULL,
772c2c66affSColin Finck "WineOleTestClass",
773c2c66affSColin Finck };
774c2c66affSColin Finck
775c2c66affSColin Finck return RegisterClassA(&wc);
776c2c66affSColin Finck }
777c2c66affSColin Finck
test_ole_menu(void)778c2c66affSColin Finck static void test_ole_menu(void)
779c2c66affSColin Finck {
780c2c66affSColin Finck HWND hwndFrame;
781c2c66affSColin Finck HRESULT hr;
782c2c66affSColin Finck
783c2c66affSColin Finck hwndFrame = CreateWindowA((LPCSTR)MAKEINTATOM(register_dummy_class()), "Test", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
784c2c66affSColin Finck hr = OleSetMenuDescriptor(NULL, hwndFrame, NULL, NULL, NULL);
785c2c66affSColin Finck todo_wine ok_ole_success(hr, "OleSetMenuDescriptor");
786c2c66affSColin Finck
787c2c66affSColin Finck DestroyWindow(hwndFrame);
788c2c66affSColin Finck }
789c2c66affSColin Finck
790c2c66affSColin Finck
MessageFilter_QueryInterface(IMessageFilter * iface,REFIID riid,void ** ppvObj)791c2c66affSColin Finck static HRESULT WINAPI MessageFilter_QueryInterface(IMessageFilter *iface, REFIID riid, void ** ppvObj)
792c2c66affSColin Finck {
793c2c66affSColin Finck if (ppvObj == NULL) return E_POINTER;
794c2c66affSColin Finck
795c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown) ||
796fc6e4ed5SAmine Khaldi IsEqualGUID(riid, &IID_IMessageFilter))
797c2c66affSColin Finck {
798c2c66affSColin Finck *ppvObj = iface;
799c2c66affSColin Finck IMessageFilter_AddRef(iface);
800c2c66affSColin Finck return S_OK;
801c2c66affSColin Finck }
802c2c66affSColin Finck
803c2c66affSColin Finck return E_NOINTERFACE;
804c2c66affSColin Finck }
805c2c66affSColin Finck
MessageFilter_AddRef(IMessageFilter * iface)806c2c66affSColin Finck static ULONG WINAPI MessageFilter_AddRef(IMessageFilter *iface)
807c2c66affSColin Finck {
808c2c66affSColin Finck return 2; /* non-heap object */
809c2c66affSColin Finck }
810c2c66affSColin Finck
MessageFilter_Release(IMessageFilter * iface)811c2c66affSColin Finck static ULONG WINAPI MessageFilter_Release(IMessageFilter *iface)
812c2c66affSColin Finck {
813c2c66affSColin Finck return 1; /* non-heap object */
814c2c66affSColin Finck }
815c2c66affSColin Finck
MessageFilter_HandleInComingCall(IMessageFilter * iface,DWORD dwCallType,HTASK threadIDCaller,DWORD dwTickCount,LPINTERFACEINFO lpInterfaceInfo)816c2c66affSColin Finck static DWORD WINAPI MessageFilter_HandleInComingCall(
817c2c66affSColin Finck IMessageFilter *iface,
818c2c66affSColin Finck DWORD dwCallType,
819c2c66affSColin Finck HTASK threadIDCaller,
820c2c66affSColin Finck DWORD dwTickCount,
821c2c66affSColin Finck LPINTERFACEINFO lpInterfaceInfo)
822c2c66affSColin Finck {
823c2c66affSColin Finck trace("HandleInComingCall\n");
824c2c66affSColin Finck return SERVERCALL_ISHANDLED;
825c2c66affSColin Finck }
826c2c66affSColin Finck
MessageFilter_RetryRejectedCall(IMessageFilter * iface,HTASK threadIDCallee,DWORD dwTickCount,DWORD dwRejectType)827c2c66affSColin Finck static DWORD WINAPI MessageFilter_RetryRejectedCall(
828c2c66affSColin Finck IMessageFilter *iface,
829c2c66affSColin Finck HTASK threadIDCallee,
830c2c66affSColin Finck DWORD dwTickCount,
831c2c66affSColin Finck DWORD dwRejectType)
832c2c66affSColin Finck {
833c2c66affSColin Finck trace("RetryRejectedCall\n");
834c2c66affSColin Finck return 0;
835c2c66affSColin Finck }
836c2c66affSColin Finck
MessageFilter_MessagePending(IMessageFilter * iface,HTASK threadIDCallee,DWORD dwTickCount,DWORD dwPendingType)837c2c66affSColin Finck static DWORD WINAPI MessageFilter_MessagePending(
838c2c66affSColin Finck IMessageFilter *iface,
839c2c66affSColin Finck HTASK threadIDCallee,
840c2c66affSColin Finck DWORD dwTickCount,
841c2c66affSColin Finck DWORD dwPendingType)
842c2c66affSColin Finck {
843c2c66affSColin Finck trace("MessagePending\n");
844*e26c8bc6STimo Kreuzer ros_skip_flaky
84566f35ef8SAmine Khaldi todo_wine ok(0, "unexpected call\n");
846c2c66affSColin Finck return PENDINGMSG_WAITNOPROCESS;
847c2c66affSColin Finck }
848c2c66affSColin Finck
849c2c66affSColin Finck static const IMessageFilterVtbl MessageFilter_Vtbl =
850c2c66affSColin Finck {
851c2c66affSColin Finck MessageFilter_QueryInterface,
852c2c66affSColin Finck MessageFilter_AddRef,
853c2c66affSColin Finck MessageFilter_Release,
854c2c66affSColin Finck MessageFilter_HandleInComingCall,
855c2c66affSColin Finck MessageFilter_RetryRejectedCall,
856c2c66affSColin Finck MessageFilter_MessagePending
857c2c66affSColin Finck };
858c2c66affSColin Finck
859c2c66affSColin Finck static IMessageFilter MessageFilter = { &MessageFilter_Vtbl };
860c2c66affSColin Finck
test_CoRegisterMessageFilter(void)861c2c66affSColin Finck static void test_CoRegisterMessageFilter(void)
862c2c66affSColin Finck {
863c2c66affSColin Finck HRESULT hr;
864c2c66affSColin Finck IMessageFilter *prev_filter;
865c2c66affSColin Finck
866c2c66affSColin Finck hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
867c2c66affSColin Finck ok(hr == CO_E_NOT_SUPPORTED,
868c2c66affSColin Finck "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
869c2c66affSColin Finck hr);
870c2c66affSColin Finck
871c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_MULTITHREADED);
872c2c66affSColin Finck prev_filter = (IMessageFilter *)0xdeadbeef;
873c2c66affSColin Finck hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
874c2c66affSColin Finck ok(hr == CO_E_NOT_SUPPORTED,
875c2c66affSColin Finck "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
876c2c66affSColin Finck hr);
877c2c66affSColin Finck ok(prev_filter == (IMessageFilter *)0xdeadbeef,
878c2c66affSColin Finck "prev_filter should have been set to %p\n", prev_filter);
879c2c66affSColin Finck CoUninitialize();
880c2c66affSColin Finck
881c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
882c2c66affSColin Finck
883c2c66affSColin Finck hr = CoRegisterMessageFilter(NULL, NULL);
884c2c66affSColin Finck ok_ole_success(hr, "CoRegisterMessageFilter");
885c2c66affSColin Finck
886c2c66affSColin Finck prev_filter = (IMessageFilter *)0xdeadbeef;
887c2c66affSColin Finck hr = CoRegisterMessageFilter(NULL, &prev_filter);
888c2c66affSColin Finck ok_ole_success(hr, "CoRegisterMessageFilter");
889c2c66affSColin Finck ok(prev_filter == NULL, "prev_filter should have been set to NULL instead of %p\n", prev_filter);
890c2c66affSColin Finck
891c2c66affSColin Finck hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
892c2c66affSColin Finck ok_ole_success(hr, "CoRegisterMessageFilter");
893c2c66affSColin Finck ok(prev_filter == NULL, "prev_filter should have been set to NULL instead of %p\n", prev_filter);
894c2c66affSColin Finck
895c2c66affSColin Finck hr = CoRegisterMessageFilter(NULL, NULL);
896c2c66affSColin Finck ok_ole_success(hr, "CoRegisterMessageFilter");
897c2c66affSColin Finck
898c2c66affSColin Finck CoUninitialize();
899c2c66affSColin Finck }
900c2c66affSColin Finck
901c2c66affSColin Finck static IUnknown Test_Unknown;
902c2c66affSColin Finck
EnumOLEVERB_QueryInterface(IEnumOLEVERB * iface,REFIID riid,void ** ppv)903c2c66affSColin Finck static HRESULT WINAPI EnumOLEVERB_QueryInterface(IEnumOLEVERB *iface, REFIID riid, void **ppv)
904c2c66affSColin Finck {
905c2c66affSColin Finck return IUnknown_QueryInterface(&Test_Unknown, riid, ppv);
906c2c66affSColin Finck }
907c2c66affSColin Finck
EnumOLEVERB_AddRef(IEnumOLEVERB * iface)908c2c66affSColin Finck static ULONG WINAPI EnumOLEVERB_AddRef(IEnumOLEVERB *iface)
909c2c66affSColin Finck {
910c2c66affSColin Finck return 2;
911c2c66affSColin Finck }
912c2c66affSColin Finck
EnumOLEVERB_Release(IEnumOLEVERB * iface)913c2c66affSColin Finck static ULONG WINAPI EnumOLEVERB_Release(IEnumOLEVERB *iface)
914c2c66affSColin Finck {
915c2c66affSColin Finck return 1;
916c2c66affSColin Finck }
917c2c66affSColin Finck
EnumOLEVERB_Next(IEnumOLEVERB * iface,ULONG celt,OLEVERB * rgelt,ULONG * fetched)918c2c66affSColin Finck static HRESULT WINAPI EnumOLEVERB_Next(IEnumOLEVERB *iface, ULONG celt, OLEVERB *rgelt, ULONG *fetched)
919c2c66affSColin Finck {
920c2c66affSColin Finck ok(0, "unexpected call\n");
921c2c66affSColin Finck return E_NOTIMPL;
922c2c66affSColin Finck }
923c2c66affSColin Finck
EnumOLEVERB_Skip(IEnumOLEVERB * iface,ULONG celt)924c2c66affSColin Finck static HRESULT WINAPI EnumOLEVERB_Skip(IEnumOLEVERB *iface, ULONG celt)
925c2c66affSColin Finck {
926c2c66affSColin Finck ok(0, "unexpected call\n");
927c2c66affSColin Finck return E_NOTIMPL;
928c2c66affSColin Finck }
929c2c66affSColin Finck
EnumOLEVERB_Reset(IEnumOLEVERB * iface)930c2c66affSColin Finck static HRESULT WINAPI EnumOLEVERB_Reset(IEnumOLEVERB *iface)
931c2c66affSColin Finck {
932c2c66affSColin Finck ok(0, "unexpected call\n");
933c2c66affSColin Finck return E_NOTIMPL;
934c2c66affSColin Finck }
935c2c66affSColin Finck
EnumOLEVERB_Clone(IEnumOLEVERB * iface,IEnumOLEVERB ** ppenum)936c2c66affSColin Finck static HRESULT WINAPI EnumOLEVERB_Clone(IEnumOLEVERB *iface, IEnumOLEVERB **ppenum)
937c2c66affSColin Finck {
938c2c66affSColin Finck ok(0, "unexpected call\n");
939c2c66affSColin Finck return E_NOTIMPL;
940c2c66affSColin Finck }
941c2c66affSColin Finck
942c2c66affSColin Finck static const IEnumOLEVERBVtbl EnumOLEVERBVtbl = {
943c2c66affSColin Finck EnumOLEVERB_QueryInterface,
944c2c66affSColin Finck EnumOLEVERB_AddRef,
945c2c66affSColin Finck EnumOLEVERB_Release,
946c2c66affSColin Finck EnumOLEVERB_Next,
947c2c66affSColin Finck EnumOLEVERB_Skip,
948c2c66affSColin Finck EnumOLEVERB_Reset,
949c2c66affSColin Finck EnumOLEVERB_Clone
950c2c66affSColin Finck };
951c2c66affSColin Finck
952c2c66affSColin Finck static IEnumOLEVERB EnumOLEVERB = { &EnumOLEVERBVtbl };
953c2c66affSColin Finck
Test_IUnknown_QueryInterface(IUnknown * iface,REFIID riid,LPVOID * ppvObj)954c2c66affSColin Finck static HRESULT WINAPI Test_IUnknown_QueryInterface(
955c2c66affSColin Finck IUnknown *iface,
956c2c66affSColin Finck REFIID riid,
957c2c66affSColin Finck LPVOID *ppvObj)
958c2c66affSColin Finck {
959c2c66affSColin Finck if (ppvObj == NULL) return E_POINTER;
960c2c66affSColin Finck
961c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IWineTest)) {
962c2c66affSColin Finck *ppvObj = iface;
963c2c66affSColin Finck }else if(IsEqualIID(riid, &IID_IEnumOLEVERB)) {
964c2c66affSColin Finck *ppvObj = &EnumOLEVERB;
965c2c66affSColin Finck }else {
966c2c66affSColin Finck *ppvObj = NULL;
967c2c66affSColin Finck return E_NOINTERFACE;
968c2c66affSColin Finck }
969c2c66affSColin Finck
970c2c66affSColin Finck IUnknown_AddRef((IUnknown*)*ppvObj);
971c2c66affSColin Finck return S_OK;
972c2c66affSColin Finck }
973c2c66affSColin Finck
Test_IUnknown_AddRef(IUnknown * iface)974c2c66affSColin Finck static ULONG WINAPI Test_IUnknown_AddRef(IUnknown *iface)
975c2c66affSColin Finck {
976c2c66affSColin Finck return 2; /* non-heap-based object */
977c2c66affSColin Finck }
978c2c66affSColin Finck
Test_IUnknown_Release(IUnknown * iface)979c2c66affSColin Finck static ULONG WINAPI Test_IUnknown_Release(IUnknown *iface)
980c2c66affSColin Finck {
981c2c66affSColin Finck return 1; /* non-heap-based object */
982c2c66affSColin Finck }
983c2c66affSColin Finck
984c2c66affSColin Finck static const IUnknownVtbl TestUnknown_Vtbl =
985c2c66affSColin Finck {
986c2c66affSColin Finck Test_IUnknown_QueryInterface,
987c2c66affSColin Finck Test_IUnknown_AddRef,
988c2c66affSColin Finck Test_IUnknown_Release,
989c2c66affSColin Finck };
990c2c66affSColin Finck
991c2c66affSColin Finck static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
992c2c66affSColin Finck
993c2c66affSColin Finck static IPSFactoryBuffer *ps_factory_buffer;
994c2c66affSColin Finck
PSFactoryBuffer_QueryInterface(IPSFactoryBuffer * This,REFIID riid,void ** ppvObject)995c2c66affSColin Finck static HRESULT WINAPI PSFactoryBuffer_QueryInterface(
996c2c66affSColin Finck IPSFactoryBuffer * This,
997c2c66affSColin Finck /* [in] */ REFIID riid,
998c2c66affSColin Finck /* [iid_is][out] */ void **ppvObject)
999c2c66affSColin Finck {
1000c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown) ||
1001c2c66affSColin Finck IsEqualIID(riid, &IID_IPSFactoryBuffer))
1002c2c66affSColin Finck {
1003c2c66affSColin Finck *ppvObject = This;
1004c2c66affSColin Finck IPSFactoryBuffer_AddRef(This);
1005c2c66affSColin Finck return S_OK;
1006c2c66affSColin Finck }
1007c2c66affSColin Finck return E_NOINTERFACE;
1008c2c66affSColin Finck }
1009c2c66affSColin Finck
PSFactoryBuffer_AddRef(IPSFactoryBuffer * This)1010c2c66affSColin Finck static ULONG WINAPI PSFactoryBuffer_AddRef(
1011c2c66affSColin Finck IPSFactoryBuffer * This)
1012c2c66affSColin Finck {
1013c2c66affSColin Finck return 2;
1014c2c66affSColin Finck }
1015c2c66affSColin Finck
PSFactoryBuffer_Release(IPSFactoryBuffer * This)1016c2c66affSColin Finck static ULONG WINAPI PSFactoryBuffer_Release(
1017c2c66affSColin Finck IPSFactoryBuffer * This)
1018c2c66affSColin Finck {
1019c2c66affSColin Finck return 1;
1020c2c66affSColin Finck }
1021c2c66affSColin Finck
PSFactoryBuffer_CreateProxy(IPSFactoryBuffer * This,IUnknown * pUnkOuter,REFIID riid,IRpcProxyBuffer ** ppProxy,void ** ppv)1022c2c66affSColin Finck static HRESULT WINAPI PSFactoryBuffer_CreateProxy(
1023c2c66affSColin Finck IPSFactoryBuffer * This,
1024c2c66affSColin Finck /* [in] */ IUnknown *pUnkOuter,
1025c2c66affSColin Finck /* [in] */ REFIID riid,
1026c2c66affSColin Finck /* [out] */ IRpcProxyBuffer **ppProxy,
1027c2c66affSColin Finck /* [out] */ void **ppv)
1028c2c66affSColin Finck {
1029c2c66affSColin Finck return E_NOTIMPL;
1030c2c66affSColin Finck }
1031c2c66affSColin Finck
PSFactoryBuffer_CreateStub(IPSFactoryBuffer * This,REFIID riid,IUnknown * pUnkServer,IRpcStubBuffer ** ppStub)1032c2c66affSColin Finck static HRESULT WINAPI PSFactoryBuffer_CreateStub(
1033c2c66affSColin Finck IPSFactoryBuffer * This,
1034c2c66affSColin Finck /* [in] */ REFIID riid,
1035c2c66affSColin Finck /* [unique][in] */ IUnknown *pUnkServer,
1036c2c66affSColin Finck /* [out] */ IRpcStubBuffer **ppStub)
1037c2c66affSColin Finck {
1038c2c66affSColin Finck CHECK_EXPECT(CreateStub);
1039c2c66affSColin Finck
1040fc6e4ed5SAmine Khaldi ok(pUnkServer == &Test_Unknown, "unexpected pUnkServer %p\n", pUnkServer);
1041c2c66affSColin Finck if(!ps_factory_buffer)
1042c2c66affSColin Finck return E_NOTIMPL;
1043c2c66affSColin Finck
1044c2c66affSColin Finck return IPSFactoryBuffer_CreateStub(ps_factory_buffer, &IID_IEnumOLEVERB, pUnkServer, ppStub);
1045c2c66affSColin Finck }
1046c2c66affSColin Finck
1047c2c66affSColin Finck static IPSFactoryBufferVtbl PSFactoryBufferVtbl =
1048c2c66affSColin Finck {
1049c2c66affSColin Finck PSFactoryBuffer_QueryInterface,
1050c2c66affSColin Finck PSFactoryBuffer_AddRef,
1051c2c66affSColin Finck PSFactoryBuffer_Release,
1052c2c66affSColin Finck PSFactoryBuffer_CreateProxy,
1053c2c66affSColin Finck PSFactoryBuffer_CreateStub
1054c2c66affSColin Finck };
1055c2c66affSColin Finck
1056c2c66affSColin Finck static IPSFactoryBuffer PSFactoryBuffer = { &PSFactoryBufferVtbl };
1057c2c66affSColin Finck
1058c2c66affSColin Finck static const CLSID CLSID_WineTestPSFactoryBuffer =
1059c2c66affSColin Finck {
1060c2c66affSColin Finck 0x52011640,
1061c2c66affSColin Finck 0x8164,
1062c2c66affSColin Finck 0x4fd0,
1063c2c66affSColin Finck {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
1064c2c66affSColin Finck }; /* 52011640-8164-4fd0-a1a2-5d5a3654d3bd */
1065c2c66affSColin Finck
register_ps_clsid_thread(void * context)1066c2c66affSColin Finck static DWORD CALLBACK register_ps_clsid_thread(void *context)
1067c2c66affSColin Finck {
1068c2c66affSColin Finck HRESULT hr;
1069c2c66affSColin Finck CLSID clsid = {0};
1070c2c66affSColin Finck
1071c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1072c2c66affSColin Finck
1073c2c66affSColin Finck hr = CoGetPSClsid(&IID_IWineTest, &clsid);
1074c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1075c2c66affSColin Finck ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1076c2c66affSColin Finck wine_dbgstr_guid(&CLSID_WineTestPSFactoryBuffer), wine_dbgstr_guid(&clsid));
1077c2c66affSColin Finck
1078c2c66affSColin Finck /* test registering a PSClsid in an apartment which is then destroyed */
1079c2c66affSColin Finck hr = CoRegisterPSClsid(&IID_TestPS, &clsid);
1080c2c66affSColin Finck ok_ole_success(hr, "CoRegisterPSClsid");
1081c2c66affSColin Finck
1082c2c66affSColin Finck CoUninitialize();
1083c2c66affSColin Finck
1084c2c66affSColin Finck return hr;
1085c2c66affSColin Finck }
1086c2c66affSColin Finck
test_CoRegisterPSClsid(void)1087c2c66affSColin Finck static void test_CoRegisterPSClsid(void)
1088c2c66affSColin Finck {
1089c2c66affSColin Finck HRESULT hr;
1090c2c66affSColin Finck DWORD dwRegistrationKey;
1091c2c66affSColin Finck IStream *stream;
1092c2c66affSColin Finck CLSID clsid;
1093c2c66affSColin Finck HANDLE thread;
1094c2c66affSColin Finck DWORD tid;
1095c2c66affSColin Finck
1096c2c66affSColin Finck hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
1097c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoRegisterPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1098c2c66affSColin Finck
1099c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1100c2c66affSColin Finck
1101c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer, (IUnknown *)&PSFactoryBuffer,
1102c2c66affSColin Finck CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegistrationKey);
1103c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1104c2c66affSColin Finck
1105c2c66affSColin Finck hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
1106c2c66affSColin Finck ok_ole_success(hr, "CoRegisterPSClsid");
1107c2c66affSColin Finck
1108c2c66affSColin Finck hr = CoGetPSClsid(&IID_IWineTest, &clsid);
1109c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1110c2c66affSColin Finck ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1111c2c66affSColin Finck wine_dbgstr_guid(&CLSID_WineTestPSFactoryBuffer), wine_dbgstr_guid(&clsid));
1112c2c66affSColin Finck
1113c2c66affSColin Finck thread = CreateThread(NULL, 0, register_ps_clsid_thread, NULL, 0, &tid);
1114c2c66affSColin Finck ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1115c2c66affSColin Finck ok(!WaitForSingleObject(thread, 10000), "wait timed out\n");
1116c2c66affSColin Finck CloseHandle(thread);
1117c2c66affSColin Finck
1118c2c66affSColin Finck hr = CoGetPSClsid(&IID_TestPS, &clsid);
1119c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1120c2c66affSColin Finck ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1121c2c66affSColin Finck wine_dbgstr_guid(&CLSID_WineTestPSFactoryBuffer), wine_dbgstr_guid(&clsid));
1122c2c66affSColin Finck
1123c2c66affSColin Finck hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1124c2c66affSColin Finck ok_ole_success(hr, "CreateStreamOnHGlobal");
1125c2c66affSColin Finck
1126c2c66affSColin Finck SET_EXPECT(CreateStub);
1127c2c66affSColin Finck hr = CoMarshalInterface(stream, &IID_IWineTest, &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1128c2c66affSColin Finck ok(hr == E_NOTIMPL, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1129fc6e4ed5SAmine Khaldi CHECK_CALLED(CreateStub, 1);
1130c2c66affSColin Finck
1131c2c66affSColin Finck hr = CoGetPSClsid(&IID_IEnumOLEVERB, &clsid);
1132c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1133c2c66affSColin Finck
1134c2c66affSColin Finck hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void **)&ps_factory_buffer);
1135c2c66affSColin Finck ok_ole_success(hr, "CoGetClassObject");
1136c2c66affSColin Finck
1137c2c66affSColin Finck hr = CoRegisterPSClsid(&IID_IEnumOLEVERB, &CLSID_WineTestPSFactoryBuffer);
1138c2c66affSColin Finck ok_ole_success(hr, "CoRegisterPSClsid");
1139c2c66affSColin Finck
1140c2c66affSColin Finck SET_EXPECT(CreateStub);
1141c2c66affSColin Finck hr = CoMarshalInterface(stream, &IID_IEnumOLEVERB, (IUnknown*)&EnumOLEVERB, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1142c2c66affSColin Finck ok(hr == S_OK, "CoMarshalInterface should have returned S_OK instead of 0x%08x\n", hr);
1143fc6e4ed5SAmine Khaldi CHECK_CALLED(CreateStub, 1);
1144c2c66affSColin Finck
1145c2c66affSColin Finck hr = CoMarshalInterface(stream, &IID_IEnumOLEVERB, &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1146c2c66affSColin Finck ok(hr == S_OK, "CoMarshalInterface should have returned S_OK instead of 0x%08x\n", hr);
1147c2c66affSColin Finck
1148c2c66affSColin Finck IStream_Release(stream);
1149c2c66affSColin Finck IPSFactoryBuffer_Release(ps_factory_buffer);
1150c2c66affSColin Finck ps_factory_buffer = NULL;
1151c2c66affSColin Finck
1152c2c66affSColin Finck hr = CoRevokeClassObject(dwRegistrationKey);
1153c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1154c2c66affSColin Finck
1155c2c66affSColin Finck CoUninitialize();
1156c2c66affSColin Finck
1157c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1158c2c66affSColin Finck
1159c2c66affSColin Finck hr = CoGetPSClsid(&IID_IWineTest, &clsid);
1160c2c66affSColin Finck ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08x\n", hr);
1161c2c66affSColin Finck
1162c2c66affSColin Finck hr = CoGetPSClsid(&IID_TestPS, &clsid);
1163c2c66affSColin Finck ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08x\n", hr);
1164c2c66affSColin Finck
1165c2c66affSColin Finck CoUninitialize();
1166c2c66affSColin Finck
1167c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_MULTITHREADED);
1168c2c66affSColin Finck
1169c2c66affSColin Finck hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
1170c2c66affSColin Finck ok_ole_success(hr, "CoRegisterPSClsid");
1171c2c66affSColin Finck
1172c2c66affSColin Finck hr = CoGetPSClsid(&IID_IWineTest, &clsid);
1173c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1174c2c66affSColin Finck ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1175c2c66affSColin Finck wine_dbgstr_guid(&CLSID_WineTestPSFactoryBuffer), wine_dbgstr_guid(&clsid));
1176c2c66affSColin Finck
1177c2c66affSColin Finck thread = CreateThread(NULL, 0, register_ps_clsid_thread, NULL, 0, &tid);
1178c2c66affSColin Finck ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1179c2c66affSColin Finck ok(!WaitForSingleObject(thread, 10000), "wait timed out\n");
1180c2c66affSColin Finck CloseHandle(thread);
1181c2c66affSColin Finck
1182c2c66affSColin Finck hr = CoGetPSClsid(&IID_TestPS, &clsid);
1183c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1184c2c66affSColin Finck ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
1185c2c66affSColin Finck wine_dbgstr_guid(&CLSID_WineTestPSFactoryBuffer), wine_dbgstr_guid(&clsid));
1186c2c66affSColin Finck
1187c2c66affSColin Finck CoUninitialize();
1188c2c66affSColin Finck }
1189c2c66affSColin Finck
test_CoGetPSClsid(void)1190c2c66affSColin Finck static void test_CoGetPSClsid(void)
1191c2c66affSColin Finck {
1192c2c66affSColin Finck ULONG_PTR cookie;
1193c2c66affSColin Finck HANDLE handle;
1194c2c66affSColin Finck HRESULT hr;
1195c2c66affSColin Finck CLSID clsid;
1196c2c66affSColin Finck HKEY hkey;
1197c2c66affSColin Finck LONG res;
1198c2c66affSColin Finck const BOOL is_win64 = (sizeof(void*) != sizeof(int));
1199c2c66affSColin Finck BOOL is_wow64 = FALSE;
1200c2c66affSColin Finck
1201c2c66affSColin Finck hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
1202c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED,
1203c2c66affSColin Finck "CoGetPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n",
1204c2c66affSColin Finck hr);
1205c2c66affSColin Finck
1206c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1207c2c66affSColin Finck
1208c2c66affSColin Finck hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
1209c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1210c2c66affSColin Finck
1211c2c66affSColin Finck hr = CoGetPSClsid(&IID_IWineTest, &clsid);
1212c2c66affSColin Finck ok(hr == REGDB_E_IIDNOTREG,
1213c2c66affSColin Finck "CoGetPSClsid for random IID returned 0x%08x instead of REGDB_E_IIDNOTREG\n",
1214c2c66affSColin Finck hr);
1215c2c66affSColin Finck
1216c2c66affSColin Finck hr = CoGetPSClsid(&IID_IClassFactory, NULL);
1217c2c66affSColin Finck ok(hr == E_INVALIDARG,
1218c2c66affSColin Finck "CoGetPSClsid for null clsid returned 0x%08x instead of E_INVALIDARG\n",
1219c2c66affSColin Finck hr);
1220c2c66affSColin Finck
1221c2c66affSColin Finck if (!pRegOverridePredefKey)
1222c2c66affSColin Finck {
1223c2c66affSColin Finck win_skip("RegOverridePredefKey not available\n");
1224c2c66affSColin Finck CoUninitialize();
1225c2c66affSColin Finck return;
1226c2c66affSColin Finck }
1227c2c66affSColin Finck hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
1228c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1229c2c66affSColin Finck
1230c2c66affSColin Finck res = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Classes", 0, NULL, 0,
1231c2c66affSColin Finck KEY_ALL_ACCESS, NULL, &hkey, NULL);
1232c2c66affSColin Finck ok(!res, "RegCreateKeyEx returned %d\n", res);
1233c2c66affSColin Finck
1234c2c66affSColin Finck res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, hkey);
1235c2c66affSColin Finck ok(!res, "RegOverridePredefKey returned %d\n", res);
1236c2c66affSColin Finck
1237c2c66affSColin Finck hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
1238c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1239c2c66affSColin Finck
1240c2c66affSColin Finck res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
1241c2c66affSColin Finck ok(!res, "RegOverridePredefKey returned %d\n", res);
1242c2c66affSColin Finck
1243c2c66affSColin Finck RegCloseKey(hkey);
1244c2c66affSColin Finck
1245c2c66affSColin Finck /* not registered CLSID */
1246c2c66affSColin Finck hr = CoGetPSClsid(&IID_Testiface, &clsid);
1247c2c66affSColin Finck ok(hr == REGDB_E_IIDNOTREG, "got 0x%08x\n", hr);
1248c2c66affSColin Finck
1249c2c66affSColin Finck if ((handle = activate_context(actctx_manifest, &cookie)))
1250c2c66affSColin Finck {
1251c2c66affSColin Finck memset(&clsid, 0, sizeof(clsid));
1252c2c66affSColin Finck hr = CoGetPSClsid(&IID_Testiface, &clsid);
1253c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1254c2c66affSColin Finck ok(IsEqualGUID(&clsid, &IID_Testiface), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1255c2c66affSColin Finck
1256c2c66affSColin Finck memset(&clsid, 0, sizeof(clsid));
1257c2c66affSColin Finck hr = CoGetPSClsid(&IID_Testiface2, &clsid);
1258c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1259c2c66affSColin Finck ok(IsEqualGUID(&clsid, &IID_Testiface2), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1260c2c66affSColin Finck
1261c2c66affSColin Finck memset(&clsid, 0, sizeof(clsid));
1262c2c66affSColin Finck hr = CoGetPSClsid(&IID_Testiface3, &clsid);
1263c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1264c2c66affSColin Finck ok(IsEqualGUID(&clsid, &IID_TestPS), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1265c2c66affSColin Finck
1266c2c66affSColin Finck memset(&clsid, 0xaa, sizeof(clsid));
1267c2c66affSColin Finck hr = CoGetPSClsid(&IID_Testiface4, &clsid);
1268c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1269c2c66affSColin Finck ok(IsEqualGUID(&clsid, &GUID_NULL), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1270c2c66affSColin Finck
1271c2c66affSColin Finck /* register same interface and try to get CLSID back */
1272c2c66affSColin Finck hr = CoRegisterPSClsid(&IID_Testiface, &IID_Testiface4);
1273c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1274c2c66affSColin Finck memset(&clsid, 0, sizeof(clsid));
1275c2c66affSColin Finck hr = CoGetPSClsid(&IID_Testiface, &clsid);
1276c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1277c2c66affSColin Finck ok(IsEqualGUID(&clsid, &IID_Testiface4), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1278c2c66affSColin Finck
1279c2c66affSColin Finck pDeactivateActCtx(0, cookie);
1280c2c66affSColin Finck pReleaseActCtx(handle);
1281c2c66affSColin Finck }
1282c2c66affSColin Finck
1283c2c66affSColin Finck if (pRegDeleteKeyExA &&
1284c2c66affSColin Finck (is_win64 ||
1285c2c66affSColin Finck (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)))
1286c2c66affSColin Finck {
1287c2c66affSColin Finck static GUID IID_DeadBeef = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
1288c2c66affSColin Finck static const char clsidDeadBeef[] = "{deadbeef-dead-beef-dead-beefdeadbeef}";
1289c2c66affSColin Finck static const char clsidA[] = "{66666666-8888-7777-6666-555555555555}";
1290c2c66affSColin Finck HKEY hkey_iface, hkey_psclsid;
1291c2c66affSColin Finck REGSAM opposite = is_win64 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
1292c2c66affSColin Finck
1293c2c66affSColin Finck hr = CoGetPSClsid(&IID_DeadBeef, &clsid);
1294c2c66affSColin Finck ok(hr == REGDB_E_IIDNOTREG, "got 0x%08x\n", hr);
1295c2c66affSColin Finck
1296c2c66affSColin Finck res = RegCreateKeyExA(HKEY_CLASSES_ROOT, "Interface",
1297c2c66affSColin Finck 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey_iface, NULL);
1298c2c66affSColin Finck ok(!res, "RegCreateKeyEx returned %d\n", res);
1299c2c66affSColin Finck res = RegCreateKeyExA(hkey_iface, clsidDeadBeef,
1300c2c66affSColin Finck 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey, NULL);
1301c2c66affSColin Finck if (res == ERROR_ACCESS_DENIED)
1302c2c66affSColin Finck {
1303c2c66affSColin Finck win_skip("Failed to create a key, skipping some of CoGetPSClsid() tests\n");
1304c2c66affSColin Finck goto cleanup;
1305c2c66affSColin Finck }
1306c2c66affSColin Finck
1307c2c66affSColin Finck ok(!res, "RegCreateKeyEx returned %d\n", res);
1308c2c66affSColin Finck res = RegCreateKeyExA(hkey, "ProxyStubClsid32",
1309c2c66affSColin Finck 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey_psclsid, NULL);
1310c2c66affSColin Finck ok(!res, "RegCreateKeyEx returned %d\n", res);
1311c2c66affSColin Finck res = RegSetValueExA(hkey_psclsid, NULL, 0, REG_SZ, (const BYTE *)clsidA, strlen(clsidA)+1);
1312c2c66affSColin Finck ok(!res, "RegSetValueEx returned %d\n", res);
1313c2c66affSColin Finck RegCloseKey(hkey_psclsid);
1314c2c66affSColin Finck
1315c2c66affSColin Finck hr = CoGetPSClsid(&IID_DeadBeef, &clsid);
1316c2c66affSColin Finck ok_ole_success(hr, "CoGetPSClsid");
1317c2c66affSColin Finck ok(IsEqualGUID(&clsid, &IID_TestPS), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1318c2c66affSColin Finck
1319c2c66affSColin Finck res = pRegDeleteKeyExA(hkey, "ProxyStubClsid32", opposite, 0);
1320c2c66affSColin Finck ok(!res, "RegDeleteKeyEx returned %d\n", res);
1321c2c66affSColin Finck RegCloseKey(hkey);
1322c2c66affSColin Finck res = pRegDeleteKeyExA(hkey_iface, clsidDeadBeef, opposite, 0);
1323c2c66affSColin Finck ok(!res, "RegDeleteKeyEx returned %d\n", res);
1324c2c66affSColin Finck
1325c2c66affSColin Finck cleanup:
1326c2c66affSColin Finck RegCloseKey(hkey_iface);
1327c2c66affSColin Finck }
1328c2c66affSColin Finck
1329c2c66affSColin Finck CoUninitialize();
1330c2c66affSColin Finck }
1331c2c66affSColin Finck
1332c2c66affSColin Finck /* basic test, mainly for invalid arguments. see marshal.c for more */
test_CoUnmarshalInterface(void)1333c2c66affSColin Finck static void test_CoUnmarshalInterface(void)
1334c2c66affSColin Finck {
1335c2c66affSColin Finck IUnknown *pProxy;
1336c2c66affSColin Finck IStream *pStream;
1337c2c66affSColin Finck HRESULT hr;
1338c2c66affSColin Finck
1339c2c66affSColin Finck hr = CoUnmarshalInterface(NULL, &IID_IUnknown, (void **)&pProxy);
1340c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoUnmarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1341c2c66affSColin Finck
1342c2c66affSColin Finck hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1343c2c66affSColin Finck ok_ole_success(hr, "CreateStreamOnHGlobal");
1344c2c66affSColin Finck
1345c2c66affSColin Finck hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
1346c2c66affSColin Finck todo_wine
1347c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoUnmarshalInterface should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1348c2c66affSColin Finck
1349c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1350c2c66affSColin Finck
1351c2c66affSColin Finck hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
1352c2c66affSColin Finck ok(hr == STG_E_READFAULT, "CoUnmarshalInterface should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1353c2c66affSColin Finck
1354c2c66affSColin Finck CoUninitialize();
1355c2c66affSColin Finck
1356c2c66affSColin Finck hr = CoUnmarshalInterface(pStream, &IID_IUnknown, NULL);
1357c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoUnmarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1358c2c66affSColin Finck
1359c2c66affSColin Finck IStream_Release(pStream);
1360c2c66affSColin Finck }
1361c2c66affSColin Finck
test_CoGetInterfaceAndReleaseStream(void)1362c2c66affSColin Finck static void test_CoGetInterfaceAndReleaseStream(void)
1363c2c66affSColin Finck {
1364c2c66affSColin Finck HRESULT hr;
1365c2c66affSColin Finck IUnknown *pUnk;
1366c2c66affSColin Finck
1367c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1368c2c66affSColin Finck
1369c2c66affSColin Finck hr = CoGetInterfaceAndReleaseStream(NULL, &IID_IUnknown, (void**)&pUnk);
1370c2c66affSColin Finck ok(hr == E_INVALIDARG, "hr %08x\n", hr);
1371c2c66affSColin Finck
1372c2c66affSColin Finck CoUninitialize();
1373c2c66affSColin Finck }
1374c2c66affSColin Finck
1375c2c66affSColin Finck /* basic test, mainly for invalid arguments. see marshal.c for more */
test_CoMarshalInterface(void)1376c2c66affSColin Finck static void test_CoMarshalInterface(void)
1377c2c66affSColin Finck {
1378c2c66affSColin Finck IStream *pStream;
1379c2c66affSColin Finck HRESULT hr;
1380c2c66affSColin Finck static const LARGE_INTEGER llZero;
1381c2c66affSColin Finck
1382c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1383c2c66affSColin Finck
1384c2c66affSColin Finck hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1385c2c66affSColin Finck ok_ole_success(hr, "CreateStreamOnHGlobal");
1386c2c66affSColin Finck
1387c2c66affSColin Finck hr = CoMarshalInterface(pStream, &IID_IUnknown, NULL, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1388c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoMarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1389c2c66affSColin Finck
1390c2c66affSColin Finck hr = CoMarshalInterface(NULL, &IID_IUnknown, (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1391c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoMarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1392c2c66affSColin Finck
1393c2c66affSColin Finck hr = CoMarshalInterface(pStream, &IID_IUnknown, (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1394c2c66affSColin Finck ok_ole_success(hr, "CoMarshalInterface");
1395c2c66affSColin Finck
1396c2c66affSColin Finck /* stream not rewound */
1397c2c66affSColin Finck hr = CoReleaseMarshalData(pStream);
1398c2c66affSColin Finck ok(hr == STG_E_READFAULT, "CoReleaseMarshalData should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1399c2c66affSColin Finck
1400c2c66affSColin Finck hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1401c2c66affSColin Finck ok_ole_success(hr, "IStream_Seek");
1402c2c66affSColin Finck
1403c2c66affSColin Finck hr = CoReleaseMarshalData(pStream);
1404c2c66affSColin Finck ok_ole_success(hr, "CoReleaseMarshalData");
1405c2c66affSColin Finck
1406c2c66affSColin Finck IStream_Release(pStream);
1407c2c66affSColin Finck
1408c2c66affSColin Finck CoUninitialize();
1409c2c66affSColin Finck }
1410c2c66affSColin Finck
test_CoMarshalInterThreadInterfaceInStream(void)1411c2c66affSColin Finck static void test_CoMarshalInterThreadInterfaceInStream(void)
1412c2c66affSColin Finck {
1413c2c66affSColin Finck IStream *pStream;
1414c2c66affSColin Finck HRESULT hr;
1415c2c66affSColin Finck IClassFactory *pProxy;
1416c2c66affSColin Finck
1417c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1418c2c66affSColin Finck
1419c2c66affSColin Finck cLocks = 0;
1420c2c66affSColin Finck
1421c2c66affSColin Finck hr = CoMarshalInterThreadInterfaceInStream(&IID_IUnknown, (IUnknown *)&Test_ClassFactory, NULL);
1422c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoMarshalInterThreadInterfaceInStream should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1423c2c66affSColin Finck
1424c2c66affSColin Finck hr = CoMarshalInterThreadInterfaceInStream(&IID_IUnknown, NULL, &pStream);
1425c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoMarshalInterThreadInterfaceInStream should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1426c2c66affSColin Finck
1427c2c66affSColin Finck ok_no_locks();
1428c2c66affSColin Finck
1429c2c66affSColin Finck hr = CoMarshalInterThreadInterfaceInStream(&IID_IUnknown, (IUnknown *)&Test_ClassFactory, &pStream);
1430c2c66affSColin Finck ok_ole_success(hr, "CoMarshalInterThreadInterfaceInStream");
1431c2c66affSColin Finck
1432c2c66affSColin Finck ok_more_than_one_lock();
1433c2c66affSColin Finck
1434c2c66affSColin Finck hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1435c2c66affSColin Finck ok_ole_success(hr, "CoUnmarshalInterface");
1436c2c66affSColin Finck
1437c2c66affSColin Finck IClassFactory_Release(pProxy);
1438c2c66affSColin Finck IStream_Release(pStream);
1439c2c66affSColin Finck
1440c2c66affSColin Finck ok_no_locks();
1441c2c66affSColin Finck
1442c2c66affSColin Finck CoUninitialize();
1443c2c66affSColin Finck }
1444c2c66affSColin Finck
test_CoRegisterClassObject(void)1445c2c66affSColin Finck static void test_CoRegisterClassObject(void)
1446c2c66affSColin Finck {
1447c2c66affSColin Finck ULONG_PTR ctxcookie;
1448c2c66affSColin Finck HANDLE handle;
1449c2c66affSColin Finck DWORD cookie;
1450c2c66affSColin Finck HRESULT hr;
1451c2c66affSColin Finck IClassFactory *pcf;
1452c2c66affSColin Finck
1453c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1454c2c66affSColin Finck
1455c2c66affSColin Finck /* CLSCTX_INPROC_SERVER */
1456c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1457c2c66affSColin Finck CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1458c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1459c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1460c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1461c2c66affSColin Finck
1462c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1463c2c66affSColin Finck CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1464c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1465c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1466c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1467c2c66affSColin Finck
1468c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1469c2c66affSColin Finck CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &cookie);
1470c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1471c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1472c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1473c2c66affSColin Finck
1474c2c66affSColin Finck /* CLSCTX_LOCAL_SERVER */
1475c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1476c2c66affSColin Finck CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1477c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1478c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1479c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1480c2c66affSColin Finck
1481c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1482c2c66affSColin Finck CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1483c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1484c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1485c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1486c2c66affSColin Finck
1487c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1488c2c66affSColin Finck CLSCTX_LOCAL_SERVER, REGCLS_MULTI_SEPARATE, &cookie);
1489c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1490c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1491c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1492c2c66affSColin Finck
1493c2c66affSColin Finck /* CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER */
1494c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1495c2c66affSColin Finck CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1496c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1497c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1498c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1499c2c66affSColin Finck
1500c2c66affSColin Finck /* test whether an object that doesn't support IClassFactory can be
1501c2c66affSColin Finck * registered for CLSCTX_LOCAL_SERVER */
1502c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, &Test_Unknown,
1503c2c66affSColin Finck CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1504c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1505c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1506c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1507c2c66affSColin Finck
1508c2c66affSColin Finck /* test whether registered class becomes invalid when apartment is destroyed */
1509c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1510c2c66affSColin Finck CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1511c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1512c2c66affSColin Finck
1513c2c66affSColin Finck CoUninitialize();
1514c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1515c2c66affSColin Finck
1516c2c66affSColin Finck hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL,
1517c2c66affSColin Finck &IID_IClassFactory, (void **)&pcf);
1518c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "object registered in an apartment shouldn't accessible after it is destroyed\n");
1519c2c66affSColin Finck
1520c2c66affSColin Finck /* crashes with at least win9x DCOM! */
1521c2c66affSColin Finck if (0)
1522c2c66affSColin Finck CoRevokeClassObject(cookie);
1523c2c66affSColin Finck
1524c2c66affSColin Finck /* test that object is accessible */
1525c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory, CLSCTX_INPROC_SERVER,
1526c2c66affSColin Finck REGCLS_MULTIPLEUSE, &cookie);
1527c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1528c2c66affSColin Finck
1529c2c66affSColin Finck hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1530c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1531c2c66affSColin Finck IClassFactory_Release(pcf);
1532c2c66affSColin Finck
1533c2c66affSColin Finck /* context now contains CLSID_WineOOPTest, test if registered one could still be used */
1534c2c66affSColin Finck if ((handle = activate_context(actctx_manifest, &ctxcookie)))
1535c2c66affSColin Finck {
1536c2c66affSColin Finck hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1537c2c66affSColin Finck todo_wine
1538c2c66affSColin Finck ok(hr == HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND), "got 0x%08x\n", hr);
1539c2c66affSColin Finck
1540c2c66affSColin Finck pDeactivateActCtx(0, ctxcookie);
1541c2c66affSColin Finck pReleaseActCtx(handle);
1542c2c66affSColin Finck }
1543c2c66affSColin Finck
1544c2c66affSColin Finck hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1545c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1546c2c66affSColin Finck IClassFactory_Release(pcf);
1547c2c66affSColin Finck
1548c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1549c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1550c2c66affSColin Finck
1551c2c66affSColin Finck CoUninitialize();
1552c2c66affSColin Finck }
1553c2c66affSColin Finck
get_class_object(CLSCTX clsctx)1554c2c66affSColin Finck static HRESULT get_class_object(CLSCTX clsctx)
1555c2c66affSColin Finck {
1556c2c66affSColin Finck HRESULT hr;
1557c2c66affSColin Finck IClassFactory *pcf;
1558c2c66affSColin Finck
1559c2c66affSColin Finck hr = CoGetClassObject(&CLSID_WineOOPTest, clsctx, NULL, &IID_IClassFactory,
1560c2c66affSColin Finck (void **)&pcf);
1561c2c66affSColin Finck
1562c2c66affSColin Finck if (SUCCEEDED(hr))
1563c2c66affSColin Finck IClassFactory_Release(pcf);
1564c2c66affSColin Finck
1565c2c66affSColin Finck return hr;
1566c2c66affSColin Finck }
1567c2c66affSColin Finck
get_class_object_thread(LPVOID pv)1568c2c66affSColin Finck static DWORD CALLBACK get_class_object_thread(LPVOID pv)
1569c2c66affSColin Finck {
1570c2c66affSColin Finck CLSCTX clsctx = (CLSCTX)(DWORD_PTR)pv;
1571c2c66affSColin Finck HRESULT hr;
1572c2c66affSColin Finck
1573c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1574c2c66affSColin Finck
1575c2c66affSColin Finck hr = get_class_object(clsctx);
1576c2c66affSColin Finck
1577c2c66affSColin Finck CoUninitialize();
1578c2c66affSColin Finck
1579c2c66affSColin Finck return hr;
1580c2c66affSColin Finck }
1581c2c66affSColin Finck
get_class_object_proxy_thread(LPVOID pv)1582c2c66affSColin Finck static DWORD CALLBACK get_class_object_proxy_thread(LPVOID pv)
1583c2c66affSColin Finck {
1584c2c66affSColin Finck CLSCTX clsctx = (CLSCTX)(DWORD_PTR)pv;
1585c2c66affSColin Finck HRESULT hr;
1586c2c66affSColin Finck IClassFactory *pcf;
1587c2c66affSColin Finck IMultiQI *pMQI;
1588c2c66affSColin Finck
1589c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1590c2c66affSColin Finck
1591c2c66affSColin Finck hr = CoGetClassObject(&CLSID_WineOOPTest, clsctx, NULL, &IID_IClassFactory,
1592c2c66affSColin Finck (void **)&pcf);
1593c2c66affSColin Finck
1594c2c66affSColin Finck if (SUCCEEDED(hr))
1595c2c66affSColin Finck {
1596c2c66affSColin Finck hr = IClassFactory_QueryInterface(pcf, &IID_IMultiQI, (void **)&pMQI);
1597c2c66affSColin Finck if (SUCCEEDED(hr))
1598c2c66affSColin Finck IMultiQI_Release(pMQI);
1599c2c66affSColin Finck IClassFactory_Release(pcf);
1600c2c66affSColin Finck }
1601c2c66affSColin Finck
1602c2c66affSColin Finck CoUninitialize();
1603c2c66affSColin Finck
1604c2c66affSColin Finck return hr;
1605c2c66affSColin Finck }
1606c2c66affSColin Finck
register_class_object_thread(LPVOID pv)1607c2c66affSColin Finck static DWORD CALLBACK register_class_object_thread(LPVOID pv)
1608c2c66affSColin Finck {
1609c2c66affSColin Finck HRESULT hr;
1610c2c66affSColin Finck DWORD cookie;
1611c2c66affSColin Finck
1612c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1613c2c66affSColin Finck
1614c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1615c2c66affSColin Finck CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1616c2c66affSColin Finck
1617c2c66affSColin Finck CoUninitialize();
1618c2c66affSColin Finck
1619c2c66affSColin Finck return hr;
1620c2c66affSColin Finck }
1621c2c66affSColin Finck
revoke_class_object_thread(LPVOID pv)1622c2c66affSColin Finck static DWORD CALLBACK revoke_class_object_thread(LPVOID pv)
1623c2c66affSColin Finck {
1624c2c66affSColin Finck DWORD cookie = (DWORD_PTR)pv;
1625c2c66affSColin Finck HRESULT hr;
1626c2c66affSColin Finck
1627c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1628c2c66affSColin Finck
1629c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1630c2c66affSColin Finck
1631c2c66affSColin Finck CoUninitialize();
1632c2c66affSColin Finck
1633c2c66affSColin Finck return hr;
1634c2c66affSColin Finck }
1635c2c66affSColin Finck
test_registered_object_thread_affinity(void)1636c2c66affSColin Finck static void test_registered_object_thread_affinity(void)
1637c2c66affSColin Finck {
1638c2c66affSColin Finck HRESULT hr;
1639c2c66affSColin Finck DWORD cookie;
1640c2c66affSColin Finck HANDLE thread;
1641c2c66affSColin Finck DWORD tid;
1642c2c66affSColin Finck DWORD exitcode;
1643c2c66affSColin Finck
1644c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1645c2c66affSColin Finck
1646c2c66affSColin Finck /* CLSCTX_INPROC_SERVER */
1647c2c66affSColin Finck
1648c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1649c2c66affSColin Finck CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1650c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1651c2c66affSColin Finck
1652c2c66affSColin Finck thread = CreateThread(NULL, 0, get_class_object_thread, (LPVOID)CLSCTX_INPROC_SERVER, 0, &tid);
1653c2c66affSColin Finck ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1654c2c66affSColin Finck ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1655c2c66affSColin Finck GetExitCodeThread(thread, &exitcode);
1656c2c66affSColin Finck hr = exitcode;
1657c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "CoGetClassObject on inproc object "
1658c2c66affSColin Finck "registered in different thread should return REGDB_E_CLASSNOTREG "
1659c2c66affSColin Finck "instead of 0x%08x\n", hr);
1660c2c66affSColin Finck
1661c2c66affSColin Finck hr = get_class_object(CLSCTX_INPROC_SERVER);
1662c2c66affSColin Finck ok(hr == S_OK, "CoGetClassObject on inproc object registered in same "
1663c2c66affSColin Finck "thread should return S_OK instead of 0x%08x\n", hr);
1664c2c66affSColin Finck
1665c2c66affSColin Finck thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid);
1666c2c66affSColin Finck ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1667c2c66affSColin Finck ok ( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1668c2c66affSColin Finck GetExitCodeThread(thread, &exitcode);
1669c2c66affSColin Finck hr = exitcode;
1670c2c66affSColin Finck ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different thread should return S_OK instead of 0x%08x\n", hr);
1671c2c66affSColin Finck
1672c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1673c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1674c2c66affSColin Finck
1675c2c66affSColin Finck /* CLSCTX_LOCAL_SERVER */
1676c2c66affSColin Finck
1677c2c66affSColin Finck hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1678c2c66affSColin Finck CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1679c2c66affSColin Finck ok_ole_success(hr, "CoRegisterClassObject");
1680c2c66affSColin Finck
1681c2c66affSColin Finck thread = CreateThread(NULL, 0, get_class_object_proxy_thread, (LPVOID)CLSCTX_LOCAL_SERVER, 0, &tid);
1682c2c66affSColin Finck ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1683c2c66affSColin Finck while (MsgWaitForMultipleObjects(1, &thread, FALSE, 10000, QS_ALLINPUT) == WAIT_OBJECT_0 + 1)
1684c2c66affSColin Finck {
1685c2c66affSColin Finck MSG msg;
1686c2c66affSColin Finck while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
1687c2c66affSColin Finck {
1688c2c66affSColin Finck TranslateMessage(&msg);
1689c2c66affSColin Finck DispatchMessageA(&msg);
1690c2c66affSColin Finck }
1691c2c66affSColin Finck }
1692c2c66affSColin Finck GetExitCodeThread(thread, &exitcode);
1693c2c66affSColin Finck hr = exitcode;
1694c2c66affSColin Finck ok(hr == S_OK, "CoGetClassObject on local server object "
1695c2c66affSColin Finck "registered in different thread should return S_OK "
1696c2c66affSColin Finck "instead of 0x%08x\n", hr);
1697c2c66affSColin Finck
1698c2c66affSColin Finck hr = get_class_object(CLSCTX_LOCAL_SERVER);
1699c2c66affSColin Finck ok(hr == S_OK, "CoGetClassObject on local server object registered in same "
1700c2c66affSColin Finck "thread should return S_OK instead of 0x%08x\n", hr);
1701c2c66affSColin Finck
1702c2c66affSColin Finck thread = CreateThread(NULL, 0, revoke_class_object_thread, (LPVOID)(DWORD_PTR)cookie, 0, &tid);
1703c2c66affSColin Finck ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1704c2c66affSColin Finck ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1705c2c66affSColin Finck GetExitCodeThread(thread, &exitcode);
1706c2c66affSColin Finck hr = exitcode;
1707c2c66affSColin Finck ok(hr == RPC_E_WRONG_THREAD || broken(hr == S_OK) /* win8 */, "CoRevokeClassObject called from different "
1708c2c66affSColin Finck "thread to where registered should return RPC_E_WRONG_THREAD instead of 0x%08x\n", hr);
1709c2c66affSColin Finck
1710c2c66affSColin Finck thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid);
1711c2c66affSColin Finck ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1712c2c66affSColin Finck ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1713c2c66affSColin Finck GetExitCodeThread(thread, &exitcode);
1714c2c66affSColin Finck hr = exitcode;
1715c2c66affSColin Finck ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different "
1716c2c66affSColin Finck "thread should return S_OK instead of 0x%08x\n", hr);
1717c2c66affSColin Finck
1718c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
1719c2c66affSColin Finck ok_ole_success(hr, "CoRevokeClassObject");
1720c2c66affSColin Finck
1721c2c66affSColin Finck CoUninitialize();
1722c2c66affSColin Finck }
1723c2c66affSColin Finck
free_libraries_thread(LPVOID p)1724c2c66affSColin Finck static DWORD CALLBACK free_libraries_thread(LPVOID p)
1725c2c66affSColin Finck {
1726c2c66affSColin Finck CoFreeUnusedLibraries();
1727c2c66affSColin Finck return 0;
1728c2c66affSColin Finck }
1729c2c66affSColin Finck
is_module_loaded(const char * module)1730c2c66affSColin Finck static inline BOOL is_module_loaded(const char *module)
1731c2c66affSColin Finck {
1732c2c66affSColin Finck return GetModuleHandleA(module) != 0;
1733c2c66affSColin Finck }
1734c2c66affSColin Finck
test_CoFreeUnusedLibraries(void)1735c2c66affSColin Finck static void test_CoFreeUnusedLibraries(void)
1736c2c66affSColin Finck {
1737c2c66affSColin Finck HRESULT hr;
1738c2c66affSColin Finck IUnknown *pUnk;
1739c2c66affSColin Finck DWORD tid;
1740c2c66affSColin Finck HANDLE thread;
1741c2c66affSColin Finck
1742c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1743c2c66affSColin Finck
1744c2c66affSColin Finck ok(!is_module_loaded("urlmon.dll"), "urlmon.dll shouldn't be loaded\n");
1745c2c66affSColin Finck
1746c2c66affSColin Finck hr = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pUnk);
1747c2c66affSColin Finck if (hr == REGDB_E_CLASSNOTREG)
1748c2c66affSColin Finck {
1749c2c66affSColin Finck skip("IE not installed so can't run CoFreeUnusedLibraries test\n");
1750c2c66affSColin Finck CoUninitialize();
1751c2c66affSColin Finck return;
1752c2c66affSColin Finck }
1753c2c66affSColin Finck ok_ole_success(hr, "CoCreateInstance");
1754c2c66affSColin Finck
1755c2c66affSColin Finck ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1756c2c66affSColin Finck
1757c2c66affSColin Finck ok(pUnk != NULL ||
1758c2c66affSColin Finck broken(pUnk == NULL), /* win9x */
1759c2c66affSColin Finck "Expected a valid pointer\n");
1760c2c66affSColin Finck if (pUnk)
1761c2c66affSColin Finck IUnknown_Release(pUnk);
1762c2c66affSColin Finck
1763c2c66affSColin Finck ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1764c2c66affSColin Finck
1765c2c66affSColin Finck thread = CreateThread(NULL, 0, free_libraries_thread, NULL, 0, &tid);
1766c2c66affSColin Finck ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1767c2c66affSColin Finck CloseHandle(thread);
1768c2c66affSColin Finck
1769c2c66affSColin Finck ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1770c2c66affSColin Finck
1771c2c66affSColin Finck CoFreeUnusedLibraries();
1772c2c66affSColin Finck
1773c2c66affSColin Finck ok(!is_module_loaded("urlmon.dll"), "urlmon.dll shouldn't be loaded\n");
1774c2c66affSColin Finck
1775c2c66affSColin Finck CoUninitialize();
1776c2c66affSColin Finck }
1777c2c66affSColin Finck
test_CoGetObjectContext(void)1778c2c66affSColin Finck static void test_CoGetObjectContext(void)
1779c2c66affSColin Finck {
1780c2c66affSColin Finck HRESULT hr;
1781c2c66affSColin Finck ULONG refs;
1782c2c66affSColin Finck IComThreadingInfo *pComThreadingInfo, *threadinginfo2;
1783c2c66affSColin Finck IContextCallback *pContextCallback;
1784c2c66affSColin Finck IObjContext *pObjContext;
1785c2c66affSColin Finck APTTYPE apttype;
1786c2c66affSColin Finck THDTYPE thdtype;
1787c2c66affSColin Finck GUID id, id2;
1788c2c66affSColin Finck
1789c2c66affSColin Finck if (!pCoGetObjectContext)
1790c2c66affSColin Finck {
1791c2c66affSColin Finck win_skip("CoGetObjectContext not present\n");
1792c2c66affSColin Finck return;
1793c2c66affSColin Finck }
1794c2c66affSColin Finck
1795c2c66affSColin Finck hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1796c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoGetObjectContext should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1797c2c66affSColin Finck ok(pComThreadingInfo == NULL, "pComThreadingInfo should have been set to NULL\n");
1798c2c66affSColin Finck
1799a6cdf4ffSAmine Khaldi pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1800c2c66affSColin Finck
1801a6cdf4ffSAmine Khaldi test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE);
1802c2c66affSColin Finck
1803c2c66affSColin Finck hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1804a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoGetObjectContext");
1805c2c66affSColin Finck
1806c2c66affSColin Finck threadinginfo2 = NULL;
1807c2c66affSColin Finck hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&threadinginfo2);
1808c2c66affSColin Finck ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
1809c2c66affSColin Finck ok(pComThreadingInfo == threadinginfo2, "got different instance\n");
1810c2c66affSColin Finck IComThreadingInfo_Release(threadinginfo2);
1811c2c66affSColin Finck
1812c2c66affSColin Finck hr = IComThreadingInfo_GetCurrentLogicalThreadId(pComThreadingInfo, NULL);
1813c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1814c2c66affSColin Finck
1815c2c66affSColin Finck id = id2 = GUID_NULL;
1816c2c66affSColin Finck hr = IComThreadingInfo_GetCurrentLogicalThreadId(pComThreadingInfo, &id);
1817c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
1818c2c66affSColin Finck
1819c2c66affSColin Finck hr = CoGetCurrentLogicalThreadId(&id2);
1820c2c66affSColin Finck ok(IsEqualGUID(&id, &id2), "got %s, expected %s\n", wine_dbgstr_guid(&id), wine_dbgstr_guid(&id2));
1821c2c66affSColin Finck
1822c2c66affSColin Finck hr = IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo, &apttype);
1823c2c66affSColin Finck ok_ole_success(hr, "IComThreadingInfo_GetCurrentApartmentType");
1824c2c66affSColin Finck ok(apttype == APTTYPE_MAINSTA, "apartment type should be APTTYPE_MAINSTA instead of %d\n", apttype);
1825c2c66affSColin Finck
1826c2c66affSColin Finck hr = IComThreadingInfo_GetCurrentThreadType(pComThreadingInfo, &thdtype);
1827c2c66affSColin Finck ok_ole_success(hr, "IComThreadingInfo_GetCurrentThreadType");
1828c2c66affSColin Finck ok(thdtype == THDTYPE_PROCESSMESSAGES, "thread type should be THDTYPE_PROCESSMESSAGES instead of %d\n", thdtype);
1829c2c66affSColin Finck
1830c2c66affSColin Finck refs = IComThreadingInfo_Release(pComThreadingInfo);
1831c2c66affSColin Finck ok(refs == 0, "pComThreadingInfo should have 0 refs instead of %d refs\n", refs);
1832c2c66affSColin Finck
1833c2c66affSColin Finck hr = pCoGetObjectContext(&IID_IContextCallback, (void **)&pContextCallback);
1834c2c66affSColin Finck ok_ole_success(hr, "CoGetObjectContext(ContextCallback)");
1835c2c66affSColin Finck
1836c2c66affSColin Finck refs = IContextCallback_Release(pContextCallback);
1837c2c66affSColin Finck ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs);
1838c2c66affSColin Finck
1839c2c66affSColin Finck CoUninitialize();
1840c2c66affSColin Finck
1841c2c66affSColin Finck pCoInitializeEx(NULL, COINIT_MULTITHREADED);
1842c2c66affSColin Finck
1843c2c66affSColin Finck hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1844c2c66affSColin Finck ok_ole_success(hr, "CoGetObjectContext");
1845c2c66affSColin Finck
1846c2c66affSColin Finck hr = IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo, &apttype);
1847c2c66affSColin Finck ok_ole_success(hr, "IComThreadingInfo_GetCurrentApartmentType");
1848c2c66affSColin Finck ok(apttype == APTTYPE_MTA, "apartment type should be APTTYPE_MTA instead of %d\n", apttype);
1849c2c66affSColin Finck
1850c2c66affSColin Finck hr = IComThreadingInfo_GetCurrentThreadType(pComThreadingInfo, &thdtype);
1851c2c66affSColin Finck ok_ole_success(hr, "IComThreadingInfo_GetCurrentThreadType");
1852c2c66affSColin Finck ok(thdtype == THDTYPE_BLOCKMESSAGES, "thread type should be THDTYPE_BLOCKMESSAGES instead of %d\n", thdtype);
1853c2c66affSColin Finck
1854c2c66affSColin Finck refs = IComThreadingInfo_Release(pComThreadingInfo);
1855c2c66affSColin Finck ok(refs == 0, "pComThreadingInfo should have 0 refs instead of %d refs\n", refs);
1856c2c66affSColin Finck
1857c2c66affSColin Finck hr = pCoGetObjectContext(&IID_IContextCallback, (void **)&pContextCallback);
1858c2c66affSColin Finck ok_ole_success(hr, "CoGetObjectContext(ContextCallback)");
1859c2c66affSColin Finck
1860c2c66affSColin Finck refs = IContextCallback_Release(pContextCallback);
1861c2c66affSColin Finck ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs);
1862c2c66affSColin Finck
1863c2c66affSColin Finck hr = pCoGetObjectContext(&IID_IObjContext, (void **)&pObjContext);
1864c2c66affSColin Finck ok_ole_success(hr, "CoGetObjectContext");
1865c2c66affSColin Finck
1866c2c66affSColin Finck refs = IObjContext_Release(pObjContext);
1867c2c66affSColin Finck ok(refs == 0, "pObjContext should have 0 refs instead of %d refs\n", refs);
1868c2c66affSColin Finck
1869c2c66affSColin Finck CoUninitialize();
1870c2c66affSColin Finck }
1871c2c66affSColin Finck
1872c2c66affSColin Finck typedef struct {
1873c2c66affSColin Finck IUnknown IUnknown_iface;
1874c2c66affSColin Finck LONG refs;
1875c2c66affSColin Finck } Test_CallContext;
1876c2c66affSColin Finck
impl_from_IUnknown(IUnknown * iface)1877c2c66affSColin Finck static inline Test_CallContext *impl_from_IUnknown(IUnknown *iface)
1878c2c66affSColin Finck {
1879c2c66affSColin Finck return CONTAINING_RECORD(iface, Test_CallContext, IUnknown_iface);
1880c2c66affSColin Finck }
1881c2c66affSColin Finck
Test_CallContext_QueryInterface(IUnknown * iface,REFIID riid,LPVOID * ppvObj)1882c2c66affSColin Finck static HRESULT WINAPI Test_CallContext_QueryInterface(
1883c2c66affSColin Finck IUnknown *iface,
1884c2c66affSColin Finck REFIID riid,
1885c2c66affSColin Finck LPVOID *ppvObj)
1886c2c66affSColin Finck {
1887c2c66affSColin Finck if (ppvObj == NULL) return E_POINTER;
1888c2c66affSColin Finck
1889c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown))
1890c2c66affSColin Finck {
1891c2c66affSColin Finck *ppvObj = iface;
1892c2c66affSColin Finck IUnknown_AddRef(iface);
1893c2c66affSColin Finck return S_OK;
1894c2c66affSColin Finck }
1895c2c66affSColin Finck
1896c2c66affSColin Finck *ppvObj = NULL;
1897c2c66affSColin Finck return E_NOINTERFACE;
1898c2c66affSColin Finck }
1899c2c66affSColin Finck
Test_CallContext_AddRef(IUnknown * iface)1900c2c66affSColin Finck static ULONG WINAPI Test_CallContext_AddRef(IUnknown *iface)
1901c2c66affSColin Finck {
1902c2c66affSColin Finck Test_CallContext *This = impl_from_IUnknown(iface);
1903c2c66affSColin Finck return InterlockedIncrement(&This->refs);
1904c2c66affSColin Finck }
1905c2c66affSColin Finck
Test_CallContext_Release(IUnknown * iface)1906c2c66affSColin Finck static ULONG WINAPI Test_CallContext_Release(IUnknown *iface)
1907c2c66affSColin Finck {
1908c2c66affSColin Finck Test_CallContext *This = impl_from_IUnknown(iface);
1909c2c66affSColin Finck ULONG refs = InterlockedDecrement(&This->refs);
1910c2c66affSColin Finck if (!refs)
1911c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This);
1912c2c66affSColin Finck return refs;
1913c2c66affSColin Finck }
1914c2c66affSColin Finck
1915c2c66affSColin Finck static const IUnknownVtbl TestCallContext_Vtbl =
1916c2c66affSColin Finck {
1917c2c66affSColin Finck Test_CallContext_QueryInterface,
1918c2c66affSColin Finck Test_CallContext_AddRef,
1919c2c66affSColin Finck Test_CallContext_Release
1920c2c66affSColin Finck };
1921c2c66affSColin Finck
test_CoGetCallContext(void)1922c2c66affSColin Finck static void test_CoGetCallContext(void)
1923c2c66affSColin Finck {
1924c2c66affSColin Finck HRESULT hr;
1925c2c66affSColin Finck ULONG refs;
1926c2c66affSColin Finck IUnknown *pUnk;
1927c2c66affSColin Finck Test_CallContext *test_object;
1928c2c66affSColin Finck
1929c2c66affSColin Finck if (!pCoSwitchCallContext)
1930c2c66affSColin Finck {
1931c2c66affSColin Finck skip("CoSwitchCallContext not present\n");
1932c2c66affSColin Finck return;
1933c2c66affSColin Finck }
1934c2c66affSColin Finck
1935c2c66affSColin Finck CoInitialize(NULL);
1936c2c66affSColin Finck
1937c2c66affSColin Finck test_object = HeapAlloc(GetProcessHeap(), 0, sizeof(Test_CallContext));
1938c2c66affSColin Finck test_object->IUnknown_iface.lpVtbl = &TestCallContext_Vtbl;
1939c2c66affSColin Finck test_object->refs = 1;
1940c2c66affSColin Finck
1941c2c66affSColin Finck hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1942c2c66affSColin Finck ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr);
1943c2c66affSColin Finck
1944c2c66affSColin Finck pUnk = (IUnknown*)0xdeadbeef;
1945c2c66affSColin Finck hr = pCoSwitchCallContext(&test_object->IUnknown_iface, &pUnk);
1946c2c66affSColin Finck ok_ole_success(hr, "CoSwitchCallContext");
1947c2c66affSColin Finck ok(pUnk == NULL, "expected NULL, got %p\n", pUnk);
1948c2c66affSColin Finck refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1949c2c66affSColin Finck ok(refs == 2, "Expected refcount 2, got %d\n", refs);
1950c2c66affSColin Finck IUnknown_Release(&test_object->IUnknown_iface);
1951c2c66affSColin Finck
1952c2c66affSColin Finck pUnk = (IUnknown*)0xdeadbeef;
1953c2c66affSColin Finck hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1954c2c66affSColin Finck ok_ole_success(hr, "CoGetCallContext");
1955c2c66affSColin Finck ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n",
1956c2c66affSColin Finck &test_object->IUnknown_iface, pUnk);
1957c2c66affSColin Finck refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1958c2c66affSColin Finck ok(refs == 3, "Expected refcount 3, got %d\n", refs);
1959c2c66affSColin Finck IUnknown_Release(&test_object->IUnknown_iface);
1960c2c66affSColin Finck IUnknown_Release(pUnk);
1961c2c66affSColin Finck
1962c2c66affSColin Finck pUnk = (IUnknown*)0xdeadbeef;
1963c2c66affSColin Finck hr = pCoSwitchCallContext(NULL, &pUnk);
1964c2c66affSColin Finck ok_ole_success(hr, "CoSwitchCallContext");
1965c2c66affSColin Finck ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n",
1966c2c66affSColin Finck &test_object->IUnknown_iface, pUnk);
1967c2c66affSColin Finck refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1968c2c66affSColin Finck ok(refs == 2, "Expected refcount 2, got %d\n", refs);
1969c2c66affSColin Finck IUnknown_Release(&test_object->IUnknown_iface);
1970c2c66affSColin Finck
1971c2c66affSColin Finck hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1972c2c66affSColin Finck ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr);
1973c2c66affSColin Finck
1974c2c66affSColin Finck IUnknown_Release(&test_object->IUnknown_iface);
1975c2c66affSColin Finck
1976c2c66affSColin Finck CoUninitialize();
1977c2c66affSColin Finck }
1978c2c66affSColin Finck
test_CoGetContextToken(void)1979c2c66affSColin Finck static void test_CoGetContextToken(void)
1980c2c66affSColin Finck {
1981c2c66affSColin Finck HRESULT hr;
1982c2c66affSColin Finck ULONG refs;
1983c2c66affSColin Finck ULONG_PTR token, token2;
1984c2c66affSColin Finck IObjContext *ctx;
1985c2c66affSColin Finck
1986c2c66affSColin Finck if (!pCoGetContextToken)
1987c2c66affSColin Finck {
1988c2c66affSColin Finck win_skip("CoGetContextToken not present\n");
1989c2c66affSColin Finck return;
1990c2c66affSColin Finck }
1991c2c66affSColin Finck
1992c2c66affSColin Finck token = 0xdeadbeef;
1993c2c66affSColin Finck hr = pCoGetContextToken(&token);
1994c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr);
1995c2c66affSColin Finck ok(token == 0xdeadbeef, "Expected 0, got 0x%lx\n", token);
1996c2c66affSColin Finck
1997a6cdf4ffSAmine Khaldi test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE);
1998c2c66affSColin Finck
1999c2c66affSColin Finck CoInitialize(NULL);
2000c2c66affSColin Finck
2001a6cdf4ffSAmine Khaldi test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE);
2002c2c66affSColin Finck
2003c2c66affSColin Finck hr = pCoGetContextToken(NULL);
2004c2c66affSColin Finck ok(hr == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hr);
2005c2c66affSColin Finck
2006c2c66affSColin Finck token = 0;
2007c2c66affSColin Finck hr = pCoGetContextToken(&token);
2008c2c66affSColin Finck ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
2009c2c66affSColin Finck ok(token, "Expected token != 0\n");
2010c2c66affSColin Finck
2011c2c66affSColin Finck token2 = 0;
2012c2c66affSColin Finck hr = pCoGetContextToken(&token2);
2013c2c66affSColin Finck ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
2014c2c66affSColin Finck ok(token2 == token, "got different token\n");
2015c2c66affSColin Finck
2016c2c66affSColin Finck refs = IUnknown_AddRef((IUnknown *)token);
2017c2c66affSColin Finck ok(refs == 1, "Expected 1, got %u\n", refs);
2018c2c66affSColin Finck
2019c2c66affSColin Finck hr = pCoGetObjectContext(&IID_IObjContext, (void **)&ctx);
2020c2c66affSColin Finck ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
2021c2c66affSColin Finck ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n");
2022c2c66affSColin Finck
2023c2c66affSColin Finck refs = IObjContext_AddRef(ctx);
2024c2c66affSColin Finck ok(refs == 3, "Expected 3, got %u\n", refs);
2025c2c66affSColin Finck
2026c2c66affSColin Finck refs = IObjContext_Release(ctx);
2027c2c66affSColin Finck ok(refs == 2, "Expected 2, got %u\n", refs);
2028c2c66affSColin Finck
2029c2c66affSColin Finck refs = IUnknown_Release((IUnknown *)token);
2030c2c66affSColin Finck ok(refs == 1, "Expected 1, got %u\n", refs);
2031c2c66affSColin Finck
2032c2c66affSColin Finck /* CoGetContextToken does not add a reference */
2033c2c66affSColin Finck token = 0;
2034c2c66affSColin Finck hr = pCoGetContextToken(&token);
2035c2c66affSColin Finck ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
2036c2c66affSColin Finck ok(token, "Expected token != 0\n");
2037c2c66affSColin Finck ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n");
2038c2c66affSColin Finck
2039c2c66affSColin Finck refs = IObjContext_AddRef(ctx);
2040c2c66affSColin Finck ok(refs == 2, "Expected 1, got %u\n", refs);
2041c2c66affSColin Finck
2042c2c66affSColin Finck refs = IObjContext_Release(ctx);
2043c2c66affSColin Finck ok(refs == 1, "Expected 0, got %u\n", refs);
2044c2c66affSColin Finck
2045c2c66affSColin Finck refs = IObjContext_Release(ctx);
2046c2c66affSColin Finck ok(refs == 0, "Expected 0, got %u\n", refs);
2047c2c66affSColin Finck
2048c2c66affSColin Finck CoUninitialize();
2049c2c66affSColin Finck }
2050c2c66affSColin Finck
test_TreatAsClass(void)2051c2c66affSColin Finck static void test_TreatAsClass(void)
2052c2c66affSColin Finck {
2053c2c66affSColin Finck HRESULT hr;
2054c2c66affSColin Finck CLSID out;
2055c2c66affSColin Finck static GUID deadbeef = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
2056c2c66affSColin Finck static const char deadbeefA[] = "{DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF}";
2057c2c66affSColin Finck IInternetProtocol *pIP = NULL;
2058c2c66affSColin Finck HKEY clsidkey, deadbeefkey;
2059c2c66affSColin Finck LONG lr;
2060c2c66affSColin Finck
2061c2c66affSColin Finck if (!pCoGetTreatAsClass)
2062c2c66affSColin Finck {
2063c2c66affSColin Finck win_skip("CoGetTreatAsClass not present\n");
2064c2c66affSColin Finck return;
2065c2c66affSColin Finck }
2066c2c66affSColin Finck
2067c2c66affSColin Finck hr = pCoGetTreatAsClass(&deadbeef,&out);
2068c2c66affSColin Finck ok (hr == S_FALSE, "expected S_FALSE got %x\n",hr);
2069c2c66affSColin Finck ok (IsEqualGUID(&out,&deadbeef), "expected to get same clsid back\n");
2070c2c66affSColin Finck
2071c2c66affSColin Finck hr = pCoGetTreatAsClass(NULL, &out);
2072c2c66affSColin Finck ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr);
2073c2c66affSColin Finck ok(IsEqualGUID(&out, &deadbeef), "expected no change to the clsid\n");
2074c2c66affSColin Finck
2075c2c66affSColin Finck hr = pCoGetTreatAsClass(&deadbeef, NULL);
2076c2c66affSColin Finck ok(hr == E_INVALIDARG, "expected E_INVALIDARG got %08x\n", hr);
2077c2c66affSColin Finck
2078c2c66affSColin Finck lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &clsidkey);
2079c2c66affSColin Finck ok(!lr, "Couldn't open CLSID key, error %d\n", lr);
2080c2c66affSColin Finck
2081c2c66affSColin Finck lr = RegCreateKeyExA(clsidkey, deadbeefA, 0, NULL, 0, KEY_WRITE, NULL, &deadbeefkey, NULL);
2082c2c66affSColin Finck if (lr) {
2083c2c66affSColin Finck win_skip("CoGetTreatAsClass() tests will be skipped (failed to create a test key, error %d)\n", lr);
2084c2c66affSColin Finck RegCloseKey(clsidkey);
2085c2c66affSColin Finck return;
2086c2c66affSColin Finck }
2087c2c66affSColin Finck
2088c2c66affSColin Finck hr = pCoTreatAsClass(&deadbeef, &deadbeef);
2089c2c66affSColin Finck ok(hr == REGDB_E_WRITEREGDB, "CoTreatAsClass gave wrong error: %08x\n", hr);
2090c2c66affSColin Finck
2091c2c66affSColin Finck hr = pCoTreatAsClass(&deadbeef, &CLSID_FileProtocol);
2092c2c66affSColin Finck if(hr == REGDB_E_WRITEREGDB){
2093c2c66affSColin Finck win_skip("Insufficient privileges to use CoTreatAsClass\n");
2094c2c66affSColin Finck goto exit;
2095c2c66affSColin Finck }
2096c2c66affSColin Finck ok(hr == S_OK, "CoTreatAsClass failed: %08x\n", hr);
2097c2c66affSColin Finck
2098c2c66affSColin Finck hr = pCoGetTreatAsClass(&deadbeef, &out);
2099c2c66affSColin Finck ok(hr == S_OK, "CoGetTreatAsClass failed: %08x\n",hr);
2100c2c66affSColin Finck ok(IsEqualGUID(&out, &CLSID_FileProtocol), "expected to get substituted clsid\n");
2101c2c66affSColin Finck
2102c2c66affSColin Finck OleInitialize(NULL);
2103c2c66affSColin Finck
2104c2c66affSColin Finck hr = CoCreateInstance(&deadbeef, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pIP);
2105c2c66affSColin Finck if(hr == REGDB_E_CLASSNOTREG)
2106c2c66affSColin Finck {
2107c2c66affSColin Finck win_skip("IE not installed so can't test CoCreateInstance\n");
2108c2c66affSColin Finck goto exit;
2109c2c66affSColin Finck }
2110c2c66affSColin Finck
2111c2c66affSColin Finck ok(hr == S_OK, "CoCreateInstance failed: %08x\n", hr);
2112c2c66affSColin Finck if(pIP){
2113c2c66affSColin Finck IInternetProtocol_Release(pIP);
2114c2c66affSColin Finck pIP = NULL;
2115c2c66affSColin Finck }
2116c2c66affSColin Finck
2117c2c66affSColin Finck hr = pCoTreatAsClass(&deadbeef, &CLSID_NULL);
2118c2c66affSColin Finck ok(hr == S_OK, "CoTreatAsClass failed: %08x\n", hr);
2119c2c66affSColin Finck
2120c2c66affSColin Finck hr = pCoGetTreatAsClass(&deadbeef, &out);
2121c2c66affSColin Finck ok(hr == S_FALSE, "expected S_FALSE got %08x\n", hr);
2122c2c66affSColin Finck ok(IsEqualGUID(&out, &deadbeef), "expected to get same clsid back\n");
2123c2c66affSColin Finck
2124c2c66affSColin Finck /* bizarrely, native's CoTreatAsClass takes some time to take effect in CoCreateInstance */
2125c2c66affSColin Finck Sleep(200);
2126c2c66affSColin Finck
2127c2c66affSColin Finck hr = CoCreateInstance(&deadbeef, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pIP);
2128c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance gave wrong error: %08x\n", hr);
2129c2c66affSColin Finck
2130c2c66affSColin Finck if(pIP)
2131c2c66affSColin Finck IInternetProtocol_Release(pIP);
2132c2c66affSColin Finck
2133c2c66affSColin Finck exit:
2134c2c66affSColin Finck OleUninitialize();
2135c2c66affSColin Finck RegCloseKey(deadbeefkey);
2136c2c66affSColin Finck RegDeleteKeyA(clsidkey, deadbeefA);
2137c2c66affSColin Finck RegCloseKey(clsidkey);
2138c2c66affSColin Finck }
2139c2c66affSColin Finck
test_CoInitializeEx(void)2140c2c66affSColin Finck static void test_CoInitializeEx(void)
2141c2c66affSColin Finck {
2142c2c66affSColin Finck HRESULT hr;
2143c2c66affSColin Finck
2144c2c66affSColin Finck hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2145c2c66affSColin Finck ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
2146c2c66affSColin Finck
2147c2c66affSColin Finck /* Calling OleInitialize for the first time should yield S_OK even with
2148c2c66affSColin Finck * apartment already initialized by previous CoInitialize(Ex) calls. */
2149c2c66affSColin Finck hr = OleInitialize(NULL);
2150c2c66affSColin Finck ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
2151c2c66affSColin Finck
2152c2c66affSColin Finck /* Subsequent calls to OleInitialize should return S_FALSE */
2153c2c66affSColin Finck hr = OleInitialize(NULL);
2154c2c66affSColin Finck ok(hr == S_FALSE, "Expected S_FALSE, hr = 0x%08x\n", hr);
2155c2c66affSColin Finck
2156c2c66affSColin Finck /* Cleanup */
2157c2c66affSColin Finck CoUninitialize();
2158c2c66affSColin Finck OleUninitialize();
2159c2c66affSColin Finck OleUninitialize();
2160c2c66affSColin Finck }
2161c2c66affSColin Finck
test_OleInitialize_InitCounting(void)2162c2c66affSColin Finck static void test_OleInitialize_InitCounting(void)
2163c2c66affSColin Finck {
2164c2c66affSColin Finck HRESULT hr;
2165c2c66affSColin Finck IUnknown *pUnk;
2166c2c66affSColin Finck REFCLSID rclsid = &CLSID_InternetZoneManager;
2167c2c66affSColin Finck
2168c2c66affSColin Finck /* 1. OleInitialize fails but OleUninitialize is still called: apartment stays initialized */
2169c2c66affSColin Finck hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED);
2170c2c66affSColin Finck ok(hr == S_OK, "CoInitializeEx(COINIT_MULTITHREADED) failed with error 0x%08x\n", hr);
2171c2c66affSColin Finck
2172c2c66affSColin Finck hr = OleInitialize(NULL);
2173c2c66affSColin Finck ok(hr == RPC_E_CHANGED_MODE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", RPC_E_CHANGED_MODE, hr);
2174c2c66affSColin Finck OleUninitialize();
2175c2c66affSColin Finck
2176c2c66affSColin Finck pUnk = (IUnknown *)0xdeadbeef;
2177c2c66affSColin Finck hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
2178c2c66affSColin Finck ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
2179c2c66affSColin Finck if (pUnk) IUnknown_Release(pUnk);
2180c2c66affSColin Finck
2181c2c66affSColin Finck CoUninitialize();
2182c2c66affSColin Finck
2183c2c66affSColin Finck /* 2. Extra multiple OleUninitialize: apartment stays initialized until CoUninitialize */
2184c2c66affSColin Finck hr = CoInitialize(NULL);
2185c2c66affSColin Finck ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr);
2186c2c66affSColin Finck
2187c2c66affSColin Finck hr = OleInitialize(NULL);
2188c2c66affSColin Finck ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
2189c2c66affSColin Finck OleUninitialize();
2190c2c66affSColin Finck OleUninitialize();
2191c2c66affSColin Finck OleUninitialize();
2192c2c66affSColin Finck
2193c2c66affSColin Finck pUnk = (IUnknown *)0xdeadbeef;
2194c2c66affSColin Finck hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
2195c2c66affSColin Finck ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
2196c2c66affSColin Finck if (pUnk) IUnknown_Release(pUnk);
2197c2c66affSColin Finck
2198c2c66affSColin Finck CoUninitialize();
2199c2c66affSColin Finck
2200c2c66affSColin Finck pUnk = (IUnknown *)0xdeadbeef;
2201c2c66affSColin Finck hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
2202c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr);
2203c2c66affSColin Finck if (pUnk) IUnknown_Release(pUnk);
2204c2c66affSColin Finck
2205c2c66affSColin Finck /* 3. CoUninitialize does not formally deinit Ole */
2206c2c66affSColin Finck hr = CoInitialize(NULL);
2207c2c66affSColin Finck ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr);
2208c2c66affSColin Finck
2209c2c66affSColin Finck hr = OleInitialize(NULL);
2210c2c66affSColin Finck ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
2211c2c66affSColin Finck
2212c2c66affSColin Finck CoUninitialize();
2213c2c66affSColin Finck CoUninitialize();
2214c2c66affSColin Finck
2215c2c66affSColin Finck pUnk = (IUnknown *)0xdeadbeef;
2216c2c66affSColin Finck hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
2217c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr);
2218c2c66affSColin Finck /* COM is not initialized anymore */
2219c2c66affSColin Finck if (pUnk) IUnknown_Release(pUnk);
2220c2c66affSColin Finck
2221c2c66affSColin Finck hr = OleInitialize(NULL);
2222c2c66affSColin Finck ok(hr == S_FALSE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_FALSE, hr);
2223c2c66affSColin Finck /* ... but native OleInit returns S_FALSE as if Ole is considered initialized */
2224c2c66affSColin Finck
2225c2c66affSColin Finck OleUninitialize();
2226c2c66affSColin Finck
2227c2c66affSColin Finck }
2228c2c66affSColin Finck
test_OleRegGetMiscStatus(void)2229c2c66affSColin Finck static void test_OleRegGetMiscStatus(void)
2230c2c66affSColin Finck {
2231c2c66affSColin Finck ULONG_PTR cookie;
2232c2c66affSColin Finck HANDLE handle;
2233c2c66affSColin Finck DWORD status;
2234c2c66affSColin Finck HRESULT hr;
2235c2c66affSColin Finck
2236c2c66affSColin Finck hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, NULL);
2237c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2238c2c66affSColin Finck
2239c2c66affSColin Finck status = 0xdeadbeef;
2240c2c66affSColin Finck hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, &status);
2241c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
2242c2c66affSColin Finck ok(status == 0, "got 0x%08x\n", status);
2243c2c66affSColin Finck
2244c2c66affSColin Finck status = -1;
2245c2c66affSColin Finck hr = OleRegGetMiscStatus(&CLSID_StdFont, DVASPECT_ICON, &status);
2246c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2247c2c66affSColin Finck ok(status == 0, "got 0x%08x\n", status);
2248c2c66affSColin Finck
2249c2c66affSColin Finck if ((handle = activate_context(actctx_manifest, &cookie)))
2250c2c66affSColin Finck {
2251c2c66affSColin Finck status = 0;
2252c2c66affSColin Finck hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, &status);
2253c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2254c2c66affSColin Finck ok(status == OLEMISC_RECOMPOSEONRESIZE, "got 0x%08x\n", status);
2255c2c66affSColin Finck
2256c2c66affSColin Finck /* context data takes precedence over registration info */
2257c2c66affSColin Finck status = 0;
2258c2c66affSColin Finck hr = OleRegGetMiscStatus(&CLSID_StdFont, DVASPECT_ICON, &status);
2259c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2260c2c66affSColin Finck ok(status == OLEMISC_RECOMPOSEONRESIZE, "got 0x%08x\n", status);
2261c2c66affSColin Finck
2262c2c66affSColin Finck /* there's no such attribute in context */
2263c2c66affSColin Finck status = -1;
2264c2c66affSColin Finck hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_DOCPRINT, &status);
2265c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2266c2c66affSColin Finck ok(status == 0, "got 0x%08x\n", status);
2267c2c66affSColin Finck
2268c2c66affSColin Finck pDeactivateActCtx(0, cookie);
2269c2c66affSColin Finck pReleaseActCtx(handle);
2270c2c66affSColin Finck }
2271c2c66affSColin Finck }
2272c2c66affSColin Finck
test_OleRegGetUserType(void)2273c2c66affSColin Finck static void test_OleRegGetUserType(void)
2274c2c66affSColin Finck {
2275c2c66affSColin Finck static const WCHAR stdfont_usertypeW[] = {'S','t','a','n','d','a','r','d',' ','F','o','n','t',0};
2276c2c66affSColin Finck static const WCHAR stdfont2_usertypeW[] = {'C','L','S','I','D','_','S','t','d','F','o','n','t',0};
2277c2c66affSColin Finck static const WCHAR clsidkeyW[] = {'C','L','S','I','D',0};
2278c2c66affSColin Finck static const WCHAR defvalueW[] = {'D','e','f','a','u','l','t',' ','N','a','m','e',0};
2279c2c66affSColin Finck static const WCHAR auxvalue0W[] = {'A','u','x',' ','N','a','m','e',' ','0',0};
2280c2c66affSColin Finck static const WCHAR auxvalue2W[] = {'A','u','x',' ','N','a','m','e',' ','2',0};
2281c2c66affSColin Finck static const WCHAR auxvalue3W[] = {'A','u','x',' ','N','a','m','e',' ','3',0};
2282c2c66affSColin Finck static const WCHAR auxvalue4W[] = {'A','u','x',' ','N','a','m','e',' ','4',0};
2283c2c66affSColin Finck
2284c2c66affSColin Finck static const char auxvalues[][16] = {
2285c2c66affSColin Finck "Aux Name 0",
2286c2c66affSColin Finck "Aux Name 1",
2287c2c66affSColin Finck "Aux Name 2",
2288c2c66affSColin Finck "Aux Name 3",
2289c2c66affSColin Finck "Aux Name 4"
2290c2c66affSColin Finck };
2291c2c66affSColin Finck
2292c2c66affSColin Finck HKEY clsidhkey, hkey, auxhkey, classkey;
2293c2c66affSColin Finck DWORD form, ret, disposition;
2294c2c66affSColin Finck WCHAR clsidW[39];
2295c2c66affSColin Finck ULONG_PTR cookie;
2296c2c66affSColin Finck HANDLE handle;
2297c2c66affSColin Finck HRESULT hr;
2298c2c66affSColin Finck WCHAR *str;
2299c2c66affSColin Finck int i;
2300c2c66affSColin Finck
2301c2c66affSColin Finck for (form = 0; form <= USERCLASSTYPE_APPNAME+1; form++) {
2302c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_Testclass, form, NULL);
2303c2c66affSColin Finck ok(hr == E_INVALIDARG, "form %u: got 0x%08x\n", form, hr);
2304c2c66affSColin Finck
2305c2c66affSColin Finck str = (void*)0xdeadbeef;
2306c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_Testclass, form, &str);
2307c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "form %u: got 0x%08x\n", form, hr);
2308c2c66affSColin Finck ok(str == NULL, "form %u: got %p\n", form, str);
2309c2c66affSColin Finck
2310c2c66affSColin Finck /* same string returned for StdFont for all form types */
2311c2c66affSColin Finck str = NULL;
2312c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_StdFont, form, &str);
2313c2c66affSColin Finck ok(hr == S_OK, "form %u: got 0x%08x\n", form, hr);
2314c2c66affSColin Finck ok(!lstrcmpW(str, stdfont_usertypeW) || !lstrcmpW(str, stdfont2_usertypeW) /* winxp */,
2315c2c66affSColin Finck "form %u, got %s\n", form, wine_dbgstr_w(str));
2316c2c66affSColin Finck CoTaskMemFree(str);
2317c2c66affSColin Finck }
2318c2c66affSColin Finck
2319c2c66affSColin Finck if ((handle = activate_context(actctx_manifest, &cookie)))
2320c2c66affSColin Finck {
2321c2c66affSColin Finck for (form = 0; form <= USERCLASSTYPE_APPNAME+1; form++) {
2322c2c66affSColin Finck str = (void*)0xdeadbeef;
2323c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_Testclass, form, &str);
2324c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "form %u: got 0x%08x\n", form, hr);
2325c2c66affSColin Finck ok(str == NULL, "form %u: got %s\n", form, wine_dbgstr_w(str));
2326c2c66affSColin Finck
2327c2c66affSColin Finck /* same string returned for StdFont for all form types */
2328c2c66affSColin Finck str = NULL;
2329c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_StdFont, form, &str);
2330c2c66affSColin Finck ok(hr == S_OK, "form %u: got 0x%08x\n", form, hr);
2331c2c66affSColin Finck ok(!lstrcmpW(str, stdfont_usertypeW) || !lstrcmpW(str, stdfont2_usertypeW) /* winxp */,
2332c2c66affSColin Finck "form %u, got %s\n", form, wine_dbgstr_w(str));
2333c2c66affSColin Finck CoTaskMemFree(str);
2334c2c66affSColin Finck }
2335c2c66affSColin Finck
2336c2c66affSColin Finck pDeactivateActCtx(0, cookie);
2337c2c66affSColin Finck pReleaseActCtx(handle);
2338c2c66affSColin Finck }
2339c2c66affSColin Finck
2340c2c66affSColin Finck /* test using registered CLSID */
23415c1bcfecSAmine Khaldi StringFromGUID2(&CLSID_non_existent, clsidW, ARRAY_SIZE(clsidW));
2342c2c66affSColin Finck
2343c2c66affSColin Finck ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsidkeyW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &clsidhkey, &disposition);
2344c2c66affSColin Finck if (!ret)
2345c2c66affSColin Finck {
2346c2c66affSColin Finck ret = RegCreateKeyExW(clsidhkey, clsidW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &classkey, NULL);
2347c2c66affSColin Finck if (ret)
2348c2c66affSColin Finck RegCloseKey(clsidhkey);
2349c2c66affSColin Finck }
2350c2c66affSColin Finck
2351c2c66affSColin Finck if (ret == ERROR_ACCESS_DENIED)
2352c2c66affSColin Finck {
2353c2c66affSColin Finck win_skip("Failed to create test key, skipping some of OleRegGetUserType() tests.\n");
2354c2c66affSColin Finck return;
2355c2c66affSColin Finck }
2356c2c66affSColin Finck
2357c2c66affSColin Finck ok(!ret, "failed to create a key, error %d\n", ret);
2358c2c66affSColin Finck
2359c2c66affSColin Finck ret = RegSetValueExW(classkey, NULL, 0, REG_SZ, (const BYTE*)defvalueW, sizeof(defvalueW));
2360c2c66affSColin Finck ok(!ret, "got error %d\n", ret);
2361c2c66affSColin Finck
2362c2c66affSColin Finck ret = RegCreateKeyExA(classkey, "AuxUserType", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &auxhkey, NULL);
2363c2c66affSColin Finck ok(!ret, "got error %d\n", ret);
2364c2c66affSColin Finck
2365c2c66affSColin Finck /* populate AuxUserType */
2366c2c66affSColin Finck for (i = 0; i <= 4; i++) {
2367c2c66affSColin Finck char name[16];
2368c2c66affSColin Finck
2369c2c66affSColin Finck sprintf(name, "AuxUserType\\%d", i);
2370c2c66affSColin Finck ret = RegCreateKeyExA(classkey, name, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
2371c2c66affSColin Finck ok(!ret, "got error %d\n", ret);
2372c2c66affSColin Finck
2373c2c66affSColin Finck ret = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE*)auxvalues[i], strlen(auxvalues[i]));
2374c2c66affSColin Finck ok(!ret, "got error %d\n", ret);
2375c2c66affSColin Finck RegCloseKey(hkey);
2376c2c66affSColin Finck }
2377c2c66affSColin Finck
2378c2c66affSColin Finck str = NULL;
2379c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_non_existent, 0, &str);
2380c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2381c2c66affSColin Finck ok(!lstrcmpW(str, auxvalue0W), "got %s\n", wine_dbgstr_w(str));
2382c2c66affSColin Finck CoTaskMemFree(str);
2383c2c66affSColin Finck
2384c2c66affSColin Finck str = NULL;
2385c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_FULL, &str);
2386c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2387c2c66affSColin Finck ok(!lstrcmpW(str, defvalueW), "got %s\n", wine_dbgstr_w(str));
2388c2c66affSColin Finck CoTaskMemFree(str);
2389c2c66affSColin Finck
2390c2c66affSColin Finck str = NULL;
2391c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_SHORT, &str);
2392c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2393c2c66affSColin Finck ok(!lstrcmpW(str, auxvalue2W), "got %s\n", wine_dbgstr_w(str));
2394c2c66affSColin Finck CoTaskMemFree(str);
2395c2c66affSColin Finck
2396c2c66affSColin Finck str = NULL;
2397c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME, &str);
2398c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2399c2c66affSColin Finck ok(!lstrcmpW(str, auxvalue3W), "got %s\n", wine_dbgstr_w(str));
2400c2c66affSColin Finck CoTaskMemFree(str);
2401c2c66affSColin Finck
2402c2c66affSColin Finck str = NULL;
2403c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME+1, &str);
2404c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2405c2c66affSColin Finck ok(!lstrcmpW(str, auxvalue4W), "got %s\n", wine_dbgstr_w(str));
2406c2c66affSColin Finck CoTaskMemFree(str);
2407c2c66affSColin Finck
2408c2c66affSColin Finck str = NULL;
2409c2c66affSColin Finck hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME+2, &str);
2410c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
2411c2c66affSColin Finck ok(!lstrcmpW(str, defvalueW), "got %s\n", wine_dbgstr_w(str));
2412c2c66affSColin Finck CoTaskMemFree(str);
2413c2c66affSColin Finck
2414c2c66affSColin Finck /* registry cleanup */
2415c2c66affSColin Finck for (i = 0; i <= 4; i++)
2416c2c66affSColin Finck {
2417c2c66affSColin Finck char name[2];
2418c2c66affSColin Finck sprintf(name, "%d", i);
2419c2c66affSColin Finck RegDeleteKeyA(auxhkey, name);
2420c2c66affSColin Finck }
2421c2c66affSColin Finck RegCloseKey(auxhkey);
2422c2c66affSColin Finck RegDeleteKeyA(classkey, "AuxUserType");
2423c2c66affSColin Finck RegCloseKey(classkey);
2424c2c66affSColin Finck RegDeleteKeyW(clsidhkey, clsidW);
2425c2c66affSColin Finck RegCloseKey(clsidhkey);
2426c2c66affSColin Finck if (disposition == REG_CREATED_NEW_KEY)
2427c2c66affSColin Finck RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID");
2428c2c66affSColin Finck }
2429c2c66affSColin Finck
test_CoCreateGuid(void)2430c2c66affSColin Finck static void test_CoCreateGuid(void)
2431c2c66affSColin Finck {
2432c2c66affSColin Finck HRESULT hr;
2433c2c66affSColin Finck
2434c2c66affSColin Finck hr = CoCreateGuid(NULL);
2435c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2436c2c66affSColin Finck }
2437c2c66affSColin Finck
apc_test_proc(ULONG_PTR param)2438c2c66affSColin Finck static void CALLBACK apc_test_proc(ULONG_PTR param)
2439c2c66affSColin Finck {
2440c2c66affSColin Finck /* nothing */
2441c2c66affSColin Finck }
2442c2c66affSColin Finck
release_semaphore_thread(LPVOID arg)2443c2c66affSColin Finck static DWORD CALLBACK release_semaphore_thread( LPVOID arg )
2444c2c66affSColin Finck {
2445c2c66affSColin Finck HANDLE handle = arg;
2446c2c66affSColin Finck if (WaitForSingleObject(handle, 200) == WAIT_TIMEOUT)
2447c2c66affSColin Finck ReleaseSemaphore(handle, 1, NULL);
2448c2c66affSColin Finck return 0;
2449c2c66affSColin Finck }
2450c2c66affSColin Finck
send_message_thread(LPVOID arg)2451c2c66affSColin Finck static DWORD CALLBACK send_message_thread(LPVOID arg)
2452c2c66affSColin Finck {
2453c2c66affSColin Finck HWND hWnd = arg;
2454c2c66affSColin Finck Sleep(50);
2455c2c66affSColin Finck SendMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2456c2c66affSColin Finck return 0;
2457c2c66affSColin Finck }
2458c2c66affSColin Finck
send_and_post_user_message_thread(void * arg)245966f35ef8SAmine Khaldi static DWORD CALLBACK send_and_post_user_message_thread(void *arg)
246066f35ef8SAmine Khaldi {
246166f35ef8SAmine Khaldi HWND hwnd = arg;
246266f35ef8SAmine Khaldi Sleep(30);
246366f35ef8SAmine Khaldi SendMessageA(hwnd, WM_USER, 0, 0);
246466f35ef8SAmine Khaldi PostMessageA(hwnd, WM_USER, 0, 0);
246566f35ef8SAmine Khaldi return 0;
246666f35ef8SAmine Khaldi }
246766f35ef8SAmine Khaldi
post_message_thread(LPVOID arg)2468c2c66affSColin Finck static DWORD CALLBACK post_message_thread(LPVOID arg)
2469c2c66affSColin Finck {
2470c2c66affSColin Finck HWND hWnd = arg;
2471c2c66affSColin Finck Sleep(50);
2472c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2473c2c66affSColin Finck return 0;
2474c2c66affSColin Finck }
2475c2c66affSColin Finck
2476c2c66affSColin Finck static const char cls_name[] = "cowait_test_class";
247766f35ef8SAmine Khaldi
247866f35ef8SAmine Khaldi static UINT cowait_msgs[100], cowait_msgs_first, cowait_msgs_last;
247966f35ef8SAmine Khaldi
cowait_msgs_reset(void)248066f35ef8SAmine Khaldi static void cowait_msgs_reset(void)
248166f35ef8SAmine Khaldi {
248266f35ef8SAmine Khaldi cowait_msgs_first = cowait_msgs_last = 0;
248366f35ef8SAmine Khaldi }
248466f35ef8SAmine Khaldi
248566f35ef8SAmine Khaldi #define cowait_msgs_expect_empty() _cowait_msgs_expect_empty(__LINE__)
_cowait_msgs_expect_empty(unsigned line)248666f35ef8SAmine Khaldi static void _cowait_msgs_expect_empty(unsigned line)
248766f35ef8SAmine Khaldi {
248866f35ef8SAmine Khaldi while(cowait_msgs_first < cowait_msgs_last) {
248966f35ef8SAmine Khaldi ok_(__FILE__,line)(0, "unexpected message %u\n", cowait_msgs[cowait_msgs_first]);
249066f35ef8SAmine Khaldi cowait_msgs_first++;
249166f35ef8SAmine Khaldi }
249266f35ef8SAmine Khaldi cowait_msgs_reset();
249366f35ef8SAmine Khaldi }
249466f35ef8SAmine Khaldi
249566f35ef8SAmine Khaldi #define cowait_msgs_expect_notified(a) _cowait_msgs_expect_notified(__LINE__,a)
_cowait_msgs_expect_notified(unsigned line,UINT expected_msg)249666f35ef8SAmine Khaldi static void _cowait_msgs_expect_notified(unsigned line, UINT expected_msg)
249766f35ef8SAmine Khaldi {
249866f35ef8SAmine Khaldi if(cowait_msgs_first == cowait_msgs_last) {
249966f35ef8SAmine Khaldi ok_(__FILE__,line)(0, "expected message %u, received none\n", expected_msg);
250066f35ef8SAmine Khaldi }else {
250166f35ef8SAmine Khaldi ok_(__FILE__,line)(cowait_msgs[cowait_msgs_first] == expected_msg,
250266f35ef8SAmine Khaldi "expected message %u, received %u \n",
250366f35ef8SAmine Khaldi expected_msg, cowait_msgs[cowait_msgs_first]);
250466f35ef8SAmine Khaldi cowait_msgs_first++;
250566f35ef8SAmine Khaldi }
250666f35ef8SAmine Khaldi }
250766f35ef8SAmine Khaldi
250866f35ef8SAmine Khaldi #define cowait_msgs_expect_queued(a,b) _cowait_msgs_expect_queued(__LINE__,a,b)
_cowait_msgs_expect_queued(unsigned line,HWND hwnd,UINT expected_msg)250966f35ef8SAmine Khaldi static void _cowait_msgs_expect_queued(unsigned line, HWND hwnd, UINT expected_msg)
251066f35ef8SAmine Khaldi {
251166f35ef8SAmine Khaldi MSG msg;
251266f35ef8SAmine Khaldi BOOL success;
251366f35ef8SAmine Khaldi
251466f35ef8SAmine Khaldi success = PeekMessageA(&msg, hwnd, expected_msg, expected_msg, PM_REMOVE);
251566f35ef8SAmine Khaldi ok_(__FILE__,line)(success, "PeekMessageA failed: %u\n", GetLastError());
251666f35ef8SAmine Khaldi if(success)
251766f35ef8SAmine Khaldi ok_(__FILE__,line)(msg.message == expected_msg, "unexpected message %u, expected %u\n",
251866f35ef8SAmine Khaldi msg.message, expected_msg);
251966f35ef8SAmine Khaldi }
252066f35ef8SAmine Khaldi
flush_messages(void)252166f35ef8SAmine Khaldi static void flush_messages(void)
252266f35ef8SAmine Khaldi {
252366f35ef8SAmine Khaldi MSG msg;
252466f35ef8SAmine Khaldi while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ));
252566f35ef8SAmine Khaldi }
252666f35ef8SAmine Khaldi
cowait_window_proc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)252766f35ef8SAmine Khaldi static LRESULT CALLBACK cowait_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
252866f35ef8SAmine Khaldi {
25295c1bcfecSAmine Khaldi if(cowait_msgs_last < ARRAY_SIZE(cowait_msgs))
253066f35ef8SAmine Khaldi cowait_msgs[cowait_msgs_last++] = msg;
253166f35ef8SAmine Khaldi if(msg == WM_DDE_FIRST)
253266f35ef8SAmine Khaldi return 6;
253366f35ef8SAmine Khaldi return DefWindowProcA(hwnd, msg, wparam, lparam);
253466f35ef8SAmine Khaldi }
253566f35ef8SAmine Khaldi
cowait_unmarshal_thread(void * arg)253666f35ef8SAmine Khaldi static DWORD CALLBACK cowait_unmarshal_thread(void *arg)
253766f35ef8SAmine Khaldi {
253866f35ef8SAmine Khaldi IStream *stream = arg;
253966f35ef8SAmine Khaldi IEnumOLEVERB *enum_verb;
254066f35ef8SAmine Khaldi LARGE_INTEGER zero;
254166f35ef8SAmine Khaldi IUnknown *unk;
254266f35ef8SAmine Khaldi HRESULT hr;
254366f35ef8SAmine Khaldi
254466f35ef8SAmine Khaldi CoInitialize(NULL);
254566f35ef8SAmine Khaldi
254666f35ef8SAmine Khaldi zero.QuadPart = 0;
254766f35ef8SAmine Khaldi hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
254866f35ef8SAmine Khaldi ok(hr == S_OK, "Seek failed: %08x\n", hr);
254966f35ef8SAmine Khaldi
255066f35ef8SAmine Khaldi hr = CoUnmarshalInterface(stream, &IID_IUnknown, (void**)&unk);
255166f35ef8SAmine Khaldi ok(hr == S_OK, "CoUnmarshalInterface failed: %08x\n", hr);
255266f35ef8SAmine Khaldi
255366f35ef8SAmine Khaldi hr = IUnknown_QueryInterface(unk, &IID_IEnumOLEVERB, (void**)&enum_verb);
255466f35ef8SAmine Khaldi ok(hr == S_OK, "QueryInterface failed: %08x\n", hr);
255566f35ef8SAmine Khaldi
255666f35ef8SAmine Khaldi IEnumOLEVERB_Release(enum_verb);
255766f35ef8SAmine Khaldi IUnknown_Release(unk);
255866f35ef8SAmine Khaldi
255966f35ef8SAmine Khaldi CoUninitialize();
256066f35ef8SAmine Khaldi return 0;
256166f35ef8SAmine Khaldi }
256266f35ef8SAmine Khaldi
test_CoWaitForMultipleHandles_thread(LPVOID arg)2563c2c66affSColin Finck static DWORD CALLBACK test_CoWaitForMultipleHandles_thread(LPVOID arg)
2564c2c66affSColin Finck {
256566f35ef8SAmine Khaldi HANDLE *handles = arg, event, thread;
256666f35ef8SAmine Khaldi IStream *stream;
2567c2c66affSColin Finck BOOL success;
256866f35ef8SAmine Khaldi DWORD index, tid;
2569c2c66affSColin Finck HRESULT hr;
2570c2c66affSColin Finck HWND hWnd;
257166f35ef8SAmine Khaldi UINT uMSG = 0xc065;
2572c2c66affSColin Finck MSG msg;
257366f35ef8SAmine Khaldi int ret;
2574c2c66affSColin Finck
2575c2c66affSColin Finck hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2576c2c66affSColin Finck ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
2577c2c66affSColin Finck
2578c2c66affSColin Finck hWnd = CreateWindowExA(0, cls_name, "Test (thread)", WS_TILEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
2579c2c66affSColin Finck ok(hWnd != 0, "CreateWindowExA failed %u\n", GetLastError());
2580c2c66affSColin Finck
2581c2c66affSColin Finck index = 0xdeadbeef;
2582c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2583c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index);
2584c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2585c2c66affSColin Finck ok(index==0 || index==0xdeadbeef/* Win 8 */, "expected index 0, got %u\n", index);
2586c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2587c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2588c2c66affSColin Finck
2589c2c66affSColin Finck index = 0xdeadbeef;
2590c2c66affSColin Finck PostMessageA(hWnd, WM_USER, 0, 0);
2591c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index);
2592c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2593c2c66affSColin Finck ok(index==0 || index==0xdeadbeef/* Win 8 */, "expected index 0, got %u\n", index);
2594c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_USER, WM_USER, PM_REMOVE);
2595c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2596c2c66affSColin Finck
259766f35ef8SAmine Khaldi /* Even if CoWaitForMultipleHandles does not pump a message it peeks
259866f35ef8SAmine Khaldi * at ALL of them */
259966f35ef8SAmine Khaldi index = 0xdeadbeef;
260066f35ef8SAmine Khaldi PostMessageA(NULL, uMSG, 0, 0);
260166f35ef8SAmine Khaldi
260266f35ef8SAmine Khaldi hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index);
260366f35ef8SAmine Khaldi ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
260466f35ef8SAmine Khaldi ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
260566f35ef8SAmine Khaldi
260666f35ef8SAmine Khaldi /* Make sure message was peeked at */
260766f35ef8SAmine Khaldi ret = MsgWaitForMultipleObjectsEx(0, NULL, 2, QS_ALLPOSTMESSAGE, MWMO_ALERTABLE);
260866f35ef8SAmine Khaldi ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjects returned %x\n", ret);
260966f35ef8SAmine Khaldi
261066f35ef8SAmine Khaldi /* But not pumped */
261166f35ef8SAmine Khaldi success = PeekMessageA(&msg, NULL, uMSG, uMSG, PM_REMOVE);
261266f35ef8SAmine Khaldi ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
261366f35ef8SAmine Khaldi
2614c2c66affSColin Finck DestroyWindow(hWnd);
2615c2c66affSColin Finck CoUninitialize();
261666f35ef8SAmine Khaldi
261766f35ef8SAmine Khaldi hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
261866f35ef8SAmine Khaldi ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
261966f35ef8SAmine Khaldi
262066f35ef8SAmine Khaldi hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
262166f35ef8SAmine Khaldi ok(hr == S_OK, "CreateStreamOnHGlobal failed: %08x\n", hr);
262266f35ef8SAmine Khaldi
262366f35ef8SAmine Khaldi hr = CoMarshalInterface(stream, &IID_IUnknown, &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
262466f35ef8SAmine Khaldi ok(hr == S_OK, "CoMarshalInterface should have returned S_OK instead of 0x%08x\n", hr);
262566f35ef8SAmine Khaldi
262666f35ef8SAmine Khaldi event = CreateEventW(NULL, TRUE, FALSE, NULL);
262766f35ef8SAmine Khaldi
262866f35ef8SAmine Khaldi PostQuitMessage(66);
262966f35ef8SAmine Khaldi PostThreadMessageW(GetCurrentThreadId(), WM_QUIT, 0, 0);
263066f35ef8SAmine Khaldi
263166f35ef8SAmine Khaldi hr = CoRegisterMessageFilter(&MessageFilter, NULL);
263266f35ef8SAmine Khaldi ok(hr == S_OK, "CoRegisterMessageFilter failed: %08x\n", hr);
263366f35ef8SAmine Khaldi
263466f35ef8SAmine Khaldi thread = CreateThread(NULL, 0, cowait_unmarshal_thread, stream, 0, &tid);
263566f35ef8SAmine Khaldi ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
263666f35ef8SAmine Khaldi hr = CoWaitForMultipleHandles(0, 50, 1, &event, &index);
263766f35ef8SAmine Khaldi ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
263866f35ef8SAmine Khaldi index = WaitForSingleObject(thread, 200);
263966f35ef8SAmine Khaldi ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
264066f35ef8SAmine Khaldi CloseHandle(thread);
264166f35ef8SAmine Khaldi
264266f35ef8SAmine Khaldi hr = CoRegisterMessageFilter(NULL, NULL);
264366f35ef8SAmine Khaldi ok(hr == S_OK, "CoRegisterMessageFilter failed: %08x\n", hr);
264466f35ef8SAmine Khaldi
264566f35ef8SAmine Khaldi IStream_Release(stream);
264666f35ef8SAmine Khaldi
264766f35ef8SAmine Khaldi CloseHandle(event);
264866f35ef8SAmine Khaldi CoUninitialize();
2649c2c66affSColin Finck return 0;
2650c2c66affSColin Finck }
2651c2c66affSColin Finck
test_CoWaitForMultipleHandles(void)2652c2c66affSColin Finck static void test_CoWaitForMultipleHandles(void)
2653c2c66affSColin Finck {
2654c2c66affSColin Finck HANDLE handles[2], thread;
2655c2c66affSColin Finck DWORD index, tid;
2656c2c66affSColin Finck WNDCLASSEXA wc;
2657c2c66affSColin Finck BOOL success;
2658c2c66affSColin Finck HRESULT hr;
2659c2c66affSColin Finck HWND hWnd;
2660c2c66affSColin Finck MSG msg;
2661c2c66affSColin Finck
2662c2c66affSColin Finck hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2663c2c66affSColin Finck ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
2664c2c66affSColin Finck
2665c2c66affSColin Finck memset(&wc, 0, sizeof(wc));
2666c2c66affSColin Finck wc.cbSize = sizeof(wc);
2667c2c66affSColin Finck wc.style = CS_VREDRAW | CS_HREDRAW;
2668c2c66affSColin Finck wc.hInstance = GetModuleHandleA(0);
2669c2c66affSColin Finck wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
2670c2c66affSColin Finck wc.hbrBackground = NULL;
2671c2c66affSColin Finck wc.lpszClassName = cls_name;
267266f35ef8SAmine Khaldi wc.lpfnWndProc = cowait_window_proc;
2673c2c66affSColin Finck success = RegisterClassExA(&wc) != 0;
2674c2c66affSColin Finck ok(success, "RegisterClassExA failed %u\n", GetLastError());
2675c2c66affSColin Finck
2676c2c66affSColin Finck hWnd = CreateWindowExA(0, cls_name, "Test", WS_TILEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
2677c2c66affSColin Finck ok(hWnd != 0, "CreateWindowExA failed %u\n", GetLastError());
2678c2c66affSColin Finck handles[0] = CreateSemaphoreA(NULL, 1, 1, NULL);
2679c2c66affSColin Finck ok(handles[0] != 0, "CreateSemaphoreA failed %u\n", GetLastError());
2680c2c66affSColin Finck handles[1] = CreateSemaphoreA(NULL, 1, 1, NULL);
2681c2c66affSColin Finck ok(handles[1] != 0, "CreateSemaphoreA failed %u\n", GetLastError());
2682c2c66affSColin Finck
2683c2c66affSColin Finck /* test without flags */
2684c2c66affSColin Finck
2685c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2686c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 0, handles, NULL);
2687c2c66affSColin Finck ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
2688c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2689c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2690c2c66affSColin Finck
2691c2c66affSColin Finck index = 0xdeadbeef;
2692c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2693c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 0, NULL, &index);
2694c2c66affSColin Finck ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
2695c2c66affSColin Finck ok(index == 0, "expected index 0, got %u\n", index);
2696c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2697c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2698c2c66affSColin Finck
2699c2c66affSColin Finck index = 0xdeadbeef;
2700c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2701c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 0, handles, &index);
2702c2c66affSColin Finck ok(hr == RPC_E_NO_SYNC, "expected RPC_E_NO_SYNC, got 0x%08x\n", hr);
2703c2c66affSColin Finck ok(index == 0, "expected index 0, got %u\n", index);
2704c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2705c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2706c2c66affSColin Finck
2707c2c66affSColin Finck index = 0xdeadbeef;
2708c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2709c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 1, handles, &index);
2710c2c66affSColin Finck ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2711c2c66affSColin Finck ok(index == 0, "expected index 0, got %u\n", index);
2712c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2713c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2714c2c66affSColin Finck
2715c2c66affSColin Finck index = 0xdeadbeef;
2716c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2717c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index);
2718c2c66affSColin Finck ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2719c2c66affSColin Finck ok(index == 1, "expected index 1, got %u\n", index);
2720c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2721c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2722c2c66affSColin Finck
2723c2c66affSColin Finck index = 0xdeadbeef;
2724c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2725c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index);
2726c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2727c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2728c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2729c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2730c2c66affSColin Finck
2731c2c66affSColin Finck /* test PostMessageA/SendMessageA from a different thread */
2732c2c66affSColin Finck
2733c2c66affSColin Finck index = 0xdeadbeef;
2734c2c66affSColin Finck thread = CreateThread(NULL, 0, post_message_thread, hWnd, 0, &tid);
2735c2c66affSColin Finck ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2736c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2737c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2738c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2739c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2740c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2741c2c66affSColin Finck index = WaitForSingleObject(thread, 200);
2742c2c66affSColin Finck ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2743c2c66affSColin Finck CloseHandle(thread);
2744c2c66affSColin Finck
2745c2c66affSColin Finck index = 0xdeadbeef;
2746c2c66affSColin Finck thread = CreateThread(NULL, 0, send_message_thread, hWnd, 0, &tid);
2747c2c66affSColin Finck ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2748c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2749c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2750c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2751c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2752c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2753c2c66affSColin Finck index = WaitForSingleObject(thread, 200);
2754c2c66affSColin Finck ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2755c2c66affSColin Finck CloseHandle(thread);
2756c2c66affSColin Finck
2757c2c66affSColin Finck ReleaseSemaphore(handles[0], 1, NULL);
2758c2c66affSColin Finck ReleaseSemaphore(handles[1], 1, NULL);
2759c2c66affSColin Finck
2760c2c66affSColin Finck /* test with COWAIT_WAITALL */
2761c2c66affSColin Finck
2762c2c66affSColin Finck index = 0xdeadbeef;
2763c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2764c2c66affSColin Finck hr = CoWaitForMultipleHandles(COWAIT_WAITALL, 50, 2, handles, &index);
2765c2c66affSColin Finck ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2766c2c66affSColin Finck ok(index == 0, "expected index 0, got %u\n", index);
2767c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2768c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2769c2c66affSColin Finck
2770c2c66affSColin Finck index = 0xdeadbeef;
2771c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2772c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index);
2773c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2774c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2775c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2776c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2777c2c66affSColin Finck
2778c2c66affSColin Finck ReleaseSemaphore(handles[0], 1, NULL);
2779c2c66affSColin Finck ReleaseSemaphore(handles[1], 1, NULL);
2780c2c66affSColin Finck
2781c2c66affSColin Finck /* test with COWAIT_ALERTABLE */
2782c2c66affSColin Finck
2783c2c66affSColin Finck index = 0xdeadbeef;
2784c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2785c2c66affSColin Finck hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 1, handles, &index);
2786c2c66affSColin Finck ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2787c2c66affSColin Finck ok(index == 0, "expected index 0, got %u\n", index);
2788c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2789c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2790c2c66affSColin Finck
2791c2c66affSColin Finck index = 0xdeadbeef;
2792c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2793c2c66affSColin Finck hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index);
2794c2c66affSColin Finck ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2795c2c66affSColin Finck ok(index == 1, "expected index 1, got %u\n", index);
2796c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2797c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2798c2c66affSColin Finck
2799c2c66affSColin Finck index = 0xdeadbeef;
2800c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2801c2c66affSColin Finck hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index);
2802c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2803c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2804c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2805c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2806c2c66affSColin Finck
2807c2c66affSColin Finck index = 0xdeadbeef;
2808c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2809c2c66affSColin Finck success = QueueUserAPC(apc_test_proc, GetCurrentThread(), 0);
2810c2c66affSColin Finck ok(success, "QueueUserAPC failed %u\n", GetLastError());
2811c2c66affSColin Finck hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index);
2812c2c66affSColin Finck ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
2813c2c66affSColin Finck ok(index == WAIT_IO_COMPLETION, "expected index WAIT_IO_COMPLETION, got %u\n", index);
2814c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2815c2c66affSColin Finck ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n");
2816c2c66affSColin Finck
2817c2c66affSColin Finck /* test with COWAIT_INPUTAVAILABLE (semaphores are still locked) */
2818c2c66affSColin Finck
2819c2c66affSColin Finck index = 0xdeadbeef;
2820c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2821c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_NOREMOVE);
2822c2c66affSColin Finck ok(success, "PeekMessageA returned FALSE\n");
2823c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index);
2824c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2825c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2826c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2827c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n");
2828c2c66affSColin Finck
2829c2c66affSColin Finck index = 0xdeadbeef;
2830c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2831c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_NOREMOVE);
2832c2c66affSColin Finck ok(success, "PeekMessageA returned FALSE\n");
2833c2c66affSColin Finck thread = CreateThread(NULL, 0, release_semaphore_thread, handles[1], 0, &tid);
2834c2c66affSColin Finck ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2835c2c66affSColin Finck hr = CoWaitForMultipleHandles(COWAIT_INPUTAVAILABLE, 50, 2, handles, &index);
2836c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING || broken(hr == E_INVALIDARG) || broken(hr == S_OK) /* Win 8 */,
2837c2c66affSColin Finck "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2838c2c66affSColin Finck if (hr != S_OK) ReleaseSemaphore(handles[1], 1, NULL);
2839c2c66affSColin Finck ok(index == 0 || broken(index == 1) /* Win 8 */, "expected index 0, got %u\n", index);
2840c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2841c2c66affSColin Finck ok(!success || broken(success && hr == E_INVALIDARG),
2842c2c66affSColin Finck "CoWaitForMultipleHandles didn't pump any messages\n");
2843c2c66affSColin Finck index = WaitForSingleObject(thread, 200);
2844c2c66affSColin Finck ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2845c2c66affSColin Finck CloseHandle(thread);
2846c2c66affSColin Finck
284766f35ef8SAmine Khaldi cowait_msgs_reset();
284866f35ef8SAmine Khaldi PostMessageA(hWnd, 0, 0, 0);
284966f35ef8SAmine Khaldi PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
285066f35ef8SAmine Khaldi PostMessageA(hWnd, WM_USER+1, 0, 0);
285166f35ef8SAmine Khaldi PostMessageA(hWnd, WM_DDE_FIRST+1, 0, 0);
285266f35ef8SAmine Khaldi thread = CreateThread(NULL, 0, send_and_post_user_message_thread, hWnd, 0, &tid);
285366f35ef8SAmine Khaldi ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
285466f35ef8SAmine Khaldi
285566f35ef8SAmine Khaldi hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
285666f35ef8SAmine Khaldi ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
285766f35ef8SAmine Khaldi
285866f35ef8SAmine Khaldi cowait_msgs_expect_notified(WM_DDE_FIRST);
285966f35ef8SAmine Khaldi cowait_msgs_expect_notified(WM_DDE_FIRST+1);
286066f35ef8SAmine Khaldi cowait_msgs_expect_notified(WM_USER);
286166f35ef8SAmine Khaldi cowait_msgs_expect_empty();
286266f35ef8SAmine Khaldi cowait_msgs_expect_queued(hWnd, WM_USER);
286366f35ef8SAmine Khaldi cowait_msgs_expect_queued(hWnd, WM_USER+1);
286466f35ef8SAmine Khaldi flush_messages();
286566f35ef8SAmine Khaldi
286666f35ef8SAmine Khaldi index = WaitForSingleObject(thread, 200);
286766f35ef8SAmine Khaldi ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
286866f35ef8SAmine Khaldi CloseHandle(thread);
286966f35ef8SAmine Khaldi
2870c2c66affSColin Finck /* test behaviour of WM_QUIT (semaphores are still locked) */
2871c2c66affSColin Finck
2872c2c66affSColin Finck PostMessageA(hWnd, WM_QUIT, 40, 0);
2873c2c66affSColin Finck memset(&msg, 0, sizeof(msg));
2874c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_QUIT, WM_QUIT, PM_REMOVE);
2875c2c66affSColin Finck ok(success, "PeekMessageA failed, error %u\n", GetLastError());
2876c2c66affSColin Finck ok(msg.message == WM_QUIT, "expected msg.message = WM_QUIT, got %u\n", msg.message);
2877c2c66affSColin Finck ok(msg.wParam == 40, "expected msg.wParam = 40, got %lu\n", msg.wParam);
2878c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_QUIT, WM_QUIT, PM_REMOVE);
2879c2c66affSColin Finck ok(!success, "PeekMessageA succeeded\n");
2880c2c66affSColin Finck
288166f35ef8SAmine Khaldi cowait_msgs_reset();
288266f35ef8SAmine Khaldi PostMessageA(hWnd, WM_QUIT, 40, 0);
288366f35ef8SAmine Khaldi PostMessageA(hWnd, 0, 0, 0);
288466f35ef8SAmine Khaldi PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
288566f35ef8SAmine Khaldi PostMessageA(hWnd, WM_USER+1, 0, 0);
288666f35ef8SAmine Khaldi PostMessageA(hWnd, WM_DDE_FIRST+1, 0, 0);
288766f35ef8SAmine Khaldi thread = CreateThread(NULL, 0, send_and_post_user_message_thread, hWnd, 0, &tid);
288866f35ef8SAmine Khaldi ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
288966f35ef8SAmine Khaldi
289066f35ef8SAmine Khaldi hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
289166f35ef8SAmine Khaldi ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
289266f35ef8SAmine Khaldi
289366f35ef8SAmine Khaldi cowait_msgs_expect_notified(WM_DDE_FIRST);
289466f35ef8SAmine Khaldi cowait_msgs_expect_notified(WM_DDE_FIRST+1);
289566f35ef8SAmine Khaldi cowait_msgs_expect_notified(WM_USER);
289666f35ef8SAmine Khaldi cowait_msgs_expect_empty();
289766f35ef8SAmine Khaldi cowait_msgs_expect_queued(hWnd, WM_USER);
289866f35ef8SAmine Khaldi flush_messages();
289966f35ef8SAmine Khaldi
290066f35ef8SAmine Khaldi index = WaitForSingleObject(thread, 200);
290166f35ef8SAmine Khaldi ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
290266f35ef8SAmine Khaldi CloseHandle(thread);
290366f35ef8SAmine Khaldi
2904c2c66affSColin Finck index = 0xdeadbeef;
2905c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2906c2c66affSColin Finck PostMessageA(hWnd, WM_QUIT, 41, 0);
2907c2c66affSColin Finck thread = CreateThread(NULL, 0, post_message_thread, hWnd, 0, &tid);
2908c2c66affSColin Finck ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2909c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2910c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2911c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2912c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2913c2c66affSColin Finck todo_wine
2914c2c66affSColin Finck ok(success || broken(!success) /* Win 2000/XP/8 */, "PeekMessageA failed, error %u\n", GetLastError());
2915c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2916c2c66affSColin Finck ok(!success, "PeekMessageA succeeded\n");
2917c2c66affSColin Finck memset(&msg, 0, sizeof(msg));
2918c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_QUIT, WM_QUIT, PM_REMOVE);
2919c2c66affSColin Finck todo_wine
2920c2c66affSColin Finck ok(!success || broken(success) /* Win 2000/XP/8 */, "PeekMessageA succeeded\n");
2921c2c66affSColin Finck if (success)
2922c2c66affSColin Finck {
2923c2c66affSColin Finck ok(msg.message == WM_QUIT, "expected msg.message = WM_QUIT, got %u\n", msg.message);
2924c2c66affSColin Finck ok(msg.wParam == 41, "expected msg.wParam = 41, got %lu\n", msg.wParam);
2925c2c66affSColin Finck }
2926c2c66affSColin Finck index = WaitForSingleObject(thread, 200);
2927c2c66affSColin Finck ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2928c2c66affSColin Finck CloseHandle(thread);
2929c2c66affSColin Finck
2930c2c66affSColin Finck index = 0xdeadbeef;
2931c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2932c2c66affSColin Finck PostMessageA(hWnd, WM_QUIT, 42, 0);
2933c2c66affSColin Finck thread = CreateThread(NULL, 0, send_message_thread, hWnd, 0, &tid);
2934c2c66affSColin Finck ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2935c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2936c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2937c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2938c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2939c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't pump all WM_DDE_FIRST messages\n");
2940c2c66affSColin Finck memset(&msg, 0, sizeof(msg));
2941c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_QUIT, WM_QUIT, PM_REMOVE);
2942c2c66affSColin Finck ok(success, "PeekMessageA failed, error %u\n", GetLastError());
2943c2c66affSColin Finck ok(msg.message == WM_QUIT, "expected msg.message = WM_QUIT, got %u\n", msg.message);
2944c2c66affSColin Finck ok(msg.wParam == 42, "expected msg.wParam = 42, got %lu\n", msg.wParam);
2945c2c66affSColin Finck index = WaitForSingleObject(thread, 200);
2946c2c66affSColin Finck ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2947c2c66affSColin Finck CloseHandle(thread);
2948c2c66affSColin Finck
2949c2c66affSColin Finck PostQuitMessage(43);
2950c2c66affSColin Finck memset(&msg, 0, sizeof(msg));
2951c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_QUIT, WM_QUIT, PM_REMOVE);
2952c2c66affSColin Finck ok(success || broken(!success) /* Win 8 */, "PeekMessageA failed, error %u\n", GetLastError());
2953c2c66affSColin Finck if (!success)
2954c2c66affSColin Finck win_skip("PostQuitMessage didn't queue a WM_QUIT message, skipping tests\n");
2955c2c66affSColin Finck else
2956c2c66affSColin Finck {
2957c2c66affSColin Finck ok(msg.message == WM_QUIT, "expected msg.message = WM_QUIT, got %u\n", msg.message);
2958c2c66affSColin Finck ok(msg.wParam == 43, "expected msg.wParam = 43, got %lu\n", msg.wParam);
2959c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_QUIT, WM_QUIT, PM_REMOVE);
2960c2c66affSColin Finck ok(!success, "PeekMessageA succeeded\n");
2961c2c66affSColin Finck
2962c2c66affSColin Finck index = 0xdeadbeef;
2963c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2964c2c66affSColin Finck PostQuitMessage(44);
2965c2c66affSColin Finck thread = CreateThread(NULL, 0, post_message_thread, hWnd, 0, &tid);
2966c2c66affSColin Finck ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2967c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2968c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2969c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2970c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2971c2c66affSColin Finck ok(success, "PeekMessageA failed, error %u\n", GetLastError());
2972c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2973c2c66affSColin Finck ok(!success, "PeekMessageA succeeded\n");
2974c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_QUIT, WM_QUIT, PM_REMOVE);
2975c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't remove WM_QUIT messages\n");
2976c2c66affSColin Finck index = WaitForSingleObject(thread, 200);
2977c2c66affSColin Finck ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2978c2c66affSColin Finck CloseHandle(thread);
2979c2c66affSColin Finck
2980c2c66affSColin Finck index = 0xdeadbeef;
2981c2c66affSColin Finck PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
2982c2c66affSColin Finck PostQuitMessage(45);
2983c2c66affSColin Finck thread = CreateThread(NULL, 0, send_message_thread, hWnd, 0, &tid);
2984c2c66affSColin Finck ok(thread != NULL, "CreateThread failed, error %u\n", GetLastError());
2985c2c66affSColin Finck hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
2986c2c66affSColin Finck ok(hr == RPC_S_CALLPENDING, "expected RPC_S_CALLPENDING, got 0x%08x\n", hr);
2987c2c66affSColin Finck ok(index == 0 || broken(index == 0xdeadbeef) /* Win 8 */, "expected index 0, got %u\n", index);
2988c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2989c2c66affSColin Finck ok(success, "PeekMessageA failed, error %u\n", GetLastError());
2990c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
2991c2c66affSColin Finck ok(!success, "PeekMessageA succeeded\n");
2992c2c66affSColin Finck success = PeekMessageA(&msg, hWnd, WM_QUIT, WM_QUIT, PM_REMOVE);
2993c2c66affSColin Finck ok(!success, "CoWaitForMultipleHandles didn't remove WM_QUIT messages\n");
2994c2c66affSColin Finck index = WaitForSingleObject(thread, 200);
2995c2c66affSColin Finck ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
2996c2c66affSColin Finck CloseHandle(thread);
2997c2c66affSColin Finck }
2998c2c66affSColin Finck
2999c2c66affSColin Finck /* test message pumping when CoWaitForMultipleHandles is called from non main apartment thread */
3000c2c66affSColin Finck thread = CreateThread(NULL, 0, test_CoWaitForMultipleHandles_thread, handles, 0, &tid);
3001c2c66affSColin Finck index = WaitForSingleObject(thread, 500);
3002c2c66affSColin Finck ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
3003c2c66affSColin Finck CloseHandle(thread);
3004c2c66affSColin Finck
3005a6cdf4ffSAmine Khaldi CoUninitialize();
3006a6cdf4ffSAmine Khaldi
3007a6cdf4ffSAmine Khaldi /* If COM was not initialized, messages are neither pumped nor peeked at */
3008a6cdf4ffSAmine Khaldi PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
3009a6cdf4ffSAmine Khaldi hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
3010a6cdf4ffSAmine Khaldi ok(hr == RPC_S_CALLPENDING, "got %#x\n", hr);
3011a6cdf4ffSAmine Khaldi success = MsgWaitForMultipleObjectsEx(0, NULL, 2, QS_ALLPOSTMESSAGE, MWMO_ALERTABLE);
3012a6cdf4ffSAmine Khaldi ok(success == 0, "MsgWaitForMultipleObjects returned %x\n", success);
3013a6cdf4ffSAmine Khaldi success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
3014a6cdf4ffSAmine Khaldi ok(success, "PeekMessage failed: %u\n", GetLastError());
3015a6cdf4ffSAmine Khaldi
3016a6cdf4ffSAmine Khaldi /* same in an MTA */
3017a6cdf4ffSAmine Khaldi CoInitializeEx(NULL, COINIT_MULTITHREADED);
3018a6cdf4ffSAmine Khaldi
3019a6cdf4ffSAmine Khaldi PostMessageA(hWnd, WM_DDE_FIRST, 0, 0);
3020a6cdf4ffSAmine Khaldi hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index);
3021a6cdf4ffSAmine Khaldi ok(hr == RPC_S_CALLPENDING, "got %#x\n", hr);
3022a6cdf4ffSAmine Khaldi success = MsgWaitForMultipleObjectsEx(0, NULL, 2, QS_ALLPOSTMESSAGE, MWMO_ALERTABLE);
3023a6cdf4ffSAmine Khaldi ok(success == 0, "MsgWaitForMultipleObjects returned %x\n", success);
3024a6cdf4ffSAmine Khaldi success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE);
3025a6cdf4ffSAmine Khaldi ok(success, "PeekMessage failed: %u\n", GetLastError());
3026a6cdf4ffSAmine Khaldi
3027a6cdf4ffSAmine Khaldi CoUninitialize();
3028a6cdf4ffSAmine Khaldi
3029c2c66affSColin Finck CloseHandle(handles[0]);
3030c2c66affSColin Finck CloseHandle(handles[1]);
3031c2c66affSColin Finck DestroyWindow(hWnd);
3032c2c66affSColin Finck
3033c2c66affSColin Finck success = UnregisterClassA(cls_name, GetModuleHandleA(0));
3034c2c66affSColin Finck ok(success, "UnregisterClass failed %u\n", GetLastError());
3035c2c66affSColin Finck }
3036c2c66affSColin Finck
test_CoGetMalloc(void)3037c2c66affSColin Finck static void test_CoGetMalloc(void)
3038c2c66affSColin Finck {
3039c2c66affSColin Finck IMalloc *imalloc;
3040c2c66affSColin Finck HRESULT hr;
3041c2c66affSColin Finck
3042c2c66affSColin Finck if (0) /* crashes on native */
3043c2c66affSColin Finck hr = CoGetMalloc(0, NULL);
3044c2c66affSColin Finck
3045c2c66affSColin Finck imalloc = (void*)0xdeadbeef;
3046c2c66affSColin Finck hr = CoGetMalloc(0, &imalloc);
3047c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3048c2c66affSColin Finck ok(imalloc == NULL, "got %p\n", imalloc);
3049c2c66affSColin Finck
3050c2c66affSColin Finck imalloc = (void*)0xdeadbeef;
3051c2c66affSColin Finck hr = CoGetMalloc(MEMCTX_SHARED, &imalloc);
3052c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3053c2c66affSColin Finck ok(imalloc == NULL, "got %p\n", imalloc);
3054c2c66affSColin Finck
3055c2c66affSColin Finck imalloc = (void*)0xdeadbeef;
3056c2c66affSColin Finck hr = CoGetMalloc(MEMCTX_MACSYSTEM, &imalloc);
3057c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3058c2c66affSColin Finck ok(imalloc == NULL, "got %p\n", imalloc);
3059c2c66affSColin Finck
3060c2c66affSColin Finck imalloc = (void*)0xdeadbeef;
3061c2c66affSColin Finck hr = CoGetMalloc(MEMCTX_UNKNOWN, &imalloc);
3062c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3063c2c66affSColin Finck ok(imalloc == NULL, "got %p\n", imalloc);
3064c2c66affSColin Finck
3065c2c66affSColin Finck imalloc = (void*)0xdeadbeef;
3066c2c66affSColin Finck hr = CoGetMalloc(MEMCTX_SAME, &imalloc);
3067c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3068c2c66affSColin Finck ok(imalloc == NULL, "got %p\n", imalloc);
3069c2c66affSColin Finck
3070c2c66affSColin Finck imalloc = NULL;
3071c2c66affSColin Finck hr = CoGetMalloc(MEMCTX_TASK, &imalloc);
3072c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3073c2c66affSColin Finck ok(imalloc != NULL, "got %p\n", imalloc);
3074c2c66affSColin Finck IMalloc_Release(imalloc);
3075c2c66affSColin Finck }
3076c2c66affSColin Finck
test_CoGetApartmentType(void)3077c2c66affSColin Finck static void test_CoGetApartmentType(void)
3078c2c66affSColin Finck {
3079c2c66affSColin Finck APTTYPEQUALIFIER qualifier;
3080c2c66affSColin Finck APTTYPE type;
3081c2c66affSColin Finck HRESULT hr;
3082c2c66affSColin Finck
3083c2c66affSColin Finck if (!pCoGetApartmentType)
3084c2c66affSColin Finck {
3085c2c66affSColin Finck win_skip("CoGetApartmentType not present\n");
3086c2c66affSColin Finck return;
3087c2c66affSColin Finck }
3088c2c66affSColin Finck
3089c2c66affSColin Finck hr = pCoGetApartmentType(NULL, NULL);
3090c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%08x\n", hr);
3091c2c66affSColin Finck
3092c2c66affSColin Finck type = 0xdeadbeef;
3093c2c66affSColin Finck hr = pCoGetApartmentType(&type, NULL);
3094c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%08x\n", hr);
3095c2c66affSColin Finck ok(type == 0xdeadbeef, "Expected 0xdeadbeef, got %u\n", type);
3096c2c66affSColin Finck
3097c2c66affSColin Finck qualifier = 0xdeadbeef;
3098c2c66affSColin Finck hr = pCoGetApartmentType(NULL, &qualifier);
3099c2c66affSColin Finck ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%08x\n", hr);
3100c2c66affSColin Finck ok(qualifier == 0xdeadbeef, "Expected 0xdeadbeef, got %u\n", qualifier);
3101c2c66affSColin Finck
3102c2c66affSColin Finck type = 0xdeadbeef;
3103c2c66affSColin Finck qualifier = 0xdeadbeef;
3104c2c66affSColin Finck hr = pCoGetApartmentType(&type, &qualifier);
3105c2c66affSColin Finck ok(hr == CO_E_NOTINITIALIZED, "CoGetApartmentType succeeded, error: 0x%08x\n", hr);
3106c2c66affSColin Finck ok(type == APTTYPE_CURRENT, "Expected APTTYPE_CURRENT, got %u\n", type);
3107c2c66affSColin Finck ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier);
3108c2c66affSColin Finck
3109c2c66affSColin Finck type = 0xdeadbeef;
3110c2c66affSColin Finck qualifier = 0xdeadbeef;
3111c2c66affSColin Finck hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
3112c2c66affSColin Finck ok(hr == S_OK, "CoInitializeEx failed, error: 0x%08x\n", hr);
3113c2c66affSColin Finck hr = pCoGetApartmentType(&type, &qualifier);
3114c2c66affSColin Finck ok(hr == S_OK, "CoGetApartmentType failed, error: 0x%08x\n", hr);
3115c2c66affSColin Finck ok(type == APTTYPE_MAINSTA, "Expected APTTYPE_MAINSTA, got %u\n", type);
3116c2c66affSColin Finck ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier);
3117c2c66affSColin Finck CoUninitialize();
3118c2c66affSColin Finck
3119c2c66affSColin Finck type = 0xdeadbeef;
3120c2c66affSColin Finck qualifier = 0xdeadbeef;
3121c2c66affSColin Finck hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED);
3122c2c66affSColin Finck ok(hr == S_OK, "CoInitializeEx failed, error: 0x%08x\n", hr);
3123c2c66affSColin Finck hr = pCoGetApartmentType(&type, &qualifier);
3124c2c66affSColin Finck ok(hr == S_OK, "CoGetApartmentType failed, error: 0x%08x\n", hr);
3125c2c66affSColin Finck ok(type == APTTYPE_MTA, "Expected APTTYPE_MTA, got %u\n", type);
3126c2c66affSColin Finck ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier);
3127c2c66affSColin Finck CoUninitialize();
3128c2c66affSColin Finck }
3129c2c66affSColin Finck
testspy_QI(IMallocSpy * iface,REFIID riid,void ** obj)3130c2c66affSColin Finck static HRESULT WINAPI testspy_QI(IMallocSpy *iface, REFIID riid, void **obj)
3131c2c66affSColin Finck {
3132c2c66affSColin Finck if (IsEqualIID(riid, &IID_IMallocSpy) || IsEqualIID(riid, &IID_IUnknown))
3133c2c66affSColin Finck {
3134c2c66affSColin Finck *obj = iface;
3135c2c66affSColin Finck IMallocSpy_AddRef(iface);
3136c2c66affSColin Finck return S_OK;
3137c2c66affSColin Finck }
3138c2c66affSColin Finck
3139c2c66affSColin Finck return E_NOINTERFACE;
3140c2c66affSColin Finck }
3141c2c66affSColin Finck
testspy_AddRef(IMallocSpy * iface)3142c2c66affSColin Finck static ULONG WINAPI testspy_AddRef(IMallocSpy *iface)
3143c2c66affSColin Finck {
3144c2c66affSColin Finck return 2;
3145c2c66affSColin Finck }
3146c2c66affSColin Finck
testspy_Release(IMallocSpy * iface)3147c2c66affSColin Finck static ULONG WINAPI testspy_Release(IMallocSpy *iface)
3148c2c66affSColin Finck {
3149c2c66affSColin Finck return 1;
3150c2c66affSColin Finck }
3151c2c66affSColin Finck
testspy_PreAlloc(IMallocSpy * iface,SIZE_T cb)3152c2c66affSColin Finck static SIZE_T WINAPI testspy_PreAlloc(IMallocSpy *iface, SIZE_T cb)
3153c2c66affSColin Finck {
3154c2c66affSColin Finck ok(0, "unexpected call\n");
3155c2c66affSColin Finck return 0;
3156c2c66affSColin Finck }
3157c2c66affSColin Finck
testspy_PostAlloc(IMallocSpy * iface,void * ptr)3158c2c66affSColin Finck static void* WINAPI testspy_PostAlloc(IMallocSpy *iface, void *ptr)
3159c2c66affSColin Finck {
3160c2c66affSColin Finck ok(0, "unexpected call\n");
3161c2c66affSColin Finck return NULL;
3162c2c66affSColin Finck }
3163c2c66affSColin Finck
testspy_PreFree(IMallocSpy * iface,void * ptr,BOOL spyed)3164c2c66affSColin Finck static void* WINAPI testspy_PreFree(IMallocSpy *iface, void *ptr, BOOL spyed)
3165c2c66affSColin Finck {
3166c2c66affSColin Finck ok(0, "unexpected call\n");
3167c2c66affSColin Finck return NULL;
3168c2c66affSColin Finck }
3169c2c66affSColin Finck
testspy_PostFree(IMallocSpy * iface,BOOL spyed)3170c2c66affSColin Finck static void WINAPI testspy_PostFree(IMallocSpy *iface, BOOL spyed)
3171c2c66affSColin Finck {
3172c2c66affSColin Finck ok(0, "unexpected call\n");
3173c2c66affSColin Finck }
3174c2c66affSColin Finck
testspy_PreRealloc(IMallocSpy * iface,void * ptr,SIZE_T cb,void ** newptr,BOOL spyed)3175c2c66affSColin Finck static SIZE_T WINAPI testspy_PreRealloc(IMallocSpy *iface, void *ptr, SIZE_T cb, void **newptr, BOOL spyed)
3176c2c66affSColin Finck {
3177c2c66affSColin Finck ok(0, "unexpected call\n");
3178c2c66affSColin Finck return 0;
3179c2c66affSColin Finck }
3180c2c66affSColin Finck
testspy_PostRealloc(IMallocSpy * iface,void * ptr,BOOL spyed)3181c2c66affSColin Finck static void* WINAPI testspy_PostRealloc(IMallocSpy *iface, void *ptr, BOOL spyed)
3182c2c66affSColin Finck {
3183c2c66affSColin Finck ok(0, "unexpected call\n");
3184c2c66affSColin Finck return NULL;
3185c2c66affSColin Finck }
3186c2c66affSColin Finck
testspy_PreGetSize(IMallocSpy * iface,void * ptr,BOOL spyed)3187c2c66affSColin Finck static void* WINAPI testspy_PreGetSize(IMallocSpy *iface, void *ptr, BOOL spyed)
3188c2c66affSColin Finck {
3189c2c66affSColin Finck ok(0, "unexpected call\n");
3190c2c66affSColin Finck return NULL;
3191c2c66affSColin Finck }
3192c2c66affSColin Finck
testspy_PostGetSize(IMallocSpy * iface,SIZE_T actual,BOOL spyed)3193c2c66affSColin Finck static SIZE_T WINAPI testspy_PostGetSize(IMallocSpy *iface, SIZE_T actual, BOOL spyed)
3194c2c66affSColin Finck {
3195c2c66affSColin Finck ok(0, "unexpected call\n");
3196c2c66affSColin Finck return 0;
3197c2c66affSColin Finck }
3198c2c66affSColin Finck
testspy_PreDidAlloc(IMallocSpy * iface,void * ptr,BOOL spyed)3199c2c66affSColin Finck static void* WINAPI testspy_PreDidAlloc(IMallocSpy *iface, void *ptr, BOOL spyed)
3200c2c66affSColin Finck {
3201c2c66affSColin Finck ok(0, "unexpected call\n");
3202c2c66affSColin Finck return NULL;
3203c2c66affSColin Finck }
3204c2c66affSColin Finck
testspy_PostDidAlloc(IMallocSpy * iface,void * ptr,BOOL spyed,int actual)3205c2c66affSColin Finck static int WINAPI testspy_PostDidAlloc(IMallocSpy *iface, void *ptr, BOOL spyed, int actual)
3206c2c66affSColin Finck {
3207c2c66affSColin Finck ok(0, "unexpected call\n");
3208c2c66affSColin Finck return 0;
3209c2c66affSColin Finck }
3210c2c66affSColin Finck
testspy_PreHeapMinimize(IMallocSpy * iface)3211c2c66affSColin Finck static void WINAPI testspy_PreHeapMinimize(IMallocSpy *iface)
3212c2c66affSColin Finck {
3213c2c66affSColin Finck ok(0, "unexpected call\n");
3214c2c66affSColin Finck }
3215c2c66affSColin Finck
testspy_PostHeapMinimize(IMallocSpy * iface)3216c2c66affSColin Finck static void WINAPI testspy_PostHeapMinimize(IMallocSpy *iface)
3217c2c66affSColin Finck {
3218c2c66affSColin Finck ok(0, "unexpected call\n");
3219c2c66affSColin Finck }
3220c2c66affSColin Finck
3221c2c66affSColin Finck static const IMallocSpyVtbl testspyvtbl =
3222c2c66affSColin Finck {
3223c2c66affSColin Finck testspy_QI,
3224c2c66affSColin Finck testspy_AddRef,
3225c2c66affSColin Finck testspy_Release,
3226c2c66affSColin Finck testspy_PreAlloc,
3227c2c66affSColin Finck testspy_PostAlloc,
3228c2c66affSColin Finck testspy_PreFree,
3229c2c66affSColin Finck testspy_PostFree,
3230c2c66affSColin Finck testspy_PreRealloc,
3231c2c66affSColin Finck testspy_PostRealloc,
3232c2c66affSColin Finck testspy_PreGetSize,
3233c2c66affSColin Finck testspy_PostGetSize,
3234c2c66affSColin Finck testspy_PreDidAlloc,
3235c2c66affSColin Finck testspy_PostDidAlloc,
3236c2c66affSColin Finck testspy_PreHeapMinimize,
3237c2c66affSColin Finck testspy_PostHeapMinimize
3238c2c66affSColin Finck };
3239c2c66affSColin Finck
3240c2c66affSColin Finck static IMallocSpy testspy = { &testspyvtbl };
3241c2c66affSColin Finck
test_IMallocSpy(void)3242c2c66affSColin Finck static void test_IMallocSpy(void)
3243c2c66affSColin Finck {
3244c2c66affSColin Finck IMalloc *imalloc;
3245c2c66affSColin Finck HRESULT hr;
3246c2c66affSColin Finck
3247c2c66affSColin Finck hr = CoRegisterMallocSpy(NULL);
3248c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3249c2c66affSColin Finck
3250c2c66affSColin Finck hr = CoRevokeMallocSpy();
3251c2c66affSColin Finck ok(hr == CO_E_OBJNOTREG, "got 0x%08x\n", hr);
3252c2c66affSColin Finck
3253c2c66affSColin Finck hr = CoRegisterMallocSpy(&testspy);
3254c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3255c2c66affSColin Finck
3256c2c66affSColin Finck hr = CoRegisterMallocSpy(NULL);
3257c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3258c2c66affSColin Finck
3259c2c66affSColin Finck hr = CoRegisterMallocSpy(&testspy);
3260c2c66affSColin Finck ok(hr == CO_E_OBJISREG, "got 0x%08x\n", hr);
3261c2c66affSColin Finck
3262c2c66affSColin Finck imalloc = NULL;
3263c2c66affSColin Finck hr = CoGetMalloc(MEMCTX_TASK, &imalloc);
3264c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3265c2c66affSColin Finck ok(imalloc != NULL, "got %p\n", imalloc);
3266c2c66affSColin Finck
3267c2c66affSColin Finck IMalloc_Free(imalloc, NULL);
3268c2c66affSColin Finck
3269c2c66affSColin Finck IMalloc_Release(imalloc);
3270c2c66affSColin Finck
3271c2c66affSColin Finck hr = CoRevokeMallocSpy();
3272c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3273c2c66affSColin Finck
3274c2c66affSColin Finck hr = CoRevokeMallocSpy();
3275c2c66affSColin Finck ok(hr == CO_E_OBJNOTREG, "got 0x%08x\n", hr);
3276c2c66affSColin Finck }
3277c2c66affSColin Finck
test_CoGetCurrentLogicalThreadId(void)3278c2c66affSColin Finck static void test_CoGetCurrentLogicalThreadId(void)
3279c2c66affSColin Finck {
3280c2c66affSColin Finck HRESULT hr;
3281c2c66affSColin Finck GUID id;
3282c2c66affSColin Finck
3283c2c66affSColin Finck hr = CoGetCurrentLogicalThreadId(NULL);
3284c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3285c2c66affSColin Finck
3286c2c66affSColin Finck id = GUID_NULL;
3287c2c66affSColin Finck hr = CoGetCurrentLogicalThreadId(&id);
3288c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3289c2c66affSColin Finck ok(!IsEqualGUID(&id, &GUID_NULL), "got null id\n");
3290c2c66affSColin Finck }
3291c2c66affSColin Finck
testinitialize_QI(IInitializeSpy * iface,REFIID riid,void ** obj)3292c2c66affSColin Finck static HRESULT WINAPI testinitialize_QI(IInitializeSpy *iface, REFIID riid, void **obj)
3293c2c66affSColin Finck {
3294c2c66affSColin Finck if (IsEqualIID(riid, &IID_IInitializeSpy) || IsEqualIID(riid, &IID_IUnknown))
3295c2c66affSColin Finck {
3296c2c66affSColin Finck *obj = iface;
3297c2c66affSColin Finck IInitializeSpy_AddRef(iface);
3298c2c66affSColin Finck return S_OK;
3299c2c66affSColin Finck }
3300c2c66affSColin Finck
3301c2c66affSColin Finck *obj = NULL;
3302c2c66affSColin Finck return E_NOINTERFACE;
3303c2c66affSColin Finck }
3304c2c66affSColin Finck
testinitialize_AddRef(IInitializeSpy * iface)3305c2c66affSColin Finck static ULONG WINAPI testinitialize_AddRef(IInitializeSpy *iface)
3306c2c66affSColin Finck {
3307c2c66affSColin Finck return 2;
3308c2c66affSColin Finck }
3309c2c66affSColin Finck
testinitialize_Release(IInitializeSpy * iface)3310c2c66affSColin Finck static ULONG WINAPI testinitialize_Release(IInitializeSpy *iface)
3311c2c66affSColin Finck {
3312c2c66affSColin Finck return 1;
3313c2c66affSColin Finck }
3314c2c66affSColin Finck
3315fc6e4ed5SAmine Khaldi static DWORD expected_coinit_flags;
3316fc6e4ed5SAmine Khaldi static ULARGE_INTEGER init_cookies[3];
3317fc6e4ed5SAmine Khaldi static BOOL revoke_spies_on_uninit;
3318fc6e4ed5SAmine Khaldi
testinitialize_PreInitialize(IInitializeSpy * iface,DWORD coinit,DWORD aptrefs)3319c2c66affSColin Finck static HRESULT WINAPI testinitialize_PreInitialize(IInitializeSpy *iface, DWORD coinit, DWORD aptrefs)
3320c2c66affSColin Finck {
3321fc6e4ed5SAmine Khaldi CHECK_EXPECT2(PreInitialize);
3322fc6e4ed5SAmine Khaldi ok(coinit == expected_coinit_flags, "Unexpected init flags %#x, expected %#x.\n", coinit, expected_coinit_flags);
3323fc6e4ed5SAmine Khaldi return S_OK;
3324c2c66affSColin Finck }
3325c2c66affSColin Finck
testinitialize_PostInitialize(IInitializeSpy * iface,HRESULT hr,DWORD coinit,DWORD aptrefs)3326c2c66affSColin Finck static HRESULT WINAPI testinitialize_PostInitialize(IInitializeSpy *iface, HRESULT hr, DWORD coinit, DWORD aptrefs)
3327c2c66affSColin Finck {
3328fc6e4ed5SAmine Khaldi CHECK_EXPECT2(PostInitialize);
3329fc6e4ed5SAmine Khaldi ok(coinit == expected_coinit_flags, "Unexpected init flags %#x, expected %#x.\n", coinit, expected_coinit_flags);
3330fc6e4ed5SAmine Khaldi return hr;
3331c2c66affSColin Finck }
3332c2c66affSColin Finck
testinitialize_PreUninitialize(IInitializeSpy * iface,DWORD aptrefs)3333c2c66affSColin Finck static HRESULT WINAPI testinitialize_PreUninitialize(IInitializeSpy *iface, DWORD aptrefs)
3334c2c66affSColin Finck {
3335fc6e4ed5SAmine Khaldi HRESULT hr;
3336fc6e4ed5SAmine Khaldi CHECK_EXPECT2(PreUninitialize);
3337fc6e4ed5SAmine Khaldi if (revoke_spies_on_uninit)
3338fc6e4ed5SAmine Khaldi {
3339fc6e4ed5SAmine Khaldi hr = CoRevokeInitializeSpy(init_cookies[0]);
3340fc6e4ed5SAmine Khaldi ok(hr == S_OK, "got 0x%08x\n", hr);
3341fc6e4ed5SAmine Khaldi
3342fc6e4ed5SAmine Khaldi hr = CoRevokeInitializeSpy(init_cookies[1]);
3343fc6e4ed5SAmine Khaldi ok(hr == S_OK, "got 0x%08x\n", hr);
3344fc6e4ed5SAmine Khaldi
3345fc6e4ed5SAmine Khaldi hr = CoRevokeInitializeSpy(init_cookies[2]);
3346fc6e4ed5SAmine Khaldi ok(hr == S_OK, "got 0x%08x\n", hr);
3347fc6e4ed5SAmine Khaldi
3348fc6e4ed5SAmine Khaldi revoke_spies_on_uninit = FALSE;
3349fc6e4ed5SAmine Khaldi }
3350fc6e4ed5SAmine Khaldi return S_OK;
3351c2c66affSColin Finck }
3352c2c66affSColin Finck
testinitialize_PostUninitialize(IInitializeSpy * iface,DWORD aptrefs)3353c2c66affSColin Finck static HRESULT WINAPI testinitialize_PostUninitialize(IInitializeSpy *iface, DWORD aptrefs)
3354c2c66affSColin Finck {
3355fc6e4ed5SAmine Khaldi CHECK_EXPECT2(PostUninitialize);
3356c2c66affSColin Finck return E_NOTIMPL;
3357c2c66affSColin Finck }
3358c2c66affSColin Finck
3359c2c66affSColin Finck static const IInitializeSpyVtbl testinitializevtbl =
3360c2c66affSColin Finck {
3361c2c66affSColin Finck testinitialize_QI,
3362c2c66affSColin Finck testinitialize_AddRef,
3363c2c66affSColin Finck testinitialize_Release,
3364c2c66affSColin Finck testinitialize_PreInitialize,
3365c2c66affSColin Finck testinitialize_PostInitialize,
3366c2c66affSColin Finck testinitialize_PreUninitialize,
3367c2c66affSColin Finck testinitialize_PostUninitialize
3368c2c66affSColin Finck };
3369c2c66affSColin Finck
3370c2c66affSColin Finck static IInitializeSpy testinitialize = { &testinitializevtbl };
3371c2c66affSColin Finck
test_init_spies_proc(void * arg)3372fc6e4ed5SAmine Khaldi static DWORD WINAPI test_init_spies_proc(void *arg)
3373c2c66affSColin Finck {
3374c2c66affSColin Finck HRESULT hr;
3375c2c66affSColin Finck
3376fc6e4ed5SAmine Khaldi hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
3377fc6e4ed5SAmine Khaldi ok(hr == S_OK, "Failed to initialize COM, hr %#x.\n", hr);
3378fc6e4ed5SAmine Khaldi
3379fc6e4ed5SAmine Khaldi hr = CoRevokeInitializeSpy(init_cookies[2]);
3380fc6e4ed5SAmine Khaldi ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3381fc6e4ed5SAmine Khaldi
3382fc6e4ed5SAmine Khaldi CoUninitialize();
3383fc6e4ed5SAmine Khaldi return 0;
3384fc6e4ed5SAmine Khaldi }
3385fc6e4ed5SAmine Khaldi
test_IInitializeSpy(BOOL mt)3386fc6e4ed5SAmine Khaldi static void test_IInitializeSpy(BOOL mt)
3387fc6e4ed5SAmine Khaldi {
3388fc6e4ed5SAmine Khaldi HRESULT hr;
3389fc6e4ed5SAmine Khaldi
3390fc6e4ed5SAmine Khaldi if (mt)
3391fc6e4ed5SAmine Khaldi {
3392fc6e4ed5SAmine Khaldi hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED);
3393fc6e4ed5SAmine Khaldi ok(hr == S_OK, "CoInitializeEx failed: %#x\n", hr);
3394fc6e4ed5SAmine Khaldi }
3395fc6e4ed5SAmine Khaldi
3396c2c66affSColin Finck hr = CoRegisterInitializeSpy(NULL, NULL);
3397c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3398c2c66affSColin Finck
3399fc6e4ed5SAmine Khaldi init_cookies[0].QuadPart = 1;
3400fc6e4ed5SAmine Khaldi hr = CoRegisterInitializeSpy(NULL, &init_cookies[0]);
3401c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3402fc6e4ed5SAmine Khaldi ok(init_cookies[0].QuadPart == 1, "got wrong cookie\n");
3403c2c66affSColin Finck
3404c2c66affSColin Finck hr = CoRegisterInitializeSpy(&testinitialize, NULL);
3405c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3406c2c66affSColin Finck
3407fc6e4ed5SAmine Khaldi init_cookies[0].HighPart = 0;
3408fc6e4ed5SAmine Khaldi init_cookies[0].LowPart = 1;
3409fc6e4ed5SAmine Khaldi hr = CoRegisterInitializeSpy(&testinitialize, &init_cookies[0]);
3410c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3411fc6e4ed5SAmine Khaldi ok(init_cookies[0].HighPart == GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", init_cookies[0].HighPart,
3412c2c66affSColin Finck GetCurrentThreadId());
3413fc6e4ed5SAmine Khaldi if (!mt) ok(init_cookies[0].LowPart == 0, "got wrong low part 0x%x\n", init_cookies[0].LowPart);
3414fc6e4ed5SAmine Khaldi
3415c2c66affSColin Finck /* register same instance one more time */
3416fc6e4ed5SAmine Khaldi init_cookies[1].HighPart = 0;
3417fc6e4ed5SAmine Khaldi init_cookies[1].LowPart = 0;
3418fc6e4ed5SAmine Khaldi hr = CoRegisterInitializeSpy(&testinitialize, &init_cookies[1]);
3419c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3420fc6e4ed5SAmine Khaldi ok(init_cookies[1].HighPart == GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", init_cookies[1].HighPart,
3421c2c66affSColin Finck GetCurrentThreadId());
3422fc6e4ed5SAmine Khaldi if (!mt) ok(init_cookies[1].LowPart == 1, "got wrong low part 0x%x\n", init_cookies[1].LowPart);
3423fc6e4ed5SAmine Khaldi
3424fc6e4ed5SAmine Khaldi init_cookies[2].HighPart = 0;
3425fc6e4ed5SAmine Khaldi init_cookies[2].LowPart = 0;
3426fc6e4ed5SAmine Khaldi hr = CoRegisterInitializeSpy(&testinitialize, &init_cookies[2]);
3427c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3428fc6e4ed5SAmine Khaldi ok(init_cookies[2].HighPart == GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", init_cookies[2].HighPart,
3429c2c66affSColin Finck GetCurrentThreadId());
3430fc6e4ed5SAmine Khaldi if (!mt) ok(init_cookies[2].LowPart == 2, "got wrong low part 0x%x\n", init_cookies[2].LowPart);
3431fc6e4ed5SAmine Khaldi
3432fc6e4ed5SAmine Khaldi hr = CoRevokeInitializeSpy(init_cookies[1]);
3433c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3434c2c66affSColin Finck
3435fc6e4ed5SAmine Khaldi hr = CoRevokeInitializeSpy(init_cookies[1]);
3436c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3437c2c66affSColin Finck
3438fc6e4ed5SAmine Khaldi init_cookies[1].HighPart = 0;
3439fc6e4ed5SAmine Khaldi init_cookies[1].LowPart = 0;
3440fc6e4ed5SAmine Khaldi hr = CoRegisterInitializeSpy(&testinitialize, &init_cookies[1]);
3441c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3442fc6e4ed5SAmine Khaldi ok(init_cookies[1].HighPart == GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", init_cookies[1].HighPart,
3443c2c66affSColin Finck GetCurrentThreadId());
3444fc6e4ed5SAmine Khaldi if (!mt) ok(init_cookies[1].LowPart == 1, "got wrong low part 0x%x\n", init_cookies[1].LowPart);
3445fc6e4ed5SAmine Khaldi
3446fc6e4ed5SAmine Khaldi SET_EXPECT(PreInitialize);
3447fc6e4ed5SAmine Khaldi SET_EXPECT(PostInitialize);
3448fc6e4ed5SAmine Khaldi hr = CoInitializeEx(NULL, expected_coinit_flags = ((mt ? COINIT_MULTITHREADED : COINIT_APARTMENTTHREADED) | COINIT_DISABLE_OLE1DDE));
3449fc6e4ed5SAmine Khaldi ok(hr == (mt ? S_FALSE : S_OK), "Failed to initialize COM, hr %#x.\n", hr);
3450fc6e4ed5SAmine Khaldi CHECK_CALLED(PreInitialize, 3);
3451fc6e4ed5SAmine Khaldi CHECK_CALLED(PostInitialize, 3);
3452fc6e4ed5SAmine Khaldi
3453fc6e4ed5SAmine Khaldi if (mt)
3454fc6e4ed5SAmine Khaldi {
3455fc6e4ed5SAmine Khaldi HANDLE thread;
3456fc6e4ed5SAmine Khaldi thread = CreateThread(NULL, 0, test_init_spies_proc, NULL, 0, NULL);
3457fc6e4ed5SAmine Khaldi ok(thread != NULL, "CreateThread failed: %u\n", GetLastError());
3458fc6e4ed5SAmine Khaldi ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
3459c2c66affSColin Finck }
3460c2c66affSColin Finck
3461fc6e4ed5SAmine Khaldi SET_EXPECT(PreInitialize);
3462fc6e4ed5SAmine Khaldi SET_EXPECT(PostInitialize);
3463fc6e4ed5SAmine Khaldi hr = CoInitializeEx(NULL, expected_coinit_flags = ((mt ? COINIT_MULTITHREADED : COINIT_APARTMENTTHREADED) | COINIT_DISABLE_OLE1DDE));
3464fc6e4ed5SAmine Khaldi ok(hr == S_FALSE, "Failed to initialize COM, hr %#x.\n", hr);
3465fc6e4ed5SAmine Khaldi CHECK_CALLED(PreInitialize, 3);
3466fc6e4ed5SAmine Khaldi CHECK_CALLED(PostInitialize, 3);
3467c2c66affSColin Finck
3468fc6e4ed5SAmine Khaldi SET_EXPECT(PreUninitialize);
3469fc6e4ed5SAmine Khaldi SET_EXPECT(PostUninitialize);
3470fc6e4ed5SAmine Khaldi CoUninitialize();
3471fc6e4ed5SAmine Khaldi CHECK_CALLED(PreUninitialize, 3);
3472fc6e4ed5SAmine Khaldi CHECK_CALLED(PostUninitialize, 3);
3473fc6e4ed5SAmine Khaldi
3474fc6e4ed5SAmine Khaldi SET_EXPECT(PreUninitialize);
3475fc6e4ed5SAmine Khaldi SET_EXPECT(PostUninitialize);
3476fc6e4ed5SAmine Khaldi CoUninitialize();
3477fc6e4ed5SAmine Khaldi CHECK_CALLED(PreUninitialize, 3);
3478fc6e4ed5SAmine Khaldi CHECK_CALLED(PostUninitialize, 3);
3479fc6e4ed5SAmine Khaldi
3480fc6e4ed5SAmine Khaldi if (mt)
3481fc6e4ed5SAmine Khaldi {
3482fc6e4ed5SAmine Khaldi SET_EXPECT(PreUninitialize);
3483fc6e4ed5SAmine Khaldi SET_EXPECT(PostUninitialize);
3484fc6e4ed5SAmine Khaldi CoUninitialize();
3485fc6e4ed5SAmine Khaldi CHECK_CALLED(PreUninitialize, 3);
3486fc6e4ed5SAmine Khaldi CHECK_CALLED(PostUninitialize, 3);
3487fc6e4ed5SAmine Khaldi }
3488fc6e4ed5SAmine Khaldi
3489fc6e4ed5SAmine Khaldi SET_EXPECT(PreInitialize);
3490fc6e4ed5SAmine Khaldi SET_EXPECT(PostInitialize);
3491fc6e4ed5SAmine Khaldi hr = CoInitializeEx(NULL, expected_coinit_flags = ((mt ? COINIT_MULTITHREADED : COINIT_APARTMENTTHREADED) | COINIT_DISABLE_OLE1DDE));
3492fc6e4ed5SAmine Khaldi ok(hr == S_OK, "Failed to initialize COM, hr %#x.\n", hr);
3493fc6e4ed5SAmine Khaldi CHECK_CALLED(PreInitialize, 3);
3494fc6e4ed5SAmine Khaldi CHECK_CALLED(PostInitialize, 3);
3495fc6e4ed5SAmine Khaldi
3496fc6e4ed5SAmine Khaldi SET_EXPECT(PreUninitialize);
3497fc6e4ed5SAmine Khaldi revoke_spies_on_uninit = TRUE;
3498fc6e4ed5SAmine Khaldi CoUninitialize();
3499fc6e4ed5SAmine Khaldi CHECK_CALLED(PreUninitialize, 1);
3500c2c66affSColin Finck }
3501c2c66affSColin Finck
3502c2c66affSColin Finck static HRESULT g_persistfile_qi_ret;
3503c2c66affSColin Finck static HRESULT g_persistfile_load_ret;
testinstance_QI(IPersistFile * iface,REFIID riid,void ** obj)3504c2c66affSColin Finck static HRESULT WINAPI testinstance_QI(IPersistFile *iface, REFIID riid, void **obj)
3505c2c66affSColin Finck {
3506c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown)) {
3507c2c66affSColin Finck *obj = iface;
3508c2c66affSColin Finck IUnknown_AddRef(iface);
3509c2c66affSColin Finck return S_OK;
3510c2c66affSColin Finck }
3511c2c66affSColin Finck
3512c2c66affSColin Finck if (IsEqualIID(riid, &IID_IPersistFile)) {
3513c2c66affSColin Finck if (SUCCEEDED(g_persistfile_qi_ret)) {
3514c2c66affSColin Finck *obj = iface;
3515c2c66affSColin Finck IUnknown_AddRef(iface);
3516c2c66affSColin Finck }
3517c2c66affSColin Finck else
3518c2c66affSColin Finck *obj = NULL;
3519c2c66affSColin Finck return g_persistfile_qi_ret;
3520c2c66affSColin Finck }
3521c2c66affSColin Finck
3522c2c66affSColin Finck ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
3523c2c66affSColin Finck *obj = NULL;
3524c2c66affSColin Finck return E_NOINTERFACE;
3525c2c66affSColin Finck }
3526c2c66affSColin Finck
testinstance_AddRef(IPersistFile * iface)3527c2c66affSColin Finck static ULONG WINAPI testinstance_AddRef(IPersistFile *iface)
3528c2c66affSColin Finck {
3529c2c66affSColin Finck return 2;
3530c2c66affSColin Finck }
3531c2c66affSColin Finck
testinstance_Release(IPersistFile * iface)3532c2c66affSColin Finck static ULONG WINAPI testinstance_Release(IPersistFile *iface)
3533c2c66affSColin Finck {
3534c2c66affSColin Finck return 1;
3535c2c66affSColin Finck }
3536c2c66affSColin Finck
testinstance_GetClassID(IPersistFile * iface,CLSID * clsid)3537c2c66affSColin Finck static HRESULT WINAPI testinstance_GetClassID(IPersistFile *iface, CLSID *clsid)
3538c2c66affSColin Finck {
3539c2c66affSColin Finck ok(0, "unexpected call\n");
3540c2c66affSColin Finck return E_NOTIMPL;
3541c2c66affSColin Finck }
3542c2c66affSColin Finck
testinstance_IsDirty(IPersistFile * iface)3543c2c66affSColin Finck static HRESULT WINAPI testinstance_IsDirty(IPersistFile *iface)
3544c2c66affSColin Finck {
3545c2c66affSColin Finck ok(0, "unexpected call\n");
3546c2c66affSColin Finck return E_NOTIMPL;
3547c2c66affSColin Finck }
3548c2c66affSColin Finck
testinstance_Load(IPersistFile * iface,LPCOLESTR filename,DWORD mode)3549c2c66affSColin Finck static HRESULT WINAPI testinstance_Load(IPersistFile *iface, LPCOLESTR filename, DWORD mode)
3550c2c66affSColin Finck {
3551c2c66affSColin Finck return g_persistfile_load_ret;
3552c2c66affSColin Finck }
3553c2c66affSColin Finck
testinstance_Save(IPersistFile * iface,LPCOLESTR filename,BOOL remember)3554c2c66affSColin Finck static HRESULT WINAPI testinstance_Save(IPersistFile *iface, LPCOLESTR filename, BOOL remember)
3555c2c66affSColin Finck {
3556c2c66affSColin Finck return E_NOTIMPL;
3557c2c66affSColin Finck }
3558c2c66affSColin Finck
testinstance_SaveCompleted(IPersistFile * iface,LPCOLESTR filename)3559c2c66affSColin Finck static HRESULT WINAPI testinstance_SaveCompleted(IPersistFile *iface, LPCOLESTR filename)
3560c2c66affSColin Finck {
3561c2c66affSColin Finck ok(0, "unexpected call\n");
3562c2c66affSColin Finck return E_NOTIMPL;
3563c2c66affSColin Finck }
3564c2c66affSColin Finck
testinstance_GetCurFile(IPersistFile * iface,LPOLESTR * filename)3565c2c66affSColin Finck static HRESULT WINAPI testinstance_GetCurFile(IPersistFile *iface, LPOLESTR *filename)
3566c2c66affSColin Finck {
3567c2c66affSColin Finck ok(0, "unexpected call\n");
3568c2c66affSColin Finck return E_NOTIMPL;
3569c2c66affSColin Finck }
3570c2c66affSColin Finck
3571c2c66affSColin Finck static const IPersistFileVtbl testpersistfilevtbl = {
3572c2c66affSColin Finck testinstance_QI,
3573c2c66affSColin Finck testinstance_AddRef,
3574c2c66affSColin Finck testinstance_Release,
3575c2c66affSColin Finck testinstance_GetClassID,
3576c2c66affSColin Finck testinstance_IsDirty,
3577c2c66affSColin Finck testinstance_Load,
3578c2c66affSColin Finck testinstance_Save,
3579c2c66affSColin Finck testinstance_SaveCompleted,
3580c2c66affSColin Finck testinstance_GetCurFile
3581c2c66affSColin Finck };
3582c2c66affSColin Finck
3583c2c66affSColin Finck static IPersistFile testpersistfile = { &testpersistfilevtbl };
3584c2c66affSColin Finck
getinstance_cf_QI(IClassFactory * iface,REFIID riid,void ** obj)3585c2c66affSColin Finck static HRESULT WINAPI getinstance_cf_QI(IClassFactory *iface, REFIID riid, void **obj)
3586c2c66affSColin Finck {
3587c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) {
3588c2c66affSColin Finck *obj = iface;
3589c2c66affSColin Finck IClassFactory_AddRef(iface);
3590c2c66affSColin Finck return S_OK;
3591c2c66affSColin Finck }
3592c2c66affSColin Finck
3593c2c66affSColin Finck *obj = NULL;
3594c2c66affSColin Finck return E_NOINTERFACE;
3595c2c66affSColin Finck }
3596c2c66affSColin Finck
getinstance_cf_AddRef(IClassFactory * iface)3597c2c66affSColin Finck static ULONG WINAPI getinstance_cf_AddRef(IClassFactory *iface)
3598c2c66affSColin Finck {
3599c2c66affSColin Finck return 2;
3600c2c66affSColin Finck }
3601c2c66affSColin Finck
getinstance_cf_Release(IClassFactory * iface)3602c2c66affSColin Finck static ULONG WINAPI getinstance_cf_Release(IClassFactory *iface)
3603c2c66affSColin Finck {
3604c2c66affSColin Finck return 1;
3605c2c66affSColin Finck }
3606c2c66affSColin Finck
getinstance_cf_CreateInstance(IClassFactory * iface,IUnknown * outer,REFIID riid,void ** obj)3607c2c66affSColin Finck static HRESULT WINAPI getinstance_cf_CreateInstance(IClassFactory *iface, IUnknown *outer,
3608c2c66affSColin Finck REFIID riid, void **obj)
3609c2c66affSColin Finck {
3610c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown)) {
3611c2c66affSColin Finck *obj = &testpersistfile;
3612c2c66affSColin Finck return S_OK;
3613c2c66affSColin Finck }
3614c2c66affSColin Finck
3615c2c66affSColin Finck ok(0, "unexpected call, riid %s\n", wine_dbgstr_guid(riid));
3616c2c66affSColin Finck *obj = NULL;
3617c2c66affSColin Finck return E_NOTIMPL;
3618c2c66affSColin Finck }
3619c2c66affSColin Finck
getinstance_cf_LockServer(IClassFactory * iface,BOOL lock)3620c2c66affSColin Finck static HRESULT WINAPI getinstance_cf_LockServer(IClassFactory *iface, BOOL lock)
3621c2c66affSColin Finck {
3622c2c66affSColin Finck ok(0, "unexpected call\n");
3623c2c66affSColin Finck return E_NOTIMPL;
3624c2c66affSColin Finck }
3625c2c66affSColin Finck
3626c2c66affSColin Finck static const IClassFactoryVtbl getinstance_cf_vtbl = {
3627c2c66affSColin Finck getinstance_cf_QI,
3628c2c66affSColin Finck getinstance_cf_AddRef,
3629c2c66affSColin Finck getinstance_cf_Release,
3630c2c66affSColin Finck getinstance_cf_CreateInstance,
3631c2c66affSColin Finck getinstance_cf_LockServer
3632c2c66affSColin Finck };
3633c2c66affSColin Finck
3634c2c66affSColin Finck static IClassFactory getinstance_cf = { &getinstance_cf_vtbl };
3635c2c66affSColin Finck
test_CoGetInstanceFromFile(void)3636c2c66affSColin Finck static void test_CoGetInstanceFromFile(void)
3637c2c66affSColin Finck {
3638c2c66affSColin Finck static const WCHAR filenameW[] = {'d','u','m','m','y','p','a','t','h',0};
3639c2c66affSColin Finck CLSID *clsid = (CLSID*)&CLSID_testclsid;
3640c2c66affSColin Finck MULTI_QI mqi[2];
3641c2c66affSColin Finck DWORD cookie;
3642c2c66affSColin Finck HRESULT hr;
3643c2c66affSColin Finck
3644c2c66affSColin Finck hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
3645c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3646c2c66affSColin Finck
3647c2c66affSColin Finck /* CLSID is not specified, file does not exist */
3648c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3649c2c66affSColin Finck mqi[0].pItf = NULL;
3650c2c66affSColin Finck mqi[0].hr = E_NOTIMPL;
3651c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, NULL, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
3652c2c66affSColin Finck todo_wine
3653c2c66affSColin Finck ok(hr == MK_E_CANTOPENFILE, "got 0x%08x\n", hr);
3654c2c66affSColin Finck ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf);
3655c2c66affSColin Finck ok(mqi[0].hr == E_NOINTERFACE, "got 0x%08x\n", mqi[0].hr);
3656c2c66affSColin Finck
3657c2c66affSColin Finck /* class is not available */
3658c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3659c2c66affSColin Finck mqi[0].pItf = NULL;
3660c2c66affSColin Finck mqi[0].hr = E_NOTIMPL;
3661c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
3662c2c66affSColin Finck ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
3663c2c66affSColin Finck ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf);
3664c2c66affSColin Finck ok(mqi[0].hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", mqi[0].hr);
3665c2c66affSColin Finck
3666c2c66affSColin Finck hr = CoRegisterClassObject(clsid, (IUnknown*)&getinstance_cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE,
3667c2c66affSColin Finck &cookie);
3668c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3669c2c66affSColin Finck
3670c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3671c2c66affSColin Finck mqi[0].pItf = (void*)0xdeadbeef;
3672c2c66affSColin Finck mqi[0].hr = S_OK;
3673c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
3674c2c66affSColin Finck todo_wine {
3675c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3676c2c66affSColin Finck ok(mqi[0].pItf == (void*)0xdeadbeef, "got %p\n", mqi[0].pItf);
3677c2c66affSColin Finck }
3678c2c66affSColin Finck ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr);
3679c2c66affSColin Finck
3680c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3681c2c66affSColin Finck mqi[0].pItf = (void*)0xdeadbeef;
3682c2c66affSColin Finck mqi[0].hr = E_NOTIMPL;
3683c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
3684c2c66affSColin Finck todo_wine {
3685c2c66affSColin Finck ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3686c2c66affSColin Finck ok(mqi[0].pItf == (void*)0xdeadbeef, "got %p\n", mqi[0].pItf);
3687c2c66affSColin Finck ok(mqi[0].hr == E_NOTIMPL, "got 0x%08x\n", mqi[0].hr);
3688c2c66affSColin Finck }
3689c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3690c2c66affSColin Finck mqi[0].pItf = NULL;
3691c2c66affSColin Finck mqi[0].hr = E_NOTIMPL;
3692c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
3693c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3694c2c66affSColin Finck ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf);
3695c2c66affSColin Finck ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr);
3696c2c66affSColin Finck
3697c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3698c2c66affSColin Finck mqi[0].pItf = NULL;
3699c2c66affSColin Finck mqi[0].hr = S_OK;
3700c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
3701c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3702c2c66affSColin Finck ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf);
3703c2c66affSColin Finck ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr);
3704c2c66affSColin Finck
3705c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3706c2c66affSColin Finck mqi[0].pItf = NULL;
3707c2c66affSColin Finck mqi[0].hr = S_OK;
3708c2c66affSColin Finck g_persistfile_qi_ret = S_FALSE;
3709c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
3710c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3711c2c66affSColin Finck ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf);
3712c2c66affSColin Finck ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr);
3713c2c66affSColin Finck g_persistfile_qi_ret = S_OK;
3714c2c66affSColin Finck
3715c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3716c2c66affSColin Finck mqi[0].pItf = NULL;
3717c2c66affSColin Finck mqi[0].hr = S_OK;
3718c2c66affSColin Finck mqi[1].pIID = &IID_IUnknown;
3719c2c66affSColin Finck mqi[1].pItf = NULL;
3720c2c66affSColin Finck mqi[1].hr = S_OK;
3721c2c66affSColin Finck g_persistfile_qi_ret = 0x8000efef;
3722c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 2, mqi);
3723c2c66affSColin Finck ok(hr == 0x8000efef, "got 0x%08x\n", hr);
3724c2c66affSColin Finck ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf);
3725c2c66affSColin Finck ok(mqi[0].hr == 0x8000efef, "got 0x%08x\n", mqi[0].hr);
3726c2c66affSColin Finck ok(mqi[1].pItf == NULL, "got %p\n", mqi[1].pItf);
3727c2c66affSColin Finck ok(mqi[1].hr == 0x8000efef, "got 0x%08x\n", mqi[1].hr);
3728c2c66affSColin Finck g_persistfile_qi_ret = S_OK;
3729c2c66affSColin Finck
3730c2c66affSColin Finck mqi[0].pIID = &IID_IUnknown;
3731c2c66affSColin Finck mqi[0].pItf = NULL;
3732c2c66affSColin Finck mqi[0].hr = S_OK;
3733c2c66affSColin Finck mqi[1].pIID = &IID_IUnknown;
3734c2c66affSColin Finck mqi[1].pItf = NULL;
3735c2c66affSColin Finck mqi[1].hr = S_OK;
3736c2c66affSColin Finck g_persistfile_load_ret = 0x8000fefe;
3737c2c66affSColin Finck hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 2, mqi);
3738c2c66affSColin Finck ok(hr == 0x8000fefe, "got 0x%08x\n", hr);
3739c2c66affSColin Finck ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf);
3740c2c66affSColin Finck ok(mqi[0].hr == 0x8000fefe, "got 0x%08x\n", mqi[0].hr);
3741c2c66affSColin Finck ok(mqi[1].pItf == NULL, "got %p\n", mqi[1].pItf);
3742c2c66affSColin Finck ok(mqi[1].hr == 0x8000fefe, "got 0x%08x\n", mqi[1].hr);
3743c2c66affSColin Finck g_persistfile_load_ret = S_OK;
3744c2c66affSColin Finck
3745c2c66affSColin Finck hr = CoRevokeClassObject(cookie);
3746c2c66affSColin Finck ok(hr == S_OK, "got 0x%08x\n", hr);
3747c2c66affSColin Finck
3748c2c66affSColin Finck CoUninitialize();
3749c2c66affSColin Finck }
3750c2c66affSColin Finck
test_GlobalOptions(void)3751c2c66affSColin Finck static void test_GlobalOptions(void)
3752c2c66affSColin Finck {
3753c2c66affSColin Finck IGlobalOptions *global_options;
3754c2c66affSColin Finck HRESULT hres;
3755c2c66affSColin Finck
3756c2c66affSColin Finck CoInitialize(NULL);
3757c2c66affSColin Finck
3758c2c66affSColin Finck hres = CoCreateInstance(&CLSID_GlobalOptions, NULL, CLSCTX_INPROC_SERVER,
3759c2c66affSColin Finck &IID_IGlobalOptions, (void**)&global_options);
3760c2c66affSColin Finck ok(hres == S_OK || broken(hres == E_NOINTERFACE), "CoCreateInstance(CLSID_GlobalOptions) failed: %08x\n", hres);
3761c2c66affSColin Finck if(FAILED(hres))
3762c2c66affSColin Finck {
3763c2c66affSColin Finck win_skip("CLSID_GlobalOptions not available\n");
3764c2c66affSColin Finck CoUninitialize();
3765c2c66affSColin Finck return;
3766c2c66affSColin Finck }
3767c2c66affSColin Finck
3768c2c66affSColin Finck IGlobalOptions_Release(global_options);
3769c2c66affSColin Finck
3770c2c66affSColin Finck hres = CoCreateInstance(&CLSID_GlobalOptions, (IUnknown*)0xdeadbeef, CLSCTX_INPROC_SERVER,
3771c2c66affSColin Finck &IID_IGlobalOptions, (void**)&global_options);
3772c2c66affSColin Finck ok(hres == E_INVALIDARG, "CoCreateInstance(CLSID_GlobalOptions) failed: %08x\n", hres);
3773c2c66affSColin Finck
3774c2c66affSColin Finck CoUninitialize();
3775c2c66affSColin Finck }
3776c2c66affSColin Finck
init_funcs(void)3777c2c66affSColin Finck static void init_funcs(void)
3778c2c66affSColin Finck {
3779c2c66affSColin Finck HMODULE hOle32 = GetModuleHandleA("ole32");
3780c2c66affSColin Finck HMODULE hAdvapi32 = GetModuleHandleA("advapi32");
3781c2c66affSColin Finck HMODULE hkernel32 = GetModuleHandleA("kernel32");
3782c2c66affSColin Finck
3783c2c66affSColin Finck pCoGetObjectContext = (void*)GetProcAddress(hOle32, "CoGetObjectContext");
3784c2c66affSColin Finck pCoSwitchCallContext = (void*)GetProcAddress(hOle32, "CoSwitchCallContext");
3785c2c66affSColin Finck pCoGetTreatAsClass = (void*)GetProcAddress(hOle32,"CoGetTreatAsClass");
3786c2c66affSColin Finck pCoTreatAsClass = (void*)GetProcAddress(hOle32,"CoTreatAsClass");
3787c2c66affSColin Finck pCoGetContextToken = (void*)GetProcAddress(hOle32, "CoGetContextToken");
3788c2c66affSColin Finck pCoGetApartmentType = (void*)GetProcAddress(hOle32, "CoGetApartmentType");
3789c2c66affSColin Finck pRegDeleteKeyExA = (void*)GetProcAddress(hAdvapi32, "RegDeleteKeyExA");
3790c2c66affSColin Finck pRegOverridePredefKey = (void*)GetProcAddress(hAdvapi32, "RegOverridePredefKey");
3791c2c66affSColin Finck pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx");
3792c2c66affSColin Finck
3793c2c66affSColin Finck pActivateActCtx = (void*)GetProcAddress(hkernel32, "ActivateActCtx");
3794c2c66affSColin Finck pCreateActCtxW = (void*)GetProcAddress(hkernel32, "CreateActCtxW");
3795c2c66affSColin Finck pDeactivateActCtx = (void*)GetProcAddress(hkernel32, "DeactivateActCtx");
3796c2c66affSColin Finck pIsWow64Process = (void*)GetProcAddress(hkernel32, "IsWow64Process");
3797c2c66affSColin Finck pReleaseActCtx = (void*)GetProcAddress(hkernel32, "ReleaseActCtx");
3798c2c66affSColin Finck }
3799c2c66affSColin Finck
implicit_mta_proc(void * param)3800a6cdf4ffSAmine Khaldi static DWORD CALLBACK implicit_mta_proc(void *param)
3801a6cdf4ffSAmine Khaldi {
3802a6cdf4ffSAmine Khaldi IComThreadingInfo *threading_info;
3803a6cdf4ffSAmine Khaldi ULONG_PTR token;
3804a6cdf4ffSAmine Khaldi IUnknown *unk;
3805a6cdf4ffSAmine Khaldi DWORD cookie;
3806a6cdf4ffSAmine Khaldi CLSID clsid;
3807a6cdf4ffSAmine Khaldi HRESULT hr;
3808a6cdf4ffSAmine Khaldi
3809a6cdf4ffSAmine Khaldi test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA);
3810a6cdf4ffSAmine Khaldi
3811a6cdf4ffSAmine Khaldi hr = CoCreateInstance(&CLSID_InternetZoneManager, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
3812a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoCreateInstance");
3813a6cdf4ffSAmine Khaldi IUnknown_Release(unk);
3814a6cdf4ffSAmine Khaldi
3815a6cdf4ffSAmine Khaldi hr = CoGetClassObject(&CLSID_InternetZoneManager, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&unk);
3816a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoGetClassObject");
3817a6cdf4ffSAmine Khaldi IUnknown_Release(unk);
3818a6cdf4ffSAmine Khaldi
3819a6cdf4ffSAmine Khaldi hr = CoGetObjectContext(&IID_IComThreadingInfo, (void **)&threading_info);
3820a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoGetObjectContext");
3821a6cdf4ffSAmine Khaldi IComThreadingInfo_Release(threading_info);
3822a6cdf4ffSAmine Khaldi
3823a6cdf4ffSAmine Khaldi hr = CoGetContextToken(&token);
3824a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoGetContextToken");
3825a6cdf4ffSAmine Khaldi
3826a6cdf4ffSAmine Khaldi hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
3827a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoRegisterPSClsid");
3828a6cdf4ffSAmine Khaldi
3829a6cdf4ffSAmine Khaldi hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
3830a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoGetPSClsid");
3831a6cdf4ffSAmine Khaldi
3832a6cdf4ffSAmine Khaldi hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
3833a6cdf4ffSAmine Khaldi CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
3834a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoRegisterClassObject");
3835a6cdf4ffSAmine Khaldi
3836a6cdf4ffSAmine Khaldi hr = CoRevokeClassObject(cookie);
3837a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoRevokeClassObject");
3838a6cdf4ffSAmine Khaldi
3839a6cdf4ffSAmine Khaldi hr = CoRegisterMessageFilter(NULL, NULL);
3840a6cdf4ffSAmine Khaldi ok(hr == CO_E_NOT_SUPPORTED, "got %#x\n", hr);
3841a6cdf4ffSAmine Khaldi
3842fc6e4ed5SAmine Khaldi hr = CoLockObjectExternal(&Test_Unknown, TRUE, TRUE);
3843a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoLockObjectExternal");
3844a6cdf4ffSAmine Khaldi
3845fc6e4ed5SAmine Khaldi hr = CoDisconnectObject(&Test_Unknown, 0);
3846a6cdf4ffSAmine Khaldi ok_ole_success(hr, "CoDisconnectObject");
3847a6cdf4ffSAmine Khaldi
3848a6cdf4ffSAmine Khaldi return 0;
3849a6cdf4ffSAmine Khaldi }
3850a6cdf4ffSAmine Khaldi
3851a6cdf4ffSAmine Khaldi /* Some COM functions (perhaps even all of them?) can make use of an "implicit"
3852a6cdf4ffSAmine Khaldi * multi-threaded apartment created by another thread in the same process. */
test_implicit_mta(void)3853a6cdf4ffSAmine Khaldi static void test_implicit_mta(void)
3854a6cdf4ffSAmine Khaldi {
3855a6cdf4ffSAmine Khaldi HANDLE thread;
3856a6cdf4ffSAmine Khaldi
3857a6cdf4ffSAmine Khaldi CoInitializeEx(NULL, COINIT_MULTITHREADED);
3858a6cdf4ffSAmine Khaldi
3859a6cdf4ffSAmine Khaldi thread = CreateThread(NULL, 0, implicit_mta_proc, NULL, 0, NULL);
3860a6cdf4ffSAmine Khaldi ok(!WaitForSingleObject(thread, 1000), "wait failed\n");
3861a6cdf4ffSAmine Khaldi
3862a6cdf4ffSAmine Khaldi CoUninitialize();
3863a6cdf4ffSAmine Khaldi }
3864a6cdf4ffSAmine Khaldi
START_TEST(compobj)3865c2c66affSColin Finck START_TEST(compobj)
3866c2c66affSColin Finck {
3867c2c66affSColin Finck init_funcs();
3868c2c66affSColin Finck
3869c2c66affSColin Finck if (!pCoInitializeEx)
3870c2c66affSColin Finck {
3871c2c66affSColin Finck trace("You need DCOM95 installed to run this test\n");
3872c2c66affSColin Finck return;
3873c2c66affSColin Finck }
3874c2c66affSColin Finck
3875c2c66affSColin Finck if (!pCreateActCtxW)
3876c2c66affSColin Finck win_skip("Activation contexts are not supported, some tests will be skipped.\n");
3877c2c66affSColin Finck
3878c2c66affSColin Finck test_ProgIDFromCLSID();
3879c2c66affSColin Finck test_CLSIDFromProgID();
3880c2c66affSColin Finck test_CLSIDFromString();
3881c2c66affSColin Finck test_IIDFromString();
3882c2c66affSColin Finck test_StringFromGUID2();
3883c2c66affSColin Finck test_CoCreateInstance();
3884c2c66affSColin Finck test_ole_menu();
3885c2c66affSColin Finck test_CoGetClassObject();
3886c2c66affSColin Finck test_CoCreateInstanceEx();
3887c2c66affSColin Finck test_CoRegisterMessageFilter();
3888c2c66affSColin Finck test_CoRegisterPSClsid();
3889c2c66affSColin Finck test_CoGetPSClsid();
3890c2c66affSColin Finck test_CoUnmarshalInterface();
3891c2c66affSColin Finck test_CoGetInterfaceAndReleaseStream();
3892c2c66affSColin Finck test_CoMarshalInterface();
3893c2c66affSColin Finck test_CoMarshalInterThreadInterfaceInStream();
3894c2c66affSColin Finck test_CoRegisterClassObject();
3895c2c66affSColin Finck test_registered_object_thread_affinity();
3896c2c66affSColin Finck test_CoFreeUnusedLibraries();
3897c2c66affSColin Finck test_CoGetObjectContext();
3898c2c66affSColin Finck test_CoGetCallContext();
3899c2c66affSColin Finck test_CoGetContextToken();
3900c2c66affSColin Finck test_TreatAsClass();
3901c2c66affSColin Finck test_CoInitializeEx();
3902c2c66affSColin Finck test_OleInitialize_InitCounting();
3903c2c66affSColin Finck test_OleRegGetMiscStatus();
3904c2c66affSColin Finck test_CoCreateGuid();
3905c2c66affSColin Finck test_CoWaitForMultipleHandles();
3906c2c66affSColin Finck test_CoGetMalloc();
3907c2c66affSColin Finck test_OleRegGetUserType();
3908c2c66affSColin Finck test_CoGetApartmentType();
3909c2c66affSColin Finck test_IMallocSpy();
3910c2c66affSColin Finck test_CoGetCurrentLogicalThreadId();
3911fc6e4ed5SAmine Khaldi test_IInitializeSpy(FALSE);
3912fc6e4ed5SAmine Khaldi test_IInitializeSpy(TRUE);
3913c2c66affSColin Finck test_CoGetInstanceFromFile();
3914c2c66affSColin Finck test_GlobalOptions();
3915a6cdf4ffSAmine Khaldi test_implicit_mta();
3916c2c66affSColin Finck }
3917