user32: Make GetRegisteredRawInputDevices hotpatchable.
[wine/multimedia.git] / dlls / ole32 / tests / compobj.c
blob1dfa9fb84c2b97a5d6db07062c8204277dba8634
1 /*
2 * Component Object Tests
4 * Copyright 2005 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define CONST_VTABLE
24 #include <stdarg.h>
25 #include <stdio.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #define USE_COM_CONTEXT_DEF
30 #include "initguid.h"
31 #include "objbase.h"
32 #include "shlguid.h"
33 #include "urlmon.h" /* for CLSID_FileProtocol */
35 #include "ctxtcall.h"
37 #include "wine/test.h"
39 /* functions that are not present on all versions of Windows */
40 static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit);
41 static HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv);
42 static HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject);
43 static HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew);
44 static HRESULT (WINAPI * pCoTreatAsClass)(REFCLSID clsidOld, REFCLSID pClsidNew);
45 static HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token);
46 static LONG (WINAPI * pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
47 static LONG (WINAPI * pRegOverridePredefKey)(HKEY key, HKEY override);
49 static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
50 static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
51 static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
52 static BOOL (WINAPI *pIsWow64Process)(HANDLE, LPBOOL);
53 static void (WINAPI *pReleaseActCtx)(HANDLE);
55 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
56 #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
57 #define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
59 static const CLSID CLSID_non_existent = { 0x12345678, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
60 static const CLSID CLSID_StdFont = { 0x0be35203, 0x8f91, 0x11ce, { 0x9d, 0xe3, 0x00, 0xaa, 0x00, 0x4b, 0xb8, 0x51 } };
61 static const GUID IID_Testiface = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
62 static const GUID IID_Testiface2 = { 0x32222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
63 static const GUID IID_Testiface3 = { 0x42222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
64 static const GUID IID_Testiface4 = { 0x52222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
65 static const GUID IID_Testiface5 = { 0x62222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
66 static const GUID IID_Testiface6 = { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
67 static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
69 DEFINE_GUID(CLSID_InProcFreeMarshaler, 0x0000033a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
71 static const WCHAR stdfont[] = {'S','t','d','F','o','n','t',0};
72 static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
73 static const WCHAR wszCLSID_StdFont[] =
75 '{','0','b','e','3','5','2','0','3','-','8','f','9','1','-','1','1','c','e','-',
76 '9','d','e','3','-','0','0','a','a','0','0','4','b','b','8','5','1','}',0
78 static const WCHAR progidW[] = {'P','r','o','g','I','d','.','P','r','o','g','I','d',0};
79 static const WCHAR cf_brokenW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
80 'c','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}','a',0};
82 DEFINE_GUID(IID_IWineTest, 0x5201163f, 0x8164, 0x4fd0, 0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd);
83 DEFINE_GUID(CLSID_WineOOPTest, 0x5201163f, 0x8164, 0x4fd0, 0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd);
85 static LONG cLocks;
87 static void LockModule(void)
89 InterlockedIncrement(&cLocks);
92 static void UnlockModule(void)
94 InterlockedDecrement(&cLocks);
97 static HRESULT WINAPI Test_IClassFactory_QueryInterface(
98 LPCLASSFACTORY iface,
99 REFIID riid,
100 LPVOID *ppvObj)
102 if (ppvObj == NULL) return E_POINTER;
104 if (IsEqualGUID(riid, &IID_IUnknown) ||
105 IsEqualGUID(riid, &IID_IClassFactory))
107 *ppvObj = iface;
108 IClassFactory_AddRef(iface);
109 return S_OK;
112 *ppvObj = NULL;
113 return E_NOINTERFACE;
116 static ULONG WINAPI Test_IClassFactory_AddRef(LPCLASSFACTORY iface)
118 LockModule();
119 return 2; /* non-heap-based object */
122 static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface)
124 UnlockModule();
125 return 1; /* non-heap-based object */
128 static HRESULT WINAPI Test_IClassFactory_CreateInstance(
129 LPCLASSFACTORY iface,
130 IUnknown *pUnkOuter,
131 REFIID riid,
132 LPVOID *ppvObj)
134 *ppvObj = NULL;
135 if (pUnkOuter) return CLASS_E_NOAGGREGATION;
136 return E_NOINTERFACE;
139 static HRESULT WINAPI Test_IClassFactory_LockServer(
140 LPCLASSFACTORY iface,
141 BOOL fLock)
143 return S_OK;
146 static const IClassFactoryVtbl TestClassFactory_Vtbl =
148 Test_IClassFactory_QueryInterface,
149 Test_IClassFactory_AddRef,
150 Test_IClassFactory_Release,
151 Test_IClassFactory_CreateInstance,
152 Test_IClassFactory_LockServer
155 static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl };
157 static WCHAR manifest_path[MAX_PATH];
159 static BOOL create_manifest_file(const char *filename, const char *manifest)
161 int manifest_len;
162 DWORD size;
163 HANDLE file;
164 WCHAR path[MAX_PATH];
166 MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
167 GetFullPathNameW(path, sizeof(manifest_path)/sizeof(WCHAR), manifest_path, NULL);
169 manifest_len = strlen(manifest);
170 file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
171 FILE_ATTRIBUTE_NORMAL, NULL);
172 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
173 if(file == INVALID_HANDLE_VALUE)
174 return FALSE;
175 WriteFile(file, manifest, manifest_len, &size, NULL);
176 CloseHandle(file);
178 return TRUE;
181 static HANDLE activate_context(const char *manifest, ULONG_PTR *cookie)
183 WCHAR path[MAX_PATH];
184 ACTCTXW actctx;
185 HANDLE handle;
186 BOOL ret;
188 if (!pCreateActCtxW) return NULL;
190 create_manifest_file("file.manifest", manifest);
192 MultiByteToWideChar( CP_ACP, 0, "file.manifest", -1, path, MAX_PATH );
193 memset(&actctx, 0, sizeof(ACTCTXW));
194 actctx.cbSize = sizeof(ACTCTXW);
195 actctx.lpSource = path;
197 handle = pCreateActCtxW(&actctx);
198 ok(handle != INVALID_HANDLE_VALUE || broken(handle == INVALID_HANDLE_VALUE) /* some old XP/2k3 versions */,
199 "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError());
200 if (handle == INVALID_HANDLE_VALUE)
202 win_skip("activation context generation failed, some tests will be skipped\n");
203 handle = NULL;
206 ok(actctx.cbSize == sizeof(ACTCTXW), "actctx.cbSize=%d\n", actctx.cbSize);
207 ok(actctx.dwFlags == 0, "actctx.dwFlags=%d\n", actctx.dwFlags);
208 ok(actctx.lpSource == path, "actctx.lpSource=%p\n", actctx.lpSource);
209 ok(actctx.wProcessorArchitecture == 0, "actctx.wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
210 ok(actctx.wLangId == 0, "actctx.wLangId=%d\n", actctx.wLangId);
211 ok(actctx.lpAssemblyDirectory == NULL, "actctx.lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
212 ok(actctx.lpResourceName == NULL, "actctx.lpResourceName=%p\n", actctx.lpResourceName);
213 ok(actctx.lpApplicationName == NULL, "actctx.lpApplicationName=%p\n", actctx.lpApplicationName);
214 ok(actctx.hModule == NULL, "actctx.hModule=%p\n", actctx.hModule);
216 DeleteFileA("file.manifest");
218 if (handle)
220 ret = pActivateActCtx(handle, cookie);
221 ok(ret, "ActivateActCtx failed: %u\n", GetLastError());
224 return handle;
227 static const char actctx_manifest[] =
228 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
229 "<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\""
230 " publicKeyToken=\"6595b6414666f1df\" />"
231 "<file name=\"testlib.dll\">"
232 " <comClass"
233 " clsid=\"{0000033a-0000-0000-c000-000000000046}\""
234 " progid=\"FTMarshal\""
235 " />"
236 " <comClass"
237 " clsid=\"{5201163f-8164-4fd0-a1a2-5d5a3654d3bd}\""
238 " progid=\"WineOOPTest\""
239 " />"
240 " <comClass description=\"Test com class\""
241 " clsid=\"{12345678-1234-1234-1234-56789abcdef0}\""
242 " progid=\"ProgId.ProgId\""
243 " miscStatusIcon=\"recomposeonresize\""
244 " />"
245 " <comClass clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb851}\""
246 " progid=\"CustomFont\""
247 " miscStatusIcon=\"recomposeonresize\""
248 " miscStatusContent=\"insideout\""
249 " />"
250 " <comClass clsid=\"{0be35203-8f91-11ce-9de3-00aa004bb852}\""
251 " progid=\"StdFont\""
252 " />"
253 " <comClass clsid=\"{62222222-1234-1234-1234-56789abcdef0}\" >"
254 " <progid>ProgId.ProgId.1</progid>"
255 " </comClass>"
256 " <comInterfaceProxyStub "
257 " name=\"Iifaceps\""
258 " iid=\"{22222222-1234-1234-1234-56789abcdef0}\""
259 " proxyStubClsid32=\"{66666666-8888-7777-6666-555555555555}\""
260 " />"
261 "</file>"
262 " <comInterfaceExternalProxyStub "
263 " name=\"Iifaceps2\""
264 " iid=\"{32222222-1234-1234-1234-56789abcdef0}\""
265 " />"
266 " <comInterfaceExternalProxyStub "
267 " name=\"Iifaceps3\""
268 " iid=\"{42222222-1234-1234-1234-56789abcdef0}\""
269 " proxyStubClsid32=\"{66666666-8888-7777-6666-555555555555}\""
270 " />"
271 " <comInterfaceExternalProxyStub "
272 " name=\"Iifaceps4\""
273 " iid=\"{52222222-1234-1234-1234-56789abcdef0}\""
274 " proxyStubClsid32=\"{00000000-0000-0000-0000-000000000000}\""
275 " />"
276 " <clrClass "
277 " clsid=\"{72222222-1234-1234-1234-56789abcdef0}\""
278 " name=\"clrclass\""
279 " >"
280 " <progid>clrprogid.1</progid>"
281 " </clrClass>"
282 "</assembly>";
284 DEFINE_GUID(CLSID_Testclass, 0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0);
286 static void test_ProgIDFromCLSID(void)
288 ULONG_PTR cookie = 0;
289 LPWSTR progid;
290 HANDLE handle;
291 HRESULT hr;
293 hr = ProgIDFromCLSID(&CLSID_StdFont, &progid);
294 ok(hr == S_OK, "ProgIDFromCLSID failed with error 0x%08x\n", hr);
295 if (hr == S_OK)
297 ok(!lstrcmpiW(progid, stdfont), "Didn't get expected prog ID\n");
298 CoTaskMemFree(progid);
301 progid = (LPWSTR)0xdeadbeef;
302 hr = ProgIDFromCLSID(&CLSID_non_existent, &progid);
303 ok(hr == REGDB_E_CLASSNOTREG, "ProgIDFromCLSID returned %08x\n", hr);
304 ok(progid == NULL, "ProgIDFromCLSID returns with progid %p\n", progid);
306 hr = ProgIDFromCLSID(&CLSID_StdFont, NULL);
307 ok(hr == E_INVALIDARG, "ProgIDFromCLSID should return E_INVALIDARG instead of 0x%08x\n", hr);
309 if ((handle = activate_context(actctx_manifest, &cookie)))
311 static const WCHAR customfontW[] = {'C','u','s','t','o','m','F','o','n','t',0};
313 hr = ProgIDFromCLSID(&CLSID_non_existent, &progid);
314 ok(hr == S_OK, "got 0x%08x\n", hr);
315 ok(!lstrcmpiW(progid, progidW), "got %s\n", wine_dbgstr_w(progid));
316 CoTaskMemFree(progid);
318 /* try something registered and redirected */
319 progid = NULL;
320 hr = ProgIDFromCLSID(&CLSID_StdFont, &progid);
321 ok(hr == S_OK, "got 0x%08x\n", hr);
322 ok(!lstrcmpiW(progid, customfontW), "got wrong progid %s\n", wine_dbgstr_w(progid));
323 CoTaskMemFree(progid);
325 /* classes without default progid, progid list is not used */
326 hr = ProgIDFromCLSID(&IID_Testiface5, &progid);
327 ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
329 hr = ProgIDFromCLSID(&IID_Testiface6, &progid);
330 ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
332 pDeactivateActCtx(0, cookie);
333 pReleaseActCtx(handle);
337 static void test_CLSIDFromProgID(void)
339 ULONG_PTR cookie = 0;
340 HANDLE handle;
341 CLSID clsid;
342 HRESULT hr = CLSIDFromProgID(stdfont, &clsid);
343 ok(hr == S_OK, "CLSIDFromProgID failed with error 0x%08x\n", hr);
344 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
346 hr = CLSIDFromString(stdfont, &clsid);
347 ok_ole_success(hr, "CLSIDFromString");
348 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
350 /* test some failure cases */
352 hr = CLSIDFromProgID(wszNonExistent, NULL);
353 ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr);
355 hr = CLSIDFromProgID(NULL, &clsid);
356 ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08x\n", hr);
358 memset(&clsid, 0xcc, sizeof(clsid));
359 hr = CLSIDFromProgID(wszNonExistent, &clsid);
360 ok(hr == CO_E_CLASSSTRING, "CLSIDFromProgID on nonexistent ProgID should have returned CO_E_CLASSSTRING instead of 0x%08x\n", hr);
361 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "CLSIDFromProgID should have set clsid to all-zeros on failure\n");
363 /* fails without proper context */
364 memset(&clsid, 0xcc, sizeof(clsid));
365 hr = CLSIDFromProgID(progidW, &clsid);
366 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
367 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "wrong clsid\n");
369 if ((handle = activate_context(actctx_manifest, &cookie)))
371 GUID clsid1;
373 memset(&clsid, 0xcc, sizeof(clsid));
374 hr = CLSIDFromProgID(wszNonExistent, &clsid);
375 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
376 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "should have zero CLSID on failure\n");
378 /* CLSIDFromString() doesn't check activation context */
379 hr = CLSIDFromString(progidW, &clsid);
380 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
382 clsid = CLSID_NULL;
383 hr = CLSIDFromProgID(progidW, &clsid);
384 /* it returns generated CLSID here */
385 ok(!IsEqualCLSID(&clsid, &CLSID_non_existent) && !IsEqualCLSID(&clsid, &CLSID_NULL),
386 "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
388 /* duplicate progid present in context - returns generated guid here too */
389 clsid = CLSID_NULL;
390 hr = CLSIDFromProgID(stdfont, &clsid);
391 ok(hr == S_OK, "got 0x%08x\n", hr);
392 clsid1 = CLSID_StdFont;
393 /* that's where it differs from StdFont */
394 clsid1.Data4[7] = 0x52;
395 ok(!IsEqualCLSID(&clsid, &CLSID_StdFont) && !IsEqualCLSID(&clsid, &CLSID_NULL) && !IsEqualCLSID(&clsid, &clsid1),
396 "got %s\n", wine_dbgstr_guid(&clsid));
398 pDeactivateActCtx(0, cookie);
399 pReleaseActCtx(handle);
403 static void test_CLSIDFromString(void)
405 CLSID clsid;
406 WCHAR wszCLSID_Broken[50];
407 UINT i;
409 HRESULT hr = CLSIDFromString(wszCLSID_StdFont, &clsid);
410 ok_ole_success(hr, "CLSIDFromString");
411 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
413 memset(&clsid, 0xab, sizeof(clsid));
414 hr = CLSIDFromString(NULL, &clsid);
415 ok(hr == S_OK, "got 0x%08x\n", hr);
416 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
418 /* string is longer, but starts with a valid CLSID */
419 memset(&clsid, 0, sizeof(clsid));
420 hr = CLSIDFromString(cf_brokenW, &clsid);
421 ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
422 ok(IsEqualCLSID(&clsid, &IID_IClassFactory), "got %s\n", wine_dbgstr_guid(&clsid));
424 lstrcpyW(wszCLSID_Broken, wszCLSID_StdFont);
425 for(i = lstrlenW(wszCLSID_StdFont); i < 49; i++)
426 wszCLSID_Broken[i] = 'A';
427 wszCLSID_Broken[i] = '\0';
429 memset(&clsid, 0, sizeof(CLSID));
430 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
431 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
432 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
434 wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = 'A';
435 memset(&clsid, 0, sizeof(CLSID));
436 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
437 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
438 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
440 wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)] = '\0';
441 memset(&clsid, 0, sizeof(CLSID));
442 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
443 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
444 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
446 wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = '\0';
447 memset(&clsid, 0, sizeof(CLSID));
448 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
449 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
450 ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
452 memset(&clsid, 0xcc, sizeof(CLSID));
453 hr = CLSIDFromString(wszCLSID_Broken+1, &clsid);
454 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
455 ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n");
457 wszCLSID_Broken[9] = '*';
458 memset(&clsid, 0xcc, sizeof(CLSID));
459 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
460 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
461 ok(clsid.Data1 == CLSID_StdFont.Data1, "Got %08x\n", clsid.Data1);
462 ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
464 wszCLSID_Broken[3] = '*';
465 memset(&clsid, 0xcc, sizeof(CLSID));
466 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
467 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
468 ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1);
469 ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
471 wszCLSID_Broken[3] = '\0';
472 memset(&clsid, 0xcc, sizeof(CLSID));
473 hr = CLSIDFromString(wszCLSID_Broken, &clsid);
474 ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr);
475 ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1);
476 ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2);
479 static void test_IIDFromString(void)
481 static const WCHAR cfW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
482 'c','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
483 static const WCHAR brokenW[] = {'{','0','0','0','0','0','0','0','1','-','0','0','0','0','-','0','0','0','0','-',
484 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
485 static const WCHAR broken2W[] = {'{','0','0','0','0','0','0','0','1','=','0','0','0','0','-','0','0','0','0','-',
486 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
487 static const WCHAR broken3W[] = {'b','r','o','k','e','n','0','0','1','=','0','0','0','0','-','0','0','0','0','-',
488 'g','0','0','0','-','0','0','0','0','0','0','0','0','0','0','4','6','}',0};
489 HRESULT hr;
490 IID iid;
492 hr = IIDFromString(wszCLSID_StdFont, &iid);
493 ok(hr == S_OK, "got 0x%08x\n", hr);
494 ok(IsEqualIID(&iid, &CLSID_StdFont), "got iid %s\n", wine_dbgstr_guid(&iid));
496 memset(&iid, 0xab, sizeof(iid));
497 hr = IIDFromString(NULL, &iid);
498 ok(hr == S_OK, "got 0x%08x\n", hr);
499 ok(IsEqualIID(&iid, &CLSID_NULL), "got iid %s\n", wine_dbgstr_guid(&iid));
501 hr = IIDFromString(cfW, &iid);
502 ok(hr == S_OK, "got 0x%08x\n", hr);
503 ok(IsEqualIID(&iid, &IID_IClassFactory), "got iid %s\n", wine_dbgstr_guid(&iid));
505 /* string starts with a valid IID but is longer */
506 memset(&iid, 0xab, sizeof(iid));
507 hr = IIDFromString(cf_brokenW, &iid);
508 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
509 ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
511 /* invalid IID in a valid format */
512 memset(&iid, 0xab, sizeof(iid));
513 hr = IIDFromString(brokenW, &iid);
514 ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
515 ok(iid.Data1 == 0x00000001, "Got %08x\n", iid.Data1);
517 memset(&iid, 0xab, sizeof(iid));
518 hr = IIDFromString(broken2W, &iid);
519 ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
520 ok(iid.Data1 == 0x00000001, "Got %08x\n", iid.Data1);
522 /* format is broken, but string length is okay */
523 memset(&iid, 0xab, sizeof(iid));
524 hr = IIDFromString(broken3W, &iid);
525 ok(hr == CO_E_IIDSTRING, "got 0x%08x\n", hr);
526 ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
528 /* invalid string */
529 memset(&iid, 0xab, sizeof(iid));
530 hr = IIDFromString(wszNonExistent, &iid);
531 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
532 ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
534 /* valid ProgID */
535 memset(&iid, 0xab, sizeof(iid));
536 hr = IIDFromString(stdfont, &iid);
537 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
538 ok(iid.Data1 == 0xabababab, "Got %08x\n", iid.Data1);
541 static void test_StringFromGUID2(void)
543 WCHAR str[50];
544 int len;
546 /* invalid pointer */
547 SetLastError(0xdeadbeef);
548 len = StringFromGUID2(NULL,str,50);
549 ok(len == 0, "len: %d (expected 0)\n", len);
550 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %x\n", GetLastError());
552 /* Test corner cases for buffer size */
553 len = StringFromGUID2(&CLSID_StdFont,str,50);
554 ok(len == 39, "len: %d (expected 39)\n", len);
555 ok(!lstrcmpiW(str, wszCLSID_StdFont),"string wasn't equal for CLSID_StdFont\n");
557 memset(str,0,sizeof str);
558 len = StringFromGUID2(&CLSID_StdFont,str,39);
559 ok(len == 39, "len: %d (expected 39)\n", len);
560 ok(!lstrcmpiW(str, wszCLSID_StdFont),"string wasn't equal for CLSID_StdFont\n");
562 len = StringFromGUID2(&CLSID_StdFont,str,38);
563 ok(len == 0, "len: %d (expected 0)\n", len);
565 len = StringFromGUID2(&CLSID_StdFont,str,30);
566 ok(len == 0, "len: %d (expected 0)\n", len);
569 struct info
571 HANDLE wait, stop;
574 static DWORD CALLBACK ole_initialize_thread(LPVOID pv)
576 HRESULT hr;
577 struct info *info = pv;
579 hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED);
581 SetEvent(info->wait);
582 WaitForSingleObject(info->stop, 10000);
584 CoUninitialize();
585 return hr;
588 static void test_CoCreateInstance(void)
590 HRESULT hr;
591 HANDLE thread;
592 DWORD tid, exitcode;
593 IUnknown *pUnk;
594 struct info info;
595 REFCLSID rclsid = &CLSID_InternetZoneManager;
597 pUnk = (IUnknown *)0xdeadbeef;
598 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
599 ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
600 ok(pUnk == NULL, "CoCreateInstance should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
602 OleInitialize(NULL);
604 /* test errors returned for non-registered clsids */
605 hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
606 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
607 hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pUnk);
608 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered inproc handler should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
609 hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_LOCAL_SERVER, &IID_IUnknown, (void **)&pUnk);
610 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered local server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
611 hr = CoCreateInstance(&CLSID_non_existent, NULL, CLSCTX_REMOTE_SERVER, &IID_IUnknown, (void **)&pUnk);
612 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance for non-registered remote server should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
614 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
615 if(hr == REGDB_E_CLASSNOTREG)
617 skip("IE not installed so can't test CoCreateInstance\n");
618 OleUninitialize();
619 return;
622 ok_ole_success(hr, "CoCreateInstance");
623 if(pUnk) IUnknown_Release(pUnk);
624 OleUninitialize();
626 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
627 ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
629 /* show that COM doesn't have to be initialized for multi-threaded apartments if another
630 thread has already done so */
632 info.wait = CreateEventA(NULL, TRUE, FALSE, NULL);
633 ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
635 info.stop = CreateEventA(NULL, TRUE, FALSE, NULL);
636 ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError());
638 thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid);
639 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
641 ok( !WaitForSingleObject(info.wait, 10000 ), "wait timed out\n" );
643 pUnk = (IUnknown *)0xdeadbeef;
644 hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
645 ok(hr == S_OK, "CoCreateInstance should have returned S_OK instead of 0x%08x\n", hr);
646 if (pUnk) IUnknown_Release(pUnk);
648 SetEvent(info.stop);
649 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
651 GetExitCodeThread(thread, &exitcode);
652 hr = exitcode;
653 ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr);
655 CloseHandle(thread);
656 CloseHandle(info.wait);
657 CloseHandle(info.stop);
660 static void test_CoGetClassObject(void)
662 HRESULT hr;
663 HANDLE thread, handle;
664 DWORD tid, exitcode;
665 ULONG_PTR cookie;
666 IUnknown *pUnk;
667 struct info info;
668 REFCLSID rclsid = &CLSID_InternetZoneManager;
669 HKEY hkey;
670 LONG res;
672 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
673 ok(hr == CO_E_NOTINITIALIZED, "CoGetClassObject should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
674 ok(pUnk == NULL, "CoGetClassObject should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
676 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, NULL);
677 ok(hr == E_INVALIDARG ||
678 broken(hr == CO_E_NOTINITIALIZED), /* win9x */
679 "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08x\n", hr);
681 /* show that COM doesn't have to be initialized for multi-threaded apartments if another
682 thread has already done so */
684 info.wait = CreateEventA(NULL, TRUE, FALSE, NULL);
685 ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
687 info.stop = CreateEventA(NULL, TRUE, FALSE, NULL);
688 ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError());
690 thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid);
691 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
693 ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
695 pUnk = (IUnknown *)0xdeadbeef;
696 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
697 if(hr == REGDB_E_CLASSNOTREG)
698 skip("IE not installed so can't test CoGetClassObject\n");
699 else
701 ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr);
702 if (pUnk) IUnknown_Release(pUnk);
705 SetEvent(info.stop);
706 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
708 GetExitCodeThread(thread, &exitcode);
709 hr = exitcode;
710 ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr);
712 CloseHandle(thread);
713 CloseHandle(info.wait);
714 CloseHandle(info.stop);
716 if (!pRegOverridePredefKey)
718 win_skip("RegOverridePredefKey not available\n");
719 return;
722 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
724 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
725 if (hr == S_OK)
727 IUnknown_Release(pUnk);
729 res = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Classes", 0, NULL, 0,
730 KEY_ALL_ACCESS, NULL, &hkey, NULL);
731 ok(!res, "RegCreateKeyEx returned %d\n", res);
733 res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, hkey);
734 ok(!res, "RegOverridePredefKey returned %d\n", res);
736 hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
737 ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr);
739 res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
740 ok(!res, "RegOverridePredefKey returned %d\n", res);
742 if (hr == S_OK) IUnknown_Release(pUnk);
743 RegCloseKey(hkey);
746 hr = CoGetClassObject(&CLSID_InProcFreeMarshaler, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
747 ok(hr == S_OK, "got 0x%08x\n", hr);
748 IUnknown_Release(pUnk);
750 /* context redefines FreeMarshaler CLSID */
751 if ((handle = activate_context(actctx_manifest, &cookie)))
753 hr = CoGetClassObject(&CLSID_InProcFreeMarshaler, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
754 ok(hr == S_OK, "got 0x%08x\n", hr);
755 IUnknown_Release(pUnk);
757 pDeactivateActCtx(0, cookie);
758 pReleaseActCtx(handle);
761 CoUninitialize();
764 static ATOM register_dummy_class(void)
766 WNDCLASSA wc =
769 DefWindowProcA,
772 GetModuleHandleA(NULL),
773 NULL,
774 LoadCursorA(NULL, (LPSTR)IDC_ARROW),
775 (HBRUSH)(COLOR_BTNFACE+1),
776 NULL,
777 "WineOleTestClass",
780 return RegisterClassA(&wc);
783 static void test_ole_menu(void)
785 HWND hwndFrame;
786 HRESULT hr;
788 hwndFrame = CreateWindowA((LPCSTR)MAKEINTATOM(register_dummy_class()), "Test", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
789 hr = OleSetMenuDescriptor(NULL, hwndFrame, NULL, NULL, NULL);
790 todo_wine ok_ole_success(hr, "OleSetMenuDescriptor");
792 DestroyWindow(hwndFrame);
796 static HRESULT WINAPI MessageFilter_QueryInterface(IMessageFilter *iface, REFIID riid, void ** ppvObj)
798 if (ppvObj == NULL) return E_POINTER;
800 if (IsEqualGUID(riid, &IID_IUnknown) ||
801 IsEqualGUID(riid, &IID_IClassFactory))
803 *ppvObj = iface;
804 IMessageFilter_AddRef(iface);
805 return S_OK;
808 return E_NOINTERFACE;
811 static ULONG WINAPI MessageFilter_AddRef(IMessageFilter *iface)
813 return 2; /* non-heap object */
816 static ULONG WINAPI MessageFilter_Release(IMessageFilter *iface)
818 return 1; /* non-heap object */
821 static DWORD WINAPI MessageFilter_HandleInComingCall(
822 IMessageFilter *iface,
823 DWORD dwCallType,
824 HTASK threadIDCaller,
825 DWORD dwTickCount,
826 LPINTERFACEINFO lpInterfaceInfo)
828 trace("HandleInComingCall\n");
829 return SERVERCALL_ISHANDLED;
832 static DWORD WINAPI MessageFilter_RetryRejectedCall(
833 IMessageFilter *iface,
834 HTASK threadIDCallee,
835 DWORD dwTickCount,
836 DWORD dwRejectType)
838 trace("RetryRejectedCall\n");
839 return 0;
842 static DWORD WINAPI MessageFilter_MessagePending(
843 IMessageFilter *iface,
844 HTASK threadIDCallee,
845 DWORD dwTickCount,
846 DWORD dwPendingType)
848 trace("MessagePending\n");
849 return PENDINGMSG_WAITNOPROCESS;
852 static const IMessageFilterVtbl MessageFilter_Vtbl =
854 MessageFilter_QueryInterface,
855 MessageFilter_AddRef,
856 MessageFilter_Release,
857 MessageFilter_HandleInComingCall,
858 MessageFilter_RetryRejectedCall,
859 MessageFilter_MessagePending
862 static IMessageFilter MessageFilter = { &MessageFilter_Vtbl };
864 static void test_CoRegisterMessageFilter(void)
866 HRESULT hr;
867 IMessageFilter *prev_filter;
869 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
870 ok(hr == CO_E_NOT_SUPPORTED,
871 "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
872 hr);
874 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
875 prev_filter = (IMessageFilter *)0xdeadbeef;
876 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
877 ok(hr == CO_E_NOT_SUPPORTED,
878 "CoRegisterMessageFilter should have failed with CO_E_NOT_SUPPORTED instead of 0x%08x\n",
879 hr);
880 ok(prev_filter == (IMessageFilter *)0xdeadbeef,
881 "prev_filter should have been set to %p\n", prev_filter);
882 CoUninitialize();
884 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
886 hr = CoRegisterMessageFilter(NULL, NULL);
887 ok_ole_success(hr, "CoRegisterMessageFilter");
889 prev_filter = (IMessageFilter *)0xdeadbeef;
890 hr = CoRegisterMessageFilter(NULL, &prev_filter);
891 ok_ole_success(hr, "CoRegisterMessageFilter");
892 ok(prev_filter == NULL, "prev_filter should have been set to NULL instead of %p\n", prev_filter);
894 hr = CoRegisterMessageFilter(&MessageFilter, &prev_filter);
895 ok_ole_success(hr, "CoRegisterMessageFilter");
896 ok(prev_filter == NULL, "prev_filter should have been set to NULL instead of %p\n", prev_filter);
898 hr = CoRegisterMessageFilter(NULL, NULL);
899 ok_ole_success(hr, "CoRegisterMessageFilter");
901 CoUninitialize();
904 static HRESULT WINAPI Test_IUnknown_QueryInterface(
905 IUnknown *iface,
906 REFIID riid,
907 LPVOID *ppvObj)
909 if (ppvObj == NULL) return E_POINTER;
911 if (IsEqualIID(riid, &IID_IUnknown) ||
912 IsEqualIID(riid, &IID_IWineTest))
914 *ppvObj = iface;
915 IUnknown_AddRef(iface);
916 return S_OK;
919 *ppvObj = NULL;
920 return E_NOINTERFACE;
923 static ULONG WINAPI Test_IUnknown_AddRef(IUnknown *iface)
925 return 2; /* non-heap-based object */
928 static ULONG WINAPI Test_IUnknown_Release(IUnknown *iface)
930 return 1; /* non-heap-based object */
933 static const IUnknownVtbl TestUnknown_Vtbl =
935 Test_IUnknown_QueryInterface,
936 Test_IUnknown_AddRef,
937 Test_IUnknown_Release,
940 static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
942 static HRESULT WINAPI PSFactoryBuffer_QueryInterface(
943 IPSFactoryBuffer * This,
944 /* [in] */ REFIID riid,
945 /* [iid_is][out] */ void **ppvObject)
947 if (IsEqualIID(riid, &IID_IUnknown) ||
948 IsEqualIID(riid, &IID_IPSFactoryBuffer))
950 *ppvObject = This;
951 IPSFactoryBuffer_AddRef(This);
952 return S_OK;
954 return E_NOINTERFACE;
957 static ULONG WINAPI PSFactoryBuffer_AddRef(
958 IPSFactoryBuffer * This)
960 return 2;
963 static ULONG WINAPI PSFactoryBuffer_Release(
964 IPSFactoryBuffer * This)
966 return 1;
969 static HRESULT WINAPI PSFactoryBuffer_CreateProxy(
970 IPSFactoryBuffer * This,
971 /* [in] */ IUnknown *pUnkOuter,
972 /* [in] */ REFIID riid,
973 /* [out] */ IRpcProxyBuffer **ppProxy,
974 /* [out] */ void **ppv)
976 return E_NOTIMPL;
979 static HRESULT WINAPI PSFactoryBuffer_CreateStub(
980 IPSFactoryBuffer * This,
981 /* [in] */ REFIID riid,
982 /* [unique][in] */ IUnknown *pUnkServer,
983 /* [out] */ IRpcStubBuffer **ppStub)
985 return E_NOTIMPL;
988 static IPSFactoryBufferVtbl PSFactoryBufferVtbl =
990 PSFactoryBuffer_QueryInterface,
991 PSFactoryBuffer_AddRef,
992 PSFactoryBuffer_Release,
993 PSFactoryBuffer_CreateProxy,
994 PSFactoryBuffer_CreateStub
997 static IPSFactoryBuffer PSFactoryBuffer = { &PSFactoryBufferVtbl };
999 static const CLSID CLSID_WineTestPSFactoryBuffer =
1001 0x52011640,
1002 0x8164,
1003 0x4fd0,
1004 {0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
1005 }; /* 52011640-8164-4fd0-a1a2-5d5a3654d3bd */
1007 static void test_CoRegisterPSClsid(void)
1009 HRESULT hr;
1010 DWORD dwRegistrationKey;
1011 IStream *stream;
1012 CLSID clsid;
1014 hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
1015 ok(hr == CO_E_NOTINITIALIZED, "CoRegisterPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1017 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1019 hr = CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer, (IUnknown *)&PSFactoryBuffer,
1020 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegistrationKey);
1021 ok_ole_success(hr, "CoRegisterClassObject");
1023 hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
1024 ok_ole_success(hr, "CoRegisterPSClsid");
1026 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1027 ok_ole_success(hr, "CreateStreamOnHGlobal");
1029 hr = CoMarshalInterface(stream, &IID_IWineTest, &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1030 ok(hr == E_NOTIMPL, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr);
1031 IStream_Release(stream);
1033 hr = CoRevokeClassObject(dwRegistrationKey);
1034 ok_ole_success(hr, "CoRevokeClassObject");
1036 CoUninitialize();
1038 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1040 hr = CoGetPSClsid(&IID_IWineTest, &clsid);
1041 ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08x\n", hr);
1043 CoUninitialize();
1046 static void test_CoGetPSClsid(void)
1048 ULONG_PTR cookie;
1049 HANDLE handle;
1050 HRESULT hr;
1051 CLSID clsid;
1052 HKEY hkey;
1053 LONG res;
1054 const BOOL is_win64 = (sizeof(void*) != sizeof(int));
1055 BOOL is_wow64 = FALSE;
1057 hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
1058 ok(hr == CO_E_NOTINITIALIZED,
1059 "CoGetPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n",
1060 hr);
1062 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1064 hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
1065 ok_ole_success(hr, "CoGetPSClsid");
1067 hr = CoGetPSClsid(&IID_IWineTest, &clsid);
1068 ok(hr == REGDB_E_IIDNOTREG,
1069 "CoGetPSClsid for random IID returned 0x%08x instead of REGDB_E_IIDNOTREG\n",
1070 hr);
1072 hr = CoGetPSClsid(&IID_IClassFactory, NULL);
1073 ok(hr == E_INVALIDARG,
1074 "CoGetPSClsid for null clsid returned 0x%08x instead of E_INVALIDARG\n",
1075 hr);
1077 if (!pRegOverridePredefKey)
1079 win_skip("RegOverridePredefKey not available\n");
1080 CoUninitialize();
1081 return;
1083 hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
1084 ok_ole_success(hr, "CoGetPSClsid");
1086 res = RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Classes", 0, NULL, 0,
1087 KEY_ALL_ACCESS, NULL, &hkey, NULL);
1088 ok(!res, "RegCreateKeyEx returned %d\n", res);
1090 res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, hkey);
1091 ok(!res, "RegOverridePredefKey returned %d\n", res);
1093 hr = CoGetPSClsid(&IID_IClassFactory, &clsid);
1094 ok_ole_success(hr, "CoGetPSClsid");
1096 res = pRegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
1097 ok(!res, "RegOverridePredefKey returned %d\n", res);
1099 RegCloseKey(hkey);
1101 /* not registered CLSID */
1102 hr = CoGetPSClsid(&IID_Testiface, &clsid);
1103 ok(hr == REGDB_E_IIDNOTREG, "got 0x%08x\n", hr);
1105 if ((handle = activate_context(actctx_manifest, &cookie)))
1107 memset(&clsid, 0, sizeof(clsid));
1108 hr = CoGetPSClsid(&IID_Testiface, &clsid);
1109 ok(hr == S_OK, "got 0x%08x\n", hr);
1110 ok(IsEqualGUID(&clsid, &IID_Testiface), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1112 memset(&clsid, 0, sizeof(clsid));
1113 hr = CoGetPSClsid(&IID_Testiface2, &clsid);
1114 ok(hr == S_OK, "got 0x%08x\n", hr);
1115 ok(IsEqualGUID(&clsid, &IID_Testiface2), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1117 memset(&clsid, 0, sizeof(clsid));
1118 hr = CoGetPSClsid(&IID_Testiface3, &clsid);
1119 ok(hr == S_OK, "got 0x%08x\n", hr);
1120 ok(IsEqualGUID(&clsid, &IID_TestPS), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1122 memset(&clsid, 0xaa, sizeof(clsid));
1123 hr = CoGetPSClsid(&IID_Testiface4, &clsid);
1124 ok(hr == S_OK, "got 0x%08x\n", hr);
1125 ok(IsEqualGUID(&clsid, &GUID_NULL), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1127 /* register same interface and try to get CLSID back */
1128 hr = CoRegisterPSClsid(&IID_Testiface, &IID_Testiface4);
1129 ok(hr == S_OK, "got 0x%08x\n", hr);
1130 memset(&clsid, 0, sizeof(clsid));
1131 hr = CoGetPSClsid(&IID_Testiface, &clsid);
1132 ok(hr == S_OK, "got 0x%08x\n", hr);
1133 ok(IsEqualGUID(&clsid, &IID_Testiface4), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1135 pDeactivateActCtx(0, cookie);
1136 pReleaseActCtx(handle);
1139 if (pRegDeleteKeyExA &&
1140 (is_win64 ||
1141 (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)))
1143 static GUID IID_DeadBeef = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
1144 static const char clsidDeadBeef[] = "{deadbeef-dead-beef-dead-beefdeadbeef}";
1145 static const char clsidA[] = "{66666666-8888-7777-6666-555555555555}";
1146 HKEY hkey_iface, hkey_psclsid;
1147 REGSAM opposite = is_win64 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
1149 hr = CoGetPSClsid(&IID_DeadBeef, &clsid);
1150 ok(hr == REGDB_E_IIDNOTREG, "got 0x%08x\n", hr);
1152 res = RegCreateKeyExA(HKEY_CLASSES_ROOT, "Interface",
1153 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey_iface, NULL);
1154 ok(!res, "RegCreateKeyEx returned %d\n", res);
1155 res = RegCreateKeyExA(hkey_iface, clsidDeadBeef,
1156 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey, NULL);
1157 ok(!res, "RegCreateKeyEx returned %d\n", res);
1158 res = RegCreateKeyExA(hkey, "ProxyStubClsid32",
1159 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey_psclsid, NULL);
1160 res = RegSetValueExA(hkey_psclsid, NULL, 0, REG_SZ, (const BYTE *)clsidA, strlen(clsidA)+1);
1161 ok(!res, "RegSetValueEx returned %d\n", res);
1162 RegCloseKey(hkey_psclsid);
1164 hr = CoGetPSClsid(&IID_DeadBeef, &clsid);
1165 ok_ole_success(hr, "CoGetPSClsid");
1166 ok(IsEqualGUID(&clsid, &IID_TestPS), "got clsid %s\n", wine_dbgstr_guid(&clsid));
1168 res = pRegDeleteKeyExA(hkey, "ProxyStubClsid32", opposite, 0);
1169 ok(!res, "RegDeleteKeyEx returned %d\n", res);
1170 RegCloseKey(hkey);
1171 res = pRegDeleteKeyExA(hkey_iface, clsidDeadBeef, opposite, 0);
1172 ok(!res, "RegDeleteKeyEx returned %d\n", res);
1173 RegCloseKey(hkey_iface);
1176 CoUninitialize();
1179 /* basic test, mainly for invalid arguments. see marshal.c for more */
1180 static void test_CoUnmarshalInterface(void)
1182 IUnknown *pProxy;
1183 IStream *pStream;
1184 HRESULT hr;
1186 hr = CoUnmarshalInterface(NULL, &IID_IUnknown, (void **)&pProxy);
1187 ok(hr == E_INVALIDARG, "CoUnmarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1189 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1190 ok_ole_success(hr, "CreateStreamOnHGlobal");
1192 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
1193 todo_wine
1194 ok(hr == CO_E_NOTINITIALIZED, "CoUnmarshalInterface should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1196 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1198 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
1199 ok(hr == STG_E_READFAULT, "CoUnmarshalInterface should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1201 CoUninitialize();
1203 hr = CoUnmarshalInterface(pStream, &IID_IUnknown, NULL);
1204 ok(hr == E_INVALIDARG, "CoUnmarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1206 IStream_Release(pStream);
1209 static void test_CoGetInterfaceAndReleaseStream(void)
1211 HRESULT hr;
1212 IUnknown *pUnk;
1214 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1216 hr = CoGetInterfaceAndReleaseStream(NULL, &IID_IUnknown, (void**)&pUnk);
1217 ok(hr == E_INVALIDARG, "hr %08x\n", hr);
1219 CoUninitialize();
1222 /* basic test, mainly for invalid arguments. see marshal.c for more */
1223 static void test_CoMarshalInterface(void)
1225 IStream *pStream;
1226 HRESULT hr;
1227 static const LARGE_INTEGER llZero;
1229 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1231 hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
1232 ok_ole_success(hr, "CreateStreamOnHGlobal");
1234 hr = CoMarshalInterface(pStream, &IID_IUnknown, NULL, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1235 ok(hr == E_INVALIDARG, "CoMarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1237 hr = CoMarshalInterface(NULL, &IID_IUnknown, (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1238 ok(hr == E_INVALIDARG, "CoMarshalInterface should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1240 hr = CoMarshalInterface(pStream, &IID_IUnknown, (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1241 ok_ole_success(hr, "CoMarshalInterface");
1243 /* stream not rewound */
1244 hr = CoReleaseMarshalData(pStream);
1245 ok(hr == STG_E_READFAULT, "CoReleaseMarshalData should have returned STG_E_READFAULT instead of 0x%08x\n", hr);
1247 hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
1248 ok_ole_success(hr, "IStream_Seek");
1250 hr = CoReleaseMarshalData(pStream);
1251 ok_ole_success(hr, "CoReleaseMarshalData");
1253 IStream_Release(pStream);
1255 CoUninitialize();
1258 static void test_CoMarshalInterThreadInterfaceInStream(void)
1260 IStream *pStream;
1261 HRESULT hr;
1262 IClassFactory *pProxy;
1264 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1266 cLocks = 0;
1268 hr = CoMarshalInterThreadInterfaceInStream(&IID_IUnknown, (IUnknown *)&Test_ClassFactory, NULL);
1269 ok(hr == E_INVALIDARG, "CoMarshalInterThreadInterfaceInStream should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1271 hr = CoMarshalInterThreadInterfaceInStream(&IID_IUnknown, NULL, &pStream);
1272 ok(hr == E_INVALIDARG, "CoMarshalInterThreadInterfaceInStream should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1274 ok_no_locks();
1276 hr = CoMarshalInterThreadInterfaceInStream(&IID_IUnknown, (IUnknown *)&Test_ClassFactory, &pStream);
1277 ok_ole_success(hr, "CoMarshalInterThreadInterfaceInStream");
1279 ok_more_than_one_lock();
1281 hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
1282 ok_ole_success(hr, "CoUnmarshalInterface");
1284 IClassFactory_Release(pProxy);
1285 IStream_Release(pStream);
1287 ok_no_locks();
1289 CoUninitialize();
1292 static void test_CoRegisterClassObject(void)
1294 ULONG_PTR ctxcookie;
1295 HANDLE handle;
1296 DWORD cookie;
1297 HRESULT hr;
1298 IClassFactory *pcf;
1300 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1302 /* CLSCTX_INPROC_SERVER */
1303 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1304 CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1305 ok_ole_success(hr, "CoRegisterClassObject");
1306 hr = CoRevokeClassObject(cookie);
1307 ok_ole_success(hr, "CoRevokeClassObject");
1309 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1310 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1311 ok_ole_success(hr, "CoRegisterClassObject");
1312 hr = CoRevokeClassObject(cookie);
1313 ok_ole_success(hr, "CoRevokeClassObject");
1315 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1316 CLSCTX_INPROC_SERVER, REGCLS_MULTI_SEPARATE, &cookie);
1317 ok_ole_success(hr, "CoRegisterClassObject");
1318 hr = CoRevokeClassObject(cookie);
1319 ok_ole_success(hr, "CoRevokeClassObject");
1321 /* CLSCTX_LOCAL_SERVER */
1322 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1323 CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1324 ok_ole_success(hr, "CoRegisterClassObject");
1325 hr = CoRevokeClassObject(cookie);
1326 ok_ole_success(hr, "CoRevokeClassObject");
1328 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1329 CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1330 ok_ole_success(hr, "CoRegisterClassObject");
1331 hr = CoRevokeClassObject(cookie);
1332 ok_ole_success(hr, "CoRevokeClassObject");
1334 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1335 CLSCTX_LOCAL_SERVER, REGCLS_MULTI_SEPARATE, &cookie);
1336 ok_ole_success(hr, "CoRegisterClassObject");
1337 hr = CoRevokeClassObject(cookie);
1338 ok_ole_success(hr, "CoRevokeClassObject");
1340 /* CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER */
1341 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1342 CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1343 ok_ole_success(hr, "CoRegisterClassObject");
1344 hr = CoRevokeClassObject(cookie);
1345 ok_ole_success(hr, "CoRevokeClassObject");
1347 /* test whether an object that doesn't support IClassFactory can be
1348 * registered for CLSCTX_LOCAL_SERVER */
1349 hr = CoRegisterClassObject(&CLSID_WineOOPTest, &Test_Unknown,
1350 CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
1351 ok_ole_success(hr, "CoRegisterClassObject");
1352 hr = CoRevokeClassObject(cookie);
1353 ok_ole_success(hr, "CoRevokeClassObject");
1355 /* test whether registered class becomes invalid when apartment is destroyed */
1356 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1357 CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1358 ok_ole_success(hr, "CoRegisterClassObject");
1360 CoUninitialize();
1361 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1363 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL,
1364 &IID_IClassFactory, (void **)&pcf);
1365 ok(hr == REGDB_E_CLASSNOTREG, "object registered in an apartment shouldn't accessible after it is destroyed\n");
1367 /* crashes with at least win9x DCOM! */
1368 if (0)
1369 CoRevokeClassObject(cookie);
1371 /* test that object is accessible */
1372 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory, CLSCTX_INPROC_SERVER,
1373 REGCLS_MULTIPLEUSE, &cookie);
1374 ok(hr == S_OK, "got 0x%08x\n", hr);
1376 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1377 ok(hr == S_OK, "got 0x%08x\n", hr);
1378 IClassFactory_Release(pcf);
1380 /* context now contains CLSID_WineOOPTest, test if registered one could still be used */
1381 if ((handle = activate_context(actctx_manifest, &ctxcookie)))
1383 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1384 todo_wine
1385 ok(hr == HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND), "got 0x%08x\n", hr);
1387 pDeactivateActCtx(0, ctxcookie);
1388 pReleaseActCtx(handle);
1391 hr = CoGetClassObject(&CLSID_WineOOPTest, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&pcf);
1392 ok(hr == S_OK, "got 0x%08x\n", hr);
1393 IClassFactory_Release(pcf);
1395 hr = CoRevokeClassObject(cookie);
1396 ok(hr == S_OK, "got 0x%08x\n", hr);
1398 CoUninitialize();
1401 static HRESULT get_class_object(CLSCTX clsctx)
1403 HRESULT hr;
1404 IClassFactory *pcf;
1406 hr = CoGetClassObject(&CLSID_WineOOPTest, clsctx, NULL, &IID_IClassFactory,
1407 (void **)&pcf);
1409 if (SUCCEEDED(hr))
1410 IClassFactory_Release(pcf);
1412 return hr;
1415 static DWORD CALLBACK get_class_object_thread(LPVOID pv)
1417 CLSCTX clsctx = (CLSCTX)(DWORD_PTR)pv;
1418 HRESULT hr;
1420 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1422 hr = get_class_object(clsctx);
1424 CoUninitialize();
1426 return hr;
1429 static DWORD CALLBACK get_class_object_proxy_thread(LPVOID pv)
1431 CLSCTX clsctx = (CLSCTX)(DWORD_PTR)pv;
1432 HRESULT hr;
1433 IClassFactory *pcf;
1434 IMultiQI *pMQI;
1436 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1438 hr = CoGetClassObject(&CLSID_WineOOPTest, clsctx, NULL, &IID_IClassFactory,
1439 (void **)&pcf);
1441 if (SUCCEEDED(hr))
1443 hr = IClassFactory_QueryInterface(pcf, &IID_IMultiQI, (void **)&pMQI);
1444 if (SUCCEEDED(hr))
1445 IMultiQI_Release(pMQI);
1446 IClassFactory_Release(pcf);
1449 CoUninitialize();
1451 return hr;
1454 static DWORD CALLBACK register_class_object_thread(LPVOID pv)
1456 HRESULT hr;
1457 DWORD cookie;
1459 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1461 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1462 CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1464 CoUninitialize();
1466 return hr;
1469 static DWORD CALLBACK revoke_class_object_thread(LPVOID pv)
1471 DWORD cookie = (DWORD_PTR)pv;
1472 HRESULT hr;
1474 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1476 hr = CoRevokeClassObject(cookie);
1478 CoUninitialize();
1480 return hr;
1483 static void test_registered_object_thread_affinity(void)
1485 HRESULT hr;
1486 DWORD cookie;
1487 HANDLE thread;
1488 DWORD tid;
1489 DWORD exitcode;
1491 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1493 /* CLSCTX_INPROC_SERVER */
1495 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1496 CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie);
1497 ok_ole_success(hr, "CoRegisterClassObject");
1499 thread = CreateThread(NULL, 0, get_class_object_thread, (LPVOID)CLSCTX_INPROC_SERVER, 0, &tid);
1500 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1501 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1502 GetExitCodeThread(thread, &exitcode);
1503 hr = exitcode;
1504 ok(hr == REGDB_E_CLASSNOTREG, "CoGetClassObject on inproc object "
1505 "registered in different thread should return REGDB_E_CLASSNOTREG "
1506 "instead of 0x%08x\n", hr);
1508 hr = get_class_object(CLSCTX_INPROC_SERVER);
1509 ok(hr == S_OK, "CoGetClassObject on inproc object registered in same "
1510 "thread should return S_OK instead of 0x%08x\n", hr);
1512 thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid);
1513 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1514 ok ( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1515 GetExitCodeThread(thread, &exitcode);
1516 hr = exitcode;
1517 ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different thread should return S_OK instead of 0x%08x\n", hr);
1519 hr = CoRevokeClassObject(cookie);
1520 ok_ole_success(hr, "CoRevokeClassObject");
1522 /* CLSCTX_LOCAL_SERVER */
1524 hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory,
1525 CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &cookie);
1526 ok_ole_success(hr, "CoRegisterClassObject");
1528 thread = CreateThread(NULL, 0, get_class_object_proxy_thread, (LPVOID)CLSCTX_LOCAL_SERVER, 0, &tid);
1529 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1530 while (MsgWaitForMultipleObjects(1, &thread, FALSE, 10000, QS_ALLINPUT) == WAIT_OBJECT_0 + 1)
1532 MSG msg;
1533 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
1535 TranslateMessage(&msg);
1536 DispatchMessageA(&msg);
1539 GetExitCodeThread(thread, &exitcode);
1540 hr = exitcode;
1541 ok(hr == S_OK, "CoGetClassObject on local server object "
1542 "registered in different thread should return S_OK "
1543 "instead of 0x%08x\n", hr);
1545 hr = get_class_object(CLSCTX_LOCAL_SERVER);
1546 ok(hr == S_OK, "CoGetClassObject on local server object registered in same "
1547 "thread should return S_OK instead of 0x%08x\n", hr);
1549 thread = CreateThread(NULL, 0, revoke_class_object_thread, (LPVOID)(DWORD_PTR)cookie, 0, &tid);
1550 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1551 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1552 GetExitCodeThread(thread, &exitcode);
1553 hr = exitcode;
1554 ok(hr == RPC_E_WRONG_THREAD, "CoRevokeClassObject called from different "
1555 "thread to where registered should return RPC_E_WRONG_THREAD instead of 0x%08x\n", hr);
1557 thread = CreateThread(NULL, 0, register_class_object_thread, NULL, 0, &tid);
1558 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1559 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1560 GetExitCodeThread(thread, &exitcode);
1561 hr = exitcode;
1562 ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different "
1563 "thread should return S_OK instead of 0x%08x\n", hr);
1565 hr = CoRevokeClassObject(cookie);
1566 ok_ole_success(hr, "CoRevokeClassObject");
1568 CoUninitialize();
1571 static DWORD CALLBACK free_libraries_thread(LPVOID p)
1573 CoFreeUnusedLibraries();
1574 return 0;
1577 static inline BOOL is_module_loaded(const char *module)
1579 return GetModuleHandleA(module) != 0;
1582 static void test_CoFreeUnusedLibraries(void)
1584 HRESULT hr;
1585 IUnknown *pUnk;
1586 DWORD tid;
1587 HANDLE thread;
1589 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1591 ok(!is_module_loaded("urlmon.dll"), "urlmon.dll shouldn't be loaded\n");
1593 hr = CoCreateInstance(&CLSID_FileProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pUnk);
1594 if (hr == REGDB_E_CLASSNOTREG)
1596 skip("IE not installed so can't run CoFreeUnusedLibraries test\n");
1597 CoUninitialize();
1598 return;
1600 ok_ole_success(hr, "CoCreateInstance");
1602 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1604 ok(pUnk != NULL ||
1605 broken(pUnk == NULL), /* win9x */
1606 "Expected a valid pointer\n");
1607 if (pUnk)
1608 IUnknown_Release(pUnk);
1610 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1612 thread = CreateThread(NULL, 0, free_libraries_thread, NULL, 0, &tid);
1613 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1614 CloseHandle(thread);
1616 ok(is_module_loaded("urlmon.dll"), "urlmon.dll should be loaded\n");
1618 CoFreeUnusedLibraries();
1620 ok(!is_module_loaded("urlmon.dll"), "urlmon.dll shouldn't be loaded\n");
1622 CoUninitialize();
1625 static void test_CoGetObjectContext(void)
1627 HRESULT hr;
1628 ULONG refs;
1629 IComThreadingInfo *pComThreadingInfo;
1630 IContextCallback *pContextCallback;
1631 IObjContext *pObjContext;
1632 APTTYPE apttype;
1633 THDTYPE thdtype;
1634 struct info info;
1635 HANDLE thread;
1636 DWORD tid, exitcode;
1638 if (!pCoGetObjectContext)
1640 skip("CoGetObjectContext not present\n");
1641 return;
1644 hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1645 ok(hr == CO_E_NOTINITIALIZED, "CoGetObjectContext should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
1646 ok(pComThreadingInfo == NULL, "pComThreadingInfo should have been set to NULL\n");
1648 /* show that COM doesn't have to be initialized for multi-threaded apartments if another
1649 thread has already done so */
1651 info.wait = CreateEventA(NULL, TRUE, FALSE, NULL);
1652 ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
1654 info.stop = CreateEventA(NULL, TRUE, FALSE, NULL);
1655 ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError());
1657 thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid);
1658 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1660 ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
1662 pComThreadingInfo = NULL;
1663 hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1664 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
1665 IComThreadingInfo_Release(pComThreadingInfo);
1667 SetEvent(info.stop);
1668 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1670 GetExitCodeThread(thread, &exitcode);
1671 hr = exitcode;
1672 ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr);
1674 CloseHandle(thread);
1675 CloseHandle(info.wait);
1676 CloseHandle(info.stop);
1678 pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1680 hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1681 ok_ole_success(hr, "CoGetObjectContext");
1683 hr = IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo, &apttype);
1684 ok_ole_success(hr, "IComThreadingInfo_GetCurrentApartmentType");
1685 ok(apttype == APTTYPE_MAINSTA, "apartment type should be APTTYPE_MAINSTA instead of %d\n", apttype);
1687 hr = IComThreadingInfo_GetCurrentThreadType(pComThreadingInfo, &thdtype);
1688 ok_ole_success(hr, "IComThreadingInfo_GetCurrentThreadType");
1689 ok(thdtype == THDTYPE_PROCESSMESSAGES, "thread type should be THDTYPE_PROCESSMESSAGES instead of %d\n", thdtype);
1691 refs = IComThreadingInfo_Release(pComThreadingInfo);
1692 ok(refs == 0, "pComThreadingInfo should have 0 refs instead of %d refs\n", refs);
1694 hr = pCoGetObjectContext(&IID_IContextCallback, (void **)&pContextCallback);
1695 ok_ole_success(hr, "CoGetObjectContext(ContextCallback)");
1697 if (hr == S_OK)
1699 refs = IContextCallback_Release(pContextCallback);
1700 ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs);
1703 CoUninitialize();
1705 pCoInitializeEx(NULL, COINIT_MULTITHREADED);
1707 hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
1708 ok_ole_success(hr, "CoGetObjectContext");
1710 hr = IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo, &apttype);
1711 ok_ole_success(hr, "IComThreadingInfo_GetCurrentApartmentType");
1712 ok(apttype == APTTYPE_MTA, "apartment type should be APTTYPE_MTA instead of %d\n", apttype);
1714 hr = IComThreadingInfo_GetCurrentThreadType(pComThreadingInfo, &thdtype);
1715 ok_ole_success(hr, "IComThreadingInfo_GetCurrentThreadType");
1716 ok(thdtype == THDTYPE_BLOCKMESSAGES, "thread type should be THDTYPE_BLOCKMESSAGES instead of %d\n", thdtype);
1718 refs = IComThreadingInfo_Release(pComThreadingInfo);
1719 ok(refs == 0, "pComThreadingInfo should have 0 refs instead of %d refs\n", refs);
1721 hr = pCoGetObjectContext(&IID_IContextCallback, (void **)&pContextCallback);
1722 ok_ole_success(hr, "CoGetObjectContext(ContextCallback)");
1724 if (hr == S_OK)
1726 refs = IContextCallback_Release(pContextCallback);
1727 ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs);
1730 hr = pCoGetObjectContext(&IID_IObjContext, (void **)&pObjContext);
1731 ok_ole_success(hr, "CoGetObjectContext");
1733 refs = IObjContext_Release(pObjContext);
1734 ok(refs == 0, "pObjContext should have 0 refs instead of %d refs\n", refs);
1736 CoUninitialize();
1739 typedef struct {
1740 IUnknown IUnknown_iface;
1741 LONG refs;
1742 } Test_CallContext;
1744 static inline Test_CallContext *impl_from_IUnknown(IUnknown *iface)
1746 return CONTAINING_RECORD(iface, Test_CallContext, IUnknown_iface);
1749 static HRESULT WINAPI Test_CallContext_QueryInterface(
1750 IUnknown *iface,
1751 REFIID riid,
1752 LPVOID *ppvObj)
1754 if (ppvObj == NULL) return E_POINTER;
1756 if (IsEqualGUID(riid, &IID_IUnknown))
1758 *ppvObj = iface;
1759 IUnknown_AddRef(iface);
1760 return S_OK;
1763 *ppvObj = NULL;
1764 return E_NOINTERFACE;
1767 static ULONG WINAPI Test_CallContext_AddRef(IUnknown *iface)
1769 Test_CallContext *This = impl_from_IUnknown(iface);
1770 return InterlockedIncrement(&This->refs);
1773 static ULONG WINAPI Test_CallContext_Release(IUnknown *iface)
1775 Test_CallContext *This = impl_from_IUnknown(iface);
1776 ULONG refs = InterlockedDecrement(&This->refs);
1777 if (!refs)
1778 HeapFree(GetProcessHeap(), 0, This);
1779 return refs;
1782 static const IUnknownVtbl TestCallContext_Vtbl =
1784 Test_CallContext_QueryInterface,
1785 Test_CallContext_AddRef,
1786 Test_CallContext_Release
1789 static void test_CoGetCallContext(void)
1791 HRESULT hr;
1792 ULONG refs;
1793 IUnknown *pUnk;
1794 Test_CallContext *test_object;
1796 if (!pCoSwitchCallContext)
1798 skip("CoSwitchCallContext not present\n");
1799 return;
1802 CoInitialize(NULL);
1804 test_object = HeapAlloc(GetProcessHeap(), 0, sizeof(Test_CallContext));
1805 test_object->IUnknown_iface.lpVtbl = &TestCallContext_Vtbl;
1806 test_object->refs = 1;
1808 hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1809 ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr);
1811 pUnk = (IUnknown*)0xdeadbeef;
1812 hr = pCoSwitchCallContext(&test_object->IUnknown_iface, &pUnk);
1813 ok_ole_success(hr, "CoSwitchCallContext");
1814 ok(pUnk == NULL, "expected NULL, got %p\n", pUnk);
1815 refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1816 ok(refs == 2, "Expected refcount 2, got %d\n", refs);
1817 IUnknown_Release(&test_object->IUnknown_iface);
1819 pUnk = (IUnknown*)0xdeadbeef;
1820 hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1821 ok_ole_success(hr, "CoGetCallContext");
1822 ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n",
1823 &test_object->IUnknown_iface, pUnk);
1824 refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1825 ok(refs == 3, "Expected refcount 3, got %d\n", refs);
1826 IUnknown_Release(&test_object->IUnknown_iface);
1827 IUnknown_Release(pUnk);
1829 pUnk = (IUnknown*)0xdeadbeef;
1830 hr = pCoSwitchCallContext(NULL, &pUnk);
1831 ok_ole_success(hr, "CoSwitchCallContext");
1832 ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n",
1833 &test_object->IUnknown_iface, pUnk);
1834 refs = IUnknown_AddRef(&test_object->IUnknown_iface);
1835 ok(refs == 2, "Expected refcount 2, got %d\n", refs);
1836 IUnknown_Release(&test_object->IUnknown_iface);
1838 hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk);
1839 ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr);
1841 IUnknown_Release(&test_object->IUnknown_iface);
1843 CoUninitialize();
1846 static void test_CoGetContextToken(void)
1848 HRESULT hr;
1849 ULONG refs;
1850 ULONG_PTR token;
1851 IObjContext *ctx;
1852 struct info info;
1853 HANDLE thread;
1854 DWORD tid, exitcode;
1856 if (!pCoGetContextToken)
1858 win_skip("CoGetContextToken not present\n");
1859 return;
1862 token = 0xdeadbeef;
1863 hr = pCoGetContextToken(&token);
1864 ok(hr == CO_E_NOTINITIALIZED, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr);
1865 ok(token == 0xdeadbeef, "Expected 0, got 0x%lx\n", token);
1867 /* show that COM doesn't have to be initialized for multi-threaded apartments if another
1868 thread has already done so */
1870 info.wait = CreateEventA(NULL, TRUE, FALSE, NULL);
1871 ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
1873 info.stop = CreateEventA(NULL, TRUE, FALSE, NULL);
1874 ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError());
1876 thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid);
1877 ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
1879 ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
1881 token = 0;
1882 hr = pCoGetContextToken(&token);
1883 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
1885 SetEvent(info.stop);
1886 ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
1888 GetExitCodeThread(thread, &exitcode);
1889 hr = exitcode;
1890 ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr);
1892 CloseHandle(thread);
1893 CloseHandle(info.wait);
1894 CloseHandle(info.stop);
1896 CoInitialize(NULL);
1898 hr = pCoGetContextToken(NULL);
1899 ok(hr == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hr);
1901 token = 0;
1902 hr = pCoGetContextToken(&token);
1903 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
1904 ok(token, "Expected token != 0\n");
1906 refs = IUnknown_AddRef((IUnknown *)token);
1907 todo_wine ok(refs == 1, "Expected 1, got %u\n", refs);
1909 hr = pCoGetObjectContext(&IID_IObjContext, (void **)&ctx);
1910 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
1911 todo_wine ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n");
1913 refs = IUnknown_AddRef((IUnknown *)ctx);
1914 todo_wine ok(refs == 3, "Expected 3, got %u\n", refs);
1916 refs = IUnknown_Release((IUnknown *)ctx);
1917 todo_wine ok(refs == 2, "Expected 2, got %u\n", refs);
1919 refs = IUnknown_Release((IUnknown *)token);
1920 ok(refs == 1, "Expected 1, got %u\n", refs);
1922 /* CoGetContextToken does not add a reference */
1923 token = 0;
1924 hr = pCoGetContextToken(&token);
1925 ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
1926 ok(token, "Expected token != 0\n");
1927 todo_wine ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n");
1929 refs = IUnknown_AddRef((IUnknown *)ctx);
1930 ok(refs == 2, "Expected 1, got %u\n", refs);
1932 refs = IUnknown_Release((IUnknown *)ctx);
1933 ok(refs == 1, "Expected 0, got %u\n", refs);
1935 refs = IUnknown_Release((IUnknown *)ctx);
1936 ok(refs == 0, "Expected 0, got %u\n", refs);
1938 CoUninitialize();
1941 static void test_TreatAsClass(void)
1943 HRESULT hr;
1944 CLSID out;
1945 static GUID deadbeef = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}};
1946 static const char deadbeefA[] = "{DEADBEEF-DEAD-BEEF-DEAD-BEEFDEADBEEF}";
1947 IInternetProtocol *pIP = NULL;
1948 HKEY clsidkey, deadbeefkey;
1949 LONG lr;
1951 if (!pCoGetTreatAsClass)
1953 win_skip("CoGetTreatAsClass not present\n");
1954 return;
1956 hr = pCoGetTreatAsClass(&deadbeef,&out);
1957 ok (hr == S_FALSE, "expected S_FALSE got %x\n",hr);
1958 ok (IsEqualGUID(&out,&deadbeef), "expected to get same clsid back\n");
1960 lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &clsidkey);
1961 ok(lr == ERROR_SUCCESS, "Couldn't open CLSID key\n");
1963 lr = RegCreateKeyExA(clsidkey, deadbeefA, 0, NULL, 0, KEY_WRITE, NULL, &deadbeefkey, NULL);
1964 ok(lr == ERROR_SUCCESS, "Couldn't create class key\n");
1966 hr = pCoTreatAsClass(&deadbeef, &deadbeef);
1967 ok(hr == REGDB_E_WRITEREGDB, "CoTreatAsClass gave wrong error: %08x\n", hr);
1969 hr = pCoTreatAsClass(&deadbeef, &CLSID_FileProtocol);
1970 if(hr == REGDB_E_WRITEREGDB){
1971 win_skip("Insufficient privileges to use CoTreatAsClass\n");
1972 goto exit;
1974 ok(hr == S_OK, "CoTreatAsClass failed: %08x\n", hr);
1976 hr = pCoGetTreatAsClass(&deadbeef, &out);
1977 ok(hr == S_OK, "CoGetTreatAsClass failed: %08x\n",hr);
1978 ok(IsEqualGUID(&out, &CLSID_FileProtocol), "expected to get substituted clsid\n");
1980 OleInitialize(NULL);
1982 hr = CoCreateInstance(&deadbeef, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pIP);
1983 if(hr == REGDB_E_CLASSNOTREG)
1985 win_skip("IE not installed so can't test CoCreateInstance\n");
1986 goto exit;
1989 ok(hr == S_OK, "CoCreateInstance failed: %08x\n", hr);
1990 if(pIP){
1991 IInternetProtocol_Release(pIP);
1992 pIP = NULL;
1995 hr = pCoTreatAsClass(&deadbeef, &CLSID_NULL);
1996 ok(hr == S_OK, "CoTreatAsClass failed: %08x\n", hr);
1998 hr = pCoGetTreatAsClass(&deadbeef, &out);
1999 ok(hr == S_FALSE, "expected S_FALSE got %08x\n", hr);
2000 ok(IsEqualGUID(&out, &deadbeef), "expected to get same clsid back\n");
2002 /* bizarrely, native's CoTreatAsClass takes some time to take effect in CoCreateInstance */
2003 Sleep(200);
2005 hr = CoCreateInstance(&deadbeef, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void **)&pIP);
2006 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance gave wrong error: %08x\n", hr);
2008 if(pIP)
2009 IInternetProtocol_Release(pIP);
2011 exit:
2012 OleUninitialize();
2013 RegCloseKey(deadbeefkey);
2014 RegDeleteKeyA(clsidkey, deadbeefA);
2015 RegCloseKey(clsidkey);
2018 static void test_CoInitializeEx(void)
2020 HRESULT hr;
2022 hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
2023 ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr);
2025 /* Calling OleInitialize for the first time should yield S_OK even with
2026 * apartment already initialized by previous CoInitialize(Ex) calls. */
2027 hr = OleInitialize(NULL);
2028 ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
2030 /* Subsequent calls to OleInitialize should return S_FALSE */
2031 hr = OleInitialize(NULL);
2032 ok(hr == S_FALSE, "Expected S_FALSE, hr = 0x%08x\n", hr);
2034 /* Cleanup */
2035 CoUninitialize();
2036 OleUninitialize();
2039 static void test_OleRegGetMiscStatus(void)
2041 ULONG_PTR cookie;
2042 HANDLE handle;
2043 DWORD status;
2044 HRESULT hr;
2046 hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, NULL);
2047 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2049 status = 0xdeadbeef;
2050 hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, &status);
2051 ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
2052 ok(status == 0, "got 0x%08x\n", status);
2054 status = -1;
2055 hr = OleRegGetMiscStatus(&CLSID_StdFont, DVASPECT_ICON, &status);
2056 ok(hr == S_OK, "got 0x%08x\n", hr);
2057 ok(status == 0, "got 0x%08x\n", status);
2059 if ((handle = activate_context(actctx_manifest, &cookie)))
2061 status = 0;
2062 hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_ICON, &status);
2063 ok(hr == S_OK, "got 0x%08x\n", hr);
2064 ok(status == OLEMISC_RECOMPOSEONRESIZE, "got 0x%08x\n", status);
2066 /* context data takes precedence over registration info */
2067 status = 0;
2068 hr = OleRegGetMiscStatus(&CLSID_StdFont, DVASPECT_ICON, &status);
2069 ok(hr == S_OK, "got 0x%08x\n", hr);
2070 ok(status == OLEMISC_RECOMPOSEONRESIZE, "got 0x%08x\n", status);
2072 /* there's no such attribute in context */
2073 status = -1;
2074 hr = OleRegGetMiscStatus(&CLSID_Testclass, DVASPECT_DOCPRINT, &status);
2075 ok(hr == S_OK, "got 0x%08x\n", hr);
2076 ok(status == 0, "got 0x%08x\n", status);
2078 pDeactivateActCtx(0, cookie);
2079 pReleaseActCtx(handle);
2083 static void test_CoCreateGuid(void)
2085 HRESULT hr;
2087 hr = CoCreateGuid(NULL);
2088 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2091 static void init_funcs(void)
2093 HMODULE hOle32 = GetModuleHandleA("ole32");
2094 HMODULE hAdvapi32 = GetModuleHandleA("advapi32");
2095 HMODULE hkernel32 = GetModuleHandleA("kernel32");
2097 pCoGetObjectContext = (void*)GetProcAddress(hOle32, "CoGetObjectContext");
2098 pCoSwitchCallContext = (void*)GetProcAddress(hOle32, "CoSwitchCallContext");
2099 pCoGetTreatAsClass = (void*)GetProcAddress(hOle32,"CoGetTreatAsClass");
2100 pCoTreatAsClass = (void*)GetProcAddress(hOle32,"CoTreatAsClass");
2101 pCoGetContextToken = (void*)GetProcAddress(hOle32, "CoGetContextToken");
2102 pRegDeleteKeyExA = (void*)GetProcAddress(hAdvapi32, "RegDeleteKeyExA");
2103 pRegOverridePredefKey = (void*)GetProcAddress(hAdvapi32, "RegOverridePredefKey");
2104 pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx");
2106 pActivateActCtx = (void*)GetProcAddress(hkernel32, "ActivateActCtx");
2107 pCreateActCtxW = (void*)GetProcAddress(hkernel32, "CreateActCtxW");
2108 pDeactivateActCtx = (void*)GetProcAddress(hkernel32, "DeactivateActCtx");
2109 pIsWow64Process = (void*)GetProcAddress(hkernel32, "IsWow64Process");
2110 pReleaseActCtx = (void*)GetProcAddress(hkernel32, "ReleaseActCtx");
2113 START_TEST(compobj)
2115 init_funcs();
2117 if (!pCoInitializeEx)
2119 trace("You need DCOM95 installed to run this test\n");
2120 return;
2123 if (!pCreateActCtxW)
2124 win_skip("Activation contexts are not supported, some tests will be skipped.\n");
2126 test_ProgIDFromCLSID();
2127 test_CLSIDFromProgID();
2128 test_CLSIDFromString();
2129 test_IIDFromString();
2130 test_StringFromGUID2();
2131 test_CoCreateInstance();
2132 test_ole_menu();
2133 test_CoGetClassObject();
2134 test_CoRegisterMessageFilter();
2135 test_CoRegisterPSClsid();
2136 test_CoGetPSClsid();
2137 test_CoUnmarshalInterface();
2138 test_CoGetInterfaceAndReleaseStream();
2139 test_CoMarshalInterface();
2140 test_CoMarshalInterThreadInterfaceInStream();
2141 test_CoRegisterClassObject();
2142 test_registered_object_thread_affinity();
2143 test_CoFreeUnusedLibraries();
2144 test_CoGetObjectContext();
2145 test_CoGetCallContext();
2146 test_CoGetContextToken();
2147 test_TreatAsClass();
2148 test_CoInitializeEx();
2149 test_OleRegGetMiscStatus();
2150 test_CoCreateGuid();