1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/files/profile.c
Alexandre Julliard 0c126c7c61 Release 960218
Sun Feb 18 16:35:54 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/desktop.c]
	Look for the wallpaper file in the Windows directory.

	* [controls/menu.c]
	Fixed swapped parameters in SetMenuItemBitmaps().
	Create a separator in MENU_SetItemData() when the string is NULL.

	* [file/dosfs.c]
	DOSFS_FindNext: don't return '.' and '..' in a drive root dir.

	* [files/file.c]
	Added a DOS_FILE structure to store per-file information (not
	really used yet).
	Fixed _lread and _hread to check the size of the buffer before
	calling Unix read() to avoid EFAULT error.

	* [misc/exec.c]
	Return TRUE in WinHelp() for HELP_QUIT to quiet Notepad on exit.

	* [miscemu/instr.c]
	Call DOSMEM_Alarm() in INSTR_ReplaceSelector(). This should fix
 	programs that poll the BIOS counter, provided they reload the
 	selector on every read.

	* [miscemu/int21.c]
	Re-implemented FindFirst/FindNext for FCB calls.

	* [windows/message.c] [windows/winpos.c]
	Merged MSG_GetWindowForEvent() and WINPOS_WindowFromPoint().

	* [windows/nonclient.c] [windows/win.c] [include/windows.h]
	Added a per-window WIN_MANAGED flag; only windows that have a
	dialog frame or a sizing border are managed.

Sat Feb 17 18:25:00 1996  Thomas Sandford <tdgsandf@prds-grn.demon.co.uk>

	* [if1632/Makefile.in]
	Added -g flag to compilation of .c files generated from *32.spec.

	* [if1632/gdi32.spec]
	Numerous additional functions implemented.

	* if1632/user32.spec]
	wsprintfA maps to vsprintf not wsprintf
	Numerous additional functions implemented.

	* [include/gdi.h] [objects/gdiobj.c]
	New #define MAGIC_DONTCARE added. This is used in
	GDI_GetObjPtr to enable getting a pointer to a GDI object of
	unknow type.

	* [win32/gdi32.c]
	New file.

	* [win32/param32.c]
	WIN32_MoveToEx() - handle NULL pointer argument.

	* [win32/user32.c]
	USER32_InvalidateRect - handle passing of a NULL pointer.
	USER32_SetTimer - New function.

	* [files/directory.c]
	Fixed DIR_Init() (off by one in allocation of space for
	environment variables).

	* [files/drive.c]
	Added <sys/types.h> to #includes (prerequisite for <sys/stat.h>
	on FreeBSD).

Fri Feb 16 10:26:56 1996  Andreas Kirschbaum <ank@rbg.informatik.th-darmstadt.de>

	* [controls/menu.c]
	Memory leak plugged.

	* [controls/edit.c]
	Erase space with function ExtTextOut(). This eliminates the use of
 	xmalloc().  Memory leak in EDIT_WriteText plugged.

	* [debugger/db_disasm.c]
	Operand for scas now is di.

	* [files/profile.c]
	PROFILE_GetSection was copying too much data.
	PROFILE_GetSection now returns the correct value. It was returning
 	the number of unused instead of used bytes.

	* [objects/dc.c]
	Corrected two typos in comments.

	* [objects/font.c]
	FONT_MatchFont didn't return if it couldn't find any font.

	* [objects/oembitmap.c]
	Free object only if it has been allocated.

	* [windows/scroll.c]
	Memory leak in ScrollDC plugged.

Tue Feb 13 11:17:00 1996 William Magro  <wmagro@tc.cornell.edu>

	* [controls/edit.c]
	Implemented ES_NOHIDESEL style, shift+click selection,
 	shift+{arrow,home,end,pgup,pgdn} selection.  Optimized
	(de)selection drawing.  Changed selection drawing to use correct
 	system colors instead of inverting.  Fixed deleting or backspacing
 	across a '\r\n' end of line pair.  Selection now anchors
 	correctly. Fixed text leaking and extra garbage problem bug
 	uncovered by change in class style in wine960131.

	* [controls/widgets.c]
	Class flags now match those of Windows.

