📄 profile.c
字号:
/***********************************************************************
* GetProfileSectionW (KERNEL32.@)
*/
DWORD WINAPI GetProfileSectionW( LPCWSTR section, LPWSTR buffer, DWORD len )
{
return GetPrivateProfileSectionW( section, buffer, len, L"win.ini" );
}
/***********************************************************************
* WritePrivateProfileStringW (KERNEL32.@)
*/
BOOL WINAPI WritePrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
LPCWSTR string, LPCWSTR filename )
{
BOOL ret = FALSE;
RtlEnterCriticalSection( &PROFILE_CritSect );
if (!section && !entry && !string) /* documented "file flush" case */
{
if (!filename || PROFILE_Open( filename ))
{
if (CurProfile) PROFILE_ReleaseFile(); /* always return FALSE in this case */
}
}
else if (PROFILE_Open( filename ))
{
if (!section) {
DPRINT1("(NULL?, %S, %S, %S)?\n",
entry, string, filename);
} else {
ret = PROFILE_SetString( section, entry, string, FALSE);
PROFILE_FlushFile();
}
}
RtlLeaveCriticalSection( &PROFILE_CritSect );
return ret;
}
/***********************************************************************
* WritePrivateProfileStringA (KERNEL32.@)
*/
BOOL WINAPI WritePrivateProfileStringA( LPCSTR section, LPCSTR entry,
LPCSTR string, LPCSTR filename )
{
UNICODE_STRING sectionW, entryW, stringW, filenameW;
BOOL ret;
if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
else sectionW.Buffer = NULL;
if (entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
else entryW.Buffer = NULL;
if (string) RtlCreateUnicodeStringFromAsciiz(&stringW, string);
else stringW.Buffer = NULL;
if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
ret = WritePrivateProfileStringW(sectionW.Buffer, entryW.Buffer,
stringW.Buffer, filenameW.Buffer);
RtlFreeUnicodeString(§ionW);
RtlFreeUnicodeString(&entryW);
RtlFreeUnicodeString(&stringW);
RtlFreeUnicodeString(&filenameW);
return ret;
}
/***********************************************************************
* WritePrivateProfileSectionW (KERNEL32.@)
*/
BOOL WINAPI WritePrivateProfileSectionW( LPCWSTR section,
LPCWSTR string, LPCWSTR filename )
{
BOOL ret = FALSE;
LPWSTR p;
RtlEnterCriticalSection( &PROFILE_CritSect );
if (!section && !string)
{
if (!filename || PROFILE_Open( filename ))
{
if (CurProfile) PROFILE_ReleaseFile(); /* always return FALSE in this case */
}
}
else if (PROFILE_Open( filename )) {
if (!string) {/* delete the named section*/
ret = PROFILE_SetString(section,NULL,NULL, FALSE);
PROFILE_FlushFile();
} else {
PROFILE_DeleteAllKeys(section);
ret = TRUE;
while(*string) {
LPWSTR buf = HeapAlloc( GetProcessHeap(), 0, (wcslen(string)+1) * sizeof(WCHAR) );
if(buf == NULL)
{
RtlLeaveCriticalSection( &PROFILE_CritSect );
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
wcscpy( buf, string );
if((p = wcschr( buf, '='))) {
*p = '\0';
ret = PROFILE_SetString( section, buf, p + 1, TRUE);
}
HeapFree( GetProcessHeap(), 0, buf );
string += wcslen(string) + 1;
}
PROFILE_FlushFile();
}
}
RtlLeaveCriticalSection( &PROFILE_CritSect );
return ret;
}
/***********************************************************************
* WritePrivateProfileSectionA (KERNEL32.@)
*/
BOOL WINAPI WritePrivateProfileSectionA( LPCSTR section,
LPCSTR string, LPCSTR filename)
{
UNICODE_STRING sectionW, filenameW;
LPWSTR stringW;
BOOL ret;
if (string)
{
INT lenA, lenW;
LPCSTR p = string;
while(*p) p += strlen(p) + 1;
lenA = p - string + 1;
lenW = MultiByteToWideChar(CP_ACP, 0, string, lenA, NULL, 0);
if ((stringW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR))))
MultiByteToWideChar(CP_ACP, 0, string, lenA, stringW, lenW);
}
else stringW = NULL;
if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
else sectionW.Buffer = NULL;
if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
ret = WritePrivateProfileSectionW(sectionW.Buffer, stringW, filenameW.Buffer);
HeapFree(GetProcessHeap(), 0, stringW);
RtlFreeUnicodeString(§ionW);
RtlFreeUnicodeString(&filenameW);
return ret;
}
/***********************************************************************
* WriteProfileSectionA (KERNEL32.@)
*/
BOOL WINAPI WriteProfileSectionA( LPCSTR section, LPCSTR keys_n_values)
{
return WritePrivateProfileSectionA(section, keys_n_values, "win.ini");
}
/***********************************************************************
* WriteProfileSectionW (KERNEL32.@)
*/
BOOL WINAPI WriteProfileSectionW( LPCWSTR section, LPCWSTR keys_n_values)
{
return WritePrivateProfileSectionW(section, keys_n_values, L"win.ini");
}
/***********************************************************************
* GetPrivateProfileSectionNamesW (KERNEL32.@)
*
* Returns the section names contained in the specified file.
* FIXME: Where do we find this file when the path is relative?
* The section names are returned as a list of strings with an extra
* '\0' to mark the end of the list. Except for that the behavior
* depends on the Windows version.
*
* Win95:
* - if the buffer is 0 or 1 character long then it is as if it was of
* infinite length.
* - otherwise, if the buffer is to small only the section names that fit
* are returned.
* - note that this means if the buffer was to small to return even just
* the first section name then a single '\0' will be returned.
* - the return value is the number of characters written in the buffer,
* except if the buffer was too smal in which case len-2 is returned
*
* Win2000:
* - if the buffer is 0, 1 or 2 characters long then it is filled with
* '\0' and the return value is 0
* - otherwise if the buffer is too small then the first section name that
* does not fit is truncated so that the string list can be terminated
* correctly (double '\0')
* - the return value is the number of characters written in the buffer
* except for the trailing '\0'. If the buffer is too small, then the
* return value is len-2
* - Win2000 has a bug that triggers when the section names and the
* trailing '\0' fit exactly in the buffer. In that case the trailing
* '\0' is missing.
*
* Wine implements the observed Win2000 behavior (except for the bug).
*
* Note that when the buffer is big enough then the return value may be any
* value between 1 and len-1 (or len in Win95), including len-2.
*/
DWORD WINAPI GetPrivateProfileSectionNamesW( LPWSTR buffer, DWORD size,
LPCWSTR filename)
{
DWORD ret = 0;
RtlEnterCriticalSection( &PROFILE_CritSect );
if (PROFILE_Open( filename ))
ret = PROFILE_GetSectionNames(buffer, size);
RtlLeaveCriticalSection( &PROFILE_CritSect );
return ret;
}
/***********************************************************************
* GetPrivateProfileSectionNamesA (KERNEL32.@)
*/
DWORD WINAPI GetPrivateProfileSectionNamesA( LPSTR buffer, DWORD size,
LPCSTR filename)
{
UNICODE_STRING filenameW;
LPWSTR bufferW;
INT retW, ret = 0;
bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)) : NULL;
if (filename)
RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else
filenameW.Buffer = NULL;
retW = GetPrivateProfileSectionNamesW(bufferW, size, filenameW.Buffer);
if (retW && size)
{
ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW, buffer, size, NULL, NULL);
if (!ret)
{
ret = size;
buffer[size-1] = 0;
}
}
RtlFreeUnicodeString(&filenameW);
HeapFree(GetProcessHeap(), 0, bufferW);
return ret;
}
/***********************************************************************
* GetPrivateProfileStructW (KERNEL32.@)
*
* Should match Win95's behaviour pretty much
*/
BOOL WINAPI GetPrivateProfileStructW (LPCWSTR section, LPCWSTR key,
LPVOID buf, UINT len, LPCWSTR filename)
{
BOOL ret = FALSE;
RtlEnterCriticalSection( &PROFILE_CritSect );
if (PROFILE_Open( filename ))
{
PROFILEKEY *k = PROFILE_Find ( &CurProfile->section, section, key, FALSE, FALSE);
if (k)
{
DPRINT("value (at %p): %S\n", k->value, k->value);
if (((wcslen(k->value) - 2) / 2) == len)
{
LPWSTR end, p;
BOOL valid = TRUE;
WCHAR c;
DWORD chksum = 0;
end = k->value + wcslen(k->value); /* -> '\0' */
/* check for invalid chars in ASCII coded hex string */
for (p = k->value; p < end; p++)
{
if (!isxdigit(*p))
{
DPRINT("invalid char '%x' in file %S->[%S]->%S !\n",
*p, filename, section, key);
valid = FALSE;
break;
}
}
if (valid)
{
BOOL highnibble = TRUE;
BYTE b = 0, val;
LPBYTE binbuf = (LPBYTE)buf;
end -= 2; /* don't include checksum in output data */
/* translate ASCII hex format into binary data */
for (p = k->value; p < end; p++)
{
c = towupper(*p);
val = (c > '9') ? (c - 'A' + 10) : (c - '0');
if (highnibble)
b = val << 4;
else
{
b += val;
*binbuf++ = b; /* feed binary data into output */
chksum += b; /* calculate checksum */
}
highnibble ^= 1; /* toggle */
}
/* retrieve stored checksum value */
c = towupper(*p++);
b = ( (c > '9') ? (c - 'A' + 10) : (c - '0') ) << 4;
c = towupper(*p);
b += (c > '9') ? (c - 'A' + 10) : (c - '0');
if (b == (chksum & 0xff)) /* checksums match ? */
ret = TRUE;
}
}
}
}
RtlLeaveCriticalSection( &PROFILE_CritSect );
return ret;
}
/***********************************************************************
* GetPrivateProfileStructA (KERNEL32.@)
*/
BOOL WINAPI GetPrivateProfileStructA (LPCSTR section, LPCSTR key,
LPVOID buffer, UINT len, LPCSTR filename)
{
UNICODE_STRING sectionW, keyW, filenameW;
INT ret;
if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
else sectionW.Buffer = NULL;
if (key) RtlCreateUnicodeStringFromAsciiz(&keyW, key);
else keyW.Buffer = NULL;
if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
ret = GetPrivateProfileStructW(sectionW.Buffer, keyW.Buffer, buffer, len,
filenameW.Buffer);
/* Do not translate binary data. */
RtlFreeUnicodeString(§ionW);
RtlFreeUnicodeString(&keyW);
RtlFreeUnicodeString(&filenameW);
return ret;
}
/***********************************************************************
* WritePrivateProfileStructW (KERNEL32.@)
*/
BOOL WINAPI WritePrivateProfileStructW (LPCWSTR section, LPCWSTR key,
LPVOID buf, UINT bufsize, LPCWSTR filename)
{
BOOL ret = FALSE;
LPBYTE binbuf;
LPWSTR outstring, p;
DWORD sum = 0;
if (!section && !key && !buf) /* flush the cache */
return WritePrivateProfileStringW( NULL, NULL, NULL, filename );
/* allocate string buffer for hex chars + checksum hex char + '\0' */
outstring = HeapAlloc( GetProcessHeap(), 0, (bufsize*2 + 2 + 1) * sizeof(WCHAR) );
if(outstring == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
p = outstring;
for (binbuf = (LPBYTE)buf; binbuf < (LPBYTE)buf+bufsize; binbuf++)
{
*p++ = hex[*binbuf >> 4];
*p++ = hex[*binbuf & 0xf];
sum += *binbuf;
}
/* checksum is sum & 0xff */
*p++ = hex[(sum & 0xf0) >> 4];
*p++ = hex[sum & 0xf];
*p++ = '\0';
RtlEnterCriticalSection( &PROFILE_CritSect );
if (PROFILE_Open( filename ))
{
ret = PROFILE_SetString( section, key, outstring, FALSE);
PROFILE_FlushFile();
}
RtlLeaveCriticalSection( &PROFILE_CritSect );
HeapFree( GetProcessHeap(), 0, outstring );
return ret;
}
/***********************************************************************
* WritePrivateProfileStructA (KERNEL32.@)
*/
BOOL WINAPI
WritePrivateProfileStructA (LPCSTR section, LPCSTR key,
LPVOID buf, UINT bufsize, LPCSTR filename)
{
UNICODE_STRING sectionW, keyW, filenameW;
INT ret;
if (section) RtlCreateUnicodeStringFromAsciiz(§ionW, section);
else sectionW.Buffer = NULL;
if (key) RtlCreateUnicodeStringFromAsciiz(&keyW, key);
else keyW.Buffer = NULL;
if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
/* Do not translate binary data. */
ret = WritePrivateProfileStructW(sectionW.Buffer, keyW.Buffer, buf, bufsize,
filenameW.Buffer);
RtlFreeUnicodeString(§ionW);
RtlFreeUnicodeString(&keyW);
RtlFreeUnicodeString(&filenameW);
return ret;
}
/***********************************************************************
* CloseProfileUserMapping
*/
BOOL WINAPI
CloseProfileUserMapping(VOID)
{
DPRINT1("(), stub!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
BOOL
STDCALL
QueryWin31IniFilesMappedToRegistry(DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2,
DWORD Unknown3)
{
DPRINT1("QueryWin31IniFilesMappedToRegistry not implemented\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -