|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
dd89bb |
/* Copyright (C) 2013,2014,2015 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 |
|