Mon Feb 12 21:28:19 1996  Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [controls/widgets.c]
	WIDGETS_Init: RELAY32_GetEntryPoint does not take a string anymore.

	* [if1632/Makefile.in][if1632/relay32.c][include/relay32.h]
	comctl32.spec ole32.spec winspool.spec: new files.
	RELAY32_Init: call initialization of new DLLs.
	RELAY32_GetEntryPoint: expects WIN32_builtin* now.
	RELAY32_MakeFakeModule: new function.

	* [if1632/gdi32.spec][if1632/kernel32.spec][if1632/user32.spec]
	Added Win95 functions. Ordinals now differ from both NT and Win95
	HeapCreate, CreateDialogIndirectParamA, CreateDialogIndirectParamW,
	CreateDialogParamA, CreateDialogParamW, DialogBoxIndirectParamA
	DialogBoxIndirectParamW, DialogBoxParamA, DialogBoxParamW:
	new relays.

	* [if1632/shell32.spec]
	shell32.spec: renumbered all functions to take into account ordinals.
	These seem to be identical between NT and Win95.

	* [include/dialog.h][windows/dialog.c]
	xBaseUnit,yBaseUnit,DIALOG_DoDialogBox: made non-static.

	* [include/handle32.h]
	New handle types VRANGE, HEAP, HEAPITEM.

	* [include/pe_image.h][loader/pe_image.c]
	struct w_files: new field builtin.
	PE_FindExportedFunction: support ordinals.
	PE_GetProcAddress: call RELAY32_GetEntryPoint for builtins.
	fixup_imports: support ordinals.
	PE_LoadImage: prefer directories over segments.

	* [include/resource.h][win32/resource.c]
	FindResource32: changed parameter from LPCTSTR to LPCWSTR
		check LANG_NEUTRAL if LANG_ENGLISH fails.
	LoadAcceleratorsW,SizeofResource32,AccessResource32: 
		disabled because it's broken.
	Casted to and from LPWSTR at various places.

	* [include/string32.h][win32/string32.c]
	Changed prototypes to take const arguments where appropriate.

	* [include/struct32.h]
	New structures DLGTEMPLATE32, DLGITEMTEMPLATE32.

	* [tools/build.c]
	BuildSpec32Files: generate Base value into code, generate call to
	RELAY32_MakeFakeModule.
	
	* [win32/heap.c]
	This is still not finished and needs rework.
	HeapAlloc: renamed to SIMPLE_HeapAlloc, implemented HeapAlloc.
	HeapCreate: implemented on top of VirtualAlloc, which does not work yet
	HeapDestroy, HEAP_GrowHeap, HeapFree: new functions.

	* [win32/memory.c]
	Support for VRANGE_OBJECT. This is not yet called from any place,
	and needs more platform specific support
	MEMORY_FindVrange, MEMORY_IsVrangeFree, MEMORY_InsertVrange,
	MEMORY_AllocVrange, MEMORY_ReleaseVrange: new functions.

	* [win32/user32.c]
	WIN32_CreateWindowExA: don't GlobalAlloc for integer class and window
	names, as in dialogs.
	Implemented dialog functions (see user32.spec).

	* [windows/caret.c]
	CARET_Initialize: call RELAY32_GetBuiltinDLL.

Mon Feb 12 18:52:40 1996  Jim Peterson <jspeter@birch.ee.vt.edu>

	* [controls/edit.c]
	Removed commented out #ifdefs for WINELIB.

	* [tools/makehtml.pl]
	Put in error checking when trying to open a file.

	* [libtest/Makefile.in] [libtest/new.c] [libtest/hello4.c]
	Added two new targets: hello4 and new.

	* [include/windows.h]
	Added definition of DEVMODE structure, although it's not yet used.
  	Modified various API functions from CreateDC() to Escape(), in
 	order to make them more compliant with the strict API definitions.

	* [include/wintypes.h]
	Added 'typedef char TCHAR'.  It probably should be defined as
	'short', but then we would have to support such characters.  Also did
	'typedef const TCHAR* LPCTSTR' and 'typedef TCHAR* LPTSTR'.
	Also defined WNDENUMPROC, FONTENUMPROC, GOBJENUMPROC, PROPENUMPROC
	MFENUMPROC, and HGDIOBJ.

