summaryrefslogtreecommitdiffhomepage
path: root/src/argv/ntapi_tt_env_vars.c
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-07-27 04:01:18 -0400
committermidipix <writeonce@midipix.org>2015-07-27 04:01:18 -0400
commitdd89bb8ad4fe184a34b5dbdda237e640fc82121b (patch)
tree5e80d2da35f5892f92be29f57982b2708e6bd99b /src/argv/ntapi_tt_env_vars.c
parentdcdadc2702712fa750ed255ed1dfa354522797a0 (diff)
downloadntapi-dd89bb8ad4fe184a34b5dbdda237e640fc82121b.tar.bz2
ntapi-dd89bb8ad4fe184a34b5dbdda237e640fc82121b.tar.xz
entered advanced internal development stage.
Diffstat (limited to 'src/argv/ntapi_tt_env_vars.c')
-rw-r--r--src/argv/ntapi_tt_env_vars.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/argv/ntapi_tt_env_vars.c b/src/argv/ntapi_tt_env_vars.c
new file mode 100644
index 0000000..1af9b77
--- /dev/null
+++ b/src/argv/ntapi_tt_env_vars.c
@@ -0,0 +1,112 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/ntapi.h>
+#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;
+}
+