kernel32: Reimplement Get/WritePrivateProfileStructW functions using exported APIs.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-04-01 10:27:53 +02:00
parent 5a5db91edd
commit 30ad67dc14

View file

@ -1600,6 +1600,23 @@ DWORD WINAPI GetPrivateProfileSectionNamesA( LPSTR buffer, DWORD size,
return ret; return ret;
} }
static int get_hex_byte( const WCHAR *p )
{
int val;
if (*p >= '0' && *p <= '9') val = *p - '0';
else if (*p >= 'A' && *p <= 'Z') val = *p - 'A' + 10;
else if (*p >= 'a' && *p <= 'z') val = *p - 'a' + 10;
else return -1;
val <<= 4;
p++;
if (*p >= '0' && *p <= '9') val += *p - '0';
else if (*p >= 'A' && *p <= 'Z') val += *p - 'A' + 10;
else if (*p >= 'a' && *p <= 'z') val += *p - 'a' + 10;
else return -1;
return val;
}
/*********************************************************************** /***********************************************************************
* GetPrivateProfileStructW (KERNEL32.@) * GetPrivateProfileStructW (KERNEL32.@)
* *
@ -1608,70 +1625,29 @@ DWORD WINAPI GetPrivateProfileSectionNamesA( LPSTR buffer, DWORD size,
BOOL WINAPI GetPrivateProfileStructW (LPCWSTR section, LPCWSTR key, BOOL WINAPI GetPrivateProfileStructW (LPCWSTR section, LPCWSTR key,
LPVOID buf, UINT len, LPCWSTR filename) LPVOID buf, UINT len, LPCWSTR filename)
{ {
BOOL ret = FALSE; BOOL ret = FALSE;
LPBYTE data = buf;
BYTE chksum = 0;
int val;
WCHAR *p, *buffer;
RtlEnterCriticalSection( &PROFILE_CritSect ); if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (2 * len + 3) * sizeof(WCHAR) ))) return FALSE;
if (PROFILE_Open( filename, FALSE )) { if (GetPrivateProfileStringW( section, key, NULL, buffer, 2 * len + 3, filename ) != 2 * len + 2)
PROFILEKEY *k = PROFILE_Find ( &CurProfile->section, section, key, FALSE, FALSE); goto done;
if (k) {
TRACE("value (at %p): %s\n", k->value, debugstr_w(k->value));
if (((strlenW(k->value) - 2) / 2) == len)
{
LPWSTR end, p;
BOOL valid = TRUE;
WCHAR c;
DWORD chksum = 0;
end = k->value + strlenW(k->value); /* -> '\0' */ for (p = buffer; len; p += 2, len--)
/* check for invalid chars in ASCII coded hex string */ {
for (p=k->value; p < end; p++) if ((val = get_hex_byte( p )) == -1) goto done;
{ *data++ = val;
if (!isxdigitW(*p)) chksum += val;
{
WARN("invalid char '%x' in file %s->[%s]->%s !\n",
*p, debugstr_w(filename), debugstr_w(section), debugstr_w(key));
valid = FALSE;
break;
}
}
if (valid)
{
BOOL highnibble = TRUE;
BYTE b = 0, val;
LPBYTE binbuf = 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 = toupperW(*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 = toupperW(*p++);
b = ( (c > '9') ? (c - 'A' + 10) : (c - '0') ) << 4;
c = toupperW(*p);
b += (c > '9') ? (c - 'A' + 10) : (c - '0');
if (b == (chksum & 0xff)) /* checksums match ? */
ret = TRUE;
}
}
}
} }
RtlLeaveCriticalSection( &PROFILE_CritSect ); /* retrieve stored checksum value */
if ((val = get_hex_byte( p )) == -1) goto done;
ret = ((BYTE)val == chksum);
done:
HeapFree( GetProcessHeap(), 0, buffer );
return ret; return ret;
} }
@ -1730,17 +1706,8 @@ BOOL WINAPI WritePrivateProfileStructW (LPCWSTR section, LPCWSTR key,
*p++ = hex[sum & 0xf]; *p++ = hex[sum & 0xf];
*p++ = '\0'; *p++ = '\0';
RtlEnterCriticalSection( &PROFILE_CritSect ); ret = WritePrivateProfileStringW( section, key, outstring, filename );
if (PROFILE_Open( filename, TRUE )) {
ret = PROFILE_SetString( section, key, outstring, FALSE);
if (ret) ret = PROFILE_FlushFile();
}
RtlLeaveCriticalSection( &PROFILE_CritSect );
HeapFree( GetProcessHeap(), 0, outstring ); HeapFree( GetProcessHeap(), 0, outstring );
return ret; return ret;
} }