📄 profile.c
字号:
if (buflen > 0) {
memcpy(buf, section->name, (buflen - 1) * sizeof(WCHAR));
buf += buflen - 1;
*buf++ = '\0';
}
*buf='\0';
return len - 2;
}
memcpy(buf, section->name, tmplen * sizeof(WCHAR));
buf += tmplen;
buflen -= tmplen;
}
section = section->next;
}
*buf = '\0';
return buf - buffer;
}
/***********************************************************************
* PROFILE_GetString
*
* Get a profile string.
*
* Tests with GetPrivateProfileString16, W95a,
* with filled buffer ("****...") and section "set1" and key_name "1" valid:
* section key_name def_val res buffer
* "set1" "1" "x" 43 [data]
* "set1" "1 " "x" 43 [data] (!)
* "set1" " 1 "' "x" 43 [data] (!)
* "set1" "" "x" 1 "x"
* "set1" "" "x " 1 "x" (!)
* "set1" "" " x " 3 " x" (!)
* "set1" NULL "x" 6 "1\02\03\0\0"
* "set1" "" "x" 1 "x"
* NULL "1" "x" 0 "" (!)
* "" "1" "x" 1 "x"
* NULL NULL "" 0 ""
*
*
*/
static INT PROFILE_GetString( LPCWSTR section, LPCWSTR key_name,
LPCWSTR def_val, LPWSTR buffer, UINT len, BOOL win32 )
{
PROFILEKEY *key = NULL;
static const WCHAR empty_strW[] = { 0 };
if (!buffer) return 0;
if (!def_val) def_val = empty_strW;
if (key_name)
{
if (!key_name[0])
{
/* Win95 returns 0 on keyname "". Tested with Likse32 bon 000227 */
return 0;
}
key = PROFILE_Find( &CurProfile->section, section, key_name, FALSE, FALSE);
PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val,
len, TRUE );
DPRINT("(%S, %S, %S): returning %S\n",
section, key_name,
def_val, buffer);
return wcslen(buffer);
}
/* no "else" here ! */
if (section && section[0])
{
INT ret = PROFILE_GetSection(CurProfile->section, section, buffer, len, FALSE, !win32);
if (!buffer[0]) /* no luck -> def_val */
{
PROFILE_CopyEntry(buffer, def_val, len, TRUE);
ret = wcslen(buffer);
}
return ret;
}
buffer[0] = '\0';
return 0;
}
/***********************************************************************
* PROFILE_SetString
*
* Set a profile string.
*/
static BOOL PROFILE_SetString( LPCWSTR section_name, LPCWSTR key_name,
LPCWSTR value, BOOL create_always )
{
if (!key_name) /* Delete a whole section */
{
DPRINT("(%S)\n", section_name);
CurProfile->changed |= PROFILE_DeleteSection( &CurProfile->section,
section_name );
return TRUE; /* Even if PROFILE_DeleteSection() has failed,
this is not an error on application's level.*/
}
else if (!value) /* Delete a key */
{
DPRINT("(%S, %S)\n", section_name, key_name);
CurProfile->changed |= PROFILE_DeleteKey( &CurProfile->section,
section_name, key_name );
return TRUE; /* same error handling as above */
}
else /* Set the key value */
{
PROFILEKEY *key = PROFILE_Find(&CurProfile->section, section_name,
key_name, TRUE, create_always );
DPRINT("(%S, %S, %S):\n",
section_name, key_name, value);
if (!key) return FALSE;
/* strip the leading spaces. We can safely strip \n\r and
* friends too, they should not happen here anyway. */
while (PROFILE_isspaceW(*value)) value++;
if (key->value)
{
if (!wcscmp( key->value, value ))
{
DPRINT(" no change needed\n" );
return TRUE; /* No change needed */
}
DPRINT(" replacing %S\n", key->value);
HeapFree( GetProcessHeap(), 0, key->value );
}
else
{
DPRINT(" creating key\n");
}
key->value = HeapAlloc( GetProcessHeap(), 0, (wcslen(value) + 1) * sizeof(WCHAR) );
if(key->value == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
wcscpy( key->value, value );
CurProfile->changed = TRUE;
}
return TRUE;
}
/********************* API functions **********************************/
/***********************************************************************
* GetProfileIntA (KERNEL32.@)
*/
UINT WINAPI GetProfileIntA( LPCSTR section, LPCSTR entry, INT def_val )
{
return GetPrivateProfileIntA( section, entry, def_val, "win.ini" );
}
/***********************************************************************
* GetProfileIntW (KERNEL32.@)
*/
UINT WINAPI GetProfileIntW( LPCWSTR section, LPCWSTR entry, INT def_val )
{
return GetPrivateProfileIntW( section, entry, def_val, L"win.ini" );
}
/*
* if win32, copy:
* - Section names if 'section' is NULL
* - Keys in a Section if 'entry' is NULL
* (see MSDN doc for GetPrivateProfileString)
*/
static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
LPCWSTR def_val, LPWSTR buffer,
UINT len, LPCWSTR filename,
BOOL win32 )
{
int ret;
LPCWSTR pDefVal = NULL;
if (!filename)
filename = L"win.ini";
DPRINT("%S, %S, %S, %p, %u, %S\n",
section, entry,
def_val, buffer, len, filename);
/* strip any trailing ' ' of def_val. */
if (def_val)
{
LPCWSTR p = &def_val[wcslen(def_val)]; /* even "" works ! */
while (p > def_val)
{
p--;
if ((*p) != ' ')
break;
}
if (*p == ' ') /* ouch, contained trailing ' ' */
{
int len = (int)(p - def_val);
LPWSTR p;
p = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if(p == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
memcpy(p, def_val, len * sizeof(WCHAR));
p[len] = '\0';
pDefVal = p;
}
}
if (!pDefVal)
pDefVal = (LPCWSTR)def_val;
RtlEnterCriticalSection( &PROFILE_CritSect );
if (PROFILE_Open( filename )) {
if (win32 && (section == NULL))
ret = PROFILE_GetSectionNames(buffer, len);
else
/* PROFILE_GetString can handle the 'entry == NULL' case */
ret = PROFILE_GetString( section, entry, pDefVal, buffer, len, win32 );
} else {
lstrcpynW( buffer, pDefVal, len );
ret = wcslen( buffer );
}
RtlLeaveCriticalSection( &PROFILE_CritSect );
if (pDefVal != def_val) /* allocated */
HeapFree(GetProcessHeap(), 0, (void*)pDefVal);
DPRINT("returning %S, %d\n", buffer, ret);
return ret;
}
/***********************************************************************
* GetPrivateProfileStringA (KERNEL32.@)
*/
DWORD WINAPI GetPrivateProfileStringA( LPCSTR section, LPCSTR entry,
LPCSTR def_val, LPSTR buffer,
DWORD len, LPCSTR filename )
{
UNICODE_STRING sectionW, entryW, def_valW, filenameW;
LPWSTR bufferW;
INT retW, ret = 0;
bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
else sectionW.Buffer = NULL;
if (entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
else entryW.Buffer = NULL;
if (def_val) RtlCreateUnicodeStringFromAsciiz(&def_valW, def_val);
else def_valW.Buffer = NULL;
if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
retW = GetPrivateProfileStringW( sectionW.Buffer, entryW.Buffer,
def_valW.Buffer, bufferW, len,
filenameW.Buffer);
if (len)
{
ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW + 1, buffer, len, NULL, NULL);
if (!ret)
{
ret = len - 1;
buffer[ret] = 0;
}
else
ret--; /* strip terminating 0 */
}
RtlFreeUnicodeString(§ionW);
RtlFreeUnicodeString(&entryW);
RtlFreeUnicodeString(&def_valW);
RtlFreeUnicodeString(&filenameW);
HeapFree(GetProcessHeap(), 0, bufferW);
return ret;
}
/***********************************************************************
* GetPrivateProfileStringW (KERNEL32.@)
*/
DWORD WINAPI GetPrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
LPCWSTR def_val, LPWSTR buffer,
DWORD len, LPCWSTR filename )
{
DPRINT("(%S, %S, %S, %p, %d, %S)\n",
section, entry, def_val, buffer, len, filename);
return PROFILE_GetPrivateProfileString( section, entry, def_val,
buffer, len, filename, TRUE );
}
/***********************************************************************
* GetProfileStringA (KERNEL32.@)
*/
DWORD WINAPI GetProfileStringA( LPCSTR section, LPCSTR entry, LPCSTR def_val,
LPSTR buffer, DWORD len )
{
return GetPrivateProfileStringA( section, entry, def_val,
buffer, len, "win.ini" );
}
/***********************************************************************
* GetProfileStringW (KERNEL32.@)
*/
DWORD WINAPI GetProfileStringW( LPCWSTR section, LPCWSTR entry,
LPCWSTR def_val, LPWSTR buffer, DWORD len )
{
return GetPrivateProfileStringW( section, entry, def_val,
buffer, len, L"win.ini" );
}
/***********************************************************************
* WriteProfileStringA (KERNEL32.@)
*/
BOOL WINAPI WriteProfileStringA( LPCSTR section, LPCSTR entry,
LPCSTR string )
{
return WritePrivateProfileStringA( section, entry, string, "win.ini" );
}
/***********************************************************************
* WriteProfileStringW (KERNEL32.@)
*/
BOOL WINAPI WriteProfileStringW( LPCWSTR section, LPCWSTR entry,
LPCWSTR string )
{
return WritePrivateProfileStringW( section, entry, string, L"win.ini" );
}
/***********************************************************************
* GetPrivateProfileIntW (KERNEL32.@)
*/
UINT WINAPI GetPrivateProfileIntW( LPCWSTR section, LPCWSTR entry,
INT def_val, LPCWSTR filename )
{
WCHAR buffer[30];
UNICODE_STRING bufferW;
INT len;
ULONG result;
if (!(len = GetPrivateProfileStringW( section, entry, emptystringW,
buffer, sizeof(buffer)/sizeof(WCHAR),
filename )))
return def_val;
if (len+1 == sizeof(buffer)/sizeof(WCHAR))
DPRINT1("result may be wrong!\n");
/* FIXME: if entry can be found but it's empty, then Win16 is
* supposed to return 0 instead of def_val ! Difficult/problematic
* to implement (every other failure also returns zero buffer),
* thus wait until testing framework avail for making sure nothing
* else gets broken that way. */
if (!buffer[0])
return (UINT)def_val;
RtlInitUnicodeString( &bufferW, buffer );
RtlUnicodeStringToInteger( &bufferW, 10, &result);
return result;
}
/***********************************************************************
* GetPrivateProfileIntA (KERNEL32.@)
*
* FIXME: rewrite using unicode
*/
UINT WINAPI GetPrivateProfileIntA( LPCSTR section, LPCSTR entry,
INT def_val, LPCSTR filename )
{
UNICODE_STRING entryW, filenameW, sectionW;
UINT res;
if(entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
else entryW.Buffer = NULL;
if(filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
if(section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
else sectionW.Buffer = NULL;
res = GetPrivateProfileIntW(sectionW.Buffer, entryW.Buffer, def_val,
filenameW.Buffer);
RtlFreeUnicodeString(§ionW);
RtlFreeUnicodeString(&filenameW);
RtlFreeUnicodeString(&entryW);
return res;
}
/***********************************************************************
* GetPrivateProfileSectionW (KERNEL32.@)
*/
DWORD WINAPI GetPrivateProfileSectionW( LPCWSTR section, LPWSTR buffer,
DWORD len, LPCWSTR filename )
{
int ret = 0;
DPRINT("(%S, %p, %ld, %S)\n",
section, buffer, len, filename);
RtlEnterCriticalSection( &PROFILE_CritSect );
if (PROFILE_Open( filename ))
ret = PROFILE_GetSection(CurProfile->section, section, buffer, len, TRUE, FALSE);
RtlLeaveCriticalSection( &PROFILE_CritSect );
return ret;
}
/***********************************************************************
* GetPrivateProfileSectionA (KERNEL32.@)
*/
DWORD WINAPI GetPrivateProfileSectionA( LPCSTR section, LPSTR buffer,
DWORD len, LPCSTR filename )
{
UNICODE_STRING sectionW, filenameW;
LPWSTR bufferW;
INT retW, ret = 0;
bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
else sectionW.Buffer = NULL;
if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
retW = GetPrivateProfileSectionW(sectionW.Buffer, bufferW, len, filenameW.Buffer);
if (len > 2)
{
ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW + 2, buffer, len, NULL, NULL);
if (ret > 2)
ret -= 2;
else
{
ret = 0;
buffer[len-2] = 0;
buffer[len-1] = 0;
}
}
else
{
buffer[0] = 0;
buffer[1] = 0;
}
RtlFreeUnicodeString(§ionW);
RtlFreeUnicodeString(&filenameW);
HeapFree(GetProcessHeap(), 0, bufferW);
return ret;
}
/***********************************************************************
* GetProfileSectionA (KERNEL32.@)
*/
DWORD WINAPI GetProfileSectionA( LPCSTR section, LPSTR buffer, DWORD len )
{
return GetPrivateProfileSectionA( section, buffer, len, "win.ini" );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -