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 (!lstrcmpi( FileName
, p
->FileName
)){
70 #define WIN_INI WinIniFileName()
72 static char *WinIniFileName(void)
74 static char *name
= NULL
;
78 if (name
) return name
;
80 len
= GetWindowsDirectory( NULL
, 0 ) + 9;
81 name
= xmalloc( len
);
82 GetWindowsDirectory( name
, len
);
83 strcat( name
, "/win.ini" );
84 if (!(unixName
= DOSFS_GetUnixFileName( name
, TRUE
))) return NULL
;
86 name
= strdup( unixName
);
90 static char *GetIniFileName(char *name
, char *dir
)
94 if (strchr(name
, '/'))
104 return DOSFS_GetUnixFileName(temp
,TRUE
);
107 static TSecHeader
*load (char *filename
, char **pfullname
)
110 TSecHeader
*SecHeader
= 0;
111 char CharBuffer
[STRSIZE
];
115 char *file
, *purefilename
;
117 char path
[MAX_PATH
+1];
122 dprintf_profile(stddeb
,"Trying to load file %s \n", filename
);
124 /* First try it as is */
125 file
= GetIniFileName(filename
, "");
126 if (!file
|| !(f
= fopen(file
, "r")))
128 if ((purefilename
= strrchr( filename
, '\\' )))
130 else if ((purefilename
= strrchr( filename
, '/' )))
133 purefilename
= filename
;
135 /* Now try the Windows directory */
136 GetWindowsDirectory(path
, sizeof(path
));
137 if ((file
= GetIniFileName(purefilename
, path
)))
139 dprintf_profile(stddeb
,"Trying to load in windows directory file %s\n",
141 f
= fopen(file
, "r");
146 { /* Try the path of the current executable */
148 if (GetCurrentTask())
151 GetModuleFileName( GetCurrentTask(), path
, MAX_PATH
);
152 if ((p
= strrchr( path
, '\\' )))
154 p
[0] = '\0'; /* Remove trailing slash */
155 if ((file
= GetIniFileName(purefilename
, path
)))
157 dprintf_profile(stddeb
,
158 "Trying to load in current directory%s\n",
160 f
= fopen(file
, "r");
165 if (f
== NULL
) { /* And now in $HOME/.wine */
167 strcpy(path
,getenv("HOME"));
168 strcat(path
, "/.wine/");
169 strcat(path
, purefilename
);
170 dprintf_profile(stddeb
,"Trying to load in user-directory %s\n", path
);
172 f
= fopen(file
, "r");
176 /* FIXED: we ought to create it now (in which directory?) */
177 /* lets do it in ~/.wine */
178 strcpy(path
,getenv("HOME"));
179 strcat(path
, "/.wine/");
180 strcat(path
, purefilename
);
181 dprintf_profile(stddeb
,"Creating %s\n", path
);
183 f
= fopen(file
, "w+");
185 fprintf(stderr
, "profile.c: load() can't find file %s\n", filename
);
191 *pfullname
= xstrdup(file
);
192 dprintf_profile(stddeb
,"Loading %s\n", file
);
197 if (c
== EOF
) goto finished
;
204 } while (!(c
== EOF
|| c
== '\n'));
205 if (c
== EOF
) goto finished
;
208 TSecHeader
*temp
= SecHeader
;
210 SecHeader
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
211 SecHeader
->link
= temp
;
212 SecHeader
->Keys
= NULL
;
215 if (c
== EOF
) goto bad_file
;
216 } while (isspace(c
));
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 section name in ini file\n");
233 SecHeader
->AppName
= xstrdup (CharBuffer
);
234 dprintf_profile(stddeb
,"%s: section %s\n", file
, CharBuffer
);
236 } else if (SecHeader
) {
237 TKeys
*temp
= SecHeader
->Keys
;
242 bufptr
= lastnonspc
= CharBuffer
;
253 if (c
== EOF
) goto bad_file
;
254 } while(bufsize
< STRSIZE
-1);
256 if (!strlen(CharBuffer
))
257 fprintf(stderr
, "warning: empty key name in ini file\n");
258 SecHeader
->Keys
= (TKeys
*) xmalloc (sizeof (TKeys
));
259 SecHeader
->Keys
->link
= temp
;
260 SecHeader
->Keys
->KeyName
= xstrdup (CharBuffer
);
262 dprintf_profile(stddeb
,"%s: key %s\n", file
, CharBuffer
);
264 bufptr
= lastnonspc
= CharBuffer
;
269 if (c
== EOF
|| c
== '\n') break;
270 if (!isspace(c
) || !skipspc
) {
277 } while(bufsize
< STRSIZE
-1);
279 SecHeader
->Keys
->Value
= xstrdup (CharBuffer
);
280 dprintf_profile (stddeb
, "[%s] (%s)=%s\n", SecHeader
->AppName
,
281 SecHeader
->Keys
->KeyName
, SecHeader
->Keys
->Value
);
285 } while (!(c
== EOF
|| c
== '\n'));
293 fprintf(stderr
, "warning: bad ini file\n");
298 static void new_key (TSecHeader
*section
, char *KeyName
, char *Value
)
302 key
= (TKeys
*) xmalloc (sizeof (TKeys
));
303 key
->KeyName
= xstrdup (KeyName
);
304 key
->Value
= xstrdup (Value
);
305 key
->link
= section
->Keys
;
309 static short GetSetProfile (int set
, LPSTR AppName
, LPSTR KeyName
,
310 LPSTR Default
, LPSTR ReturnedString
, short Size
,
318 /* Supposedly Default should NEVER be NULL. But sometimes it is. */
322 if (!(section
= is_loaded (FileName
))){
323 New
= (TProfile
*) xmalloc (sizeof (TProfile
));
325 New
->FileName
= xstrdup (FileName
);
326 New
->Section
= load (FileName
, &New
->FullName
);
327 New
->changed
= FALSE
;
329 section
= New
->Section
;
334 for (; section
; section
= section
->link
){
335 if (lstrcmpi(section
->AppName
, AppName
))
338 /* If no key value given, then list all the keys */
339 if ((!KeyName
) && (!set
)){
340 char *p
= ReturnedString
;
344 dprintf_profile(stddeb
,"GetSetProfile // KeyName == NULL, Enumeration !\n");
345 for (key
= section
->Keys
; key
; key
= key
->link
){
347 dprintf_profile(stddeb
,"GetSetProfile // No more storage for enum !\n");
350 slen
= MIN(strlen(key
->KeyName
) + 1, left
);
351 lstrcpyn(p
, key
->KeyName
, slen
);
352 dprintf_profile(stddeb
,"GetSetProfile // enum '%s' !\n", p
);
357 return Size
- 2 - left
;
359 for (key
= section
->Keys
; key
; key
= key
->link
){
361 if (lstrcmpi(key
->KeyName
, KeyName
))
365 key
->Value
= xstrdup (Default
? Default
: "");
366 Current
->changed
=TRUE
;
369 slen
= MIN(strlen(key
->Value
)+1, Size
);
370 lstrcpyn(ReturnedString
, key
->Value
, slen
);
371 dprintf_profile(stddeb
,"GetSetProfile // Return ``%s''\n", ReturnedString
);
374 /* If Getting the information, then don't write the information
375 to the INI file, need to run a couple of tests with windog */
378 new_key (section
, KeyName
, Default
);
380 int slen
= MIN(strlen(Default
)+1, Size
);
381 lstrcpyn(ReturnedString
, Default
, slen
);
382 dprintf_profile(stddeb
,"GetSetProfile // Key not found\n");
387 /* Non existent section */
389 section
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
390 section
->AppName
= xstrdup (AppName
);
392 new_key (section
, KeyName
, Default
);
393 section
->link
= Current
->Section
;
394 Current
->Section
= section
;
395 Current
->changed
= TRUE
;
397 int slen
= MIN(strlen(Default
)+1, Size
);
398 lstrcpyn(ReturnedString
, Default
, slen
);
399 dprintf_profile(stddeb
,"GetSetProfile // Section not found\n");
404 short GetPrivateProfileString (LPCSTR AppName
, LPCSTR KeyName
,
405 LPCSTR Default
, LPSTR ReturnedString
,
406 short Size
, LPCSTR FileName
)
410 dprintf_profile(stddeb
,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n",
411 AppName
, KeyName
, Default
, ReturnedString
, Size
, FileName
);
412 v
= GetSetProfile (0,AppName
,KeyName
,Default
,ReturnedString
,Size
,FileName
);
414 return strlen (ReturnedString
);
419 int GetProfileString (LPCSTR AppName
, LPCSTR KeyName
, LPCSTR Default
,
420 LPSTR ReturnedString
, int Size
)
422 return GetPrivateProfileString (AppName
, KeyName
, Default
,
423 ReturnedString
, Size
, WIN_INI
);
426 WORD
GetPrivateProfileInt (LPCSTR AppName
, LPCSTR KeyName
, short Default
,
429 static char IntBuf
[10];
432 sprintf (buf
, "%d", Default
);
434 /* Check the exact semantic with the SDK */
435 GetPrivateProfileString (AppName
, KeyName
, buf
, IntBuf
, 10, File
);
436 if (!lstrcmpi(IntBuf
, "true"))
438 if (!lstrcmpi(IntBuf
, "yes"))
440 return strtoul( IntBuf
, NULL
, 0 );
443 WORD
GetProfileInt (LPCSTR AppName
, LPCSTR KeyName
, int Default
)
445 return GetPrivateProfileInt (AppName
, KeyName
, Default
, WIN_INI
);
448 BOOL
WritePrivateProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
,
451 if (!AppName
|| !KeyName
|| !String
) /* Flush file to disk */
453 return GetSetProfile (1, AppName
, KeyName
, String
, "", 0, FileName
);
456 BOOL
WriteProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
)
458 return (WritePrivateProfileString (AppName
, KeyName
, String
, WIN_INI
));
461 static void dump_keys (FILE *profile
, TKeys
*p
)
465 dump_keys (profile
, p
->link
);
466 fprintf (profile
, "%s=%s\r\n", p
->KeyName
, p
->Value
);
469 static void dump_sections (FILE *profile
, TSecHeader
*p
)
473 dump_sections (profile
, p
->link
);
474 fprintf (profile
, "\r\n[%s]\r\n", p
->AppName
);
475 dump_keys (profile
, p
->Keys
);
478 static void dump_profile (TProfile
*p
)
484 dump_profile (p
->link
);
487 if (p
->FullName
&& (profile
= fopen (p
->FullName
, "w")) != NULL
){
488 dump_sections (profile
, p
->Section
);
493 void sync_profiles (void)