summaryrefslogtreecommitdiffhomepage
path: root/src/string/ntapi_tt_hex_utf16_to_uintptr.c
blob: 33478f33d3a5f7d282f567503c4e28100d783543 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/********************************************************/
/*  ntapi: Native API core library                      */
/*  Copyright (C) 2013--2017  Z. Gilboa                 */
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
/********************************************************/

#include <psxtypes/psxtypes.h>
#include <ntapi/nt_status.h>

int32_t __fastcall __ntapi_tt_hex_utf16_to_uint32(
	__in	const wchar16_t	hex_key_utf16[8],
	__out	uint32_t *	key)
{
	int		i;
	unsigned char	uch[8];
	unsigned char	ubytes[4];
	uint32_t *	key_ret;

	/* input validation */
	i = 0;
	do {
		if (/* [a-f],[[A-F],[0-9] */
			((hex_key_utf16[i] >= 'a') && (hex_key_utf16[i] <= 'f'))
			|| ((hex_key_utf16[i] >= 'A') && (hex_key_utf16[i] <= 'F'))
			|| ((hex_key_utf16[i] >= '0') && (hex_key_utf16[i] <= '9')))
			/* valid hex character */
			i++;
		else
			return NT_STATUS_ILLEGAL_CHARACTER;
	} while (i < 8);

	/* intermediate step: little endian byte order */
	uch[0] = (unsigned char)hex_key_utf16[6];
	uch[1] = (unsigned char)hex_key_utf16[7];
	uch[2] = (unsigned char)hex_key_utf16[4];
	uch[3] = (unsigned char)hex_key_utf16[5];
	uch[4] = (unsigned char)hex_key_utf16[2];
	uch[5] = (unsigned char)hex_key_utf16[3];
	uch[6] = (unsigned char)hex_key_utf16[0];
	uch[7] = (unsigned char)hex_key_utf16[1];

	for (i=0; i<8; i++) {
		/* 'a' > 'A' > '0' */
		if (uch[i] >= 'a')
			uch[i] -= ('a' - 0x0a);
		else if (uch[i] >= 'A')
			uch[i] -= ('A' - 0x0a);
		else
			uch[i] -= '0';
	}

	ubytes[0] = uch[0] * 0x10 + uch[1];
	ubytes[1] = uch[2] * 0x10 + uch[3];
	ubytes[2] = uch[4] * 0x10 + uch[5];
	ubytes[3] = uch[6] * 0x10 + uch[7];

	key_ret = (uint32_t *)ubytes;
	*key = *key_ret;

	return NT_STATUS_SUCCESS;
}


int32_t __fastcall __ntapi_tt_hex_utf16_to_uint64(
	__in	const wchar16_t	hex_key_utf16[16],
	__out	uint64_t *	key)
{
	int32_t		status;
	uint32_t	x64_key[2];
	uint64_t *	key_ret;

	status = __ntapi_tt_hex_utf16_to_uint32(
			&hex_key_utf16[0],
			&x64_key[1]);

	if (status != NT_STATUS_SUCCESS)
		return status;

	status = __ntapi_tt_hex_utf16_to_uint32(
			&hex_key_utf16[8],
			&x64_key[0]);

	if (status != NT_STATUS_SUCCESS)
		return status;

	key_ret = (uint64_t *)x64_key;
	*key = *key_ret;

	return NT_STATUS_SUCCESS;
}


int32_t __fastcall __ntapi_tt_hex_utf16_to_uintptr(
	__in	const wchar16_t	hex_key_utf16[],
	__out	uintptr_t *	key)
{
	#if (__SIZEOF_POINTER__ == 4)
		return __ntapi_tt_hex_utf16_to_uint32(hex_key_utf16,key);
	#elif (__SIZEOF_POINTER__ == 8)
		return __ntapi_tt_hex_utf16_to_uint64(hex_key_utf16,key);
	#endif
}


int32_t __fastcall __ntapi_tt_hex_utf16_to_uint16(
	__in	const wchar16_t	hex_key_utf16[4],
	__out	uint16_t *	key)
{
	int32_t		ret;
	uint32_t	dword_key;
	wchar16_t	hex_buf[8] = {'0','0','0','0'};

	hex_buf[4] = hex_key_utf16[0];
	hex_buf[5] = hex_key_utf16[1];
	hex_buf[6] = hex_key_utf16[2];
	hex_buf[7] = hex_key_utf16[3];

	ret = __ntapi_tt_hex_utf16_to_uint32(hex_buf,&dword_key);

	if (ret == NT_STATUS_SUCCESS)
		*key = (uint16_t)dword_key;

	return ret;
}