2 * Initialization-File Functions.
4 * Copyright (c) 1993 Miguel de Icaza
6 * 1/Dec o Corrected return values for Get*ProfileString
8 * o Now, if AppName == NULL in Get*ProfileString it returns a list
9 * of the KeyNames (as documented in the MS-SDK).
11 * o if KeyValue == NULL now clears the value in Get*ProfileString
13 * 20/Apr SL - I'm not sure where these definitions came from, but my SDK
14 * has a NULL KeyValue returning a list of KeyNames, and a NULL
15 * AppName undefined. I changed GetSetProfile to match. This makes
16 * PROGMAN.EXE do the right thing.
33 typedef struct TKeys
{
39 typedef struct TSecHeader
{
42 struct TSecHeader
*link
;
45 typedef struct TProfile
{
49 struct TProfile
*link
;
53 TProfile
*Current
= 0;
56 static TSecHeader
*is_loaded (char *FileName
)
61 if (!strcasecmp (FileName
, p
->FileName
)){
70 static char *GetIniFileName(char *name
, char *dir
)
74 if (strchr(name
, '/'))
84 return DOS_GetUnixFileName(temp
);
87 static TSecHeader
*load (char *filename
, char **pfullname
)
90 TSecHeader
*SecHeader
= 0;
91 char CharBuffer
[STRSIZE
];
95 char *file
, *purefilename
;
97 char path
[MAX_PATH
+1];
102 dprintf_profile(stddeb
,"Trying to load file %s \n", filename
);
104 /* First try it as is */
105 file
= GetIniFileName(filename
, "");
106 f
= fopen(file
, "r");
110 if ((purefilename
= strrchr( filename
, '\\' )))
112 else if ((purefilename
= strrchr( filename
, '/' )))
115 purefilename
= filename
;
116 ToUnix(purefilename
);
118 /* Now try the Windows directory */
119 GetWindowsDirectory(path
, sizeof(path
));
120 file
= GetIniFileName(purefilename
, path
);
121 dprintf_profile(stddeb
,"Trying to load in windows directory file %s\n",
123 f
= fopen(file
, "r");
125 if (f
== NULL
) { /* Try the path of the current executable */
127 if (GetCurrentTask())
130 GetModuleFileName( GetCurrentTask(), path
, MAX_PATH
);
131 if ((p
= strrchr( path
, '\\' )))
133 p
[0] = '\0'; /* Remove trailing slash */
134 file
= GetIniFileName(purefilename
, path
);
135 dprintf_profile(stddeb
,
136 "Trying to load in current directory%s\n",
138 f
= fopen(file
, "r");
142 if (f
== NULL
) { /* And now in $HOME/.wine */
144 strcpy(file
,getenv("HOME"));
145 strcat(file
, "/.wine/");
146 strcat(file
, purefilename
);
147 dprintf_profile(stddeb
,"Trying to load in user-directory %s\n", file
);
148 f
= fopen(file
, "r");
152 /* FIXED: we ought to create it now (in which directory?) */
153 /* lets do it in ~/.wine */
154 strcpy(file
,getenv("HOME"));
155 strcat(file
, "/.wine/");
156 strcat(file
, purefilename
);
157 dprintf_profile(stddeb
,"Creating %s\n", file
);
158 f
= fopen(file
, "w+");
160 fprintf(stderr
, "profile.c: load() can't find file %s\n", filename
);
166 *pfullname
= strdup(file
);
167 dprintf_profile(stddeb
,"Loading %s\n", file
);
172 if (c
== EOF
) goto finished
;
179 } while (!(c
== EOF
|| c
== '\n'));
180 if (c
== EOF
) goto finished
;
183 TSecHeader
*temp
= SecHeader
;
185 SecHeader
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
186 SecHeader
->link
= temp
;
187 SecHeader
->Keys
= NULL
;
190 if (c
== EOF
) goto bad_file
;
191 } while (isspace(c
));
192 bufptr
= lastnonspc
= CharBuffer
;
203 if (c
== EOF
) goto bad_file
;
204 } while(bufsize
< STRSIZE
-1);
206 if (!strlen(CharBuffer
))
207 fprintf(stderr
, "warning: empty section name in ini file\n");
208 SecHeader
->AppName
= strdup (CharBuffer
);
209 dprintf_profile(stddeb
,"%s: section %s\n", file
, CharBuffer
);
211 } else if (SecHeader
) {
212 TKeys
*temp
= SecHeader
->Keys
;
217 bufptr
= lastnonspc
= CharBuffer
;
228 if (c
== EOF
) goto bad_file
;
229 } while(bufsize
< STRSIZE
-1);
231 if (!strlen(CharBuffer
))
232 fprintf(stderr
, "warning: empty key name in ini file\n");
233 SecHeader
->Keys
= (TKeys
*) xmalloc (sizeof (TKeys
));
234 SecHeader
->Keys
->link
= temp
;
235 SecHeader
->Keys
->KeyName
= strdup (CharBuffer
);
237 dprintf_profile(stddeb
,"%s: key %s\n", file
, CharBuffer
);
239 bufptr
= lastnonspc
= CharBuffer
;
244 if (c
== EOF
|| c
== '\n') break;
245 if (!isspace(c
) || !skipspc
) {
252 } while(bufsize
< STRSIZE
-1);
254 SecHeader
->Keys
->Value
= strdup (CharBuffer
);
255 dprintf_profile (stddeb
, "[%s] (%s)=%s\n", SecHeader
->AppName
,
256 SecHeader
->Keys
->KeyName
, SecHeader
->Keys
->Value
);
260 } while (!(c
== EOF
|| c
== '\n'));
268 fprintf(stderr
, "warning: bad ini file\n");
273 static void new_key (TSecHeader
*section
, char *KeyName
, char *Value
)
277 key
= (TKeys
*) xmalloc (sizeof (TKeys
));
278 key
->KeyName
= strdup (KeyName
);
279 key
->Value
= strdup (Value
);
280 key
->link
= section
->Keys
;
284 static short GetSetProfile (int set
, LPSTR AppName
, LPSTR KeyName
,
285 LPSTR Default
, LPSTR ReturnedString
, short Size
,
293 /* Supposedly Default should NEVER be NULL. But sometimes it is. */
297 if (!(section
= is_loaded (FileName
))){
298 New
= (TProfile
*) xmalloc (sizeof (TProfile
));
300 New
->FileName
= strdup (FileName
);
301 New
->Section
= load (FileName
, &New
->FullName
);
302 New
->changed
= FALSE
;
304 section
= New
->Section
;
309 for (; section
; section
= section
->link
){
310 if (strcasecmp (section
->AppName
, AppName
))
313 /* If no key value given, then list all the keys */
314 if ((!KeyName
) && (!set
)){
315 char *p
= ReturnedString
;
319 dprintf_profile(stddeb
,"GetSetProfile // KeyName == NULL, Enumeration !\n");
320 for (key
= section
->Keys
; key
; key
= key
->link
){
322 dprintf_profile(stddeb
,"GetSetProfile // No more storage for enum !\n");
325 slen
= MIN(strlen(key
->KeyName
) + 1, left
);
326 lstrcpyn(p
, key
->KeyName
, slen
);
327 dprintf_profile(stddeb
,"GetSetProfile // enum '%s' !\n", p
);
332 return Size
- 2 - left
;
334 for (key
= section
->Keys
; key
; key
= key
->link
){
336 if (strcasecmp (key
->KeyName
, KeyName
))
340 key
->Value
= strdup (Default
? Default
: "");
341 Current
->changed
=TRUE
;
344 slen
= MIN(strlen(key
->Value
)+1, Size
);
345 lstrcpyn(ReturnedString
, key
->Value
, slen
);
346 dprintf_profile(stddeb
,"GetSetProfile // Return ``%s''\n", ReturnedString
);
349 /* If Getting the information, then don't write the information
350 to the INI file, need to run a couple of tests with windog */
353 new_key (section
, KeyName
, Default
);
355 int slen
= MIN(strlen(Default
)+1, Size
);
356 lstrcpyn(ReturnedString
, Default
, slen
);
357 dprintf_profile(stddeb
,"GetSetProfile // Key not found\n");
362 /* Non existent section */
364 section
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
365 section
->AppName
= strdup (AppName
);
367 new_key (section
, KeyName
, Default
);
368 section
->link
= Current
->Section
;
369 Current
->Section
= section
;
370 Current
->changed
= TRUE
;
372 int slen
= MIN(strlen(Default
)+1, Size
);
373 lstrcpyn(ReturnedString
, Default
, slen
);
374 dprintf_profile(stddeb
,"GetSetProfile // Section not found\n");
379 short GetPrivateProfileString (LPSTR AppName
, LPSTR KeyName
,
380 LPSTR Default
, LPSTR ReturnedString
,
381 short Size
, LPSTR FileName
)
385 dprintf_profile(stddeb
,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n",
386 AppName
, KeyName
, Default
, ReturnedString
, Size
, FileName
);
387 v
= GetSetProfile (0,AppName
,KeyName
,Default
,ReturnedString
,Size
,FileName
);
389 return strlen (ReturnedString
);
394 int GetProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR Default
,
395 LPSTR ReturnedString
, int Size
)
397 return GetPrivateProfileString (AppName
, KeyName
, Default
,
398 ReturnedString
, Size
, WIN_INI
);
401 WORD
GetPrivateProfileInt (LPSTR AppName
, LPSTR KeyName
, short Default
,
404 static char IntBuf
[10];
407 sprintf (buf
, "%d", Default
);
409 /* Check the exact semantic with the SDK */
410 GetPrivateProfileString (AppName
, KeyName
, buf
, IntBuf
, 10, File
);
411 if (!strcasecmp (IntBuf
, "true"))
413 if (!strcasecmp (IntBuf
, "yes"))
415 return strtoul( IntBuf
, NULL
, 0 );
418 WORD
GetProfileInt (LPSTR AppName
, LPSTR KeyName
, int Default
)
420 return GetPrivateProfileInt (AppName
, KeyName
, Default
, WIN_INI
);
423 BOOL
WritePrivateProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
,
426 if (!AppName
|| !KeyName
|| !String
) /* Flush file to disk */
428 return GetSetProfile (1, AppName
, KeyName
, String
, "", 0, FileName
);
431 BOOL
WriteProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
)
433 return (WritePrivateProfileString (AppName
, KeyName
, String
, WIN_INI
));
436 static void dump_keys (FILE *profile
, TKeys
*p
)
440 dump_keys (profile
, p
->link
);
441 fprintf (profile
, "%s=%s\r\n", p
->KeyName
, p
->Value
);
444 static void dump_sections (FILE *profile
, TSecHeader
*p
)
448 dump_sections (profile
, p
->link
);
449 fprintf (profile
, "\r\n[%s]\r\n", p
->AppName
);
450 dump_keys (profile
, p
->Keys
);
453 static void dump_profile (TProfile
*p
)
459 dump_profile (p
->link
);
462 if (p
->FullName
&& (profile
= fopen (p
->FullName
, "w")) != NULL
){
463 dump_sections (profile
, p
->Section
);
468 void sync_profiles (void)