2 * Unit tests for profile functions
4 * Copyright (c) 2003 Stefan Leichter
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
24 #include "wine/test.h"
30 #define KEY "ProfileInt"
31 #define SECTION "Test"
32 #define TESTFILE ".\\testwine.ini"
33 #define TESTFILE2 ".\\testwine2.ini"
35 static void check_profile_string_(int line
, const char *section
, const char *name
, const char *file
, const char *expect
)
37 char value
[200] = {0};
38 DWORD ret
= GetPrivateProfileStringA(section
, name
, "default", value
, sizeof(value
), file
);
39 ok_(__FILE__
, line
)(ret
== strlen(expect
), "expected len %u, got %u\n", strlen(expect
), ret
);
40 ok_(__FILE__
, line
)(!strcmp(value
, expect
), "expected %s, got %s\n", debugstr_a(expect
), debugstr_a(value
));
42 #define check_profile_string(a, b, c, d) check_profile_string_(__LINE__, a, b, c, d);
53 static void test_profile_int(void)
55 struct _profileInt profileInt
[]={
56 { NULL
, NULL
, NULL
, NULL
, 70, 0}, /* 0 */
57 { NULL
, NULL
, NULL
, TESTFILE
, -1, 4294967295U},
58 { NULL
, NULL
, NULL
, TESTFILE
, 1, 1},
59 { SECTION
, NULL
, NULL
, TESTFILE
, -1, 4294967295U},
60 { SECTION
, NULL
, NULL
, TESTFILE
, 1, 1},
61 { NULL
, KEY
, NULL
, TESTFILE
, -1, 4294967295U}, /* 5 */
62 { NULL
, KEY
, NULL
, TESTFILE
, 1, 1},
63 { SECTION
, KEY
, NULL
, TESTFILE
, -1, 4294967295U},
64 { SECTION
, KEY
, NULL
, TESTFILE
, 1, 1},
65 { SECTION
, KEY
, "-1", TESTFILE
, -1, 4294967295U},
66 { SECTION
, KEY
, "-1", TESTFILE
, 1, 4294967295U}, /* 10 */
67 { SECTION
, KEY
, "1", TESTFILE
, -1, 1},
68 { SECTION
, KEY
, "1", TESTFILE
, 1, 1},
69 { SECTION
, KEY
, "+1", TESTFILE
, -1, 1},
70 { SECTION
, KEY
, "+1", TESTFILE
, 1, 1},
71 { SECTION
, KEY
, "4294967296", TESTFILE
, -1, 0}, /* 15 */
72 { SECTION
, KEY
, "4294967296", TESTFILE
, 1, 0},
73 { SECTION
, KEY
, "4294967297", TESTFILE
, -1, 1},
74 { SECTION
, KEY
, "4294967297", TESTFILE
, 1, 1},
75 { SECTION
, KEY
, "-4294967297", TESTFILE
, -1, 4294967295U},
76 { SECTION
, KEY
, "-4294967297", TESTFILE
, 1, 4294967295U}, /* 20 */
77 { SECTION
, KEY
, "42A94967297", TESTFILE
, -1, 42},
78 { SECTION
, KEY
, "42A94967297", TESTFILE
, 1, 42},
79 { SECTION
, KEY
, "B4294967297", TESTFILE
, -1, 0},
80 { SECTION
, KEY
, "B4294967297", TESTFILE
, 1, 0},
82 int i
, num_test
= ARRAY_SIZE(profileInt
);
85 DeleteFileA( TESTFILE
);
87 for (i
=0; i
< num_test
; i
++) {
88 if (profileInt
[i
].value
)
89 WritePrivateProfileStringA(SECTION
, KEY
, profileInt
[i
].value
,
90 profileInt
[i
].iniFile
);
92 res
= GetPrivateProfileIntA(profileInt
[i
].section
, profileInt
[i
].key
,
93 profileInt
[i
].defaultVal
, profileInt
[i
].iniFile
);
94 ok((res
== profileInt
[i
].result
), "test<%02d>: ret<%010u> exp<%010u>\n",
95 i
, res
, profileInt
[i
].result
);
98 DeleteFileA( TESTFILE
);
101 static void test_profile_string(void)
103 static WCHAR emptyW
[] = { 0 }; /* if "const", GetPrivateProfileStringW(emptyW, ...) crashes on win2k */
104 static const WCHAR keyW
[] = { 'k','e','y',0 };
105 static const WCHAR sW
[] = { 's',0 };
106 static const WCHAR TESTFILE2W
[] = {'.','\\','t','e','s','t','w','i','n','e','2','.','i','n','i',0};
107 static const WCHAR valsectionW
[] = {'v','a','l','_','e','_','s','e','c','t','i','o','n',0 };
108 static const WCHAR valnokeyW
[] = {'v','a','l','_','n','o','_','k','e','y',0};
115 /* test that lines without an '=' will not be enumerated */
116 /* in the case below, name2 is a key while name3 is not. */
117 char content
[]="[s]\r\nname1=val1\r\nname2=\r\nname3\r\nname4=val4\r\n";
118 char content2
[]="\r\nkey=val_no_section\r\n[]\r\nkey=val_e_section\r\n"
119 "[s]\r\n=val_no_key\r\n[t]\r\n";
120 DeleteFileA( TESTFILE2
);
121 h
= CreateFileA( TESTFILE2
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
122 FILE_ATTRIBUTE_NORMAL
, NULL
);
123 ok( h
!= INVALID_HANDLE_VALUE
, " cannot create %s\n", TESTFILE2
);
124 if( h
== INVALID_HANDLE_VALUE
) return;
125 WriteFile( h
, content
, sizeof(content
), &count
, NULL
);
128 /* enumerate the keys */
129 ret
=GetPrivateProfileStringA( "s", NULL
, "", buf
, sizeof(buf
),
131 for( p
= buf
+ strlen(buf
) + 1; *p
;p
+= strlen(p
)+1)
134 ok( ret
== 18 && !strcmp( buf
, "name1,name2,name4"), "wrong keys returned(%d): %s\n", ret
,
137 /* add a new key to test that the file is quite usable */
138 WritePrivateProfileStringA( "s", "name5", "val5", TESTFILE2
);
139 ret
=GetPrivateProfileStringA( "s", NULL
, "", buf
, sizeof(buf
),
141 for( p
= buf
+ strlen(buf
) + 1; *p
;p
+= strlen(p
)+1)
143 ok( ret
== 24 && !strcmp( buf
, "name1,name2,name4,name5"), "wrong keys returned(%d): %s\n",
146 h
= CreateFileA( TESTFILE2
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
147 FILE_ATTRIBUTE_NORMAL
, NULL
);
148 ok( h
!= INVALID_HANDLE_VALUE
, " cannot create %s\n", TESTFILE2
);
149 if( h
== INVALID_HANDLE_VALUE
) return;
150 WriteFile( h
, content2
, sizeof(content2
), &count
, NULL
);
153 /* works only in unicode, ascii crashes */
154 ret
=GetPrivateProfileStringW(emptyW
, keyW
, emptyW
, bufW
, ARRAY_SIZE(bufW
), TESTFILE2W
);
156 ok(ret
== 13, "expected 13, got %u\n", ret
);
158 ok(!lstrcmpW(valsectionW
,bufW
), "expected %s, got %s\n",
159 wine_dbgstr_w(valsectionW
), wine_dbgstr_w(bufW
) );
161 /* works only in unicode, ascii crashes */
162 ret
=GetPrivateProfileStringW(sW
, emptyW
, emptyW
, bufW
, ARRAY_SIZE(bufW
), TESTFILE2W
);
163 ok(ret
== 10, "expected 10, got %u\n", ret
);
164 ok(!lstrcmpW(valnokeyW
,bufW
), "expected %s, got %s\n",
165 wine_dbgstr_w(valnokeyW
), wine_dbgstr_w(bufW
) );
167 DeleteFileA( TESTFILE2
);
170 static void test_profile_sections(void)
177 static const char content
[]="[section1]\r\nname1=val1\r\nname2=\r\nname3\r\nname4=val4\r\n[section2]\r\n[section3]\r\n=val5\r\n";
178 static const char testfile4
[]=".\\testwine4.ini";
179 BOOL on_win98
= FALSE
;
181 DeleteFileA( testfile4
);
182 h
= CreateFileA( testfile4
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
183 ok( h
!= INVALID_HANDLE_VALUE
, " cannot create %s\n", testfile4
);
184 if( h
== INVALID_HANDLE_VALUE
) return;
185 WriteFile( h
, content
, sizeof(content
), &count
, NULL
);
188 /* Some parameter checking */
189 SetLastError(0xdeadbeef);
190 ret
= GetPrivateProfileSectionA( NULL
, NULL
, 0, NULL
);
191 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
192 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
193 GetLastError() == 0xdeadbeef /* Win98 */,
194 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
195 if (GetLastError() == 0xdeadbeef) on_win98
= TRUE
;
197 SetLastError(0xdeadbeef);
198 ret
= GetPrivateProfileSectionA( NULL
, NULL
, 0, testfile4
);
199 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
200 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
201 GetLastError() == 0xdeadbeef /* Win98 */,
202 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
206 SetLastError(0xdeadbeef);
207 ret
= GetPrivateProfileSectionA( "section1", NULL
, 0, testfile4
);
208 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
209 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
212 SetLastError(0xdeadbeef);
213 ret
= GetPrivateProfileSectionA( NULL
, buf
, sizeof(buf
), testfile4
);
214 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
215 ok( GetLastError() == ERROR_INVALID_PARAMETER
,
216 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
218 SetLastError(0xdeadbeef);
219 ret
= GetPrivateProfileSectionA( "section1", buf
, sizeof(buf
), NULL
);
220 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
222 ok( GetLastError() == ERROR_FILE_NOT_FOUND
,
223 "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
225 /* Existing empty section with no keys */
226 SetLastError(0xdeadbeef);
227 ret
=GetPrivateProfileSectionA("section2", buf
, sizeof(buf
), testfile4
);
228 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
229 ok( GetLastError() == ERROR_SUCCESS
,
230 "expected ERROR_SUCCESS, got %d\n", GetLastError());
232 /* Existing section with keys and values*/
233 SetLastError(0xdeadbeef);
234 ret
=GetPrivateProfileSectionA("section1", buf
, sizeof(buf
), testfile4
);
235 for( p
= buf
+ strlen(buf
) + 1; *p
;p
+= strlen(p
)+1)
237 ok( ret
== 35 && !strcmp( buf
, "name1=val1,name2=,name3,name4=val4"), "wrong section returned(%d): %s\n",
239 ok( buf
[ret
-1] == 0 && buf
[ret
] == 0, "returned buffer not terminated with double-null\n" );
240 ok( GetLastError() == ERROR_SUCCESS
,
241 "expected ERROR_SUCCESS, got %d\n", GetLastError());
243 /* Existing section with no keys but has values */
244 SetLastError(0xdeadbeef);
245 ret
=GetPrivateProfileSectionA("section3", buf
, sizeof(buf
), testfile4
);
246 trace("section3 return: %s\n", buf
);
247 for( p
= buf
+ strlen(buf
) + 1; *p
;p
+= strlen(p
)+1)
249 ok( ret
== 6 && !strcmp( buf
, "=val5"), "wrong section returned(%d): %s\n",
251 ok( buf
[ret
-1] == 0 && buf
[ret
] == 0, "returned buffer not terminated with double-null\n" );
252 ok( GetLastError() == ERROR_SUCCESS
,
253 "expected ERROR_SUCCESS, got %d\n", GetLastError());
256 ret
=GetPrivateProfileSectionA("section1", buf
, 24, testfile4
);
257 for( p
= buf
+ strlen(buf
) + 1; *p
;p
+= strlen(p
)+1)
259 ok( ret
== 22 && !strcmp( buf
, "name1=val1,name2=,name"), "wrong section returned(%d): %s\n",
261 ok( buf
[ret
] == 0 && buf
[ret
+1] == 0, "returned buffer not terminated with double-null\n" );
263 DeleteFileA( testfile4
);
266 static void test_profile_sections_names(void)
273 static const char content
[]="[section1]\r\n[section2]\r\n[section3]\r\n";
274 static const char testfile3
[]=".\\testwine3.ini";
275 static const WCHAR testfile3W
[]={ '.','\\','t','e','s','t','w','i','n','e','3','.','i','n','i',0 };
276 static const WCHAR not_here
[] = {'.','\\','n','o','t','_','h','e','r','e','.','i','n','i',0};
277 DeleteFileA( testfile3
);
278 h
= CreateFileA( testfile3
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
279 FILE_ATTRIBUTE_NORMAL
, NULL
);
280 ok( h
!= INVALID_HANDLE_VALUE
, " cannot create %s\n", testfile3
);
281 if( h
== INVALID_HANDLE_VALUE
) return;
282 WriteFile( h
, content
, sizeof(content
), &count
, NULL
);
285 /* Test with sufficiently large buffer */
286 memset(buf
, 0xc, sizeof(buf
));
287 ret
= GetPrivateProfileSectionNamesA( buf
, 29, testfile3
);
288 ok( ret
== 27, "expected return size 27, got %d\n", ret
);
289 ok( (buf
[ret
-1] == 0 && buf
[ret
] == 0),
290 "returned buffer not terminated with double-null\n" );
292 /* Test with exactly fitting buffer */
293 memset(buf
, 0xc, sizeof(buf
));
294 ret
= GetPrivateProfileSectionNamesA( buf
, 28, testfile3
);
295 ok( ret
== 26, "expected return size 26, got %d\n", ret
);
297 ok( (buf
[ret
+1] == 0 && buf
[ret
] == 0) || /* W2K3 and higher */
298 broken(buf
[ret
+1] == 0xc && buf
[ret
] == 0), /* NT4, W2K, WinXP */
299 "returned buffer not terminated with double-null\n" );
301 /* Test with a buffer too small */
302 memset(buf
, 0xc, sizeof(buf
));
303 ret
= GetPrivateProfileSectionNamesA( buf
, 27, testfile3
);
304 ok( ret
== 25, "expected return size 25, got %d\n", ret
);
305 count
= strlen("section1") + sizeof(CHAR
) + strlen("section2");
307 ok( buf
[ret
+1] == 0 && buf
[ret
] == 0,
308 "returned buffer not terminated with double-null\n" );
310 /* Tests on nonexistent file */
311 memset(buf
, 0xc, sizeof(buf
));
312 ret
= GetPrivateProfileSectionNamesA( buf
, 10, ".\\not_here.ini" );
313 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
314 ok( buf
[0] == 0, "returned buffer not terminated with null\n" );
315 ok( buf
[1] != 0, "returned buffer terminated with double-null\n" );
317 /* Test with sufficiently large buffer */
318 SetLastError(0xdeadbeef);
319 memset(bufW
, 0xcc, sizeof(bufW
));
320 ret
= GetPrivateProfileSectionNamesW( bufW
, 29, testfile3W
);
321 if (ret
== 0 && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
323 win_skip("GetPrivateProfileSectionNamesW is not implemented\n");
324 DeleteFileA( testfile3
);
327 ok( ret
== 27, "expected return size 27, got %d\n", ret
);
328 ok( bufW
[ret
-1] == 0 && bufW
[ret
] == 0, "returned buffer not terminated with double-null\n" );
330 /* Test with exactly fitting buffer */
331 memset(bufW
, 0xcc, sizeof(bufW
));
332 ret
= GetPrivateProfileSectionNamesW( bufW
, 28, testfile3W
);
333 ok( ret
== 26, "expected return size 26, got %d\n", ret
);
334 ok( (bufW
[ret
+1] == 0 && bufW
[ret
] == 0) || /* W2K3 and higher */
335 broken(bufW
[ret
+1] == 0xcccc && bufW
[ret
] == 0), /* NT4, W2K, WinXP */
336 "returned buffer not terminated with double-null\n" );
338 /* Test with a buffer too small */
339 memset(bufW
, 0xcc, sizeof(bufW
));
340 ret
= GetPrivateProfileSectionNamesW( bufW
, 27, testfile3W
);
341 ok( ret
== 25, "expected return size 25, got %d\n", ret
);
342 ok( bufW
[ret
+1] == 0 && bufW
[ret
] == 0, "returned buffer not terminated with double-null\n" );
344 DeleteFileA( testfile3
);
346 /* Tests on nonexistent file */
347 memset(bufW
, 0xcc, sizeof(bufW
));
348 ret
= GetPrivateProfileSectionNamesW( bufW
, 10, not_here
);
349 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
350 ok( bufW
[0] == 0, "returned buffer not terminated with null\n" );
351 ok( bufW
[1] != 0, "returned buffer terminated with double-null\n" );
354 /* If the ini-file has already been opened with CreateFile, WritePrivateProfileString failed in wine with an error ERROR_SHARING_VIOLATION, some testing here */
355 static void test_profile_existing(void)
357 static const char *testfile1
= ".\\winesharing1.ini";
358 static const char *testfile2
= ".\\winesharing2.ini";
360 static const struct {
361 DWORD dwDesiredAccess
;
367 {GENERIC_READ
, FILE_SHARE_READ
, ERROR_SHARING_VIOLATION
, FALSE
},
368 {GENERIC_READ
, FILE_SHARE_WRITE
, ERROR_SHARING_VIOLATION
, TRUE
},
369 {GENERIC_WRITE
, FILE_SHARE_READ
, ERROR_SHARING_VIOLATION
, FALSE
},
370 {GENERIC_WRITE
, FILE_SHARE_WRITE
, ERROR_SHARING_VIOLATION
, TRUE
},
371 {GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
, ERROR_SHARING_VIOLATION
, FALSE
},
372 {GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_WRITE
, ERROR_SHARING_VIOLATION
, TRUE
},
373 {GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, 0, FALSE
, ERROR_SHARING_VIOLATION
/* nt4 */},
374 {GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, 0, FALSE
, ERROR_SHARING_VIOLATION
/* nt4 */},
375 /*Thief demo (bug 5024) opens .ini file like this*/
376 {GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, 0, FALSE
, ERROR_SHARING_VIOLATION
/* nt4 */}
383 char buffer
[MAX_PATH
];
385 for (i
=0; i
< ARRAY_SIZE(pe
); i
++)
387 h
= CreateFileA(testfile1
, pe
[i
].dwDesiredAccess
, pe
[i
].dwShareMode
, NULL
,
388 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
389 ok(INVALID_HANDLE_VALUE
!= h
, "%d: CreateFile failed\n",i
);
390 SetLastError(0xdeadbeef);
392 ret
= WritePrivateProfileStringA(SECTION
, KEY
, "12345", testfile1
);
393 if (!pe
[i
].write_error
)
396 ok( broken(GetLastError() == pe
[i
].broken_error
),
397 "%d: WritePrivateProfileString failed with error %u\n", i
, GetLastError() );
399 size
= GetPrivateProfileStringA(SECTION
, KEY
, 0, buffer
, MAX_PATH
, testfile1
);
401 ok( size
== 5, "%d: test failed, number of characters copied: %d instead of 5\n", i
, size
);
403 ok( !size
, "%d: test failed, number of characters copied: %d instead of 0\n", i
, size
);
407 DWORD err
= GetLastError();
408 ok( !ret
, "%d: WritePrivateProfileString succeeded\n", i
);
410 ok( err
== pe
[i
].write_error
, "%d: WritePrivateProfileString failed with error %u/%u\n",
411 i
, err
, pe
[i
].write_error
);
413 size
= GetPrivateProfileStringA(SECTION
, KEY
, 0, buffer
, MAX_PATH
, testfile1
);
414 ok( !size
, "%d: test failed, number of characters copied: %d instead of 0\n", i
, size
);
417 ok( DeleteFileA(testfile1
), "delete failed\n" );
420 h
= CreateFileA(testfile2
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
421 sprintf( buffer
, "[%s]\r\n%s=123\r\n", SECTION
, KEY
);
422 ok( WriteFile( h
, buffer
, strlen(buffer
), &size
, NULL
), "failed to write\n" );
425 for (i
=0; i
< ARRAY_SIZE(pe
); i
++)
427 h
= CreateFileA(testfile2
, pe
[i
].dwDesiredAccess
, pe
[i
].dwShareMode
, NULL
,
428 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
429 ok(INVALID_HANDLE_VALUE
!= h
, "%d: CreateFile failed\n",i
);
430 SetLastError(0xdeadbeef);
431 ret
= GetPrivateProfileStringA(SECTION
, KEY
, NULL
, buffer
, MAX_PATH
, testfile2
);
432 if (!pe
[i
].read_error
)
433 ok( ret
, "%d: GetPrivateProfileString failed with error %u\n", i
, GetLastError() );
435 ok( !ret
, "%d: GetPrivateProfileString succeeded\n", i
);
438 ok( DeleteFileA(testfile2
), "delete failed\n" );
441 static void test_profile_delete_on_close(void)
445 static const CHAR testfile
[] = ".\\testwine5.ini";
446 static const char contents
[] = "[" SECTION
"]\n" KEY
"=123\n";
448 h
= CreateFileA(testfile
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
,
449 CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, NULL
);
450 res
= WriteFile( h
, contents
, sizeof contents
- 1, &size
, NULL
);
451 ok( res
, "Cannot write test file: %x\n", GetLastError() );
452 ok( size
== sizeof contents
- 1, "Test file: partial write\n");
454 SetLastError(0xdeadbeef);
455 res
= GetPrivateProfileIntA(SECTION
, KEY
, 0, testfile
);
456 ok( res
== 123, "Got %d instead of 123\n", res
);
458 /* This also deletes the file */
462 static void test_profile_refresh(void)
464 static const CHAR testfile
[] = ".\\winetest4.ini";
467 static const char contents1
[] = "[" SECTION
"]\n" KEY
"=123\n";
468 static const char contents2
[] = "[" SECTION
"]\n" KEY
"=124\n";
470 h
= CreateFileA(testfile
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
,
471 CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, NULL
);
472 res
= WriteFile( h
, contents1
, sizeof contents1
- 1, &size
, NULL
);
473 ok( res
, "Cannot write test file: %x\n", GetLastError() );
474 ok( size
== sizeof contents1
- 1, "Test file: partial write\n");
476 SetLastError(0xdeadbeef);
477 res
= GetPrivateProfileIntA(SECTION
, KEY
, 0, testfile
);
478 ok( res
== 123, "Got %d instead of 123\n", res
);
482 /* Test proper invalidation of wine's profile file cache */
484 h
= CreateFileA(testfile
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
,
485 CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, NULL
);
486 res
= WriteFile( h
, contents2
, sizeof contents2
- 1, &size
, NULL
);
487 ok( res
, "Cannot write test file: %x\n", GetLastError() );
488 ok( size
== sizeof contents2
- 1, "Test file: partial write\n");
490 SetLastError(0xdeadbeef);
491 res
= GetPrivateProfileIntA(SECTION
, KEY
, 0, testfile
);
492 ok( res
== 124, "Got %d instead of 124\n", res
);
494 /* This also deletes the file */
497 /* Cache must be invalidated if file no longer exists and default must be returned */
498 SetLastError(0xdeadbeef);
499 res
= GetPrivateProfileIntA(SECTION
, KEY
, 421, testfile
);
500 ok( res
== 421, "Got %d instead of 421\n", res
);
503 static void create_test_file(LPCSTR name
, LPCSTR data
, DWORD size
)
508 hfile
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
509 ok(hfile
!= INVALID_HANDLE_VALUE
, "cannot create %s\n", name
);
510 WriteFile(hfile
, data
, size
, &count
, NULL
);
514 static BOOL
emptystr_ok(CHAR emptystr
[MAX_PATH
])
518 for(i
= 0;i
< MAX_PATH
;++i
)
521 trace("emptystr[%d] = %d\n",i
,emptystr
[i
]);
528 static void test_profile_directory_readonly(void)
531 CHAR path_folder
[MAX_PATH
];
532 CHAR path_file
[MAX_PATH
];
533 const char *sddl_string_everyone_readonly
= "D:PAI(A;;0x1200a9;;;WD)";
534 SECURITY_ATTRIBUTES attributes
= {0};
535 char lpStruct
[] = { 's', 't', 'r', 'i', 'n', 'g' };
537 attributes
.nLength
= sizeof(attributes
);
538 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorA(sddl_string_everyone_readonly
, SDDL_REVISION_1
, &attributes
.lpSecurityDescriptor
, NULL
);
539 ok(ret
== TRUE
, "ConvertStringSecurityDescriptorToSecurityDescriptor failed: %d\n", GetLastError());
541 GetTempPathA(MAX_PATH
, path_folder
);
542 lstrcatA(path_folder
, "wine-test");
544 strcpy(path_file
, path_folder
);
545 lstrcatA(path_file
, "\\tmp.ini");
547 ret
= CreateDirectoryA(path_folder
, &attributes
);
548 ok(ret
== TRUE
, "CreateDirectoryA failed: %d\n", GetLastError());
550 ret
= WritePrivateProfileStringA("App", "key", "string", path_file
);
551 ok(ret
== FALSE
, "Expected FALSE, got %d\n", ret
);
553 ret
= WritePrivateProfileSectionA("App", "key=string", path_file
);
554 ok(ret
== FALSE
, "Expected FALSE, got %d\n", ret
);
556 ret
= WritePrivateProfileStructA("App", "key", lpStruct
, sizeof(lpStruct
), path_file
);
557 ok(ret
== FALSE
, "Expected FALSE, got %d\n", ret
);
559 ret
= RemoveDirectoryA(path_folder
);
560 ok(ret
== TRUE
, "RemoveDirectoryA failed: %d\n", GetLastError());
562 LocalFree(attributes
.lpSecurityDescriptor
);
565 static void test_GetPrivateProfileString(const char *content
, const char *descript
)
569 CHAR def_val
[MAX_PATH
];
571 CHAR windir
[MAX_PATH
];
572 /* NT series crashes on r/o empty strings, so pass an r/w
573 empty string and check for modification */
574 CHAR emptystr
[MAX_PATH
] = "";
577 static const char filename
[] = ".\\winetest.ini";
579 trace("test_GetPrivateProfileStringA: %s\n", descript
);
581 create_test_file(filename
, content
, lstrlenA(content
));
583 /* Run this test series with caching. Wine won't cache profile
584 files younger than 2.1 seconds. */
587 /* lpAppName is NULL */
588 memset(buf
, 0xc, sizeof(buf
));
589 lstrcpyA(buf
, "kumquat");
590 ret
= GetPrivateProfileStringA(NULL
, "name1", "default",
591 buf
, MAX_PATH
, filename
);
592 ok(ret
== 18, "Expected 18, got %d\n", ret
);
593 len
= lstrlenA("section1") + sizeof(CHAR
) + lstrlenA("section2") + 2 * sizeof(CHAR
);
595 ok(!memcmp(buf
, "section1\0section2\0", len
),
596 "Expected \"section1\\x00section2\\x00\\x00\", got %s\n",
597 debugstr_an(buf
, (ret
+ 2 >= MAX_PATH
? MAX_PATH
: ret
+ 1)));
599 /* lpAppName is empty */
600 memset(buf
, 0xc, sizeof(buf
));
601 lstrcpyA(buf
, "kumquat");
602 ret
= GetPrivateProfileStringA(emptystr
, "name1", "default",
603 buf
, MAX_PATH
, filename
);
604 ok(ret
== 7, "Expected 7, got %d\n", ret
);
605 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
606 ok(emptystr_ok(emptystr
), "AppName modified\n");
608 /* lpAppName is missing */
609 memset(buf
, 0xc,sizeof(buf
));
610 lstrcpyA(buf
, "kumquat");
611 ret
= GetPrivateProfileStringA("notasection", "name1", "default",
612 buf
, MAX_PATH
, filename
);
613 ok(ret
== 7, "Expected 7, got %d\n", ret
);
614 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
616 /* lpAppName is empty, lpDefault is NULL */
617 memset(buf
, 0xc,sizeof(buf
));
618 lstrcpyA(buf
, "kumquat");
619 ret
= GetPrivateProfileStringA(emptystr
, "name1", NULL
,
620 buf
, MAX_PATH
, filename
);
621 ok(ret
== 0, "Expected 0, got %d\n", ret
);
622 ok(!lstrcmpA(buf
, ""), "Expected \"\", got \"%s\"\n", buf
);
623 ok(emptystr_ok(emptystr
), "AppName modified\n");
625 /* lpAppName is empty, lpDefault is empty */
626 memset(buf
, 0xc,sizeof(buf
));
627 lstrcpyA(buf
, "kumquat");
628 ret
= GetPrivateProfileStringA(emptystr
, "name1", "",
629 buf
, MAX_PATH
, filename
);
630 ok(ret
== 0, "Expected 0, got %d\n", ret
);
631 ok(!lstrcmpA(buf
, ""), "Expected \"\", got \"%s\"\n", buf
);
632 ok(emptystr_ok(emptystr
), "AppName modified\n");
634 /* lpAppName is empty, lpDefault has trailing blank characters */
635 memset(buf
, 0xc,sizeof(buf
));
636 lstrcpyA(buf
, "kumquat");
637 /* lpDefault must be writable (trailing blanks are removed inplace in win9x) */
638 lstrcpyA(def_val
, "default ");
639 ret
= GetPrivateProfileStringA(emptystr
, "name1", def_val
,
640 buf
, MAX_PATH
, filename
);
641 ok(ret
== 7, "Expected 7, got %d\n", ret
);
642 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
643 ok(emptystr_ok(emptystr
), "AppName modified\n");
645 /* lpAppName is empty, many blank characters in lpDefault */
646 memset(buf
, 0xc,sizeof(buf
));
647 lstrcpyA(buf
, "kumquat");
648 /* lpDefault must be writable (trailing blanks are removed inplace in win9x) */
649 lstrcpyA(def_val
, "one two ");
650 ret
= GetPrivateProfileStringA(emptystr
, "name1", def_val
,
651 buf
, MAX_PATH
, filename
);
652 ok(ret
== 7, "Expected 7, got %d\n", ret
);
653 ok(!lstrcmpA(buf
, "one two"), "Expected \"one two\", got \"%s\"\n", buf
);
654 ok(emptystr_ok(emptystr
), "AppName modified\n");
656 /* lpAppName is empty, blank character but not trailing in lpDefault */
657 memset(buf
, 0xc,sizeof(buf
));
658 lstrcpyA(buf
, "kumquat");
659 ret
= GetPrivateProfileStringA(emptystr
, "name1", "one two",
660 buf
, MAX_PATH
, filename
);
661 ok(ret
== 7, "Expected 7, got %d\n", ret
);
662 ok(!lstrcmpA(buf
, "one two"), "Expected \"one two\", got \"%s\"\n", buf
);
663 ok(emptystr_ok(emptystr
), "AppName modified\n");
665 /* lpKeyName is NULL */
666 memset(buf
, 0xc,sizeof(buf
));
667 lstrcpyA(buf
, "kumquat");
668 ret
= GetPrivateProfileStringA("section1", NULL
, "default",
669 buf
, MAX_PATH
, filename
);
670 ok(ret
== 18, "Expected 18, got %d\n", ret
);
671 ok(!memcmp(buf
, "name1\0name2\0name4\0", ret
+ 1),
672 "Expected \"name1\\x00name2\\x00name4\\x00\\x00\", got %s\n",
673 debugstr_an(buf
, (ret
+ 2 >= MAX_PATH
? MAX_PATH
: ret
+ 1)));
675 /* lpKeyName is empty */
676 memset(buf
, 0xc,sizeof(buf
));
677 lstrcpyA(buf
, "kumquat");
678 ret
= GetPrivateProfileStringA("section1", emptystr
, "default",
679 buf
, MAX_PATH
, filename
);
680 ok(ret
== 7, "Expected 7, got %d\n", ret
);
681 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
682 ok(emptystr_ok(emptystr
), "KeyName modified\n");
684 /* lpKeyName is missing */
685 memset(buf
, 0xc,sizeof(buf
));
686 lstrcpyA(buf
, "kumquat");
687 ret
= GetPrivateProfileStringA("section1", "notakey", "default",
688 buf
, MAX_PATH
, filename
);
689 ok(ret
== 7, "Expected 7, got %d\n", ret
);
690 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
692 /* lpKeyName is empty, lpDefault is NULL */
693 memset(buf
, 0xc,sizeof(buf
));
694 lstrcpyA(buf
, "kumquat");
695 ret
= GetPrivateProfileStringA("section1", emptystr
, NULL
,
696 buf
, MAX_PATH
, filename
);
697 ok(ret
== 0, "Expected 0, got %d\n", ret
);
698 ok(!lstrcmpA(buf
, ""), "Expected \"\", got \"%s\"\n", buf
);
699 ok(emptystr_ok(emptystr
), "KeyName modified\n");
701 /* lpKeyName is empty, lpDefault is empty */
702 memset(buf
, 0xc,sizeof(buf
));
703 lstrcpyA(buf
, "kumquat");
704 ret
= GetPrivateProfileStringA("section1", emptystr
, "",
705 buf
, MAX_PATH
, filename
);
706 ok(ret
== 0, "Expected 0, got %d\n", ret
);
707 ok(!lstrcmpA(buf
, ""), "Expected \"\", got \"%s\"\n", buf
);
708 ok(emptystr_ok(emptystr
), "KeyName modified\n");
710 /* lpKeyName is empty, lpDefault has trailing blank characters */
711 memset(buf
, 0xc,sizeof(buf
));
712 lstrcpyA(buf
, "kumquat");
713 /* lpDefault must be writable (trailing blanks are removed inplace in win9x) */
714 lstrcpyA(def_val
, "default ");
715 ret
= GetPrivateProfileStringA("section1", emptystr
, def_val
,
716 buf
, MAX_PATH
, filename
);
717 ok(ret
== 7, "Expected 7, got %d\n", ret
);
718 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
719 ok(emptystr_ok(emptystr
), "KeyName modified\n");
723 /* lpReturnedString is NULL */
724 ret
= GetPrivateProfileStringA("section1", "name1", "default",
725 NULL
, MAX_PATH
, filename
);
728 /* lpFileName is NULL */
729 memset(buf
, 0xc,sizeof(buf
));
730 lstrcpyA(buf
, "kumquat");
731 ret
= GetPrivateProfileStringA("section1", "name1", "default",
732 buf
, MAX_PATH
, NULL
);
733 ok(ret
== 7, "Expected 7, got %d\n", ret
);
734 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
736 /* lpFileName is empty */
737 memset(buf
, 0xc,sizeof(buf
));
738 lstrcpyA(buf
, "kumquat");
739 ret
= GetPrivateProfileStringA("section1", "name1", "default",
741 ok(ret
== 7, "Expected 7, got %d\n", ret
);
742 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
744 /* lpFileName is nonexistent */
745 memset(buf
, 0xc,sizeof(buf
));
746 lstrcpyA(buf
, "kumquat");
747 ret
= GetPrivateProfileStringA("section1", "name1", "default",
748 buf
, MAX_PATH
, "nonexistent");
749 ok(ret
== 7, "Expected 7, got %d\n", ret
);
750 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
753 memset(buf
, 0xc,sizeof(buf
));
754 lstrcpyA(buf
, "kumquat");
755 ret
= GetPrivateProfileStringA("section1", "name1", "default",
757 ok(ret
== 0, "Expected 0, got %d\n", ret
);
758 ok(!lstrcmpA(buf
, "kumquat"), "Expected buf to be unchanged, got \"%s\"\n", buf
);
760 /* nSize is exact size of output */
761 memset(buf
, 0xc,sizeof(buf
));
762 lstrcpyA(buf
, "kumquat");
763 ret
= GetPrivateProfileStringA("section1", "name1", "default",
765 ok(ret
== 3, "Expected 3, got %d\n", ret
);
766 ok(!lstrcmpA(buf
, "val"), "Expected \"val\", got \"%s\"\n", buf
);
768 /* nSize has room for NULL terminator */
769 memset(buf
, 0xc,sizeof(buf
));
770 lstrcpyA(buf
, "kumquat");
771 ret
= GetPrivateProfileStringA("section1", "name1", "default",
773 ok(ret
== 4, "Expected 4, got %d\n", ret
);
774 ok(!lstrcmpA(buf
, "val1"), "Expected \"val1\", got \"%s\"\n", buf
);
776 /* output is 1 character */
777 memset(buf
, 0xc,sizeof(buf
));
778 lstrcpyA(buf
, "kumquat");
779 ret
= GetPrivateProfileStringA("section1", "name4", "default",
780 buf
, MAX_PATH
, filename
);
781 ok(ret
== 1, "Expected 1, got %d\n", ret
);
782 ok(!lstrcmpA(buf
, "a"), "Expected \"a\", got \"%s\"\n", buf
);
784 /* output is 1 character, no room for NULL terminator */
785 memset(buf
, 0xc,sizeof(buf
));
786 lstrcpyA(buf
, "kumquat");
787 ret
= GetPrivateProfileStringA("section1", "name4", "default",
789 ok(ret
== 0, "Expected 0, got %d\n", ret
);
790 ok(!lstrcmpA(buf
, ""), "Expected \"\", got \"%s\"\n", buf
);
792 /* lpAppName is NULL, not enough room for final section name */
793 memset(buf
, 0xc,sizeof(buf
));
794 lstrcpyA(buf
, "kumquat");
795 ret
= GetPrivateProfileStringA(NULL
, "name1", "default",
797 ok(ret
== 14, "Expected 14, got %d\n", ret
);
798 len
= lstrlenA("section1") + 2 * sizeof(CHAR
);
800 ok(!memcmp(buf
, "section1\0secti\0", ret
+ 2),
801 "Expected \"section1\\x00secti\\x00\\x00\", got %s\n",
802 debugstr_an(buf
, (ret
+ 2 >= 16 ? 16 : ret
+ 1)));
804 /* lpKeyName is NULL, not enough room for final key name */
805 memset(buf
, 0xc,sizeof(buf
));
806 lstrcpyA(buf
, "kumquat");
807 ret
= GetPrivateProfileStringA("section1", NULL
, "default",
809 ok(ret
== 14, "Expected 14, got %d\n", ret
);
811 ok(!memcmp(buf
, "name1\0name2\0na\0", ret
+ 2),
812 "Expected \"name1\\x00name2\\x00na\\x00\\x00\", got %s\n",
813 debugstr_an(buf
, (ret
+ 2 >= 16 ? 16 : ret
+ 1)));
815 /* key value has quotation marks which are stripped */
816 memset(buf
, 0xc,sizeof(buf
));
817 lstrcpyA(buf
, "kumquat");
818 ret
= GetPrivateProfileStringA("section1", "name2", "default",
819 buf
, MAX_PATH
, filename
);
820 ok(ret
== 4, "Expected 4, got %d\n", ret
);
821 ok(!lstrcmpA(buf
, "val2"), "Expected \"val2\", got \"%s\"\n", buf
);
823 /* case does not match */
824 memset(buf
, 0xc,sizeof(buf
));
825 lstrcpyA(buf
, "kumquat");
826 ret
= GetPrivateProfileStringA("section1", "NaMe1", "default",
827 buf
, MAX_PATH
, filename
);
828 ok(ret
== 4, "Expected 4, got %d\n", ret
);
829 ok(!lstrcmpA(buf
, "val1"), "Expected \"val1\", got \"%s\"\n", buf
);
831 /* only filename is used */
832 memset(buf
, 0xc,sizeof(buf
));
833 lstrcpyA(buf
, "kumquat");
834 ret
= GetPrivateProfileStringA("section1", "NaMe1", "default",
835 buf
, MAX_PATH
, "winetest.ini");
836 ok(ret
== 7, "Expected 7, got %d\n", ret
);
837 ok(!lstrcmpA(buf
, "default"), "Expected \"default\", got \"%s\"\n", buf
);
839 GetWindowsDirectoryA(windir
, MAX_PATH
);
840 SetLastError(0xdeadbeef);
841 ret
= GetTempFileNameA(windir
, "pre", 0, path
);
842 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
844 skip("Not allowed to create a file in the Windows directory\n");
845 DeleteFileA(filename
);
848 tempfile
= strrchr(path
, '\\') + 1;
849 create_test_file(path
, content
, lstrlenA(content
));
851 /* only filename is used, file exists in windows directory */
852 memset(buf
, 0xc,sizeof(buf
));
853 lstrcpyA(buf
, "kumquat");
854 ret
= GetPrivateProfileStringA("section1", "NaMe1", "default",
855 buf
, MAX_PATH
, tempfile
);
856 ok(ret
== 4, "Expected 4, got %d\n", ret
);
857 ok(!lstrcmpA(buf
, "val1"), "Expected \"val1\", got \"%s\"\n", buf
);
859 /* successful case */
860 memset(buf
, 0xc,sizeof(buf
));
861 lstrcpyA(buf
, "kumquat");
862 ret
= GetPrivateProfileStringA("section1", "name1", "default",
863 buf
, MAX_PATH
, filename
);
864 ok(ret
== 4, "Expected 4, got %d\n", ret
);
865 ok(!lstrcmpA(buf
, "val1"), "Expected \"val1\", got \"%s\"\n", buf
);
867 /* Existing section with no keys in an existing file */
868 memset(buf
, 0xc,sizeof(buf
));
869 SetLastError(0xdeadbeef);
870 ret
=GetPrivateProfileStringA("section2", "DoesntExist", "",
871 buf
, MAX_PATH
, filename
);
872 ok( ret
== 0, "expected return size 0, got %d\n", ret
);
873 ok(!lstrcmpA(buf
, ""), "Expected \"\", got \"%s\"\n", buf
);
875 ok( GetLastError() == 0xdeadbeef ||
876 GetLastError() == ERROR_FILE_NOT_FOUND
/* Win 7 */,
877 "expected 0xdeadbeef or ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
881 DeleteFileA(filename
);
884 static BOOL
check_binary_file_data(LPCSTR path
, const VOID
*data
, DWORD size
)
890 file
= CreateFileA(path
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, 0);
891 if (file
== INVALID_HANDLE_VALUE
)
894 if(size
!= GetFileSize(file
, NULL
) )
900 ret
= ReadFile(file
, buf
, size
, &size
, NULL
);
905 return !memcmp(buf
, data
, size
);
908 static BOOL
check_file_data(LPCSTR path
, LPCSTR data
)
910 return check_binary_file_data(path
, data
, lstrlenA(data
));
913 static void test_WritePrivateProfileString(void)
921 GetTempPathA(MAX_PATH
, temp
);
922 GetTempFileNameA(temp
, "wine", 0, path
);
925 /* path is not created yet */
928 SetLastError(0xdeadbeef);
929 ret
= WritePrivateProfileStringA(NULL
, "key", "string", path
);
930 ok(ret
== FALSE
, "Expected FALSE, got %d\n", ret
);
931 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
932 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
933 ok(GetFileAttributesA(path
) == INVALID_FILE_ATTRIBUTES
,
934 "Expected path to not exist\n");
936 GetTempFileNameA(temp
, "wine", 0, path
);
938 /* NULL lpAppName, path exists */
940 SetLastError(0xdeadbeef);
941 ret
= WritePrivateProfileStringA(NULL
, "key", "string", path
);
942 ok(ret
== FALSE
, "Expected FALSE, got %d\n", ret
);
943 ok(GetLastError() == ERROR_FILE_NOT_FOUND
,
944 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
945 ok(check_file_data(path
, data
), "File doesn't match\n");
950 /* empty lpAppName, crashes on NT4 and higher */
953 ret
= WritePrivateProfileStringA("", "key", "string", path
);
954 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
955 ok(check_file_data(path
, data
), "File doesn't match\n");
961 ret
= WritePrivateProfileStringA("App", NULL
, "string", path
);
962 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
965 ok(check_file_data(path
, data
), "File doesn't match\n");
971 /* empty lpKeyName, crashes on NT4 and higher */
974 ret
= WritePrivateProfileStringA("App", "", "string", path
);
975 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
978 ok(check_file_data(path
, data
), "File doesn't match\n");
985 ret
= WritePrivateProfileStringA("App", "key", NULL
, path
);
986 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
989 ok(check_file_data(path
, data
), "File doesn't match\n");
996 ret
= WritePrivateProfileStringA("App", "key", "", path
);
997 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
998 ok(check_file_data(path
, data
), "File doesn't match\n");
1001 /* empty lpFileName */
1002 SetLastError(0xdeadbeef);
1003 ret
= WritePrivateProfileStringA("App", "key", "string", "");
1004 ok(ret
== FALSE
, "Expected FALSE, got %d\n", ret
);
1005 ok(GetLastError() == ERROR_ACCESS_DENIED
,
1006 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1008 /* Relative paths are relative to X:\\%WINDIR% */
1009 GetWindowsDirectoryA(path
, MAX_PATH
);
1010 strcat(path
, "\\win1.tmp");
1011 file
= CreateFileA(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1012 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1013 skip("Not allowed to create a file in the Windows directory\n");
1021 ret
= WritePrivateProfileStringA("App", "key", "string", "win1.tmp");
1022 ok(ret
== TRUE
, "Expected TRUE, got %d, le=%u\n", ret
, GetLastError());
1023 ok(check_file_data(path
, data
), "File doesn't match\n");
1027 GetTempPathA(MAX_PATH
, temp
);
1028 GetTempFileNameA(temp
, "wine", 0, path
);
1030 /* build up an INI file */
1031 WritePrivateProfileStringA("App1", "key1", "string1", path
);
1032 WritePrivateProfileStringA("App1", "key2", "string2", path
);
1033 WritePrivateProfileStringA("App1", "key3", "string3", path
);
1034 WritePrivateProfileStringA("App2", "key4", "string4", path
);
1036 /* make an addition and verify the INI */
1045 ret
= WritePrivateProfileStringA("App3", "key5", "string5", path
);
1046 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1047 ok(check_file_data(path
, data
), "File doesn't match\n");
1049 /* lpString is NULL, key2 key is deleted */
1057 ret
= WritePrivateProfileStringA("App1", "key2", NULL
, path
);
1058 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1059 ok(check_file_data(path
, data
), "File doesn't match\n");
1061 /* try to delete key2 again */
1069 ret
= WritePrivateProfileStringA("App1", "key2", NULL
, path
);
1070 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1071 ok(check_file_data(path
, data
), "File doesn't match\n");
1073 /* lpKeyName is NULL, App1 section is deleted */
1078 ret
= WritePrivateProfileStringA("App1", NULL
, "string1", path
);
1079 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1080 ok(check_file_data(path
, data
), "File doesn't match\n");
1082 /* lpString is not needed to delete a section */
1085 ret
= WritePrivateProfileStringA("App2", NULL
, NULL
, path
);
1086 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1087 ok(check_file_data(path
, data
), "File doesn't match\n");
1089 /* leave just the section */
1090 data
= "[App3]\r\n";
1091 ret
= WritePrivateProfileStringA("App3", "key5", NULL
, path
);
1092 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1093 ok(check_file_data(path
, data
), "File doesn't match\n");
1096 /* NULLs in file before first section. Should be preserved in output */
1097 data
= "Data \0 before \0 first \0 section" /* 31 bytes */
1098 "\r\n[section1]\r\n" /* 14 bytes */
1099 "key1=string1\r\n"; /* 14 bytes */
1100 GetTempFileNameA(temp
, "wine", 0, path
);
1101 create_test_file(path
, data
, 31);
1102 ret
= WritePrivateProfileStringA("section1", "key1", "string1", path
);
1103 ok(ret
== TRUE
, "Expected TRUE, got %d\n", ret
);
1105 ok( check_binary_file_data(path
, data
, 59), "File doesn't match\n");
1109 static void test_profile_struct(void)
1111 static const char expect_data
[] = "[s]\r\nkey=616261637573006F\r\n";
1115 SetLastError(0xdeadbeef);
1116 ret
= GetPrivateProfileStructA("s", "key", buffer
, sizeof(buffer
), "./winetest.ini");
1117 ok(!ret
, "expected failure\n");
1118 todo_wine
ok(GetLastError() == ERROR_BAD_LENGTH
, "got error %u\n", GetLastError());
1120 ret
= WritePrivateProfileStructA("s", "key", (void *)"abacus", sizeof("abacus"), "./winetest.ini");
1121 ok(ret
, "got error %u\n", GetLastError());
1122 ok(check_file_data("./winetest.ini", expect_data
), "file doesn't match\n");
1124 SetLastError(0xdeadbeef);
1125 ret
= GetPrivateProfileStructA("s", "key", buffer
, 6, "./winetest.ini");
1126 ok(!ret
, "expected failure\n");
1127 todo_wine
ok(GetLastError() == ERROR_BAD_LENGTH
, "got error %u\n", GetLastError());
1129 SetLastError(0xdeadbeef);
1130 ret
= GetPrivateProfileStructA("s", "key", buffer
, 8, "./winetest.ini");
1131 ok(!ret
, "expected failure\n");
1132 todo_wine
ok(GetLastError() == ERROR_BAD_LENGTH
, "got error %u\n", GetLastError());
1134 memset(buffer
, 0xcc, sizeof(buffer
));
1135 ret
= GetPrivateProfileStructA("s", "key", buffer
, 7, "./winetest.ini");
1136 ok(ret
, "got error %u\n", GetLastError());
1137 ok(!strcmp(buffer
, "abacus"), "data didn't match\n");
1139 memset(buffer
, 0xcc, sizeof(buffer
));
1140 ret
= GetPrivateProfileStringA("s", "key", "default", buffer
, sizeof(buffer
), "./winetest.ini");
1141 ok(ret
== 16, "got size %u\n", ret
);
1142 ok(!strcmp(buffer
, "616261637573006F"), "got %s\n", debugstr_a(buffer
));
1144 ret
= WritePrivateProfileStringA("s", "key", "636163747573006F", "./winetest.ini");
1145 ok(ret
, "got error %u\n", GetLastError());
1147 SetLastError(0xdeadbeef);
1148 ret
= GetPrivateProfileStructA("s", "key", buffer
, 7, "./winetest.ini");
1149 ok(!ret
, "expected failure\n");
1150 todo_wine
ok(GetLastError() == ERROR_INVALID_DATA
, "got error %u\n", GetLastError());
1152 ret
= WritePrivateProfileStringA("s", "key", "6361637475730083", "./winetest.ini");
1153 ok(ret
, "got error %u\n", GetLastError());
1155 memset(buffer
, 0xcc, sizeof(buffer
));
1156 ret
= GetPrivateProfileStructA("s", "key", buffer
, 7, "./winetest.ini");
1157 ok(ret
, "got error %u\n", GetLastError());
1158 ok(!strcmp(buffer
, "cactus"), "data didn't match\n");
1160 ret
= WritePrivateProfileStringA("s", "key", "636163747573008Q", "./winetest.ini");
1161 ok(ret
, "got error %u\n", GetLastError());
1163 SetLastError(0xdeadbeef);
1164 ret
= GetPrivateProfileStructA("s", "key", buffer
, 7, "./winetest.ini");
1165 ok(!ret
, "expected failure\n");
1166 todo_wine
ok(GetLastError() == ERROR_INVALID_DATA
, "got error %u\n", GetLastError());
1168 ret
= WritePrivateProfileStringA("s", "key", "16361637475730083", "./winetest.ini");
1169 ok(ret
, "got error %u\n", GetLastError());
1171 SetLastError(0xdeadbeef);
1172 ret
= GetPrivateProfileStructA("s", "key", buffer
, 7, "./winetest.ini");
1173 ok(!ret
, "expected failure\n");
1174 todo_wine
ok(GetLastError() == ERROR_BAD_LENGTH
, "got error %u\n", GetLastError());
1176 ret
= DeleteFileA("./winetest.ini");
1177 ok(ret
, "got error %u\n", GetLastError());
1180 static void check_registry_value_(int line
, HKEY key
, const char *value
, const char *expect
)
1183 DWORD type
, size
= sizeof(buffer
);
1186 memset(buffer
, 0xcc, sizeof(buffer
));
1187 ret
= RegQueryValueExA(key
, value
, 0, &type
, (BYTE
*)buffer
, &size
);
1188 ok_(__FILE__
, line
)(!ret
, "got error %u\n", ret
);
1189 ok_(__FILE__
, line
)(!strcmp(buffer
, expect
), "expected %s, got %s\n", debugstr_a(expect
), debugstr_a(buffer
));
1190 ok_(__FILE__
, line
)(type
== REG_SZ
, "got type %u\n", type
);
1192 #define check_registry_value(a, b, c) check_registry_value_(__LINE__, a, b, c)
1194 static void test_registry_mapping(void)
1196 static const DWORD ivalue
= 0xabacab;
1197 HKEY mapping_key
, mapped_key
, mapping_subkey
;
1201 /* impersonate ourselves to prevent registry virtualization */
1202 ret
= ImpersonateSelf(SecurityImpersonation
);
1203 ok(ret
, "got error %u\n", GetLastError());
1205 ret
= RegCreateKeyExA(HKEY_LOCAL_MACHINE
,
1206 "Software\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\winetest_map.ini",
1207 0, NULL
, 0, KEY_READ
| KEY_WRITE
| KEY_WOW64_64KEY
, NULL
, &mapping_key
, NULL
);
1208 if (ret
== ERROR_ACCESS_DENIED
)
1210 skip("Not enough permissions to write to the IniFileMapping key.\n");
1213 ok(!ret
, "got error %u\n", ret
);
1215 ret
= RegSetValueExA(mapping_key
, "section1", 0, REG_SZ
, (BYTE
*)"USR:winetest_map", sizeof("USR:winetest_map"));
1216 ok(!ret
, "got error %u\n", ret
);
1217 ret
= WritePrivateProfileStringA(NULL
, NULL
, NULL
, "winetest_map.ini");
1218 todo_wine
ok(ret
, "got error %u\n", GetLastError());
1220 check_profile_string("section1", "name1", "winetest_map.ini", "default");
1222 ret
= WritePrivateProfileStringA("section1", "name1", "value1", "winetest_map.ini");
1223 ok(ret
, "got error %u\n", GetLastError());
1225 check_profile_string("section1", "name1", "winetest_map.ini", "value1");
1226 check_profile_string("section1", "name1", "C:/fake/path/winetest_map.ini", "value1");
1228 ret
= RegOpenKeyExA(HKEY_CURRENT_USER
, "winetest_map", 0, KEY_READ
| KEY_WRITE
, &mapped_key
);
1229 ok(!ret
, "got error %u\n", ret
);
1230 check_registry_value(mapped_key
, "name1", "value1");
1232 ret
= RegSetValueExA(mapped_key
, "name2", 0, REG_SZ
, (BYTE
*)"value2", sizeof("value2"));
1233 ok(!ret
, "got error %u\n", ret
);
1235 check_profile_string("section1", "name2", "winetest_map.ini", "value2");
1237 ret
= GetFileAttributesA("C:/windows/winetest_map.ini");
1238 ok(ret
== INVALID_FILE_ATTRIBUTES
, "winetest_map.ini should not exist.\n");
1240 ret
= WritePrivateProfileStringA("section1", "name2", NULL
, "winetest_map.ini");
1241 ok(ret
, "got error %u\n", GetLastError());
1242 ret
= RegQueryValueExA(mapped_key
, "name2", 0, NULL
, NULL
, NULL
);
1243 ok(ret
== ERROR_FILE_NOT_FOUND
, "got error %u\n", ret
);
1245 /* Test non-string types. */
1247 ret
= RegSetValueExA(mapped_key
, "name3", 0, REG_DWORD
, (BYTE
*)&ivalue
, sizeof(ivalue
));
1248 ok(!ret
, "got error %u\n", ret
);
1249 check_profile_string("section1", "name3", "winetest_map.ini", "default");
1251 ret
= GetPrivateProfileIntA("section1", "name3", 0, "winetest_map.ini");
1252 ok(ret
== 0, "got %#x\n", ret
);
1254 ret
= RegSetValueExA(mapped_key
, "name3", 0, REG_BINARY
, (BYTE
*)"value3", sizeof("value3"));
1255 ok(!ret
, "got error %u\n", ret
);
1256 check_profile_string("section1", "name3", "winetest_map.ini", "default");
1258 ret
= RegSetValueExA(mapped_key
, "name3", 0, REG_MULTI_SZ
, (BYTE
*)"one\0two\0", sizeof("one\0two\0"));
1259 ok(!ret
, "got error %u\n", ret
);
1260 check_profile_string("section1", "name3", "winetest_map.ini", "default");
1262 ret
= RegSetValueExA(mapped_key
, "name3", 0, REG_EXPAND_SZ
, (BYTE
*)"x%SystemRoot%", sizeof("x%SystemRoot%"));
1263 ok(!ret
, "got error %u\n", ret
);
1264 check_profile_string("section1", "name3", "winetest_map.ini", "default");
1266 /* Test WritePrivateProfileSection(). Unlike with .ini files, it doesn't
1267 * remove existing entries. */
1269 ret
= WritePrivateProfileStringA("section1", "name4", "value4", "winetest_map.ini");
1270 ok(ret
, "got error %u\n", GetLastError());
1271 ret
= WritePrivateProfileStringA("section1", "name5", "value5", "winetest_map.ini");
1272 ok(ret
, "got error %u\n", GetLastError());
1273 ret
= WritePrivateProfileSectionA("section1", "name4=four\0name6=six\0", "winetest_map.ini");
1274 ok(ret
, "got error %u\n", GetLastError());
1275 check_profile_string("section1", "name4", "winetest_map.ini", "four");
1276 check_profile_string("section1", "name5", "winetest_map.ini", "value5");
1277 check_profile_string("section1", "name6", "winetest_map.ini", "six");
1279 /* Test deleting the section. */
1281 RegCloseKey(mapped_key
);
1283 ret
= RegCreateKeyExA(HKEY_CURRENT_USER
, "winetest_map\\subkey", 0, NULL
, 0, 0, NULL
, &mapped_key
, NULL
);
1284 ok(!ret
, "got error %u\n", ret
);
1285 RegCloseKey(mapped_key
);
1287 ret
= WritePrivateProfileStringA("section1", "name1", "value1", "winetest_map.ini");
1288 ok(ret
, "got error %u\n", GetLastError());
1289 ret
= WritePrivateProfileStringA("section1", NULL
, NULL
, "winetest_map.ini");
1290 ok(ret
, "got error %u\n", GetLastError());
1291 check_profile_string("section1", "name1", "winetest_map.ini", "default");
1293 ret
= WritePrivateProfileStringA("section1", "name1", "value1", "winetest_map.ini");
1294 ok(ret
, "got error %u\n", GetLastError());
1295 ret
= WritePrivateProfileSectionA("section1", NULL
, "winetest_map.ini");
1296 ok(ret
, "got error %u\n", GetLastError());
1297 check_profile_string("section1", "name1", "winetest_map.ini", "default");
1299 ret
= RegDeleteKeyA(HKEY_CURRENT_USER
, "winetest_map\\subkey");
1300 ok(!ret
, "got error %u\n", ret
);
1301 ret
= RegDeleteKeyA(HKEY_CURRENT_USER
, "winetest_map");
1302 ok(!ret
, "got error %u\n", ret
);
1304 /* Test GetPrivateProfileSectionNames(). */
1306 memset(buffer
, 0xcc, sizeof(buffer
));
1307 ret
= GetPrivateProfileSectionNamesA(buffer
, 5, "winetest_map.ini");
1308 ok(ret
== 3, "got %u\n", ret
);
1309 ok(!memcmp(buffer
, "sec\0", 5), "got %s\n", debugstr_an(buffer
, ret
));
1311 memset(buffer
, 0xcc, sizeof(buffer
));
1312 ret
= GetPrivateProfileSectionNamesA(buffer
, sizeof(buffer
), "winetest_map.ini");
1313 ok(ret
== 9, "got %u\n", ret
);
1314 ok(!memcmp(buffer
, "section1\0", 10), "got %s\n", debugstr_an(buffer
, ret
));
1316 ret
= WritePrivateProfileStringA("file_section", "name1", "value1", "winetest_map.ini");
1317 ok(ret
, "got error %u\n", GetLastError());
1319 memset(buffer
, 0xcc, sizeof(buffer
));
1320 ret
= GetPrivateProfileSectionNamesA(buffer
, 5, "winetest_map.ini");
1321 ok(ret
== 3, "got %u\n", ret
);
1322 ok(!memcmp(buffer
, "sec\0", 5), "got %s\n", debugstr_an(buffer
, ret
));
1324 memset(buffer
, 0xcc, sizeof(buffer
));
1325 ret
= GetPrivateProfileSectionNamesA(buffer
, sizeof(buffer
), "winetest_map.ini");
1326 ok(ret
== 22, "got %u\n", ret
);
1327 ok(!memcmp(buffer
, "section1\0file_section\0", 23), "got %s\n", debugstr_an(buffer
, ret
));
1329 ret
= DeleteFileA("C:/windows/winetest_map.ini");
1330 ok(ret
, "got error %u\n", GetLastError());
1332 /* Test the SYS: prefix. */
1334 ret
= RegSetValueExA(mapping_key
, "section2", 0, REG_SZ
, (BYTE
*)"SYS:winetest_map", sizeof("SYS:winetest_map"));
1335 ok(!ret
, "got error %u\n", ret
);
1336 ret
= WritePrivateProfileStringA(NULL
, NULL
, NULL
, "winetest_map.ini");
1337 todo_wine
ok(ret
, "got error %u\n", GetLastError());
1339 check_profile_string("section2", "name1", "winetest_map.ini", "default");
1341 ret
= WritePrivateProfileStringA("section2", "name1", "value1", "winetest_map.ini");
1342 ok(ret
, "got error %u\n", GetLastError());
1344 check_profile_string("section2", "name1", "winetest_map.ini", "value1");
1346 ret
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "Software\\winetest_map", 0, KEY_READ
| KEY_WRITE
, &mapped_key
);
1347 ok(!ret
, "got error %u\n", ret
);
1348 check_registry_value(mapped_key
, "name1", "value1");
1350 ret
= RegSetValueExA(mapped_key
, "name2", 0, REG_SZ
, (BYTE
*)"value2", sizeof("value2"));
1351 ok(!ret
, "got error %u\n", ret
);
1353 check_profile_string("section2", "name2", "winetest_map.ini", "value2");
1355 ret
= GetFileAttributesA("C:/windows/winetest_map.ini");
1356 ok(ret
== INVALID_FILE_ATTRIBUTES
, "winetest_map.ini should not exist.\n");
1358 ret
= RegDeleteKeyA(mapped_key
, "");
1359 ok(!ret
, "got error %u\n", ret
);
1360 RegCloseKey(mapped_key
);
1362 /* Try writing directly to the .ini file on disk instead. */
1364 ret
= WritePrivateProfileStringA("section3", "name1", "value1", "winetest_map.ini");
1365 ok(ret
, "got error %u\n", GetLastError());
1366 check_profile_string("section3", "name1", "winetest_map.ini", "value1");
1368 ret
= RegSetValueExA(mapping_key
, "section3", 0, REG_SZ
, (BYTE
*)"USR:winetest_map", sizeof("USR:winetest_map"));
1369 ok(!ret
, "got error %u\n", ret
);
1370 ret
= WritePrivateProfileStringA(NULL
, NULL
, NULL
, "winetest_map.ini");
1371 todo_wine
ok(ret
, "got error %u\n", GetLastError());
1373 check_profile_string("section3", "name1", "winetest_map.ini", "default");
1375 ret
= RegOpenKeyExA(HKEY_CURRENT_USER
, "winetest_section3", 0, KEY_READ
| KEY_WRITE
, &mapped_key
);
1376 ok(ret
== ERROR_FILE_NOT_FOUND
, "got error %u\n", ret
);
1378 ret
= WritePrivateProfileStringA("section3", "name1", "value2", "winetest_map.ini");
1379 ok(ret
, "got error %u\n", GetLastError());
1381 check_profile_string("section3", "name1", "winetest_map.ini", "value2");
1383 ret
= RegOpenKeyExA(HKEY_CURRENT_USER
, "winetest_map", 0, KEY_READ
| KEY_WRITE
, &mapped_key
);
1384 ok(!ret
, "got error %u\n", ret
);
1386 ret
= RegDeleteKeyA(mapped_key
, "");
1387 ok(!ret
, "got error %u\n", ret
);
1388 RegCloseKey(mapped_key
);
1390 ret
= RegDeleteValueA(mapping_key
, "section3");
1391 ok(!ret
, "got error %u\n", ret
);
1392 ret
= WritePrivateProfileStringA(NULL
, NULL
, NULL
, "winetest_map.ini");
1393 todo_wine
ok(ret
, "got error %u\n", GetLastError());
1395 check_profile_string("section3", "name1", "winetest_map.ini", "value1");
1397 ret
= DeleteFileA("C:/windows/winetest_map.ini");
1398 ok(ret
, "got error %u\n", GetLastError());
1400 /* Test default keys. */
1402 ret
= WritePrivateProfileStringA("section4", "name1", "value1", "winetest_map.ini");
1403 ok(ret
, "got error %u\n", GetLastError());
1405 check_profile_string("section4", "name1", "winetest_map.ini", "value1");
1407 ret
= DeleteFileA("C:/windows/winetest_map.ini");
1408 ok(ret
, "got error %u\n", GetLastError());
1410 ret
= RegSetValueExA(mapping_key
, NULL
, 0, REG_SZ
, (BYTE
*)"SYS:winetest_default", sizeof("SYS:winetest_default"));
1411 ok(!ret
, "got error %u\n", ret
);
1412 ret
= WritePrivateProfileStringA(NULL
, NULL
, NULL
, "winetest_map.ini");
1413 todo_wine
ok(ret
, "got error %u\n", GetLastError());
1415 ret
= WritePrivateProfileStringA("section4", "name1", "value1", "winetest_map.ini");
1416 ok(ret
, "got error %u\n", GetLastError());
1418 ret
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "Software\\winetest_default\\section4", 0, KEY_READ
, &mapped_key
);
1419 ok(!ret
, "got error %u\n", ret
);
1420 check_registry_value(mapped_key
, "name1", "value1");
1421 RegCloseKey(mapped_key
);
1423 ret
= RegCreateKeyExA(HKEY_LOCAL_MACHINE
, "Software\\winetest_default\\section5",
1424 0, NULL
, 0, KEY_WRITE
, NULL
, &mapped_key
, NULL
);
1425 ok(!ret
, "got error %u\n", ret
);
1426 ret
= RegSetValueExA(mapped_key
, "name2", 0, REG_SZ
, (BYTE
*)"value2", sizeof("value2"));
1427 ok(!ret
, "got error %u\n", ret
);
1428 RegCloseKey(mapped_key
);
1430 check_profile_string("section5", "name2", "winetest_map.ini", "value2");
1432 ret
= GetFileAttributesA("C:/windows/winetest_map.ini");
1433 ok(ret
== INVALID_FILE_ATTRIBUTES
, "winetest_map.ini should not exist.\n");
1435 ret
= RegDeleteKeyA(HKEY_LOCAL_MACHINE
, "Software\\winetest_default\\Section4");
1436 ret
= RegDeleteKeyA(HKEY_LOCAL_MACHINE
, "Software\\winetest_default\\Section5");
1437 ret
= RegDeleteKeyA(HKEY_LOCAL_MACHINE
, "Software\\winetest_default");
1438 ok(!ret
, "got error %u\n", ret
);
1439 ret
= RegDeleteValueA(mapping_key
, NULL
);
1440 ok(!ret
, "got error %u\n", ret
);
1442 /* Test name-specific mapping. */
1444 ret
= RegCreateKeyExA(mapping_key
, "section6", 0, NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
, &mapping_subkey
, NULL
);
1445 ok(!ret
, "got error %u\n", ret
);
1446 ret
= RegSetValueExA(mapping_subkey
, "name1", 0, REG_SZ
, (BYTE
*)"USR:winetest_name1", sizeof("USR:winetest_name1"));
1447 ok(!ret
, "got error %u\n", ret
);
1448 ret
= RegSetValueExA(mapping_subkey
, "name2", 0, REG_SZ
, (BYTE
*)"SYS:winetest_name2", sizeof("SYS:winetest_name2"));
1449 ok(!ret
, "got error %u\n", ret
);
1450 ret
= WritePrivateProfileStringA(NULL
, NULL
, NULL
, "winetest_map.ini");
1451 todo_wine
ok(ret
, "got error %u\n", GetLastError());
1453 ret
= WritePrivateProfileStringA("section6", "name1", "value1", "winetest_map.ini");
1454 ok(ret
, "got error %u\n", GetLastError());
1455 check_profile_string("section6", "name1", "winetest_map.ini", "value1");
1457 ret
= RegOpenKeyExA(HKEY_CURRENT_USER
, "winetest_name1", 0, KEY_READ
| KEY_WRITE
, &mapped_key
);
1458 ok(!ret
, "got error %u\n", ret
);
1459 check_registry_value(mapped_key
, "name1", "value1");
1461 ret
= RegSetValueExA(mapped_key
, "name1", 0, REG_SZ
, (BYTE
*)"one", sizeof("one"));
1462 ok(!ret
, "got error %u\n", ret
);
1463 check_profile_string("section6", "name1", "winetest_map.ini", "one");
1465 ret
= RegDeleteKeyA(mapped_key
, "");
1466 ok(!ret
, "got error %u\n", ret
);
1467 RegCloseKey(mapped_key
);
1469 ret
= WritePrivateProfileStringA("section6", "name2", "value2", "winetest_map.ini");
1470 ok(ret
, "got error %u\n", GetLastError());
1472 ret
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, "Software\\winetest_name2", 0, KEY_READ
| KEY_WRITE
, &mapped_key
);
1473 ok(!ret
, "got error %u\n", ret
);
1474 check_registry_value(mapped_key
, "name2", "value2");
1476 ret
= RegSetValueExA(mapped_key
, "name2", 0, REG_SZ
, (BYTE
*)"two", sizeof("two"));
1477 ok(!ret
, "got error %u\n", ret
);
1478 check_profile_string("section6", "name2", "winetest_map.ini", "two");
1480 ret
= RegDeleteKeyA(mapped_key
, "");
1481 ok(!ret
, "got error %u\n", ret
);
1482 RegCloseKey(mapped_key
);
1484 ret
= WritePrivateProfileStringA("section6", "name3", "value3", "winetest_map.ini");
1485 ok(ret
, "got error %u\n", GetLastError());
1486 check_profile_string("section6", "name3", "winetest_map.ini", "value3");
1487 ret
= DeleteFileA("C:/windows/winetest_map.ini");
1488 ok(ret
, "got error %u\n", GetLastError());
1490 /* Test name-specific mapping with Get/WritePrivateProfileSection(). */
1492 ret
= WritePrivateProfileStringA("section6", "name2", "value2", "winetest_map.ini");
1493 ok(ret
, "got error %u\n", GetLastError());
1495 ret
= WritePrivateProfileStringA("section6", "name3", "value3", "winetest_map.ini");
1496 ok(ret
, "got error %u\n", GetLastError());
1498 ret
= WritePrivateProfileSectionA("section6", "name1=one\0name3=three\0", "winetest_map.ini");
1499 ok(ret
, "got error %u\n", GetLastError());
1500 check_profile_string("section6", "name1", "winetest_map.ini", "one");
1501 check_profile_string("section6", "name2", "winetest_map.ini", "value2");
1502 check_profile_string("section6", "name3", "winetest_map.ini", "value3");
1504 ret
= RegOpenKeyExA(HKEY_CURRENT_USER
, "winetest_name1", 0, KEY_READ
| KEY_WRITE
, &mapped_key
);
1505 ok(!ret
, "got error %u\n", ret
);
1506 ret
= RegDeleteValueA(mapped_key
, "name1");
1507 ok(!ret
, "got error %u\n", ret
);
1508 RegCloseKey(mapped_key
);
1510 memset(buffer
, 0xcc, sizeof(buffer
));
1511 ret
= GetPrivateProfileSectionA("section6", buffer
, 5, "winetest_map.ini");
1512 ok(ret
== 3, "got %u\n", ret
);
1513 ok(!memcmp(buffer
, "nam\0", 5), "got %s\n", debugstr_an(buffer
, ret
));
1515 memset(buffer
, 0xcc, sizeof(buffer
));
1516 ret
= GetPrivateProfileSectionA("section6", buffer
, sizeof(buffer
), "winetest_map.ini");
1517 ok(ret
== 26, "got %u\n", ret
);
1518 ok(!memcmp(buffer
, "name2=value2\0name3=value3\0", 27), "got %s\n", debugstr_an(buffer
, ret
));
1520 ret
= WritePrivateProfileStringA("section6", NULL
, NULL
, "winetest_map.ini");
1521 ok(ret
, "got error %u\n", GetLastError());
1522 check_profile_string("section6", "name1", "winetest_map.ini", "default");
1523 check_profile_string("section6", "name2", "winetest_map.ini", "default");
1524 check_profile_string("section6", "name3", "winetest_map.ini", "default");
1526 ret
= RegDeleteKeyA(HKEY_CURRENT_USER
, "winetest_name1");
1527 ok(!ret
, "got error %u\n", ret
);
1528 ret
= RegDeleteKeyA(HKEY_LOCAL_MACHINE
, "Software\\winetest_name2");
1529 ok(!ret
, "got error %u\n", ret
);
1530 ret
= DeleteFileA("C:/windows/winetest_map.ini");
1531 ok(ret
, "got error %u\n", GetLastError());
1533 /* Test name-specific mapping with a default value. */
1535 ret
= RegSetValueExA(mapping_subkey
, NULL
, 0, REG_SZ
, (BYTE
*)"USR:winetest_default", sizeof("USR:winetest_default"));
1536 ok(!ret
, "got error %u\n", ret
);
1537 ret
= WritePrivateProfileStringA(NULL
, NULL
, NULL
, "winetest_map.ini");
1538 todo_wine
ok(ret
, "got error %u\n", GetLastError());
1540 ret
= WritePrivateProfileStringA("section6", "name2", "value2", "winetest_map.ini");
1541 ok(ret
, "got error %u\n", GetLastError());
1542 ret
= WritePrivateProfileStringA("section6", "name3", "value3", "winetest_map.ini");
1543 ok(ret
, "got error %u\n", GetLastError());
1545 ret
= RegOpenKeyExA(HKEY_CURRENT_USER
, "winetest_default", 0, KEY_READ
| KEY_WRITE
, &mapped_key
);
1546 ok(!ret
, "got error %u\n", ret
);
1547 check_registry_value(mapped_key
, "name3", "value3");
1549 ret
= RegSetValueExA(mapped_key
, "name3", 0, REG_SZ
, (BYTE
*)"three", sizeof("three"));
1550 ok(!ret
, "got error %u\n", ret
);
1551 check_profile_string("section6", "name3", "winetest_map.ini", "three");
1553 memset(buffer
, 0xcc, sizeof(buffer
));
1554 ret
= GetPrivateProfileSectionA("section6", buffer
, sizeof(buffer
), "winetest_map.ini");
1555 ok(ret
== 25, "got %u\n", ret
);
1556 todo_wine
ok(!memcmp(buffer
, "name2=value2\0name3=three\0", 26), "got %s\n", debugstr_an(buffer
, ret
));
1558 ret
= WritePrivateProfileSectionA("section6", "name2=duo\0name3=treis\0", "winetest_map.ini");
1559 ok(ret
, "got error %u\n", GetLastError());
1560 check_profile_string("section6", "name2", "winetest_map.ini", "duo");
1561 check_profile_string("section6", "name3", "winetest_map.ini", "treis");
1563 ret
= WritePrivateProfileStringA("section6", NULL
, NULL
, "winetest_map.ini");
1564 ok(ret
, "got error %u\n", GetLastError());
1565 check_profile_string("section6", "name2", "winetest_map.ini", "default");
1566 check_profile_string("section6", "name3", "winetest_map.ini", "default");
1568 ret
= RegDeleteKeyA(HKEY_LOCAL_MACHINE
, "Software\\winetest_name2");
1569 ok(!ret
, "got error %u\n", ret
);
1570 ret
= RegDeleteKeyA(HKEY_CURRENT_USER
, "winetest_name1");
1571 ok(!ret
, "got error %u\n", ret
);
1572 ret
= RegDeleteKeyA(mapped_key
, "");
1573 ok(!ret
, "got error %u\n", ret
);
1574 RegCloseKey(mapped_key
);
1576 ret
= RegDeleteKeyA(mapping_subkey
, "");
1577 ok(!ret
, "got error %u\n", ret
);
1578 RegCloseKey(mapping_subkey
);
1580 ret
= RegDeleteKeyA(mapping_key
, "");
1581 ok(!ret
, "got error %u\n", ret
);
1582 RegCloseKey(mapping_key
);
1584 ret
= DeleteFileA("C:/windows/winetest_map.ini");
1585 ok(!ret
, "expected failure\n");
1586 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %u\n", GetLastError());
1587 ret
= RevertToSelf();
1588 ok(ret
, "got error %u\n", GetLastError());
1594 test_profile_string();
1595 test_profile_sections();
1596 test_profile_sections_names();
1597 test_profile_existing();
1598 test_profile_delete_on_close();
1599 test_profile_refresh();
1600 test_profile_directory_readonly();
1601 test_GetPrivateProfileString(
1604 "name2=\"val2\"\r\n"
1609 test_GetPrivateProfileString(
1617 test_WritePrivateProfileString();
1618 test_profile_struct();
1619 test_registry_mapping();