2 * Copyright 2010 Louis Lenders
3 * Copyright 2011 André Hentschel
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/test.h"
31 DEFINE_GUID(IID__AppDomain
, 0x05f696dc,0x2b29,0x3663,0xad,0x8b,0xc4,0x38,0x9c,0xf2,0xa7,0x13);
33 static const WCHAR v4_0
[] = {'v','4','.','0','.','3','0','3','1','9',0};
35 static HMODULE hmscoree
;
37 static HRESULT (WINAPI
*pGetCORVersion
)(LPWSTR
, DWORD
, DWORD
*);
38 static HRESULT (WINAPI
*pGetCORSystemDirectory
)(LPWSTR
, DWORD
, DWORD
*);
39 static HRESULT (WINAPI
*pGetRequestedRuntimeInfo
)(LPCWSTR
, LPCWSTR
, LPCWSTR
, DWORD
, DWORD
, LPWSTR
, DWORD
, DWORD
*, LPWSTR
, DWORD
, DWORD
*);
40 static HRESULT (WINAPI
*pLoadLibraryShim
)(LPCWSTR
, LPCWSTR
, LPVOID
, HMODULE
*);
41 static HRESULT (WINAPI
*pCreateConfigStream
)(LPCWSTR
, IStream
**);
42 static HRESULT (WINAPI
*pCreateInterface
)(REFCLSID
, REFIID
, VOID
**);
43 static HRESULT (WINAPI
*pCLRCreateInstance
)(REFCLSID
, REFIID
, VOID
**);
45 static BOOL no_legacy_runtimes
;
47 static BOOL
init_functionpointers(void)
49 hmscoree
= LoadLibraryA("mscoree.dll");
53 win_skip("mscoree.dll not available\n");
57 pGetCORVersion
= (void *)GetProcAddress(hmscoree
, "GetCORVersion");
58 pGetCORSystemDirectory
= (void *)GetProcAddress(hmscoree
, "GetCORSystemDirectory");
59 pGetRequestedRuntimeInfo
= (void *)GetProcAddress(hmscoree
, "GetRequestedRuntimeInfo");
60 pLoadLibraryShim
= (void *)GetProcAddress(hmscoree
, "LoadLibraryShim");
61 pCreateConfigStream
= (void *)GetProcAddress(hmscoree
, "CreateConfigStream");
62 pCreateInterface
= (void *)GetProcAddress(hmscoree
, "CreateInterface");
63 pCLRCreateInstance
= (void *)GetProcAddress(hmscoree
, "CLRCreateInstance");
65 if (!pGetCORVersion
|| !pGetCORSystemDirectory
|| !pGetRequestedRuntimeInfo
|| !pLoadLibraryShim
||
66 !pCreateInterface
|| !pCLRCreateInstance
69 win_skip("functions not available\n");
70 FreeLibrary(hmscoree
);
77 static int check_runtime(void)
79 ICLRMetaHost
*metahost
;
80 ICLRRuntimeInfo
*runtimeinfo
;
81 ICorRuntimeHost
*runtimehost
;
84 if (!pCLRCreateInstance
)
86 win_skip("Function CLRCreateInstance not found.\n");
90 hr
= pCLRCreateInstance(&CLSID_CLRMetaHost
, &IID_ICLRMetaHost
, (void **)&metahost
);
93 win_skip("CLRCreateInstance not implemented\n");
96 ok(SUCCEEDED(hr
), "CLRCreateInstance failed, hr=%#.8x\n", hr
);
100 hr
= ICLRMetaHost_GetRuntime(metahost
, v4_0
, &IID_ICLRRuntimeInfo
, (void **)&runtimeinfo
);
101 ok(SUCCEEDED(hr
), "ICLRMetaHost::GetRuntime failed, hr=%#.8x\n", hr
);
105 hr
= ICLRRuntimeInfo_GetInterface(runtimeinfo
, &CLSID_CorRuntimeHost
, &IID_ICorRuntimeHost
,
106 (void **)&runtimehost
);
107 ok(SUCCEEDED(hr
), "ICLRRuntimeInfo::GetInterface failed, hr=%#.8x\n", hr
);
111 hr
= ICorRuntimeHost_Start(runtimehost
);
112 ok(SUCCEEDED(hr
), "ICorRuntimeHost::Start failed, hr=%#.8x\n", hr
);
116 ICorRuntimeHost_Release(runtimehost
);
118 ICLRRuntimeInfo_Release(runtimeinfo
);
120 ICLRMetaHost_ExitProcess(metahost
, 0);
122 ok(0, "ICLRMetaHost_ExitProcess is not supposed to return\n");
126 static BOOL
runtime_is_usable(void)
128 static const char cmdline_format
[] = "\"%s\" mscoree check_runtime";
130 char cmdline
[MAX_PATH
+ sizeof(cmdline_format
)];
131 STARTUPINFOA si
= {0};
132 PROCESS_INFORMATION pi
;
136 winetest_get_mainargs(&argv
);
138 sprintf(cmdline
, cmdline_format
, argv
[0]);
142 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
143 ok(ret
, "CreateProcessA failed\n");
147 CloseHandle(pi
.hThread
);
149 WaitForSingleObject(pi
.hProcess
, INFINITE
);
151 ret
= GetExitCodeProcess(pi
.hProcess
, &exitcode
);
152 CloseHandle(pi
.hProcess
);
154 ok(ret
, "GetExitCodeProcess failed\n");
156 if (!ret
|| exitcode
!= 0)
158 win_skip(".NET 4.0 runtime is not usable\n");
165 static void test_versioninfo(void)
167 const WCHAR v9_0
[] = {'v','9','.','0','.','3','0','3','1','9',0};
168 const WCHAR v2_0cap
[] = {'V','2','.','0','.','5','0','7','2','7',0};
169 const WCHAR v2_0
[] = {'v','2','.','0','.','5','0','7','2','7',0};
170 const WCHAR v2_0_0
[] = {'v','2','.','0','.','0',0};
171 const WCHAR v1_1
[] = {'v','1','.','1','.','4','3','2','2',0};
172 const WCHAR v1_1_0
[] = {'v','1','.','1','.','0',0};
174 WCHAR version
[MAX_PATH
];
175 WCHAR path
[MAX_PATH
];
176 DWORD size
, path_len
;
179 if (0) /* crashes on <= w2k3 */
181 hr
= pGetCORVersion(NULL
, MAX_PATH
, &size
);
182 ok(hr
== E_POINTER
,"GetCORVersion returned %08x\n", hr
);
185 hr
= pGetCORVersion(version
, 1, &size
);
186 if (hr
== CLR_E_SHIM_RUNTIME
)
188 no_legacy_runtimes
= TRUE
;
189 win_skip("No legacy .NET runtimes are installed\n");
193 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "GetCORVersion returned %08x\n", hr
);
195 hr
= pGetCORVersion(version
, MAX_PATH
, &size
);
196 ok(hr
== S_OK
,"GetCORVersion returned %08x\n", hr
);
198 trace("latest installed .net runtime: %s\n", wine_dbgstr_w(version
));
200 hr
= pGetCORSystemDirectory(path
, MAX_PATH
, &size
);
201 ok(hr
== S_OK
, "GetCORSystemDirectory returned %08x\n", hr
);
202 /* size includes terminating null-character */
203 ok(size
== (lstrlenW(path
) + 1),"size is %d instead of %d\n", size
, (lstrlenW(path
) + 1));
207 hr
= pGetCORSystemDirectory(path
, path_len
-1 , &size
);
208 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "GetCORSystemDirectory returned %08x\n", hr
);
210 if (0) /* crashes on <= w2k3 */
212 hr
= pGetCORSystemDirectory(NULL
, MAX_PATH
, &size
);
213 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "GetCORSystemDirectory returned %08x\n", hr
);
216 hr
= pGetCORSystemDirectory(path
, MAX_PATH
, NULL
);
217 ok(hr
== E_POINTER
,"GetCORSystemDirectory returned %08x\n", hr
);
219 trace("latest installed .net installed in directory: %s\n", wine_dbgstr_w(path
));
221 /* test GetRequestedRuntimeInfo, first get info about different versions of runtime */
222 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
224 if(hr
== CLR_E_SHIM_RUNTIME
) return; /* skipping rest of tests on win2k as .net 2.0 not installed */
226 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
227 trace(" installed in directory %s is .net version %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(version
));
229 hr
= pGetRequestedRuntimeInfo( NULL
, v1_1
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
230 ok(hr
== S_OK
|| hr
== CLR_E_SHIM_RUNTIME
/*v1_1 not installed*/, "GetRequestedRuntimeInfo returned %08x\n", hr
);
232 trace(" installed in directory %s is .net version %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(version
));
233 /* version number NULL not allowed without RUNTIME_INFO_UPGRADE_VERSION flag */
234 hr
= pGetRequestedRuntimeInfo( NULL
, NULL
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
235 ok(hr
== CLR_E_SHIM_RUNTIME
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
236 /* with RUNTIME_INFO_UPGRADE_VERSION flag and version number NULL, latest installed version is returned */
237 hr
= pGetRequestedRuntimeInfo( NULL
, NULL
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
238 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
240 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0
, NULL
, 0, 0, path
, 1, &path_len
, version
, MAX_PATH
, &size
);
241 ok(hr
== E_NOT_SUFFICIENT_BUFFER
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
243 /* if one of the buffers is NULL, the other one is still happily filled */
244 memset(version
, 0, sizeof(version
));
245 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0
, NULL
, 0, 0, NULL
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
246 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
247 ok(!winetest_strcmpW(version
, v2_0
), "version is %s , expected %s\n", wine_dbgstr_w(version
), wine_dbgstr_w(v2_0
));
248 /* With NULL-pointer for bufferlength, the buffer itself still gets filled with correct string */
249 memset(version
, 0, sizeof(version
));
250 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
251 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
252 ok(!winetest_strcmpW(version
, v2_0
), "version is %s , expected %s\n", wine_dbgstr_w(version
), wine_dbgstr_w(v2_0
));
254 memset(version
, 0, sizeof(version
));
255 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0cap
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
256 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
257 ok(!winetest_strcmpW(version
, v2_0cap
), "version is %s , expected %s\n", wine_dbgstr_w(version
), wine_dbgstr_w(v2_0cap
));
259 /* Invalid Version and RUNTIME_INFO_UPGRADE_VERSION flag*/
260 memset(version
, 0, sizeof(version
));
261 hr
= pGetRequestedRuntimeInfo( NULL
, v1_1
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
262 ok(hr
== S_OK
|| hr
== CLR_E_SHIM_RUNTIME
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
265 /* .NET 1.1 may not be installed. */
266 ok(!winetest_strcmpW(version
, v1_1
) || !winetest_strcmpW(version
, v2_0
),
267 "version is %s , expected %s or %s\n", wine_dbgstr_w(version
), wine_dbgstr_w(v1_1
), wine_dbgstr_w(v2_0
));
271 memset(version
, 0, sizeof(version
));
272 hr
= pGetRequestedRuntimeInfo( NULL
, v9_0
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
273 ok(hr
== CLR_E_SHIM_RUNTIME
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
275 memset(version
, 0, sizeof(version
));
276 hr
= pGetRequestedRuntimeInfo( NULL
, v1_1_0
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
277 ok(hr
== CLR_E_SHIM_RUNTIME
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
279 memset(version
, 0, sizeof(version
));
280 hr
= pGetRequestedRuntimeInfo( NULL
, v1_1_0
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
281 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
282 ok(!winetest_strcmpW(version
, v2_0
), "version is %s , expected %s\n", wine_dbgstr_w(version
), wine_dbgstr_w(v2_0
));
284 memset(version
, 0, sizeof(version
));
285 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0_0
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
286 ok(hr
== CLR_E_SHIM_RUNTIME
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
288 memset(version
, 0, sizeof(version
));
289 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0_0
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
290 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
291 ok(!winetest_strcmpW(version
, v2_0
), "version is %s , expected %s\n", wine_dbgstr_w(version
), wine_dbgstr_w(v2_0
));
294 static void test_loadlibraryshim(void)
296 const WCHAR v2_0
[] = {'v','2','.','0','.','5','0','7','2','7',0};
297 const WCHAR v1_1
[] = {'v','1','.','1','.','4','3','2','2',0};
298 const WCHAR vbogus
[] = {'v','b','o','g','u','s',0};
299 const WCHAR fusion
[] = {'f','u','s','i','o','n',0};
300 const WCHAR fusiondll
[] = {'f','u','s','i','o','n','.','d','l','l',0};
301 const WCHAR nosuchdll
[] = {'j','n','v','n','l','.','d','l','l',0};
302 const WCHAR gdidll
[] = {'g','d','i','3','2','.','d','l','l',0};
304 const WCHAR
*latest
= NULL
;
305 CHAR latestA
[MAX_PATH
];
307 CHAR dllpath
[MAX_PATH
];
309 if (no_legacy_runtimes
)
311 win_skip("No legacy .NET runtimes are installed\n");
315 hr
= pLoadLibraryShim(fusion
, v1_1
, NULL
, &hdll
);
316 ok(hr
== S_OK
|| hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
321 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
323 todo_wine
ok(StrStrIA(dllpath
, "v1.1.4322") != 0, "incorrect fusion.dll path %s\n", dllpath
);
324 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
329 hr
= pLoadLibraryShim(fusion
, v2_0
, NULL
, &hdll
);
330 ok(hr
== S_OK
|| hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
335 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
337 todo_wine
ok(StrStrIA(dllpath
, "v2.0.50727") != 0, "incorrect fusion.dll path %s\n", dllpath
);
338 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
343 hr
= pLoadLibraryShim(fusion
, v4_0
, NULL
, &hdll
);
344 ok(hr
== S_OK
|| hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
347 /* LoadLibraryShim with a NULL version prefers 2.0 and earlier */
351 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
353 todo_wine
ok(StrStrIA(dllpath
, "v4.0.30319") != 0, "incorrect fusion.dll path %s\n", dllpath
);
354 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
359 hr
= pLoadLibraryShim(fusion
, vbogus
, NULL
, &hdll
);
360 todo_wine
ok(hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
364 WideCharToMultiByte(CP_ACP
, 0, latest
, -1, latestA
, MAX_PATH
, NULL
, NULL
);
366 hr
= pLoadLibraryShim(fusion
, NULL
, NULL
, &hdll
);
367 ok(hr
== S_OK
, "LoadLibraryShim failed, hr=%x\n", hr
);
370 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
373 todo_wine
ok(StrStrIA(dllpath
, latestA
) != 0, "incorrect fusion.dll path %s\n", dllpath
);
374 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
379 hr
= pLoadLibraryShim(fusiondll
, NULL
, NULL
, &hdll
);
380 ok(hr
== S_OK
, "LoadLibraryShim failed, hr=%x\n", hr
);
383 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
386 todo_wine
ok(StrStrIA(dllpath
, latestA
) != 0, "incorrect fusion.dll path %s\n", dllpath
);
387 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
392 hr
= pLoadLibraryShim(nosuchdll
, latest
, NULL
, &hdll
);
393 ok(hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
397 hr
= pLoadLibraryShim(gdidll
, latest
, NULL
, &hdll
);
398 todo_wine
ok(hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
403 static const char xmldata
[] =
404 "<?xml version=\"1.0\" ?>\n"
405 "<!DOCTYPE Config>\n"
407 " <Name>Test</Name>\n"
408 " <Value>1234</Value>\n"
411 static void create_xml_file(LPCWSTR filename
)
413 DWORD dwNumberOfBytesWritten
;
414 HANDLE hfile
= CreateFileW(filename
, GENERIC_WRITE
, 0, NULL
,
415 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
416 ok(hfile
!= INVALID_HANDLE_VALUE
, "File creation failed\n");
417 WriteFile(hfile
, xmldata
, sizeof(xmldata
) - 1, &dwNumberOfBytesWritten
, NULL
);
421 static void test_createconfigstream(void)
423 IStream
*stream
= NULL
;
424 WCHAR file
[] = {'c', 'o', 'n', 'f', '.', 'x', 'm', 'l', 0};
425 WCHAR nonexistent
[] = {'n', 'o', 'n', 'e', 'x', 'i', 's', 't', '.', 'x', 'm', 'l', 0};
426 WCHAR path
[MAX_PATH
];
428 char buffer
[256] = {0};
430 if (!pCreateConfigStream
)
432 win_skip("CreateConfigStream not available\n");
436 create_xml_file(file
);
437 GetFullPathNameW(file
, MAX_PATH
, path
, NULL
);
439 hr
= pCreateConfigStream(NULL
, &stream
);
440 todo_wine
ok(hr
== E_FAIL
||
441 broken(hr
== HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND
)) || /* some WinXP, Win2K3 and Win7 */
442 broken(hr
== S_OK
&& !stream
), /* some Win2K3 */
443 "CreateConfigStream returned %x\n", hr
);
445 hr
= pCreateConfigStream(path
, NULL
);
446 todo_wine
ok(hr
== COR_E_NULLREFERENCE
, "CreateConfigStream returned %x\n", hr
);
448 hr
= pCreateConfigStream(NULL
, NULL
);
449 todo_wine
ok(hr
== COR_E_NULLREFERENCE
, "CreateConfigStream returned %x\n", hr
);
451 hr
= pCreateConfigStream(nonexistent
, &stream
);
452 todo_wine
ok(hr
== COR_E_FILENOTFOUND
, "CreateConfigStream returned %x\n", hr
);
453 ok(stream
== NULL
, "Expected stream to be NULL\n");
455 hr
= pCreateConfigStream(path
, &stream
);
456 todo_wine
ok(hr
== S_OK
, "CreateConfigStream failed, hr=%x\n", hr
);
457 todo_wine
ok(stream
!= NULL
, "Expected non-NULL stream\n");
464 IStream
*stream2
= NULL
;
466 hr
= IStream_Read(stream
, buffer
, strlen(xmldata
), &count
);
467 ok(hr
== S_OK
, "IStream_Read failed, hr=%x\n", hr
);
468 ok(count
== strlen(xmldata
), "wrong count: %u\n", count
);
469 ok(!strcmp(buffer
, xmldata
), "Strings do not match\n");
471 hr
= IStream_Write(stream
, xmldata
, strlen(xmldata
), &count
);
472 ok(hr
== E_FAIL
, "IStream_Write returned hr=%x\n", hr
);
474 pos
.QuadPart
= strlen(xmldata
);
475 hr
= IStream_Seek(stream
, pos
, STREAM_SEEK_SET
, NULL
);
476 ok(hr
== E_NOTIMPL
, "IStream_Seek returned hr=%x\n", hr
);
478 size
.QuadPart
= strlen(xmldata
);
479 hr
= IStream_SetSize(stream
, size
);
480 ok(hr
== E_NOTIMPL
, "IStream_SetSize returned hr=%x\n", hr
);
482 hr
= IStream_Clone(stream
, &stream2
);
483 ok(hr
== E_NOTIMPL
, "IStream_Clone returned hr=%x\n", hr
);
485 hr
= IStream_Commit(stream
, STGC_DEFAULT
);
486 ok(hr
== E_NOTIMPL
, "IStream_Commit returned hr=%x\n", hr
);
488 hr
= IStream_Revert(stream
);
489 ok(hr
== E_NOTIMPL
, "IStream_Revert returned hr=%x\n", hr
);
491 hr
= IStream_Release(stream
);
492 ok(hr
== S_OK
, "IStream_Release returned hr=%x\n", hr
);
497 static void test_createinstance(void)
502 if (no_legacy_runtimes
)
504 /* If we don't have 1.x or 2.0 runtimes, we should at least have .NET 4. */
505 ok(pCreateInterface
!= NULL
, "no legacy runtimes or .NET 4 interfaces available\n");
508 if(!pCreateInterface
)
510 win_skip("Function CreateInterface not found.\n");
514 hr
= pCreateInterface(&CLSID_CLRMetaHost
, &IID_ICLRMetaHost
, (void**)&host
);
517 ICLRMetaHost_Release(host
);
521 win_skip(".NET 4 not installed.\n");
525 static void test_createdomain(void)
527 static const WCHAR test_name
[] = {'t','e','s','t',0};
528 static const WCHAR test2_name
[] = {'t','e','s','t','2',0};
529 ICLRMetaHost
*metahost
;
530 ICLRRuntimeInfo
*runtimeinfo
;
531 ICorRuntimeHost
*runtimehost
;
532 IUnknown
*domain
, *defaultdomain_unk
, *defaultdomain
, *newdomain_unk
, *newdomain
, *domainsetup
,
533 *newdomain2_unk
, *newdomain2
;
536 if (!pCLRCreateInstance
)
538 win_skip("Function CLRCreateInstance not found.\n");
542 hr
= pCLRCreateInstance(&CLSID_CLRMetaHost
, &IID_ICLRMetaHost
, (void **)&metahost
);
543 ok(SUCCEEDED(hr
), "CLRCreateInstance failed, hr=%#.8x\n", hr
);
545 hr
= ICLRMetaHost_GetRuntime(metahost
, v4_0
, &IID_ICLRRuntimeInfo
, (void **)&runtimeinfo
);
546 ok(SUCCEEDED(hr
), "ICLRMetaHost::GetRuntime failed, hr=%#.8x\n", hr
);
548 hr
= ICLRRuntimeInfo_GetInterface(runtimeinfo
, &CLSID_CorRuntimeHost
, &IID_ICorRuntimeHost
,
549 (void **)&runtimehost
);
550 ok(SUCCEEDED(hr
), "ICLRRuntimeInfo::GetInterface failed, hr=%#.8x\n", hr
);
552 hr
= ICorRuntimeHost_Start(runtimehost
);
553 ok(SUCCEEDED(hr
), "ICorRuntimeHost::Start failed, hr=%#.8x\n", hr
);
555 hr
= ICorRuntimeHost_GetDefaultDomain(runtimehost
, &domain
);
556 ok(SUCCEEDED(hr
), "ICorRuntimeHost::GetDefaultDomain failed, hr=%#.8x\n", hr
);
558 hr
= IUnknown_QueryInterface(domain
, &IID_IUnknown
, (void **)&defaultdomain_unk
);
559 ok(SUCCEEDED(hr
), "COM object doesn't support IUnknown?!\n");
561 hr
= IUnknown_QueryInterface(domain
, &IID__AppDomain
, (void **)&defaultdomain
);
562 ok(SUCCEEDED(hr
), "AppDomain object doesn't support _AppDomain interface\n");
564 IUnknown_Release(domain
);
566 hr
= ICorRuntimeHost_CreateDomain(runtimehost
, test_name
, NULL
, &domain
);
567 ok(SUCCEEDED(hr
), "ICorRuntimeHost::CreateDomain failed, hr=%#.8x\n", hr
);
569 hr
= IUnknown_QueryInterface(domain
, &IID_IUnknown
, (void **)&newdomain_unk
);
570 ok(SUCCEEDED(hr
), "COM object doesn't support IUnknown?!\n");
572 hr
= IUnknown_QueryInterface(domain
, &IID__AppDomain
, (void **)&newdomain
);
573 ok(SUCCEEDED(hr
), "AppDomain object doesn't support _AppDomain interface\n");
575 IUnknown_Release(domain
);
577 ok(defaultdomain_unk
!= newdomain_unk
, "New and default domain objects are the same\n");
579 hr
= ICorRuntimeHost_CreateDomainSetup(runtimehost
, &domainsetup
);
580 ok(SUCCEEDED(hr
), "ICorRuntimeHost::CreateDomainSetup failed, hr=%#.8x\n", hr
);
582 hr
= ICorRuntimeHost_CreateDomainEx(runtimehost
, test2_name
, domainsetup
, NULL
, &domain
);
583 ok(SUCCEEDED(hr
), "ICorRuntimeHost::CreateDomainEx failed, hr=%#.8x\n", hr
);
585 hr
= IUnknown_QueryInterface(domain
, &IID_IUnknown
, (void **)&newdomain2_unk
);
586 ok(SUCCEEDED(hr
), "COM object doesn't support IUnknown?!\n");
588 hr
= IUnknown_QueryInterface(domain
, &IID__AppDomain
, (void **)&newdomain2
);
589 ok(SUCCEEDED(hr
), "AppDomain object doesn't support _AppDomain interface\n");
591 IUnknown_Release(domain
);
593 ok(defaultdomain_unk
!= newdomain2_unk
, "New and default domain objects are the same\n");
594 ok(newdomain_unk
!= newdomain2_unk
, "Both new domain objects are the same\n");
596 IUnknown_Release(newdomain2
);
597 IUnknown_Release(newdomain2_unk
);
598 IUnknown_Release(domainsetup
);
599 IUnknown_Release(newdomain
);
600 IUnknown_Release(newdomain_unk
);
601 IUnknown_Release(defaultdomain
);
602 IUnknown_Release(defaultdomain_unk
);
604 ICorRuntimeHost_Release(runtimehost
);
606 ICLRRuntimeInfo_Release(runtimeinfo
);
608 ICLRMetaHost_Release(metahost
);
616 if (!init_functionpointers())
619 argc
= winetest_get_mainargs(&argv
);
620 if (argc
>= 3 && !strcmp(argv
[2], "check_runtime"))
622 int result
= check_runtime();
623 FreeLibrary(hmscoree
);
628 test_loadlibraryshim();
629 test_createconfigstream();
630 test_createinstance();
632 if (runtime_is_usable())
637 FreeLibrary(hmscoree
);