Commit f92581ee authored by Daniel Lehman's avatar Daniel Lehman Committed by Alexandre Julliard

crypt32: Implement CryptBinaryToStringW(HEXRAW).

parent 6f8ae18c
......@@ -477,6 +477,49 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary,
return ret;
}
static BOOL BinaryToHexW(const BYTE *bin, DWORD nbin, DWORD flags, LPWSTR str, DWORD *nstr)
{
static const WCHAR hex[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
DWORD needed;
if (flags & CRYPT_STRING_NOCRLF)
needed = 0;
else if (flags & CRYPT_STRING_NOCR)
needed = 1;
else
needed = 2;
needed += nbin * 2 + 1;
if (needed > *nstr)
{
SetLastError(ERROR_MORE_DATA);
return FALSE;
}
*nstr = needed;
if (!str)
return TRUE;
while (nbin--)
{
*str++ = hex[(*bin >> 4) & 0xf];
*str++ = hex[*bin & 0xf];
bin++;
}
if (flags & CRYPT_STRING_NOCR)
*str++ = '\n';
else if (!(flags & CRYPT_STRING_NOCRLF))
{
*str++ = '\r';
*str++ = '\n';
}
*str = 0;
*nstr = needed - 1;
return TRUE;
}
BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
{
......@@ -507,6 +550,9 @@ BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary,
case CRYPT_STRING_BASE64X509CRLHEADER:
encoder = BinaryToBase64W;
break;
case CRYPT_STRING_HEXRAW:
encoder = BinaryToHexW;
break;
case CRYPT_STRING_HEX:
case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR:
......
......@@ -238,7 +238,12 @@ static void encode_compare_base64_W(const BYTE *toEncode, DWORD toEncodeLen, DWO
static void test_CryptBinaryToString(void)
{
DWORD strLen, strLen2, i;
static const DWORD flags[] = { 0, CRYPT_STRING_NOCR, CRYPT_STRING_NOCRLF };
static const WCHAR hexdig[] = L"0123456789abcdef";
OSVERSIONINFOA ver = { sizeof(ver) };
BYTE input[256 * sizeof(WCHAR)];
DWORD strLen, strLen2, i, j;
WCHAR *hex, *cmp, *ptr;
BOOL ret;
ret = CryptBinaryToStringA(NULL, 0, 0, NULL, NULL);
......@@ -357,6 +362,81 @@ static void test_CryptBinaryToString(void)
heap_free(encodedW);
}
/* winxp and win2k3 are documented as not handling HEXRAW but do not return failure */
GetVersionExA(&ver);
if (ver.dwMajorVersion <= 5)
{
win_skip("CryptBinaryToString(HEX) not supported\n");
return;
}
for (i = 0; i < sizeof(input) / sizeof(WCHAR); i++)
((WCHAR *)input)[i] = i;
for (i = 0; i < ARRAY_SIZE(flags); i++)
{
strLen = ~0;
ret = CryptBinaryToStringW(input, sizeof(input), CRYPT_STRING_HEXRAW|flags[i],
NULL, &strLen);
ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError());
if (flags[i] & CRYPT_STRING_NOCRLF)
strLen2 = 0;
else if (flags[i] & CRYPT_STRING_NOCR)
strLen2 = 1;
else
strLen2 = 2;
strLen2 += sizeof(input) * 2 + 1;
ok(strLen == strLen2, "Expected length %d, got %d\n", strLen2, strLen);
hex = heap_alloc(strLen * sizeof(WCHAR));
memset(hex, 0xcc, strLen * sizeof(WCHAR));
ptr = cmp = heap_alloc(strLen * sizeof(WCHAR));
for (j = 0; j < ARRAY_SIZE(input); j++)
{
*ptr++ = hexdig[(input[j] >> 4) & 0xf];
*ptr++ = hexdig[input[j] & 0xf];
}
if (flags[i] & CRYPT_STRING_NOCR)
{
*ptr++ = '\n';
}
else if (!(flags[i] & CRYPT_STRING_NOCRLF))
{
*ptr++ = '\r';
*ptr++ = '\n';
}
*ptr++ = 0;
ret = CryptBinaryToStringW(input, sizeof(input), CRYPT_STRING_HEXRAW|flags[i],
hex, &strLen);
ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError());
strLen2--;
ok(strLen == strLen2, "Expected length %d, got %d\n", strLen, strLen2);
ok(!memcmp(hex, cmp, strLen * sizeof(WCHAR)), "Unexpected value\n");
/* adjusts size if buffer too big */
strLen *= 2;
ret = CryptBinaryToStringW(input, sizeof(input), CRYPT_STRING_HEXRAW|flags[i],
hex, &strLen);
ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError());
ok(strLen == strLen2, "Expected length %d, got %d\n", strLen, strLen2);
/* no writes if buffer too small */
strLen /= 2;
strLen2 /= 2;
memset(hex, 0xcc, strLen * sizeof(WCHAR));
memset(cmp, 0xcc, strLen * sizeof(WCHAR));
SetLastError(0xdeadbeef);
ret = CryptBinaryToStringW(input, sizeof(input), CRYPT_STRING_HEXRAW|flags[i],
hex, &strLen);
ok(!ret && GetLastError() == ERROR_MORE_DATA,"Expected ERROR_MORE_DATA, got ret=%d le=%u\n",
ret, GetLastError());
ok(strLen == strLen2, "Expected length %d, got %d\n", strLen, strLen2);
ok(!memcmp(hex, cmp, strLen * sizeof(WCHAR)), "Unexpected value\n");
heap_free(hex);
heap_free(cmp);
}
}
static void decodeAndCompareBase64_A(LPCSTR toDecode, LPCSTR header,
......
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