4 * Copyright 1993 Miguel de Icaza
5 * Copyright 1996 Alexandre Julliard
20 typedef struct tagPROFILEKEY
24 struct tagPROFILEKEY
*next
;
27 typedef struct tagPROFILESECTION
30 struct tagPROFILEKEY
*key
;
31 struct tagPROFILESECTION
*next
;
38 PROFILESECTION
*section
;
46 #define N_CACHED_PROFILES 10
48 /* Cached profile files */
49 static PROFILE
*MRUProfile
[N_CACHED_PROFILES
]={NULL
};
51 #define CurProfile (MRUProfile[0])
53 /* wine.ini profile content */
54 static PROFILESECTION
*WineProfile
;
56 #define PROFILE_MAX_LINE_LEN 1024
58 /* Wine profile name in $HOME directory; must begin with slash */
59 static const char PROFILE_WineIniName
[] = "/.winerc";
61 /* Wine profile: the profile file being used */
62 static char PROFILE_WineIniUsed
[MAX_PATHNAME_LEN
] = "";
64 /* Check for comments in profile */
65 #define IS_ENTRY_COMMENT(str) ((str)[0] == ';')
67 #define WINE_INI_GLOBAL ETCDIR "/wine.conf"
69 static LPCWSTR wininiW
= NULL
;
71 /***********************************************************************
74 * Copy the content of an entry into a buffer, removing quotes, and possibly
75 * translating environment variables.
77 static void PROFILE_CopyEntry( char *buffer
, const char *value
, int len
,
83 if ((*value
== '\'') || (*value
== '\"'))
85 if (value
[1] && (value
[strlen(value
)-1] == *value
)) quote
= *value
++;
90 lstrcpyn32A( buffer
, value
, len
);
91 if (quote
&& (len
>= strlen(value
))) buffer
[strlen(buffer
)-1] = '\0';
95 for (p
= value
; (*p
&& (len
> 1)); *buffer
++ = *p
++, len
-- )
97 if ((*p
== '$') && (p
[1] == '{'))
101 const char *p2
= strchr( p
, '}' );
102 if (!p2
) continue; /* ignore it */
103 lstrcpyn32A(env_val
, p
+ 2, MIN( sizeof(env_val
), (int)(p2
-p
)-1 ));
104 if ((env_p
= getenv( env_val
)) != NULL
)
106 lstrcpyn32A( buffer
, env_p
, len
);
107 buffer
+= strlen( buffer
);
108 len
-= strlen( buffer
);
117 /***********************************************************************
120 * Save a profile tree to a file.
122 static void PROFILE_Save( FILE *file
, PROFILESECTION
*section
)
126 for ( ; section
; section
= section
->next
)
128 if (section
->name
) fprintf( file
, "\r\n[%s]\r\n", section
->name
);
129 for (key
= section
->key
; key
; key
= key
->next
)
131 fprintf( file
, "%s", key
->name
);
132 if (key
->value
) fprintf( file
, "=%s", key
->value
);
133 fprintf( file
, "\r\n" );
139 /***********************************************************************
142 * Free a profile tree.
144 static void PROFILE_Free( PROFILESECTION
*section
)
146 PROFILESECTION
*next_section
;
147 PROFILEKEY
*key
, *next_key
;
149 for ( ; section
; section
= next_section
)
151 if (section
->name
) HeapFree( SystemHeap
, 0, section
->name
);
152 for (key
= section
->key
; key
; key
= next_key
)
154 next_key
= key
->next
;
155 if (key
->name
) HeapFree( SystemHeap
, 0, key
->name
);
156 if (key
->value
) HeapFree( SystemHeap
, 0, key
->value
);
157 HeapFree( SystemHeap
, 0, key
);
159 next_section
= section
->next
;
160 HeapFree( SystemHeap
, 0, section
);
165 PROFILE_isspace(char c
) {
166 if (isspace(c
)) return 1;
167 if (c
=='\r' || c
==0x1a) return 1;
168 /* CR and ^Z (DOS EOF) are spaces too (found on CD-ROMs) */
173 /***********************************************************************
176 * Load a profile tree from a file.
178 static PROFILESECTION
*PROFILE_Load( FILE *file
)
180 char buffer
[PROFILE_MAX_LINE_LEN
];
183 PROFILESECTION
*section
, *first_section
;
184 PROFILESECTION
**next_section
;
185 PROFILEKEY
*key
, *prev_key
, **next_key
;
187 first_section
= HEAP_xalloc( SystemHeap
, 0, sizeof(*section
) );
188 first_section
->name
= NULL
;
189 first_section
->key
= NULL
;
190 first_section
->next
= NULL
;
191 next_section
= &first_section
->next
;
192 next_key
= &first_section
->key
;
195 while (fgets( buffer
, PROFILE_MAX_LINE_LEN
, file
))
199 while (*p
&& PROFILE_isspace(*p
)) p
++;
200 if (*p
== '[') /* section start */
202 if (!(p2
= strrchr( p
, ']' )))
204 WARN(profile
, "Invalid section header at line %d: '%s'\n",
211 section
= HEAP_xalloc( SystemHeap
, 0, sizeof(*section
) );
212 section
->name
= HEAP_strdupA( SystemHeap
, 0, p
);
214 section
->next
= NULL
;
215 *next_section
= section
;
216 next_section
= §ion
->next
;
217 next_key
= §ion
->key
;
220 TRACE(profile
, "New section: '%s'\n",section
->name
);
227 while ((p2
> p
) && ((*p2
== '\n') || PROFILE_isspace(*p2
))) *p2
--='\0';
229 if ((p2
= strchr( p
, '=' )) != NULL
)
232 while ((p3
> p
) && PROFILE_isspace(*p3
)) *p3
-- = '\0';
234 while (*p2
&& PROFILE_isspace(*p2
)) p2
++;
237 if(*p
|| !prev_key
|| *prev_key
->name
)
239 key
= HEAP_xalloc( SystemHeap
, 0, sizeof(*key
) );
240 key
->name
= HEAP_strdupA( SystemHeap
, 0, p
);
241 key
->value
= p2
? HEAP_strdupA( SystemHeap
, 0, p2
) : NULL
;
244 next_key
= &key
->next
;
247 TRACE(profile
, "New key: name='%s', value='%s'\n",key
->name
,key
->value
?key
->value
:"(none)");
250 return first_section
;
254 /***********************************************************************
255 * PROFILE_DeleteSection
257 * Delete a section from a profile tree.
259 static BOOL32
PROFILE_DeleteSection( PROFILESECTION
**section
, LPCSTR name
)
263 if ((*section
)->name
&& !strcasecmp( (*section
)->name
, name
))
265 PROFILESECTION
*to_del
= *section
;
266 *section
= to_del
->next
;
268 PROFILE_Free( to_del
);
271 section
= &(*section
)->next
;
277 /***********************************************************************
280 * Delete a key from a profile tree.
282 static BOOL32
PROFILE_DeleteKey( PROFILESECTION
**section
,
283 LPCSTR section_name
, LPCSTR key_name
)
287 if ((*section
)->name
&& !strcasecmp( (*section
)->name
, section_name
))
289 PROFILEKEY
**key
= &(*section
)->key
;
292 if (!strcasecmp( (*key
)->name
, key_name
))
294 PROFILEKEY
*to_del
= *key
;
296 if (to_del
->name
) HeapFree( SystemHeap
, 0, to_del
->name
);
297 if (to_del
->value
) HeapFree( SystemHeap
, 0, to_del
->value
);
298 HeapFree( SystemHeap
, 0, to_del
);
304 section
= &(*section
)->next
;
310 /***********************************************************************
313 * Find a key in a profile tree, optionally creating it.
315 static PROFILEKEY
*PROFILE_Find( PROFILESECTION
**section
,
316 const char *section_name
,
317 const char *key_name
, int create
)
321 if ((*section
)->name
&& !strcasecmp( (*section
)->name
, section_name
))
323 PROFILEKEY
**key
= &(*section
)->key
;
326 if (!strcasecmp( (*key
)->name
, key_name
)) return *key
;
329 if (!create
) return NULL
;
330 *key
= HEAP_xalloc( SystemHeap
, 0, sizeof(PROFILEKEY
) );
331 (*key
)->name
= HEAP_strdupA( SystemHeap
, 0, key_name
);
332 (*key
)->value
= NULL
;
336 section
= &(*section
)->next
;
338 if (!create
) return NULL
;
339 *section
= HEAP_xalloc( SystemHeap
, 0, sizeof(PROFILESECTION
) );
340 (*section
)->name
= HEAP_strdupA( SystemHeap
, 0, section_name
);
341 (*section
)->next
= NULL
;
342 (*section
)->key
= HEAP_xalloc( SystemHeap
, 0, sizeof(PROFILEKEY
) );
343 (*section
)->key
->name
= HEAP_strdupA( SystemHeap
, 0, key_name
);
344 (*section
)->key
->value
= NULL
;
345 (*section
)->key
->next
= NULL
;
346 return (*section
)->key
;
350 /***********************************************************************
353 * Flush the current profile to disk if changed.
355 static BOOL32
PROFILE_FlushFile(void)
357 char *p
, buffer
[MAX_PATHNAME_LEN
];
358 const char *unix_name
;
364 WARN(profile
, "No current profile!\n");
368 if (!CurProfile
->changed
|| !CurProfile
->dos_name
) return TRUE
;
369 if (!(unix_name
= CurProfile
->unix_name
) || !(file
= fopen(unix_name
, "w")))
371 /* Try to create it in $HOME/.wine */
372 /* FIXME: this will need a more general solution */
373 if ((p
= getenv( "HOME" )) != NULL
)
376 strcat( buffer
, "/.wine/" );
377 p
= buffer
+ strlen(buffer
);
378 strcpy( p
, strrchr( CurProfile
->dos_name
, '\\' ) + 1 );
380 file
= fopen( buffer
, "w" );
387 WARN(profile
, "could not save profile file %s\n", CurProfile
->dos_name
);
391 TRACE(profile
, "Saving '%s' into '%s'\n", CurProfile
->dos_name
, unix_name
);
392 PROFILE_Save( file
, CurProfile
->section
);
394 CurProfile
->changed
= FALSE
;
395 if(!stat(unix_name
,&buf
))
396 CurProfile
->mtime
=buf
.st_mtime
;
401 /***********************************************************************
404 * Open a profile file, checking the cached file first.
406 static BOOL32
PROFILE_Open( LPCSTR filename
)
408 DOS_FULL_NAME full_name
;
409 char buffer
[MAX_PATHNAME_LEN
];
410 char *newdos_name
, *p
;
414 PROFILE
*tempProfile
;
416 /* First time around */
419 for(i
=0;i
<N_CACHED_PROFILES
;i
++)
421 MRUProfile
[i
]=HEAP_xalloc( SystemHeap
, 0, sizeof(PROFILE
) );
422 MRUProfile
[i
]->changed
=FALSE
;
423 MRUProfile
[i
]->section
=NULL
;
424 MRUProfile
[i
]->dos_name
=NULL
;
425 MRUProfile
[i
]->unix_name
=NULL
;
426 MRUProfile
[i
]->filename
=NULL
;
427 MRUProfile
[i
]->mtime
=0;
430 /* Check for a match */
432 if (strchr( filename
, '/' ) || strchr( filename
, '\\' ) ||
433 strchr( filename
, ':' ))
435 if (!DOSFS_GetFullName( filename
, FALSE
, &full_name
)) return FALSE
;
439 GetWindowsDirectory32A( buffer
, sizeof(buffer
) );
440 strcat( buffer
, "\\" );
441 strcat( buffer
, filename
);
442 if (!DOSFS_GetFullName( buffer
, FALSE
, &full_name
)) return FALSE
;
445 for(i
=0;i
<N_CACHED_PROFILES
;i
++)
447 if ((MRUProfile
[i
]->filename
&& !strcmp( filename
, MRUProfile
[i
]->filename
)) ||
448 (MRUProfile
[i
]->dos_name
&& !strcmp( full_name
.short_name
, MRUProfile
[i
]->dos_name
)))
453 tempProfile
=MRUProfile
[i
];
455 MRUProfile
[j
]=MRUProfile
[j
-1];
456 CurProfile
=tempProfile
;
458 if(!stat(CurProfile
->unix_name
,&buf
) && CurProfile
->mtime
==buf
.st_mtime
)
459 TRACE(profile
, "(%s): already opened (mru=%d)\n",
462 TRACE(profile
, "(%s): already opened, needs refreshing (mru=%d)\n",
468 /* Rotate the oldest to the top to be replaced */
470 if(i
==N_CACHED_PROFILES
)
472 tempProfile
=MRUProfile
[N_CACHED_PROFILES
-1];
473 for(i
=N_CACHED_PROFILES
-1;i
>0;i
--)
474 MRUProfile
[i
]=MRUProfile
[i
-1];
475 CurProfile
=tempProfile
;
478 /* Flush the profile */
480 if(CurProfile
->filename
)
483 PROFILE_Free( CurProfile
->section
);
484 if (CurProfile
->dos_name
) HeapFree( SystemHeap
, 0, CurProfile
->dos_name
);
485 if (CurProfile
->unix_name
) HeapFree( SystemHeap
, 0, CurProfile
->unix_name
);
486 if (CurProfile
->filename
) HeapFree( SystemHeap
, 0, CurProfile
->filename
);
487 CurProfile
->changed
=FALSE
;
488 CurProfile
->section
=NULL
;
489 CurProfile
->dos_name
=NULL
;
490 CurProfile
->unix_name
=NULL
;
491 CurProfile
->filename
=NULL
;
495 newdos_name
= HEAP_strdupA( SystemHeap
, 0, full_name
.short_name
);
496 CurProfile
->dos_name
= newdos_name
;
497 CurProfile
->filename
= HEAP_strdupA( SystemHeap
, 0, filename
);
499 /* Try to open the profile file, first in $HOME/.wine */
501 /* FIXME: this will need a more general solution */
502 if ((p
= getenv( "HOME" )) != NULL
)
505 strcat( buffer
, "/.wine/" );
506 p
= buffer
+ strlen(buffer
);
507 strcpy( p
, strrchr( newdos_name
, '\\' ) + 1 );
509 if ((file
= fopen( buffer
, "r" )))
511 TRACE(profile
, "(%s): found it in %s\n",
513 CurProfile
->unix_name
= HEAP_strdupA( SystemHeap
, 0, buffer
);
519 CurProfile
->unix_name
= HEAP_strdupA( SystemHeap
, 0,
520 full_name
.long_name
);
521 if ((file
= fopen( full_name
.long_name
, "r" )))
522 TRACE(profile
, "(%s): found it in %s\n",
523 filename
, full_name
.long_name
);
528 CurProfile
->section
= PROFILE_Load( file
);
530 if(!stat(CurProfile
->unix_name
,&buf
))
531 CurProfile
->mtime
=buf
.st_mtime
;
535 /* Does not exist yet, we will create it in PROFILE_FlushFile */
536 WARN(profile
, "profile file %s not found\n", newdos_name
);
542 /***********************************************************************
545 * Returns all keys of a section.
546 * If return_values is TRUE, also include the corresponding values.
548 static INT32
PROFILE_GetSection( PROFILESECTION
*section
, LPCSTR section_name
,
549 LPSTR buffer
, UINT32 len
, BOOL32 handle_env
,
550 BOOL32 return_values
)
555 if (section
->name
&& !strcasecmp( section
->name
, section_name
))
558 for (key
= section
->key
; key
&& *(key
->name
); key
= key
->next
)
561 if (IS_ENTRY_COMMENT(key
->name
)) continue; /* Skip comments */
562 PROFILE_CopyEntry( buffer
, key
->name
, len
- 1, handle_env
);
563 len
-= strlen(buffer
) + 1;
564 buffer
+= strlen(buffer
) + 1;
565 if (return_values
&& key
->value
) {
567 PROFILE_CopyEntry ( buffer
,
568 key
->value
, len
- 1, handle_env
);
569 len
-= strlen(buffer
) + 1;
570 buffer
+= strlen(buffer
) + 1;
575 /*If either lpszSection or lpszKey is NULL and the supplied
576 destination buffer is too small to hold all the strings,
577 the last string is truncated and followed by two null characters.
578 In this case, the return value is equal to cchReturnBuffer
586 section
= section
->next
;
588 buffer
[0] = buffer
[1] = '\0';
593 /***********************************************************************
596 * Get a profile string.
598 static INT32
PROFILE_GetString( LPCSTR section
, LPCSTR key_name
,
599 LPCSTR def_val
, LPSTR buffer
, UINT32 len
)
601 PROFILEKEY
*key
= NULL
;
603 if (!def_val
) def_val
= "";
604 if (key_name
&& key_name
[0])
606 key
= PROFILE_Find( &CurProfile
->section
, section
, key_name
, FALSE
);
607 PROFILE_CopyEntry( buffer
, (key
&& key
->value
) ? key
->value
: def_val
,
609 TRACE(profile
, "('%s','%s','%s'): returning '%s'\n",
610 section
, key_name
, def_val
, buffer
);
611 return strlen( buffer
);
613 return PROFILE_GetSection(CurProfile
->section
, section
, buffer
, len
,
618 /***********************************************************************
621 * Set a profile string.
623 static BOOL32
PROFILE_SetString( LPCSTR section_name
, LPCSTR key_name
,
626 if (!key_name
) /* Delete a whole section */
628 TRACE(profile
, "('%s')\n", section_name
);
629 CurProfile
->changed
|= PROFILE_DeleteSection( &CurProfile
->section
,
631 return TRUE
; /* Even if PROFILE_DeleteSection() has failed,
632 this is not an error on application's level.*/
634 else if (!value
) /* Delete a key */
636 TRACE(profile
, "('%s','%s')\n",
637 section_name
, key_name
);
638 CurProfile
->changed
|= PROFILE_DeleteKey( &CurProfile
->section
,
639 section_name
, key_name
);
640 return TRUE
; /* same error handling as above */
642 else /* Set the key value */
644 PROFILEKEY
*key
= PROFILE_Find( &CurProfile
->section
, section_name
,
646 TRACE(profile
, "('%s','%s','%s'): \n",
647 section_name
, key_name
, value
);
648 if (!key
) return FALSE
;
651 if (!strcmp( key
->value
, value
))
653 TRACE(profile
, " no change needed\n" );
654 return TRUE
; /* No change needed */
656 TRACE(profile
, " replacing '%s'\n", key
->value
);
657 HeapFree( SystemHeap
, 0, key
->value
);
659 else TRACE(profile
, " creating key\n" );
660 key
->value
= HEAP_strdupA( SystemHeap
, 0, value
);
661 CurProfile
->changed
= TRUE
;
667 /***********************************************************************
668 * PROFILE_GetWineIniString
670 * Get a config string from the wine.ini file.
672 int PROFILE_GetWineIniString( const char *section
, const char *key_name
,
673 const char *def
, char *buffer
, int len
)
677 PROFILEKEY
*key
= PROFILE_Find(&WineProfile
, section
, key_name
, FALSE
);
678 PROFILE_CopyEntry( buffer
, (key
&& key
->value
) ? key
->value
: def
,
680 TRACE(profile
, "('%s','%s','%s'): returning '%s'\n",
681 section
, key_name
, def
, buffer
);
682 return strlen( buffer
);
684 return PROFILE_GetSection( WineProfile
, section
, buffer
, len
, TRUE
, FALSE
);
688 /***********************************************************************
689 * PROFILE_GetWineIniInt
691 * Get a config integer from the wine.ini file.
693 int PROFILE_GetWineIniInt( const char *section
, const char *key_name
, int def
)
699 PROFILEKEY
*key
= PROFILE_Find( &WineProfile
, section
, key_name
, FALSE
);
700 if (!key
|| !key
->value
) return def
;
701 PROFILE_CopyEntry( buffer
, key
->value
, sizeof(buffer
), TRUE
);
702 result
= strtol( buffer
, &p
, 0 );
703 if (p
== buffer
) return 0; /* No digits at all */
708 /******************************************************************************
710 * int PROFILE_EnumerateWineIniSection(
711 * char const *section, // Name of the section to enumerate
712 * void (*cbfn)(char const *key, char const *value, void *user),
713 // Address of the callback function
714 * void *user ) // User-specified pointer.
716 * For each entry in a section in the wine.conf file, this function will
717 * call the specified callback function, informing it of each key and
718 * value. An optional user pointer may be passed to it (if this is not
719 * needed, pass NULL through it and ignore the value in the callback
722 * The callback function must accept three parameters:
723 * The name of the key (char const *)
724 * The value of the key (char const *)
725 * A user-specified parameter (void *)
726 * Note that the first two are char CONST *'s, not char *'s! The callback
727 * MUST not modify these strings!
729 * The return value indicates the number of times the callback function
732 int PROFILE_EnumerateWineIniSection(
734 void (*cbfn
)(char const *, char const *, void *),
737 PROFILESECTION
*scansect
;
741 /* Search for the correct section */
742 for(scansect
= WineProfile
; scansect
; scansect
= scansect
->next
) {
743 if(scansect
->name
&& !strcasecmp(scansect
->name
, section
)) {
745 /* Enumerate each key with the callback */
746 for(scankey
= scansect
->key
; scankey
; scankey
= scankey
->next
) {
748 /* Ignore blank entries -- these shouldn't exist, but let's
750 if(scankey
->name
[0]) {
751 cbfn(scankey
->name
, scankey
->value
, userptr
);
764 /******************************************************************************
766 * int PROFILE_GetWineIniBool(
767 * char const *section,
768 * char const *key_name,
771 * Reads a boolean value from the wine.ini file. This function attempts to
772 * be user-friendly by accepting 'n', 'N' (no), 'f', 'F' (false), or '0'
773 * (zero) for false, 'y', 'Y' (yes), 't', 'T' (true), or '1' (one) for
774 * true. Anything else results in the return of the default value.
776 * This function uses 1 to indicate true, and 0 for false. You can check
777 * for existence by setting def to something other than 0 or 1 and
778 * examining the return value.
780 int PROFILE_GetWineIniBool(
782 char const *key_name
,
788 PROFILE_GetWineIniString(section
, key_name
, "~", key_value
, 2);
790 switch(key_value
[0]) {
811 TRACE(profile
, "(\"%s\", \"%s\", %s), "
812 "[%c], ret %s.\n", section
, key_name
,
813 def
? "TRUE" : "FALSE", key_value
[0],
814 retval
? "TRUE" : "FALSE");
820 /***********************************************************************
821 * PROFILE_LoadWineIni
823 * Load the wine.ini file.
825 int PROFILE_LoadWineIni(void)
827 char buffer
[MAX_PATHNAME_LEN
];
831 if ( (Options
.configFileName
!=NULL
) && (f
= fopen(Options
.configFileName
, "r")) )
833 /* Open -config specified file */
834 WineProfile
= PROFILE_Load ( f
);
836 strncpy(PROFILE_WineIniUsed
,Options
.configFileName
,MAX_PATHNAME_LEN
-1);
840 if ( (p
= getenv( "WINE_INI" )) && (f
= fopen( p
, "r" )) )
842 WineProfile
= PROFILE_Load( f
);
844 strncpy(PROFILE_WineIniUsed
,p
,MAX_PATHNAME_LEN
-1);
847 if ((p
= getenv( "HOME" )) != NULL
)
849 lstrcpyn32A(buffer
, p
, MAX_PATHNAME_LEN
- sizeof(PROFILE_WineIniName
));
850 strcat( buffer
, PROFILE_WineIniName
);
851 if ((f
= fopen( buffer
, "r" )) != NULL
)
853 WineProfile
= PROFILE_Load( f
);
855 strncpy(PROFILE_WineIniUsed
,buffer
,MAX_PATHNAME_LEN
-1);
859 else WARN(profile
, "could not get $HOME value for config file.\n" );
861 /* Try global file */
863 if ((f
= fopen( WINE_INI_GLOBAL
, "r" )) != NULL
)
865 WineProfile
= PROFILE_Load( f
);
867 strncpy(PROFILE_WineIniUsed
,WINE_INI_GLOBAL
,MAX_PATHNAME_LEN
-1);
870 MSG( "Can't open configuration file %s or $HOME%s\n",
871 WINE_INI_GLOBAL
, PROFILE_WineIniName
);
876 /***********************************************************************
877 * PROFILE_UsageWineIni
879 * Explain the wine.ini file to those who don't read documentation.
880 * Keep below one screenful in length so that error messages above are
883 void PROFILE_UsageWineIni(void)
885 MSG("Perhaps you have not properly edited or created "
886 "your Wine configuration file.\n");
887 MSG("This is either %s or $HOME%s\n",WINE_INI_GLOBAL
,PROFILE_WineIniName
);
888 MSG(" or it is determined by the -config option or from\n"
889 " the WINE_INI environment variable.\n");
890 if (*PROFILE_WineIniUsed
)
891 MSG("Wine has used %s as configuration file.\n", PROFILE_WineIniUsed
);
892 /* RTFM, so to say */
896 /***********************************************************************
897 * PROFILE_GetStringItem
899 * Convenience function that turns a string 'xxx, yyy, zzz' into
900 * the 'xxx\0 yyy, zzz' and returns a pointer to the 'yyy, zzz'.
902 char* PROFILE_GetStringItem( char* start
)
906 for (lpchX
= start
, lpch
= NULL
; *lpchX
!= '\0'; lpchX
++ )
910 if( lpch
) *lpch
= '\0'; else *lpchX
= '\0';
912 if( !PROFILE_isspace(*lpchX
) ) return lpchX
;
914 else if( PROFILE_isspace( *lpchX
) && !lpch
) lpch
= lpchX
;
917 if( lpch
) *lpch
= '\0';
922 /********************* API functions **********************************/
924 /***********************************************************************
925 * GetProfileInt16 (KERNEL.57)
927 UINT16 WINAPI
GetProfileInt16( LPCSTR section
, LPCSTR entry
, INT16 def_val
)
929 return GetPrivateProfileInt16( section
, entry
, def_val
, "win.ini" );
933 /***********************************************************************
934 * GetProfileInt32A (KERNEL32.264)
936 UINT32 WINAPI
GetProfileInt32A( LPCSTR section
, LPCSTR entry
, INT32 def_val
)
938 return GetPrivateProfileInt32A( section
, entry
, def_val
, "win.ini" );
941 /***********************************************************************
942 * GetProfileInt32W (KERNEL32.264)
944 UINT32 WINAPI
GetProfileInt32W( LPCWSTR section
, LPCWSTR entry
, INT32 def_val
)
946 if (!wininiW
) wininiW
= HEAP_strdupAtoW( SystemHeap
, 0, "win.ini" );
947 return GetPrivateProfileInt32W( section
, entry
, def_val
, wininiW
);
950 /***********************************************************************
951 * GetProfileString16 (KERNEL.58)
953 INT16 WINAPI
GetProfileString16( LPCSTR section
, LPCSTR entry
, LPCSTR def_val
,
954 LPSTR buffer
, UINT16 len
)
956 return GetPrivateProfileString16( section
, entry
, def_val
,
957 buffer
, len
, "win.ini" );
960 /***********************************************************************
961 * GetProfileString32A (KERNEL32.268)
963 INT32 WINAPI
GetProfileString32A( LPCSTR section
, LPCSTR entry
, LPCSTR def_val
,
964 LPSTR buffer
, UINT32 len
)
966 return GetPrivateProfileString32A( section
, entry
, def_val
,
967 buffer
, len
, "win.ini" );
970 /***********************************************************************
971 * GetProfileString32W (KERNEL32.269)
973 INT32 WINAPI
GetProfileString32W( LPCWSTR section
, LPCWSTR entry
,
974 LPCWSTR def_val
, LPWSTR buffer
, UINT32 len
)
976 if (!wininiW
) wininiW
= HEAP_strdupAtoW( SystemHeap
, 0, "win.ini" );
977 return GetPrivateProfileString32W( section
, entry
, def_val
,
978 buffer
, len
, wininiW
);
981 /***********************************************************************
982 * GetProfileSection32A (KERNEL32.268)
984 INT32 WINAPI
GetProfileSection32A( LPCSTR section
, LPSTR buffer
, DWORD len
)
986 return GetPrivateProfileSection32A( section
, buffer
, len
, "win.ini" );
990 /***********************************************************************
991 * GetProfileSection32W (KERNEL32)
993 INT32 WINAPI
GetProfileSection32W( LPCWSTR section
, LPWSTR buffer
, DWORD len
)
995 if (!wininiW
) wininiW
= HEAP_strdupAtoW( SystemHeap
, 0, "win.ini" );
996 return GetPrivateProfileSection32W( section
, buffer
, len
, wininiW
);
1003 /***********************************************************************
1004 * WriteProfileString16 (KERNEL.59)
1006 BOOL16 WINAPI
WriteProfileString16( LPCSTR section
, LPCSTR entry
,
1009 return WritePrivateProfileString16( section
, entry
, string
, "win.ini" );
1012 /***********************************************************************
1013 * WriteProfileString32A (KERNEL32.587)
1015 BOOL32 WINAPI
WriteProfileString32A( LPCSTR section
, LPCSTR entry
,
1018 return WritePrivateProfileString32A( section
, entry
, string
, "win.ini" );
1021 /***********************************************************************
1022 * WriteProfileString32W (KERNEL32.588)
1024 BOOL32 WINAPI
WriteProfileString32W( LPCWSTR section
, LPCWSTR entry
,
1027 if (!wininiW
) wininiW
= HEAP_strdupAtoW( SystemHeap
, 0, "win.ini" );
1028 return WritePrivateProfileString32W( section
, entry
, string
, wininiW
);
1032 /***********************************************************************
1033 * GetPrivateProfileInt16 (KERNEL.127)
1035 UINT16 WINAPI
GetPrivateProfileInt16( LPCSTR section
, LPCSTR entry
,
1036 INT16 def_val
, LPCSTR filename
)
1038 long result
=(long)GetPrivateProfileInt32A(section
,entry
,def_val
,filename
);
1040 if (result
> 65535) return 65535;
1041 if (result
>= 0) return (UINT16
)result
;
1042 if (result
< -32768) return -32768;
1043 return (UINT16
)(INT16
)result
;
1046 /***********************************************************************
1047 * GetPrivateProfileInt32A (KERNEL32.251)
1049 UINT32 WINAPI
GetPrivateProfileInt32A( LPCSTR section
, LPCSTR entry
,
1050 INT32 def_val
, LPCSTR filename
)
1056 GetPrivateProfileString32A( section
, entry
, "",
1057 buffer
, sizeof(buffer
), filename
);
1058 if (!buffer
[0]) return (UINT32
)def_val
;
1059 result
= strtol( buffer
, &p
, 0 );
1060 if (p
== buffer
) return 0; /* No digits at all */
1061 return (UINT32
)result
;
1064 /***********************************************************************
1065 * GetPrivateProfileInt32W (KERNEL32.252)
1067 UINT32 WINAPI
GetPrivateProfileInt32W( LPCWSTR section
, LPCWSTR entry
,
1068 INT32 def_val
, LPCWSTR filename
)
1070 LPSTR sectionA
= HEAP_strdupWtoA( GetProcessHeap(), 0, section
);
1071 LPSTR entryA
= HEAP_strdupWtoA( GetProcessHeap(), 0, entry
);
1072 LPSTR filenameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
1073 UINT32 res
= GetPrivateProfileInt32A(sectionA
, entryA
, def_val
, filenameA
);
1074 HeapFree( GetProcessHeap(), 0, sectionA
);
1075 HeapFree( GetProcessHeap(), 0, filenameA
);
1076 HeapFree( GetProcessHeap(), 0, entryA
);
1080 /***********************************************************************
1081 * GetPrivateProfileString16 (KERNEL.128)
1083 INT16 WINAPI
GetPrivateProfileString16( LPCSTR section
, LPCSTR entry
,
1084 LPCSTR def_val
, LPSTR buffer
,
1085 UINT16 len
, LPCSTR filename
)
1087 return GetPrivateProfileString32A(section
,entry
,def_val
,buffer
,len
,filename
);
1090 /***********************************************************************
1091 * GetPrivateProfileString32A (KERNEL32.255)
1093 INT32 WINAPI
GetPrivateProfileString32A( LPCSTR section
, LPCSTR entry
,
1094 LPCSTR def_val
, LPSTR buffer
,
1095 UINT32 len
, LPCSTR filename
)
1098 filename
= "win.ini";
1099 if (PROFILE_Open( filename
))
1100 return PROFILE_GetString( section
, entry
, def_val
, buffer
, len
);
1101 lstrcpyn32A( buffer
, def_val
, len
);
1102 return strlen( buffer
);
1105 /***********************************************************************
1106 * GetPrivateProfileString32W (KERNEL32.256)
1108 INT32 WINAPI
GetPrivateProfileString32W( LPCWSTR section
, LPCWSTR entry
,
1109 LPCWSTR def_val
, LPWSTR buffer
,
1110 UINT32 len
, LPCWSTR filename
)
1112 LPSTR sectionA
= HEAP_strdupWtoA( GetProcessHeap(), 0, section
);
1113 LPSTR entryA
= HEAP_strdupWtoA( GetProcessHeap(), 0, entry
);
1114 LPSTR filenameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
1115 LPSTR def_valA
= HEAP_strdupWtoA( GetProcessHeap(), 0, def_val
);
1116 LPSTR bufferA
= HeapAlloc( GetProcessHeap(), 0, len
);
1117 INT32 ret
= GetPrivateProfileString32A( sectionA
, entryA
, def_valA
,
1118 bufferA
, len
, filenameA
);
1119 lstrcpynAtoW( buffer
, bufferA
, len
);
1120 HeapFree( GetProcessHeap(), 0, sectionA
);
1121 HeapFree( GetProcessHeap(), 0, entryA
);
1122 HeapFree( GetProcessHeap(), 0, filenameA
);
1123 HeapFree( GetProcessHeap(), 0, def_valA
);
1124 HeapFree( GetProcessHeap(), 0, bufferA
);
1128 /***********************************************************************
1129 * GetPrivateProfileSection32A (KERNEL32.255)
1131 INT32 WINAPI
GetPrivateProfileSection32A( LPCSTR section
, LPSTR buffer
,
1132 DWORD len
, LPCSTR filename
)
1134 if (PROFILE_Open( filename
))
1135 return PROFILE_GetSection(CurProfile
->section
, section
, buffer
, len
,
1141 /***********************************************************************
1142 * GetPrivateProfileSection32W (KERNEL32.256)
1145 INT32 WINAPI
GetPrivateProfileSection32W (LPCWSTR section
, LPWSTR buffer
,
1146 DWORD len
, LPCWSTR filename
)
1149 LPSTR sectionA
= HEAP_strdupWtoA( GetProcessHeap(), 0, section
);
1150 LPSTR filenameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
1151 LPSTR bufferA
= HeapAlloc( GetProcessHeap(), 0, len
);
1152 INT32 ret
= GetPrivateProfileSection32A( sectionA
, bufferA
, len
,
1154 HeapFree( GetProcessHeap(), 0, sectionA
);
1155 HeapFree( GetProcessHeap(), 0, filenameA
);
1156 HeapFree( GetProcessHeap(), 0, bufferA
);
1160 /***********************************************************************
1161 * WritePrivateProfileString16 (KERNEL.129)
1163 BOOL16 WINAPI
WritePrivateProfileString16( LPCSTR section
, LPCSTR entry
,
1164 LPCSTR string
, LPCSTR filename
)
1166 return WritePrivateProfileString32A(section
,entry
,string
,filename
);
1169 /***********************************************************************
1170 * WritePrivateProfileString32A (KERNEL32.582)
1172 BOOL32 WINAPI
WritePrivateProfileString32A( LPCSTR section
, LPCSTR entry
,
1173 LPCSTR string
, LPCSTR filename
)
1175 if (!PROFILE_Open( filename
)) return FALSE
;
1176 if (!section
) return PROFILE_FlushFile();
1177 return PROFILE_SetString( section
, entry
, string
);
1180 /***********************************************************************
1181 * WritePrivateProfileString32W (KERNEL32.583)
1183 BOOL32 WINAPI
WritePrivateProfileString32W( LPCWSTR section
, LPCWSTR entry
,
1184 LPCWSTR string
, LPCWSTR filename
)
1186 LPSTR sectionA
= HEAP_strdupWtoA( GetProcessHeap(), 0, section
);
1187 LPSTR entryA
= HEAP_strdupWtoA( GetProcessHeap(), 0, entry
);
1188 LPSTR stringA
= HEAP_strdupWtoA( GetProcessHeap(), 0, string
);
1189 LPSTR filenameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
1190 BOOL32 res
= WritePrivateProfileString32A( sectionA
, entryA
,
1191 stringA
, filenameA
);
1192 HeapFree( GetProcessHeap(), 0, sectionA
);
1193 HeapFree( GetProcessHeap(), 0, entryA
);
1194 HeapFree( GetProcessHeap(), 0, stringA
);
1195 HeapFree( GetProcessHeap(), 0, filenameA
);
1199 /***********************************************************************
1200 * WritePrivateProfileSection32A (KERNEL32)
1202 BOOL32 WINAPI
WritePrivateProfileSection32A( LPCSTR section
,
1203 LPCSTR string
, LPCSTR filename
)
1205 char *p
=(char*)string
;
1207 FIXME(profile
, "WritePrivateProfileSection32A empty stub\n");
1208 if (TRACE_ON(profile
)) {
1209 TRACE(profile
, "(%s) => [%s]\n", filename
, section
);
1211 TRACE(profile
, "%s\n", p
);
1220 /***********************************************************************
1221 * WritePrivateProfileSection32W (KERNEL32)
1223 BOOL32 WINAPI
WritePrivateProfileSection32W( LPCWSTR section
,
1224 LPCWSTR string
, LPCWSTR filename
)
1227 LPSTR sectionA
= HEAP_strdupWtoA( GetProcessHeap(), 0, section
);
1228 LPSTR stringA
= HEAP_strdupWtoA( GetProcessHeap(), 0, string
);
1229 LPSTR filenameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
1230 BOOL32 res
= WritePrivateProfileSection32A( sectionA
, stringA
, filenameA
);
1231 HeapFree( GetProcessHeap(), 0, sectionA
);
1232 HeapFree( GetProcessHeap(), 0, stringA
);
1233 HeapFree( GetProcessHeap(), 0, filenameA
);
1238 /***********************************************************************
1239 * WriteProfileSection32A (KERNEL32.747)
1241 BOOL32 WINAPI
WriteProfileSection32A( LPCSTR section
, LPCSTR keys_n_values
)
1244 return WritePrivateProfileSection32A( section
, keys_n_values
, "win.ini");
1247 /***********************************************************************
1248 * WriteProfileSection32W (KERNEL32.748)
1250 BOOL32 WINAPI
WriteProfileSection32W( LPCWSTR section
, LPCWSTR keys_n_values
)
1252 if (!wininiW
) wininiW
= HEAP_strdupAtoW( SystemHeap
, 0, "win.ini");
1254 return (WritePrivateProfileSection32W (section
,keys_n_values
, wininiW
));
1257 /***********************************************************************
1258 * GetPrivateProfileSectionNames16 (KERNEL.143)
1260 WORD WINAPI
GetPrivateProfileSectionNames16( LPSTR buffer
, WORD size
,
1265 PROFILESECTION
*section
;
1267 if (PROFILE_Open( filename
)) {
1270 section
=CurProfile
->section
;
1271 for ( ; section
; section
= section
->next
)
1272 if (section
->name
) {
1273 l
=strlen (section
->name
);
1275 if (cursize
> size
+1)
1277 strcpy (buf
,section
->name
);
1284 return (buf
-buffer
);
1290 /***********************************************************************
1291 * GetProfileSectionNames16 (KERNEL.142)
1293 WORD WINAPI
GetProfileSectionNames16( LPSTR buffer
, WORD size
)
1296 return (GetPrivateProfileSectionNames16 (buffer
,size
,"win.ini"));
1300 /***********************************************************************
1301 * GetPrivateProfileSectionNames32A (KERNEL32.365)
1303 DWORD WINAPI
GetPrivateProfileSectionNames32A( LPSTR buffer
, DWORD size
,
1307 return (GetPrivateProfileSectionNames16 (buffer
,size
,filename
));
1311 /***********************************************************************
1312 * GetPrivateProfileSectionNames32W (KERNEL32.366)
1314 DWORD WINAPI
GetPrivateProfileSectionNames32W( LPWSTR buffer
, DWORD size
,
1318 LPSTR filenameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
1319 LPSTR bufferA
= HeapAlloc( GetProcessHeap(), 0, size
);
1321 INT32 ret
= GetPrivateProfileSectionNames16 (bufferA
, size
, filenameA
);
1322 lstrcpynAtoW( buffer
, bufferA
, size
);
1323 HeapFree( GetProcessHeap(), 0, bufferA
);
1324 HeapFree( GetProcessHeap(), 0, filenameA
);
1330 /***********************************************************************
1331 * GetPrivateProfileStruct32A (KERNEL32.370)
1333 BOOL32 WINAPI
GetPrivateProfileStruct32A (LPCSTR section
, LPCSTR key
,
1334 LPVOID buf
, UINT32 len
, LPCSTR filename
)
1338 if (PROFILE_Open( filename
)) {
1339 k
=PROFILE_Find ( &CurProfile
->section
, section
, key
, FALSE
);
1340 if (!k
) return FALSE
;
1341 lstrcpyn32A( buf
, k
->value
, strlen(k
->value
));
1347 /***********************************************************************
1348 * GetPrivateProfileStruct32W (KERNEL32.543)
1350 BOOL32 WINAPI
GetPrivateProfileStruct32W (LPCWSTR section
, LPCWSTR key
,
1351 LPVOID buffer
, UINT32 len
, LPCWSTR filename
)
1353 LPSTR sectionA
= HEAP_strdupWtoA( GetProcessHeap(), 0, section
);
1354 LPSTR keyA
= HEAP_strdupWtoA( GetProcessHeap(), 0, key
);
1355 LPSTR filenameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
1356 LPSTR bufferA
= HeapAlloc( GetProcessHeap(), 0, len
);
1358 INT32 ret
= GetPrivateProfileStruct32A( sectionA
, keyA
, bufferA
,
1360 lstrcpynAtoW( buffer
, bufferA
, len
);
1361 HeapFree( GetProcessHeap(), 0, bufferA
);
1362 HeapFree( GetProcessHeap(), 0, sectionA
);
1363 HeapFree( GetProcessHeap(), 0, keyA
);
1364 HeapFree( GetProcessHeap(), 0, filenameA
);
1372 /***********************************************************************
1373 * WritePrivateProfileStruct32A (KERNEL32.744)
1375 BOOL32 WINAPI
WritePrivateProfileStruct32A (LPCSTR section
, LPCSTR key
,
1376 LPVOID buf
, UINT32 bufsize
, LPCSTR filename
)
1378 if ((!section
) && (!key
) && (!buf
)) { /* flush the cache */
1379 PROFILE_FlushFile();
1383 if (!PROFILE_Open( filename
)) return FALSE
;
1384 return PROFILE_SetString( section
, key
, buf
);
1387 /***********************************************************************
1388 * WritePrivateProfileStruct32W (KERNEL32.544)
1390 BOOL32 WINAPI
WritePrivateProfileStruct32W (LPCWSTR section
, LPCWSTR key
,
1391 LPVOID buf
, UINT32 bufsize
, LPCWSTR filename
)
1393 LPSTR sectionA
= HEAP_strdupWtoA( GetProcessHeap(), 0, section
);
1394 LPSTR keyA
= HEAP_strdupWtoA( GetProcessHeap(), 0, key
);
1395 LPSTR filenameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, filename
);
1396 INT32 ret
= WritePrivateProfileStruct32A( sectionA
, keyA
, buf
, bufsize
,
1398 HeapFree( GetProcessHeap(), 0, sectionA
);
1399 HeapFree( GetProcessHeap(), 0, keyA
);
1400 HeapFree( GetProcessHeap(), 0, filenameA
);
1406 /***********************************************************************
1407 * WriteOutProfiles (KERNEL.315)
1409 void WINAPI
WriteOutProfiles(void)
1411 PROFILE_FlushFile();