Blame src/argv/ntapi_tt_env_vars.c

dd89bb
/********************************************************/
dd89bb
/*  ntapi: Native API core library                      */
4256e2
/*  Copyright (C) 2013--2016  Z. Gilboa                 */
dd89bb
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
dd89bb
/********************************************************/
dd89bb
dd89bb
#include <psxtypes/psxtypes.h>
dd89bb
#include <ntapi/ntapi.h>
dd89bb
#include "ntapi_impl.h"
dd89bb
dd89bb
int32_t __stdcall __ntapi_tt_get_env_var_meta_utf16(
dd89bb
	__in	const uint32_t *	crc32_table,
dd89bb
	__in	wchar16_t *		env_var_name,
dd89bb
	__in	uint32_t		env_var_name_hash __optional,
dd89bb
	__in	wchar16_t **		envp,
dd89bb
	__out	nt_env_var_meta_utf16 *	env_var_meta)
dd89bb
{
dd89bb
	int		idx;
dd89bb
	uint32_t	crc32;
dd89bb
	unsigned char *	byte_buffer;
dd89bb
	wchar16_t *	wch;
dd89bb
dd89bb
	#define EQUAL_SIGN	0x3D
dd89bb
dd89bb
	/* step 1: crc32 of the target env_var_name */
dd89bb
	if (env_var_name_hash)
dd89bb
		crc32 = env_var_name_hash;
dd89bb
	else {
dd89bb
		crc32 = 0 ^ 0xFFFFFFFF;
dd89bb
dd89bb
		/* initialize byte_buffer */
dd89bb
		byte_buffer = (unsigned char *)env_var_name;
dd89bb
dd89bb
		/* iterate */
dd89bb
		while (*byte_buffer) {
dd89bb
			/* two bytes at a time */
dd89bb
			crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF];
dd89bb
			byte_buffer++;
dd89bb
			crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF];
dd89bb
			byte_buffer++;
dd89bb
		}
dd89bb
		crc32 = (crc32 ^ 0xFFFFFFFF);
dd89bb
	}
dd89bb
dd89bb
	/* initialize the env_var_meta structure */
dd89bb
	env_var_meta->name_hash		= crc32;
dd89bb
	env_var_meta->name		= (wchar16_t *)0;
dd89bb
	env_var_meta->value		= (wchar16_t *)0;
dd89bb
	env_var_meta->value_hash	= 0;
dd89bb
	env_var_meta->envp_index	= 0;
dd89bb
	env_var_meta->flags		= 0;
dd89bb
dd89bb
	/* step 2: look for the environment variable in envp[] */
dd89bb
	idx = 0;
dd89bb
	while (envp[idx] && (!env_var_meta->value)) {
dd89bb
		wch = envp[idx];
dd89bb
dd89bb
		/* find the equal sign */
dd89bb
		while ((*wch) && (*wch != EQUAL_SIGN))
dd89bb
			wch++;
dd89bb
dd89bb
		if (*wch != EQUAL_SIGN)
dd89bb
			return NT_STATUS_ILLEGAL_CHARACTER;
dd89bb
dd89bb
		/* hash the current environment variable */
dd89bb
		crc32 = 0 ^ 0xFFFFFFFF;
dd89bb
dd89bb
		/* initialize byte_buffer */
dd89bb
		byte_buffer = (unsigned char *)envp[idx];
dd89bb
dd89bb
		/* iterate */
dd89bb
		while ((uintptr_t)(byte_buffer) < (uintptr_t)wch) {
dd89bb
			/* two bytes at a time */
dd89bb
			crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF];
dd89bb
			byte_buffer++;
dd89bb
			crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF];
dd89bb
			byte_buffer++;
dd89bb
		}
dd89bb
dd89bb
		if (env_var_meta->name_hash == (crc32 ^ 0xFFFFFFFF)) {
dd89bb
			/* found it, get ready to hash the value */
dd89bb
			wch++;
dd89bb
			env_var_meta->name	 = envp[idx];
dd89bb
			env_var_meta->value	 = wch;
dd89bb
			env_var_meta->envp_index = idx;
dd89bb
		} else {
dd89bb
			idx++;
dd89bb
		}
dd89bb
	}
dd89bb
dd89bb
	if (env_var_meta->value) {
dd89bb
		/* hash the value: utf-16, null-terminated */
dd89bb
		crc32 = 0 ^ 0xFFFFFFFF;
dd89bb
dd89bb
		/* initialize byte_buffer */
dd89bb
		byte_buffer = (unsigned char *)env_var_meta->value;
dd89bb
dd89bb
		/* iterate */
dd89bb
		while (*byte_buffer) {
dd89bb
			/* two bytes at a time */
dd89bb
			crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF];
dd89bb
			byte_buffer++;
dd89bb
			crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF];
dd89bb
			byte_buffer++;
dd89bb
		}
dd89bb
dd89bb
		env_var_meta->value_hash = (crc32 ^ 0xFFFFFFFF);
dd89bb
	}
dd89bb
dd89bb
	return NT_STATUS_SUCCESS;
dd89bb
}
dd89bb