Release 961222
[wine/gsoc-2012-control.git] / files / profile.c
blob2f08849104ce228f11023d0a8c6b027abf83763e
1 /*
2 * Profile functions
4 * Copyright 1993 Miguel de Icaza
5 * Copyright 1996 Alexandre Julliard
6 */
8 #define NO_TRANSITION_TYPES /* This file is Win32-clean */
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include "windows.h"
15 #include "dos_fs.h"
16 #include "heap.h"
17 #include "xmalloc.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 typedef struct tagPROFILEKEY
23 char *name;
24 char *value;
25 struct tagPROFILEKEY *next;
26 } PROFILEKEY;
28 typedef struct tagPROFILESECTION
30 char *name;
31 struct tagPROFILEKEY *key;
32 struct tagPROFILESECTION *next;
33 } PROFILESECTION;
36 typedef struct
38 BOOL32 changed;
39 PROFILESECTION *section;
40 char *dos_name;
41 } PROFILE;
44 /* Cached profile file */
45 static PROFILE CurProfile = { FALSE, NULL, NULL };
47 /* wine.ini profile content */
48 static PROFILESECTION *WineProfile;
50 #define PROFILE_MAX_LINE_LEN 1024
52 /* Wine profile name in $HOME directory; must begin with slash */
53 static const char PROFILE_WineIniName[] = "/.winerc";
55 /* Check for comments in profile */
56 #define IS_ENTRY_COMMENT(str) ((str)[0] == ';')
58 #define WINE_INI_GLOBAL ETCDIR "/wine.conf"
60 static LPCWSTR wininiW = NULL;
62 /***********************************************************************
63 * PROFILE_CopyEntry
65 * Copy the content of an entry into a buffer, removing quotes, and possibly
66 * translating environment variables.
68 static void PROFILE_CopyEntry( char *buffer, const char *value, int len,
69 int handle_env )
71 char quote = '\0';
72 const char *p;
74 if ((*value == '\'') || (*value == '\"'))
76 if (value[1] && (value[strlen(value)-1] == *value)) quote = *value++;
79 if (!handle_env)
81 lstrcpyn32A( buffer, value, len );
82 if (quote && (len >= strlen(value))) buffer[strlen(buffer)-1] = '\0';
83 return;
86 for (p = value; (*p && (len > 1)); *buffer++ = *p++, len-- )
88 if ((*p == '$') && (p[1] == '{'))
90 char env_val[1024];
91 const char *env_p;
92 const char *p2 = strchr( p, '}' );
93 if (!p2) continue; /* ignore it */
94 lstrcpyn32A(env_val, p + 2, MIN( sizeof(env_val), (int)(p2-p)-1 ));
95 if ((env_p = getenv( env_val )) != NULL)
97 lstrcpyn32A( buffer, env_p, len );
98 buffer += strlen( buffer );
99 len -= strlen( buffer );
101 p = p2 + 1;
104 *buffer = '\0';
108 /***********************************************************************
109 * PROFILE_Save
111 * Save a profile tree to a file.
113 static void PROFILE_Save( FILE *file, PROFILESECTION *section )
115 PROFILEKEY *key;
117 for ( ; section; section = section->next)
119 if (section->name) fprintf( file, "[%s]\r\n", section->name );
120 for (key = section->key; key; key = key->next)
122 fprintf( file, "%s", key->name );
123 if (key->value) fprintf( file, "=%s", key->value );
124 fprintf( file, "\r\n" );
130 /***********************************************************************
131 * PROFILE_Free
133 * Free a profile tree.
135 static void PROFILE_Free( PROFILESECTION *section )
137 PROFILESECTION *next_section;
138 PROFILEKEY *key, *next_key;
140 for ( ; section; section = next_section)
142 if (section->name) free( section->name );
143 for (key = section->key; key; key = next_key)
145 next_key = key->next;
146 if (key->name) free( key->name );
147 if (key->value) free( key->value );
148 free( key );
150 next_section = section->next;
151 free( section );
156 /***********************************************************************
157 * PROFILE_Load
159 * Load a profile tree from a file.
161 static PROFILESECTION *PROFILE_Load( FILE *file )
163 char buffer[PROFILE_MAX_LINE_LEN];
164 char *p, *p2;
165 int line = 0;
166 PROFILESECTION *section, *first_section;
167 PROFILESECTION **prev_section;
168 PROFILEKEY *key, **prev_key;
170 first_section = (PROFILESECTION *)xmalloc( sizeof(*section) );
171 first_section->name = NULL;
172 first_section->key = NULL;
173 first_section->next = NULL;
174 prev_section = &first_section->next;
175 prev_key = &first_section->key;
177 while (fgets( buffer, PROFILE_MAX_LINE_LEN, file ))
179 line++;
180 p = buffer + strlen(buffer) - 1;
181 while ((p > buffer) && ((*p == '\n') || isspace(*p))) *p-- = '\0';
182 p = buffer;
183 while (*p && isspace(*p)) p++;
184 if (*p == '[') /* section start */
186 if (!(p2 = strrchr( p, ']' )))
188 fprintf( stderr, "PROFILE_Load: Invalid section header at line %d: '%s'\n",
189 line, p );
191 else
193 *p2 = '\0';
194 p++;
195 section = (PROFILESECTION *)xmalloc( sizeof(*section));
196 section->name = xstrdup( p );
197 section->key = NULL;
198 section->next = NULL;
199 *prev_section = section;
200 prev_section = &section->next;
201 prev_key = &section->key;
202 continue;
205 if ((p2 = strchr( p, '=' )) != NULL)
207 char *p3 = p2 - 1;
208 while ((p3 > p) && isspace(*p3)) *p3-- = '\0';
209 *p2++ = '\0';
210 while (*p2 && isspace(*p2)) p2++;
212 key = (PROFILEKEY *)xmalloc( sizeof(*key) );
213 key->name = xstrdup( p );
214 key->value = p2 ? xstrdup( p2 ) : NULL;
215 key->next = NULL;
216 *prev_key = key;
217 prev_key = &key->next;
219 if (debugging_profile)
221 fprintf( stddeb, "PROFILE_Load:\n" );
222 PROFILE_Save( stddeb, first_section );
223 fprintf( stddeb, "PROFILE_Load finished.\n" );
225 return first_section;
229 /***********************************************************************
230 * PROFILE_DeleteSection
232 * Delete a section from a profile tree.
234 static BOOL32 PROFILE_DeleteSection( PROFILESECTION **section, LPCSTR name )
236 while (*section)
238 if ((*section)->name && !lstrcmpi32A( (*section)->name, name ))
240 PROFILESECTION *to_del = *section;
241 *section = to_del->next;
242 to_del->next = NULL;
243 PROFILE_Free( to_del );
244 return TRUE;
246 section = &(*section)->next;
248 return FALSE;
252 /***********************************************************************
253 * PROFILE_DeleteKey
255 * Delete a key from a profile tree.
257 static BOOL32 PROFILE_DeleteKey( PROFILESECTION **section,
258 LPCSTR section_name, LPCSTR key_name )
260 while (*section)
262 if ((*section)->name && !lstrcmpi32A( (*section)->name, section_name ))
264 PROFILEKEY **key = &(*section)->key;
265 while (*key)
267 if (!lstrcmpi32A( (*key)->name, key_name ))
269 PROFILEKEY *to_del = *key;
270 *key = to_del->next;
271 if (to_del->name) free( to_del->name );
272 if (to_del->value) free( to_del->value );
273 free( to_del );
274 return TRUE;
276 key = &(*key)->next;
279 section = &(*section)->next;
281 return FALSE;
285 /***********************************************************************
286 * PROFILE_Find
288 * Find a key in a profile tree, optionally creating it.
290 static PROFILEKEY *PROFILE_Find( PROFILESECTION **section,
291 const char *section_name,
292 const char *key_name, int create )
294 while (*section)
296 if ((*section)->name && !lstrcmpi32A( (*section)->name, section_name ))
298 PROFILEKEY **key = &(*section)->key;
299 while (*key)
301 if (!lstrcmpi32A( (*key)->name, key_name )) return *key;
302 key = &(*key)->next;
304 if (!create) return NULL;
305 *key = (PROFILEKEY *)xmalloc( sizeof(PROFILEKEY) );
306 (*key)->name = xstrdup( key_name );
307 (*key)->value = NULL;
308 (*key)->next = NULL;
309 return *key;
311 section = &(*section)->next;
313 if (!create) return NULL;
314 *section = (PROFILESECTION *)xmalloc( sizeof(PROFILESECTION) );
315 (*section)->name = xstrdup(section_name);
316 (*section)->next = NULL;
317 (*section)->key = (PROFILEKEY *)xmalloc( sizeof(PROFILEKEY) );
318 (*section)->key->name = xstrdup( key_name );
319 (*section)->key->value = NULL;
320 (*section)->key->next = NULL;
321 return (*section)->key;
325 /***********************************************************************
326 * PROFILE_FlushFile
328 * Flush the current profile to disk if changed.
330 static BOOL32 PROFILE_FlushFile(void)
332 char *p, buffer[MAX_PATHNAME_LEN];
333 const char *unix_name;
334 FILE *file = NULL;
336 if (!CurProfile.changed || !CurProfile.dos_name) return TRUE;
337 if (!(unix_name = DOSFS_GetUnixFileName( CurProfile.dos_name, FALSE )) ||
338 !(file = fopen( unix_name, "w" )))
340 /* Try to create it in $HOME/.wine */
341 /* FIXME: this will need a more general solution */
342 if ((p = getenv( "HOME" )) != NULL)
344 strcpy( buffer, p );
345 strcat( buffer, "/.wine/" );
346 p = buffer + strlen(buffer);
347 strcpy( p, strrchr( CurProfile.dos_name, '\\' ) + 1 );
348 AnsiLower( p );
349 file = fopen( buffer, "w" );
350 unix_name = buffer;
354 if (!file)
356 fprintf( stderr, "Warning: could not save profile file %s\n",
357 CurProfile.dos_name );
358 return FALSE;
361 dprintf_profile( stddeb, "Saving '%s' into '%s'\n",
362 CurProfile.dos_name, unix_name );
363 PROFILE_Save( file, CurProfile.section );
364 fclose( file );
365 CurProfile.changed = FALSE;
366 return TRUE;
370 /***********************************************************************
371 * PROFILE_Open
373 * Open a profile file, checking the cached file first.
375 static BOOL32 PROFILE_Open( LPCSTR filename )
377 char buffer[MAX_PATHNAME_LEN];
378 const char *dos_name, *unix_name;
379 char *newdos_name, *p;
380 FILE *file = NULL;
382 if (strchr( filename, '/' ) || strchr( filename, '\\' ) ||
383 strchr( filename, ':' ))
385 if (!(dos_name = DOSFS_GetDosTrueName( filename, FALSE))) return FALSE;
387 else
389 GetWindowsDirectory32A( buffer, sizeof(buffer) );
390 strcat( buffer, "\\" );
391 strcat( buffer, filename );
392 if (!(dos_name = DOSFS_GetDosTrueName( buffer, FALSE ))) return FALSE;
394 if (CurProfile.dos_name && !strcmp( dos_name, CurProfile.dos_name ))
396 dprintf_profile( stddeb, "PROFILE_Open(%s): already opened\n",
397 filename );
398 return TRUE;
401 /* Flush the previous profile */
403 newdos_name = xstrdup( dos_name );
404 PROFILE_FlushFile();
405 PROFILE_Free( CurProfile.section );
406 if (CurProfile.dos_name) free( CurProfile.dos_name );
407 CurProfile.section = NULL;
408 CurProfile.dos_name = newdos_name;
410 /* Try to open the profile file, first in $HOME/.wine */
412 /* FIXME: this will need a more general solution */
413 if ((p = getenv( "HOME" )) != NULL)
415 strcpy( buffer, p );
416 strcat( buffer, "/.wine/" );
417 p = buffer + strlen(buffer);
418 strcpy( p, strrchr( newdos_name, '\\' ) + 1 );
419 AnsiLower( p );
420 if ((file = fopen( buffer, "r" )))
421 dprintf_profile( stddeb, "Found it in %s\n", buffer );
424 if (!file && ((unix_name = DOSFS_GetUnixFileName( dos_name, TRUE ))))
426 if ((file = fopen( unix_name, "r" )))
427 dprintf_profile( stddeb, "Found it in %s\n", unix_name );
430 if (file)
432 CurProfile.section = PROFILE_Load( file );
433 fclose( file );
435 else
437 /* Does not exist yet, we will create it in PROFILE_FlushFile */
438 fprintf( stderr, "Warning: profile file %s not found\n", newdos_name );
440 dprintf_profile( stddeb, "PROFILE_Open(%s): successful\n", filename );
441 return TRUE;
445 /***********************************************************************
446 * PROFILE_GetSection
448 * Enumerate all the keys of a section.
450 static INT32 PROFILE_GetSection( PROFILESECTION *section, LPCSTR section_name,
451 LPSTR buffer, INT32 len, BOOL32 handle_env )
453 PROFILEKEY *key;
454 while (section)
456 if (section->name && !lstrcmpi32A( section->name, section_name ))
458 INT32 oldlen = len;
459 for (key = section->key; key; key = key->next)
461 if (len <= 2) break;
462 if (IS_ENTRY_COMMENT(key->name)) continue; /* Skip comments */
463 PROFILE_CopyEntry( buffer, key->name, len - 1, handle_env );
464 len -= strlen(buffer) + 1;
465 buffer += strlen(buffer) + 1;
467 *buffer = '\0';
468 return oldlen - len + 1;
470 section = section->next;
472 buffer[0] = buffer[1] = '\0';
473 return 2;
477 /***********************************************************************
478 * PROFILE_GetString
480 * Get a profile string.
482 static INT32 PROFILE_GetString( LPCSTR section, LPCSTR key_name,
483 LPCSTR def_val, LPSTR buffer, INT32 len )
485 PROFILEKEY *key = NULL;
487 if (!def_val) def_val = "";
488 if (key_name)
490 key = PROFILE_Find( &CurProfile.section, section, key_name, FALSE );
491 PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val,
492 len, FALSE );
493 dprintf_profile( stddeb, "PROFILE_GetString('%s','%s','%s'): returning '%s'\n",
494 section, key_name, def_val, buffer );
495 return strlen( buffer );
497 return PROFILE_GetSection(CurProfile.section, section, buffer, len, FALSE);
501 /***********************************************************************
502 * PROFILE_SetString
504 * Set a profile string.
506 static BOOL32 PROFILE_SetString( LPCSTR section_name, LPCSTR key_name,
507 LPCSTR value )
509 if (!key_name) /* Delete a whole section */
511 dprintf_profile(stddeb, "PROFILE_DeleteSection('%s')\n", section_name);
512 CurProfile.changed |= PROFILE_DeleteSection( &CurProfile.section,
513 section_name );
514 return TRUE; /* Even if PROFILE_DeleteSection() has failed,
515 this is not an error on application's level.*/
517 else if (!value) /* Delete a key */
519 dprintf_profile( stddeb, "PROFILE_DeleteKey('%s','%s')\n",
520 section_name, key_name );
521 CurProfile.changed |= PROFILE_DeleteKey( &CurProfile.section,
522 section_name, key_name );
523 return TRUE; /* same error handling as above */
525 else /* Set the key value */
527 PROFILEKEY *key = PROFILE_Find( &CurProfile.section, section_name,
528 key_name, TRUE );
529 dprintf_profile( stddeb, "PROFILE_SetString('%s','%s','%s'): ",
530 section_name, key_name, value );
531 if (key->value)
533 if (!strcmp( key->value, value ))
535 dprintf_profile( stddeb, "no change needed\n" );
536 return TRUE; /* No change needed */
538 dprintf_profile( stddeb, "replacing '%s'\n", key->value );
539 free( key->value );
541 else dprintf_profile( stddeb, "creating key\n" );
542 key->value = xstrdup( value );
543 CurProfile.changed = TRUE;
545 return TRUE;
549 /***********************************************************************
550 * PROFILE_GetWineIniString
552 * Get a config string from the wine.ini file.
554 int PROFILE_GetWineIniString( const char *section, const char *key_name,
555 const char *def, char *buffer, int len )
557 if (key_name)
559 PROFILEKEY *key = PROFILE_Find(&WineProfile, section, key_name, FALSE);
560 PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def,
561 len, TRUE );
562 dprintf_profile( stddeb, "PROFILE_GetWineIniString('%s','%s','%s'): returning '%s'\n",
563 section, key_name, def, buffer );
564 return strlen( buffer );
566 return PROFILE_GetSection( WineProfile, section, buffer, len, TRUE );
570 /***********************************************************************
571 * PROFILE_GetWineIniInt
573 * Get a config integer from the wine.ini file.
575 int PROFILE_GetWineIniInt( const char *section, const char *key_name, int def )
577 char buffer[20];
578 char *p;
579 long result;
581 PROFILEKEY *key = PROFILE_Find( &WineProfile, section, key_name, FALSE );
582 if (!key || !key->value) return def;
583 PROFILE_CopyEntry( buffer, key->value, sizeof(buffer), TRUE );
584 result = strtol( buffer, &p, 0 );
585 if (p == buffer) return 0; /* No digits at all */
586 return (int)result;
590 /***********************************************************************
591 * PROFILE_LoadWineIni
593 * Load the wine.ini file.
595 int PROFILE_LoadWineIni(void)
597 char buffer[MAX_PATHNAME_LEN];
598 const char *p;
599 FILE *f;
601 if ((p = getenv( "HOME" )) != NULL)
603 lstrcpyn32A(buffer, p, MAX_PATHNAME_LEN - sizeof(PROFILE_WineIniName));
604 strcat( buffer, PROFILE_WineIniName );
605 if ((f = fopen( buffer, "r" )) != NULL)
607 WineProfile = PROFILE_Load( f );
608 fclose( f );
609 return 1;
612 else fprintf( stderr, "Warning: could not get $HOME value for config file.\n" );
614 /* Try global file */
616 if ((f = fopen( WINE_INI_GLOBAL, "r" )) != NULL)
618 WineProfile = PROFILE_Load( f );
619 fclose( f );
620 return 1;
622 fprintf( stderr, "Can't open configuration file %s or $HOME%s\n",
623 WINE_INI_GLOBAL, PROFILE_WineIniName );
624 return 0;
628 /********************* API functions **********************************/
630 /***********************************************************************
631 * GetProfileInt16 (KERNEL.57)
633 UINT16 GetProfileInt16( LPCSTR section, LPCSTR entry, INT16 def_val )
635 return GetPrivateProfileInt16( section, entry, def_val, "win.ini" );
639 /***********************************************************************
640 * GetProfileInt32A (KERNEL32.264)
642 UINT32 GetProfileInt32A( LPCSTR section, LPCSTR entry, INT32 def_val )
644 return GetPrivateProfileInt32A( section, entry, def_val, "win.ini" );
647 /***********************************************************************
648 * GetProfileInt32W (KERNEL32.264)
650 UINT32 GetProfileInt32W( LPCWSTR section, LPCWSTR entry, INT32 def_val )
652 if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
653 return GetPrivateProfileInt32W( section, entry, def_val, wininiW );
656 /***********************************************************************
657 * GetProfileString16 (KERNEL.58)
659 INT16 GetProfileString16( LPCSTR section, LPCSTR entry, LPCSTR def_val,
660 LPSTR buffer, INT16 len )
662 return GetPrivateProfileString16( section, entry, def_val,
663 buffer, len, "win.ini" );
666 /***********************************************************************
667 * GetProfileString32A (KERNEL32.268)
669 INT32 GetProfileString32A( LPCSTR section, LPCSTR entry, LPCSTR def_val,
670 LPSTR buffer, INT32 len )
672 return GetPrivateProfileString32A( section, entry, def_val,
673 buffer, len, "win.ini" );
676 /***********************************************************************
677 * GetProfileString32W (KERNEL32.269)
679 INT32 GetProfileString32W( LPCWSTR section,LPCWSTR entry,LPCWSTR def_val,
680 LPWSTR buffer, INT32 len )
682 if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
683 return GetPrivateProfileString32W( section, entry, def_val,
684 buffer, len, wininiW );
688 /***********************************************************************
689 * WriteProfileString16 (KERNEL.59)
691 BOOL16 WriteProfileString16( LPCSTR section, LPCSTR entry, LPCSTR string )
693 return WritePrivateProfileString16( section, entry, string, "win.ini" );
696 /***********************************************************************
697 * WriteProfileString32A (KERNEL32.587)
699 BOOL32 WriteProfileString32A( LPCSTR section, LPCSTR entry, LPCSTR string )
701 return WritePrivateProfileString32A( section, entry, string, "win.ini" );
704 /***********************************************************************
705 * WriteProfileString32W (KERNEL32.588)
707 BOOL32 WriteProfileString32W( LPCWSTR section, LPCWSTR entry, LPCWSTR string )
709 if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
710 return WritePrivateProfileString32W( section, entry, string, wininiW );
714 /***********************************************************************
715 * GetPrivateProfileInt16 (KERNEL.127)
717 UINT16 GetPrivateProfileInt16( LPCSTR section, LPCSTR entry, INT16 def_val,
718 LPCSTR filename )
720 long result=(long)GetPrivateProfileInt32A(section,entry,def_val,filename);
722 if (result > 65535) return 65535;
723 if (result >= 0) return (UINT16)result;
724 if (result < -32768) return -32768;
725 return (UINT16)(INT16)result;
728 /***********************************************************************
729 * GetPrivateProfileInt32A (KERNEL32.251)
731 UINT32 GetPrivateProfileInt32A( LPCSTR section, LPCSTR entry, INT32 def_val,
732 LPCSTR filename )
734 char buffer[20];
735 char *p;
736 long result;
738 GetPrivateProfileString32A( section, entry, "",
739 buffer, sizeof(buffer), filename );
740 if (!buffer[0]) return (UINT32)def_val;
741 result = strtol( buffer, &p, 0 );
742 if (p == buffer) return 0; /* No digits at all */
743 return (UINT32)result;
746 /***********************************************************************
747 * GetPrivateProfileInt32W (KERNEL32.252)
749 UINT32 GetPrivateProfileInt32W( LPCWSTR section, LPCWSTR entry, INT32 def_val,
750 LPCWSTR filename )
752 LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
753 LPSTR entryA = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
754 LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
755 UINT32 res = GetPrivateProfileInt32A(sectionA, entryA, def_val, filenameA);
756 HeapFree( GetProcessHeap(), 0, sectionA );
757 HeapFree( GetProcessHeap(), 0, filenameA );
758 HeapFree( GetProcessHeap(), 0, entryA );
759 return res;
762 /***********************************************************************
763 * GetPrivateProfileString16 (KERNEL.128)
765 INT16 GetPrivateProfileString16( LPCSTR section, LPCSTR entry, LPCSTR def_val,
766 LPSTR buffer, INT16 len, LPCSTR filename )
768 return GetPrivateProfileString32A(section,entry,def_val,buffer,len,filename);
771 /***********************************************************************
772 * GetPrivateProfileString32A (KERNEL32.255)
774 INT32 GetPrivateProfileString32A( LPCSTR section, LPCSTR entry, LPCSTR def_val,
775 LPSTR buffer, INT32 len, LPCSTR filename )
777 if (PROFILE_Open( filename ))
778 return PROFILE_GetString( section, entry, def_val, buffer, len );
779 lstrcpyn32A( buffer, def_val, len );
780 return strlen( buffer );
783 /***********************************************************************
784 * GetPrivateProfileString32W (KERNEL32.256)
786 INT32 GetPrivateProfileString32W( LPCWSTR section, LPCWSTR entry,
787 LPCWSTR def_val, LPWSTR buffer,
788 INT32 len, LPCWSTR filename )
790 LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
791 LPSTR entryA = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
792 LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
793 LPSTR def_valA = HEAP_strdupWtoA( GetProcessHeap(), 0, def_val );
794 LPSTR bufferA = HeapAlloc( GetProcessHeap(), 0, len );
795 INT32 ret = GetPrivateProfileString32A( sectionA, entryA, def_valA,
796 bufferA, len, filenameA );
797 lstrcpynAtoW( buffer, bufferA, len );
798 HeapFree( GetProcessHeap(), 0, sectionA );
799 HeapFree( GetProcessHeap(), 0, entryA );
800 HeapFree( GetProcessHeap(), 0, filenameA );
801 HeapFree( GetProcessHeap(), 0, def_valA );
802 HeapFree( GetProcessHeap(), 0, bufferA);
803 return ret;
808 /***********************************************************************
809 * WritePrivateProfileString16 (KERNEL.129)
811 BOOL16 WritePrivateProfileString16(LPCSTR section,LPCSTR entry,LPCSTR string,
812 LPCSTR filename)
814 return WritePrivateProfileString32A(section,entry,string,filename);
817 /***********************************************************************
818 * WritePrivateProfileString32A (KERNEL32.582)
820 BOOL32 WritePrivateProfileString32A(LPCSTR section,LPCSTR entry,LPCSTR string,
821 LPCSTR filename )
823 if (!PROFILE_Open( filename )) return FALSE;
824 if (!section) return PROFILE_FlushFile();
825 return PROFILE_SetString( section, entry, string );
828 /***********************************************************************
829 * WritePrivateProfileString32W (KERNEL32.583)
831 BOOL32 WritePrivateProfileString32W( LPCWSTR section, LPCWSTR entry,
832 LPCWSTR string, LPCWSTR filename )
834 LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
835 LPSTR entryA = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
836 LPSTR stringA = HEAP_strdupWtoA( GetProcessHeap(), 0, string );
837 LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
838 BOOL32 res = WritePrivateProfileString32A( sectionA, entryA,
839 stringA, filenameA );
840 HeapFree( GetProcessHeap(), 0, sectionA );
841 HeapFree( GetProcessHeap(), 0, entryA );
842 HeapFree( GetProcessHeap(), 0, stringA );
843 HeapFree( GetProcessHeap(), 0, filenameA );
844 return res;
848 /***********************************************************************
849 * WriteOutProfiles (KERNEL.315)
851 void WriteOutProfiles(void)
853 PROFILE_FlushFile();