Blame src/string/ntapi_tt_hex_utf8_to_uintptr.c

a41388
/********************************************************/
a41388
/*  ntapi: Native API core library                      */
a41388
/*  Copyright (C) 2013--2017  Z. Gilboa                 */
a41388
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
a41388
/********************************************************/
a41388
a41388
#include <psxtypes/psxtypes.h>
a41388
#include <ntapi/nt_status.h>
a41388
#include "ntapi_impl.h"
a41388
a41388
int32_t __fastcall __ntapi_tt_hex_utf8_to_uint32(
a41388
	__in	const unsigned char hex_key_utf8[8],
a41388
	__out	uint32_t *          key)
a41388
{
a41388
	int		i;
a41388
	unsigned char	uch[8];
a41388
	unsigned char	ubytes[4];
a41388
	uint32_t *	key_ret;
a41388
a41388
	/* input validation */
a41388
	i = 0;
a41388
	do {
a41388
		if (/* [a-f],[[A-F],[0-9] */
a41388
			((hex_key_utf8[i] >= 'a') && (hex_key_utf8[i] <= 'f'))
a41388
			|| ((hex_key_utf8[i] >= 'A') && (hex_key_utf8[i] <= 'F'))
a41388
			|| ((hex_key_utf8[i] >= '0') && (hex_key_utf8[i] <= '9')))
a41388
			/* valid hex character */
a41388
			i++;
a41388
		else
a41388
			return NT_STATUS_ILLEGAL_CHARACTER;
a41388
	} while (i < 8);
a41388
a41388
	/* intermediate step: little endian byte order */
a41388
	uch[0] = hex_key_utf8[6];
a41388
	uch[1] = hex_key_utf8[7];
a41388
	uch[2] = hex_key_utf8[4];
a41388
	uch[3] = hex_key_utf8[5];
a41388
	uch[4] = hex_key_utf8[2];
a41388
	uch[5] = hex_key_utf8[3];
a41388
	uch[6] = hex_key_utf8[0];
a41388
	uch[7] = hex_key_utf8[1];
a41388
a41388
	for (i=0; i<8; i++) {
a41388
		/* 'a' > 'A' > '0' */
a41388
		if (uch[i] >= 'a')
a41388
			uch[i] -= ('a' - 0x0a);
a41388
		else if (uch[i] >= 'A')
a41388
			uch[i] -= ('A' - 0x0a);
a41388
		else
a41388
			uch[i] -= '0';
a41388
	}
a41388
a41388
	ubytes[0] = uch[0] * 0x10 + uch[1];
a41388
	ubytes[1] = uch[2] * 0x10 + uch[3];
a41388
	ubytes[2] = uch[4] * 0x10 + uch[5];
a41388
	ubytes[3] = uch[6] * 0x10 + uch[7];
a41388
a41388
	key_ret = (uint32_t *)ubytes;
a41388
	*key = *key_ret;
a41388
a41388
	return NT_STATUS_SUCCESS;
a41388
}
a41388
a41388
a41388
int32_t __fastcall __ntapi_tt_hex_utf8_to_uint64(
a41388
	__in	const unsigned char hex_key_utf8[16],
a41388
	__out	uint64_t *          key)
a41388
{
a41388
	int32_t		status;
a41388
	uint32_t	x64_key[2];
a41388
	uint64_t *	key_ret;
a41388
a41388
	status = __ntapi_tt_hex_utf8_to_uint32(
a41388
			&hex_key_utf8[0],
a41388
			&x64_key[1]);
a41388
a41388
	if (status != NT_STATUS_SUCCESS)
a41388
		return status;
a41388
a41388
	status = __ntapi_tt_hex_utf8_to_uint32(
a41388
			&hex_key_utf8[8],
a41388
			&x64_key[0]);
a41388
a41388
	if (status != NT_STATUS_SUCCESS)
a41388
		return status;
a41388
a41388
	key_ret = (uint64_t *)x64_key;
a41388
	*key = *key_ret;
a41388
a41388
	return NT_STATUS_SUCCESS;
a41388
}
a41388
a41388
a41388
int32_t __fastcall __ntapi_tt_hex_utf8_to_uintptr(
a41388
	__in	const unsigned char hex_key_utf8[],
a41388
	__out	uintptr_t *         key)
a41388
{
a41388
	#if (__SIZEOF_POINTER__ == 4)
a41388
		return __ntapi_tt_hex_utf8_to_uint32(hex_key_utf8,key);
a41388
	#elif (__SIZEOF_POINTER__ == 8)
a41388
		return __ntapi_tt_hex_utf8_to_uint64(hex_key_utf8,key);
a41388
	#endif
a41388
}
a41388
a41388
a41388
int32_t __fastcall __ntapi_tt_hex_utf8_to_uint16(
a41388
	__in	const unsigned char hex_key_utf8[4],
a41388
	__out	uint16_t *          key)
a41388
{
a41388
	int32_t		ret;
a41388
	uint32_t	dword_key;
a41388
	unsigned char	hex_buf[8] = {'0','0','0','0'};
a41388
a41388
	hex_buf[4] = hex_key_utf8[0];
a41388
	hex_buf[5] = hex_key_utf8[1];
a41388
	hex_buf[6] = hex_key_utf8[2];
a41388
	hex_buf[7] = hex_key_utf8[3];
a41388
a41388
	ret = __ntapi_tt_hex_utf8_to_uint32(hex_buf,&dword_key);
a41388
a41388
	if (ret == NT_STATUS_SUCCESS)
a41388
		*key = (uint16_t)dword_key;
a41388
a41388
	return ret;
a41388
}