2003-03-04 05:34:57 +01:00
/*
* Unit tests for profile functions
*
* Copyright ( c ) 2003 Stefan Leichter
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2003-03-04 05:34:57 +01:00
*/
2003-09-06 01:08:26 +02:00
# include <stdarg.h>
2008-05-22 12:15:37 +02:00
# include <stdio.h>
2003-09-06 01:08:26 +02:00
2003-03-04 05:34:57 +01:00
# include "wine/test.h"
2003-09-06 01:08:26 +02:00
# include "windef.h"
2003-03-04 05:34:57 +01:00
# include "winbase.h"
# include "windows.h"
2018-01-27 21:11:10 +01:00
# include "sddl.h"
2003-03-04 05:34:57 +01:00
# define KEY "ProfileInt"
# define SECTION "Test"
# define TESTFILE ".\\testwine.ini"
2005-03-02 11:08:18 +01:00
# define TESTFILE2 ".\\testwine2.ini"
2003-03-04 05:34:57 +01:00
struct _profileInt {
LPCSTR section ;
LPCSTR key ;
LPCSTR value ;
LPCSTR iniFile ;
INT defaultVal ;
UINT result ;
2004-06-18 01:00:54 +02:00
UINT result9x ;
2003-03-04 05:34:57 +01:00
} ;
static void test_profile_int ( void )
{
struct _profileInt profileInt [ ] = {
2004-06-18 01:00:54 +02:00
{ NULL , NULL , NULL , NULL , 70 , 0 , 0 } , /* 0 */
{ NULL , NULL , NULL , TESTFILE , - 1 , 4294967295U , 0 } ,
{ NULL , NULL , NULL , TESTFILE , 1 , 1 , 0 } ,
{ SECTION , NULL , NULL , TESTFILE , - 1 , 4294967295U , 0 } ,
{ SECTION , NULL , NULL , TESTFILE , 1 , 1 , 0 } ,
{ NULL , KEY , NULL , TESTFILE , - 1 , 4294967295U , 0 } , /* 5 */
{ NULL , KEY , NULL , TESTFILE , 1 , 1 , 0 } ,
{ SECTION , KEY , NULL , TESTFILE , - 1 , 4294967295U , 4294967295U } ,
{ SECTION , KEY , NULL , TESTFILE , 1 , 1 , 1 } ,
{ SECTION , KEY , " -1 " , TESTFILE , - 1 , 4294967295U , 4294967295U } ,
{ SECTION , KEY , " -1 " , TESTFILE , 1 , 4294967295U , 4294967295U } , /* 10 */
{ SECTION , KEY , " 1 " , TESTFILE , - 1 , 1 , 1 } ,
{ SECTION , KEY , " 1 " , TESTFILE , 1 , 1 , 1 } ,
{ SECTION , KEY , " +1 " , TESTFILE , - 1 , 1 , 0 } ,
{ SECTION , KEY , " +1 " , TESTFILE , 1 , 1 , 0 } ,
{ SECTION , KEY , " 4294967296 " , TESTFILE , - 1 , 0 , 0 } , /* 15 */
{ SECTION , KEY , " 4294967296 " , TESTFILE , 1 , 0 , 0 } ,
{ SECTION , KEY , " 4294967297 " , TESTFILE , - 1 , 1 , 1 } ,
{ SECTION , KEY , " 4294967297 " , TESTFILE , 1 , 1 , 1 } ,
{ SECTION , KEY , " -4294967297 " , TESTFILE , - 1 , 4294967295U , 4294967295U } ,
{ SECTION , KEY , " -4294967297 " , TESTFILE , 1 , 4294967295U , 4294967295U } , /* 20 */
{ SECTION , KEY , " 42A94967297 " , TESTFILE , - 1 , 42 , 42 } ,
{ SECTION , KEY , " 42A94967297 " , TESTFILE , 1 , 42 , 42 } ,
{ SECTION , KEY , " B4294967297 " , TESTFILE , - 1 , 0 , 0 } ,
{ SECTION , KEY , " B4294967297 " , TESTFILE , 1 , 0 , 0 } ,
2003-03-04 05:34:57 +01:00
} ;
2018-06-27 20:56:45 +02:00
int i , num_test = ARRAY_SIZE ( profileInt ) ;
2003-03-04 05:34:57 +01:00
UINT res ;
DeleteFileA ( TESTFILE ) ;
for ( i = 0 ; i < num_test ; i + + ) {
if ( profileInt [ i ] . value )
WritePrivateProfileStringA ( SECTION , KEY , profileInt [ i ] . value ,
profileInt [ i ] . iniFile ) ;
res = GetPrivateProfileIntA ( profileInt [ i ] . section , profileInt [ i ] . key ,
profileInt [ i ] . defaultVal , profileInt [ i ] . iniFile ) ;
2004-06-18 01:00:54 +02:00
ok ( ( res = = profileInt [ i ] . result ) | | ( res = = profileInt [ i ] . result9x ) ,
" test<%02d>: ret<%010u> exp<%010u><%010u> \n " ,
i , res , profileInt [ i ] . result , profileInt [ i ] . result9x ) ;
2003-03-04 05:34:57 +01:00
}
DeleteFileA ( TESTFILE ) ;
}
2005-06-14 13:40:04 +02:00
static void test_profile_string ( void )
2005-03-02 11:08:18 +01:00
{
2014-01-10 02:37:02 +01:00
static WCHAR emptyW [ ] = { 0 } ; /* if "const", GetPrivateProfileStringW(emptyW, ...) crashes on win2k */
2013-12-24 09:25:37 +01:00
static const WCHAR keyW [ ] = { ' k ' , ' e ' , ' y ' , 0 } ;
static const WCHAR sW [ ] = { ' s ' , 0 } ;
static const WCHAR TESTFILE2W [ ] = { ' . ' , ' \\ ' , ' t ' , ' e ' , ' s ' , ' t ' , ' w ' , ' i ' , ' n ' , ' e ' , ' 2 ' , ' . ' , ' i ' , ' n ' , ' i ' , 0 } ;
static const WCHAR valsectionW [ ] = { ' v ' , ' a ' , ' l ' , ' _ ' , ' e ' , ' _ ' , ' s ' , ' e ' , ' c ' , ' t ' , ' i ' , ' o ' , ' n ' , 0 } ;
static const WCHAR valnokeyW [ ] = { ' v ' , ' a ' , ' l ' , ' _ ' , ' n ' , ' o ' , ' _ ' , ' k ' , ' e ' , ' y ' , 0 } ;
2005-03-02 11:08:18 +01:00
HANDLE h ;
int ret ;
DWORD count ;
char buf [ 100 ] ;
2009-08-21 13:03:37 +02:00
WCHAR bufW [ 100 ] ;
2005-03-02 11:08:18 +01:00
char * p ;
/* test that lines without an '=' will not be enumerated */
/* in the case below, name2 is a key while name3 is not. */
char content [ ] = " [s] \r \n name1=val1 \r \n name2= \r \n name3 \r \n name4=val4 \r \n " ;
2009-08-21 13:03:37 +02:00
char content2 [ ] = " \r \n key=val_no_section \r \n [] \r \n key=val_e_section \r \n "
" [s] \r \n =val_no_key \r \n [t] \r \n " ;
2005-03-02 11:08:18 +01:00
DeleteFileA ( TESTFILE2 ) ;
h = CreateFileA ( TESTFILE2 , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS ,
FILE_ATTRIBUTE_NORMAL , NULL ) ;
ok ( h ! = INVALID_HANDLE_VALUE , " cannot create %s \n " , TESTFILE2 ) ;
if ( h = = INVALID_HANDLE_VALUE ) return ;
WriteFile ( h , content , sizeof ( content ) , & count , NULL ) ;
CloseHandle ( h ) ;
2005-08-10 14:59:38 +02:00
2005-03-02 11:08:18 +01:00
/* enumerate the keys */
ret = GetPrivateProfileStringA ( " s " , NULL , " " , buf , sizeof ( buf ) ,
TESTFILE2 ) ;
for ( p = buf + strlen ( buf ) + 1 ; * p ; p + = strlen ( p ) + 1 )
p [ - 1 ] = ' , ' ;
/* and test */
2005-08-10 14:59:38 +02:00
ok ( ret = = 18 & & ! strcmp ( buf , " name1,name2,name4 " ) , " wrong keys returned(%d): %s \n " , ret ,
2005-03-02 11:08:18 +01:00
buf ) ;
2005-03-04 11:46:55 +01:00
2005-03-02 11:08:18 +01:00
/* add a new key to test that the file is quite usable */
WritePrivateProfileStringA ( " s " , " name5 " , " val5 " , TESTFILE2 ) ;
ret = GetPrivateProfileStringA ( " s " , NULL , " " , buf , sizeof ( buf ) ,
TESTFILE2 ) ;
for ( p = buf + strlen ( buf ) + 1 ; * p ; p + = strlen ( p ) + 1 )
p [ - 1 ] = ' , ' ;
2005-08-10 14:59:38 +02:00
ok ( ret = = 24 & & ! strcmp ( buf , " name1,name2,name4,name5 " ) , " wrong keys returned(%d): %s \n " ,
ret , buf ) ;
2009-08-21 13:03:37 +02:00
h = CreateFileA ( TESTFILE2 , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS ,
FILE_ATTRIBUTE_NORMAL , NULL ) ;
ok ( h ! = INVALID_HANDLE_VALUE , " cannot create %s \n " , TESTFILE2 ) ;
if ( h = = INVALID_HANDLE_VALUE ) return ;
WriteFile ( h , content2 , sizeof ( content2 ) , & count , NULL ) ;
CloseHandle ( h ) ;
/* works only in unicode, ascii crashes */
2018-06-27 20:56:45 +02:00
ret = GetPrivateProfileStringW ( emptyW , keyW , emptyW , bufW , ARRAY_SIZE ( bufW ) , TESTFILE2W ) ;
2009-08-21 13:03:37 +02:00
todo_wine
2011-07-26 03:39:58 +02:00
ok ( ret = = 13 , " expected 13, got %u \n " , ret ) ;
todo_wine
2009-08-21 13:03:37 +02:00
ok ( ! lstrcmpW ( valsectionW , bufW ) , " expected %s, got %s \n " ,
wine_dbgstr_w ( valsectionW ) , wine_dbgstr_w ( bufW ) ) ;
/* works only in unicode, ascii crashes */
2018-06-27 20:56:45 +02:00
ret = GetPrivateProfileStringW ( sW , emptyW , emptyW , bufW , ARRAY_SIZE ( bufW ) , TESTFILE2W ) ;
2011-07-26 03:39:58 +02:00
ok ( ret = = 10 , " expected 10, got %u \n " , ret ) ;
2009-08-21 13:03:37 +02:00
ok ( ! lstrcmpW ( valnokeyW , bufW ) , " expected %s, got %s \n " ,
wine_dbgstr_w ( valnokeyW ) , wine_dbgstr_w ( bufW ) ) ;
2005-03-02 11:08:18 +01:00
DeleteFileA ( TESTFILE2 ) ;
}
2007-03-27 22:08:07 +02:00
static void test_profile_sections ( void )
{
HANDLE h ;
int ret ;
DWORD count ;
char buf [ 100 ] ;
char * p ;
2018-03-06 09:13:20 +01:00
static const char content [ ] = " [section1] \r \n name1=val1 \r \n name2= \r \n name3 \r \n name4=val4 \r \n [section2] \r \n [section3] \r \n =val5 \r \n " ;
2007-03-27 22:08:07 +02:00
static const char testfile4 [ ] = " . \\ testwine4.ini " ;
2007-07-05 16:30:09 +02:00
BOOL on_win98 = FALSE ;
2007-03-27 22:08:07 +02:00
DeleteFileA ( testfile4 ) ;
h = CreateFileA ( testfile4 , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
ok ( h ! = INVALID_HANDLE_VALUE , " cannot create %s \n " , testfile4 ) ;
if ( h = = INVALID_HANDLE_VALUE ) return ;
WriteFile ( h , content , sizeof ( content ) , & count , NULL ) ;
CloseHandle ( h ) ;
2007-03-27 22:08:20 +02:00
/* Some parameter checking */
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileSectionA ( NULL , NULL , 0 , NULL ) ;
ok ( ret = = 0 , " expected return size 0, got %d \n " , ret ) ;
2007-07-05 16:30:09 +02:00
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER | |
GetLastError ( ) = = 0xdeadbeef /* Win98 */ ,
" expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
if ( GetLastError ( ) = = 0xdeadbeef ) on_win98 = TRUE ;
2007-03-27 22:08:20 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileSectionA ( NULL , NULL , 0 , testfile4 ) ;
ok ( ret = = 0 , " expected return size 0, got %d \n " , ret ) ;
2007-07-05 16:30:09 +02:00
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER | |
GetLastError ( ) = = 0xdeadbeef /* Win98 */ ,
" expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
if ( ! on_win98 )
{
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileSectionA ( " section1 " , NULL , 0 , testfile4 ) ;
ok ( ret = = 0 , " expected return size 0, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
}
2007-03-27 22:08:20 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileSectionA ( NULL , buf , sizeof ( buf ) , testfile4 ) ;
ok ( ret = = 0 , " expected return size 0, got %d \n " , ret ) ;
2009-01-31 15:03:13 +01:00
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER | |
broken ( GetLastError ( ) = = 0xdeadbeef ) , /* Win9x, WinME */
" expected ERROR_INVALID_PARAMETER, got %d \n " , GetLastError ( ) ) ;
2007-03-27 22:08:20 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileSectionA ( " section1 " , buf , sizeof ( buf ) , NULL ) ;
ok ( ret = = 0 , " expected return size 0, got %d \n " , ret ) ;
todo_wine
2009-01-31 15:03:13 +01:00
ok ( GetLastError ( ) = = ERROR_FILE_NOT_FOUND | |
broken ( GetLastError ( ) = = 0xdeadbeef ) , /* Win9x, WinME */
" expected ERROR_FILE_NOT_FOUND, got %d \n " , GetLastError ( ) ) ;
2007-03-27 22:08:20 +02:00
2009-04-20 09:01:55 +02:00
/* Existing empty section with no keys */
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileSectionA ( " section2 " , buf , sizeof ( buf ) , testfile4 ) ;
ok ( ret = = 0 , " expected return size 0, got %d \n " , ret ) ;
ok ( GetLastError ( ) = = ERROR_SUCCESS | |
broken ( GetLastError ( ) = = 0xdeadbeef ) , /* Win9x, WinME */
" expected ERROR_SUCCESS, got %d \n " , GetLastError ( ) ) ;
/* Existing section with keys and values*/
2008-09-11 05:55:09 +02:00
SetLastError ( 0xdeadbeef ) ;
2007-03-27 22:08:20 +02:00
ret = GetPrivateProfileSectionA ( " section1 " , buf , sizeof ( buf ) , testfile4 ) ;
2007-03-27 22:08:07 +02:00
for ( p = buf + strlen ( buf ) + 1 ; * p ; p + = strlen ( p ) + 1 )
p [ - 1 ] = ' , ' ;
ok ( ret = = 35 & & ! strcmp ( buf , " name1=val1,name2=,name3,name4=val4 " ) , " wrong section returned(%d): %s \n " ,
ret , buf ) ;
2007-03-27 22:08:20 +02:00
ok ( buf [ ret - 1 ] = = 0 & & buf [ ret ] = = 0 , " returned buffer not terminated with double-null \n " ) ;
2018-03-06 09:13:20 +01:00
ok ( GetLastError ( ) = = ERROR_SUCCESS | |
broken ( GetLastError ( ) = = 0xdeadbeef ) , /* Win9x, WinME */
" expected ERROR_SUCCESS, got %d \n " , GetLastError ( ) ) ;
/* Existing section with no keys but has values */
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileSectionA ( " section3 " , buf , sizeof ( buf ) , testfile4 ) ;
trace ( " section3 return: %s \n " , buf ) ;
for ( p = buf + strlen ( buf ) + 1 ; * p ; p + = strlen ( p ) + 1 )
p [ - 1 ] = ' , ' ;
ok ( ret = = 6 & & ! strcmp ( buf , " =val5 " ) , " wrong section returned(%d): %s \n " ,
ret , buf ) ;
ok ( buf [ ret - 1 ] = = 0 & & buf [ ret ] = = 0 , " returned buffer not terminated with double-null \n " ) ;
2009-01-31 15:03:13 +01:00
ok ( GetLastError ( ) = = ERROR_SUCCESS | |
broken ( GetLastError ( ) = = 0xdeadbeef ) , /* Win9x, WinME */
" expected ERROR_SUCCESS, got %d \n " , GetLastError ( ) ) ;
2007-03-27 22:08:07 +02:00
2009-10-08 16:28:17 +02:00
/* Overflow*/
ret = GetPrivateProfileSectionA ( " section1 " , buf , 24 , testfile4 ) ;
for ( p = buf + strlen ( buf ) + 1 ; * p ; p + = strlen ( p ) + 1 )
p [ - 1 ] = ' , ' ;
ok ( ret = = 22 & & ! strcmp ( buf , " name1=val1,name2=,name " ) , " wrong section returned(%d): %s \n " ,
ret , buf ) ;
ok ( buf [ ret ] = = 0 & & buf [ ret + 1 ] = = 0 , " returned buffer not terminated with double-null \n " ) ;
2007-03-27 22:08:07 +02:00
DeleteFileA ( testfile4 ) ;
}
2007-03-27 22:07:57 +02:00
static void test_profile_sections_names ( void )
2006-08-25 20:00:53 +02:00
{
HANDLE h ;
int ret ;
DWORD count ;
char buf [ 100 ] ;
WCHAR bufW [ 100 ] ;
static const char content [ ] = " [section1] \r \n [section2] \r \n [section3] \r \n " ;
static const char testfile3 [ ] = " . \\ testwine3.ini " ;
static const WCHAR testfile3W [ ] = { ' . ' , ' \\ ' , ' t ' , ' e ' , ' s ' , ' t ' , ' w ' , ' i ' , ' n ' , ' e ' , ' 3 ' , ' . ' , ' i ' , ' n ' , ' i ' , 0 } ;
2007-03-14 15:55:14 +01:00
static const WCHAR not_here [ ] = { ' . ' , ' \\ ' , ' n ' , ' o ' , ' t ' , ' _ ' , ' h ' , ' e ' , ' r ' , ' e ' , ' . ' , ' i ' , ' n ' , ' i ' , 0 } ;
2006-08-25 20:00:53 +02:00
DeleteFileA ( testfile3 ) ;
h = CreateFileA ( testfile3 , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS ,
FILE_ATTRIBUTE_NORMAL , NULL ) ;
ok ( h ! = INVALID_HANDLE_VALUE , " cannot create %s \n " , testfile3 ) ;
if ( h = = INVALID_HANDLE_VALUE ) return ;
WriteFile ( h , content , sizeof ( content ) , & count , NULL ) ;
CloseHandle ( h ) ;
/* Test with sufficiently large buffer */
2009-01-28 09:00:26 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2006-08-25 20:00:53 +02:00
ret = GetPrivateProfileSectionNamesA ( buf , 29 , testfile3 ) ;
2009-01-28 21:17:08 +01:00
ok ( ret = = 27 | |
broken ( ret = = 28 ) , /* Win9x, WinME */
" expected return size 27, got %d \n " , ret ) ;
ok ( ( buf [ ret - 1 ] = = 0 & & buf [ ret ] = = 0 ) | |
broken ( buf [ ret - 1 ] = = 0 & & buf [ ret - 2 ] = = 0 ) , /* Win9x, WinME */
" returned buffer not terminated with double-null \n " ) ;
2006-08-25 20:00:53 +02:00
/* Test with exactly fitting buffer */
2009-01-28 09:00:26 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2006-08-25 20:00:53 +02:00
ret = GetPrivateProfileSectionNamesA ( buf , 28 , testfile3 ) ;
2009-01-28 20:51:56 +01:00
ok ( ret = = 26 | |
broken ( ret = = 28 ) , /* Win9x, WinME */
" expected return size 26, got %d \n " , ret ) ;
2009-01-28 09:00:26 +01:00
todo_wine
2009-01-28 20:51:56 +01:00
ok ( ( buf [ ret + 1 ] = = 0 & & buf [ ret ] = = 0 ) | | /* W2K3 and higher */
broken ( buf [ ret + 1 ] = = 0xc & & buf [ ret ] = = 0 ) | | /* NT4, W2K, WinXP */
broken ( buf [ ret - 1 ] = = 0 & & buf [ ret - 2 ] = = 0 ) , /* Win9x, WinME */
" returned buffer not terminated with double-null \n " ) ;
2006-08-25 20:00:53 +02:00
/* Test with a buffer too small */
2009-01-28 09:00:26 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2006-08-25 20:00:53 +02:00
ret = GetPrivateProfileSectionNamesA ( buf , 27 , testfile3 ) ;
ok ( ret = = 25 , " expected return size 25, got %d \n " , ret ) ;
2009-01-28 21:17:08 +01:00
/* Win9x and WinME only fills the buffer with complete section names (double-null terminated) */
count = strlen ( " section1 " ) + sizeof ( CHAR ) + strlen ( " section2 " ) ;
2009-01-28 09:00:26 +01:00
todo_wine
2009-01-28 21:17:08 +01:00
ok ( ( buf [ ret + 1 ] = = 0 & & buf [ ret ] = = 0 ) | |
broken ( buf [ count ] = = 0 & & buf [ count + 1 ] = = 0 ) , /* Win9x, WinME */
" returned buffer not terminated with double-null \n " ) ;
2007-07-05 16:35:10 +02:00
/* Tests on nonexistent file */
2009-01-28 09:00:26 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2007-07-05 16:35:10 +02:00
ret = GetPrivateProfileSectionNamesA ( buf , 10 , " . \\ not_here.ini " ) ;
2009-01-28 21:17:08 +01:00
ok ( ret = = 0 | |
broken ( ret = = 1 ) , /* Win9x, WinME */
" expected return size 0, got %d \n " , ret ) ;
2007-07-05 16:35:10 +02:00
ok ( buf [ 0 ] = = 0 , " returned buffer not terminated with null \n " ) ;
ok ( buf [ 1 ] ! = 0 , " returned buffer terminated with double-null \n " ) ;
2006-08-25 20:00:53 +02:00
/* Test with sufficiently large buffer */
2007-07-05 16:35:10 +02:00
SetLastError ( 0xdeadbeef ) ;
2009-01-28 09:00:26 +01:00
memset ( bufW , 0xcc , sizeof ( bufW ) ) ;
2006-08-25 20:00:53 +02:00
ret = GetPrivateProfileSectionNamesW ( bufW , 29 , testfile3W ) ;
2007-07-07 22:00:07 +02:00
if ( ret = = 0 & & ( GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ) )
2007-07-05 16:35:10 +02:00
{
2009-01-29 19:46:50 +01:00
win_skip ( " GetPrivateProfileSectionNamesW is not implemented \n " ) ;
2007-07-05 16:35:10 +02:00
DeleteFileA ( testfile3 ) ;
return ;
}
2006-08-25 20:00:53 +02:00
ok ( ret = = 27 , " expected return size 27, got %d \n " , ret ) ;
2007-07-05 16:35:10 +02:00
ok ( bufW [ ret - 1 ] = = 0 & & bufW [ ret ] = = 0 , " returned buffer not terminated with double-null \n " ) ;
2006-08-25 20:00:53 +02:00
/* Test with exactly fitting buffer */
2009-01-28 09:00:26 +01:00
memset ( bufW , 0xcc , sizeof ( bufW ) ) ;
2006-08-25 20:00:53 +02:00
ret = GetPrivateProfileSectionNamesW ( bufW , 28 , testfile3W ) ;
ok ( ret = = 26 , " expected return size 26, got %d \n " , ret ) ;
2009-01-28 20:51:56 +01:00
ok ( ( bufW [ ret + 1 ] = = 0 & & bufW [ ret ] = = 0 ) | | /* W2K3 and higher */
broken ( bufW [ ret + 1 ] = = 0xcccc & & bufW [ ret ] = = 0 ) , /* NT4, W2K, WinXP */
" returned buffer not terminated with double-null \n " ) ;
2006-08-25 20:00:53 +02:00
/* Test with a buffer too small */
2009-01-28 09:00:26 +01:00
memset ( bufW , 0xcc , sizeof ( bufW ) ) ;
2006-08-25 20:00:53 +02:00
ret = GetPrivateProfileSectionNamesW ( bufW , 27 , testfile3W ) ;
ok ( ret = = 25 , " expected return size 25, got %d \n " , ret ) ;
2007-07-05 16:35:10 +02:00
ok ( bufW [ ret + 1 ] = = 0 & & bufW [ ret ] = = 0 , " returned buffer not terminated with double-null \n " ) ;
2006-08-25 20:00:53 +02:00
DeleteFileA ( testfile3 ) ;
2007-03-14 15:55:14 +01:00
2007-04-02 19:17:56 +02:00
/* Tests on nonexistent file */
2007-03-14 15:55:14 +01:00
memset ( bufW , 0xcc , sizeof ( bufW ) ) ;
ret = GetPrivateProfileSectionNamesW ( bufW , 10 , not_here ) ;
ok ( ret = = 0 , " expected return size 0, got %d \n " , ret ) ;
ok ( bufW [ 0 ] = = 0 , " returned buffer not terminated with null \n " ) ;
ok ( bufW [ 1 ] ! = 0 , " returned buffer terminated with double-null \n " ) ;
2006-08-25 20:00:53 +02:00
}
2008-05-21 14:23:44 +02:00
/* If the ini-file has already been opened with CreateFile, WritePrivateProfileString failed in wine with an error ERROR_SHARING_VIOLATION, some testing here */
static void test_profile_existing ( void )
{
2008-05-22 12:15:37 +02:00
static const char * testfile1 = " . \\ winesharing1.ini " ;
static const char * testfile2 = " . \\ winesharing2.ini " ;
2008-05-21 14:23:44 +02:00
static const struct {
DWORD dwDesiredAccess ;
DWORD dwShareMode ;
2008-05-22 12:15:37 +02:00
DWORD write_error ;
BOOL read_error ;
2008-11-10 11:09:02 +01:00
DWORD broken_error ;
2008-05-21 14:23:44 +02:00
} pe [ ] = {
2008-05-22 12:15:37 +02:00
{ GENERIC_READ , FILE_SHARE_READ , ERROR_SHARING_VIOLATION , FALSE } ,
{ GENERIC_READ , FILE_SHARE_WRITE , ERROR_SHARING_VIOLATION , TRUE } ,
{ GENERIC_WRITE , FILE_SHARE_READ , ERROR_SHARING_VIOLATION , FALSE } ,
{ GENERIC_WRITE , FILE_SHARE_WRITE , ERROR_SHARING_VIOLATION , TRUE } ,
{ GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ , ERROR_SHARING_VIOLATION , FALSE } ,
{ GENERIC_READ | GENERIC_WRITE , FILE_SHARE_WRITE , ERROR_SHARING_VIOLATION , TRUE } ,
2008-11-10 11:09:02 +01:00
{ GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE , 0 , FALSE , ERROR_SHARING_VIOLATION /* nt4 */ } ,
{ GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE , 0 , FALSE , ERROR_SHARING_VIOLATION /* nt4 */ } ,
2008-05-21 14:23:44 +02:00
/*Thief demo (bug 5024) opens .ini file like this*/
2008-11-10 11:09:02 +01:00
{ GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE , 0 , FALSE , ERROR_SHARING_VIOLATION /* nt4 */ }
2008-05-21 14:23:44 +02:00
} ;
int i ;
BOOL ret ;
DWORD size ;
HANDLE h = 0 ;
char buffer [ MAX_PATH ] ;
2018-06-27 20:56:45 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( pe ) ; i + + )
2008-05-21 14:23:44 +02:00
{
2013-10-21 10:02:27 +02:00
h = CreateFileA ( testfile1 , pe [ i ] . dwDesiredAccess , pe [ i ] . dwShareMode , NULL ,
2008-05-22 12:15:37 +02:00
CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
2008-05-21 14:23:44 +02:00
ok ( INVALID_HANDLE_VALUE ! = h , " %d: CreateFile failed \n " , i ) ;
SetLastError ( 0xdeadbeef ) ;
2008-05-22 12:15:37 +02:00
2013-10-21 10:02:27 +02:00
ret = WritePrivateProfileStringA ( SECTION , KEY , " 12345 " , testfile1 ) ;
2008-05-22 12:15:37 +02:00
if ( ! pe [ i ] . write_error )
2008-05-21 14:23:44 +02:00
{
2008-11-10 11:09:02 +01:00
if ( ! ret )
ok ( broken ( GetLastError ( ) = = pe [ i ] . broken_error ) ,
" %d: WritePrivateProfileString failed with error %u \n " , i , GetLastError ( ) ) ;
2008-05-21 14:23:44 +02:00
CloseHandle ( h ) ;
2013-10-21 10:02:27 +02:00
size = GetPrivateProfileStringA ( SECTION , KEY , 0 , buffer , MAX_PATH , testfile1 ) ;
2008-11-10 11:09:02 +01:00
if ( ret )
ok ( size = = 5 , " %d: test failed, number of characters copied: %d instead of 5 \n " , i , size ) ;
else
ok ( ! size , " %d: test failed, number of characters copied: %d instead of 0 \n " , i , size ) ;
2008-05-21 14:23:44 +02:00
}
else
{
DWORD err = GetLastError ( ) ;
ok ( ! ret , " %d: WritePrivateProfileString succeeded \n " , i ) ;
2008-05-22 12:15:37 +02:00
if ( ! ret )
ok ( err = = pe [ i ] . write_error , " %d: WritePrivateProfileString failed with error %u/%u \n " ,
i , err , pe [ i ] . write_error ) ;
2008-05-21 14:23:44 +02:00
CloseHandle ( h ) ;
2013-10-21 10:02:27 +02:00
size = GetPrivateProfileStringA ( SECTION , KEY , 0 , buffer , MAX_PATH , testfile1 ) ;
2008-05-21 14:23:44 +02:00
ok ( ! size , " %d: test failed, number of characters copied: %d instead of 0 \n " , i , size ) ;
}
2008-05-22 12:15:37 +02:00
2013-10-21 10:02:27 +02:00
ok ( DeleteFileA ( testfile1 ) , " delete failed \n " ) ;
2008-05-22 12:15:37 +02:00
}
2013-10-21 10:02:27 +02:00
h = CreateFileA ( testfile2 , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
2008-05-22 12:15:37 +02:00
sprintf ( buffer , " [%s] \r \n %s=123 \r \n " , SECTION , KEY ) ;
ok ( WriteFile ( h , buffer , strlen ( buffer ) , & size , NULL ) , " failed to write \n " ) ;
CloseHandle ( h ) ;
2018-06-27 20:56:45 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( pe ) ; i + + )
2008-05-22 12:15:37 +02:00
{
2013-10-21 10:02:27 +02:00
h = CreateFileA ( testfile2 , pe [ i ] . dwDesiredAccess , pe [ i ] . dwShareMode , NULL ,
2008-05-22 12:15:37 +02:00
OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL ) ;
ok ( INVALID_HANDLE_VALUE ! = h , " %d: CreateFile failed \n " , i ) ;
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileStringA ( SECTION , KEY , NULL , buffer , MAX_PATH , testfile2 ) ;
2009-01-31 15:23:33 +01:00
/* Win9x and WinME returns 0 for all cases except the first one */
2008-05-22 12:15:37 +02:00
if ( ! pe [ i ] . read_error )
2009-01-31 15:23:33 +01:00
ok ( ret | |
broken ( ! ret & & GetLastError ( ) = = 0xdeadbeef ) , /* Win9x, WinME */
" %d: GetPrivateProfileString failed with error %u \n " , i , GetLastError ( ) ) ;
2008-05-22 12:15:37 +02:00
else
ok ( ! ret , " %d: GetPrivateProfileString succeeded \n " , i ) ;
CloseHandle ( h ) ;
2008-05-21 14:23:44 +02:00
}
2013-10-21 10:02:27 +02:00
ok ( DeleteFileA ( testfile2 ) , " delete failed \n " ) ;
2008-05-21 14:23:44 +02:00
}
2009-01-28 00:35:55 +01:00
static void test_profile_delete_on_close ( void )
2008-08-17 19:03:14 +02:00
{
HANDLE h ;
DWORD size , res ;
2013-12-24 09:25:37 +01:00
static const CHAR testfile [ ] = " . \\ testwine5.ini " ;
2008-08-17 19:03:14 +02:00
static const char contents [ ] = " [ " SECTION " ] \n " KEY " =123 \n " ;
2013-10-21 10:02:27 +02:00
h = CreateFileA ( testfile , GENERIC_WRITE , FILE_SHARE_READ , NULL ,
2008-08-17 19:03:14 +02:00
CREATE_ALWAYS , FILE_FLAG_DELETE_ON_CLOSE , NULL ) ;
2011-09-25 20:30:38 +02:00
res = WriteFile ( h , contents , sizeof contents - 1 , & size , NULL ) ;
ok ( res , " Cannot write test file: %x \n " , GetLastError ( ) ) ;
2008-08-17 19:03:14 +02:00
ok ( size = = sizeof contents - 1 , " Test file: partial write \n " ) ;
2009-01-31 15:37:59 +01:00
SetLastError ( 0xdeadbeef ) ;
2013-10-21 10:02:27 +02:00
res = GetPrivateProfileIntA ( SECTION , KEY , 0 , testfile ) ;
2009-01-31 15:37:59 +01:00
ok ( res = = 123 | |
broken ( res = = 0 & & GetLastError ( ) = = ERROR_SHARING_VIOLATION ) , /* Win9x, WinME */
" Got %d instead of 123 \n " , res ) ;
2008-08-17 19:03:24 +02:00
/* This also deletes the file */
CloseHandle ( h ) ;
}
static void test_profile_refresh ( void )
{
2013-12-24 09:25:37 +01:00
static const CHAR testfile [ ] = " . \\ winetest4.ini " ;
2008-08-17 19:03:24 +02:00
HANDLE h ;
DWORD size , res ;
static const char contents1 [ ] = " [ " SECTION " ] \n " KEY " =123 \n " ;
static const char contents2 [ ] = " [ " SECTION " ] \n " KEY " =124 \n " ;
2013-10-21 10:02:27 +02:00
h = CreateFileA ( testfile , GENERIC_WRITE , FILE_SHARE_READ , NULL ,
2008-08-17 19:03:24 +02:00
CREATE_ALWAYS , FILE_FLAG_DELETE_ON_CLOSE , NULL ) ;
2011-09-25 20:30:38 +02:00
res = WriteFile ( h , contents1 , sizeof contents1 - 1 , & size , NULL ) ;
ok ( res , " Cannot write test file: %x \n " , GetLastError ( ) ) ;
2008-08-17 19:03:24 +02:00
ok ( size = = sizeof contents1 - 1 , " Test file: partial write \n " ) ;
2008-08-17 19:03:14 +02:00
2009-01-31 15:37:59 +01:00
SetLastError ( 0xdeadbeef ) ;
2013-10-21 10:02:27 +02:00
res = GetPrivateProfileIntA ( SECTION , KEY , 0 , testfile ) ;
2009-01-31 15:37:59 +01:00
ok ( res = = 123 | |
broken ( res = = 0 & & GetLastError ( ) = = ERROR_SHARING_VIOLATION ) , /* Win9x, WinME */
" Got %d instead of 123 \n " , res ) ;
2008-08-17 19:03:14 +02:00
2008-08-17 19:03:24 +02:00
CloseHandle ( h ) ;
/* Test proper invalidation of wine's profile file cache */
2013-10-21 10:02:27 +02:00
h = CreateFileA ( testfile , GENERIC_WRITE , FILE_SHARE_READ , NULL ,
2008-08-17 19:03:24 +02:00
CREATE_ALWAYS , FILE_FLAG_DELETE_ON_CLOSE , NULL ) ;
2011-09-25 20:30:38 +02:00
res = WriteFile ( h , contents2 , sizeof contents2 - 1 , & size , NULL ) ;
ok ( res , " Cannot write test file: %x \n " , GetLastError ( ) ) ;
2008-08-17 19:03:24 +02:00
ok ( size = = sizeof contents2 - 1 , " Test file: partial write \n " ) ;
2009-01-31 15:37:59 +01:00
SetLastError ( 0xdeadbeef ) ;
2013-10-21 10:02:27 +02:00
res = GetPrivateProfileIntA ( SECTION , KEY , 0 , testfile ) ;
2009-01-31 15:37:59 +01:00
ok ( res = = 124 | |
broken ( res = = 0 & & GetLastError ( ) = = 0xdeadbeef ) , /* Win9x, WinME */
" Got %d instead of 124 \n " , res ) ;
2008-08-17 19:03:24 +02:00
2008-08-17 19:03:14 +02:00
/* This also deletes the file */
CloseHandle ( h ) ;
2012-03-28 07:26:42 +02:00
/* Cache must be invalidated if file no longer exists and default must be returned */
SetLastError ( 0xdeadbeef ) ;
2013-10-21 10:02:27 +02:00
res = GetPrivateProfileIntA ( SECTION , KEY , 421 , testfile ) ;
2012-03-28 07:30:27 +02:00
ok ( res = = 421 | |
2012-03-28 07:26:42 +02:00
broken ( res = = 0 & & GetLastError ( ) = = 0xdeadbeef ) , /* Win9x, WinME */
" Got %d instead of 421 \n " , res ) ;
2008-08-17 19:03:14 +02:00
}
2008-07-16 23:25:02 +02:00
static void create_test_file ( LPCSTR name , LPCSTR data , DWORD size )
{
HANDLE hfile ;
DWORD count ;
hfile = CreateFileA ( name , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
ok ( hfile ! = INVALID_HANDLE_VALUE , " cannot create %s \n " , name ) ;
WriteFile ( hfile , data , size , & count , NULL ) ;
CloseHandle ( hfile ) ;
}
2008-08-17 19:03:03 +02:00
static BOOL emptystr_ok ( CHAR emptystr [ MAX_PATH ] )
{
int i ;
for ( i = 0 ; i < MAX_PATH ; + + i )
if ( emptystr [ i ] ! = 0 )
{
trace ( " emptystr[%d] = %d \n " , i , emptystr [ i ] ) ;
return FALSE ;
}
return TRUE ;
}
2018-01-27 21:11:10 +01:00
static void test_profile_directory_readonly ( void )
{
BOOL ret ;
CHAR path_folder [ MAX_PATH ] ;
CHAR path_file [ MAX_PATH ] ;
const char * sddl_string_everyone_readonly = " D:PAI(A;;0x1200a9;;;WD) " ;
SECURITY_ATTRIBUTES attributes = { 0 } ;
char lpStruct [ ] = { ' s ' , ' t ' , ' r ' , ' i ' , ' n ' , ' g ' } ;
attributes . nLength = sizeof ( attributes ) ;
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA ( sddl_string_everyone_readonly , SDDL_REVISION_1 , & attributes . lpSecurityDescriptor , NULL ) ;
ok ( ret = = TRUE , " ConvertStringSecurityDescriptorToSecurityDescriptor failed: %d \n " , GetLastError ( ) ) ;
GetTempPathA ( MAX_PATH , path_folder ) ;
lstrcatA ( path_folder , " wine-test " ) ;
strcpy ( path_file , path_folder ) ;
lstrcatA ( path_file , " \\ tmp.ini " ) ;
ret = CreateDirectoryA ( path_folder , & attributes ) ;
ok ( ret = = TRUE , " CreateDirectoryA failed: %d \n " , GetLastError ( ) ) ;
ret = WritePrivateProfileStringA ( " App " , " key " , " string " , path_file ) ;
ok ( ret = = FALSE , " Expected FALSE, got %d \n " , ret ) ;
ret = WritePrivateProfileSectionA ( " App " , " key=string " , path_file ) ;
ok ( ret = = FALSE , " Expected FALSE, got %d \n " , ret ) ;
ret = WritePrivateProfileStructA ( " App " , " key " , lpStruct , sizeof ( lpStruct ) , path_file ) ;
ok ( ret = = FALSE , " Expected FALSE, got %d \n " , ret ) ;
ret = RemoveDirectoryA ( path_folder ) ;
ok ( ret = = TRUE , " RemoveDirectoryA failed: %d \n " , GetLastError ( ) ) ;
2019-01-20 22:02:14 +01:00
LocalFree ( attributes . lpSecurityDescriptor ) ;
2018-01-27 21:11:10 +01:00
}
2008-09-21 16:49:16 +02:00
static void test_GetPrivateProfileString ( const char * content , const char * descript )
2008-07-16 23:25:02 +02:00
{
2009-01-29 20:23:13 +01:00
DWORD ret , len ;
2008-07-16 23:25:02 +02:00
CHAR buf [ MAX_PATH ] ;
2008-07-27 15:29:31 +02:00
CHAR def_val [ MAX_PATH ] ;
2008-07-16 23:25:02 +02:00
CHAR path [ MAX_PATH ] ;
CHAR windir [ MAX_PATH ] ;
2008-08-17 19:03:03 +02:00
/* NT series crashes on r/o empty strings, so pass an r/w
empty string and check for modification */
CHAR emptystr [ MAX_PATH ] = " " ;
2008-07-16 23:25:02 +02:00
LPSTR tempfile ;
static const char filename [ ] = " . \\ winetest.ini " ;
2008-09-21 16:49:16 +02:00
trace ( " test_GetPrivateProfileStringA: %s \n " , descript ) ;
2009-01-29 19:46:50 +01:00
if ( ! lstrcmpA ( descript , " CR only " ) )
{
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileStringW ( NULL , NULL , NULL ,
NULL , 0 , NULL ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
win_skip ( " Win9x and WinME don't handle 'CR only' correctly \n " ) ;
return ;
}
}
2008-09-21 16:49:16 +02:00
create_test_file ( filename , content , lstrlenA ( content ) ) ;
2008-07-16 23:25:02 +02:00
2008-08-17 19:03:24 +02:00
/* Run this test series with caching. Wine won't cache profile
files younger than 2.1 seconds . */
Sleep ( 2500 ) ;
2008-07-16 23:25:02 +02:00
/* lpAppName is NULL */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( NULL , " name1 " , " default " ,
buf , MAX_PATH , filename ) ;
2009-01-29 20:23:13 +01:00
ok ( ret = = 18 | |
broken ( ret = = 19 ) , /* Win9x and WinME */
" Expected 18, got %d \n " , ret ) ;
len = lstrlenA ( " section1 " ) + sizeof ( CHAR ) + lstrlenA ( " section2 " ) + 2 * sizeof ( CHAR ) ;
2009-01-31 14:50:02 +01:00
ok ( ! memcmp ( buf , " section1 \0 section2 \0 \0 " , len ) ,
" Expected \" section1 \\ 0section2 \\ 0 \\ 0 \" , got \" %s \" \n " , buf ) ;
2008-07-16 23:25:02 +02:00
/* lpAppName is empty */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( emptystr , " name1 " , " default " ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " AppName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpAppName is missing */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " notasection " , " name1 " , " default " ,
buf , MAX_PATH , filename ) ;
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
/* lpAppName is empty, lpDefault is NULL */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( emptystr , " name1 " , NULL ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
ok ( ret = = 0 , " Expected 0, got %d \n " , ret ) ;
2009-01-28 21:54:41 +01:00
ok ( ! lstrcmpA ( buf , " " ) | |
broken ( ! lstrcmpA ( buf , " kumquat " ) ) , /* Win9x, WinME */
" Expected \" \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " AppName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpAppName is empty, lpDefault is empty */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( emptystr , " name1 " , " " ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
ok ( ret = = 0 , " Expected 0, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " " ) , " Expected \" \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " AppName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpAppName is empty, lpDefault has trailing blank characters */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-04 10:20:20 +02:00
/* lpDefault must be writable (trailing blanks are removed inplace in win9x) */
2008-07-27 15:29:31 +02:00
lstrcpyA ( def_val , " default " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( emptystr , " name1 " , def_val ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
2008-07-16 23:25:54 +02:00
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " AppName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpAppName is empty, many blank characters in lpDefault */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-04 10:20:20 +02:00
/* lpDefault must be writable (trailing blanks are removed inplace in win9x) */
2008-07-27 15:29:31 +02:00
lstrcpyA ( def_val , " one two " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( emptystr , " name1 " , def_val ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
2008-07-16 23:25:54 +02:00
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " one two " ) , " Expected \" one two \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " AppName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpAppName is empty, blank character but not trailing in lpDefault */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( emptystr , " name1 " , " one two " ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " one two " ) , " Expected \" one two \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " AppName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpKeyName is NULL */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , NULL , " default " ,
buf , MAX_PATH , filename ) ;
ok ( ret = = 18 , " Expected 18, got %d \n " , ret ) ;
ok ( ! memcmp ( buf , " name1 \0 name2 \0 name4 \0 " , ret + 1 ) ,
" Expected \" name1 \\ 0name2 \\ 0name4 \\ 0 \" , got \" %s \" \n " , buf ) ;
/* lpKeyName is empty */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( " section1 " , emptystr , " default " ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
2008-07-16 23:27:17 +02:00
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " KeyName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpKeyName is missing */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " notakey " , " default " ,
buf , MAX_PATH , filename ) ;
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
/* lpKeyName is empty, lpDefault is NULL */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( " section1 " , emptystr , NULL ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
ok ( ret = = 0 , " Expected 0, got %d \n " , ret ) ;
2009-01-28 21:54:41 +01:00
ok ( ! lstrcmpA ( buf , " " ) | |
broken ( ! lstrcmpA ( buf , " kumquat " ) ) , /* Win9x, WinME */
" Expected \" \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " KeyName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpKeyName is empty, lpDefault is empty */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( " section1 " , emptystr , " " ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
ok ( ret = = 0 , " Expected 0, got %d \n " , ret ) ;
2008-07-16 23:27:17 +02:00
ok ( ! lstrcmpA ( buf , " " ) , " Expected \" \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " KeyName modified \n " ) ;
2008-07-16 23:25:02 +02:00
/* lpKeyName is empty, lpDefault has trailing blank characters */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
2008-08-04 10:20:20 +02:00
/* lpDefault must be writable (trailing blanks are removed inplace in win9x) */
2008-07-27 15:29:31 +02:00
lstrcpyA ( def_val , " default " ) ;
2008-08-17 19:03:03 +02:00
ret = GetPrivateProfileStringA ( " section1 " , emptystr , def_val ,
2008-07-16 23:25:02 +02:00
buf , MAX_PATH , filename ) ;
2008-07-16 23:27:17 +02:00
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
2008-08-17 19:03:03 +02:00
ok ( emptystr_ok ( emptystr ) , " KeyName modified \n " ) ;
2008-07-16 23:25:02 +02:00
if ( 0 ) /* crashes */
{
/* lpReturnedString is NULL */
ret = GetPrivateProfileStringA ( " section1 " , " name1 " , " default " ,
NULL , MAX_PATH , filename ) ;
}
/* lpFileName is NULL */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name1 " , " default " ,
buf , MAX_PATH , NULL ) ;
2009-01-28 21:54:41 +01:00
ok ( ret = = 7 | |
broken ( ret = = 0 ) , /* Win9x, WinME */
" Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) | |
broken ( ! lstrcmpA ( buf , " kumquat " ) ) , /* Win9x, WinME */
" Expected \" default \" , got \" %s \" \n " , buf ) ;
2008-07-16 23:25:02 +02:00
/* lpFileName is empty */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name1 " , " default " ,
buf , MAX_PATH , " " ) ;
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
/* lpFileName is nonexistent */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name1 " , " default " ,
buf , MAX_PATH , " nonexistent " ) ;
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
/* nSize is 0 */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name1 " , " default " ,
buf , 0 , filename ) ;
ok ( ret = = 0 , " Expected 0, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " kumquat " ) , " Expected buf to be unchanged, got \" %s \" \n " , buf ) ;
/* nSize is exact size of output */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name1 " , " default " ,
buf , 4 , filename ) ;
ok ( ret = = 3 , " Expected 3, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " val " ) , " Expected \" val \" , got \" %s \" \n " , buf ) ;
/* nSize has room for NULL terminator */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name1 " , " default " ,
buf , 5 , filename ) ;
ok ( ret = = 4 , " Expected 4, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " val1 " ) , " Expected \" val1 \" , got \" %s \" \n " , buf ) ;
/* output is 1 character */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name4 " , " default " ,
buf , MAX_PATH , filename ) ;
ok ( ret = = 1 , " Expected 1, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " a " ) , " Expected \" a \" , got \" %s \" \n " , buf ) ;
/* output is 1 character, no room for NULL terminator */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name4 " , " default " ,
buf , 1 , filename ) ;
ok ( ret = = 0 , " Expected 0, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " " ) , " Expected \" \" , got \" %s \" \n " , buf ) ;
/* lpAppName is NULL, not enough room for final section name */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( NULL , " name1 " , " default " ,
buf , 16 , filename ) ;
ok ( ret = = 14 , " Expected 14, got %d \n " , ret ) ;
2009-01-29 20:23:13 +01:00
len = lstrlenA ( " section1 " ) + 2 * sizeof ( CHAR ) ;
2009-01-31 14:50:02 +01:00
todo_wine
ok ( ! memcmp ( buf , " section1 \0 secti \0 \0 " , ret + 2 ) | |
2009-01-29 20:23:13 +01:00
broken ( ! memcmp ( buf , " section1 \0 \0 " , len ) ) , /* Win9x, WinME */
2009-01-31 14:50:02 +01:00
" Expected \" section1 \\ 0secti \\ 0 \\ 0 \" , got \" %s \" \n " , buf ) ;
2008-07-16 23:25:02 +02:00
/* lpKeyName is NULL, not enough room for final key name */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , NULL , " default " ,
buf , 16 , filename ) ;
ok ( ret = = 14 , " Expected 14, got %d \n " , ret ) ;
2009-01-31 14:50:02 +01:00
todo_wine
ok ( ! memcmp ( buf , " name1 \0 name2 \0 na \0 \0 " , ret + 2 ) | |
2009-01-29 20:23:13 +01:00
broken ( ! memcmp ( buf , " name1 \0 name2 \0 n \0 \0 " , ret + 1 ) ) , /* Win9x, WinME */
2009-01-31 14:50:02 +01:00
" Expected \" name1 \\ 0name2 \\ 0na \\ 0 \\ 0 \" , got \" %s \" \n " , buf ) ;
2008-07-16 23:25:02 +02:00
/* key value has quotation marks which are stripped */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name2 " , " default " ,
buf , MAX_PATH , filename ) ;
ok ( ret = = 4 , " Expected 4, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " val2 " ) , " Expected \" val2 \" , got \" %s \" \n " , buf ) ;
/* case does not match */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " NaMe1 " , " default " ,
buf , MAX_PATH , filename ) ;
ok ( ret = = 4 , " Expected 4, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " val1 " ) , " Expected \" val1 \" , got \" %s \" \n " , buf ) ;
/* only filename is used */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " NaMe1 " , " default " ,
buf , MAX_PATH , " winetest.ini " ) ;
ok ( ret = = 7 , " Expected 7, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " default " ) , " Expected \" default \" , got \" %s \" \n " , buf ) ;
GetWindowsDirectoryA ( windir , MAX_PATH ) ;
2009-01-28 11:43:30 +01:00
SetLastError ( 0xdeadbeef ) ;
ret = GetTempFileNameA ( windir , " pre " , 0 , path ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_ACCESS_DENIED )
{
skip ( " Not allowed to create a file in the Windows directory \n " ) ;
DeleteFileA ( filename ) ;
return ;
}
2008-07-16 23:25:02 +02:00
tempfile = strrchr ( path , ' \\ ' ) + 1 ;
2008-09-21 16:49:16 +02:00
create_test_file ( path , content , lstrlenA ( content ) ) ;
2008-07-16 23:25:02 +02:00
/* only filename is used, file exists in windows directory */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " NaMe1 " , " default " ,
buf , MAX_PATH , tempfile ) ;
ok ( ret = = 4 , " Expected 4, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " val1 " ) , " Expected \" val1 \" , got \" %s \" \n " , buf ) ;
/* successful case */
2009-01-31 14:50:02 +01:00
memset ( buf , 0xc , sizeof ( buf ) ) ;
2008-07-16 23:25:02 +02:00
lstrcpyA ( buf , " kumquat " ) ;
ret = GetPrivateProfileStringA ( " section1 " , " name1 " , " default " ,
buf , MAX_PATH , filename ) ;
ok ( ret = = 4 , " Expected 4, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " val1 " ) , " Expected \" val1 \" , got \" %s \" \n " , buf ) ;
2009-04-20 09:01:55 +02:00
/* Existing section with no keys in an existing file */
memset ( buf , 0xc , sizeof ( buf ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = GetPrivateProfileStringA ( " section2 " , " DoesntExist " , " " ,
buf , MAX_PATH , filename ) ;
ok ( ret = = 0 , " expected return size 0, got %d \n " , ret ) ;
ok ( ! lstrcmpA ( buf , " " ) , " Expected \" \" , got \" %s \" \n " , buf ) ;
todo_wine
2009-10-05 11:50:30 +02:00
ok ( GetLastError ( ) = = 0xdeadbeef | |
GetLastError ( ) = = ERROR_FILE_NOT_FOUND /* Win 7 */ ,
" expected 0xdeadbeef or ERROR_FILE_NOT_FOUND, got %d \n " , GetLastError ( ) ) ;
2009-04-20 09:01:55 +02:00
2008-07-16 23:25:02 +02:00
DeleteFileA ( path ) ;
DeleteFileA ( filename ) ;
}
2009-05-07 04:11:35 +02:00
static BOOL check_binary_file_data ( LPCSTR path , const VOID * data , DWORD size )
2009-03-22 22:36:54 +01:00
{
HANDLE file ;
CHAR buf [ MAX_PATH ] ;
BOOL ret ;
file = CreateFileA ( path , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , 0 , 0 ) ;
if ( file = = INVALID_HANDLE_VALUE )
return FALSE ;
2009-05-07 04:11:35 +02:00
if ( size ! = GetFileSize ( file , NULL ) )
{
CloseHandle ( file ) ;
return FALSE ;
}
2009-03-22 22:36:54 +01:00
ret = ReadFile ( file , buf , size , & size , NULL ) ;
CloseHandle ( file ) ;
if ( ! ret )
return FALSE ;
2009-05-07 04:11:35 +02:00
return ! memcmp ( buf , data , size ) ;
}
2009-03-22 22:36:54 +01:00
2009-05-07 04:11:35 +02:00
static BOOL check_file_data ( LPCSTR path , LPCSTR data )
{
return check_binary_file_data ( path , data , lstrlenA ( data ) ) ;
2009-03-22 22:36:54 +01:00
}
static void test_WritePrivateProfileString ( void )
{
BOOL ret ;
LPCSTR data ;
CHAR path [ MAX_PATH ] ;
CHAR temp [ MAX_PATH ] ;
2018-03-12 02:03:30 +01:00
HANDLE file ;
2009-03-22 22:36:54 +01:00
2009-06-03 21:56:10 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = WritePrivateProfileStringW ( NULL , NULL , NULL , NULL ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
/* Win9x/WinME needs (variable) timeouts between tests and even long timeouts don't
* guarantee a correct result .
* Win9x / WinMe also produces different ini files where there is always a newline before
* a section start ( except for the first one ) .
*/
win_skip ( " WritePrivateProfileString on Win9x/WinME is hard to test reliably \n " ) ;
return ;
}
2009-03-22 22:36:54 +01:00
GetTempPathA ( MAX_PATH , temp ) ;
GetTempFileNameA ( temp , " wine " , 0 , path ) ;
DeleteFileA ( path ) ;
/* path is not created yet */
/* NULL lpAppName */
SetLastError ( 0xdeadbeef ) ;
ret = WritePrivateProfileStringA ( NULL , " key " , " string " , path ) ;
ok ( ret = = FALSE , " Expected FALSE, got %d \n " , ret ) ;
2009-03-27 11:46:25 +01:00
ok ( GetLastError ( ) = = ERROR_FILE_NOT_FOUND | |
broken ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ) | | /* NT4 */
broken ( GetLastError ( ) = = 0xdeadbeef ) , /* Win9x and WinME */
2009-03-22 22:36:54 +01:00
" Expected ERROR_FILE_NOT_FOUND, got %d \n " , GetLastError ( ) ) ;
ok ( GetFileAttributesA ( path ) = = INVALID_FILE_ATTRIBUTES ,
" Expected path to not exist \n " ) ;
GetTempFileNameA ( temp , " wine " , 0 , path ) ;
/* NULL lpAppName, path exists */
data = " " ;
SetLastError ( 0xdeadbeef ) ;
ret = WritePrivateProfileStringA ( NULL , " key " , " string " , path ) ;
ok ( ret = = FALSE , " Expected FALSE, got %d \n " , ret ) ;
2009-03-27 11:46:25 +01:00
ok ( GetLastError ( ) = = ERROR_FILE_NOT_FOUND | |
broken ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ) | | /* NT4 */
broken ( GetLastError ( ) = = 0xdeadbeef ) , /* Win9x and WinME */
2009-03-22 22:37:31 +01:00
" Expected ERROR_FILE_NOT_FOUND, got %d \n " , GetLastError ( ) ) ;
2009-03-22 22:36:54 +01:00
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
DeleteFileA ( path ) ;
2009-03-25 17:14:25 +01:00
if ( 0 )
{
/* empty lpAppName, crashes on NT4 and higher */
2009-03-22 22:36:54 +01:00
data = " [] \r \n "
" key=string \r \n " ;
ret = WritePrivateProfileStringA ( " " , " key " , " string " , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
2009-03-22 22:37:54 +01:00
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
DeleteFileA ( path ) ;
2009-03-25 17:14:25 +01:00
}
2009-03-22 22:36:54 +01:00
/* NULL lpKeyName */
data = " " ;
ret = WritePrivateProfileStringA ( " App " , NULL , " string " , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
todo_wine
{
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
}
DeleteFileA ( path ) ;
2009-03-25 17:14:25 +01:00
if ( 0 )
{
/* empty lpKeyName, crashes on NT4 and higher */
2009-03-22 22:36:54 +01:00
data = " [App] \r \n "
" =string \r \n " ;
ret = WritePrivateProfileStringA ( " App " , " " , " string " , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
todo_wine
{
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
}
DeleteFileA ( path ) ;
2009-03-25 17:14:25 +01:00
}
2009-03-22 22:36:54 +01:00
/* NULL lpString */
data = " " ;
ret = WritePrivateProfileStringA ( " App " , " key " , NULL , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
todo_wine
{
2009-03-30 10:43:50 +02:00
ok ( check_file_data ( path , data ) | |
( broken ( GetFileAttributesA ( path ) = = INVALID_FILE_ATTRIBUTES ) ) , /* Win9x and WinME */
" File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
}
DeleteFileA ( path ) ;
/* empty lpString */
data = " [App] \r \n "
" key= \r \n " ;
ret = WritePrivateProfileStringA ( " App " , " key " , " " , path ) ;
2009-03-30 10:43:50 +02:00
ok ( ret = = TRUE | |
broken ( ! ret ) , /* Win9x and WinME */
" Expected TRUE, got %d \n " , ret ) ;
ok ( check_file_data ( path , data ) | |
( broken ( GetFileAttributesA ( path ) = = INVALID_FILE_ATTRIBUTES ) ) , /* Win9x and WinME */
" File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
DeleteFileA ( path ) ;
/* empty lpFileName */
SetLastError ( 0xdeadbeef ) ;
ret = WritePrivateProfileStringA ( " App " , " key " , " string " , " " ) ;
ok ( ret = = FALSE , " Expected FALSE, got %d \n " , ret ) ;
2009-03-30 10:43:50 +02:00
ok ( GetLastError ( ) = = ERROR_ACCESS_DENIED | |
broken ( GetLastError ( ) = = ERROR_PATH_NOT_FOUND ) , /* Win9x and WinME */
2009-03-22 22:36:54 +01:00
" Expected ERROR_ACCESS_DENIED, got %d \n " , GetLastError ( ) ) ;
2014-03-04 15:21:56 +01:00
/* Relative paths are relative to X:\\%WINDIR% */
2018-03-12 02:03:30 +01:00
GetWindowsDirectoryA ( path , MAX_PATH ) ;
strcat ( path , " \\ win1.tmp " ) ;
file = CreateFileA ( path , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_ACCESS_DENIED )
2014-03-04 15:21:56 +01:00
skip ( " Not allowed to create a file in the Windows directory \n " ) ;
else
{
2018-03-12 02:03:30 +01:00
CloseHandle ( file ) ;
2014-03-04 15:21:56 +01:00
DeleteFileA ( path ) ;
2009-03-22 22:36:54 +01:00
2014-03-04 15:21:56 +01:00
data = " [App] \r \n "
" key=string \r \n " ;
ret = WritePrivateProfileStringA ( " App " , " key " , " string " , " win1.tmp " ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d, le=%u \n " , ret , GetLastError ( ) ) ;
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
DeleteFileA ( path ) ;
}
2009-03-22 22:36:54 +01:00
GetTempPathA ( MAX_PATH , temp ) ;
GetTempFileNameA ( temp , " wine " , 0 , path ) ;
/* build up an INI file */
WritePrivateProfileStringA ( " App1 " , " key1 " , " string1 " , path ) ;
WritePrivateProfileStringA ( " App1 " , " key2 " , " string2 " , path ) ;
WritePrivateProfileStringA ( " App1 " , " key3 " , " string3 " , path ) ;
WritePrivateProfileStringA ( " App2 " , " key4 " , " string4 " , path ) ;
/* make an addition and verify the INI */
data = " [App1] \r \n "
" key1=string1 \r \n "
" key2=string2 \r \n "
" key3=string3 \r \n "
" [App2] \r \n "
" key4=string4 \r \n "
" [App3] \r \n "
" key5=string5 \r \n " ;
ret = WritePrivateProfileStringA ( " App3 " , " key5 " , " string5 " , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
2009-04-02 12:16:11 +02:00
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
/* lpString is NULL, key2 key is deleted */
data = " [App1] \r \n "
" key1=string1 \r \n "
" key3=string3 \r \n "
" [App2] \r \n "
" key4=string4 \r \n "
" [App3] \r \n "
" key5=string5 \r \n " ;
ret = WritePrivateProfileStringA ( " App1 " , " key2 " , NULL , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
2009-04-02 12:16:11 +02:00
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
/* try to delete key2 again */
data = " [App1] \r \n "
" key1=string1 \r \n "
" key3=string3 \r \n "
" [App2] \r \n "
" key4=string4 \r \n "
" [App3] \r \n "
" key5=string5 \r \n " ;
ret = WritePrivateProfileStringA ( " App1 " , " key2 " , NULL , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
2009-04-02 12:16:11 +02:00
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
/* lpKeyName is NULL, App1 section is deleted */
data = " [App2] \r \n "
" key4=string4 \r \n "
" [App3] \r \n "
" key5=string5 \r \n " ;
ret = WritePrivateProfileStringA ( " App1 " , NULL , " string1 " , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
2009-04-02 12:16:11 +02:00
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
/* lpString is not needed to delete a section */
data = " [App3] \r \n "
" key5=string5 \r \n " ;
ret = WritePrivateProfileStringA ( " App2 " , NULL , NULL , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
2009-04-02 12:16:11 +02:00
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
/* leave just the section */
data = " [App3] \r \n " ;
ret = WritePrivateProfileStringA ( " App3 " , " key5 " , NULL , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
2009-04-02 12:16:11 +02:00
ok ( check_file_data ( path , data ) , " File doesn't match \n " ) ;
2009-05-07 04:11:35 +02:00
DeleteFileA ( path ) ;
2009-03-22 22:36:54 +01:00
2009-05-07 04:11:35 +02:00
/* NULLs in file before first section. Should be preserved in output */
data = " Data \0 before \0 first \0 section " /* 31 bytes */
" \r \n [section1] \r \n " /* 14 bytes */
" key1=string1 \r \n " ; /* 14 bytes */
GetTempFileNameA ( temp , " wine " , 0 , path ) ;
create_test_file ( path , data , 31 ) ;
ret = WritePrivateProfileStringA ( " section1 " , " key1 " , " string1 " , path ) ;
ok ( ret = = TRUE , " Expected TRUE, got %d \n " , ret ) ;
todo_wine
ok ( check_binary_file_data ( path , data , 59 ) | |
broken ( check_binary_file_data ( path , /* Windows 9x */
" Data \0 before \0 first \0 section " /* 31 bytes */
" \r \n \r \n [section1] \r \n " /* 14 bytes */
" key1=string1 " /* 14 bytes */
, 59 ) ) , " File doesn't match \n " ) ;
2009-03-22 22:36:54 +01:00
DeleteFileA ( path ) ;
}
2003-03-04 05:34:57 +01:00
START_TEST ( profile )
{
test_profile_int ( ) ;
2005-03-02 11:08:18 +01:00
test_profile_string ( ) ;
2007-03-27 22:08:07 +02:00
test_profile_sections ( ) ;
2007-03-27 22:07:57 +02:00
test_profile_sections_names ( ) ;
2008-05-21 14:23:44 +02:00
test_profile_existing ( ) ;
2008-08-17 19:03:14 +02:00
test_profile_delete_on_close ( ) ;
2008-08-17 19:03:24 +02:00
test_profile_refresh ( ) ;
2018-01-27 21:11:10 +01:00
test_profile_directory_readonly ( ) ;
2008-09-21 16:49:16 +02:00
test_GetPrivateProfileString (
" [section1] \r \n "
" name1=val1 \r \n "
" name2= \" val2 \" \r \n "
" name3 \r \n "
" name4=a \r \n "
" [section2] \r \n " ,
" CR+LF " ) ;
test_GetPrivateProfileString (
" [section1] \r "
" name1=val1 \r "
" name2= \" val2 \" \r "
" name3 \r "
" name4=a \r "
" [section2] \r " ,
" CR only " ) ;
2009-03-22 22:36:54 +01:00
test_WritePrivateProfileString ( ) ;
2003-03-04 05:34:57 +01:00
}