Convert most of the file APIs to Unicode.
diff --git a/files/profile.c b/files/profile.c
index 8f342a2..2580cf4 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -40,10 +40,13 @@
#include "winbase.h"
#include "winnls.h"
#include "winerror.h"
+#include "ntddk.h"
#include "wine/winbase16.h"
#include "winreg.h"
+#include "drive.h"
#include "file.h"
#include "heap.h"
+#include "wine/unicode.h"
#include "wine/server.h"
#include "wine/library.h"
#include "wine/debug.h"
@@ -52,16 +55,16 @@
typedef struct tagPROFILEKEY
{
- char *value;
+ WCHAR *value;
struct tagPROFILEKEY *next;
- char name[1];
+ WCHAR name[1];
} PROFILEKEY;
typedef struct tagPROFILESECTION
{
struct tagPROFILEKEY *key;
struct tagPROFILESECTION *next;
- char name[1];
+ WCHAR name[1];
} PROFILESECTION;
@@ -69,9 +72,9 @@
{
BOOL changed;
PROFILESECTION *section;
- char *dos_name;
+ WCHAR *dos_name;
char *unix_name;
- char *filename;
+ WCHAR *filename;
time_t mtime;
} PROFILE;
@@ -109,23 +112,23 @@
* Copy the content of an entry into a buffer, removing quotes, and possibly
* translating environment variables.
*/
-static void PROFILE_CopyEntry( char *buffer, const char *value, int len,
- int handle_env )
+static void PROFILE_CopyEntry( LPWSTR buffer, LPCWSTR value, int len,
+ int handle_env, BOOL strip_quote )
{
- char quote = '\0';
- const char *p;
+ WCHAR quote = '\0';
+ LPCWSTR p;
if(!buffer) return;
- if ((*value == '\'') || (*value == '\"'))
+ if (strip_quote && ((*value == '\'') || (*value == '\"')))
{
- if (value[1] && (value[strlen(value)-1] == *value)) quote = *value++;
+ if (value[1] && (value[strlenW(value)-1] == *value)) quote = *value++;
}
if (!handle_env)
{
- lstrcpynA( buffer, value, len );
- if (quote && (len >= strlen(value))) buffer[strlen(buffer)-1] = '\0';
+ lstrcpynW( buffer, value, len );
+ if (quote && (len >= strlenW(value))) buffer[strlenW(buffer)-1] = '\0';
return;
}
@@ -133,18 +136,19 @@
{
if ((*p == '$') && (p[1] == '{'))
{
- char env_val[1024];
- const char *env_p;
- const char *p2 = strchr( p, '}' );
+ WCHAR env_val[1024];
+ LPCWSTR p2 = strchrW( p, '}' );
+ int copy_len;
if (!p2) continue; /* ignore it */
- lstrcpynA(env_val, p + 2, min( sizeof(env_val), (int)(p2-p)-1 ));
- if ((env_p = getenv( env_val )) != NULL)
+ copy_len = min( 1024, (int)(p2-p)-1 );
+ strncpyW(env_val, p + 2, copy_len );
+ env_val[copy_len - 1] = 0; /* ensure 0 termination */
+ *buffer = 0;
+ if (GetEnvironmentVariableW( env_val, buffer, len))
{
- int buffer_len;
- lstrcpynA( buffer, env_p, len );
- buffer_len = strlen( buffer );
- buffer += buffer_len;
- len -= buffer_len;
+ copy_len = strlenW( buffer );
+ buffer += copy_len;
+ len -= copy_len;
}
p = p2 + 1;
}
@@ -162,14 +166,24 @@
static void PROFILE_Save( FILE *file, PROFILESECTION *section )
{
PROFILEKEY *key;
+ char buffer[PROFILE_MAX_LINE_LEN];
for ( ; section; section = section->next)
{
- if (section->name[0]) fprintf( file, "\r\n[%s]\r\n", section->name );
+ if (section->name[0])
+ {
+ WideCharToMultiByte(CP_ACP, 0, section->name, -1, buffer, sizeof(buffer), NULL, NULL);
+ fprintf( file, "\r\n[%s]\r\n", buffer );
+ }
for (key = section->key; key; key = key->next)
{
- fprintf( file, "%s", key->name );
- if (key->value) fprintf( file, "=%s", key->value );
+ WideCharToMultiByte(CP_ACP, 0, key->name, -1, buffer, sizeof(buffer), NULL, NULL);
+ fprintf( file, "%s", buffer );
+ if (key->value)
+ {
+ WideCharToMultiByte(CP_ACP, 0, key->value, -1, buffer, sizeof(buffer), NULL, NULL);
+ fprintf( file, "=%s", buffer );
+ }
fprintf( file, "\r\n" );
}
}
@@ -217,7 +231,7 @@
{
char buffer[PROFILE_MAX_LINE_LEN];
char *p, *p2;
- int line = 0;
+ int line = 0, len;
PROFILESECTION *section, *first_section;
PROFILESECTION **next_section;
PROFILEKEY *key, *prev_key, **next_key;
@@ -247,9 +261,10 @@
{
*p2 = '\0';
p++;
- if (!(section = HeapAlloc( GetProcessHeap(), 0, sizeof(*section) + strlen(p) )))
+ len = strlen(p);
+ if (!(section = HeapAlloc( GetProcessHeap(), 0, sizeof(*section) + len * sizeof(WCHAR) )))
break;
- strcpy( section->name, p );
+ MultiByteToWideChar(CP_ACP, 0, p, -1, section->name, len + 1);
section->key = NULL;
section->next = NULL;
*next_section = section;
@@ -257,7 +272,7 @@
next_key = §ion->key;
prev_key = NULL;
- TRACE("New section: '%s'\n",section->name);
+ TRACE("New section: %s\n", debugstr_w(section->name));
continue;
}
@@ -276,12 +291,14 @@
if(*p || !prev_key || *prev_key->name)
{
- if (!(key = HeapAlloc( GetProcessHeap(), 0, sizeof(*key) + strlen(p) ))) break;
- strcpy( key->name, p );
+ len = strlen(p);
+ if (!(key = HeapAlloc( GetProcessHeap(), 0, sizeof(*key) + len * sizeof(WCHAR) ))) break;
+ MultiByteToWideChar(CP_ACP, 0, p, -1, key->name, len + 1);
if (p2)
{
- key->value = HeapAlloc( GetProcessHeap(), 0, strlen(p2)+1 );
- strcpy( key->value, p2 );
+ len = strlen(p2) + 1;
+ key->value = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ MultiByteToWideChar(CP_ACP, 0, p2, -1, key->value, len);
}
else key->value = NULL;
@@ -290,7 +307,8 @@
next_key = &key->next;
prev_key = key;
- TRACE("New key: name='%s', value='%s'\n",key->name,key->value?key->value:"(none)");
+ TRACE("New key: name=%s, value=%s\n",
+ debugstr_w(key->name), key->value ? debugstr_w(key->value) : "(none)");
}
}
return first_section;
@@ -380,11 +398,11 @@
*
* Delete a section from a profile tree.
*/
-static BOOL PROFILE_DeleteSection( PROFILESECTION **section, LPCSTR name )
+static BOOL PROFILE_DeleteSection( PROFILESECTION **section, LPCWSTR name )
{
while (*section)
{
- if ((*section)->name[0] && !strcasecmp( (*section)->name, name ))
+ if ((*section)->name[0] && !strcmpiW( (*section)->name, name ))
{
PROFILESECTION *to_del = *section;
*section = to_del->next;
@@ -404,16 +422,16 @@
* Delete a key from a profile tree.
*/
static BOOL PROFILE_DeleteKey( PROFILESECTION **section,
- LPCSTR section_name, LPCSTR key_name )
+ LPCWSTR section_name, LPCWSTR key_name )
{
while (*section)
{
- if ((*section)->name[0] && !strcasecmp( (*section)->name, section_name ))
+ if ((*section)->name[0] && !strcmpiW( (*section)->name, section_name ))
{
PROFILEKEY **key = &(*section)->key;
while (*key)
{
- if (!strcasecmp( (*key)->name, key_name ))
+ if (!strcmpiW( (*key)->name, key_name ))
{
PROFILEKEY *to_del = *key;
*key = to_del->next;
@@ -435,12 +453,12 @@
*
* Delete all keys from a profile tree.
*/
-void PROFILE_DeleteAllKeys( LPCSTR section_name)
+void PROFILE_DeleteAllKeys( LPCWSTR section_name)
{
PROFILESECTION **section= &CurProfile->section;
while (*section)
{
- if ((*section)->name[0] && !strcasecmp( (*section)->name, section_name ))
+ if ((*section)->name[0] && !strcmpiW( (*section)->name, section_name ))
{
PROFILEKEY **key = &(*section)->key;
while (*key)
@@ -462,26 +480,26 @@
*
* Find a key in a profile tree, optionally creating it.
*/
-static PROFILEKEY *PROFILE_Find( PROFILESECTION **section, const char *section_name,
- const char *key_name, BOOL create, BOOL create_always )
+static PROFILEKEY *PROFILE_Find( PROFILESECTION **section, LPCWSTR section_name,
+ LPCWSTR key_name, BOOL create, BOOL create_always )
{
- const char *p;
+ LPCWSTR p;
int seclen, keylen;
while (PROFILE_isspace(*section_name)) section_name++;
- p = section_name + strlen(section_name) - 1;
+ p = section_name + strlenW(section_name) - 1;
while ((p > section_name) && PROFILE_isspace(*p)) p--;
seclen = p - section_name + 1;
while (PROFILE_isspace(*key_name)) key_name++;
- p = key_name + strlen(key_name) - 1;
+ p = key_name + strlenW(key_name) - 1;
while ((p > key_name) && PROFILE_isspace(*p)) p--;
keylen = p - key_name + 1;
while (*section)
{
if ( ((*section)->name[0])
- && (!(strncasecmp( (*section)->name, section_name, seclen )))
+ && (!(strncmpiW( (*section)->name, section_name, seclen )))
&& (((*section)->name)[seclen] == '\0') )
{
PROFILEKEY **key = &(*section)->key;
@@ -494,16 +512,16 @@
*/
if(!create_always)
{
- if ( (!(strncasecmp( (*key)->name, key_name, keylen )))
+ if ( (!(strncmpiW( (*key)->name, key_name, keylen )))
&& (((*key)->name)[keylen] == '\0') )
return *key;
}
key = &(*key)->next;
}
if (!create) return NULL;
- if (!(*key = HeapAlloc( GetProcessHeap(), 0, sizeof(PROFILEKEY) + strlen(key_name) )))
+ if (!(*key = HeapAlloc( GetProcessHeap(), 0, sizeof(PROFILEKEY) + strlenW(key_name) * sizeof(WCHAR) )))
return NULL;
- strcpy( (*key)->name, key_name );
+ strcpyW( (*key)->name, key_name );
(*key)->value = NULL;
(*key)->next = NULL;
return *key;
@@ -511,17 +529,17 @@
section = &(*section)->next;
}
if (!create) return NULL;
- *section = HeapAlloc( GetProcessHeap(), 0, sizeof(PROFILESECTION) + strlen(section_name) );
+ *section = HeapAlloc( GetProcessHeap(), 0, sizeof(PROFILESECTION) + strlenW(section_name) * sizeof(WCHAR) );
if(*section == NULL) return NULL;
- strcpy( (*section)->name, section_name );
+ strcpyW( (*section)->name, section_name );
(*section)->next = NULL;
if (!((*section)->key = HeapAlloc( GetProcessHeap(), 0,
- sizeof(PROFILEKEY) + strlen(key_name) )))
+ sizeof(PROFILEKEY) + strlenW(key_name) * sizeof(WCHAR) )))
{
HeapFree(GetProcessHeap(), 0, *section);
return NULL;
}
- strcpy( (*section)->key->name, key_name );
+ strcpyW( (*section)->key->name, key_name );
(*section)->key->value = NULL;
(*section)->key->next = NULL;
return (*section)->key;
@@ -549,24 +567,28 @@
if (!CurProfile->changed || !CurProfile->dos_name) return TRUE;
if (!(unix_name = CurProfile->unix_name) || !(file = fopen(unix_name, "w")))
{
+ int drive = toupperW(CurProfile->dos_name[0]) - 'A';
+ WCHAR *name;
/* Try to create it in $HOME/.wine */
/* FIXME: this will need a more general solution */
strcpy( buffer, wine_get_config_dir() );
p = buffer + strlen(buffer);
*p++ = '/';
- strcpy( p, strrchr( CurProfile->dos_name, '\\' ) + 1 );
- _strlwr( p );
+ *p = 0; /* make strlen() below happy */
+ name = strrchrW( CurProfile->dos_name, '\\' ) + 1;
+ WideCharToMultiByte(DRIVE_GetCodepage(drive), 0, name, -1,
+ p, sizeof(buffer) - strlen(buffer), NULL, NULL);
file = fopen( buffer, "w" );
unix_name = buffer;
}
if (!file)
{
- WARN("could not save profile file %s\n", CurProfile->dos_name);
+ WARN("could not save profile file %s\n", debugstr_w(CurProfile->dos_name));
return FALSE;
}
- TRACE("Saving '%s' into '%s'\n", CurProfile->dos_name, unix_name );
+ TRACE("Saving %s into '%s'\n", debugstr_w(CurProfile->dos_name), unix_name );
PROFILE_Save( file, CurProfile->section );
fclose( file );
CurProfile->changed = FALSE;
@@ -602,11 +624,13 @@
*
* Open a profile file, checking the cached file first.
*/
-static BOOL PROFILE_Open( LPCSTR filename )
+static BOOL PROFILE_Open( LPCWSTR filename )
{
DOS_FULL_NAME full_name;
char buffer[MAX_PATHNAME_LEN];
- char *newdos_name, *p;
+ WCHAR *newdos_name;
+ WCHAR *name;
+ char *p;
FILE *file = NULL;
int i,j;
struct stat buf;
@@ -629,23 +653,26 @@
/* Check for a match */
- if (strchr( filename, '/' ) || strchr( filename, '\\' ) ||
- strchr( filename, ':' ))
+ if (strchrW( filename, '/' ) || strchrW( filename, '\\' ) ||
+ strchrW( filename, ':' ))
{
if (!DOSFS_GetFullName( filename, FALSE, &full_name )) return FALSE;
}
else
{
- GetWindowsDirectoryA( buffer, sizeof(buffer) );
- strcat( buffer, "\\" );
- strcat( buffer, filename );
- if (!DOSFS_GetFullName( buffer, FALSE, &full_name )) return FALSE;
+ static const WCHAR bkslashW[] = {'\\',0};
+ WCHAR windirW[MAX_PATH];
+
+ GetWindowsDirectoryW( windirW, MAX_PATH );
+ strcatW( windirW, bkslashW );
+ strcatW( windirW, filename );
+ if (!DOSFS_GetFullName( windirW, FALSE, &full_name )) return FALSE;
}
for(i=0;i<N_CACHED_PROFILES;i++)
{
- if ((MRUProfile[i]->filename && !strcmp( filename, MRUProfile[i]->filename )) ||
- (MRUProfile[i]->dos_name && !strcmp( full_name.short_name, MRUProfile[i]->dos_name )))
+ if ((MRUProfile[i]->filename && !strcmpW( filename, MRUProfile[i]->filename )) ||
+ (MRUProfile[i]->dos_name && !strcmpW( full_name.short_name, MRUProfile[i]->dos_name )))
{
if(i)
{
@@ -657,10 +684,10 @@
}
if(!stat(CurProfile->unix_name,&buf) && CurProfile->mtime==buf.st_mtime)
TRACE("(%s): already opened (mru=%d)\n",
- filename, i );
+ debugstr_w(filename), i );
else
TRACE("(%s): already opened, needs refreshing (mru=%d)\n",
- filename, i );
+ debugstr_w(filename), i );
return TRUE;
}
}
@@ -679,11 +706,11 @@
if(CurProfile->filename) PROFILE_ReleaseFile();
/* OK, now that CurProfile is definitely free we assign it our new file */
- newdos_name = HeapAlloc( GetProcessHeap(), 0, strlen(full_name.short_name)+1 );
- strcpy( newdos_name, full_name.short_name );
+ newdos_name = HeapAlloc( GetProcessHeap(), 0, (strlenW(full_name.short_name)+1) * sizeof(WCHAR) );
+ strcpyW( newdos_name, full_name.short_name );
CurProfile->dos_name = newdos_name;
- CurProfile->filename = HeapAlloc( GetProcessHeap(), 0, strlen(filename)+1 );
- strcpy( CurProfile->filename, filename );
+ CurProfile->filename = HeapAlloc( GetProcessHeap(), 0, (strlenW(filename)+1) * sizeof(WCHAR) );
+ strcpyW( CurProfile->filename, filename );
/* Try to open the profile file, first in $HOME/.wine */
@@ -691,23 +718,23 @@
strcpy( buffer, wine_get_config_dir() );
p = buffer + strlen(buffer);
*p++ = '/';
- strcpy( p, strrchr( newdos_name, '\\' ) + 1 );
- _strlwr( p );
+ *p = 0; /* make strlen() below happy */
+ name = strrchrW( newdos_name, '\\' ) + 1;
+ WideCharToMultiByte(DRIVE_GetCodepage(full_name.drive), 0, name, -1,
+ p, sizeof(buffer) - strlen(buffer), NULL, NULL);
if ((file = fopen( buffer, "r" )))
{
- TRACE("(%s): found it in %s\n",
- filename, buffer );
+ TRACE("(%s): found it in %s\n", debugstr_w(filename), buffer );
CurProfile->unix_name = HeapAlloc( GetProcessHeap(), 0, strlen(buffer)+1 );
strcpy( CurProfile->unix_name, buffer );
}
-
- if (!file)
+ else
{
CurProfile->unix_name = HeapAlloc( GetProcessHeap(), 0, strlen(full_name.long_name)+1 );
strcpy( CurProfile->unix_name, full_name.long_name );
if ((file = fopen( full_name.long_name, "r" )))
TRACE("(%s): found it in %s\n",
- filename, full_name.long_name );
+ debugstr_w(filename), full_name.long_name );
}
if (file)
@@ -720,7 +747,7 @@
else
{
/* Does not exist yet, we will create it in PROFILE_FlushFile */
- WARN("profile file %s not found\n", newdos_name );
+ WARN("profile file %s not found\n", debugstr_w(newdos_name) );
}
return TRUE;
}
@@ -732,17 +759,19 @@
* Returns all keys of a section.
* If return_values is TRUE, also include the corresponding values.
*/
-static INT PROFILE_GetSection( PROFILESECTION *section, LPCSTR section_name,
- LPSTR buffer, UINT len, BOOL handle_env,
+static INT PROFILE_GetSection( PROFILESECTION *section, LPCWSTR section_name,
+ LPWSTR buffer, UINT len, BOOL handle_env,
BOOL return_values )
{
PROFILEKEY *key;
if(!buffer) return 0;
+ TRACE("%s,%p,%u\n", debugstr_w(section_name), buffer, len);
+
while (section)
{
- if (section->name[0] && !strcasecmp( section->name, section_name ))
+ if (section->name[0] && !strcmpiW( section->name, section_name ))
{
UINT oldlen = len;
for (key = section->key; key; key = key->next)
@@ -750,17 +779,17 @@
if (len <= 2) break;
if (!*key->name) continue; /* Skip empty lines */
if (IS_ENTRY_COMMENT(key->name)) continue; /* Skip comments */
- PROFILE_CopyEntry( buffer, key->name, len - 1, handle_env );
- len -= strlen(buffer) + 1;
- buffer += strlen(buffer) + 1;
+ PROFILE_CopyEntry( buffer, key->name, len - 1, handle_env, 0 );
+ len -= strlenW(buffer) + 1;
+ buffer += strlenW(buffer) + 1;
if (len < 2)
break;
if (return_values && key->value) {
buffer[-1] = '=';
PROFILE_CopyEntry ( buffer,
- key->value, len - 1, handle_env );
- len -= strlen(buffer) + 1;
- buffer += strlen(buffer) + 1;
+ key->value, len - 1, handle_env, 0 );
+ len -= strlenW(buffer) + 1;
+ buffer += strlenW(buffer) + 1;
}
}
*buffer = '\0';
@@ -783,9 +812,9 @@
}
/* See GetPrivateProfileSectionNamesA for documentation */
-static INT PROFILE_GetSectionNames( LPSTR buffer, UINT len )
+static INT PROFILE_GetSectionNames( LPWSTR buffer, UINT len )
{
- LPSTR buf;
+ LPWSTR buf;
UINT f,l;
PROFILESECTION *section;
@@ -801,17 +830,17 @@
section = CurProfile->section;
while ((section!=NULL)) {
if (section->name[0]) {
- l = strlen(section->name)+1;
+ l = strlenW(section->name)+1;
if (l > f) {
if (f>0) {
- strncpy(buf, section->name, f-1);
+ strncpyW(buf, section->name, f-1);
buf += f-1;
*buf++='\0';
}
*buf='\0';
return len-2;
}
- strcpy(buf, section->name);
+ strcpyW(buf, section->name);
buf += l;
f -= l;
}
@@ -844,25 +873,29 @@
*
*
*/
-static INT PROFILE_GetString( LPCSTR section, LPCSTR key_name,
- LPCSTR def_val, LPSTR buffer, UINT len )
+static INT PROFILE_GetString( LPCWSTR section, LPCWSTR key_name,
+ LPCWSTR def_val, LPWSTR buffer, UINT len )
{
PROFILEKEY *key = NULL;
+ static const WCHAR empty_strW[] = { 0 };
if(!buffer) return 0;
- if (!def_val) def_val = "";
+ if (!def_val) def_val = empty_strW;
if (key_name)
{
if (!key_name[0])
+ {
/* Win95 returns 0 on keyname "". Tested with Likse32 bon 000227 */
return 0;
+ }
key = PROFILE_Find( &CurProfile->section, section, key_name, FALSE, FALSE);
PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val,
- len, FALSE );
- TRACE("('%s','%s','%s'): returning '%s'\n",
- section, key_name, def_val, buffer );
- return strlen( buffer );
+ len, FALSE, TRUE );
+ TRACE("(%s,%s,%s): returning %s\n",
+ debugstr_w(section), debugstr_w(key_name),
+ debugstr_w(def_val), debugstr_w(buffer) );
+ return strlenW( buffer );
}
/* no "else" here ! */
if (section && section[0])
@@ -870,8 +903,8 @@
INT ret = PROFILE_GetSection(CurProfile->section, section, buffer, len, FALSE, FALSE);
if (!buffer[0]) /* no luck -> def_val */
{
- PROFILE_CopyEntry(buffer, def_val, len, FALSE);
- ret = strlen(buffer);
+ PROFILE_CopyEntry(buffer, def_val, len, FALSE, TRUE);
+ ret = strlenW(buffer);
}
return ret;
}
@@ -885,12 +918,12 @@
*
* Set a profile string.
*/
-static BOOL PROFILE_SetString( LPCSTR section_name, LPCSTR key_name,
- LPCSTR value, BOOL create_always )
+static BOOL PROFILE_SetString( LPCWSTR section_name, LPCWSTR key_name,
+ LPCWSTR value, BOOL create_always )
{
if (!key_name) /* Delete a whole section */
{
- TRACE("('%s')\n", section_name);
+ TRACE("(%s)\n", debugstr_w(section_name));
CurProfile->changed |= PROFILE_DeleteSection( &CurProfile->section,
section_name );
return TRUE; /* Even if PROFILE_DeleteSection() has failed,
@@ -898,8 +931,7 @@
}
else if (!value) /* Delete a key */
{
- TRACE("('%s','%s')\n",
- section_name, key_name );
+ TRACE("(%s,%s)\n", debugstr_w(section_name), debugstr_w(key_name) );
CurProfile->changed |= PROFILE_DeleteKey( &CurProfile->section,
section_name, key_name );
return TRUE; /* same error handling as above */
@@ -908,8 +940,8 @@
{
PROFILEKEY *key = PROFILE_Find(&CurProfile->section, section_name,
key_name, TRUE, create_always );
- TRACE("('%s','%s','%s'): \n",
- section_name, key_name, value );
+ TRACE("(%s,%s,%s):\n",
+ debugstr_w(section_name), debugstr_w(key_name), debugstr_w(value) );
if (!key) return FALSE;
if (key->value)
{
@@ -917,17 +949,17 @@
* friends too, they should not happen here anyway. */
while (PROFILE_isspace(*value)) value++;
- if (!strcmp( key->value, value ))
+ if (!strcmpW( key->value, value ))
{
TRACE(" no change needed\n" );
return TRUE; /* No change needed */
}
- TRACE(" replacing '%s'\n", key->value );
+ TRACE(" replacing %s\n", debugstr_w(key->value) );
HeapFree( GetProcessHeap(), 0, key->value );
}
else TRACE(" creating key\n" );
- key->value = HeapAlloc( GetProcessHeap(), 0, strlen(value)+1 );
- strcpy( key->value, value );
+ key->value = HeapAlloc( GetProcessHeap(), 0, (strlenW(value)+1) * sizeof(WCHAR) );
+ strcpyW( key->value, value );
CurProfile->changed = TRUE;
}
return TRUE;
@@ -939,32 +971,31 @@
*
* Get a config string from the wine.ini file.
*/
-int PROFILE_GetWineIniString( const char *section, const char *key_name,
- const char *def, char *buffer, int len )
+int PROFILE_GetWineIniString( LPCWSTR section, LPCWSTR key_name,
+ LPCWSTR def, LPWSTR buffer, int len )
{
- char tmp[PROFILE_MAX_LINE_LEN];
+ WCHAR tmp[PROFILE_MAX_LINE_LEN];
HKEY hkey;
DWORD err;
- if (!(err = RegOpenKeyA( wine_profile_key, section, &hkey )))
+ if (!(err = RegOpenKeyW( wine_profile_key, section, &hkey )))
{
DWORD type;
DWORD count = sizeof(tmp);
- err = RegQueryValueExA( hkey, key_name, 0, &type, tmp, &count );
+ err = RegQueryValueExW( hkey, key_name, 0, &type, (LPBYTE)tmp, &count );
RegCloseKey( hkey );
}
- PROFILE_CopyEntry( buffer, err ? def : tmp, len, TRUE );
- TRACE( "('%s','%s','%s'): returning '%s'\n", section, key_name, def, buffer );
- return strlen(buffer);
+
+ PROFILE_CopyEntry( buffer, err ? def : tmp, len, TRUE, TRUE );
+ TRACE( "(%s,%s,%s): returning %s\n", debugstr_w(section),
+ debugstr_w(key_name), debugstr_w(def), debugstr_w(buffer) );
+ return strlenW(buffer);
}
/******************************************************************************
*
- * int PROFILE_GetWineIniBool(
- * char const *section,
- * char const *key_name,
- * int def )
+ * PROFILE_GetWineIniBool
*
* Reads a boolean value from the wine.ini file. This function attempts to
* be user-friendly by accepting 'n', 'N' (no), 'f', 'F' (false), or '0'
@@ -975,15 +1006,13 @@
* for existence by setting def to something other than 0 or 1 and
* examining the return value.
*/
-int PROFILE_GetWineIniBool(
- char const *section,
- char const *key_name,
- int def )
+int PROFILE_GetWineIniBool( LPCWSTR section, LPCWSTR key_name, int def )
{
- char key_value[2];
+ static const WCHAR def_valueW[] = {'~',0};
+ WCHAR key_value[2];
int retval;
- PROFILE_GetWineIniString(section, key_name, "~", key_value, 2);
+ PROFILE_GetWineIniString(section, key_name, def_valueW, key_value, 2);
switch(key_value[0]) {
case 'n':
@@ -1006,7 +1035,7 @@
retval = def;
}
- TRACE("(\"%s\", \"%s\", %s), [%c], ret %s.\n", section, key_name,
+ TRACE("(%s, %s, %s), [%c], ret %s\n", debugstr_w(section), debugstr_w(key_name),
def ? "TRUE" : "FALSE", key_value[0],
retval ? "TRUE" : "FALSE");
@@ -1133,21 +1162,24 @@
* - of Keys in a Section if 'entry' is NULL
* (see MSDN doc for GetPrivateProfileString)
*/
-static int PROFILE_GetPrivateProfileString( LPCSTR section, LPCSTR entry,
- LPCSTR def_val, LPSTR buffer,
- UINT16 len, LPCSTR filename,
+static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
+ LPCWSTR def_val, LPWSTR buffer,
+ UINT len, LPCWSTR filename,
BOOL allow_section_name_copy )
{
int ret;
- LPSTR pDefVal = NULL;
+ LPWSTR pDefVal = NULL;
if (!filename)
- filename = "win.ini";
+ filename = wininiW;
+
+ TRACE("%s,%s,%s,%p,%u,%s\n", debugstr_w(section), debugstr_w(entry),
+ debugstr_w(def_val), buffer, len, debugstr_w(filename));
/* strip any trailing ' ' of def_val. */
if (def_val)
{
- LPSTR p = (LPSTR)&def_val[strlen(def_val)]; /* even "" works ! */
+ LPCWSTR p = &def_val[strlenW(def_val)]; /* even "" works ! */
while (p > def_val)
{
@@ -1157,14 +1189,14 @@
}
if (*p == ' ') /* ouch, contained trailing ' ' */
{
- int len = (int)p - (int)def_val;
- pDefVal = HeapAlloc(GetProcessHeap(), 0, len + 1);
- strncpy(pDefVal, def_val, len);
+ int len = (int)(p - def_val);
+ pDefVal = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
+ strncpyW(pDefVal, def_val, len);
pDefVal[len] = '\0';
}
}
if (!pDefVal)
- pDefVal = (LPSTR)def_val;
+ pDefVal = (LPWSTR)def_val;
EnterCriticalSection( &PROFILE_CritSect );
@@ -1175,8 +1207,8 @@
/* PROFILE_GetString already handles the 'entry == NULL' case */
ret = PROFILE_GetString( section, entry, pDefVal, buffer, len );
} else {
- lstrcpynA( buffer, pDefVal, len );
- ret = strlen( buffer );
+ lstrcpynW( buffer, pDefVal, len );
+ ret = strlenW( buffer );
}
LeaveCriticalSection( &PROFILE_CritSect );
@@ -1184,6 +1216,8 @@
if (pDefVal != def_val) /* allocated */
HeapFree(GetProcessHeap(), 0, pDefVal);
+ TRACE("returning %s, %d\n", debugstr_w(buffer), ret);
+
return ret;
}
@@ -1194,8 +1228,41 @@
LPCSTR def_val, LPSTR buffer,
UINT16 len, LPCSTR filename )
{
- return PROFILE_GetPrivateProfileString( section, entry, def_val,
- buffer, len, filename, FALSE );
+ UNICODE_STRING sectionW, entryW, def_valW, filenameW;
+ LPWSTR bufferW;
+ INT16 retW, ret = 0;
+
+ bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
+ if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
+ else sectionW.Buffer = NULL;
+ if (entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
+ else entryW.Buffer = NULL;
+ if (def_val) RtlCreateUnicodeStringFromAsciiz(&def_valW, def_val);
+ else def_valW.Buffer = NULL;
+ if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
+ else filenameW.Buffer = NULL;
+
+ retW = PROFILE_GetPrivateProfileString( sectionW.Buffer, entryW.Buffer,
+ def_valW.Buffer, bufferW, len,
+ filenameW.Buffer, FALSE );
+ if (len)
+ {
+ ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW + 1, buffer, len, NULL, NULL);
+ if (!ret)
+ {
+ ret = len - 1;
+ buffer[ret] = 0;
+ }
+ else
+ ret--; /* strip terminating 0 */
+ }
+
+ RtlFreeUnicodeString(§ionW);
+ RtlFreeUnicodeString(&entryW);
+ RtlFreeUnicodeString(&def_valW);
+ RtlFreeUnicodeString(&filenameW);
+ if (bufferW) HeapFree(GetProcessHeap(), 0, bufferW);
+ return ret;
}
/***********************************************************************
@@ -1205,8 +1272,41 @@
LPCSTR def_val, LPSTR buffer,
UINT len, LPCSTR filename )
{
- return PROFILE_GetPrivateProfileString( section, entry, def_val,
- buffer, len, filename, TRUE );
+ UNICODE_STRING sectionW, entryW, def_valW, filenameW;
+ LPWSTR bufferW;
+ INT retW, ret = 0;
+
+ bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
+ if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
+ else sectionW.Buffer = NULL;
+ if (entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
+ else entryW.Buffer = NULL;
+ if (def_val) RtlCreateUnicodeStringFromAsciiz(&def_valW, def_val);
+ else def_valW.Buffer = NULL;
+ if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
+ else filenameW.Buffer = NULL;
+
+ retW = GetPrivateProfileStringW( sectionW.Buffer, entryW.Buffer,
+ def_valW.Buffer, bufferW, len,
+ filenameW.Buffer);
+ if (len)
+ {
+ ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW + 1, buffer, len, NULL, NULL);
+ if (!ret)
+ {
+ ret = len - 1;
+ buffer[ret] = 0;
+ }
+ else
+ ret--; /* strip terminating 0 */
+ }
+
+ RtlFreeUnicodeString(§ionW);
+ RtlFreeUnicodeString(&entryW);
+ RtlFreeUnicodeString(&def_valW);
+ RtlFreeUnicodeString(&filenameW);
+ if (bufferW) HeapFree(GetProcessHeap(), 0, bufferW);
+ return ret;
}
/***********************************************************************
@@ -1216,21 +1316,8 @@
LPCWSTR def_val, LPWSTR buffer,
UINT len, LPCWSTR filename )
{
- LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
- LPSTR entryA = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
- LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
- LPSTR def_valA = HEAP_strdupWtoA( GetProcessHeap(), 0, def_val );
- LPSTR bufferA = HeapAlloc( GetProcessHeap(), 0, len );
- INT ret = GetPrivateProfileStringA( sectionA, entryA, def_valA,
- bufferA, len, filenameA );
- if (len > 0 && !MultiByteToWideChar( CP_ACP, 0, bufferA, -1, buffer, len ))
- buffer[len-1] = 0;
- HeapFree( GetProcessHeap(), 0, sectionA );
- HeapFree( GetProcessHeap(), 0, entryA );
- HeapFree( GetProcessHeap(), 0, filenameA );
- HeapFree( GetProcessHeap(), 0, def_valA );
- HeapFree( GetProcessHeap(), 0, bufferA);
- return ret;
+ return PROFILE_GetPrivateProfileString( section, entry, def_val,
+ buffer, len, filename, TRUE );
}
/***********************************************************************
@@ -1239,8 +1326,8 @@
INT16 WINAPI GetProfileString16( LPCSTR section, LPCSTR entry, LPCSTR def_val,
LPSTR buffer, UINT16 len )
{
- return PROFILE_GetPrivateProfileString( section, entry, def_val,
- buffer, len, "win.ini", FALSE );
+ return GetPrivateProfileString16( section, entry, def_val,
+ buffer, len, "win.ini" );
}
/***********************************************************************
@@ -1249,8 +1336,8 @@
INT WINAPI GetProfileStringA( LPCSTR section, LPCSTR entry, LPCSTR def_val,
LPSTR buffer, UINT len )
{
- return PROFILE_GetPrivateProfileString( section, entry, def_val,
- buffer, len, "win.ini", TRUE );
+ return GetPrivateProfileStringA( section, entry, def_val,
+ buffer, len, "win.ini" );
}
/***********************************************************************
@@ -1312,8 +1399,8 @@
char buffer[20];
long result;
- if (!PROFILE_GetPrivateProfileString( section, entry, "",
- buffer, sizeof(buffer), filename, FALSE ))
+ if (!GetPrivateProfileStringA( section, entry, "",
+ buffer, sizeof(buffer), filename ))
return def_val;
/* FIXME: if entry can be found but it's empty, then Win16 is
* supposed to return 0 instead of def_val ! Difficult/problematic
@@ -1331,6 +1418,8 @@
/***********************************************************************
* GetPrivateProfileIntW (KERNEL32.@)
+ *
+ * FIXME: rewrite using unicode
*/
UINT WINAPI GetPrivateProfileIntW( LPCWSTR section, LPCWSTR entry,
INT def_val, LPCWSTR filename )
@@ -1355,10 +1444,10 @@
}
/***********************************************************************
- * GetPrivateProfileSectionA (KERNEL32.@)
+ * GetPrivateProfileSectionW (KERNEL32.@)
*/
-INT WINAPI GetPrivateProfileSectionA( LPCSTR section, LPSTR buffer,
- DWORD len, LPCSTR filename )
+INT WINAPI GetPrivateProfileSectionW( LPCWSTR section, LPWSTR buffer,
+ DWORD len, LPCWSTR filename )
{
int ret = 0;
@@ -1374,22 +1463,43 @@
}
/***********************************************************************
- * GetPrivateProfileSectionW (KERNEL32.@)
+ * GetPrivateProfileSectionA (KERNEL32.@)
*/
-
-INT WINAPI GetPrivateProfileSectionW (LPCWSTR section, LPWSTR buffer,
- DWORD len, LPCWSTR filename )
-
+INT WINAPI GetPrivateProfileSectionA( LPCSTR section, LPSTR buffer,
+ DWORD len, LPCSTR filename )
{
- LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
- LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
- LPSTR bufferA = HeapAlloc( GetProcessHeap(), 0, len );
- INT ret = GetPrivateProfileSectionA( sectionA, bufferA, len,
- filenameA );
- MultiByteToWideChar(CP_ACP,0,bufferA,ret,buffer,len);
- HeapFree( GetProcessHeap(), 0, sectionA );
- HeapFree( GetProcessHeap(), 0, filenameA );
- HeapFree( GetProcessHeap(), 0, bufferA);
+ UNICODE_STRING sectionW, filenameW;
+ LPWSTR bufferW;
+ INT retW, ret = 0;
+
+ bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
+ if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
+ else sectionW.Buffer = NULL;
+ if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
+ else filenameW.Buffer = NULL;
+
+ retW = GetPrivateProfileSectionW(sectionW.Buffer, bufferW, len, filenameW.Buffer);
+ if (len > 2)
+ {
+ ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW + 2, buffer, len, NULL, NULL);
+ if (ret > 2)
+ ret -= 2;
+ else
+ {
+ ret = 0;
+ buffer[len-2] = 0;
+ buffer[len-1] = 0;
+ }
+ }
+ else
+ {
+ buffer[0] = 0;
+ buffer[1] = 0;
+ }
+
+ RtlFreeUnicodeString(§ionW);
+ RtlFreeUnicodeString(&filenameW);
+ if (bufferW) HeapFree(GetProcessHeap(), 0, bufferW);
return ret;
}
@@ -1428,10 +1538,10 @@
}
/***********************************************************************
- * WritePrivateProfileStringA (KERNEL32.@)
+ * WritePrivateProfileStringW (KERNEL32.@)
*/
-BOOL WINAPI WritePrivateProfileStringA( LPCSTR section, LPCSTR entry,
- LPCSTR string, LPCSTR filename )
+BOOL WINAPI WritePrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
+ LPCWSTR string, LPCWSTR filename )
{
BOOL ret = FALSE;
@@ -1440,12 +1550,17 @@
if (PROFILE_Open( filename ))
{
if (!section && !entry && !string) /* documented "file flush" case */
+ {
+ PROFILE_FlushFile();
PROFILE_ReleaseFile(); /* always return FALSE in this case */
+ }
else {
if (!section) {
- FIXME("(NULL?,%s,%s,%s)? \n",entry,string,filename);
+ FIXME("(NULL?,%s,%s,%s)?\n",
+ debugstr_w(entry), debugstr_w(string), debugstr_w(filename));
} else {
ret = PROFILE_SetString( section, entry, string, FALSE);
+ PROFILE_FlushFile();
}
}
}
@@ -1455,22 +1570,30 @@
}
/***********************************************************************
- * WritePrivateProfileStringW (KERNEL32.@)
+ * WritePrivateProfileStringA (KERNEL32.@)
*/
-BOOL WINAPI WritePrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
- LPCWSTR string, LPCWSTR filename )
+BOOL WINAPI WritePrivateProfileStringA( LPCSTR section, LPCSTR entry,
+ LPCSTR string, LPCSTR filename )
{
- LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
- LPSTR entryA = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
- LPSTR stringA = HEAP_strdupWtoA( GetProcessHeap(), 0, string );
- LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
- BOOL res = WritePrivateProfileStringA( sectionA, entryA,
- stringA, filenameA );
- HeapFree( GetProcessHeap(), 0, sectionA );
- HeapFree( GetProcessHeap(), 0, entryA );
- HeapFree( GetProcessHeap(), 0, stringA );
- HeapFree( GetProcessHeap(), 0, filenameA );
- return res;
+ UNICODE_STRING sectionW, entryW, stringW, filenameW;
+ BOOL ret;
+
+ if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
+ else sectionW.Buffer = NULL;
+ if (entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
+ else entryW.Buffer = NULL;
+ if (string) RtlCreateUnicodeStringFromAsciiz(&stringW, string);
+ else stringW.Buffer = NULL;
+ if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
+ else filenameW.Buffer = NULL;
+
+ ret = WritePrivateProfileStringW(sectionW.Buffer, entryW.Buffer,
+ stringW.Buffer, filenameW.Buffer);
+ RtlFreeUnicodeString(§ionW);
+ RtlFreeUnicodeString(&entryW);
+ RtlFreeUnicodeString(&stringW);
+ RtlFreeUnicodeString(&filenameW);
+ return ret;
}
/***********************************************************************
@@ -1483,34 +1606,36 @@
}
/***********************************************************************
- * WritePrivateProfileSectionA (KERNEL32.@)
+ * WritePrivateProfileSectionW (KERNEL32.@)
*/
-BOOL WINAPI WritePrivateProfileSectionA( LPCSTR section,
- LPCSTR string, LPCSTR filename )
+BOOL WINAPI WritePrivateProfileSectionW( LPCWSTR section,
+ LPCWSTR string, LPCWSTR filename )
{
BOOL ret = FALSE;
- LPSTR p ;
+ LPWSTR p;
EnterCriticalSection( &PROFILE_CritSect );
if (PROFILE_Open( filename )) {
if (!section && !string)
PROFILE_ReleaseFile(); /* always return FALSE in this case */
- else if (!string) /* delete the named section*/
+ else if (!string) {/* delete the named section*/
ret = PROFILE_SetString(section,NULL,NULL, FALSE);
- else {
+ PROFILE_FlushFile();
+ } else {
PROFILE_DeleteAllKeys(section);
ret = TRUE;
while(*string) {
- LPSTR buf = HeapAlloc( GetProcessHeap(), 0, strlen(string)+1 );
- strcpy( buf, string );
- if((p=strchr( buf, '='))){
+ LPWSTR buf = HeapAlloc( GetProcessHeap(), 0, (strlenW(string)+1) * sizeof(WCHAR) );
+ strcpyW( buf, string );
+ if((p = strchrW( buf, '='))) {
*p='\0';
ret = PROFILE_SetString( section, buf, p+1, TRUE);
}
HeapFree( GetProcessHeap(), 0, buf );
- string += strlen(string)+1;
+ string += strlenW(string)+1;
}
+ PROFILE_FlushFile();
}
}
@@ -1519,20 +1644,39 @@
}
/***********************************************************************
- * WritePrivateProfileSectionW (KERNEL32.@)
+ * WritePrivateProfileSectionA (KERNEL32.@)
*/
-BOOL WINAPI WritePrivateProfileSectionW( LPCWSTR section,
- LPCWSTR string, LPCWSTR filename)
+BOOL WINAPI WritePrivateProfileSectionA( LPCSTR section,
+ LPCSTR string, LPCSTR filename)
{
- LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
- LPSTR stringA = HEAP_strdupWtoA( GetProcessHeap(), 0, string );
- LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
- BOOL res = WritePrivateProfileSectionA( sectionA, stringA, filenameA );
- HeapFree( GetProcessHeap(), 0, sectionA );
- HeapFree( GetProcessHeap(), 0, stringA );
- HeapFree( GetProcessHeap(), 0, filenameA );
- return res;
+ UNICODE_STRING sectionW, filenameW;
+ LPWSTR stringW;
+ BOOL ret;
+
+ if (string)
+ {
+ INT lenA, lenW;
+ LPCSTR p = string;
+
+ while(*p) p += strlen(p) + 1;
+ lenA = p - string + 1;
+ lenW = MultiByteToWideChar(CP_ACP, 0, string, lenA, NULL, 0);
+ if ((stringW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR))))
+ MultiByteToWideChar(CP_ACP, 0, string, lenA, stringW, lenW);
+ }
+ else stringW = NULL;
+ if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
+ else sectionW.Buffer = NULL;
+ if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
+ else filenameW.Buffer = NULL;
+
+ ret = WritePrivateProfileSectionW(sectionW.Buffer, stringW, filenameW.Buffer);
+
+ HeapFree(GetProcessHeap(), 0, stringW);
+ RtlFreeUnicodeString(§ionW);
+ RtlFreeUnicodeString(&filenameW);
+ return ret;
}
/***********************************************************************
@@ -1557,7 +1701,7 @@
*/
BOOL WINAPI WriteProfileSectionW( LPCWSTR section, LPCWSTR keys_n_values)
{
- return (WritePrivateProfileSectionW (section,keys_n_values, wininiW));
+ return WritePrivateProfileSectionW(section, keys_n_values, wininiW);
}
/***********************************************************************
@@ -1581,7 +1725,7 @@
/***********************************************************************
- * GetPrivateProfileSectionNamesA (KERNEL32.@)
+ * GetPrivateProfileSectionNamesW (KERNEL32.@)
*
* Returns the section names contained in the specified file.
* FIXME: Where do we find this file when the path is relative?
@@ -1617,9 +1761,8 @@
* Note that when the buffer is big enough then the return value may be any
* value between 1 and len-1 (or len in Win95), including len-2.
*/
-DWORD WINAPI GetPrivateProfileSectionNamesA( LPSTR buffer, DWORD size,
- LPCSTR filename)
-
+DWORD WINAPI GetPrivateProfileSectionNamesW( LPWSTR buffer, DWORD size,
+ LPCWSTR filename)
{
DWORD ret = 0;
@@ -1635,21 +1778,32 @@
/***********************************************************************
- * GetPrivateProfileSectionNamesW (KERNEL32.@)
+ * GetPrivateProfileSectionNamesA (KERNEL32.@)
*/
-DWORD WINAPI GetPrivateProfileSectionNamesW( LPWSTR buffer, DWORD size,
- LPCWSTR filename)
-
+DWORD WINAPI GetPrivateProfileSectionNamesA( LPSTR buffer, DWORD size,
+ LPCSTR filename)
{
- LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
- LPSTR bufferA = HeapAlloc( GetProcessHeap(), 0, size);
+ UNICODE_STRING filenameW;
+ LPWSTR bufferW;
+ INT retW, ret = 0;
- INT ret = GetPrivateProfileSectionNamesA(bufferA, size, filenameA);
- if (size > 0 && !MultiByteToWideChar( CP_ACP, 0, bufferA, -1, buffer, size ))
- buffer[size-1] = 0;
- HeapFree( GetProcessHeap(), 0, bufferA);
- HeapFree( GetProcessHeap(), 0, filenameA );
+ bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)) : NULL;
+ if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
+ else filenameW.Buffer = NULL;
+ retW = GetPrivateProfileSectionNamesW(bufferW, size, filenameW.Buffer);
+ if (retW && size)
+ {
+ ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW, buffer, size, NULL, NULL);
+ if (!ret)
+ {
+ ret = size;
+ buffer[size-1] = 0;
+ }
+ }
+
+ RtlFreeUnicodeString(&filenameW);
+ if (bufferW) HeapFree(GetProcessHeap(), 0, bufferW);
return ret;
}
@@ -1663,12 +1817,12 @@
}
/***********************************************************************
- * GetPrivateProfileStructA (KERNEL32.@)
+ * GetPrivateProfileStructW (KERNEL32.@)
*
* Should match Win95's behaviour pretty much
*/
-BOOL WINAPI GetPrivateProfileStructA (LPCSTR section, LPCSTR key,
- LPVOID buf, UINT len, LPCSTR filename)
+BOOL WINAPI GetPrivateProfileStructW (LPCWSTR section, LPCWSTR key,
+ LPVOID buf, UINT len, LPCWSTR filename)
{
BOOL ret = FALSE;
@@ -1677,22 +1831,22 @@
if (PROFILE_Open( filename )) {
PROFILEKEY *k = PROFILE_Find ( &CurProfile->section, section, key, FALSE, FALSE);
if (k) {
- TRACE("value (at %p): '%s'\n", k->value, k->value);
- if (((strlen(k->value) - 2) / 2) == len)
+ TRACE("value (at %p): %s\n", k->value, debugstr_w(k->value));
+ if (((strlenW(k->value) - 2) / 2) == len)
{
- LPSTR end, p;
+ LPWSTR end, p;
BOOL valid = TRUE;
- CHAR c;
+ WCHAR c;
DWORD chksum = 0;
- end = k->value + strlen(k->value); /* -> '\0' */
+ end = k->value + strlenW(k->value); /* -> '\0' */
/* check for invalid chars in ASCII coded hex string */
for (p=k->value; p < end; p++)
{
- if (!isxdigit(*p))
+ if (!isxdigitW(*p))
{
- WARN("invalid char '%c' in file '%s'->'[%s]'->'%s' !\n",
- *p, filename, section, key);
+ WARN("invalid char '%x' in file %s->[%s]->%s !\n",
+ *p, debugstr_w(filename), debugstr_w(section), debugstr_w(key));
valid = FALSE;
break;
}
@@ -1707,7 +1861,7 @@
/* translate ASCII hex format into binary data */
for (p=k->value; p < end; p++)
{
- c = toupper(*p);
+ c = toupperW(*p);
val = (c > '9') ?
(c - 'A' + 10) : (c - '0');
@@ -1722,9 +1876,9 @@
highnibble ^= 1; /* toggle */
}
/* retrieve stored checksum value */
- c = toupper(*p++);
+ c = toupperW(*p++);
b = ( (c > '9') ? (c - 'A' + 10) : (c - '0') ) << 4;
- c = toupper(*p);
+ c = toupperW(*p);
b += (c > '9') ? (c - 'A' + 10) : (c - '0');
if (b == (chksum & 0xff)) /* checksums match ? */
ret = TRUE;
@@ -1738,25 +1892,28 @@
}
/***********************************************************************
- * GetPrivateProfileStructW (KERNEL32.@)
+ * GetPrivateProfileStructA (KERNEL32.@)
*/
-BOOL WINAPI GetPrivateProfileStructW (LPCWSTR section, LPCWSTR key,
- LPVOID buffer, UINT len, LPCWSTR filename)
+BOOL WINAPI GetPrivateProfileStructA (LPCSTR section, LPCSTR key,
+ LPVOID buffer, UINT len, LPCSTR filename)
{
- LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
- LPSTR keyA = HEAP_strdupWtoA( GetProcessHeap(), 0, key);
- LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
- LPSTR bufferA = HeapAlloc( GetProcessHeap(), 0, len );
+ UNICODE_STRING sectionW, keyW, filenameW;
+ INT ret;
- INT ret = GetPrivateProfileStructA( sectionA, keyA, bufferA,
- len, filenameA );
- if (len > 0 && !MultiByteToWideChar( CP_ACP, 0, bufferA, -1, buffer, len ))
- ((LPWSTR)buffer)[len-1] = 0;
- HeapFree( GetProcessHeap(), 0, bufferA);
- HeapFree( GetProcessHeap(), 0, sectionA );
- HeapFree( GetProcessHeap(), 0, keyA );
- HeapFree( GetProcessHeap(), 0, filenameA );
+ if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
+ else sectionW.Buffer = NULL;
+ if (key) RtlCreateUnicodeStringFromAsciiz(&keyW, key);
+ else keyW.Buffer = NULL;
+ if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
+ else filenameW.Buffer = NULL;
+ ret = GetPrivateProfileStructW(sectionW.Buffer, keyW.Buffer, buffer, len,
+ filenameW.Buffer);
+ /* Do not translate binary data. */
+
+ RtlFreeUnicodeString(§ionW);
+ RtlFreeUnicodeString(&keyW);
+ RtlFreeUnicodeString(&filenameW);
return ret;
}
@@ -1772,21 +1929,21 @@
}
/***********************************************************************
- * WritePrivateProfileStructA (KERNEL32.@)
+ * WritePrivateProfileStructW (KERNEL32.@)
*/
-BOOL WINAPI WritePrivateProfileStructA (LPCSTR section, LPCSTR key,
- LPVOID buf, UINT bufsize, LPCSTR filename)
+BOOL WINAPI WritePrivateProfileStructW (LPCWSTR section, LPCWSTR key,
+ LPVOID buf, UINT bufsize, LPCWSTR filename)
{
BOOL ret = FALSE;
LPBYTE binbuf;
- LPSTR outstring, p;
+ LPWSTR outstring, p;
DWORD sum = 0;
if (!section && !key && !buf) /* flush the cache */
- return WritePrivateProfileStringA( NULL, NULL, NULL, filename );
+ return WritePrivateProfileStringW( NULL, NULL, NULL, filename );
/* allocate string buffer for hex chars + checksum hex char + '\0' */
- outstring = HeapAlloc( GetProcessHeap(), 0, bufsize*2 + 2 + 1);
+ outstring = HeapAlloc( GetProcessHeap(), 0, (bufsize*2 + 2 + 1) * sizeof(WCHAR) );
p = outstring;
for (binbuf = (LPBYTE)buf; binbuf < (LPBYTE)buf+bufsize; binbuf++) {
*p++ = hex[*binbuf >> 4];
@@ -1800,8 +1957,10 @@
EnterCriticalSection( &PROFILE_CritSect );
- if (PROFILE_Open( filename ))
+ if (PROFILE_Open( filename )) {
ret = PROFILE_SetString( section, key, outstring, FALSE);
+ PROFILE_FlushFile();
+ }
LeaveCriticalSection( &PROFILE_CritSect );
@@ -1811,20 +1970,28 @@
}
/***********************************************************************
- * WritePrivateProfileStructW (KERNEL32.@)
+ * WritePrivateProfileStructA (KERNEL32.@)
*/
-BOOL WINAPI WritePrivateProfileStructW (LPCWSTR section, LPCWSTR key,
- LPVOID buf, UINT bufsize, LPCWSTR filename)
+BOOL WINAPI WritePrivateProfileStructA (LPCSTR section, LPCSTR key,
+ LPVOID buf, UINT bufsize, LPCSTR filename)
{
- LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
- LPSTR keyA = HEAP_strdupWtoA( GetProcessHeap(), 0, key);
- LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
- INT ret = WritePrivateProfileStructA( sectionA, keyA, buf, bufsize,
- filenameA );
- HeapFree( GetProcessHeap(), 0, sectionA );
- HeapFree( GetProcessHeap(), 0, keyA );
- HeapFree( GetProcessHeap(), 0, filenameA );
+ UNICODE_STRING sectionW, keyW, filenameW;
+ INT ret;
+ if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
+ else sectionW.Buffer = NULL;
+ if (key) RtlCreateUnicodeStringFromAsciiz(&keyW, key);
+ else keyW.Buffer = NULL;
+ if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
+ else filenameW.Buffer = NULL;
+
+ /* Do not translate binary data. */
+ ret = WritePrivateProfileStructW(sectionW.Buffer, keyW.Buffer, buf, bufsize,
+ filenameW.Buffer);
+
+ RtlFreeUnicodeString(§ionW);
+ RtlFreeUnicodeString(&keyW);
+ RtlFreeUnicodeString(&filenameW);
return ret;
}