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
25 #include "wine/test.h"
27 static HMODULE hmscoree
;
29 static HRESULT (WINAPI
*pGetCORVersion
)(LPWSTR
, DWORD
, DWORD
*);
30 static HRESULT (WINAPI
*pGetCORSystemDirectory
)(LPWSTR
, DWORD
, DWORD
*);
31 static HRESULT (WINAPI
*pGetRequestedRuntimeInfo
)(LPCWSTR
, LPCWSTR
, LPCWSTR
, DWORD
, DWORD
, LPWSTR
, DWORD
, DWORD
*, LPWSTR
, DWORD
, DWORD
*);
32 static HRESULT (WINAPI
*pLoadLibraryShim
)(LPCWSTR
, LPCWSTR
, LPVOID
, HMODULE
*);
33 static HRESULT (WINAPI
*pCreateConfigStream
)(LPCWSTR
, IStream
**);
35 static BOOL
init_functionpointers(void)
37 hmscoree
= LoadLibraryA("mscoree.dll");
41 win_skip("mscoree.dll not available\n");
45 pGetCORVersion
= (void *)GetProcAddress(hmscoree
, "GetCORVersion");
46 pGetCORSystemDirectory
= (void *)GetProcAddress(hmscoree
, "GetCORSystemDirectory");
47 pGetRequestedRuntimeInfo
= (void *)GetProcAddress(hmscoree
, "GetRequestedRuntimeInfo");
48 pLoadLibraryShim
= (void *)GetProcAddress(hmscoree
, "LoadLibraryShim");
49 pCreateConfigStream
= (void *)GetProcAddress(hmscoree
, "CreateConfigStream");
51 if (!pGetCORVersion
|| !pGetCORSystemDirectory
|| !pGetRequestedRuntimeInfo
|| !pLoadLibraryShim
)
53 win_skip("functions not available\n");
54 FreeLibrary(hmscoree
);
61 static void test_versioninfo(void)
63 const WCHAR v2_0
[] = {'v','2','.','0','.','5','0','7','2','7',0};
64 const WCHAR v1_1
[] = {'v','1','.','1','.','4','3','2','2',0};
66 WCHAR version
[MAX_PATH
];
71 if (0) /* crashes on <= w2k3 */
73 hr
= pGetCORVersion(NULL
, MAX_PATH
, &size
);
74 ok(hr
== E_POINTER
,"GetCORVersion returned %08x\n", hr
);
77 hr
= pGetCORVersion(version
, 1, &size
);
78 if (hr
== CLR_E_SHIM_RUNTIME
)
80 /* FIXME: Get Mono packaged properly so we can fail here. */
81 todo_wine
ok(hr
== HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
),"GetCORVersion returned %08x\n", hr
);
82 skip("No .NET runtimes are installed\n");
86 ok(hr
== HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
),"GetCORVersion returned %08x\n", hr
);
88 hr
= pGetCORVersion(version
, MAX_PATH
, &size
);
89 ok(hr
== S_OK
,"GetCORVersion returned %08x\n", hr
);
91 trace("latest installed .net runtime: %s\n", wine_dbgstr_w(version
));
93 hr
= pGetCORSystemDirectory(path
, MAX_PATH
, &size
);
94 ok(hr
== S_OK
, "GetCORSystemDirectory returned %08x\n", hr
);
95 /* size includes terminating null-character */
96 ok(size
== (lstrlenW(path
) + 1),"size is %d instead of %d\n", size
, (lstrlenW(path
) + 1));
100 hr
= pGetCORSystemDirectory(path
, path_len
-1 , &size
);
101 ok(hr
== HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
), "GetCORSystemDirectory returned %08x\n", hr
);
103 if (0) /* crashes on <= w2k3 */
105 hr
= pGetCORSystemDirectory(NULL
, MAX_PATH
, &size
);
106 ok(hr
== HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
), "GetCORSystemDirectory returned %08x\n", hr
);
109 hr
= pGetCORSystemDirectory(path
, MAX_PATH
, NULL
);
110 ok(hr
== E_POINTER
,"GetCORSystemDirectory returned %08x\n", hr
);
112 trace("latest installed .net installed in directory: %s\n", wine_dbgstr_w(path
));
114 /* test GetRequestedRuntimeInfo, first get info about different versions of runtime */
115 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
117 if(hr
== CLR_E_SHIM_RUNTIME
) return; /* skipping rest of tests on win2k as .net 2.0 not installed */
119 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
120 trace(" installed in directory %s is .net version %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(version
));
122 hr
= pGetRequestedRuntimeInfo( NULL
, v1_1
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
123 ok(hr
== S_OK
|| hr
== CLR_E_SHIM_RUNTIME
/*v1_1 not installed*/, "GetRequestedRuntimeInfo returned %08x\n", hr
);
125 trace(" installed in directory %s is .net version %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(version
));
126 /* version number NULL not allowed without RUNTIME_INFO_UPGRADE_VERSION flag */
127 hr
= pGetRequestedRuntimeInfo( NULL
, NULL
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
128 ok(hr
== CLR_E_SHIM_RUNTIME
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
129 /* with RUNTIME_INFO_UPGRADE_VERSION flag and version number NULL, latest installed version is returned */
130 hr
= pGetRequestedRuntimeInfo( NULL
, NULL
, NULL
, 0, RUNTIME_INFO_UPGRADE_VERSION
, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
131 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
133 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0
, NULL
, 0, 0, path
, 1, &path_len
, version
, MAX_PATH
, &size
);
134 ok(hr
== HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
), "GetRequestedRuntimeInfo returned %08x\n", hr
);
136 /* if one of the buffers is NULL, the other one is still happily filled */
137 memset(version
, 0, sizeof(version
));
138 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0
, NULL
, 0, 0, NULL
, MAX_PATH
, &path_len
, version
, MAX_PATH
, &size
);
139 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
140 ok(!winetest_strcmpW(version
, v2_0
), "version is %s , expected %s\n", wine_dbgstr_w(version
), wine_dbgstr_w(v2_0
));
141 /* With NULL-pointer for bufferlength, the buffer itself still gets filled with correct string */
142 memset(version
, 0, sizeof(version
));
143 hr
= pGetRequestedRuntimeInfo( NULL
, v2_0
, NULL
, 0, 0, path
, MAX_PATH
, &path_len
, version
, MAX_PATH
, NULL
);
144 ok(hr
== S_OK
, "GetRequestedRuntimeInfo returned %08x\n", hr
);
145 ok(!winetest_strcmpW(version
, v2_0
), "version is %s , expected %s\n", wine_dbgstr_w(version
), wine_dbgstr_w(v2_0
));
148 static void test_loadlibraryshim(void)
150 const WCHAR v4_0
[] = {'v','4','.','0','.','3','0','3','1','9',0};
151 const WCHAR v2_0
[] = {'v','2','.','0','.','5','0','7','2','7',0};
152 const WCHAR v1_1
[] = {'v','1','.','1','.','4','3','2','2',0};
153 const WCHAR vbogus
[] = {'v','b','o','g','u','s',0};
154 const WCHAR fusion
[] = {'f','u','s','i','o','n',0};
155 const WCHAR fusiondll
[] = {'f','u','s','i','o','n','.','d','l','l',0};
156 const WCHAR nosuchdll
[] = {'j','n','v','n','l','.','d','l','l',0};
157 const WCHAR gdidll
[] = {'g','d','i','3','2','.','d','l','l',0};
159 const WCHAR
*latest
= NULL
;
160 CHAR latestA
[MAX_PATH
];
162 CHAR dllpath
[MAX_PATH
];
164 hr
= pLoadLibraryShim(fusion
, v1_1
, NULL
, &hdll
);
165 ok(hr
== S_OK
|| hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
170 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
172 todo_wine
ok(StrStrIA(dllpath
, "v1.1.4322") != 0, "incorrect fusion.dll path %s\n", dllpath
);
173 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
178 hr
= pLoadLibraryShim(fusion
, v2_0
, NULL
, &hdll
);
179 ok(hr
== S_OK
|| hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
184 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
186 todo_wine
ok(StrStrIA(dllpath
, "v2.0.50727") != 0, "incorrect fusion.dll path %s\n", dllpath
);
187 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
192 hr
= pLoadLibraryShim(fusion
, v4_0
, NULL
, &hdll
);
193 ok(hr
== S_OK
|| hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
196 /* LoadLibraryShim with a NULL version prefers 2.0 and earlier */
200 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
202 todo_wine
ok(StrStrIA(dllpath
, "v4.0.30319") != 0, "incorrect fusion.dll path %s\n", dllpath
);
203 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
208 hr
= pLoadLibraryShim(fusion
, vbogus
, NULL
, &hdll
);
209 todo_wine
ok(hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
213 WideCharToMultiByte(CP_ACP
, 0, latest
, -1, latestA
, MAX_PATH
, NULL
, NULL
);
215 hr
= pLoadLibraryShim(fusion
, NULL
, NULL
, &hdll
);
216 ok(hr
== S_OK
, "LoadLibraryShim failed, hr=%x\n", hr
);
219 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
222 todo_wine
ok(StrStrIA(dllpath
, latestA
) != 0, "incorrect fusion.dll path %s\n", dllpath
);
223 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
228 hr
= pLoadLibraryShim(fusiondll
, NULL
, NULL
, &hdll
);
229 ok(hr
== S_OK
, "LoadLibraryShim failed, hr=%x\n", hr
);
232 GetModuleFileNameA(hdll
, dllpath
, MAX_PATH
);
235 todo_wine
ok(StrStrIA(dllpath
, latestA
) != 0, "incorrect fusion.dll path %s\n", dllpath
);
236 ok(StrStrIA(dllpath
, "fusion.dll") != 0, "incorrect fusion.dll path %s\n", dllpath
);
241 hr
= pLoadLibraryShim(nosuchdll
, latest
, NULL
, &hdll
);
242 ok(hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
246 hr
= pLoadLibraryShim(gdidll
, latest
, NULL
, &hdll
);
247 todo_wine
ok(hr
== E_HANDLE
, "LoadLibraryShim failed, hr=%x\n", hr
);
252 static const char xmldata
[] =
253 "<?xml version=\"1.0\" ?>\n"
254 "<!DOCTYPE Config>\n"
256 " <Name>Test</Name>\n"
257 " <Value>1234</Value>\n"
260 static void create_xml_file(LPCWSTR filename
)
262 DWORD dwNumberOfBytesWritten
;
263 HANDLE hfile
= CreateFileW(filename
, GENERIC_WRITE
, 0, NULL
,
264 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
265 ok(hfile
!= INVALID_HANDLE_VALUE
, "File creation failed\n");
266 WriteFile(hfile
, xmldata
, sizeof(xmldata
) - 1, &dwNumberOfBytesWritten
, NULL
);
270 static void test_createconfigstream(void)
272 IStream
*stream
= NULL
;
273 WCHAR file
[] = {'c', 'o', 'n', 'f', '.', 'x', 'm', 'l', 0};
274 WCHAR nonexistent
[] = {'n', 'o', 'n', 'e', 'x', 'i', 's', 't', '.', 'x', 'm', 'l', 0};
275 WCHAR path
[MAX_PATH
];
277 char buffer
[256] = {0};
279 if (!pCreateConfigStream
)
281 win_skip("CreateConfigStream not available\n");
285 create_xml_file(file
);
286 GetFullPathNameW(file
, MAX_PATH
, path
, NULL
);
288 hr
= pCreateConfigStream(NULL
, &stream
);
289 todo_wine
ok(hr
== E_FAIL
||
290 broken(hr
== HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND
)) || /* some WinXP, Win2K3 and Win7 */
291 broken(hr
== S_OK
&& !stream
), /* some Win2K3 */
292 "CreateConfigStream returned %x\n", hr
);
294 hr
= pCreateConfigStream(path
, NULL
);
295 todo_wine
ok(hr
== COR_E_NULLREFERENCE
, "CreateConfigStream returned %x\n", hr
);
297 hr
= pCreateConfigStream(NULL
, NULL
);
298 todo_wine
ok(hr
== COR_E_NULLREFERENCE
, "CreateConfigStream returned %x\n", hr
);
300 hr
= pCreateConfigStream(nonexistent
, &stream
);
301 todo_wine
ok(hr
== COR_E_FILENOTFOUND
, "CreateConfigStream returned %x\n", hr
);
302 ok(stream
== NULL
, "Expected stream to be NULL\n");
304 hr
= pCreateConfigStream(path
, &stream
);
305 todo_wine
ok(hr
== S_OK
, "CreateConfigStream failed, hr=%x\n", hr
);
306 todo_wine
ok(stream
!= NULL
, "Expected non-NULL stream\n");
313 IStream
*stream2
= NULL
;
315 hr
= IStream_Read(stream
, buffer
, strlen(xmldata
), &count
);
316 ok(hr
== S_OK
, "IStream_Read failed, hr=%x\n", hr
);
317 ok(count
== strlen(xmldata
), "wrong count: %u\n", count
);
318 ok(!strcmp(buffer
, xmldata
), "Strings do not match\n");
320 hr
= IStream_Write(stream
, xmldata
, strlen(xmldata
), &count
);
321 ok(hr
== E_FAIL
, "IStream_Write returned hr=%x\n", hr
);
323 pos
.QuadPart
= strlen(xmldata
);
324 hr
= IStream_Seek(stream
, pos
, STREAM_SEEK_SET
, NULL
);
325 ok(hr
== E_NOTIMPL
, "IStream_Seek returned hr=%x\n", hr
);
327 size
.QuadPart
= strlen(xmldata
);
328 hr
= IStream_SetSize(stream
, size
);
329 ok(hr
== E_NOTIMPL
, "IStream_SetSize returned hr=%x\n", hr
);
331 hr
= IStream_Clone(stream
, &stream2
);
332 ok(hr
== E_NOTIMPL
, "IStream_Clone returned hr=%x\n", hr
);
334 hr
= IStream_Commit(stream
, STGC_DEFAULT
);
335 ok(hr
== E_NOTIMPL
, "IStream_Commit returned hr=%x\n", hr
);
337 hr
= IStream_Revert(stream
);
338 ok(hr
== E_NOTIMPL
, "IStream_Revert returned hr=%x\n", hr
);
340 hr
= IStream_Release(stream
);
341 ok(hr
== S_OK
, "IStream_Release returned hr=%x\n", hr
);
348 if (!init_functionpointers())
352 test_loadlibraryshim();
353 test_createconfigstream();
355 FreeLibrary(hmscoree
);