1 /* Unit test suite for SHReg* functions
3 * Copyright 2002 Juergen Schmied
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
24 #include "wine/test.h"
32 /* Keys used for testing */
33 #define REG_TEST_KEY "Software\\Wine\\Test"
34 #define REG_CURRENT_VERSION "Software\\Microsoft\\Windows\\CurrentVersion\\explorer"
36 static HMODULE hshlwapi
;
37 typedef DWORD (WINAPI
*SHCopyKeyA_func
)(HKEY
,LPCSTR
,HKEY
,DWORD
);
38 static SHCopyKeyA_func pSHCopyKeyA
;
39 typedef DWORD (WINAPI
*SHRegGetPathA_func
)(HKEY
,LPCSTR
,LPCSTR
,LPSTR
,DWORD
);
40 static SHRegGetPathA_func pSHRegGetPathA
;
42 static char sTestpath1
[] = "%LONGSYSTEMVAR%\\subdir1";
43 static char sTestpath2
[] = "%FOO%\\subdir1";
45 static const char * sEnvvar1
= "bar";
46 static const char * sEnvvar2
= "ImARatherLongButIndeedNeededString";
48 static char sExpTestpath1
[MAX_PATH
];
49 static char sExpTestpath2
[MAX_PATH
];
50 static DWORD nExpLen1
;
51 static DWORD nExpLen2
;
53 static const char * sEmptyBuffer
="0123456789";
55 /* delete key and all its subkeys */
56 static DWORD
delete_key( HKEY hkey
, LPCSTR parent
, LPCSTR keyname
)
63 /* open the parent of the key to close */
64 ret
= RegOpenKeyExA( HKEY_CURRENT_USER
, parent
, 0, KEY_ALL_ACCESS
, &parentKey
);
65 if (ret
!= ERROR_SUCCESS
)
68 ret
= SHDeleteKeyA( parentKey
, keyname
);
69 RegCloseKey(parentKey
);
74 static HKEY
create_test_entries(void)
78 DWORD nExpectedLen1
, nExpectedLen2
;
80 SetEnvironmentVariableA("LONGSYSTEMVAR", sEnvvar1
);
81 SetEnvironmentVariableA("FOO", sEnvvar2
);
83 ret
= RegCreateKeyA(HKEY_CURRENT_USER
, REG_TEST_KEY
, &hKey
);
84 ok( ERROR_SUCCESS
== ret
, "RegCreateKeyA failed, ret=%u\n", ret
);
88 ok(!RegSetValueExA(hKey
,"Test1",0,REG_EXPAND_SZ
, (LPBYTE
) sTestpath1
, strlen(sTestpath1
)+1), "RegSetValueExA failed\n");
89 ok(!RegSetValueExA(hKey
,"Test2",0,REG_SZ
, (LPBYTE
) sTestpath1
, strlen(sTestpath1
)+1), "RegSetValueExA failed\n");
90 ok(!RegSetValueExA(hKey
,"Test3",0,REG_EXPAND_SZ
, (LPBYTE
) sTestpath2
, strlen(sTestpath2
)+1), "RegSetValueExA failed\n");
93 nExpLen1
= ExpandEnvironmentStringsA(sTestpath1
, sExpTestpath1
, sizeof(sExpTestpath1
));
94 nExpLen2
= ExpandEnvironmentStringsA(sTestpath2
, sExpTestpath2
, sizeof(sExpTestpath2
));
96 nExpectedLen1
= strlen(sTestpath1
) - strlen("%LONGSYSTEMVAR%") + strlen(sEnvvar1
) + 1;
97 nExpectedLen2
= strlen(sTestpath2
) - strlen("%FOO%") + strlen(sEnvvar2
) + 1;
98 /* ExpandEnvironmentStringsA on NT4 returns 2x the correct result */
99 trace("sExplen1 = (%d)\n", nExpLen1
);
100 if (nExpectedLen1
!= nExpLen1
)
101 trace( "Expanding %s failed (expected %d) - known bug in NT4\n", sTestpath1
, nExpectedLen1
);
103 trace("sExplen2 = (%d)\n", nExpLen2
);
104 if (nExpectedLen2
!= nExpLen2
)
105 trace( "Expanding %s failed (expected %d) - known bug in NT4\n", sTestpath2
, nExpectedLen2
);
107 /* Make sure we carry on with correct values */
108 nExpLen1
= nExpectedLen1
;
109 nExpLen2
= nExpectedLen2
;
113 static void test_SHGetValue(void)
120 strcpy(buf
, sEmptyBuffer
);
123 dwRet
= SHGetValueA(HKEY_CURRENT_USER
, REG_TEST_KEY
, "Test1", &dwType
, buf
, &dwSize
);
124 ok( ERROR_SUCCESS
== dwRet
, "SHGetValueA failed, ret=%u\n", dwRet
);
125 ok( 0 == strcmp(sExpTestpath1
, buf
) ||
126 broken(0 == strcmp(sTestpath1
, buf
)), /* IE4.x */
127 "Comparing of (%s) with (%s) failed\n", buf
, sExpTestpath1
);
128 ok( REG_SZ
== dwType
||
129 broken(REG_EXPAND_SZ
== dwType
), /* IE4.x */
130 "Expected REG_SZ, got (%u)\n", dwType
);
132 strcpy(buf
, sEmptyBuffer
);
135 dwRet
= SHGetValueA(HKEY_CURRENT_USER
, REG_TEST_KEY
, "Test2", &dwType
, buf
, &dwSize
);
136 ok( ERROR_SUCCESS
== dwRet
, "SHGetValueA failed, ret=%u\n", dwRet
);
137 ok( 0 == strcmp(sTestpath1
, buf
) , "Comparing of (%s) with (%s) failed\n", buf
, sTestpath1
);
138 ok( REG_SZ
== dwType
, "Expected REG_SZ, got (%u)\n", dwType
);
141 static void test_SHGetRegPath(void)
149 strcpy(buf
, sEmptyBuffer
);
150 dwRet
= (*pSHRegGetPathA
)(HKEY_CURRENT_USER
, REG_TEST_KEY
, "Test1", buf
, 0);
151 ok( ERROR_SUCCESS
== dwRet
, "SHRegGetPathA failed, ret=%u\n", dwRet
);
152 ok( 0 == strcmp(sExpTestpath1
, buf
) , "Comparing (%s) with (%s) failed\n", buf
, sExpTestpath1
);
155 static void test_SHQUeryValueEx(void)
162 const char * sTestedFunction
= "";
163 DWORD nUsedBuffer1
,nUsedBuffer2
;
165 sTestedFunction
= "RegOpenKeyExA";
166 dwRet
= RegOpenKeyExA(HKEY_CURRENT_USER
, REG_TEST_KEY
, 0, KEY_QUERY_VALUE
, &hKey
);
167 ok( ERROR_SUCCESS
== dwRet
, "%s failed, ret=%u\n", sTestedFunction
, dwRet
);
169 /****** SHQueryValueExA ******/
171 sTestedFunction
= "SHQueryValueExA";
172 nUsedBuffer1
= max(strlen(sExpTestpath1
)+1, strlen(sTestpath1
)+1);
173 nUsedBuffer2
= max(strlen(sExpTestpath2
)+1, strlen(sTestpath2
)+1);
175 * Case 1.1 All arguments are NULL
177 dwRet
= SHQueryValueExA( hKey
, "Test1", NULL
, NULL
, NULL
, NULL
);
178 ok( ERROR_SUCCESS
== dwRet
, "%s failed, ret=%u\n", sTestedFunction
, dwRet
);
181 * Case 1.2 dwType is set
184 dwRet
= SHQueryValueExA( hKey
, "Test1", NULL
, &dwType
, NULL
, NULL
);
185 ok( ERROR_SUCCESS
== dwRet
, "%s failed, ret=%u\n", sTestedFunction
, dwRet
);
186 ok( REG_SZ
== dwType
, "Expected REG_SZ, got (%u)\n", dwType
);
190 * dwExpanded < dwUnExpanded
193 dwRet
= SHQueryValueExA( hKey
, "Test1", NULL
, NULL
, NULL
, &dwSize
);
194 ok( ERROR_SUCCESS
== dwRet
, "%s failed, ret=%u\n", sTestedFunction
, dwRet
);
195 ok( dwSize
== nUsedBuffer1
, "Buffer sizes (%u) and (%u) are not equal\n", dwSize
, nUsedBuffer1
);
198 * dwExpanded > dwUnExpanded
201 dwRet
= SHQueryValueExA( hKey
, "Test3", NULL
, NULL
, NULL
, &dwSize
);
202 ok( ERROR_SUCCESS
== dwRet
, "%s failed, ret=%u\n", sTestedFunction
, dwRet
);
203 ok( dwSize
>= nUsedBuffer2
||
204 broken(dwSize
== (strlen(sTestpath2
) + 1)), /* < IE4.x */
205 "Buffer size (%u) should be >= (%u)\n", dwSize
, nUsedBuffer2
);
208 * Case 1 string shrinks during expanding
210 strcpy(buf
, sEmptyBuffer
);
213 dwRet
= SHQueryValueExA( hKey
, "Test1", NULL
, &dwType
, buf
, &dwSize
);
214 ok( ERROR_MORE_DATA
== dwRet
, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet
);
215 ok( 0 == strcmp(sEmptyBuffer
, buf
) , "Comparing (%s) with (%s) failed\n", buf
, sEmptyBuffer
);
216 ok( dwSize
== nUsedBuffer1
, "Buffer sizes (%u) and (%u) are not equal\n", dwSize
, nUsedBuffer1
);
217 ok( REG_SZ
== dwType
||
218 broken(REG_EXPAND_SZ
== dwType
), /* < IE6 */
219 "Expected REG_SZ, got (%u)\n", dwType
);
222 * string grows during expanding
223 * dwSize is smaller than the size of the unexpanded string
225 strcpy(buf
, sEmptyBuffer
);
228 dwRet
= SHQueryValueExA( hKey
, "Test3", NULL
, &dwType
, buf
, &dwSize
);
229 ok( ERROR_MORE_DATA
== dwRet
, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet
);
230 ok( 0 == strcmp(sEmptyBuffer
, buf
) , "Comparing (%s) with (%s) failed\n", buf
, sEmptyBuffer
);
231 ok( dwSize
>= nUsedBuffer2
||
232 broken(dwSize
== (strlen(sTestpath2
) + 1)), /* < IE6 */
233 "Buffer size (%u) should be >= (%u)\n", dwSize
, nUsedBuffer2
);
234 ok( REG_SZ
== dwType
||
235 broken(REG_EXPAND_SZ
== dwType
), /* < IE6 */
236 "Expected REG_SZ, got (%u)\n", dwType
);
239 * string grows during expanding
240 * dwSize is larger than the size of the unexpanded string, but
241 * smaller than the part before the backslash. If the unexpanded
242 * string fits into the buffer, it can get cut when expanded.
244 strcpy(buf
, sEmptyBuffer
);
245 dwSize
= strlen(sEnvvar2
) - 2;
247 dwRet
= SHQueryValueExA( hKey
, "Test3", NULL
, &dwType
, buf
, &dwSize
);
248 ok( ERROR_MORE_DATA
== dwRet
||
249 broken(ERROR_ENVVAR_NOT_FOUND
== dwRet
) || /* IE5.5 */
250 broken(ERROR_SUCCESS
== dwRet
), /* < IE5.5*/
251 "Expected ERROR_MORE_DATA, got (%u)\n", dwRet
);
255 ok( (0 == strcmp("", buf
)) || (0 == strcmp(sTestpath2
, buf
)),
256 "Expected empty or unexpanded string (win98), got (%s)\n", buf
);
259 ok( dwSize
>= nUsedBuffer2
||
260 broken(dwSize
== (strlen("") + 1)), /* < IE 5.5 */
261 "Buffer size (%u) should be >= (%u)\n", dwSize
, nUsedBuffer2
);
262 ok( REG_SZ
== dwType
, "Expected REG_SZ, got (%u)\n", dwType
);
265 * string grows during expanding
266 * dwSize is larger than the size of the part before the backslash,
267 * but smaller than the expanded string. If the unexpanded string fits
268 * into the buffer, it can get cut when expanded.
270 strcpy(buf
, sEmptyBuffer
);
271 dwSize
= nExpLen2
- 4;
273 dwRet
= SHQueryValueExA( hKey
, "Test3", NULL
, &dwType
, buf
, &dwSize
);
274 ok( ERROR_MORE_DATA
== dwRet
||
275 broken(ERROR_ENVVAR_NOT_FOUND
== dwRet
) || /* IE5.5 */
276 broken(ERROR_SUCCESS
== dwRet
), /* < IE5.5 */
277 "Expected ERROR_MORE_DATA, got (%u)\n", dwRet
);
281 ok( (0 == strcmp("", buf
)) || (0 == strcmp(sEnvvar2
, buf
)) ||
282 broken(0 == strcmp(sTestpath2
, buf
)), /* IE 5.5 */
283 "Expected empty or first part of the string \"%s\", got \"%s\"\n", sEnvvar2
, buf
);
286 ok( dwSize
>= nUsedBuffer2
||
287 broken(dwSize
== (strlen(sEnvvar2
) + 1)) || /* IE4.01 SP1 (W98) and IE5 (W98SE) */
288 broken(dwSize
== (strlen("") + 1)), /* IE4.01 (NT4) and IE5.x (W2K) */
289 "Buffer size (%u) should be >= (%u)\n", dwSize
, nUsedBuffer2
);
290 ok( REG_SZ
== dwType
, "Expected REG_SZ, got (%u)\n", dwType
);
293 * The buffer is NULL but the size is set
295 strcpy(buf
, sEmptyBuffer
);
298 dwRet
= SHQueryValueExA( hKey
, "Test3", NULL
, &dwType
, NULL
, &dwSize
);
299 ok( ERROR_SUCCESS
== dwRet
, "%s failed, ret=%u\n", sTestedFunction
, dwRet
);
300 ok( dwSize
>= nUsedBuffer2
||
301 broken(dwSize
== (strlen(sTestpath2
) + 1)), /* IE4.01 SP1 (Win98) */
302 "Buffer size (%u) should be >= (%u)\n", dwSize
, nUsedBuffer2
);
303 ok( REG_SZ
== dwType
, "Expected REG_SZ, got (%u)\n", dwType
);
308 static void test_SHCopyKey(void)
310 HKEY hKeySrc
, hKeyDst
;
315 win_skip("SHCopyKeyA is not available\n");
319 /* Delete existing destination sub keys */
321 if (!RegOpenKeyA(HKEY_CURRENT_USER
, REG_TEST_KEY
"\\CopyDestination", &hKeyDst
) && hKeyDst
)
323 SHDeleteKeyA(hKeyDst
, NULL
);
324 RegCloseKey(hKeyDst
);
328 dwRet
= RegCreateKeyA(HKEY_CURRENT_USER
, REG_TEST_KEY
"\\CopyDestination", &hKeyDst
);
329 if (dwRet
|| !hKeyDst
)
331 ok( 0, "Destination couldn't be created, RegCreateKeyA returned (%u)\n", dwRet
);
336 dwRet
= RegOpenKeyA(HKEY_LOCAL_MACHINE
, REG_CURRENT_VERSION
, &hKeySrc
);
337 if (dwRet
|| !hKeySrc
)
339 ok( 0, "Source couldn't be opened, RegOpenKeyA returned (%u)\n", dwRet
);
340 RegCloseKey(hKeyDst
);
344 dwRet
= (*pSHCopyKeyA
)(hKeySrc
, NULL
, hKeyDst
, 0);
345 ok ( ERROR_SUCCESS
== dwRet
, "Copy failed, ret=(%u)\n", dwRet
);
347 RegCloseKey(hKeySrc
);
348 RegCloseKey(hKeyDst
);
350 /* Check we copied the sub keys, i.e. something that's on every windows system (including Wine) */
352 dwRet
= RegOpenKeyA(HKEY_CURRENT_USER
, REG_TEST_KEY
"\\CopyDestination\\Shell Folders", &hKeyDst
);
353 if (dwRet
|| !hKeyDst
)
355 ok ( 0, "Copy couldn't be opened, RegOpenKeyA returned (%u)\n", dwRet
);
359 /* And the we copied the values too */
360 ok(!SHQueryValueExA(hKeyDst
, "Common AppData", NULL
, NULL
, NULL
, NULL
), "SHQueryValueExA failed\n");
362 RegCloseKey(hKeyDst
);
365 static void test_SHDeleteKey(void)
367 HKEY hKeyTest
, hKeyS
;
371 if (!RegOpenKeyA(HKEY_CURRENT_USER
, REG_TEST_KEY
, &hKeyTest
))
373 if (!RegCreateKey(hKeyTest
, "ODBC", &hKeyS
))
377 if (!RegCreateKey(hKeyS
, "ODBC.INI", &hKeyO
))
381 if (!RegCreateKey(hKeyS
, "ODBCINST.INI", &hKeyO
))
389 RegCloseKey (hKeyTest
);
395 dwRet
= SHDeleteKeyA(HKEY_CURRENT_USER
, REG_TEST_KEY
"\\ODBC");
396 ok ( ERROR_SUCCESS
== dwRet
, "SHDeleteKey failed, ret=(%u)\n", dwRet
);
398 dwRet
= RegOpenKeyA(HKEY_CURRENT_USER
, REG_TEST_KEY
"\\ODBC", &hKeyS
);
399 ok ( ERROR_FILE_NOT_FOUND
== dwRet
, "SHDeleteKey did not delete\n");
401 if (dwRet
== ERROR_SUCCESS
)
405 ok( 0, "Could not set up SHDeleteKey test\n");
410 HKEY hkey
= create_test_entries();
414 hshlwapi
= GetModuleHandleA("shlwapi.dll");
415 pSHCopyKeyA
=(SHCopyKeyA_func
)GetProcAddress(hshlwapi
,"SHCopyKeyA");
416 pSHRegGetPathA
=(SHRegGetPathA_func
)GetProcAddress(hshlwapi
,"SHRegGetPathA");
418 test_SHQUeryValueEx();
422 delete_key( hkey
, "Software\\Wine", "Test" );