Commit 1120a1cb authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

crypt32: Support CRYPT_STRING_HEX in CryptStringToBinary().

parent a79ec1c5
......@@ -943,6 +943,120 @@ static LONG DecodeAnyA(LPCSTR pszString, DWORD cchString,
return ret;
}
static BOOL is_hex_string_special_char(WCHAR c)
{
switch (c)
{
case '-':
case ',':
case ' ':
case '\t':
case '\r':
case '\n':
return TRUE;
default:
return FALSE;
}
}
static WCHAR wchar_from_str(BOOL wide, const void **str, DWORD *len)
{
WCHAR c;
if (!*len)
return 0;
--*len;
if (wide)
c = *(*(const WCHAR **)str)++;
else
c = *(*(const char **)str)++;
return c ? c : 0xffff;
}
static BYTE digit_from_char(WCHAR c)
{
if (c >= '0' && c <= '9')
return c - '0';
c = towlower(c);
if (c >= 'a' && c <= 'f')
return c - 'a' + 0xa;
return 0xff;
}
static LONG string_to_hex(const void* str, BOOL wide, DWORD len, BYTE *hex, DWORD *hex_len,
DWORD *skipped, DWORD *ret_flags)
{
unsigned int byte_idx = 0;
BYTE d1, d2;
WCHAR c;
if (!str || !hex_len)
return ERROR_INVALID_PARAMETER;
if (!len)
len = wide ? wcslen(str) : strlen(str);
if (wide && !len)
return ERROR_INVALID_PARAMETER;
if (skipped)
*skipped = 0;
if (ret_flags)
*ret_flags = 0;
while ((c = wchar_from_str(wide, &str, &len)) && is_hex_string_special_char(c))
;
while ((d1 = digit_from_char(c)) != 0xff)
{
if ((d2 = digit_from_char(wchar_from_str(wide, &str, &len))) == 0xff)
{
if (!hex)
*hex_len = 0;
return ERROR_INVALID_DATA;
}
if (hex && byte_idx < *hex_len)
hex[byte_idx] = (d1 << 4) | d2;
++byte_idx;
do
{
c = wchar_from_str(wide, &str, &len);
} while (c == '-' || c == ',');
}
while (c)
{
if (!is_hex_string_special_char(c))
{
if (!hex)
*hex_len = 0;
return ERROR_INVALID_DATA;
}
c = wchar_from_str(wide, &str, &len);
}
if (hex && byte_idx > *hex_len)
return ERROR_MORE_DATA;
if (ret_flags)
*ret_flags = CRYPT_STRING_HEX;
*hex_len = byte_idx;
return ERROR_SUCCESS;
}
static LONG string_to_hexA(const char *str, DWORD len, BYTE *hex, DWORD *hex_len, DWORD *skipped, DWORD *ret_flags)
{
return string_to_hex(str, FALSE, len, hex, hex_len, skipped, ret_flags);
}
BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString,
DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary,
DWORD *pdwSkip, DWORD *pdwFlags)
......@@ -988,6 +1102,8 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString,
decoder = DecodeAnyA;
break;
case CRYPT_STRING_HEX:
decoder = string_to_hexA;
break;
case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR:
case CRYPT_STRING_HEXASCIIADDR:
......@@ -1154,6 +1270,11 @@ static LONG DecodeAnyW(LPCWSTR pszString, DWORD cchString,
return ret;
}
static LONG string_to_hexW(const WCHAR *str, DWORD len, BYTE *hex, DWORD *hex_len, DWORD *skipped, DWORD *ret_flags)
{
return string_to_hex(str, TRUE, len, hex, hex_len, skipped, ret_flags);
}
BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString,
DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary,
DWORD *pdwSkip, DWORD *pdwFlags)
......@@ -1199,6 +1320,8 @@ BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString,
decoder = DecodeAnyW;
break;
case CRYPT_STRING_HEX:
decoder = string_to_hexW;
break;
case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR:
case CRYPT_STRING_HEXASCIIADDR:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment