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