4 * Copyright 1993 Miguel de Icaza
5 * Copyright 1996 Alexandre Julliard
19 typedef struct tagPROFILEKEY
23 struct tagPROFILEKEY *next;
26 typedef struct tagPROFILESECTION
29 struct tagPROFILEKEY *key;
30 struct tagPROFILESECTION *next;
37 PROFILESECTION *section;
45 #define N_CACHED_PROFILES 10
47 /* Cached profile files */
48 static PROFILE *MRUProfile[N_CACHED_PROFILES]={NULL};
50 #define CurProfile (MRUProfile[0])
52 /* wine.ini profile content */
53 static PROFILESECTION *WineProfile;
55 #define PROFILE_MAX_LINE_LEN 1024
57 /* Wine profile name in $HOME directory; must begin with slash */
58 static const char PROFILE_WineIniName[] = "/.winerc";
60 /* Check for comments in profile */
61 #define IS_ENTRY_COMMENT(str) ((str)[0] == ';')
63 #define WINE_INI_GLOBAL ETCDIR "/wine.conf"
65 static LPCWSTR wininiW = NULL;
67 /***********************************************************************
70 * Copy the content of an entry into a buffer, removing quotes, and possibly
71 * translating environment variables.
73 static void PROFILE_CopyEntry( char *buffer, const char *value, int len,
79 if ((*value == '\'') || (*value == '\"'))
81 if (value[1] && (value[strlen(value)-1] == *value)) quote = *value++;
86 lstrcpyn32A( buffer, value, len );
87 if (quote && (len >= strlen(value))) buffer[strlen(buffer)-1] = '\0';
91 for (p = value; (*p && (len > 1)); *buffer++ = *p++, len-- )
93 if ((*p == '$') && (p[1] == '{'))
97 const char *p2 = strchr( p, '}' );
98 if (!p2) continue; /* ignore it */
99 lstrcpyn32A(env_val, p + 2, MIN( sizeof(env_val), (int)(p2-p)-1 ));
100 if ((env_p = getenv( env_val )) != NULL)
102 lstrcpyn32A( buffer, env_p, len );
103 buffer += strlen( buffer );
104 len -= strlen( buffer );
113 /***********************************************************************
116 * Save a profile tree to a file.
118 static void PROFILE_Save( FILE *file, PROFILESECTION *section )
122 for ( ; section; section = section->next)
124 if (section->name) fprintf( file, "\r\n[%s]\r\n", section->name );
125 for (key = section->key; key; key = key->next)
127 fprintf( file, "%s", key->name );
128 if (key->value) fprintf( file, "=%s", key->value );
129 fprintf( file, "\r\n" );
135 /***********************************************************************
138 * Free a profile tree.
140 static void PROFILE_Free( PROFILESECTION *section )
142 PROFILESECTION *next_section;
143 PROFILEKEY *key, *next_key;
145 for ( ; section; section = next_section)
147 if (section->name) HeapFree( SystemHeap, 0, section->name );
148 for (key = section->key; key; key = next_key)
150 next_key = key->next;
151 if (key->name) HeapFree( SystemHeap, 0, key->name );
152 if (key->value) HeapFree( SystemHeap, 0, key->value );
153 HeapFree( SystemHeap, 0, key );
155 next_section = section->next;
156 HeapFree( SystemHeap, 0, section );
161 PROFILE_isspace(char c) {
162 if (isspace(c)) return 1;
163 if (c=='\r' || c==0x1a) return 1;
164 /* CR and ^Z (DOS EOF) are spaces too (found on CD-ROMs) */
169 /***********************************************************************
172 * Load a profile tree from a file.
174 static PROFILESECTION *PROFILE_Load( FILE *file )
176 char buffer[PROFILE_MAX_LINE_LEN];
179 PROFILESECTION *section, *first_section;
180 PROFILESECTION **next_section;
181 PROFILEKEY *key, *prev_key, **next_key;
183 first_section = HEAP_xalloc( SystemHeap, 0, sizeof(*section) );
184 first_section->name = NULL;
185 first_section->key = NULL;
186 first_section->next = NULL;
187 next_section = &first_section->next;
188 next_key = &first_section->key;
191 while (fgets( buffer, PROFILE_MAX_LINE_LEN, file ))
195 while (*p && PROFILE_isspace(*p)) p++;
196 if (*p == '[') /* section start */
198 if (!(p2 = strrchr( p, ']' )))
200 WARN(profile, "Invalid section header at line %d: '%s'\n",
207 section = HEAP_xalloc( SystemHeap, 0, sizeof(*section) );
208 section->name = HEAP_strdupA( SystemHeap, 0, p );
210 section->next = NULL;
211 *next_section = section;
212 next_section = §ion->next;
213 next_key = §ion->key;
216 TRACE(profile, "New section: '%s'\n",section->name);
223 while ((p2 > p) && ((*p2 == '\n') || PROFILE_isspace(*p2))) *p2--='\0';
225 if ((p2 = strchr( p, '=' )) != NULL)
228 while ((p3 > p) && PROFILE_isspace(*p3)) *p3-- = '\0';
230 while (*p2 && PROFILE_isspace(*p2)) p2++;
233 if(*p || !prev_key || *prev_key->name)
235 key = HEAP_xalloc( SystemHeap, 0, sizeof(*key) );
236 key->name = HEAP_strdupA( SystemHeap, 0, p );
237 key->value = p2 ? HEAP_strdupA( SystemHeap, 0, p2 ) : NULL;
240 next_key = &key->next;
243 TRACE(profile, "New key: name='%s', value='%s'\n",key->name,key->value?key->value:"(none)");
246 return first_section;
250 /***********************************************************************
251 * PROFILE_DeleteSection
253 * Delete a section from a profile tree.
255 static BOOL32 PROFILE_DeleteSection( PROFILESECTION **section, LPCSTR name )
259 if ((*section)->name && !strcasecmp( (*section)->name, name ))
261 PROFILESECTION *to_del = *section;
262 *section = to_del->next;
264 PROFILE_Free( to_del );
267 section = &(*section)->next;
273 /***********************************************************************
276 * Delete a key from a profile tree.
278 static BOOL32 PROFILE_DeleteKey( PROFILESECTION **section,
279 LPCSTR section_name, LPCSTR key_name )
283 if ((*section)->name && !strcasecmp( (*section)->name, section_name ))
285 PROFILEKEY **key = &(*section)->key;
288 if (!strcasecmp( (*key)->name, key_name ))
290 PROFILEKEY *to_del = *key;
292 if (to_del->name) HeapFree( SystemHeap, 0, to_del->name );
293 if (to_del->value) HeapFree( SystemHeap, 0, to_del->value);
294 HeapFree( SystemHeap, 0, to_del );
300 section = &(*section)->next;
306 /***********************************************************************
309 * Find a key in a profile tree, optionally creating it.
311 static PROFILEKEY *PROFILE_Find( PROFILESECTION **section,
312 const char *section_name,
313 const char *key_name, int create )
317 if ((*section)->name && !strcasecmp( (*section)->name, section_name ))
319 PROFILEKEY **key = &(*section)->key;
322 if (!strcasecmp( (*key)->name, key_name )) return *key;
325 if (!create) return NULL;
326 *key = HEAP_xalloc( SystemHeap, 0, sizeof(PROFILEKEY) );
327 (*key)->name = HEAP_strdupA( SystemHeap, 0, key_name );
328 (*key)->value = NULL;
332 section = &(*section)->next;
334 if (!create) return NULL;
335 *section = HEAP_xalloc( SystemHeap, 0, sizeof(PROFILESECTION) );
336 (*section)->name = HEAP_strdupA( SystemHeap, 0, section_name );
337 (*section)->next = NULL;
338 (*section)->key = HEAP_xalloc( SystemHeap, 0, sizeof(PROFILEKEY) );
339 (*section)->key->name = HEAP_strdupA( SystemHeap, 0, key_name );
340 (*section)->key->value = NULL;
341 (*section)->key->next = NULL;
342 return (*section)->key;
346 /***********************************************************************
349 * Flush the current profile to disk if changed.
351 static BOOL32 PROFILE_FlushFile(void)
353 char *p, buffer[MAX_PATHNAME_LEN];
354 const char *unix_name;
360 WARN(profile, "No current profile!\n");
364 if (!CurProfile->changed || !CurProfile->dos_name) return TRUE;
365 if (!(unix_name = CurProfile->unix_name) || !(file = fopen(unix_name, "w")))
367 /* Try to create it in $HOME/.wine */
368 /* FIXME: this will need a more general solution */
369 if ((p = getenv( "HOME" )) != NULL)
372 strcat( buffer, "/.wine/" );
373 p = buffer + strlen(buffer);
374 strcpy( p, strrchr( CurProfile->dos_name, '\\' ) + 1 );
376 file = fopen( buffer, "w" );
383 WARN(profile, "could not save profile file %s\n", CurProfile->dos_name);
387 TRACE(profile, "Saving '%s' into '%s'\n", CurProfile->dos_name, unix_name );
388 PROFILE_Save( file, CurProfile->section );
390 CurProfile->changed = FALSE;
391 if(!stat(unix_name,&buf))
392 CurProfile->mtime=buf.st_mtime;
397 /***********************************************************************
400 * Open a profile file, checking the cached file first.
402 static BOOL32 PROFILE_Open( LPCSTR filename )
404 DOS_FULL_NAME full_name;
405 char buffer[MAX_PATHNAME_LEN];
406 char *newdos_name, *p;
410 PROFILE *tempProfile;
412 /* First time around */
415 for(i=0;i<N_CACHED_PROFILES;i++)
417 MRUProfile[i]=HEAP_xalloc( SystemHeap, 0, sizeof(PROFILE) );
418 MRUProfile[i]->changed=FALSE;
419 MRUProfile[i]->section=NULL;
420 MRUProfile[i]->dos_name=NULL;
421 MRUProfile[i]->unix_name=NULL;
422 MRUProfile[i]->filename=NULL;
423 MRUProfile[i]->mtime=0;
426 /* Check for a match */
428 if (strchr( filename, '/' ) || strchr( filename, '\\' ) ||
429 strchr( filename, ':' ))
431 if (!DOSFS_GetFullName( filename, FALSE, &full_name )) return FALSE;
435 GetWindowsDirectory32A( buffer, sizeof(buffer) );
436 strcat( buffer, "\\" );
437 strcat( buffer, filename );
438 if (!DOSFS_GetFullName( buffer, FALSE, &full_name )) return FALSE;
441 for(i=0;i<N_CACHED_PROFILES;i++)
443 if ((MRUProfile[i]->filename && !strcmp( filename, MRUProfile[i]->filename )) ||
444 (MRUProfile[i]->dos_name && !strcmp( full_name.short_name, MRUProfile[i]->dos_name )))
449 tempProfile=MRUProfile[i];
451 MRUProfile[j]=MRUProfile[j-1];
452 CurProfile=tempProfile;
454 if(!stat(CurProfile->unix_name,&buf) && CurProfile->mtime==buf.st_mtime)
455 TRACE(profile, "(%s): already opened (mru=%d)\n",
458 TRACE(profile, "(%s): already opened, needs refreshing (mru=%d)\n",
464 /* Rotate the oldest to the top to be replaced */
466 if(i==N_CACHED_PROFILES)
468 tempProfile=MRUProfile[N_CACHED_PROFILES-1];
469 for(i=N_CACHED_PROFILES-1;i>0;i--)
470 MRUProfile[i]=MRUProfile[i-1];
471 CurProfile=tempProfile;
474 /* Flush the profile */
476 if(CurProfile->filename)
479 PROFILE_Free( CurProfile->section );
480 if (CurProfile->dos_name) HeapFree( SystemHeap, 0, CurProfile->dos_name );
481 if (CurProfile->unix_name) HeapFree( SystemHeap, 0, CurProfile->unix_name );
482 if (CurProfile->filename) HeapFree( SystemHeap, 0, CurProfile->filename );
483 CurProfile->changed=FALSE;
484 CurProfile->section=NULL;
485 CurProfile->dos_name=NULL;
486 CurProfile->unix_name=NULL;
487 CurProfile->filename=NULL;
491 newdos_name = HEAP_strdupA( SystemHeap, 0, full_name.short_name );
492 CurProfile->dos_name = newdos_name;
493 CurProfile->filename = HEAP_strdupA( SystemHeap, 0, filename );
495 /* Try to open the profile file, first in $HOME/.wine */
497 /* FIXME: this will need a more general solution */
498 if ((p = getenv( "HOME" )) != NULL)
501 strcat( buffer, "/.wine/" );
502 p = buffer + strlen(buffer);
503 strcpy( p, strrchr( newdos_name, '\\' ) + 1 );
505 if ((file = fopen( buffer, "r" )))
507 TRACE(profile, "(%s): found it in %s\n",
509 CurProfile->unix_name = HEAP_strdupA( SystemHeap, 0, buffer );
515 CurProfile->unix_name = HEAP_strdupA( SystemHeap, 0,
516 full_name.long_name );
517 if ((file = fopen( full_name.long_name, "r" )))
518 TRACE(profile, "(%s): found it in %s\n",
519 filename, full_name.long_name );
524 CurProfile->section = PROFILE_Load( file );
526 if(!stat(CurProfile->unix_name,&buf))
527 CurProfile->mtime=buf.st_mtime;
531 /* Does not exist yet, we will create it in PROFILE_FlushFile */
532 WARN(profile, "profile file %s not found\n", newdos_name );
538 /***********************************************************************
541 * Returns all keys of a section.
542 * If return_values is TRUE, also include the corresponding values.
544 static INT32 PROFILE_GetSection( PROFILESECTION *section, LPCSTR section_name,
545 LPSTR buffer, UINT32 len, BOOL32 handle_env,
546 BOOL32 return_values )
551 if (section->name && !strcasecmp( section->name, section_name ))
554 for (key = section->key; key && *(key->name); key = key->next)
557 if (IS_ENTRY_COMMENT(key->name)) continue; /* Skip comments */
558 PROFILE_CopyEntry( buffer, key->name, len - 1, handle_env );
559 len -= strlen(buffer) + 1;
560 buffer += strlen(buffer) + 1;
561 if (return_values && key->value) {
563 PROFILE_CopyEntry ( buffer,
564 key->value, len - 1, handle_env );
565 len -= strlen(buffer) + 1;
566 buffer += strlen(buffer) + 1;
571 /*If either lpszSection or lpszKey is NULL and the supplied
572 destination buffer is too small to hold all the strings,
573 the last string is truncated and followed by two null characters.
574 In this case, the return value is equal to cchReturnBuffer
582 section = section->next;
584 buffer[0] = buffer[1] = '\0';
589 /***********************************************************************
592 * Get a profile string.
594 static INT32 PROFILE_GetString( LPCSTR section, LPCSTR key_name,
595 LPCSTR def_val, LPSTR buffer, UINT32 len )
597 PROFILEKEY *key = NULL;
599 if (!def_val) def_val = "";
600 if (key_name && key_name[0])
602 key = PROFILE_Find( &CurProfile->section, section, key_name, FALSE );
603 PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val,
605 TRACE(profile, "('%s','%s','%s'): returning '%s'\n",
606 section, key_name, def_val, buffer );
607 return strlen( buffer );
609 return PROFILE_GetSection(CurProfile->section, section, buffer, len,
614 /***********************************************************************
617 * Set a profile string.
619 static BOOL32 PROFILE_SetString( LPCSTR section_name, LPCSTR key_name,
622 if (!key_name) /* Delete a whole section */
624 TRACE(profile, "('%s')\n", section_name);
625 CurProfile->changed |= PROFILE_DeleteSection( &CurProfile->section,
627 return TRUE; /* Even if PROFILE_DeleteSection() has failed,
628 this is not an error on application's level.*/
630 else if (!value) /* Delete a key */
632 TRACE(profile, "('%s','%s')\n",
633 section_name, key_name );
634 CurProfile->changed |= PROFILE_DeleteKey( &CurProfile->section,
635 section_name, key_name );
636 return TRUE; /* same error handling as above */
638 else /* Set the key value */
640 PROFILEKEY *key = PROFILE_Find( &CurProfile->section, section_name,
642 TRACE(profile, "('%s','%s','%s'): \n",
643 section_name, key_name, value );
644 if (!key) return FALSE;
647 if (!strcmp( key->value, value ))
649 TRACE(profile, " no change needed\n" );
650 return TRUE; /* No change needed */
652 TRACE(profile, " replacing '%s'\n", key->value );
653 HeapFree( SystemHeap, 0, key->value );
655 else TRACE(profile, " creating key\n" );
656 key->value = HEAP_strdupA( SystemHeap, 0, value );
657 CurProfile->changed = TRUE;
663 /***********************************************************************
664 * PROFILE_GetWineIniString
666 * Get a config string from the wine.ini file.
668 int PROFILE_GetWineIniString( const char *section, const char *key_name,
669 const char *def, char *buffer, int len )
673 PROFILEKEY *key = PROFILE_Find(&WineProfile, section, key_name, FALSE);
674 PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def,
676 TRACE(profile, "('%s','%s','%s'): returning '%s'\n",
677 section, key_name, def, buffer );
678 return strlen( buffer );
680 return PROFILE_GetSection( WineProfile, section, buffer, len, TRUE, FALSE );
684 /***********************************************************************
685 * PROFILE_GetWineIniInt
687 * Get a config integer from the wine.ini file.
689 int PROFILE_GetWineIniInt( const char *section, const char *key_name, int def )
695 PROFILEKEY *key = PROFILE_Find( &WineProfile, section, key_name, FALSE );
696 if (!key || !key->value) return def;
697 PROFILE_CopyEntry( buffer, key->value, sizeof(buffer), TRUE );
698 result = strtol( buffer, &p, 0 );
699 if (p == buffer) return 0; /* No digits at all */
704 /******************************************************************************
706 * int PROFILE_EnumerateWineIniSection(
707 * char const *section, // Name of the section to enumerate
708 * void (*cbfn)(char const *key, char const *value, void *user),
709 // Address of the callback function
710 * void *user ) // User-specified pointer.
712 * For each entry in a section in the wine.conf file, this function will
713 * call the specified callback function, informing it of each key and
714 * value. An optional user pointer may be passed to it (if this is not
715 * needed, pass NULL through it and ignore the value in the callback
718 * The callback function must accept three parameters:
719 * The name of the key (char const *)
720 * The value of the key (char const *)
721 * A user-specified parameter (void *)
722 * Note that the first two are char CONST *'s, not char *'s! The callback
723 * MUST not modify these strings!
725 * The return value indicates the number of times the callback function
728 int PROFILE_EnumerateWineIniSection(
730 void (*cbfn)(char const *, char const *, void *),
733 PROFILESECTION *scansect;
737 /* Search for the correct section */
738 for(scansect = WineProfile; scansect; scansect = scansect->next) {
739 if(scansect->name && !strcasecmp(scansect->name, section)) {
741 /* Enumerate each key with the callback */
742 for(scankey = scansect->key; scankey; scankey = scankey->next) {
744 /* Ignore blank entries -- these shouldn't exist, but let's
746 if(scankey->name[0]) {
747 cbfn(scankey->name, scankey->value, userptr);
760 /******************************************************************************
762 * int PROFILE_GetWineIniBool(
763 * char const *section,
764 * char const *key_name,
767 * Reads a boolean value from the wine.ini file. This function attempts to
768 * be user-friendly by accepting 'n', 'N' (no), 'f', 'F' (false), or '0'
769 * (zero) for false, 'y', 'Y' (yes), 't', 'T' (true), or '1' (one) for
770 * true. Anything else results in the return of the default value.
772 * This function uses 1 to indicate true, and 0 for false. You can check
773 * for existence by setting def to something other than 0 or 1 and
774 * examining the return value.
776 int PROFILE_GetWineIniBool(
778 char const *key_name,
784 PROFILE_GetWineIniString(section, key_name, "~", key_value, 2);
786 switch(key_value[0]) {
807 TRACE(profile, "(\"%s\", \"%s\", %s), "
808 "[%c], ret %s.\n", section, key_name,
809 def ? "TRUE" : "FALSE", key_value[0],
810 retval ? "TRUE" : "FALSE");
816 /***********************************************************************
817 * PROFILE_LoadWineIni
819 * Load the wine.ini file.
821 int PROFILE_LoadWineIni(void)
823 char buffer[MAX_PATHNAME_LEN];
827 if ( (p = getenv( "WINE_INI" )) && (f = fopen( p, "r" )) )
829 WineProfile = PROFILE_Load( f );
833 if ((p = getenv( "HOME" )) != NULL)
835 lstrcpyn32A(buffer, p, MAX_PATHNAME_LEN - sizeof(PROFILE_WineIniName));
836 strcat( buffer, PROFILE_WineIniName );
837 if ((f = fopen( buffer, "r" )) != NULL)
839 WineProfile = PROFILE_Load( f );
844 else WARN(profile, "could not get $HOME value for config file.\n" );
846 /* Try global file */
848 if ((f = fopen( WINE_INI_GLOBAL, "r" )) != NULL)
850 WineProfile = PROFILE_Load( f );
854 MSG( "Can't open configuration file %s or $HOME%s\n",
855 WINE_INI_GLOBAL, PROFILE_WineIniName );
860 /***********************************************************************
861 * PROFILE_GetStringItem
863 * Convenience function that turns a string 'xxx, yyy, zzz' into
864 * the 'xxx\0 yyy, zzz' and returns a pointer to the 'yyy, zzz'.
866 char* PROFILE_GetStringItem( char* start )
870 for (lpchX = start, lpch = NULL; *lpchX != '\0'; lpchX++ )
874 if( lpch ) *lpch = '\0'; else *lpchX = '\0';
876 if( !PROFILE_isspace(*lpchX) ) return lpchX;
878 else if( PROFILE_isspace( *lpchX ) && !lpch ) lpch = lpchX;
881 if( lpch ) *lpch = '\0';
886 /********************* API functions **********************************/
888 /***********************************************************************
889 * GetProfileInt16 (KERNEL.57)
891 UINT16 WINAPI GetProfileInt16( LPCSTR section, LPCSTR entry, INT16 def_val )
893 return GetPrivateProfileInt16( section, entry, def_val, "win.ini" );
897 /***********************************************************************
898 * GetProfileInt32A (KERNEL32.264)
900 UINT32 WINAPI GetProfileInt32A( LPCSTR section, LPCSTR entry, INT32 def_val )
902 return GetPrivateProfileInt32A( section, entry, def_val, "win.ini" );
905 /***********************************************************************
906 * GetProfileInt32W (KERNEL32.264)
908 UINT32 WINAPI GetProfileInt32W( LPCWSTR section, LPCWSTR entry, INT32 def_val )
910 if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
911 return GetPrivateProfileInt32W( section, entry, def_val, wininiW );
914 /***********************************************************************
915 * GetProfileString16 (KERNEL.58)
917 INT16 WINAPI GetProfileString16( LPCSTR section, LPCSTR entry, LPCSTR def_val,
918 LPSTR buffer, UINT16 len )
920 return GetPrivateProfileString16( section, entry, def_val,
921 buffer, len, "win.ini" );
924 /***********************************************************************
925 * GetProfileString32A (KERNEL32.268)
927 INT32 WINAPI GetProfileString32A( LPCSTR section, LPCSTR entry, LPCSTR def_val,
928 LPSTR buffer, UINT32 len )
930 return GetPrivateProfileString32A( section, entry, def_val,
931 buffer, len, "win.ini" );
934 /***********************************************************************
935 * GetProfileString32W (KERNEL32.269)
937 INT32 WINAPI GetProfileString32W( LPCWSTR section, LPCWSTR entry,
938 LPCWSTR def_val, LPWSTR buffer, UINT32 len )
940 if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
941 return GetPrivateProfileString32W( section, entry, def_val,
942 buffer, len, wininiW );
945 /***********************************************************************
946 * GetProfileSection32A (KERNEL32.268)
948 INT32 WINAPI GetProfileSection32A( LPCSTR section, LPSTR buffer, UINT32 len )
950 return GetPrivateProfileSection32A( section, buffer, len, "win.ini" );
954 /***********************************************************************
955 * WriteProfileString16 (KERNEL.59)
957 BOOL16 WINAPI WriteProfileString16( LPCSTR section, LPCSTR entry,
960 return WritePrivateProfileString16( section, entry, string, "win.ini" );
963 /***********************************************************************
964 * WriteProfileString32A (KERNEL32.587)
966 BOOL32 WINAPI WriteProfileString32A( LPCSTR section, LPCSTR entry,
969 return WritePrivateProfileString32A( section, entry, string, "win.ini" );
972 /***********************************************************************
973 * WriteProfileString32W (KERNEL32.588)
975 BOOL32 WINAPI WriteProfileString32W( LPCWSTR section, LPCWSTR entry,
978 if (!wininiW) wininiW = HEAP_strdupAtoW( SystemHeap, 0, "win.ini" );
979 return WritePrivateProfileString32W( section, entry, string, wininiW );
983 /***********************************************************************
984 * GetPrivateProfileInt16 (KERNEL.127)
986 UINT16 WINAPI GetPrivateProfileInt16( LPCSTR section, LPCSTR entry,
987 INT16 def_val, LPCSTR filename )
989 long result=(long)GetPrivateProfileInt32A(section,entry,def_val,filename);
991 if (result > 65535) return 65535;
992 if (result >= 0) return (UINT16)result;
993 if (result < -32768) return -32768;
994 return (UINT16)(INT16)result;
997 /***********************************************************************
998 * GetPrivateProfileInt32A (KERNEL32.251)
1000 UINT32 WINAPI GetPrivateProfileInt32A( LPCSTR section, LPCSTR entry,
1001 INT32 def_val, LPCSTR filename )
1007 GetPrivateProfileString32A( section, entry, "",
1008 buffer, sizeof(buffer), filename );
1009 if (!buffer[0]) return (UINT32)def_val;
1010 result = strtol( buffer, &p, 0 );
1011 if (p == buffer) return 0; /* No digits at all */
1012 return (UINT32)result;
1015 /***********************************************************************
1016 * GetPrivateProfileInt32W (KERNEL32.252)
1018 UINT32 WINAPI GetPrivateProfileInt32W( LPCWSTR section, LPCWSTR entry,
1019 INT32 def_val, LPCWSTR filename )
1021 LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
1022 LPSTR entryA = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
1023 LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
1024 UINT32 res = GetPrivateProfileInt32A(sectionA, entryA, def_val, filenameA);
1025 HeapFree( GetProcessHeap(), 0, sectionA );
1026 HeapFree( GetProcessHeap(), 0, filenameA );
1027 HeapFree( GetProcessHeap(), 0, entryA );
1031 /***********************************************************************
1032 * GetPrivateProfileString16 (KERNEL.128)
1034 INT16 WINAPI GetPrivateProfileString16( LPCSTR section, LPCSTR entry,
1035 LPCSTR def_val, LPSTR buffer,
1036 UINT16 len, LPCSTR filename )
1038 return GetPrivateProfileString32A(section,entry,def_val,buffer,len,filename);
1041 /***********************************************************************
1042 * GetPrivateProfileString32A (KERNEL32.255)
1044 INT32 WINAPI GetPrivateProfileString32A( LPCSTR section, LPCSTR entry,
1045 LPCSTR def_val, LPSTR buffer,
1046 UINT32 len, LPCSTR filename )
1049 filename = "win.ini";
1050 if (PROFILE_Open( filename ))
1051 return PROFILE_GetString( section, entry, def_val, buffer, len );
1052 lstrcpyn32A( buffer, def_val, len );
1053 return strlen( buffer );
1056 /***********************************************************************
1057 * GetPrivateProfileString32W (KERNEL32.256)
1059 INT32 WINAPI GetPrivateProfileString32W( LPCWSTR section, LPCWSTR entry,
1060 LPCWSTR def_val, LPWSTR buffer,
1061 UINT32 len, LPCWSTR filename )
1063 LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
1064 LPSTR entryA = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
1065 LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
1066 LPSTR def_valA = HEAP_strdupWtoA( GetProcessHeap(), 0, def_val );
1067 LPSTR bufferA = HeapAlloc( GetProcessHeap(), 0, len );
1068 INT32 ret = GetPrivateProfileString32A( sectionA, entryA, def_valA,
1069 bufferA, len, filenameA );
1070 lstrcpynAtoW( buffer, bufferA, len );
1071 HeapFree( GetProcessHeap(), 0, sectionA );
1072 HeapFree( GetProcessHeap(), 0, entryA );
1073 HeapFree( GetProcessHeap(), 0, filenameA );
1074 HeapFree( GetProcessHeap(), 0, def_valA );
1075 HeapFree( GetProcessHeap(), 0, bufferA);
1079 /***********************************************************************
1080 * GetPrivateProfileSection32A (KERNEL32.255)
1082 INT32 WINAPI GetPrivateProfileSection32A( LPCSTR section, LPSTR buffer,
1083 UINT32 len, LPCSTR filename )
1085 if (PROFILE_Open( filename ))
1086 return PROFILE_GetSection(CurProfile->section, section, buffer, len,
1092 /***********************************************************************
1093 * WritePrivateProfileString16 (KERNEL.129)
1095 BOOL16 WINAPI WritePrivateProfileString16( LPCSTR section, LPCSTR entry,
1096 LPCSTR string, LPCSTR filename )
1098 return WritePrivateProfileString32A(section,entry,string,filename);
1101 /***********************************************************************
1102 * WritePrivateProfileString32A (KERNEL32.582)
1104 BOOL32 WINAPI WritePrivateProfileString32A( LPCSTR section, LPCSTR entry,
1105 LPCSTR string, LPCSTR filename )
1107 if (!PROFILE_Open( filename )) return FALSE;
1108 if (!section) return PROFILE_FlushFile();
1109 return PROFILE_SetString( section, entry, string );
1112 /***********************************************************************
1113 * WritePrivateProfileString32W (KERNEL32.583)
1115 BOOL32 WINAPI WritePrivateProfileString32W( LPCWSTR section, LPCWSTR entry,
1116 LPCWSTR string, LPCWSTR filename )
1118 LPSTR sectionA = HEAP_strdupWtoA( GetProcessHeap(), 0, section );
1119 LPSTR entryA = HEAP_strdupWtoA( GetProcessHeap(), 0, entry );
1120 LPSTR stringA = HEAP_strdupWtoA( GetProcessHeap(), 0, string );
1121 LPSTR filenameA = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
1122 BOOL32 res = WritePrivateProfileString32A( sectionA, entryA,
1123 stringA, filenameA );
1124 HeapFree( GetProcessHeap(), 0, sectionA );
1125 HeapFree( GetProcessHeap(), 0, entryA );
1126 HeapFree( GetProcessHeap(), 0, stringA );
1127 HeapFree( GetProcessHeap(), 0, filenameA );
1131 /***********************************************************************
1132 * WritePrivateProfileSection32A (KERNEL32)
1134 BOOL32 WINAPI WritePrivateProfileSection32A( LPCSTR section,
1135 LPCSTR string, LPCSTR filename )
1137 char *p =(char*)string;
1139 FIXME(profile, "WritePrivateProfileSection32A empty stup\n");
1140 if (TRACE_ON(profile)) {
1141 TRACE(profile, "(%s) => [%s]\n", filename, section);
1143 TRACE(profile, "%s\n", p);
1152 /***********************************************************************
1153 * GetPrivateProfileSectionNames16 (KERNEL.143)
1155 WORD WINAPI GetPrivateProfileSectionNames16( LPSTR buffer, WORD size,
1160 PROFILESECTION *section;
1162 if (PROFILE_Open( filename )) {
1165 section=CurProfile->section;
1166 for ( ; section; section = section->next)
1167 if (section->name) {
1168 l=strlen (section->name);
1170 if (cursize > size+1)
1172 strcpy (buf,section->name);
1179 return (buf-buffer);
1186 /***********************************************************************
1187 * GetPrivateProfileStruct32A (KERNEL32.370)
1189 WORD WINAPI GetPrivateProfileStruct32A (LPCSTR section, LPCSTR key,
1190 LPVOID buf, UINT32 len, LPCSTR filename)
1194 if (PROFILE_Open( filename )) {
1195 k=PROFILE_Find ( &CurProfile->section, section, key, FALSE);
1196 if (!k) return FALSE;
1197 lstrcpyn32A( buf, k->value, strlen(k->value));
1204 /***********************************************************************
1205 * WritePrivateProfileStruct32A (KERNEL32.744)
1207 WORD WINAPI WritePrivateProfileStruct32A (LPCSTR section, LPCSTR key,
1208 LPVOID buf, UINT32 bufsize, LPCSTR filename)
1210 if ((!section) && (!key) && (!buf)) { /* flush the cache */
1211 PROFILE_FlushFile();
1215 if (!PROFILE_Open( filename )) return FALSE;
1216 return PROFILE_SetString( section, key, buf);
1220 /***********************************************************************
1221 * WriteOutProfiles (KERNEL.315)
1223 void WINAPI WriteOutProfiles(void)
1225 PROFILE_FlushFile();