Mon Feb  5 16:42:07 1996  Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl>

	* [misc/commdlg.c]
	Patched a bug that occurred in the internal COMMDLG module for the
 	FileOpen(), FileSave() and FileSaveAs() functions.  The file-type
 	combobox is now handled correctly.

Fri Feb  2 22:52:58 1996  Roman Dolejsi  <roman@sorry.vse.cz>

	* [resources/sysres_Cz.rc]
	Added support for Czech [Cz] language.

Thu Feb  1 00:35:04 1996  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [objects/font.c]
	FONT_matchfont : for fixed-spacing fonts, allow 'c' if 'm' fails;
	for variable-spacing fonts : allow '*' if 'p' fails; if asked lfHeight
	is -1, assume 0.
	CreateFontIndirect : if font parameter is NULL, issue an error message.
	CreateFont : null-terminate lfFaceName.
	ParseFontParms : debug code turned off : too verbose.
	InitFontsList : recognize *-c-* fonts as fixed-spacing fonts.

	* [objects/color.c]
	ColorToPhysical : admit 0xff...... COLORREF's as 0x00...... ones.
1996-02-18 18:44:41 +00:00

687 lines
20 KiB
C

/*
* Profile functions
*
* Copyright 1993 Miguel de Icaza
* Copyright 1996 Alexandre Julliard
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "dos_fs.h"
#include "windows.h"
#include "xmalloc.h"
#include "stddebug.h"
#include "debug.h"
typedef struct tagPROFILEKEY
{
char *name;
char *value;
struct tagPROFILEKEY *next;
} PROFILEKEY;
typedef struct tagPROFILESECTION
{
char *name;
struct tagPROFILEKEY *key;
struct tagPROFILESECTION *next;
} PROFILESECTION;
typedef struct
{
int changed;
PROFILESECTION *section;
char *dos_name;
} PROFILE;
/* Cached profile file */
static PROFILE CurProfile = { FALSE, NULL, NULL };
/* wine.ini profile content */
static PROFILESECTION *WineProfile;
#define PROFILE_MAX_LINE_LEN 1024
/* Wine profile name in $HOME directory; must begin with slash */
static const char PROFILE_WineIniName[] = "/.winerc";
/* Check for comments in profile */
#define IS_ENTRY_COMMENT(str) ((str)[0] == ';')
/***********************************************************************
* PROFILE_CopyEntry
*
* Copy the content of an entry into a buffer, removing quotes, and possibly
* translating environment variables.
*/
static void PROFILE_CopyEntry( char *buffer, const char *value, int len,
int handle_env )
{
char quote = '\0';
const char *p;
if ((*value == '\'') || (*value == '\"'))
{
if (value[1] && (value[strlen(value)-1] == *value)) quote = *value++;
}
if (!handle_env)
{
lstrcpyn( buffer, value, len );
if (quote && (len >= strlen(value))) buffer[strlen(buffer)-1] = '\0';
return;
}
for (p = value; (*p && (len > 1)); *buffer++ = *p++, len-- )
{
if ((*p == '$') && (p[1] == '{'))
{
char env_val[1024];
const char *env_p;
const char *p2 = strchr( p, '}' );
if (!p2) continue; /* ignore it */
lstrcpyn( env_val, p + 2, MIN( sizeof(env_val), (int)(p2-p)-1 ) );
if ((env_p = getenv( env_val )) != NULL)
{
lstrcpyn( buffer, env_p, len );
buffer += strlen( buffer );
len -= strlen( buffer );
}
p = p2 + 1;
}
}
*buffer = '\0';
}
/***********************************************************************
* PROFILE_Save
*
* Save a profile tree to a file.
*/
static void PROFILE_Save( FILE *file, PROFILESECTION *section )
{
PROFILEKEY *key;
for ( ; section; section = section->next)
{
if (section->name) fprintf( file, "[%s]\n", section->name );
for (key = section->key; key; key = key->next)
{
fprintf( file, "%s", key->name );
if (key->value) fprintf( file, "=%s", key->value );
fprintf( file, "\n" );
}
}
}
/***********************************************************************
* PROFILE_Free
*
* Free a profile tree.
*/
static void PROFILE_Free( PROFILESECTION *section )
{
PROFILESECTION *next_section;
PROFILEKEY *key, *next_key;
for ( ; section; section = next_section)
{
if (section->name) free( section->name );
for (key = section->key; key; key = next_key)
{
next_key = key->next;
if (key->name) free( key->name );
if (key->value) free( key->value );
free( key );
}
next_section = section->next;
free( section );
}
}
/***********************************************************************
* PROFILE_Load
*
* Load a profile tree from a file.
*/
static PROFILESECTION *PROFILE_Load( FILE *file )
{
char buffer[PROFILE_MAX_LINE_LEN];
char *p, *p2;
int line = 0;
PROFILESECTION *section, *first_section;
PROFILESECTION **prev_section;
PROFILEKEY *key, **prev_key;
first_section = (PROFILESECTION *)xmalloc( sizeof(*section) );
first_section->name = NULL;
first_section->key = NULL;
first_section->next = NULL;
prev_section = &first_section->next;
prev_key = &first_section->key;
while (fgets( buffer, PROFILE_MAX_LINE_LEN, file ))
{
line++;
p = buffer + strlen(buffer) - 1;
while ((p > buffer) && ((*p == '\n') || isspace(*p))) *p-- = '\0';
p = buffer;
while (*p && isspace(*p)) p++;
if (*p == '[') /* section start */
{
if (!(p2 = strrchr( p, ']' )))
{
fprintf( stderr, "PROFILE_Load: Invalid section header at line %d: '%s'\n",
line, p );
}
else
{
*p2 = '\0';
p++;
section = (PROFILESECTION *)xmalloc( sizeof(*section));
section->name = xstrdup( p );
section->key = NULL;
section->next = NULL;
*prev_section = section;
prev_section = &section->next;
prev_key = &section->key;
continue;
}
}
if ((p2 = strchr( p, '=' )) != NULL)
{
char *p3 = p2 - 1;
while ((p3 > p) && isspace(*p3)) *p3-- = '\0';
*p2++ = '\0';
while (*p2 && isspace(*p2)) p2++;
}
key = (PROFILEKEY *)xmalloc( sizeof(*key) );
key->name = xstrdup( p );
key->value = p2 ? xstrdup( p2 ) : NULL;
key->next = NULL;
*prev_key = key;
prev_key = &key->next;
}
if (debugging_profile)
{
fprintf( stddeb, "PROFILE_Load:\n" );
PROFILE_Save( stddeb, first_section );
fprintf( stddeb, "PROFILE_Load finished.\n" );
}
return first_section;
}
/***********************************************************************
* PROFILE_DeleteSection
*
* Delete a section from a profile tree.
*/
static BOOL PROFILE_DeleteSection( PROFILESECTION **section, const char *name )
{
while (*section)
{
if ((*section)->name && !lstrcmpi( (*section)->name, name ))
{
PROFILESECTION *to_del = *section;
*section = to_del->next;
to_del->next = NULL;
PROFILE_Free( to_del );
return TRUE;
}
section = &(*section)->next;
}
return FALSE;
}
/***********************************************************************
* PROFILE_DeleteKey
*
* Delete a key from a profile tree.
*/
static BOOL PROFILE_DeleteKey( PROFILESECTION **section,
const char *section_name, const char *key_name )
{
while (*section)
{
if ((*section)->name && !lstrcmpi( (*section)->name, section_name ))
{
PROFILEKEY **key = &(*section)->key;
while (*key)
{
if (!lstrcmpi( (*key)->name, key_name ))
{
PROFILEKEY *to_del = *key;
*key = to_del->next;
if (to_del->name) free( to_del->name );
if (to_del->value) free( to_del->value );
free( to_del );
return TRUE;
}
key = &(*key)->next;
}
}
section = &(*section)->next;
}
return FALSE;
}
/***********************************************************************
* PROFILE_Find
*
* Find a key in a profile tree, optionally creating it.
*/
static PROFILEKEY *PROFILE_Find( PROFILESECTION **section,
const char *section_name,
const char *key_name, int create )
{
while (*section)
{
if ((*section)->name && !lstrcmpi( (*section)->name, section_name ))
{
PROFILEKEY **key = &(*section)->key;
while (*key)
{
if (!lstrcmpi( (*key)->name, key_name )) return *key;
key = &(*key)->next;
}
if (!create) return NULL;
*key = (PROFILEKEY *)xmalloc( sizeof(PROFILEKEY) );
(*key)->name = xstrdup( key_name );
(*key)->value = NULL;
(*key)->next = NULL;
return *key;
}
section = &(*section)->next;
}
if (!create) return NULL;
*section = (PROFILESECTION *)xmalloc( sizeof(PROFILESECTION) );
(*section)->name = xstrdup(section_name);
(*section)->next = NULL;
(*section)->key = (PROFILEKEY *)xmalloc( sizeof(PROFILEKEY) );
(*section)->key->name = xstrdup( key_name );
(*section)->key->value = NULL;
(*section)->key->next = NULL;
return (*section)->key;
}
/***********************************************************************
* PROFILE_FlushFile
*
* Flush the current profile to disk if changed.
*/
static BOOL PROFILE_FlushFile(void)
{
char *p, buffer[MAX_PATHNAME_LEN];
const char *unix_name;
FILE *file = NULL;
if (!CurProfile.changed || !CurProfile.dos_name) return TRUE;
if (!(unix_name = DOSFS_GetUnixFileName( CurProfile.dos_name, FALSE )) ||
!(file = fopen( unix_name, "w" )))
{
/* Try to create it in $HOME/.wine */
/* FIXME: this will need a more general solution */
if ((p = getenv( "HOME" )) != NULL)
{
strcpy( buffer, p );
strcat( buffer, "/.wine/" );
p = buffer + strlen(buffer);
strcpy( p, strrchr( CurProfile.dos_name, '\\' ) + 1 );
AnsiLower( p );
file = fopen( buffer, "w" );
unix_name = buffer;
}
}
if (!file)
{
fprintf( stderr, "Warning: could not save profile file %s\n",
CurProfile.dos_name );
return FALSE;
}
dprintf_profile( stddeb, "Saving '%s' into '%s'\n",
CurProfile.dos_name, unix_name );
PROFILE_Save( file, CurProfile.section );
fclose( file );
CurProfile.changed = FALSE;
return TRUE;
}
/***********************************************************************
* PROFILE_Open
*
* Open a profile file, checking the cached file first.
*/
static BOOL PROFILE_Open( const char *filename )
{
char buffer[MAX_PATHNAME_LEN];
const char *dos_name, *unix_name;
char *newdos_name, *p;
FILE *file = NULL;
if (strchr( filename, '/' ) || strchr( filename, '\\' ) ||
strchr( filename, ':' ))
{
if (!(dos_name = DOSFS_GetDosTrueName( filename, FALSE))) return FALSE;
}
else
{
GetWindowsDirectory( buffer, sizeof(buffer) );
strcat( buffer, "\\" );
strcat( buffer, filename );
if (!(dos_name = DOSFS_GetDosTrueName( buffer, FALSE ))) return FALSE;
}
if (CurProfile.dos_name && !strcmp( dos_name, CurProfile.dos_name ))
{
dprintf_profile( stddeb, "PROFILE_Open(%s): already opened\n",
filename );
return TRUE;
}
/* Flush the previous profile */
newdos_name = xstrdup( dos_name );
PROFILE_FlushFile();
PROFILE_Free( CurProfile.section );
if (CurProfile.dos_name) free( CurProfile.dos_name );
CurProfile.section = NULL;
CurProfile.dos_name = newdos_name;
/* Try to open the profile file, first in $HOME/.wine */
/* FIXME: this will need a more general solution */
if ((p = getenv( "HOME" )) != NULL)
{
strcpy( buffer, p );
strcat( buffer, "/.wine/" );
p = buffer + strlen(buffer);
strcpy( p, strrchr( newdos_name, '\\' ) + 1 );
AnsiLower( p );
if ((file = fopen( buffer, "r" )))
dprintf_profile( stddeb, "Found it in %s\n", buffer );
}
if (!file && ((unix_name = DOSFS_GetUnixFileName( dos_name, TRUE ))))
{
if ((file = fopen( unix_name, "r" )))
dprintf_profile( stddeb, "Found it in %s\n", unix_name );
}
if (file)
{
CurProfile.section = PROFILE_Load( file );
fclose( file );
}
else
fprintf( stderr, "Warning: profile file %s not found\n", newdos_name );
dprintf_profile( stddeb, "PROFILE_Open(%s): successful\n", filename );
return TRUE;
}
/***********************************************************************
* PROFILE_GetSection
*
* Enumerate all the keys of a section.
*/
static INT PROFILE_GetSection( PROFILESECTION *section,
const char *section_name,
char *buffer, INT len, int handle_env )
{
PROFILEKEY *key;
while (section)
{
if (section->name && !lstrcmpi( section->name, section_name ))
{
INT oldlen = len;
for (key = section->key; key; key = key->next)
{
if (len <= 2) break;
if (IS_ENTRY_COMMENT(key->name)) continue; /* Skip comments */
PROFILE_CopyEntry( buffer, key->name, len - 1, handle_env );
len -= strlen(buffer) + 1;
buffer += strlen(buffer) + 1;
}
*buffer = '\0';
return oldlen - len + 1;
}
section = section->next;
}
buffer[0] = buffer[1] = '\0';
return 2;
}
/***********************************************************************
* PROFILE_GetString
*
* Get a profile string.
*/
static INT PROFILE_GetString( const char *section, const char *key_name,
const char *def_val, char *buffer, INT len )
{
PROFILEKEY *key = NULL;
if (!def_val) def_val = "";
if (key_name)
{
key = PROFILE_Find( &CurProfile.section, section, key_name, FALSE );
PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val,
len, FALSE );
dprintf_profile( stddeb, "PROFILE_GetString('%s','%s','%s'): returning '%s'\n",
section, key_name, def_val, buffer );
return strlen( buffer );
}
return PROFILE_GetSection(CurProfile.section, section, buffer, len, FALSE);
}
/***********************************************************************
* PROFILE_SetString
*
* Set a profile string.
*/
static BOOL PROFILE_SetString( const char *section_name, const char *key_name,
const char *value )
{
BOOL ret;
if (!key_name) /* Delete a whole section */
{
dprintf_profile(stddeb, "PROFILE_DeleteSection('%s')\n", section_name);
ret = PROFILE_DeleteSection( &CurProfile.section, section_name );
CurProfile.changed |= ret;
return ret;
}
else if (!value) /* Delete a key */
{
dprintf_profile( stddeb, "PROFILE_DeleteKey('%s','%s')\n",
section_name, key_name );
ret = PROFILE_DeleteKey( &CurProfile.section, section_name, key_name );
CurProfile.changed |= ret;
return ret;
}
else /* Set the key value */
{
PROFILEKEY *key = PROFILE_Find( &CurProfile.section, section_name,
key_name, TRUE );
dprintf_profile( stddeb, "PROFILE_SetString('%s','%s','%s'): ",
section_name, key_name, value );
if (key->value)
{
if (!strcmp( key->value, value ))
{
dprintf_profile( stddeb, "no change needed\n" );
return TRUE; /* No change needed */
}
dprintf_profile( stddeb, "replacing '%s'\n", key->value );
free( key->value );
}
else dprintf_profile( stddeb, "creating key\n" );
key->value = xstrdup( value );
CurProfile.changed = TRUE;
return TRUE;
}
}
/***********************************************************************
* PROFILE_GetWineIniString
*
* Get a config string from the wine.ini file.
*/
int PROFILE_GetWineIniString( const char *section, const char *key_name,
const char *def, char *buffer, int len )
{
if (key_name)
{
PROFILEKEY *key = PROFILE_Find(&WineProfile, section, key_name, FALSE);
PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def,
len, TRUE );
dprintf_profile( stddeb, "PROFILE_GetWineIniString('%s','%s','%s'): returning '%s'\n",
section, key_name, def, buffer );
return strlen( buffer );
}
return PROFILE_GetSection( WineProfile, section, buffer, len, TRUE );
}
/***********************************************************************
* PROFILE_LoadWineIni
*
* Load the wine.ini file.
*/
int PROFILE_LoadWineIni(void)
{
char buffer[MAX_PATHNAME_LEN];
const char *p;
FILE *f;
if ((p = getenv( "HOME" )) != NULL)
{
lstrcpyn( buffer, p, MAX_PATHNAME_LEN - sizeof(PROFILE_WineIniName) );
strcat( buffer, PROFILE_WineIniName );
if ((f = fopen( buffer, "r" )) != NULL)
{
WineProfile = PROFILE_Load( f );
fclose( f );
return 1;
}
}
else fprintf( stderr, "Warning: could not get $HOME value for config file.\n" );
/* Try global file */
if ((f = fopen( WINE_INI_GLOBAL, "r" )) != NULL)
{
WineProfile = PROFILE_Load( f );
fclose( f );
return 1;
}
fprintf( stderr, "Can't open configuration file %s or $HOME%s\n",
WINE_INI_GLOBAL, PROFILE_WineIniName );
return 0;
}
/***********************************************************************
* GetProfileInt (KERNEL.57)
*/
UINT GetProfileInt( LPCSTR section, LPCSTR entry, INT def_val )
{
return GetPrivateProfileInt( section, entry, def_val, "win.ini" );
}
/***********************************************************************
* GetProfileString (KERNEL.58)
*/
INT GetProfileString( LPCSTR section, LPCSTR entry, LPCSTR def_val,
LPSTR buffer, INT len )
{
return GetPrivateProfileString( section, entry, def_val,
buffer, len, "win.ini" );
}
/***********************************************************************
* WriteProfileString (KERNEL.59)
*/
BOOL WriteProfileString( LPCSTR section, LPCSTR entry, LPCSTR string )
{
return WritePrivateProfileString( section, entry, string, "win.ini" );
}
/***********************************************************************
* GetPrivateProfileInt (KERNEL.127)
*/
UINT GetPrivateProfileInt( LPCSTR section, LPCSTR entry, INT def_val,
LPCSTR filename )
{
char buffer[20];
char *p;
long result;
GetPrivateProfileString( section, entry, "",
buffer, sizeof(buffer), filename );
if (!buffer[0]) return (UINT)def_val;
result = strtol( buffer, &p, 0 );
if (p == buffer) return 0; /* No digits at all */
#ifdef WINELIB32
return (UINT)result;
#else
if (result > 65535) return 65535;
if (result >= 0) return (UINT)result;
if (result < -32768) return -32768;
return (UINT)(INT)result;
#endif
}
/***********************************************************************
* GetPrivateProfileString (KERNEL.128)
*/
INT GetPrivateProfileString( LPCSTR section, LPCSTR entry, LPCSTR def_val,
LPSTR buffer, INT len, LPCSTR filename )
{
if (PROFILE_Open( filename ))
return PROFILE_GetString( section, entry, def_val, buffer, len );
lstrcpyn( buffer, def_val, len );
return strlen( buffer );
}
/***********************************************************************
* WritePrivateProfileString (KERNEL.129)
*/
BOOL WritePrivateProfileString( LPCSTR section, LPCSTR entry, LPCSTR string,
LPCSTR filename )
{
if (!PROFILE_Open( filename )) return FALSE;
if (!section) return PROFILE_FlushFile();
return PROFILE_SetString( section, entry, string );
}
/***********************************************************************
* WriteOutProfiles (KERNEL.315)
*/
void WriteOutProfiles(void)
{
PROFILE_FlushFile();
}