summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile.in14
-rw-r--r--config.lzy28
-rwxr-xr-xconfigure116
-rw-r--r--include/ntapi/bits/i386/nt_atomic_i386_asm__gcc.h533
-rw-r--r--include/ntapi/bits/i386/nt_atomic_i386_asm__msvc.h350
-rw-r--r--include/ntapi/bits/i386/nt_thread_i386.h45
-rw-r--r--include/ntapi/bits/nt_atomic_inline_asm.h15
-rw-r--r--include/ntapi/bits/x86_64/nt_atomic_x86_64_asm__gcc.h571
-rw-r--r--include/ntapi/bits/x86_64/nt_atomic_x86_64_asm__msvc.h350
-rw-r--r--include/ntapi/bits/x86_64/nt_thread_x86_64.h104
-rw-r--r--include/ntapi/nt_acl.h109
-rw-r--r--include/ntapi/nt_argv.h204
-rw-r--r--include/ntapi/nt_atom.h52
-rw-r--r--include/ntapi/nt_atomic.h157
-rw-r--r--include/ntapi/nt_auxv.h50
-rw-r--r--include/ntapi/nt_blitter.h129
-rw-r--r--include/ntapi/nt_crc32.h95
-rw-r--r--include/ntapi/nt_daemon.h89
-rw-r--r--include/ntapi/nt_debug.h37
-rw-r--r--include/ntapi/nt_device.h308
-rw-r--r--include/ntapi/nt_exception.h29
-rw-r--r--include/ntapi/nt_file.h1206
-rw-r--r--include/ntapi/nt_fsctl.h44
-rw-r--r--include/ntapi/nt_guid.h37
-rw-r--r--include/ntapi/nt_hash.h13
-rw-r--r--include/ntapi/nt_ioctl.h31
-rw-r--r--include/ntapi/nt_ipc.h12
-rw-r--r--include/ntapi/nt_istat.h45
-rw-r--r--include/ntapi/nt_job.h212
-rw-r--r--include/ntapi/nt_ldr.h33
-rw-r--r--include/ntapi/nt_locale.h31
-rw-r--r--include/ntapi/nt_memory.h199
-rw-r--r--include/ntapi/nt_mount.h135
-rw-r--r--include/ntapi/nt_object.h514
-rw-r--r--include/ntapi/nt_os.h99
-rw-r--r--include/ntapi/nt_pnp.h326
-rw-r--r--include/ntapi/nt_port.h332
-rw-r--r--include/ntapi/nt_process.h676
-rw-r--r--include/ntapi/nt_profiling.h41
-rw-r--r--include/ntapi/nt_registry.h339
-rw-r--r--include/ntapi/nt_section.h137
-rw-r--r--include/ntapi/nt_security.h190
-rw-r--r--include/ntapi/nt_slist.h22
-rw-r--r--include/ntapi/nt_socket.h429
-rw-r--r--include/ntapi/nt_stat.h46
-rw-r--r--include/ntapi/nt_statfs.h68
-rw-r--r--include/ntapi/nt_status.h1796
-rw-r--r--include/ntapi/nt_string.h143
-rw-r--r--include/ntapi/nt_sync.h428
-rw-r--r--include/ntapi/nt_sysinfo.h796
-rw-r--r--include/ntapi/nt_termios.h305
-rw-r--r--include/ntapi/nt_thread.h263
-rw-r--r--include/ntapi/nt_time.h45
-rw-r--r--include/ntapi/nt_token.h161
-rw-r--r--include/ntapi/nt_tty.h438
-rw-r--r--include/ntapi/nt_unicode.h146
-rw-r--r--include/ntapi/nt_uuid.h22
-rw-r--r--include/ntapi/nt_vfd.h20
-rw-r--r--include/ntapi/nt_vmount.h329
-rw-r--r--include/ntapi/ntapi.h596
-rw-r--r--ntapi.lzy113
-rw-r--r--src/argv/ntapi_tt_argv_envp.c717
-rw-r--r--src/argv/ntapi_tt_array_utf16.c258
-rw-r--r--src/argv/ntapi_tt_array_utf8.c117
-rw-r--r--src/argv/ntapi_tt_env_vars.c112
-rw-r--r--src/argv/ntapi_tt_get_option.c451
-rw-r--r--src/blitter/ntapi_blt_alloc.c149
-rw-r--r--src/blitter/ntapi_blt_block.c204
-rw-r--r--src/blitter/ntapi_blt_free.c48
-rw-r--r--src/daemon/ntapi_dsr_init.c189
-rw-r--r--src/daemon/ntapi_dsr_internal_connection.c142
-rw-r--r--src/fs/ntapi_tt_get_file_handle_type.c83
-rw-r--r--src/fs/ntapi_tt_istat.c155
-rw-r--r--src/fs/ntapi_tt_mount.c358
-rw-r--r--src/fs/ntapi_tt_open_logical_parent_directory.c21
-rw-r--r--src/fs/ntapi_tt_open_physical_parent_directory.c69
-rw-r--r--src/fs/ntapi_tt_stat.c129
-rw-r--r--src/fs/ntapi_tt_statfs.c225
-rw-r--r--src/guid/ntapi_tt_guid.c182
-rw-r--r--src/hash/ntapi_tt_crc32.c50
-rw-r--r--src/hash/ntapi_tt_populate_hashed_import_table.c95
-rw-r--r--src/internal/ntapi.c411
-rw-r--r--src/internal/ntapi_blitter.h27
-rw-r--r--src/internal/ntapi_context.h55
-rw-r--r--src/internal/ntapi_debug.c170
-rw-r--r--src/internal/ntapi_fnapi.h262
-rw-r--r--src/internal/ntapi_hash_table.h266
-rw-r--r--src/internal/ntapi_impl.h120
-rw-r--r--src/internal/ntapi_lib_entry_point.c12
-rw-r--r--src/internal/ntapi_pty.h37
-rw-r--r--src/ipc/ntapi_tt_create_pipe_v1.c164
-rw-r--r--src/ipc/ntapi_tt_create_pipe_v2.c116
-rw-r--r--src/ldr/ntapi_ldr_create_state_snapshot.c69
-rw-r--r--src/ldr/ntapi_ldr_load_system_dll.c44
-rw-r--r--src/ldr/ntapi_ldr_revert_state_to_snapshot.c104
-rw-r--r--src/object/ntapi_tt_keyed_object_directory.c134
-rw-r--r--src/port/ntapi_port_name_helper.c167
-rw-r--r--src/process/nt32/tt_fork_v1.s60
-rw-r--r--src/process/nt32/tt_fork_v1_i386.c66
-rw-r--r--src/process/nt64/tt_fork_v1.s134
-rw-r--r--src/process/nt64/tt_fork_v1_x86_64.asm136
-rw-r--r--src/process/nt64/tt_fork_v2_x86_64.asm50
-rw-r--r--src/process/ntapi_tt_create_native_process_v1.c258
-rw-r--r--src/process/ntapi_tt_create_native_process_v2.c233
-rw-r--r--src/process/ntapi_tt_create_remote_process_params.c331
-rw-r--r--src/process/ntapi_tt_create_remote_runtime_data.c178
-rw-r--r--src/process/ntapi_tt_fork_v1.c218
-rw-r--r--src/process/ntapi_tt_fork_v2.c183
-rw-r--r--src/process/ntapi_tt_get_runtime_data.c83
-rw-r--r--src/process/ntapi_tt_init_runtime_data.c82
-rw-r--r--src/process/ntapi_tt_map_image_as_data.c120
-rw-r--r--src/process/tt_fork_v1.c0
-rw-r--r--src/pty/ntapi_pty_cancel.c46
-rw-r--r--src/pty/ntapi_pty_fd.c232
-rw-r--r--src/pty/ntapi_pty_io.c130
-rw-r--r--src/pty/ntapi_pty_ioctl.c92
-rw-r--r--src/pty/ntapi_pty_query.c64
-rw-r--r--src/pty/ntapi_pty_set.c64
-rw-r--r--src/section/ntapi_tt_get_section_name.c32
-rw-r--r--src/socket/ntapi_sc_accept.c79
-rw-r--r--src/socket/ntapi_sc_bind_v1.c101
-rw-r--r--src/socket/ntapi_sc_bind_v2.c85
-rw-r--r--src/socket/ntapi_sc_connect_v1.c93
-rw-r--r--src/socket/ntapi_sc_connect_v2.c69
-rw-r--r--src/socket/ntapi_sc_getsockname_v1.c80
-rw-r--r--src/socket/ntapi_sc_getsockname_v2.c42
-rw-r--r--src/socket/ntapi_sc_listen.c44
-rw-r--r--src/socket/ntapi_sc_recv.c63
-rw-r--r--src/socket/ntapi_sc_send.c59
-rw-r--r--src/socket/ntapi_sc_server_accept_connection_v1.c78
-rw-r--r--src/socket/ntapi_sc_server_accept_connection_v2.c44
-rw-r--r--src/socket/ntapi_sc_server_duplicate_socket.c45
-rw-r--r--src/socket/ntapi_sc_shutdown.c65
-rw-r--r--src/socket/ntapi_sc_socket_v1.c118
-rw-r--r--src/socket/ntapi_sc_socket_v2.c124
-rw-r--r--src/socket/ntapi_sc_wait.c42
-rw-r--r--src/string/ntapi_tt_aligned_block_memcpy.c50
-rw-r--r--src/string/ntapi_tt_aligned_block_memset.c57
-rw-r--r--src/string/ntapi_tt_aligned_memcpy_utf16.c70
-rw-r--r--src/string/ntapi_tt_hex_utf16_to_uintptr.c124
-rw-r--r--src/string/ntapi_tt_init_unicode_string_from_utf16.c26
-rw-r--r--src/string/ntapi_tt_memcpy_utf16.c28
-rw-r--r--src/string/ntapi_tt_string_null_offset.c93
-rw-r--r--src/string/ntapi_tt_uintptr_to_hex_utf16.c87
-rw-r--r--src/string/ntapi_tt_uintptr_to_hex_utf8.c73
-rw-r--r--src/sync/ntapi_tt_create_event.c76
-rw-r--r--src/sync/ntapi_tt_sync_block.c283
-rw-r--r--src/sync/ntapi_tt_wait_for_dummy_event.c31
-rw-r--r--src/system/ntapi_tt_get_csr_port_handle_addr_by_logic.c197
-rw-r--r--src/system/ntapi_tt_get_system_directory.c257
-rw-r--r--src/system/ntapi_tt_get_system_info_snapshot.c89
-rw-r--r--src/thread/ntapi_tt_create_thread.c418
-rw-r--r--src/tty/ntapi_tty_client_process_register.c37
-rw-r--r--src/tty/ntapi_tty_client_session_query.c40
-rw-r--r--src/tty/ntapi_tty_client_session_set.c38
-rw-r--r--src/tty/ntapi_tty_connect.c47
-rw-r--r--src/tty/ntapi_tty_create_session.c166
-rw-r--r--src/tty/ntapi_tty_join_session.c53
-rw-r--r--src/tty/ntapi_tty_query_information_server.c40
-rw-r--r--src/tty/ntapi_tty_request_peer.c46
-rw-r--r--src/tty/ntapi_tty_vms_query.c40
-rw-r--r--src/tty/ntapi_tty_vms_request.c46
-rw-r--r--src/unicode/ntapi_uc_unicode_conversion_from_utf16.c287
-rw-r--r--src/unicode/ntapi_uc_unicode_conversion_from_utf8.c288
-rw-r--r--src/unicode/ntapi_uc_unicode_validation.c329
-rw-r--r--src/vfd/ntapi_vfd_helper.c34
-rw-r--r--src/vmount/ntapi_vms_cache.c209
-rw-r--r--src/vmount/ntapi_vms_client_connect.c86
-rw-r--r--src/vmount/ntapi_vms_client_disconnect.c37
-rw-r--r--src/vmount/ntapi_vms_helper.c118
-rw-r--r--src/vmount/ntapi_vms_point_attach.c52
-rw-r--r--src/vmount/ntapi_vms_ref_count.c96
-rw-r--r--src/vmount/ntapi_vms_table_query.c45
173 files changed, 28231 insertions, 0 deletions
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..b370cb0
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,14 @@
+all:
+ ./lazy -x build
+
+install:
+ ./lazy -x build -e install
+
+clean:
+ rm -rf src
+ rm -rf lib
+ rm -f lazy
+ rm -f lazy.config.tag
+ rm -f lz_stack
+ rm -f *.objs
+ rm -rf *.lst
diff --git a/config.lzy b/config.lzy
new file mode 100644
index 0000000..1c83db3
--- /dev/null
+++ b/config.lzy
@@ -0,0 +1,28 @@
+# package
+lz_package=ntapi
+
+
+# toolchain
+lz_default_target=x86_64-nt64-midipix
+lz_default_arch=nt64
+lz_default_compiler=gcc
+
+
+# lazy
+export lz_cflags_cmdline=-Os
+export lz_cxxflags_cmdline=-Os
+lz_ldflags_cmdline=
+
+lz_cflags_debug=
+lz_cflags_release=
+
+lz_cflags_include_first=
+lz_cflags_include_last=
+lz_cflags_include_cmdline=
+lz_cxxflags_include_cmdline=
+
+lz_exec_prefix=
+lz_bindir=
+lz_libdir=
+lz_includedir=
+lz_syslibdir=
diff --git a/configure b/configure
new file mode 100755
index 0000000..8d175eb
--- /dev/null
+++ b/configure
@@ -0,0 +1,116 @@
+#!/bin/sh
+
+# a simple configure-make wrapper for use in conjunction with the 'lazy' build script.
+# 'lazy' is deviant, occasionally useful, and permissively licensed; get_lazy() below,
+# then look for configure.template in the root directory.
+
+init_vars()
+{
+ lz_config_dir=`readlink -f $(dirname $0)`
+ lz_pwd=`pwd`
+
+ if [ x"$lz_config" = x ]; then
+ . $lz_config_dir/config.lzy || exit 2
+ else
+ . "$lz_config" || exit 2
+ fi
+}
+
+
+error_msg()
+{
+ echo $@ >&2
+}
+
+
+require_out_of_tree()
+{
+ if [ x"$lz_config_dir" = x"$lz_pwd" ]; then
+ error_msg "$lz_package: out-of-tree builds are required."
+ error_msg "please invoke configure again from a clean build directory."
+ exit 2
+ fi
+
+ return 0
+}
+
+
+get_lazy()
+{
+ which lazy && lazy=`which lazy` && return 0
+
+ if ! [ -d slazy ]; then
+ git clone git://midipix.org/lazy slazy || exit 2
+ fi
+
+ lazy=$lz_pwd/slazy/lazy
+}
+
+
+lazy_approach()
+{
+ if [ x"$lz_prefix" = x ]; then
+ error_msg "prefix is required."
+ exit 2
+ fi
+
+ if [ x"$lz_arch" = x ]; then lz_arch=$lz_default_arch; fi
+ if [ x"$lz_subarch" = x ]; then lz_subarch=$lz_default_subarch; fi
+ if [ x"$lz_target" = x ]; then lz_target=$lz_default_target; fi
+ if [ x"$lz_compiler" = x ]; then lz_compiler=$lz_default_compiler; fi
+ if [ x"$lz_compiler" = x ]; then lz_compiler=gcc; fi
+
+ $lazy -x config $lz_debug \
+ -t $lz_target \
+ -a $lz_arch \
+ -c $lz_compiler \
+ -n $lz_package \
+ -p $lz_config_dir \
+ -f $lz_prefix \
+ || exit 2
+
+}
+
+
+lazy_copy()
+{
+ cp "$lz_config_dir/Makefile.in" "$lz_pwd/Makefile"
+}
+
+
+for arg ; do
+ case "$arg" in
+ --help) usage
+ ;;
+
+ --prefix=*)
+ lz_prefix=${arg#*=}
+ ;;
+ --host=*)
+ lz_target=${arg#*=}
+ ;;
+ --target=*)
+ lz_target=${arg#*=}
+ ;;
+ --compiler=*)
+ lz_compiler=${arg#*=}
+ ;;
+ --config=*)
+ lz_config=${arg#*=}
+ ;;
+ --debug)
+ lz_debug='-d'
+ ;;
+ *)
+ error_msg ${arg#}: "unsupported config argument."
+ exit 2
+ ;;
+ esac
+done
+
+
+init_vars
+require_out_of_tree
+get_lazy
+lazy_approach
+lazy_copy
diff --git a/include/ntapi/bits/i386/nt_atomic_i386_asm__gcc.h b/include/ntapi/bits/i386/nt_atomic_i386_asm__gcc.h
new file mode 100644
index 0000000..f6e11ca
--- /dev/null
+++ b/include/ntapi/bits/i386/nt_atomic_i386_asm__gcc.h
@@ -0,0 +1,533 @@
+#include <psxtypes/psxtypes.h>
+
+static __inline__ void at_locked_inc(
+ intptr_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "incl %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_inc_32(
+ int32_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "incl %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_inc_64(
+ int64_t volatile * ptr)
+{
+ __sync_fetch_and_add(ptr,1);
+}
+
+
+static __inline__ void at_locked_dec(
+ intptr_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "decl %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_dec_32(
+ int32_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "decl %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_dec_64(
+ int64_t volatile * ptr)
+{
+ __sync_fetch_and_sub(ptr,1);
+}
+
+
+static __inline__ void at_locked_add(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_add_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_add_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ __sync_fetch_and_add(ptr,val);
+}
+
+
+static __inline__ void at_locked_sub(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_sub_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_sub_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ __sync_fetch_and_sub(ptr,val);
+}
+
+
+static __inline__ intptr_t at_locked_xadd(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ int32_t at_locked_xadd_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ int64_t at_locked_xadd_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ return __sync_fetch_and_add(ptr,val);
+}
+
+
+static __inline__ intptr_t at_locked_xsub(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ int32_t at_locked_xsub_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ int64_t at_locked_xsub_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ return __sync_fetch_and_sub(ptr,val);
+}
+
+
+static __inline__ intptr_t at_locked_cas(
+ intptr_t volatile * dst,
+ intptr_t cmp,
+ intptr_t xchg)
+{
+ intptr_t ret;
+
+ __asm__(
+ "lock;"
+ "cmpxchg %3, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "a" (cmp), "r" (xchg)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int32_t at_locked_cas_32(
+ int32_t volatile * dst,
+ int32_t cmp,
+ int32_t xchg)
+{
+ int32_t ret;
+
+ __asm__(
+ "lock;"
+ "cmpxchg %3, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "a" (cmp), "r" (xchg)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int64_t at_locked_cas_64(
+ int64_t volatile * dst,
+ int64_t cmp,
+ int64_t xchg)
+{
+ __atomic_compare_exchange_n(
+ dst,
+ &cmp,
+ xchg,
+ 0,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+
+ return cmp;
+}
+
+
+static __inline__ intptr_t at_locked_and(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ intptr_t ret;
+
+ __asm__(
+ "lock;"
+ "andl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int32_t at_locked_and_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ int32_t ret;
+
+ __asm__(
+ "lock;"
+ "andl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int64_t at_locked_and_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ int64_t ret;
+ int64_t cmp;
+ int64_t xchg;
+
+ do {
+ cmp = *dst;
+ xchg = cmp & mask;
+ ret = at_locked_cas_64(dst,cmp,xchg);
+ } while (ret != cmp);
+
+ return ret;
+}
+
+
+static __inline__ intptr_t at_locked_or(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ intptr_t ret;
+
+ __asm__(
+ "lock;"
+ "orl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int32_t at_locked_or_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ int32_t ret;
+
+ __asm__(
+ "lock;"
+ "orl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int64_t at_locked_or_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ int64_t ret;
+ int64_t cmp;
+ int64_t xchg;
+
+ do {
+ cmp = *dst;
+ xchg = cmp | mask;
+ ret = at_locked_cas_64(dst,cmp,xchg);
+ } while (ret != cmp);
+
+ return ret;
+}
+
+
+static __inline__ intptr_t at_locked_xor(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ intptr_t ret;
+
+ __asm__(
+ "lock;"
+ "xorl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memxory");
+
+ return ret;
+}
+
+
+static __inline__ int32_t at_locked_xor_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ int32_t ret;
+
+ __asm__(
+ "lock;"
+ "xorl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memxory");
+
+ return ret;
+}
+
+
+static __inline__ int64_t at_locked_xor_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ int64_t ret;
+ int64_t cmp;
+ int64_t xchg;
+
+ do {
+ cmp = *dst;
+ xchg = cmp ^ mask;
+ ret = at_locked_cas_64(dst,cmp,xchg);
+ } while (ret != cmp);
+
+ return ret;
+}
+
+
+static __inline__ void at_store(
+ volatile intptr_t * dst,
+ intptr_t val)
+{
+ __asm__(
+ "mov %1, %0"
+ : "=m" (*dst)
+ : "r" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_store_32(
+ volatile int32_t * dst,
+ int32_t val)
+{
+ __asm__(
+ "mov %1, %0"
+ : "=m" (*dst)
+ : "r" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_store_64(
+ volatile int64_t * dst,
+ int64_t val)
+{
+ __asm__(
+ "mov %1, %0"
+ : "=m" (*dst)
+ : "r" (val)
+ : "memory");
+}
+
+
+static __inline__ int at_bsf(
+ unsigned int * index,
+ uintptr_t mask)
+{
+ if (mask) {
+ __asm__(
+ "bsf %1, %0"
+ : "=r" (mask)
+ : "r" (mask));
+
+ *index = (int)mask;
+ return 1;
+ } else
+ return 0;
+}
+
+
+static __inline__ int at_bsr(
+ unsigned int * index,
+ uintptr_t mask)
+{
+ if (mask) {
+ __asm__(
+ "bsr %1, %0"
+ : "=r" (mask)
+ : "r" (mask));
+
+ *index = (int)mask;
+ return 1;
+ } else
+ return 0;
+}
+
+
+static __inline__ size_t at_popcount(
+ uintptr_t mask)
+{
+ __asm__(
+ "popcnt %0, %0"
+ : "=r" (mask)
+ : "0" (mask)
+ : "memory");
+ return mask;
+}
+
+
+static __inline__ size_t at_popcount_16(
+ uint16_t mask)
+{
+ __asm__(
+ "popcnt %0, %0"
+ : "=r" (mask)
+ : "0" (mask)
+ : "memory");
+ return mask;
+}
+
+
+static __inline__ size_t at_popcount_32(
+ uint32_t mask)
+{
+ __asm__(
+ "popcnt %0, %0"
+ : "=r" (mask)
+ : "0" (mask)
+ : "memory");
+ return mask;
+}
+
+
+static __inline__ size_t at_popcount_64(
+ uint64_t mask)
+{
+ int ret = at_popcount_32(mask >> 32);
+ return ret + ((mask << 32) >> 32);
+}
diff --git a/include/ntapi/bits/i386/nt_atomic_i386_asm__msvc.h b/include/ntapi/bits/i386/nt_atomic_i386_asm__msvc.h
new file mode 100644
index 0000000..c0a0ba8
--- /dev/null
+++ b/include/ntapi/bits/i386/nt_atomic_i386_asm__msvc.h
@@ -0,0 +1,350 @@
+#include <psxtypes/psxtypes.h>
+
+long _InterlockedIncrement(long volatile * ptr);
+int64_t _InterlockedIncrement64(int64_t volatile * ptr);
+long _InterlockedDecrement(long volatile * ptr);
+int64_t _InterlockedDecrement64(int64_t volatile * ptr);
+long _InterlockedExchangeAdd(long volatile * ptr, long val);
+int64_t _InterlockedExchangeAdd64(int64_t volatile * ptr, int64_t val);
+long _InterlockedCompareExchange(long volatile * dst, long xchg, long cmp);
+int64_t _InterlockedCompareExchange64(int64_t volatile * dst, int64_t xchg, int64_t cmp);
+long _InterlockedAnd(long volatile * dst, long mask);
+int64_t _InterlockedAnd64(int64_t volatile * dst, int64_t mask);
+long _InterlockedOr(long volatile * dst, long mask);
+int64_t _InterlockedOr64(int64_t volatile * dst, int64_t mask);
+long _InterlockedXor(long volatile * dst, long mask);
+int64_t _InterlockedXor64(int64_t volatile * dst, int64_t mask);
+uint16_t __popcnt16(uint16_t mask);
+unsigned int __popcnt(uint32_t mask);
+uint64_t __popcnt64(uint64_t mask);
+void _ReadWriteBarrier(void);
+unsigned char _BitScanForward(unsigned int * index, uintptr_t mask);
+unsigned char _BitScanReverse(unsigned int * index, uintptr_t mask);
+
+static __inline__ void at_locked_inc(
+ intptr_t volatile * ptr)
+{
+ _InterlockedIncrement(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_inc_32(
+ int32_t volatile * ptr)
+{
+ _InterlockedIncrement((long *)ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_inc_64(
+ int64_t volatile * ptr)
+{
+ _InterlockedIncrement64(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_dec(
+ intptr_t volatile * ptr)
+{
+ _InterlockedDecrement(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_dec_32(
+ int32_t volatile * ptr)
+{
+ _InterlockedDecrement((long *)ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_dec_64(
+ int64_t volatile * ptr)
+{
+ _InterlockedDecrement64(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_add(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ _InterlockedExchangeAdd(ptr, val);
+ return;
+}
+
+
+static __inline__ void at_locked_add_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ _InterlockedExchangeAdd((long *)ptr, val);
+ return;
+}
+
+
+static __inline__ void at_locked_add_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ _InterlockedExchangeAdd64(ptr, val);
+ return;
+}
+
+
+static __inline__ void at_locked_sub(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ _InterlockedExchangeAdd(ptr, -val);
+ return;
+}
+
+
+static __inline__ void at_locked_sub_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ _InterlockedExchangeAdd((long *)ptr, -val);
+ return;
+}
+
+
+static __inline__ void at_locked_sub_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ _InterlockedExchangeAdd64(ptr, -val);
+ return;
+}
+
+
+static __inline__ intptr_t at_locked_xadd(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ return _InterlockedExchangeAdd(ptr, val);
+}
+
+
+static __inline__ int32_t at_locked_xadd_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ return _InterlockedExchangeAdd((long *)ptr, val);
+}
+
+
+static __inline__ int64_t at_locked_xadd_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ return _InterlockedExchangeAdd64(ptr, val);
+}
+
+
+static __inline__ intptr_t at_locked_xsub(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ return _InterlockedExchangeAdd(ptr, -val);
+}
+
+
+static __inline__ int32_t at_locked_xsub_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ return _InterlockedExchangeAdd((long *)ptr, -val);
+}
+
+
+static __inline__ int64_t at_locked_xsub_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ return _InterlockedExchangeAdd64(ptr, -val);
+}
+
+
+static __inline__ intptr_t at_locked_cas(
+ intptr_t volatile * dst,
+ intptr_t cmp,
+ intptr_t xchg)
+{
+ return _InterlockedCompareExchange(dst,xchg,cmp);
+}
+
+
+static __inline__ int32_t at_locked_cas_32(
+ int32_t volatile * dst,
+ int32_t cmp,
+ int32_t xchg)
+{
+ return _InterlockedCompareExchange((long *)dst,xchg,cmp);
+}
+
+
+static __inline__ int64_t at_locked_cas_64(
+ int64_t volatile * dst,
+ int64_t cmp,
+ int64_t xchg)
+{
+ return _InterlockedCompareExchange64(dst,xchg,cmp);
+}
+
+
+static __inline__ intptr_t at_locked_and(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ return _InterlockedAnd(dst,mask);
+}
+
+
+static __inline__ int32_t at_locked_and_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ return _InterlockedAnd((long *)dst,mask);
+}
+
+
+static __inline__ int64_t at_locked_and_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ return _InterlockedAnd64(dst,mask);
+}
+
+
+static __inline__ intptr_t at_locked_or(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ return _InterlockedOr(dst,mask);
+}
+
+
+static __inline__ int32_t at_locked_or_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ return _InterlockedOr((long *)dst,mask);
+}
+
+
+static __inline__ int64_t at_locked_or_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ return _InterlockedOr64(dst,mask);
+}
+
+
+static __inline__ intptr_t at_locked_xor(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ return _InterlockedXor(dst,mask);
+}
+
+
+static __inline__ int32_t at_locked_xor_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ return _InterlockedXor((long *)dst,mask);
+}
+
+
+static __inline__ int64_t at_locked_xor_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ return _InterlockedXor64(dst,mask);
+}
+
+
+static __inline__ void at_store(
+ volatile intptr_t * dst,
+ intptr_t val)
+{
+ _ReadWriteBarrier();
+ *dst = val;
+ _ReadWriteBarrier();
+
+ return;
+}
+
+
+static __inline__ void at_store_32(
+ volatile int32_t * dst,
+ int32_t val)
+{
+ _ReadWriteBarrier();
+ *dst = val;
+ _ReadWriteBarrier();
+
+ return;
+}
+
+
+static __inline__ void at_store_64(
+ volatile int64_t * dst,
+ int64_t val)
+{
+ _ReadWriteBarrier();
+ *dst = val;
+ _ReadWriteBarrier();
+
+ return;
+}
+
+
+static __inline__ int at_bsf(
+ unsigned int * index,
+ uintptr_t mask)
+{
+ return (int)_BitScanForward(index,mask);
+}
+
+
+static __inline__ int at_bsr(
+ unsigned int * index,
+ uintptr_t mask)
+{
+ return (int)_BitScanReverse(index,mask);
+}
+
+
+static __inline__ size_t at_popcount(
+ uintptr_t mask)
+{
+ return __popcnt(mask);
+}
+
+
+static __inline__ size_t at_popcount_16(
+ uint16_t mask)
+{
+ return __popcnt16(mask);
+}
+
+
+static __inline__ size_t at_popcount_32(
+ uint32_t mask)
+{
+ return __popcnt(mask);
+}
+
+
+static __inline__ size_t at_popcount_64(
+ uint64_t mask)
+{
+ return (size_t)__popcnt64(mask);
+}
diff --git a/include/ntapi/bits/i386/nt_thread_i386.h b/include/ntapi/bits/i386/nt_thread_i386.h
new file mode 100644
index 0000000..466d129
--- /dev/null
+++ b/include/ntapi/bits/i386/nt_thread_i386.h
@@ -0,0 +1,45 @@
+#include <psxtypes/psxtypes.h>
+
+typedef struct _nt_floating_save_area_i386 {
+ uint32_t uc_ctrl_word; /* 0x000 */
+ uint32_t uc_status_word; /* 0x004 */
+ uint32_t uc_tag_word; /* 0x008 */
+ uint32_t uc_error_offset; /* 0x00c */
+ uint32_t uc_error_selector; /* 0x010 */
+ uint32_t uc_data_offset; /* 0x014 */
+ uint32_t uc_data_selector; /* 0x018 */
+ unsigned char uc_reg_area[80]; /* 0x01c */
+ uint32_t uc_cr0_npx_state; /* 0x06c */
+} nt_floating_save_area_i386;
+
+
+typedef struct _nt_thread_context_i386 {
+ uint32_t uc_context_flags; /* 0x000 */
+ uint32_t uc_dr0; /* 0x004 */
+ uint32_t uc_dr1; /* 0x008 */
+ uint32_t uc_dr2; /* 0x00c */
+ uint32_t uc_dr3; /* 0x010 */
+ uint32_t uc_dr6; /* 0x014 */
+ uint32_t uc_dr7; /* 0x018 */
+
+ nt_floating_save_area_i386
+ uc_float_save; /* 0x01c */
+
+ uint32_t uc_seg_gs; /* 0x08c */
+ uint32_t uc_seg_fs; /* 0x090 */
+ uint32_t uc_seg_es; /* 0x094 */
+ uint32_t uc_seg_ds; /* 0x098 */
+ uint32_t uc_edi; /* 0x09c */
+ uint32_t uc_esi; /* 0x0a0 */
+ uint32_t uc_ebx; /* 0x0a4 */
+ uint32_t uc_edx; /* 0x0a8 */
+ uint32_t uc_ecx; /* 0x0ac */
+ uint32_t uc_eax; /* 0x0b0 */
+ uint32_t uc_ebp; /* 0x0b4 */
+ uint32_t uc_eip; /* 0x0b8 */
+ uint32_t uc_seg_cs; /* 0x0bc */
+ uint32_t uc_eflags; /* 0x0c0 */
+ uint32_t uc_esp; /* 0x0c4 */
+ uint32_t uc_seg_ss; /* 0x0c8 */
+ unsigned char uc_extended_regs[512]; /* 0x0cc */
+} nt_thread_context_i386;
diff --git a/include/ntapi/bits/nt_atomic_inline_asm.h b/include/ntapi/bits/nt_atomic_inline_asm.h
new file mode 100644
index 0000000..f749bdf
--- /dev/null
+++ b/include/ntapi/bits/nt_atomic_inline_asm.h
@@ -0,0 +1,15 @@
+#if defined(__X86_MODEL)
+#if (__COMPILER__ == __GCC__)
+#include "i386/nt_atomic_i386_asm__gcc.h"
+#elif (__COMPILER__ == __MSVC__)
+#include "i386/nt_atomic_i386_asm__msvc.h"
+#endif
+
+#elif defined(__X86_64_MODEL)
+#if (__COMPILER__ == __GCC__)
+#include "x86_64/nt_atomic_x86_64_asm__gcc.h"
+#elif (__COMPILER__ == __MSVC__)
+#include "x86_64/nt_atomic_x86_64_asm__msvc.h"
+#endif
+
+#endif
diff --git a/include/ntapi/bits/x86_64/nt_atomic_x86_64_asm__gcc.h b/include/ntapi/bits/x86_64/nt_atomic_x86_64_asm__gcc.h
new file mode 100644
index 0000000..b15bcdc
--- /dev/null
+++ b/include/ntapi/bits/x86_64/nt_atomic_x86_64_asm__gcc.h
@@ -0,0 +1,571 @@
+#include <psxtypes/psxtypes.h>
+
+static __inline__ void at_locked_inc(
+ intptr_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "incq %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_inc_32(
+ int32_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "incl %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_inc_64(
+ int64_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "incq %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_dec(
+ intptr_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "decq %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_dec_32(
+ int32_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "decl %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_dec_64(
+ int64_t volatile * ptr)
+{
+ __asm__(
+ "lock;"
+ "decq %0"
+ : "=m" (*ptr)
+ : "m" (*ptr)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_add(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddq %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_add_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_add_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddq %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_sub(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddq %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_sub_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_locked_sub_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddq %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+}
+
+
+static __inline__ intptr_t at_locked_xadd(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddq %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ int32_t at_locked_xadd_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ int64_t at_locked_xadd_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ __asm__(
+ "lock;"
+ "xaddq %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ intptr_t at_locked_xsub(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddq %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ int32_t at_locked_xsub_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddl %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ int64_t at_locked_xsub_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ val = -val;
+
+ __asm__(
+ "lock;"
+ "xaddq %1, %0"
+ : "=m" (*ptr), "=r" (val)
+ : "1" (val)
+ : "memory");
+ return val;
+}
+
+
+static __inline__ intptr_t at_locked_cas(
+ intptr_t volatile * dst,
+ intptr_t cmp,
+ intptr_t xchg)
+{
+ intptr_t ret;
+
+ __asm__(
+ "lock;"
+ "cmpxchgq %3, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "a" (cmp), "r" (xchg)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int32_t at_locked_cas_32(
+ int32_t volatile * dst,
+ int32_t cmp,
+ int32_t xchg)
+{
+ int32_t ret;
+
+ __asm__(
+ "lock;"
+ "cmpxchg %3, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "a" (cmp), "r" (xchg)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int64_t at_locked_cas_64(
+ int64_t volatile * dst,
+ int64_t cmp,
+ int64_t xchg)
+{
+ int64_t ret;
+
+ __asm__(
+ "lock;"
+ "cmpxchgq %3, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "a" (cmp), "r" (xchg)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ intptr_t at_locked_and(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ intptr_t ret;
+
+ __asm__(
+ "lock;"
+ "andq %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int32_t at_locked_and_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ int32_t ret;
+
+ __asm__(
+ "lock;"
+ "andl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int64_t at_locked_and_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ int64_t ret;
+
+ __asm__(
+ "lock;"
+ "andq %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ intptr_t at_locked_or(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ intptr_t ret;
+
+ __asm__(
+ "lock;"
+ "orq %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int32_t at_locked_or_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ int32_t ret;
+
+ __asm__(
+ "lock;"
+ "orl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ int64_t at_locked_or_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ int64_t ret;
+
+ __asm__(
+ "lock;"
+ "orq %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memory");
+
+ return ret;
+}
+
+
+static __inline__ intptr_t at_locked_xor(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ intptr_t ret;
+
+ __asm__(
+ "lock;"
+ "xorq %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memxory");
+
+ return ret;
+}
+
+
+static __inline__ int32_t at_locked_xor_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ int32_t ret;
+
+ __asm__(
+ "lock;"
+ "xorl %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memxory");
+
+ return ret;
+}
+
+
+static __inline__ int64_t at_locked_xor_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ int64_t ret;
+
+ __asm__(
+ "lock;"
+ "xorq %1, %0"
+ : "=m" (*dst), "=a" (ret)
+ : "r" (mask)
+ : "memxory");
+
+ return ret;
+}
+
+
+static __inline__ void at_store(
+ volatile intptr_t * dst,
+ intptr_t val)
+{
+ __asm__(
+ "mov %1, %0"
+ : "=m" (*dst)
+ : "r" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_store_32(
+ volatile int32_t * dst,
+ int32_t val)
+{
+ __asm__(
+ "mov %1, %0"
+ : "=m" (*dst)
+ : "r" (val)
+ : "memory");
+}
+
+
+static __inline__ void at_store_64(
+ volatile int64_t * dst,
+ int64_t val)
+{
+ __asm__(
+ "mov %1, %0"
+ : "=m" (*dst)
+ : "r" (val)
+ : "memory");
+}
+
+
+static __inline__ int at_bsf(
+ unsigned int * index,
+ uintptr_t mask)
+{
+ if (mask) {
+ __asm__(
+ "bsf %1, %0"
+ : "=r" (mask)
+ : "r" (mask));
+
+ *index = (int)mask;
+ return 1;
+ } else
+ return 0;
+}
+
+
+static __inline__ int at_bsr(
+ unsigned int * index,
+ uintptr_t mask)
+{
+ if (mask) {
+ __asm__(
+ "bsr %1, %0"
+ : "=r" (mask)
+ : "r" (mask));
+
+ *index = (int)mask;
+ return 1;
+ } else
+ return 0;
+}
+
+
+static __inline__ size_t at_popcount(
+ uintptr_t mask)
+{
+ __asm__(
+ "popcntq %0, %0"
+ : "=r" (mask)
+ : "0" (mask)
+ : "memory");
+ return mask;
+}
+
+
+static __inline__ size_t at_popcount_16(
+ uint16_t mask)
+{
+ __asm__(
+ "popcnt %0, %0"
+ : "=r" (mask)
+ : "0" (mask)
+ : "memory");
+ return mask;
+}
+
+
+static __inline__ size_t at_popcount_32(
+ uint32_t mask)
+{
+ __asm__(
+ "popcnt %0, %0"
+ : "=r" (mask)
+ : "0" (mask)
+ : "memory");
+ return mask;
+}
+
+
+static __inline__ size_t at_popcount_64(
+ uint64_t mask)
+{
+ __asm__(
+ "popcntq %0, %0"
+ : "=r" (mask)
+ : "0" (mask)
+ : "memory");
+ return mask;
+}
diff --git a/include/ntapi/bits/x86_64/nt_atomic_x86_64_asm__msvc.h b/include/ntapi/bits/x86_64/nt_atomic_x86_64_asm__msvc.h
new file mode 100644
index 0000000..a52bfd4
--- /dev/null
+++ b/include/ntapi/bits/x86_64/nt_atomic_x86_64_asm__msvc.h
@@ -0,0 +1,350 @@
+#include <psxtypes/psxtypes.h>
+
+long _InterlockedIncrement(int32_t volatile * ptr);
+int64_t _InterlockedIncrement64(int64_t volatile * ptr);
+long _InterlockedDecrement(int32_t volatile * ptr);
+int64_t _InterlockedDecrement64(int64_t volatile * ptr);
+long _InterlockedExchangeAdd(int32_t volatile * ptr, int32_t val);
+int64_t _InterlockedExchangeAdd64(int64_t volatile * ptr, int64_t val);
+long _InterlockedCompareExchange(int32_t volatile * dst, int32_t xchg, int32_t cmp);
+int64_t _InterlockedCompareExchange64(int64_t volatile * dst, int64_t xchg, int64_t cmp);
+long _InterlockedAnd(int32_t volatile * dst, int32_t mask);
+int64_t _InterlockedAnd64(int64_t volatile * dst, int64_t mask);
+long _InterlockedOr(int32_t volatile * dst, int32_t mask);
+int64_t _InterlockedOr64(int64_t volatile * dst, int64_t mask);
+long _InterlockedXor(int32_t volatile * dst, int32_t mask);
+int64_t _InterlockedXor64(int64_t volatile * dst, int64_t mask);
+uint16_t __popcnt16(uint16_t mask);
+uint32_t __popcnt(uint32_t mask);
+uint64_t __popcnt64(uint64_t mask);
+void _ReadWriteBarrier(void);
+unsigned char _BitScanForward64(unsigned int * index, uintptr_t mask);
+unsigned char _BitScanReverse64(unsigned int * index, uintptr_t mask);
+
+static __inline__ void at_locked_inc(
+ intptr_t volatile * ptr)
+{
+ _InterlockedIncrement64(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_inc_32(
+ int32_t volatile * ptr)
+{
+ _InterlockedIncrement(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_inc_64(
+ int64_t volatile * ptr)
+{
+ _InterlockedIncrement64(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_dec(
+ intptr_t volatile * ptr)
+{
+ _InterlockedDecrement64(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_dec_32(
+ int32_t volatile * ptr)
+{
+ _InterlockedDecrement(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_dec_64(
+ int64_t volatile * ptr)
+{
+ _InterlockedDecrement64(ptr);
+ return;
+}
+
+
+static __inline__ void at_locked_add(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ _InterlockedExchangeAdd64(ptr, val);
+ return;
+}
+
+
+static __inline__ void at_locked_add_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ _InterlockedExchangeAdd(ptr, val);
+ return;
+}
+
+
+static __inline__ void at_locked_add_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ _InterlockedExchangeAdd64(ptr, val);
+ return;
+}
+
+
+static __inline__ void at_locked_sub(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ _InterlockedExchangeAdd64(ptr, -val);
+ return;
+}
+
+
+static __inline__ void at_locked_sub_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ _InterlockedExchangeAdd(ptr, -val);
+ return;
+}
+
+
+static __inline__ void at_locked_sub_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ _InterlockedExchangeAdd64(ptr, -val);
+ return;
+}
+
+
+static __inline__ intptr_t at_locked_xadd(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ return _InterlockedExchangeAdd64(ptr, val);
+}
+
+
+static __inline__ int32_t at_locked_xadd_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ return _InterlockedExchangeAdd(ptr, val);
+}
+
+
+static __inline__ int64_t at_locked_xadd_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ return _InterlockedExchangeAdd64(ptr, val);
+}
+
+
+static __inline__ intptr_t at_locked_xsub(
+ intptr_t volatile * ptr,
+ intptr_t val)
+{
+ return _InterlockedExchangeAdd64(ptr, -val);
+}
+
+
+static __inline__ int32_t at_locked_xsub_32(
+ int32_t volatile * ptr,
+ int32_t val)
+{
+ return _InterlockedExchangeAdd(ptr, -val);
+}
+
+
+static __inline__ int64_t at_locked_xsub_64(
+ int64_t volatile * ptr,
+ int64_t val)
+{
+ return _InterlockedExchangeAdd64(ptr, -val);
+}
+
+
+static __inline__ intptr_t at_locked_cas(
+ intptr_t volatile * dst,
+ intptr_t cmp,
+ intptr_t xchg)
+{
+ return _InterlockedCompareExchange64(dst,xchg,cmp);
+}
+
+
+static __inline__ int32_t at_locked_cas_32(
+ int32_t volatile * dst,
+ int32_t cmp,
+ int32_t xchg)
+{
+ return _InterlockedCompareExchange(dst,xchg,cmp);
+}
+
+
+static __inline__ int64_t at_locked_cas_64(
+ int64_t volatile * dst,
+ int64_t cmp,
+ int64_t xchg)
+{
+ return _InterlockedCompareExchange64(dst,xchg,cmp);
+}
+
+
+static __inline__ intptr_t at_locked_and(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ return _InterlockedAnd64(dst,mask);
+}
+
+
+static __inline__ int32_t at_locked_and_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ return _InterlockedAnd(dst,mask);
+}
+
+
+static __inline__ int64_t at_locked_and_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ return _InterlockedAnd64(dst,mask);
+}
+
+
+static __inline__ intptr_t at_locked_or(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ return _InterlockedOr64(dst,mask);
+}
+
+
+static __inline__ int32_t at_locked_or_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ return _InterlockedOr(dst,mask);
+}
+
+
+static __inline__ int64_t at_locked_or_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ return _InterlockedOr64(dst,mask);
+}
+
+
+static __inline__ intptr_t at_locked_xor(
+ intptr_t volatile * dst,
+ intptr_t mask)
+{
+ return _InterlockedXor64(dst,mask);
+}
+
+
+static __inline__ int32_t at_locked_xor_32(
+ int32_t volatile * dst,
+ int32_t mask)
+{
+ return _InterlockedXor(dst,mask);
+}
+
+
+static __inline__ int64_t at_locked_xor_64(
+ int64_t volatile * dst,
+ int64_t mask)
+{
+ return _InterlockedXor64(dst,mask);
+}
+
+
+static __inline__ void at_store(
+ volatile intptr_t * dst,
+ intptr_t val)
+{
+ _ReadWriteBarrier();
+ *dst = val;
+ _ReadWriteBarrier();
+
+ return;
+}
+
+
+static __inline__ void at_store_32(
+ volatile int32_t * dst,
+ int32_t val)
+{
+ _ReadWriteBarrier();
+ *dst = val;
+ _ReadWriteBarrier();
+
+ return;
+}
+
+
+static __inline__ void at_store_64(
+ volatile int64_t * dst,
+ int64_t val)
+{
+ _ReadWriteBarrier();
+ *dst = val;
+ _ReadWriteBarrier();
+
+ return;
+}
+
+
+static __inline__ int at_bsf(
+ unsigned int * index,
+ uintptr_t mask)
+{
+ return (int)_BitScanForward64(index,mask);
+}
+
+
+static __inline__ int at_bsr(
+ unsigned int * index,
+ uintptr_t mask)
+{
+ return (int)_BitScanReverse64(index,mask);
+}
+
+
+static __inline__ size_t at_popcount(
+ uintptr_t mask)
+{
+ return __popcnt64(mask);
+}
+
+
+static __inline__ size_t at_popcount_16(
+ uint16_t mask)
+{
+ return __popcnt16(mask);
+}
+
+
+static __inline__ size_t at_popcount_32(
+ uint32_t mask)
+{
+ return __popcnt(mask);
+}
+
+
+static __inline__ size_t at_popcount_64(
+ uint64_t mask)
+{
+ return __popcnt64(mask);
+}
diff --git a/include/ntapi/bits/x86_64/nt_thread_x86_64.h b/include/ntapi/bits/x86_64/nt_thread_x86_64.h
new file mode 100644
index 0000000..efe5664
--- /dev/null
+++ b/include/ntapi/bits/x86_64/nt_thread_x86_64.h
@@ -0,0 +1,104 @@
+#ifndef _NT_THREAD_X86_64_H_
+#define _NT_THREAD_X86_64_H_
+
+#include <psxtypes/psxtypes.h>
+
+typedef struct {
+ uintptr_t uc_low;
+ intptr_t uc_high;
+} nt_m128a_t;
+
+typedef struct {
+ uint16_t uc_control_word; /* 0x000 */
+ uint16_t uc_status_word; /* 0x002 */
+ uint8_t uc_tag_word; /* 0x004 */
+ uint8_t uc_reserved1; /* 0x005 */
+ uint16_t uc_error_opcode; /* 0x006 */
+ uint32_t uc_error_offset; /* 0x008 */
+ uint16_t uc_error_selector; /* 0x00c */
+ uint16_t uc_reserved2; /* 0x00e */
+ uint32_t uc_data_offset; /* 0x010 */
+ uint16_t uc_data_selector; /* 0x014 */
+ uint16_t uc_reserved3; /* 0x016 */
+ uint32_t uc_mx_csr; /* 0x018 */
+ uint32_t uc_mx_csr_mask; /* 0x01c */
+ nt_m128a_t uc_float_registers[8]; /* 0x020 */
+ nt_m128a_t uc_xmm_registers[16]; /* 0x0a0 */
+ uint8_t uc_reserved4[96]; /* 0x1a0 */
+} nt_xsave_fmt_t;
+
+typedef struct {
+ uintptr_t uc_p1_home; /* 0x000 */
+ uintptr_t uc_p2_home; /* 0x008 */
+ uintptr_t uc_p3_home; /* 0x010 */
+ uintptr_t uc_p4_home; /* 0x018 */
+ uintptr_t uc_p5_home; /* 0x020 */
+ uintptr_t uc_p6_home; /* 0x028 */
+ uint32_t uc_context_flags; /* 0x030 */
+ uint32_t uc_mx_csr; /* 0x034 */
+ uint16_t uc_seg_cs; /* 0x038 */
+ uint16_t uc_seg_ds; /* 0x03a */
+ uint16_t uc_seg_es; /* 0x03c */
+ uint16_t uc_seg_fs; /* 0x03e */
+ uint16_t uc_seg_gs; /* 0x040 */
+ uint16_t uc_seg_ss; /* 0x042 */
+ uint32_t uc_eflags; /* 0x044 */
+ uintptr_t uc_dr0; /* 0x048 */
+ uintptr_t uc_dr1; /* 0x050 */
+ uintptr_t uc_dr2; /* 0x058 */
+ uintptr_t uc_dr3; /* 0x060 */
+ uintptr_t uc_dr6; /* 0x068 */
+ uintptr_t uc_dr7; /* 0x070 */
+ uintptr_t uc_rax; /* 0x078 */
+ uintptr_t uc_rcx; /* 0x080 */
+ uintptr_t uc_rdx; /* 0x088 */
+ uintptr_t uc_rbx; /* 0x090 */
+ uintptr_t uc_rsp; /* 0x098 */
+ uintptr_t uc_rbp; /* 0x0a0 */
+ uintptr_t uc_rsi; /* 0x0a8 */
+ uintptr_t uc_rdi; /* 0x0b0 */
+ uintptr_t uc_r8; /* 0x0b8 */
+ uintptr_t uc_r9; /* 0x0c0 */
+ uintptr_t uc_r10; /* 0x0c8 */
+ uintptr_t uc_r11; /* 0x0d0 */
+ uintptr_t uc_r12; /* 0x0d8 */
+ uintptr_t uc_r13; /* 0x0e0 */
+ uintptr_t uc_r14; /* 0x0e8 */
+ uintptr_t uc_r15; /* 0x0f0 */
+ uintptr_t uc_rip; /* 0x0f8 */
+
+ union {
+ nt_xsave_fmt_t uc_flt_save; /* 0x100 */
+
+ struct {
+ nt_m128a_t uc_header[2]; /* 0x100 */
+ nt_m128a_t uc_legacy[8]; /* 0x120 */
+ } uc_hdr;
+ } uc_flt;
+
+ nt_m128a_t uc_xmm0; /* 0x1a0 */
+ nt_m128a_t uc_xmm1; /* 0x1b0 */
+ nt_m128a_t uc_xmm2; /* 0x1c0 */
+ nt_m128a_t uc_xmm3; /* 0x1d0 */
+ nt_m128a_t uc_xmm4; /* 0x1e0 */
+ nt_m128a_t uc_xmm5; /* 0x1f0 */
+ nt_m128a_t uc_xmm6; /* 0x200 */
+ nt_m128a_t uc_xmm7; /* 0x210 */
+ nt_m128a_t uc_xmm8; /* 0x220 */
+ nt_m128a_t uc_xmm9; /* 0x230 */
+ nt_m128a_t uc_xmm10; /* 0x240 */
+ nt_m128a_t uc_xmm11; /* 0x250 */
+ nt_m128a_t uc_xmm12; /* 0x260 */
+ nt_m128a_t uc_xmm13; /* 0x270 */
+ nt_m128a_t uc_xmm14; /* 0x280 */
+ nt_m128a_t uc_xmm15; /* 0x290 */
+ nt_m128a_t uc_vector_register[26]; /* 0x300 */
+ uintptr_t uc_vector_control; /* 0x4a0 */
+ uintptr_t uc_debug_control; /* 0x4a8 */
+ uintptr_t uc_last_branch_to_rip; /* 0x4b0 */
+ uintptr_t uc_last_branch_from_rip; /* 0x4b8 */
+ uintptr_t uc_last_exception_to_rip; /* 0x4c0 */
+ uintptr_t uc_last_exception_from_rip; /* 0x4c8 */
+} nt_mcontext_x86_64_t;
+
+#endif
diff --git a/include/ntapi/nt_acl.h b/include/ntapi/nt_acl.h
new file mode 100644
index 0000000..8d82e0f
--- /dev/null
+++ b/include/ntapi/nt_acl.h
@@ -0,0 +1,109 @@
+#ifndef _NT_ACL_H_
+#define _NT_ACL_H_
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+
+typedef enum _nt_sid_name_use {
+ NT_SID_TYPE_USER = 1,
+ NT_SID_TYPE_GROUP,
+ NT_SID_TYPE_DOMAIN,
+ NT_SID_TYPE_ALIAS,
+ NT_SID_TYPE_WELL_KNOWN_GROUP,
+ NT_SID_TYPE_DELETED_ACCOUNT,
+ NT_SID_TYPE_INVALID,
+ NT_SID_TYPE_UNKNOWN,
+ NT_SID_TYPE_COMPUTER,
+ NT_SID_TYPE_LABEL
+} nt_sid_name_use;
+
+
+/* access control entry types */
+#define NT_ACE_TYPE_ACCESS_ALLOWED (0x00)
+#define NT_ACE_TYPE_ACCESS_DENIED (0x01)
+#define NT_ACE_TYPE_SYSTEM_AUDIT (0x02)
+#define NT_ACE_TYPE_SYSTEM_ALARM (0x03)
+#define NT_ACE_TYPE_ACCESS_ALLOWED_COMPOUND (0x04)
+#define NT_ACE_TYPE_ACCESS_ALLOWED_OBJECT (0x05)
+#define NT_ACE_TYPE_ACCESS_DENIED_OBJECT (0x06)
+#define NT_ACE_TYPE_SYSTEM_AUDIT_OBJECT (0x07)
+#define NT_ACE_TYPE_SYSTEM_ALARM_OBJECT (0x08)
+#define NT_ACE_TYPE_ACCESS_ALLOWED_CALLBACK (0x09)
+#define NT_ACE_TYPE_ACCESS_DENIED_CALLBACK (0x0A)
+#define NT_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT (0x0B)
+#define NT_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT (0x0C)
+#define NT_ACE_TYPE_SYSTEM_AUDIT_CALLBACK (0x0D)
+#define NT_ACE_TYPE_SYSTEM_ALARM_CALLBACK (0x0E)
+#define NT_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT (0x0F)
+#define NT_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT (0x10)
+#define NT_ACE_TYPE_SYSTEM_MANDATORY_LABEL (0x11)
+#define NT_ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE (0x12)
+#define NT_ACE_TYPE_SYSTEM_SCOPED_POLICY_ID (0x13)
+
+
+/* acceess control entry flags */
+#define NT_ACE_OBJECT_INHERIT (0x01)
+#define NT_ACE_CONTAINER_INHERIT (0x02)
+#define NT_ACE_NO_PROPAGATE_INHERIT (0x04)
+#define NT_ACE_INHERIT_ONLY (0x08)
+#define NT_ACE_INHERITED (0x10)
+#define NT_ACE_VALID_INHERIT_FLAGS (0x1F)
+#define NT_ACE_SUCCESSFUL_ACCESS_ACE_FLAG (0x40)
+#define NT_ACE_FAILED_ACCESS_ACE_FLAG (0x80)
+
+typedef struct _nt_ace_header {
+ unsigned char ace_type;
+ unsigned char ace_flags;
+ uint16_t ace_size;
+} nt_ace_header;
+
+
+typedef struct _nt_access_allowed_ace {
+ nt_ace_header header;
+ uint32_t mask;
+ uint32_t sid_start;
+} nt_access_allowed_ace;
+
+
+typedef struct _nt_access_denied_ace {
+ nt_ace_header header;
+ uint32_t mask;
+ uint32_t sid_start;
+} nt_access_denied_ace;
+
+
+typedef struct _nt_system_audit_ace {
+ nt_ace_header header;
+ uint32_t mask;
+ uint32_t sid_start;
+} nt_system_audit_ace;
+
+
+typedef struct _nt_system_alarm_ace {
+ nt_ace_header header;
+ uint32_t mask;
+ uint32_t sid_start;
+} nt_system_alarm_ace;
+
+
+typedef struct _nt_system_resource_attribute_ace {
+ nt_ace_header header;
+ uint32_t mask;
+ uint32_t sid_start;
+} nt_system_resource_attribute_ace;
+
+
+typedef struct _nt_system_scoped_policy_id_ace {
+ nt_ace_header header;
+ uint32_t mask;
+ uint32_t sid_start;
+} nt_system_scoped_policy_id_ace;
+
+
+typedef struct _nt_system_mandatory_label_ace {
+ nt_ace_header header;
+ uint32_t mask;
+ uint32_t sid_start;
+} nt_system_mandatory_label_ace;
+
+#endif
diff --git a/include/ntapi/nt_argv.h b/include/ntapi/nt_argv.h
new file mode 100644
index 0000000..eae5996
--- /dev/null
+++ b/include/ntapi/nt_argv.h
@@ -0,0 +1,204 @@
+#ifndef _NT_ARGV_H_
+#define _NT_ARGV_H_
+
+/******************************************************
+ * *
+ * this header is REALLY NOT what you are looking *
+ * for, however if you are into writing your apps *
+ * using the Native API only, then you might find *
+ * the below interfaces somehow useful. *
+ * *
+ *****************************************************/
+
+#include <psxtypes/psxtypes.h>
+
+/* ntapi_tt_get_argv_envp_utf16 flag bits */
+#define NT_GET_ARGV_ENVP_USE_INTERNAL_BUFFER (0x0000)
+#define NT_GET_ARGV_ENVP_USE_CALLER_BUFFER (0x0001)
+#define NT_GET_ARGV_ENVP_COPY_ENVIRONMENT (0x0002)
+#define NT_GET_ARGV_ENVP_VALIDATE_UTF16 (0x0004)
+
+/* ntapi_tt_program_option flag bits */
+#define NT_OPTION_SHORT (0x0001)
+#define NT_OPTION_LONG (0x0002)
+#define NT_OPTION_ALLOWED_ONCE (0x0100)
+#define NT_OPTION_ALLOWED_MANY (0x0200)
+#define NT_OPTION_REQUIRED (0x0400)
+#define NT_OPTION_VALUE_REQUIRED (0x1000)
+
+typedef struct _nt_program_option {
+ int option_count;
+ wchar16_t short_name_code;
+ wchar16_t * long_name;
+ uint32_t long_name_hash;
+ wchar16_t * value;
+ uint32_t value_hash;
+ uint32_t flags;
+} nt_program_option;
+
+
+typedef struct _nt_program_options_meta {
+ int idx_next_argument;
+ int idx_invalid_short_name;
+ int idx_invalid_long_name;
+ int idx_invalid_argument;
+ int idx_missing_option_value;
+} nt_program_options_meta;
+
+
+typedef struct _nt_env_var_meta_utf16 {
+ wchar16_t * name;
+ uint32_t name_hash;
+ wchar16_t * value;
+ uint32_t value_hash;
+ int envp_index;
+ uint32_t flags;
+} nt_env_var_meta_utf16;
+
+
+typedef struct _nt_cmd_option_meta_utf16 {
+ wchar16_t * short_name;
+ uint32_t short_name_code;
+ wchar16_t * long_name;
+ uint32_t long_name_hash;
+ wchar16_t * value;
+ uint32_t value_hash;
+ int argv_index;
+ uint32_t flags;
+} nt_cmd_option_meta_utf16;
+
+
+typedef struct _nt_argv_envp_block_info {
+ wchar16_t * cmd_line;
+ wchar16_t ** wargv_buffer;
+ size_t wargv_buffer_len;
+ wchar16_t * wargs_buffer;
+ size_t wargs_buffer_len;
+ size_t wargs_bytes_written;
+ wchar16_t ** wenvp_buffer;
+ size_t wenvp_buffer_len;
+ wchar16_t * wenvs_buffer;
+ size_t wenvs_buffer_len;
+ size_t wenvs_bytes_used;
+ char * args_buffer;
+ size_t args_buffer_len;
+ size_t args_bytes_written;
+ char * envs_buffer;
+ size_t envs_buffer_len;
+ size_t envs_bytes_used;
+ uint32_t arg_flags;
+ uint32_t env_flags;
+ uint32_t psx_flags;
+ uint32_t psx_padding;
+ uint32_t argv_envp_ptr_total;
+ int envc;
+
+ int argc;
+ char ** argv;
+ char ** envp;
+} nt_argv_envp_block_info;
+
+
+typedef struct _nt_get_argv_envp_ext_params {
+ nt_argv_envp_block_info argv_envp_block_info;
+} nt_get_argv_envp_ext_params;
+
+
+typedef wchar16_t * __stdcall ntapi_tt_get_cmd_line_utf16(void);
+
+
+typedef wchar16_t * __stdcall ntapi_tt_get_peb_env_block_utf16(void);
+
+
+typedef int32_t __stdcall ntapi_tt_parse_cmd_line_args_utf16(
+ __in wchar16_t * cmd_line,
+ __out int * arg_count,
+ __in wchar16_t * args_buffer,
+ __in size_t args_buffer_len,
+ __out size_t * args_bytes_written __optional,
+ __in wchar16_t ** argv_buffer,
+ __in size_t argv_buffer_len,
+ __in uint32_t arg_flags);
+
+
+typedef int32_t __stdcall ntapi_tt_get_argv_envp_utf8(
+ __out int * argc,
+ __out char *** argv,
+ __out char *** envp,
+ __in uint32_t flags,
+ __in void * ext_params __optional,
+ __out void * reserved __optional);
+
+
+typedef int32_t __stdcall ntapi_tt_get_argv_envp_utf16(
+ __out int * argc,
+ __out wchar16_t *** wargv,
+ __out wchar16_t *** wenvp,
+ __in uint32_t flags,
+ __in void * ext_params __optional,
+ __out void * reserved __optional);
+
+
+typedef 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);
+
+
+typedef int32_t __stdcall ntapi_tt_get_short_option_meta_utf16(
+ __in const uint32_t * crc32_table,
+ __in wchar16_t option_name,
+ __in wchar16_t * argv[],
+ __out nt_cmd_option_meta_utf16 * cmd_opt_meta);
+
+
+typedef int32_t __stdcall ntapi_tt_get_long_option_meta_utf16(
+ __in const uint32_t * crc32_table,
+ __in wchar16_t * option_name,
+ __in uint32_t option_name_hash __optional,
+ __in wchar16_t * argv[],
+ __out nt_cmd_option_meta_utf16 * cmd_opt_meta);
+
+typedef int32_t __stdcall ntapi_tt_array_copy_utf8(
+ __out int * argc,
+ __in const char ** argv,
+ __in const char ** wenvp,
+ __in const char * image_name __optional,
+ __in const char * interpreter __optional,
+ __in const char * optarg __optional,
+ __in void * base,
+ __out void * buffer,
+ __in size_t buflen,
+ __out size_t * blklen);
+
+typedef int32_t __stdcall ntapi_tt_array_copy_utf16(
+ __out int * argc,
+ __in const wchar16_t ** wargv,
+ __in const wchar16_t ** wenvp,
+ __in const wchar16_t * image_name __optional,
+ __in const wchar16_t * interpreter __optional,
+ __in const wchar16_t * optarg __optional,
+ __in void * base,
+ __out void * buffer,
+ __in size_t buflen,
+ __out size_t * blklen);
+
+typedef int32_t __stdcall ntapi_tt_array_convert_utf8_to_utf16(
+ __in char ** arrv,
+ __in wchar16_t ** arra,
+ __in void * base,
+ __in wchar16_t * buffer,
+ __in size_t buffer_len,
+ __out size_t * bytes_written);
+
+typedef int32_t __stdcall ntapi_tt_array_convert_utf16_to_utf8(
+ __in wchar16_t ** warrv,
+ __in char ** arra,
+ __in void * base,
+ __in char * buffer,
+ __in size_t buffer_len,
+ __out size_t * bytes_written);
+
+#endif
diff --git a/include/ntapi/nt_atom.h b/include/ntapi/nt_atom.h
new file mode 100644
index 0000000..36d660d
--- /dev/null
+++ b/include/ntapi/nt_atom.h
@@ -0,0 +1,52 @@
+#ifndef _NT_ATOM_H_
+#define _NT_ATOM_H_
+
+#include <psxtypes/psxtypes.h>
+
+typedef enum _nt_atom_info_class {
+ NT_ATOM_BASIC_INFORMATION,
+ NT_ATOM_LIST_INFORMATION
+} nt_atom_info_class;
+
+
+typedef uint16_t nt_atom;
+
+
+typedef struct _nt_atom_basic_information {
+ uint16_t reference_count;
+ uint16_t pinned;
+ uint16_t name_length;
+ wchar16_t name[];
+} nt_atom_basic_information;
+
+
+typedef struct _nt_atom_list_information {
+ uint32_t number_of_atoms;
+ nt_atom atoms[2];
+} nt_atom_list_information;
+
+
+typedef int32_t __stdcall ntapi_zw_add_atom(
+ __in wchar16_t str,
+ __in uint16_t str_length,
+ __out uint16_t * atom);
+
+
+typedef int32_t __stdcall ntapi_zw_find_atom(
+ __in wchar16_t str,
+ __in uint16_t str_length,
+ __out uint16_t * atom);
+
+
+typedef int32_t __stdcall ntapi_zw_delete_atom(
+ __in uint16_t * atom);
+
+
+typedef int32_t __stdcall ntapi_zw_query_information_atom(
+ __in uint16_t * atom,
+ __in nt_atom_info_class atom_info_class,
+ __out void * atom_info,
+ __in uint32_t atom_info_length,
+ __out uint32_t * returned_length __optional);
+
+#endif
diff --git a/include/ntapi/nt_atomic.h b/include/ntapi/nt_atomic.h
new file mode 100644
index 0000000..068b4e2
--- /dev/null
+++ b/include/ntapi/nt_atomic.h
@@ -0,0 +1,157 @@
+#ifndef _NT_ATOMIC_H_
+#define _NT_ATOMIC_H_
+
+#include <psxtypes/psxtypes.h>
+
+static __inline__ void at_locked_inc(
+ intptr_t volatile * ptr);
+
+static __inline__ void at_locked_inc_32(
+ int32_t volatile * ptr);
+
+static __inline__ void at_locked_inc_64(
+ int64_t volatile * ptr);
+
+static __inline__ void at_locked_dec(
+ intptr_t volatile * ptr);
+
+static __inline__ void at_locked_dec_32(
+ int32_t volatile * ptr);
+
+static __inline__ void at_locked_dec_64(
+ int64_t volatile * ptr);
+
+static __inline__ void at_locked_add(
+ intptr_t volatile * ptr,
+ intptr_t val);
+
+static __inline__ void at_locked_add_32(
+ int32_t volatile * ptr,
+ int32_t val);
+
+static __inline__ void at_locked_add_64(
+ int64_t volatile * ptr,
+ int64_t val);
+
+static __inline__ void at_locked_sub(
+ intptr_t volatile * ptr,
+ intptr_t val);
+
+static __inline__ void at_locked_sub_32(
+ int32_t volatile * ptr,
+ int32_t val);
+
+static __inline__ void at_locked_sub_64(
+ int64_t volatile * ptr,
+ int64_t val);
+
+static __inline__ intptr_t at_locked_xadd(
+ intptr_t volatile * ptr,
+ intptr_t val);
+
+static __inline__ int32_t at_locked_xadd_32(
+ int32_t volatile * ptr,
+ int32_t val);
+
+static __inline__ int64_t at_locked_xadd_64(
+ int64_t volatile * ptr,
+ int64_t val);
+
+static __inline__ intptr_t at_locked_xsub(
+ intptr_t volatile * ptr,
+ intptr_t val);
+
+static __inline__ int32_t at_locked_xsub_32(
+ int32_t volatile * ptr,
+ int32_t val);
+
+static __inline__ int64_t at_locked_xsub_64(
+ int64_t volatile * ptr,
+ int64_t val);
+
+static __inline__ intptr_t at_locked_cas(
+ intptr_t volatile * dst,
+ intptr_t cmp,
+ intptr_t xchg);
+
+static __inline__ int32_t at_locked_cas_32(
+ int32_t volatile * dst,
+ int32_t cmp,
+ int32_t xchg);
+
+static __inline__ int64_t at_locked_cas_64(
+ int64_t volatile * dst,
+ int64_t cmp,
+ int64_t xchg);
+
+static __inline__ intptr_t at_locked_and(
+ intptr_t volatile * dst,
+ intptr_t mask);
+
+
+static __inline__ int32_t at_locked_and_32(
+ int32_t volatile * dst,
+ int32_t mask);
+
+
+static __inline__ int64_t at_locked_and_64(
+ int64_t volatile * dst,
+ int64_t mask);
+
+
+static __inline__ intptr_t at_locked_or(
+ intptr_t volatile * dst,
+ intptr_t mask);
+
+
+static __inline__ int32_t at_locked_or_32(
+ int32_t volatile * dst,
+ int32_t mask);
+
+
+static __inline__ int64_t at_locked_or_64(
+ int64_t volatile * dst,
+ int64_t mask);
+
+
+static __inline__ intptr_t at_locked_xor(
+ intptr_t volatile * dst,
+ intptr_t mask);
+
+
+static __inline__ int32_t at_locked_xor_32(
+ int32_t volatile * dst,
+ int32_t mask);
+
+
+static __inline__ int64_t at_locked_xor_64(
+ int64_t volatile * dst,
+ int64_t mask);
+
+static __inline__ void at_store(
+ volatile intptr_t * dst,
+ intptr_t val);
+
+static __inline__ int at_bsf(
+ unsigned int * index,
+ uintptr_t mask);
+
+static __inline__ int at_bsr(
+ unsigned int * index,
+ uintptr_t mask);
+
+static __inline__ size_t at_popcount(
+ uintptr_t mask);
+
+static __inline__ size_t at_popcount_16(
+ uint16_t mask);
+
+static __inline__ size_t at_popcount_32(
+ uint32_t mask);
+
+static __inline__ size_t at_popcount_64(
+ uint64_t mask);
+
+#include "bits/nt_atomic_inline_asm.h"
+
+#endif
diff --git a/include/ntapi/nt_auxv.h b/include/ntapi/nt_auxv.h
new file mode 100644
index 0000000..d460c82
--- /dev/null
+++ b/include/ntapi/nt_auxv.h
@@ -0,0 +1,50 @@
+#ifndef _NT_AUXV_H_
+#define _NT_AUXV_H_
+
+#include <psxtypes/psxtypes.h>
+
+#define NT_AT_NULL 0
+#define NT_AT_IGNORE 1
+#define NT_AT_EXECFD 2
+#define NT_AT_PHDR 3
+#define NT_AT_PHENT 4
+#define NT_AT_PHNUM 5
+#define NT_AT_PAGESZ 6
+#define NT_AT_BASE 7
+#define NT_AT_FLAGS 8
+#define NT_AT_ENTRY 9
+#define NT_AT_NOTELF 10
+#define NT_AT_UID 11
+#define NT_AT_EUID 12
+#define NT_AT_GID 13
+#define NT_AT_EGID 14
+#define NT_AT_CLKTCK 17
+#define NT_AT_PLATFORM 15
+#define NT_AT_HWCAP 16
+#define NT_AT_FPUCW 18
+#define NT_AT_DCACHEBSIZE 19
+#define NT_AT_ICACHEBSIZE 20
+#define NT_AT_UCACHEBSIZE 21
+#define NT_AT_IGNOREPPC 22
+#define AT_SECURE 23
+#define NT_AT_BASE_PLATFORM 24
+#define NT_AT_RANDOM 25
+#define NT_AT_HWCAP2 26
+#define NT_AT_EXECFN 31
+#define NT_AT_SYSINFO 32
+#define NT_AT_SYSINFO_EHDR 33
+#define NT_AT_L1I_CACHESHAPE 34
+#define NT_AT_L1D_CACHESHAPE 35
+#define NT_AT_L2_CACHESHAPE 36
+#define NT_AT_L3_CACHESHAPE 37
+#define NT_AT_ARRAY_CAP 38
+
+typedef struct _nt_auxv_t {
+ uintptr_t a_type;
+
+ union {
+ uintptr_t a_val;
+ } a_un;
+} nt_auxv_t;
+
+#endif
diff --git a/include/ntapi/nt_blitter.h b/include/ntapi/nt_blitter.h
new file mode 100644
index 0000000..529a843
--- /dev/null
+++ b/include/ntapi/nt_blitter.h
@@ -0,0 +1,129 @@
+#ifndef _NT_BLITTER_H_
+#define _NT_BLITTER_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+/* blt_alloc flag bits */
+#define NT_BLITTER_ENABLE_BLOCK_ARRAY 0x01
+#define NT_BLITTER_ENABLE_BLOCK_SECTIONS 0x02
+#define NT_BLITTER_ENABLE_CACHE 0x04
+#define NT_BLITTER_PRESERVE_BITS 0x08
+
+/* blitter query type bits */
+#define NT_BLITTER_QUERY_INFO 0x01
+#define NT_BLITTER_QUERY_PARAMS 0x02
+
+/* blitter context (opaque) */
+typedef struct nt_blitter_context nt_blitter;
+
+typedef struct _nt_blitter_params {
+ size_t params_size;
+ size_t block_size;
+ intptr_t block_count;
+ intptr_t cache_blocks_min; __optional
+ intptr_t cache_blocks_max; __optional
+ size_t zero_bits; __optional
+ uint32_t srvtid; __optional
+ uint32_t flags; __optional
+ int32_t lock_tries; __optional
+ int32_t round_trips; __optional
+ void * hsignal_blt; __optional
+ void * hsignal_app; __optional
+ void * bitmap; __optional
+ void * region; __optional
+} nt_blitter_params;
+
+
+typedef struct _nt_blitter_info {
+ size_t info_size;
+ void * region_addr;
+ size_t region_size;
+ size_t block_size;
+ intptr_t block_count;
+ intptr_t blocks_used;
+ intptr_t blocks_avail;
+ intptr_t blocks_cached;
+ intptr_t lock_tries;
+ intptr_t busy;
+} nt_blitter_info;
+
+
+typedef struct _nt_blitter_query {
+ size_t size;
+ int32_t type;
+ uint32_t flags;
+ nt_blitter_params * params;
+ nt_blitter_info * info;
+} nt_blitter_query;
+
+
+typedef struct _nt_blitter_config {
+ size_t size;
+ int32_t type;
+ uint32_t flags;
+ nt_blitter_params * params;
+} nt_blitter_config;
+
+
+/* blitter functions */
+typedef int32_t __fastcall ntapi_blt_alloc(
+ __out nt_blitter ** blitter,
+ __in nt_blitter_params * params);
+
+
+typedef int32_t __fastcall ntapi_blt_free(
+ __in nt_blitter * blitter);
+
+
+typedef int32_t __fastcall ntapi_blt_query(
+ __in nt_blitter * blitter,
+ __in nt_blitter_query * blt_query);
+
+
+typedef int32_t __fastcall ntapi_blt_config(
+ __in nt_blitter * blitter,
+ __in nt_blitter_config * blt_config);
+
+
+typedef int32_t __fastcall ntapi_blt_acquire(
+ __in nt_blitter * blitter,
+ __out intptr_t * block_id);
+
+
+typedef int32_t __fastcall ntapi_blt_obtain(
+ __in nt_blitter * blitter,
+ __out intptr_t * block_id);
+
+
+typedef int32_t __fastcall ntapi_blt_possess(
+ __in nt_blitter * blitter,
+ __out intptr_t * block_id);
+
+
+typedef int32_t __fastcall ntapi_blt_release(
+ __in nt_blitter * blitter,
+ __in intptr_t block_id);
+
+
+typedef void * __fastcall ntapi_blt_region(
+ __in const nt_blitter * blitter);
+
+
+/**
+ * blt_get,blt_set:
+ * clients might prefr to write inlined
+ * alternatives that use a cached blt_region.
+**/
+typedef void * __fastcall ntapi_blt_get(
+ __in const nt_blitter * blitter,
+ __in intptr_t block_id);
+
+
+typedef void __fastcall ntapi_blt_set(
+ __in const nt_blitter * blitter,
+ __in intptr_t block_id,
+ __in void * val);
+
+
+#endif
diff --git a/include/ntapi/nt_crc32.h b/include/ntapi/nt_crc32.h
new file mode 100644
index 0000000..9f08e12
--- /dev/null
+++ b/include/ntapi/nt_crc32.h
@@ -0,0 +1,95 @@
+#ifndef _NT_CRC32_H_
+#define _NT_CRC32_H_
+
+#include <psxtypes/psxtypes.h>
+
+#define NTAPI_CRC32_POLY 0xd35a6b40
+
+#define NTAPI_CRC32_TABLE { \
+ 0x00000000, 0xd2fcdf96, 0x034d69ad, 0xd1b1b63b, \
+ 0x069ad35a, 0xd4660ccc, 0x05d7baf7, 0xd72b6561, \
+ 0x0d35a6b4, 0xdfc97922, 0x0e78cf19, 0xdc84108f, \
+ 0x0baf75ee, 0xd953aa78, 0x08e21c43, 0xda1ec3d5, \
+ 0x1a6b4d68, 0xc89792fe, 0x192624c5, 0xcbdafb53, \
+ 0x1cf19e32, 0xce0d41a4, 0x1fbcf79f, 0xcd402809, \
+ 0x175eebdc, 0xc5a2344a, 0x14138271, 0xc6ef5de7, \
+ 0x11c43886, 0xc338e710, 0x1289512b, 0xc0758ebd, \
+ 0x34d69ad0, 0xe62a4546, 0x379bf37d, 0xe5672ceb, \
+ 0x324c498a, 0xe0b0961c, 0x31012027, 0xe3fdffb1, \
+ 0x39e33c64, 0xeb1fe3f2, 0x3aae55c9, 0xe8528a5f, \
+ 0x3f79ef3e, 0xed8530a8, 0x3c348693, 0xeec85905, \
+ 0x2ebdd7b8, 0xfc41082e, 0x2df0be15, 0xff0c6183, \
+ 0x282704e2, 0xfadbdb74, 0x2b6a6d4f, 0xf996b2d9, \
+ 0x2388710c, 0xf174ae9a, 0x20c518a1, 0xf239c737, \
+ 0x2512a256, 0xf7ee7dc0, 0x265fcbfb, 0xf4a3146d, \
+ 0x69ad35a0, 0xbb51ea36, 0x6ae05c0d, 0xb81c839b, \
+ 0x6f37e6fa, 0xbdcb396c, 0x6c7a8f57, 0xbe8650c1, \
+ 0x64989314, 0xb6644c82, 0x67d5fab9, 0xb529252f, \
+ 0x6202404e, 0xb0fe9fd8, 0x614f29e3, 0xb3b3f675, \
+ 0x73c678c8, 0xa13aa75e, 0x708b1165, 0xa277cef3, \
+ 0x755cab92, 0xa7a07404, 0x7611c23f, 0xa4ed1da9, \
+ 0x7ef3de7c, 0xac0f01ea, 0x7dbeb7d1, 0xaf426847, \
+ 0x78690d26, 0xaa95d2b0, 0x7b24648b, 0xa9d8bb1d, \
+ 0x5d7baf70, 0x8f8770e6, 0x5e36c6dd, 0x8cca194b, \
+ 0x5be17c2a, 0x891da3bc, 0x58ac1587, 0x8a50ca11, \
+ 0x504e09c4, 0x82b2d652, 0x53036069, 0x81ffbfff, \
+ 0x56d4da9e, 0x84280508, 0x5599b333, 0x87656ca5, \
+ 0x4710e218, 0x95ec3d8e, 0x445d8bb5, 0x96a15423, \
+ 0x418a3142, 0x9376eed4, 0x42c758ef, 0x903b8779, \
+ 0x4a2544ac, 0x98d99b3a, 0x49682d01, 0x9b94f297, \
+ 0x4cbf97f6, 0x9e434860, 0x4ff2fe5b, 0x9d0e21cd, \
+ 0xd35a6b40, 0x01a6b4d6, 0xd01702ed, 0x02ebdd7b, \
+ 0xd5c0b81a, 0x073c678c, 0xd68dd1b7, 0x04710e21, \
+ 0xde6fcdf4, 0x0c931262, 0xdd22a459, 0x0fde7bcf, \
+ 0xd8f51eae, 0x0a09c138, 0xdbb87703, 0x0944a895, \
+ 0xc9312628, 0x1bcdf9be, 0xca7c4f85, 0x18809013, \
+ 0xcfabf572, 0x1d572ae4, 0xcce69cdf, 0x1e1a4349, \
+ 0xc404809c, 0x16f85f0a, 0xc749e931, 0x15b536a7, \
+ 0xc29e53c6, 0x10628c50, 0xc1d33a6b, 0x132fe5fd, \
+ 0xe78cf190, 0x35702e06, 0xe4c1983d, 0x363d47ab, \
+ 0xe11622ca, 0x33eafd5c, 0xe25b4b67, 0x30a794f1, \
+ 0xeab95724, 0x384588b2, 0xe9f43e89, 0x3b08e11f, \
+ 0xec23847e, 0x3edf5be8, 0xef6eedd3, 0x3d923245, \
+ 0xfde7bcf8, 0x2f1b636e, 0xfeaad555, 0x2c560ac3, \
+ 0xfb7d6fa2, 0x2981b034, 0xf830060f, 0x2accd999, \
+ 0xf0d21a4c, 0x222ec5da, 0xf39f73e1, 0x2163ac77, \
+ 0xf648c916, 0x24b41680, 0xf505a0bb, 0x27f97f2d, \
+ 0xbaf75ee0, 0x680b8176, 0xb9ba374d, 0x6b46e8db, \
+ 0xbc6d8dba, 0x6e91522c, 0xbf20e417, 0x6ddc3b81, \
+ 0xb7c2f854, 0x653e27c2, 0xb48f91f9, 0x66734e6f, \
+ 0xb1582b0e, 0x63a4f498, 0xb21542a3, 0x60e99d35, \
+ 0xa09c1388, 0x7260cc1e, 0xa3d17a25, 0x712da5b3, \
+ 0xa606c0d2, 0x74fa1f44, 0xa54ba97f, 0x77b776e9, \
+ 0xada9b53c, 0x7f556aaa, 0xaee4dc91, 0x7c180307, \
+ 0xab336666, 0x79cfb9f0, 0xa87e0fcb, 0x7a82d05d, \
+ 0x8e21c430, 0x5cdd1ba6, 0x8d6cad9d, 0x5f90720b, \
+ 0x88bb176a, 0x5a47c8fc, 0x8bf67ec7, 0x590aa151, \
+ 0x83146284, 0x51e8bd12, 0x80590b29, 0x52a5d4bf, \
+ 0x858eb1de, 0x57726e48, 0x86c3d873, 0x543f07e5, \
+ 0x944a8958, 0x46b656ce, 0x9707e0f5, 0x45fb3f63, \
+ 0x92d05a02, 0x402c8594, 0x919d33af, 0x4361ec39, \
+ 0x997f2fec, 0x4b83f07a, 0x9a324641, 0x48ce99d7, \
+ 0x9fe5fcb6, 0x4d192320, 0x9ca8951b, 0x4e544a8d \
+}
+
+
+typedef struct _ntapi_hashed_symbol {
+ uint32_t crc32_hash;
+ uint32_t ordinal;
+} ntapi_hashed_symbol;
+
+
+typedef uint32_t __cdecl ntapi_tt_buffer_crc32(
+ uint32_t prev_hash,
+ const void * buffer,
+ size_t size);
+
+
+typedef uint32_t __cdecl ntapi_tt_mbstr_crc32(
+ const void * str);
+
+
+typedef const uint32_t * __cdecl ntapi_tt_crc32_table(void);
+
+
+#endif
diff --git a/include/ntapi/nt_daemon.h b/include/ntapi/nt_daemon.h
new file mode 100644
index 0000000..ef9939b
--- /dev/null
+++ b/include/ntapi/nt_daemon.h
@@ -0,0 +1,89 @@
+#ifndef _NT_DAEMON_H_
+#define _NT_DAEMON_H_
+
+/**
+ * daemon start-up routines
+ * -----------------------
+ * upon successful return from dsr_init(),
+ * an LPC-based daemon will have entered its
+ * main service loop in a dedicated thread,
+ * having already established an internal
+ * connection.
+ *
+ * remarks
+ * -------
+ * 1) in the larger-scale midipix project, three
+ * different daemons are initialized using the
+ * below api, namely the optional tty server,
+ * the optional virtual mount server, and the
+ * posix system call layer internal daemon.
+ *
+ * 2) the initialization routines make use of two
+ * events: a 'damon-is-ready' event, and an
+ * 'internal-client-is-ready' event. if these
+ * events are not provided by the application
+ * then they will be created by this library,
+ * in which case each of the two handles may
+ * optionally be saved to a caller-provided
+ * address.
+ *
+ * 3) the dedicated thread of a well-designed
+ * daemon should be able to use a stack that
+ * is relatively very small; to fine-tune
+ * the stack size of the daemon's dedicated
+ * thread, use the appropriate members of
+ * the nt_daemon_params structure.
+**/
+
+#include <psxtypes/psxtypes.h>
+#include "nt_thread.h"
+#include "nt_port.h"
+
+/* NT_DSR_INIT_FLAGS */
+#define NT_DSR_INIT_DEFAULT 0x0000
+#define NT_DSR_INIT_GENERATE_KEYS 0x0001
+#define NT_DSR_INIT_FORMAT_KEYS 0x0002
+#define NT_DSR_INIT_CLOSE_EVENTS 0x0004
+
+/* daemon start: max wait: 156 seconds (twelve bonobo couples) */
+#define NT_DSR_INIT_MAX_WAIT 156 * (-1) * 10 * 1000 * 1000
+
+typedef int32_t __stdcall nt_daemon_routine(void * context);
+
+typedef struct _nt_daemon_params {
+ wchar16_t * port_name;
+ nt_port_keys * port_keys;
+ nt_port_name_keys * port_name_keys;
+ uintptr_t port_msg_size;
+ nt_daemon_routine * daemon_once_routine;
+ nt_daemon_routine * daemon_loop_routine;
+ void * daemon_loop_context;
+ void * hport_daemon;
+ void ** pport_daemon;
+ void * hport_internal_client;
+ void ** pport_internal_client;
+ void * hevent_daemon_ready;
+ void ** pevent_daemon_ready;
+ void * hevent_internal_client_ready;
+ void ** pevent_internal_client_ready;
+ void * hthread_daemon_start;
+ void * hthread_daemon_loop;
+ void * hthread_internal_client;
+ int32_t exit_code_daemon_start;
+ int32_t exit_code_daemon_loop;
+ int32_t exit_code_internal_client;
+ uint32_t flags;
+ size_t stack_size_commit;
+ size_t stack_size_reserve;
+ nt_user_stack * stack_info;
+} nt_daemon_params, nt_dsr_params;
+
+
+typedef int32_t __stdcall ntapi_dsr_init(nt_daemon_params *);
+typedef int32_t __stdcall ntapi_dsr_start(nt_daemon_params *);
+typedef int32_t __stdcall ntapi_dsr_create_port(nt_daemon_params *);
+typedef int32_t __stdcall ntapi_dsr_connect_internal_client(nt_daemon_params *);
+typedef int32_t __stdcall ntapi_dsr_internal_client_connect(nt_daemon_params *);
+typedef int32_t __stdcall ntapi_dsr_loop(void *);
+
+#endif
diff --git a/include/ntapi/nt_debug.h b/include/ntapi/nt_debug.h
new file mode 100644
index 0000000..bd07dcc
--- /dev/null
+++ b/include/ntapi/nt_debug.h
@@ -0,0 +1,37 @@
+#ifndef _NT_DEBUG_H_
+#define _NT_DEBUG_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_file.h"
+
+typedef ssize_t __cdecl ntapi_dbg_write(
+ __in void * hfile,
+ __in const void * buf,
+ __in size_t bytes);
+
+
+typedef int32_t __cdecl ntapi_dbg_fn_call(
+ __in void * hfile __optional,
+ __in char * fn_caller_name,
+ __in void * fn_callee_addr,
+ __in uintptr_t fn_ret,
+ __in ntapi_dbg_write* pfn_dbg_write __optional,
+ __in char * source __optional,
+ __in int line __optional);
+
+
+typedef int32_t __cdecl ntapi_dbg_msg(
+ __in void * hfile __optional,
+ __in char * source __optional,
+ __in int line __optional,
+ __in char * fn_caller_name,
+ __in char * fmt,
+ __in uintptr_t arg1,
+ __in uintptr_t arg2,
+ __in uintptr_t arg3,
+ __in uintptr_t arg4,
+ __in uintptr_t arg5,
+ __in uintptr_t arg6,
+ __in ntapi_dbg_write* pfn_dbg_write __optional);
+
+#endif
diff --git a/include/ntapi/nt_device.h b/include/ntapi/nt_device.h
new file mode 100644
index 0000000..ca1b4d9
--- /dev/null
+++ b/include/ntapi/nt_device.h
@@ -0,0 +1,308 @@
+#ifndef _NT_DEVICE_H_
+#define _NT_DEVICE_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_device_type {
+ NT_FILE_DEVICE_8042_PORT = 0x00000027,
+ NT_FILE_DEVICE_ACPI = 0x00000032,
+ NT_FILE_DEVICE_BATTERY = 0x00000029,
+ NT_FILE_DEVICE_BEEP = 0x00000001,
+ NT_FILE_DEVICE_BUS_EXTENDER = 0x0000002a,
+ NT_FILE_DEVICE_CD_ROM = 0x00000002,
+ NT_FILE_DEVICE_CD_ROM_FILE_SYSTEM = 0x00000003,
+ NT_FILE_DEVICE_CHANGER = 0x00000030,
+ NT_FILE_DEVICE_CONTROLLER = 0x00000004,
+ NT_FILE_DEVICE_DATALINK = 0x00000005,
+ NT_FILE_DEVICE_DFS = 0x00000006,
+ NT_FILE_DEVICE_DFS_FILE_SYSTEM = 0x00000035,
+ NT_FILE_DEVICE_DFS_VOLUME = 0x00000036,
+ NT_FILE_DEVICE_DISK = 0x00000007,
+ NT_FILE_DEVICE_DISK_FILE_SYSTEM = 0x00000008,
+ NT_FILE_DEVICE_DVD = 0x00000033,
+ NT_FILE_DEVICE_FILE_SYSTEM = 0x00000009,
+ NT_FILE_DEVICE_FIPS = 0x0000003a,
+ NT_FILE_DEVICE_FULLSCREEN_VIDEO = 0x00000034,
+ NT_FILE_DEVICE_INPORT_PORT = 0x0000000a,
+ NT_FILE_DEVICE_KEYBOARD = 0x0000000b,
+ NT_FILE_DEVICE_KS = 0x0000002f,
+ NT_FILE_DEVICE_KSEC = 0x00000039,
+ NT_FILE_DEVICE_MAILSLOT = 0x0000000c,
+ NT_FILE_DEVICE_MASS_STORAGE = 0x0000002d,
+ NT_FILE_DEVICE_MIDI_IN = 0x0000000d,
+ NT_FILE_DEVICE_MIDI_OUT = 0x0000000e,
+ NT_FILE_DEVICE_MODEM = 0x0000002b,
+ NT_FILE_DEVICE_MOUSE = 0x0000000f,
+ NT_FILE_DEVICE_MULTI_UNC_PROVIDER = 0x00000010,
+ NT_FILE_DEVICE_NAMED_PIPE = 0x00000011,
+ NT_FILE_DEVICE_NETWORK = 0x00000012,
+ NT_FILE_DEVICE_NETWORK_BROWSER = 0x00000013,
+ NT_FILE_DEVICE_NETWORK_FILE_SYSTEM = 0x00000014,
+ NT_FILE_DEVICE_NETWORK_REDIRECTOR = 0x00000028,
+ NT_FILE_DEVICE_NULL = 0x00000015,
+ NT_FILE_DEVICE_PARALLEL_PORT = 0x00000016,
+ NT_FILE_DEVICE_PHYSICAL_NETCARD = 0x00000017,
+ NT_FILE_DEVICE_PRINTER = 0x00000018,
+ NT_FILE_DEVICE_SCANNER = 0x00000019,
+ NT_FILE_DEVICE_SCREEN = 0x0000001c,
+ NT_FILE_DEVICE_SERENUM = 0x00000037,
+ NT_FILE_DEVICE_SERIAL_MOUSE_PORT = 0x0000001a,
+ NT_FILE_DEVICE_SERIAL_PORT = 0x0000001b,
+ NT_FILE_DEVICE_SMARTCARD = 0x00000031,
+ NT_FILE_DEVICE_SMB = 0x0000002e,
+ NT_FILE_DEVICE_SOUND = 0x0000001d,
+ NT_FILE_DEVICE_STREAMS = 0x0000001e,
+ NT_FILE_DEVICE_TAPE = 0x0000001f,
+ NT_FILE_DEVICE_TAPE_FILE_SYSTEM = 0x00000020,
+ NT_FILE_DEVICE_TERMSRV = 0x00000038,
+ NT_FILE_DEVICE_TRANSPORT = 0x00000021,
+ NT_FILE_DEVICE_UNKNOWN = 0x00000022,
+ NT_FILE_DEVICE_VDM = 0x0000002c,
+ NT_FILE_DEVICE_VIDEO = 0x00000023,
+ NT_FILE_DEVICE_VIRTUAL_DISK = 0x00000024,
+ NT_FILE_DEVICE_WAVE_IN = 0x00000025,
+ NT_FILE_DEVICE_WAVE_OUT = 0x00000026,
+} nt_device_type;
+
+
+/* forward declaration of structures */
+struct _nt_device_object;
+struct _nt_driver_object;
+
+typedef struct _nt_list_entry {
+ struct _nt_list_entry * flink;
+ struct _nt_list_entry * blink;
+} nt_list_entry;
+
+
+typedef struct _nt_dispatcher_header {
+ int32_t lock; /* context-specific interpretations */
+ int32_t signal_state; /* context-specific interpretations */
+ nt_list_entry wait_list_head;
+} nt_dispatcher_header;
+
+
+typedef struct _nt_io_completion_context {
+ void * port;
+ void * key;
+} nt_io_completion_context;
+
+
+typedef struct _nt_fast_io_dispatch {
+ uint32_t size_of_fast_io_dispatch;
+ unsigned char * fast_io_check_if_possible;
+ unsigned char * fast_io_read;
+ unsigned char * fast_io_write;
+ unsigned char * fast_io_query_basic_info;
+ unsigned char * fast_io_query_standard_info;
+ unsigned char * fast_io_lock;
+ unsigned char * fast_io_unlock_single;
+ unsigned char * fast_io_unlock_all;
+ unsigned char * fast_io_unlock_all_by_key;
+ unsigned char * fast_io_device_control;
+ void * acquire_file_for_nt_create_section;
+ void * release_file_for_nt_create_section;
+ void * fast_io_detach_device;
+ unsigned char * fast_io_query_network_open_info;
+ int32_t acquire_for_mod_write;
+ unsigned char * mdl_read;
+ unsigned char * mdl_read_complete;
+ unsigned char * prepare_mdl_write;
+ unsigned char * mdl_write_complete;
+ unsigned char * fast_io_read_compressed;
+ unsigned char * fast_io_write_compressed;
+ unsigned char * mdl_read_complete_compressed;
+ unsigned char * mdl_write_complete_compressed;
+ unsigned char * fast_io_query_open;
+ int32_t * release_for_mod_write;
+ int32_t * acquire_for_cc_flush;
+ int32_t * release_for_cc_flush;
+} nt_fast_io_dispatch;
+
+
+typedef struct _nt_io_timer {
+ int16_t type;
+ int16_t timer_flag;
+ nt_list_entry timer_listj;
+ void * timer_routine;
+ void * context;
+ void * device_object;
+} nt_io_timer;
+
+
+typedef struct _nt_ecp_list {
+ char opaque[1];
+} nt_ecp_list;
+
+
+typedef struct _nt_txn_parameter_block {
+ uint16_t length;
+ uint16_t tx_fs_context;
+ void * transaction_object;
+} nt_txn_parameter_block;
+
+
+typedef struct _nt_io_driver_create_context {
+ uint16_t size;
+ struct _nt_ecp_list * extra_create_parameters;
+ void * device_object_hint;
+ nt_txn_parameter_block * txn_parameters;
+} nt_io_driver_create_context;
+
+
+typedef struct _nt_irp {
+ int16_t type;
+ uint16_t size;
+ struct _nt_mdl * mdl_address;
+ uint32_t flags;
+ uintptr_t associated_irp;
+ nt_list_entry thread_list_entry;
+ char requestor_mode;
+ unsigned char pending_returned;
+ char stack_count;
+ char current_location;
+ unsigned char cancel;
+ unsigned char cancel_irql;
+ char apc_environment;
+ unsigned char allocation_flags;
+ nt_io_status_block * user_iosb;
+ struct _nt_kevent * user_event;
+ void * overlay[2];
+ void * cancel_routine;
+ void * user_buffer;
+ void * tail;
+} nt_irp;
+
+
+typedef struct _nt_kdevice_queue {
+ int16_t type;
+ int16_t size;
+ struct _nt_list_entry device_list_head;
+ uint64_t lock;
+ unsigned char busy_hint[8];
+} nt_kdevice_queue;
+
+
+typedef struct _nt_kdevice_queue_entry {
+ nt_list_entry device_list_entry;
+ uint32_t sort_key;
+ unsigned char inserted;
+} nt_kdevice_queue_entry;
+
+
+typedef struct _nt_kevent {
+ struct _nt_dispatcher_header header;
+} nt_kevent;
+
+
+typedef struct _nt_kdpc {
+ unsigned char type;
+ unsigned char importance;
+ uint16_t number;
+ nt_list_entry dpc_list_entry;
+ void * deferred_routine;
+ void * deferred_context;
+ void * system_argument_1st;
+ void * system_argument_2nd;
+ void * dpc_data;
+} nt_kdpc;
+
+
+typedef struct _nt_mdl {
+ struct _nt_mdl * next;
+ int16_t size;
+ int16_t mdl_flags;
+ void * process;
+ void * mapped_system_va;
+ void * start_va;
+ uint32_t byte_count;
+ uint32_t byte_offset;
+} nt_mdl;
+
+
+typedef struct _nt_vpb {
+ int16_t type;
+ int16_t size;
+ uint16_t flags;
+ uint16_t volume_label_length;
+ struct _nt_device_object * device_object;
+ struct _nt_device_object * real_device;
+ uint32_t serial_number;
+ uint32_t reference_count;
+ wchar16_t volume_label[32];
+} nt_vpb;
+
+
+typedef struct _nt_wait_context_block {
+ struct _nt_kdevice_queue_entry wait_queue_entry;
+ void * device_routine;
+ void * device_context;
+ uint32_t number_of_map_registers;
+ void * device_object;
+ void * current_irp;
+ struct _kdpc * buffer_chaining_dpc;
+} nt_wait_context_block;
+
+
+typedef struct _nt_device_object {
+ int16_t type;
+ uint16_t size;
+ int32_t ref_count;
+ struct _nt_driver_object * driver_obj;
+ struct _nt_device_object * next_device;
+ struct _nt_device_object * attached_device;
+ struct _nt_irp * current_irp;
+ struct _nt_io_timer * timer;
+ uint32_t flags;
+ uint32_t characteristics;
+ struct _nt_vpb * vpb;
+ void * dev_ext;
+ nt_device_type dev_type;
+ char stack_size;
+
+ union {
+ struct _nt_list_entry list_entry;
+ struct _nt_wait_context_block wcb;
+ } queue;
+
+ uint32_t alignment_requirement;
+ struct _nt_kdevice_queue dev_queue;
+ struct _nt_kdpc dpc;
+ uint32_t active_thread_count;
+ nt_security_descriptor * sec_desc;
+ struct _nt_kevent dev_lock;
+ uint16_t sector_size;
+ uint16_t spare1;
+ void * device_object_extension;
+ void * reserved;
+} nt_device_object;
+
+
+typedef struct _nt_driver_object {
+ int16_t type;
+ int16_t size;
+ struct _nt_device_object * dev_obj;
+ uint32_t flags;
+ void * driver_start;
+ uint32_t driver_size;
+ void * driver_section;
+ void * driver_extension; /* TODO: define struct _nt_driver_extension (tedious) */
+ nt_unicode_string driver_name;
+ nt_unicode_string * hardware_database;
+ struct _nt_fast_io_dispatch * fast_io_dispatch;
+ int32_t * driver_init;
+ void * driver_start_io;
+ void * driver_unload;
+ void * major_function[28];
+} nt_driver_object;
+
+
+typedef int32_t __stdcall ntapi_zw_load_driver(
+ __in nt_unicode_string * driver_service_name);
+
+
+typedef int32_t __stdcall ntapi_zw_unload_driver(
+ __in nt_unicode_string * driver_service_name);
+
+#endif
diff --git a/include/ntapi/nt_exception.h b/include/ntapi/nt_exception.h
new file mode 100644
index 0000000..6284372
--- /dev/null
+++ b/include/ntapi/nt_exception.h
@@ -0,0 +1,29 @@
+#ifndef _NT_EXCEPTION_H_
+#define _NT_EXCEPTION_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+#include "nt_thread.h"
+
+/* limits */
+#define NT_EXCEPTION_MAX_PARAMS (0x0F)
+
+typedef struct _nt_exception_record {
+ uint32_t exception_code;
+ uint32_t exception_flags;
+ struct _nt_exception_record * exception_record;
+ void * exception_address;
+ uint32_t number_of_params;
+ uintptr_t exception_information[NT_EXCEPTION_MAX_PARAMS];
+} nt_exception_record;
+
+typedef int32_t __stdcall ntapi_zw_raise_exception(
+ __in nt_exception_record * exception_record,
+ __in nt_thread_context * context,
+ __in unsigned char search_frames);
+
+typedef int32_t __stdcall ntapi_zw_continue(
+ __in nt_thread_context * context,
+ __in unsigned char test_alert);
+
+#endif
diff --git a/include/ntapi/nt_file.h b/include/ntapi/nt_file.h
new file mode 100644
index 0000000..3bdd085
--- /dev/null
+++ b/include/ntapi/nt_file.h
@@ -0,0 +1,1206 @@
+#ifndef _NT_FILE_H_
+#define _NT_FILE_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+#include "nt_device.h"
+
+typedef enum _nt_file_info_class {
+ NT_FILE_DIRECTORY_INFORMATION = 1,
+ NT_FILE_FULL_DIRECTORY_INFORMATION = 2,
+ NT_FILE_BOTH_DIRECTORY_INFORMATION = 3,
+ NT_FILE_BASIC_INFORMATION = 4,
+ NT_FILE_STANDARD_INFORMATION = 5,
+ NT_FILE_INTERNAL_INFORMATION = 6,
+ NT_FILE_EA_INFORMATION = 7,
+ NT_FILE_ACCESS_INFORMATION = 8,
+ NT_FILE_NAME_INFORMATION = 9,
+ NT_FILE_RENAME_INFORMATION = 10,
+ NT_FILE_LINK_INFORMATION = 11,
+ NT_FILE_NAMES_INFORMATION = 12,
+ NT_FILE_DISPOSITION_INFORMATION = 13,
+ NT_FILE_POSITION_INFORMATION = 14,
+ NT_FILE_FULL_EA_INFORMATION = 15,
+ NT_FILE_MODE_INFORMATION = 16,
+ NT_FILE_ALIGNMENT_INFORMATION = 17,
+ NT_FILE_ALL_INFORMATION = 18,
+ NT_FILE_ALLOCATION_INFORMATION = 19,
+ NT_FILE_END_OF_FILE_INFORMATION = 20,
+ NT_FILE_ALTERNATE_NAME_INFORMATION = 21,
+ NT_FILE_STREAM_INFORMATION = 22,
+ NT_FILE_PIPE_INFORMATION = 23,
+ NT_FILE_PIPE_LOCAL_INFORMATION = 24,
+ NT_FILE_PIPE_REMOTE_INFORMATION = 25,
+ NT_FILE_MAILSLOT_QUERY_INFORMATION = 26,
+ NT_FILE_MAILSLOT_SET_INFORMATION = 27,
+ NT_FILE_COMPRESSION_INFORMATION = 28,
+ NT_FILE_OBJECT_ID_INFORMATION = 29,
+ NT_FILE_COMPLETION_INFORMATION = 30,
+ NT_FILE_MOVE_CLUSTER_INFORMATION = 31,
+ NT_FILE_QUOTA_INFORMATION = 32,
+ NT_FILE_REPARSE_POINT_INFORMATION = 33,
+ NT_FILE_NETWORK_OPEN_INFORMATION = 34,
+ NT_FILE_ATTRIBUTE_TAG_INFORMATION = 35,
+ NT_FILE_TRACKING_INFORMATION = 36,
+ NT_FILE_ID_BOTH_DIRECTORY_INFORMATION = 37,
+ NT_FILE_ID_FULL_DIRECTORY_INFORMATION = 38,
+ NT_FILE_VALID_DATA_LENGTH_INFORMATION = 39,
+ NT_FILE_SHORT_NAME_INFORMATION = 40,
+ NT_FILE_IO_COMPLETION_NOTIFICATION_INFORMATION = 41,
+ NT_FILE_IO_STATUS_BLOCK_RANGE_INFORMATION = 42,
+ NT_FILE_IO_PRIORITY_HINT_INFORMATION = 43,
+ NT_FILE_SFIO_RESERVE_INFORMATION = 44,
+ NT_FILE_SFIO_VOLUME_INFORMATION = 45,
+ NT_FILE_HARD_LINK_INFORMATION = 46,
+ NT_FILE_PROCESS_IDS_USING_FILE_INFORMATION = 47,
+ NT_FILE_NORMALIZED_NAME_INFORMATION = 48,
+ NT_FILE_NETWORK_PHYSICAL_NAME_INFORMATION = 49,
+ NT_FILE_ID_GLOBAL_TX_DIRECTORY_INFORMATION = 50,
+ NT_FILE_IS_REMOTE_DEVICE_INFORMATION = 51,
+ NT_FILE_ATTRIBUTE_CACHE_INFORMATION = 52,
+ NT_FILE_NUMA_NODE_INFORMATION = 53,
+ NT_FILE_STANDARD_LINK_INFORMATION = 54,
+ NT_FILE_REMOTE_PROTOCOL_INFORMATION = 55,
+ NT_FILE_REPLACE_COMPLETION_INFORMATION = 56,
+ NT_FILE_INFORMATION_CAP = 57
+} nt_file_info_class;
+
+
+typedef enum _nt_file_create_disposition {
+ NT_FILE_SUPERSEDE = 0x00000000,
+ NT_FILE_OPEN = 0x00000001,
+ NT_FILE_CREATE = 0x00000002,
+ NT_FILE_OPEN_IF = 0x00000003,
+ NT_FILE_OVERWRITE = 0x00000004,
+ NT_FILE_OVERWRITE_IF = 0x00000005
+} nt_file_create_disposition;
+
+
+typedef enum _nt_file_status {
+ NT_FILE_SUPERSEDED = 0x00000000,
+ NT_FILE_OPENED = 0x00000001,
+ NT_FILE_CREATED = 0x00000002,
+ NT_FILE_OVERWRITTEN = 0x00000003,
+ NT_FILE_EXISTS = 0x00000004,
+ NT_FILE_DOES_NOT_EXIST = 0x00000005
+} nt_file_status;
+
+
+typedef enum _nt_file_action {
+ NT_FILE_ACTION_ADDED = 0x00000001,
+ NT_FILE_ACTION_REMOVED = 0x00000002,
+ NT_FILE_ACTION_MODIFIED = 0x00000003,
+ NT_FILE_ACTION_RENAMED_OLD_NAME = 0x00000004,
+ NT_FILE_ACTION_RENAMED_NEW_NAME = 0x00000005,
+ NT_FILE_ACTION_ADDED_STREAM = 0x00000006,
+ NT_FILE_ACTION_REMOVED_STREAM = 0x00000007,
+ NT_FILE_ACTION_MODIFIED_STREAM = 0x00000008,
+ NT_FILE_ACTION_REMOVED_BY_DELETE = 0x00000009,
+} nt_file_action;
+
+
+typedef enum _nt_file_pipe_flags {
+ NT_FILE_PIPE_BYTE_STREAM_MODE = 0x00000000,
+ NT_FILE_PIPE_MESSAGE_MODE = 0x00000001,
+
+ NT_FILE_PIPE_QUEUE_OPERATION = 0x00000000,
+ NT_FILE_PIPE_COMPLETE_OPERATION = 0x00000001,
+
+ NT_FILE_PIPE_BYTE_STREAM_TYPE = 0x00000000,
+ NT_FILE_PIPE_MESSAGE_TYPE = 0x00000001,
+
+ NT_FILE_PIPE_INBOUND = 0x00000000,
+ NT_FILE_PIPE_OUTBOUND = 0x00000001,
+ NT_FILE_PIPE_FULL_DUPLEX = 0x00000002,
+
+ NT_FILE_PIPE_DISCONNECTED_STATE = 0x00000001,
+ NT_FILE_PIPE_LISTENING_STATE = 0x00000002,
+ NT_FILE_PIPE_CONNECTED_STATE = 0x00000003,
+ NT_FILE_PIPE_CLOSING_STATE = 0x00000004,
+
+ NT_FILE_PIPE_CLIENT_END = 0x00000000,
+ NT_FILE_PIPE_SERVER_END = 0x00000001,
+} nt_file_pipe_flags;
+
+
+typedef enum _nt_io_priority_hint {
+ NT_IO_PRIORITY_VERY_LOW = 0,
+ NT_IO_PRIORITY_LOW = 1,
+ NT_IO_PRIORITY_NORMAL = 2,
+ NT_IO_PRIORITY_HIGH = 3,
+ NT_IO_PRIORITY_CRITICAL = 4,
+ NT_MAX_IO_PRIORITY_TYPES = 5
+} nt_io_priority_hint;
+
+
+typedef enum _nt_fs_info_class {
+ NT_FILE_FS_VOLUME_INFORMATION = 1,
+ NT_FILE_FS_LABEL_INFORMATION = 2,
+ NT_FILE_FS_SIZE_INFORMATION = 3,
+ NT_FILE_FS_DEVICE_INFORMATION = 4,
+ NT_FILE_FS_ATTRIBUTE_INFORMATION = 5,
+ NT_FILE_FS_CONTROL_INFORMATION = 6,
+ NT_FILE_FS_FULL_SIZE_INFORMATION = 7,
+ NT_FILE_FS_OBJECT_ID_INFORMATION = 8,
+ NT_FILE_FS_DRIVER_PATH_INFORMATION = 9,
+ NT_FILE_FS_VOLUME_FLAGS_INFORMATION = 10,
+ NT_FILE_FS_SECTOR_SIZE_INFORMATION = 11,
+} nt_fs_info_class;
+
+
+/* file attributes */
+#define NT_FILE_ATTRIBUTE_READONLY 0x00000001
+#define NT_FILE_ATTRIBUTE_HIDDEN 0x00000002
+#define NT_FILE_ATTRIBUTE_SYSTEM 0x00000004
+#define NT_FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#define NT_FILE_ATTRIBUTE_ARCHIVE 0x00000020
+#define NT_FILE_ATTRIBUTE_DEVICE 0x00000040
+#define NT_FILE_ATTRIBUTE_NORMAL 0x00000080
+#define NT_FILE_ATTRIBUTE_TEMPORARY 0x00000100
+#define NT_FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
+#define NT_FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
+#define NT_FILE_ATTRIBUTE_COMPRESSED 0x00000800
+#define NT_FILE_ATTRIBUTE_OFFLINE 0x00001000
+#define NT_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+#define NT_FILE_ATTRIBUTE_ENCRYPTED 0x00004000
+#define NT_FILE_ATTRIBUTE_INTEGRITY_STREAM 0x00008000
+#define NT_FILE_ATTRIBUTE_VIRTUAL 0x00010000
+#define NT_FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000
+
+
+/* file create options */
+#define NT_FILE_ASYNCHRONOUS_IO 0x00000000
+#define NT_FILE_DIRECTORY_FILE 0x00000001
+#define NT_FILE_WRITE_THROUGH 0x00000002
+#define NT_FILE_SEQUENTIAL_ONLY 0x00000004
+#define NT_FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
+#define NT_FILE_SYNCHRONOUS_IO_ALERT 0x00000010
+#define NT_FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
+#define NT_FILE_NON_DIRECTORY_FILE 0x00000040
+#define NT_FILE_CREATE_TREE_CONNECTION 0x00000080
+#define NT_FILE_COMPLETE_IF_OPLOCKED 0x00000100
+#define NT_FILE_NO_EA_KNOWLEDGE 0x00000200
+#define NT_FILE_OPEN_REMOTE_INSTANCE 0x00000400
+#define NT_FILE_RANDOM_ACCESS 0x00000800
+#define NT_FILE_DELETE_ON_CLOSE 0x00001000
+#define NT_FILE_OPEN_BY_FILE_ID 0x00002000
+#define NT_FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
+#define NT_FILE_NO_COMPRESSION 0x00008000
+#define NT_FILE_SESSION_AWARE 0x00040000
+#define NT_FILE_RESERVE_OPFILTER 0x00100000
+#define NT_FILE_OPEN_REPARSE_POINT 0x00200000
+#define NT_FILE_OPEN_NO_RECALL 0x00400000
+#define NT_FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
+
+
+/* file share access */
+#define NT_FILE_SHARE_READ 0x00000001
+#define NT_FILE_SHARE_WRITE 0x00000002
+#define NT_FILE_SHARE_DELETE 0x00000004
+
+
+/* file notify */
+#define NT_FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
+#define NT_FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
+#define NT_FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004
+#define NT_FILE_NOTIFY_CHANGE_SIZE 0x00000008
+#define NT_FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
+#define NT_FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020
+#define NT_FILE_NOTIFY_CHANGE_CREATION 0x00000040
+#define NT_FILE_NOTIFY_CHANGE_EA 0x00000040
+#define NT_FILE_NOTIFY_CHANGE_SECURITY 0x00000100
+#define NT_FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000100
+#define NT_FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000100
+#define NT_FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000100
+
+
+/* file system flags */
+#define NT_FILE_CASE_SENSITIVE_SEARCH 0x00000001
+#define NT_FILE_CASE_PRESERVED_NAMES 0x00000002
+#define NT_FILE_UNICODE_ON_DISK 0x00000004
+#define NT_FILE_PERSISTENT_ACLS 0x00000008
+#define NT_FILE_FILE_COMPRESSION 0x00000010
+#define NT_FILE_VOLUME_QUOTAS 0x00000020
+#define NT_FILE_SUPPORTS_SPARSE_FILES 0x00000040
+#define NT_FILE_SUPPORTS_REPARSE_POINTS 0x00000080
+#define NT_FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
+#define NT_FILE_VOLUME_IS_COMPRESSED 0x00008000
+#define NT_FILE_SUPPORTS_OBJECT_IDS 0x00010000
+#define NT_FILE_SUPPORTS_ENCRYPTION 0x00020000
+#define NT_FILE_NAMED_STREAMS 0x00040000
+#define NT_FILE_READ_ONLY_VOLUME 0x00080000
+#define NT_FILE_SEQUENTIAL_WRITE_ONCE 0x00100000
+#define NT_FILE_SUPPORTS_TRANSACTIONS 0x00200000
+#define NT_FILE_SUPPORTS_HARD_LINKS 0x00400000
+#define NT_FILE_SUPPORTS_EXTENDED_ATTRIBUTES 0x00800000
+#define NT_FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000
+#define NT_FILE_SUPPORTS_USN_JOURNAL 0x02000000
+#define NT_FILE_SUPPORT_INTEGRITY_STREAMS 0x04000000
+
+
+/* file sector size flags */
+#define NT_SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001
+#define NT_SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002
+#define NT_SSINFO_FLAGS_NO_SEEK_PENALTY 0x00000004
+#define NT_SSINFO_FLAGS_TRIM_ENABLED 0x00000008
+
+
+/* file alignment flags */
+#define NT_FILE_BYTE_ALIGNMENT 0x00000000
+#define NT_FILE_WORD_ALIGNMENT 0x00000001
+#define NT_FILE_LONG_ALIGNMENT 0x00000003
+#define NT_FILE_QUAD_ALIGNMENT 0x00000007
+#define NT_FILE_OCTA_ALIGNMENT 0x0000000f
+#define NT_FILE_32_BYTE_ALIGNMENT 0x0000001f
+#define NT_FILE_64_BYTE_ALIGNMENT 0x0000003f
+#define NT_FILE_128_BYTE_ALIGNMENT 0x0000007f
+#define NT_FILE_256_BYTE_ALIGNMENT 0x000000ff
+#define NT_FILE_512_BYTE_ALIGNMENT 0x000001ff
+
+
+/* file tx info flags */
+#define NT_FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_WRITELOCKED 0x00000001
+#define NT_FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_VISIBLE_TO_TX 0x00000002
+#define NT_FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_VISIBLE_OUTSIDE_TX 0x00000004
+
+
+/* friendly file type bits */
+#define NT_FILE_TYPE_UNKNOWN (0x0000u)
+#define NT_FILE_TYPE_FILE (0x0001u)
+#define NT_FILE_TYPE_DIRECTORY (0x0002u)
+#define NT_FILE_TYPE_PIPE (0x0004u)
+#define NT_FILE_TYPE_SOCKET (0x0008u)
+#define NT_FILE_TYPE_MAILSLOT (0x0010u)
+#define NT_FILE_TYPE_CSRSS (0x0020u)
+#define NT_FILE_TYPE_PTY (0x0040u)
+#define NT_FILE_TYPE_VFD (0x0080u)
+
+
+/* file access bits */
+#define NT_FILE_ANY_ACCESS (0x0000u)
+#define NT_FILE_READ_ACCESS (0x0001u)
+#define NT_FILE_READ_DATA (0x0001u)
+#define NT_FILE_LIST_DIRECTORY (0x0001u)
+#define NT_FILE_WRITE_ACCESS (0x0002u)
+#define NT_FILE_WRITE_DATA (0x0002u)
+#define NT_FILE_ADD_FILE (0x0002u)
+#define NT_FILE_APPEND_DATA (0x0004u)
+#define NT_FILE_ADD_SUBDIRECTORY (0x0004u)
+#define NT_FILE_CREATE_PIPE_INSTANCE (0x0004u)
+#define NT_FILE_READ_EA (0x0008u)
+#define NT_FILE_WRITE_EA (0x0010u)
+#define NT_FILE_EXECUTE (0x0020u)
+#define NT_FILE_TRAVERSE (0x0020u)
+#define NT_FILE_DELETE_CHILD (0x0040u)
+#define NT_FILE_READ_ATTRIBUTES (0x0080u)
+#define NT_FILE_WRITE_ATTRIBUTES (0x0100u)
+
+#define NT_FILE_ALL_ACCESS NT_FILE_ANY_ACCESS \
+ | NT_FILE_READ_ACCESS \
+ | NT_FILE_WRITE_ACCESS \
+ | NT_FILE_APPEND_DATA \
+ | NT_FILE_READ_EA \
+ | NT_FILE_WRITE_EA \
+ | NT_FILE_EXECUTE \
+ | NT_FILE_TRAVERSE \
+ | NT_FILE_DELETE_CHILD \
+ | NT_FILE_READ_ATTRIBUTES \
+ | NT_FILE_WRITE_ATTRIBUTES \
+ | NT_SEC_SYNCHRONIZE \
+ | NT_SEC_STANDARD_RIGHTS_ALL
+
+
+/* structures related to nt_fs_info_class */
+typedef struct _nt_file_fs_volume_information {
+ nt_large_integer volume_creation_time;
+ uint32_t volume_serial_number;
+ uint32_t volume_label_length;
+ unsigned char supports_objects ;
+ unsigned char reserved;
+ wchar16_t volume_label[];
+} nt_file_fs_volume_information, nt_fsvi;
+
+
+typedef struct _nt_file_fs_label_information {
+ uint32_t volume_label_length;
+ wchar16_t volume_label[];
+} nt_file_fs_label_information;
+
+
+typedef struct _nt_file_fs_size_information {
+ nt_large_integer total_allocation_units;
+ nt_large_integer available_allocation_units;
+ uint32_t sectors_per_allocation_unit;
+ uint32_t bytes_per_sector;
+} nt_file_fs_size_information, nt_fssi;
+
+
+typedef struct _nt_file_fs_device_information {
+ nt_device_type device_type;
+ uint32_t characteristics;
+} nt_file_fs_device_information, nt_fsdi;
+
+
+typedef struct _nt_file_fs_attribute_information {
+ uint32_t file_system_attributes;
+ uint32_t maximum_component_name_length;
+ uint32_t file_system_name_length;
+ wchar16_t file_system_name[];
+} nt_file_fs_attribute_information, nt_fsai;
+
+
+typedef struct _nt_file_fs_control_information {
+ nt_large_integer free_space_start_filtering;
+ nt_large_integer free_space_threshold;
+ nt_large_integer free_space_stop_filtering;
+ nt_large_integer default_quota_threshold;
+ nt_large_integer default_quota_limit;
+ uint32_t file_system_control_flags;
+ uint32_t padding;
+} nt_file_fs_control_information, nt_fsci;
+
+
+typedef struct _nt_file_fs_full_size_information {
+ nt_large_integer total_allocation_units;
+ nt_large_integer caller_available_allocation_units;
+ nt_large_integer actual_available_allocation_units;
+ uint32_t sectors_per_allocation_unit;
+ uint32_t bytes_per_sector;
+} nt_file_fs_full_size_information, nt_fsfsi;
+
+
+typedef struct _nt_file_fs_object_id_information {
+ nt_uuid volume_object_id;
+ uint32_t volume_object_id_extended_info;
+} nt_file_fs_object_id_information, nt_fsoii;
+
+
+typedef struct _nt_file_fs_driver_path_information {
+ unsigned char driver_in_path;
+ unsigned char reserved[3];
+ uint32_t driver_name_length;
+ wchar16_t driver_name[];
+} nt_file_fs_driver_path_information, nt_fsdpi;
+
+
+typedef struct _nt_file_fs_sector_size_information {
+ uint32_t logical_bytes_per_sector;
+ uint32_t physical_bytes_per_sector_for_atomicity;
+ uint32_t physical_bytes_per_sector_for_performance;
+ uint32_t effective_physical_bytes_per_sector_for_atomicity;
+ uint32_t flags;
+ uint32_t byte_offset_for_sector_alignment;
+ uint32_t byte_offset_for_partition_alignment;
+} nt_file_fs_sector_size_information, nt_fsssi;
+
+
+typedef struct _nt_file_fs_persistent_volume_information {
+ uint32_t volume_flags;
+ uint32_t flag_mask;
+ uint32_t version;
+ uint32_t reserved;
+} nt_file_fs_persistent_volume_information;
+
+
+/* structures related to zw_query_quota_information_file */
+typedef struct _nt_file_user_quota_information {
+ uint32_t next_entry_offset;
+ uint32_t sid_length;
+ nt_large_integer change_time;
+ nt_large_integer quota_used;
+ nt_large_integer quota_threshold;
+ nt_large_integer quota_limit;
+ nt_sid sid[];
+} nt_file_user_quota_information;
+
+
+typedef struct _nt_file_quota_list_information {
+ uint32_t next_entry_offset;
+ uint32_t sid_length;
+ nt_sid sid[];
+} nt_file_quota_list_information;
+
+
+
+/* structures included in nt_file_all_information */
+typedef struct _nt_file_basic_information {
+ nt_large_integer creation_time;
+ nt_large_integer last_access_time;
+ nt_large_integer last_write_time;
+ nt_large_integer change_time;
+ uint32_t file_attr;
+} nt_file_basic_information, nt_fbi;
+
+
+typedef struct _nt_file_standard_information {
+ nt_large_integer allocation_size;
+ nt_large_integer end_of_file;
+ uint32_t number_of_links;
+ unsigned char delete_pending;
+ unsigned char directory;
+ unsigned char reserved[2];
+} nt_file_standard_information, nt_fsi;
+
+
+typedef struct _nt_file_internal_information {
+ nt_large_integer index_number;
+} nt_file_internal_information, nt_fii;
+
+
+typedef struct _nt_file_ea_information {
+ uint32_t ea_size;
+} nt_file_ea_information, nt_fei;
+
+
+typedef struct _nt_file_access_information {
+ uint32_t access_flags;
+} nt_file_access_information, nt_facci;
+
+
+typedef struct _nt_file_position_information {
+ nt_large_integer current_byte_offset;
+} nt_file_position_information, nt_fpi;
+
+
+typedef struct _nt_file_mode_information {
+ uint32_t mode;
+} nt_file_mode_information, nt_fmi;
+
+
+typedef struct _nt_file_alignment_information {
+ uint32_t alignment_requirement;
+} nt_file_alignment_information, nt_falii;
+
+
+typedef struct _nt_file_name_information {
+ uint32_t file_name_length;
+ wchar16_t file_name[];
+} nt_file_name_information, nt_fni;
+
+
+typedef struct _nt_file_all_information {
+ nt_file_basic_information basic_info;
+ nt_file_standard_information standard_info;
+ nt_file_internal_information internal_info;
+ nt_file_ea_information ea_info;
+ nt_file_access_information access_info;
+ nt_file_position_information position_info;
+ nt_file_mode_information mode_info;
+ nt_file_alignment_information alignment_info;
+ nt_file_name_information name_info;
+} nt_file_all_information, nt_fai;
+
+
+
+/* structures related to nt_file_info_class */
+typedef struct _nt_file_directory_information {
+ uint32_t next_entry_offset;
+ uint32_t file_index;
+ nt_large_integer creation_time;
+ nt_large_integer last_access_time;
+ nt_large_integer last_write_time;
+ nt_large_integer change_time;
+ nt_large_integer end_of_file;
+ nt_large_integer allocation_size;
+ uint32_t file_attributes;
+ uint32_t file_name_length;
+ wchar16_t file_name[];
+} nt_file_directory_information, nt_fdiri;
+
+
+typedef struct _nt_file_full_dir_information {
+ uint32_t next_entry_offset;
+ uint32_t file_index;
+ nt_large_integer creation_time;
+ nt_large_integer last_access_time;
+ nt_large_integer last_write_time;
+ nt_large_integer change_time;
+ nt_large_integer end_of_file;
+ nt_large_integer allocation_size;
+ uint32_t file_attributes;
+ uint32_t file_name_length;
+ uint32_t ea_size;
+ wchar16_t file_name[];
+} nt_file_full_dir_information;
+
+
+typedef struct _nt_file_both_dir_information {
+ uint32_t next_entry_offset;
+ uint32_t file_index;
+ nt_large_integer creation_time;
+ nt_large_integer last_access_time;
+ nt_large_integer last_write_time;
+ nt_large_integer change_time;
+ nt_large_integer end_of_file;
+ nt_large_integer allocation_size;
+ uint32_t file_attributes;
+ uint32_t file_name_length;
+ uint32_t ea_size;
+ char short_name_length;
+ char reserved;
+ wchar16_t short_name[12];
+ wchar16_t file_name[];
+} nt_file_both_dir_information;
+
+
+typedef struct _nt_file_rename_information {
+ unsigned char replace_if_exists;
+ void * root_directory;
+ uint32_t file_name_length;
+ wchar16_t file_name[];
+} nt_file_rename_information, nt_frni;
+
+
+typedef struct _nt_file_link_information {
+ unsigned char replace_if_exists;
+ void * root_directory;
+ uint32_t file_name_length;
+ wchar16_t file_name[];
+} nt_file_link_information;
+
+
+typedef struct _nt_file_names_information {
+ uint32_t next_entry_offset;
+ uint32_t file_index;
+ uint32_t file_name_length;
+ wchar16_t file_name[];
+} nt_file_names_information, nt_fnamesi;
+
+
+typedef struct _nt_file_disposition_information {
+ unsigned char delete_file;
+} nt_file_disposition_information, nt_fdi;
+
+
+typedef struct _nt_file_full_ea_information {
+ uint32_t next_entry_offset;
+ unsigned char flags;
+ unsigned char ea_name_length;
+ uint16_t ea_value_length;
+ char ea_name[];
+} nt_file_full_ea_information;
+
+
+typedef struct _nt_file_allocation_information {
+ nt_large_integer allocation_size;
+} nt_file_allocation_information;
+
+
+typedef struct _nt_file_end_of_file_information {
+ nt_large_integer end_of_file;
+} nt_file_end_of_file_information, nt_eof;
+
+
+typedef struct _nt_file_stream_information {
+ uint32_t next_entry_offset;
+ uint32_t stream_name_length;
+ nt_large_integer stream_size;
+ nt_large_integer stream_allocation_size;
+ wchar16_t stream_name[];
+} nt_file_stream_information;
+
+
+typedef struct _nt_file_pipe_information {
+ uint32_t read_mode;
+ uint32_t completion_mode;
+} nt_file_pipe_information;
+
+
+typedef struct _nt_file_pipe_local_information {
+ uint32_t named_pipe_type;
+ uint32_t named_pipe_configuration;
+ uint32_t maximum_instances;
+ uint32_t current_instances;
+ uint32_t inbound_quota;
+ uint32_t read_data_available;
+ uint32_t outbound_quota;
+ uint32_t write_quota_available;
+ uint32_t named_pipe_state;
+ uint32_t named_pipe_end;
+} nt_file_pipe_local_information;
+
+
+typedef struct _nt_file_pipe_remote_information {
+ nt_large_integer collect_data_time;
+ uint32_t maximum_collection_count;
+} nt_file_pipe_remote_information;
+
+
+typedef struct _nt_file_mailslot_query_information {
+ uint32_t maximum_message_size;
+ uint32_t mailslot_quota;
+ uint32_t next_message_size;
+ uint32_t messages_available;
+ nt_large_integer read_timeout;
+} nt_file_mailslot_query_information;
+
+
+typedef struct _nt_file_mailslot_set_information {
+ nt_large_integer * read_timeout;
+} nt_file_mailslot_set_information;
+
+
+typedef struct _nt_file_compression_information {
+ nt_large_integer CompressedFileSize;
+ uint16_t CompressionFormat;
+ unsigned char CompressionUnitShift;
+ unsigned char ChunkShift;
+ unsigned char ClusterShift;
+ unsigned char Reserved[3];
+} nt_file_compression_information;
+
+
+typedef struct _nt_file_object_id_buffer {
+ unsigned char obj_id[16];
+ unsigned char birth_volume_id[16];
+ unsigned char birth_object_id[16];
+ unsigned char domain_id[16];
+} nt_file_object_id_buffer;
+
+
+typedef struct _nt_file_object_id_information {
+ int64_t file_reference;
+ unsigned char object_id[16];
+
+ union {
+ struct {
+ unsigned char birth_volume_id[16];
+ unsigned char birth_object_id[16];
+ unsigned char domain_id[16];
+ };
+ unsigned char extended_info[48];
+ };
+} nt_file_object_id_information;
+
+
+typedef struct _nt_file_quota_information {
+ uint32_t next_entry_offset;
+ uint32_t sid_length;
+ nt_large_integer change_time;
+ nt_large_integer quota_used;
+ nt_large_integer quota_threshold;
+ nt_large_integer quota_limit;
+ nt_sid sid;
+} nt_file_quota_information;
+
+
+typedef struct _nt_file_reparse_point_information {
+ int64_t file_reference;
+ uint32_t tag;
+} nt_file_reparse_point_information, nt_frpi;
+
+
+typedef struct _nt_file_network_open_information {
+ nt_large_integer creation_time;
+ nt_large_integer last_access_time;
+ nt_large_integer last_write_time;
+ nt_large_integer change_time;
+ nt_large_integer allocation_size;
+ nt_large_integer end_of_file;
+ uint32_t file_attributes;
+} nt_file_network_open_information;
+
+
+typedef struct _nt_file_attribute_tag_information {
+ uint32_t file_attr;
+ uint32_t reparse_tag;
+} nt_file_attribute_tag_information, nt_ftagi;
+
+
+typedef struct _nt_file_id_both_dir_information {
+ uint32_t next_entry_offset;
+ uint32_t file_index;
+ nt_large_integer creation_time;
+ nt_large_integer last_access_time;
+ nt_large_integer last_write_time;
+ nt_large_integer change_time;
+ nt_large_integer end_of_file;
+ nt_large_integer allocation_size;
+ uint32_t file_attributes;
+ uint32_t file_name_length;
+ uint32_t ea_size;
+ char short_name_length;
+ char reserved;
+ wchar16_t short_name[12];
+ nt_large_integer file_id;
+ wchar16_t file_name[];
+} nt_file_id_both_dir_information, nt_fsdirent;
+
+
+typedef struct _nt_file_id_full_dir_information {
+ uint32_t next_entry_offset;
+ uint32_t file_index;
+ nt_large_integer creation_time;
+ nt_large_integer last_access_time;
+ nt_large_integer last_write_time;
+ nt_large_integer change_time;
+ nt_large_integer end_of_file;
+ nt_large_integer allocation_size;
+ uint32_t file_attributes;
+ uint32_t file_name_length;
+ uint32_t ea_size;
+ nt_large_integer FileId;
+ wchar16_t file_name[];
+} nt_file_id_full_dir_information;
+
+
+typedef struct _nt_file_valid_data_length_information {
+ nt_large_integer valid_data_length;
+} nt_file_valid_data_length_information;
+
+
+typedef struct _nt_file_io_priority_hint_information {
+ nt_io_priority_hint priority_hint;
+} nt_file_io_priority_hint_information;
+
+
+typedef struct _nt_file_link_entry_information {
+ uint32_t next_entry_offset;
+ int64_t parent_file_id;
+ uint32_t file_name_length;
+ wchar16_t file_name[];
+} nt_file_link_entry_information;
+
+
+typedef struct _nt_file_links_information {
+ uint32_t bytes_needed;
+ uint32_t entries_returned;
+ nt_file_link_entry_information entry;
+} nt_file_links_information;
+
+
+typedef struct _nt_file_id_global_tx_dir_information {
+ uint32_t next_entry_offset;
+ uint32_t file_index;
+ nt_large_integer creation_time;
+ nt_large_integer last_access_time;
+ nt_large_integer last_write_time;
+ nt_large_integer change_time;
+ nt_large_integer end_of_file;
+ nt_large_integer allocation_size;
+ uint32_t file_attributes;
+ uint32_t file_name_length;
+ nt_large_integer file_id;
+ nt_guid locking_transaction_id;
+ uint32_t tx_info_flags;
+ wchar16_t file_name[];
+} nt_file_id_global_tx_dir_information;
+
+
+typedef struct _nt_file_completion_information {
+ void * port;
+ void * key;
+} nt_file_completion_information;
+
+
+
+/* file extended attributes */
+typedef struct _nt_file_get_ea_information {
+ uint32_t next_entry_offset;
+ unsigned char ea_name_length;
+ char ea_name[];
+} nt_file_get_ea_information;
+
+
+/* quota information */
+typedef struct _nt_file_get_quota_information {
+ uint32_t next_entry_offset;
+ uint32_t sid_length;
+ nt_sid sid;
+} nt_file_get_quota_information;
+
+
+/* file change notification */
+typedef struct _nt_file_notify_information {
+ uint32_t next_entry_offset;
+ uint32_t action;
+ uint32_t file_name_length;
+ wchar16_t file_name[];
+} nt_file_notify_information;
+
+
+/* file segment element */
+typedef union _nt_file_segment_element {
+ uint64_t * buffer;
+ uint64_t alignment;
+} nt_file_segment_element;
+
+
+/* section object pointers */
+typedef struct _nt_section_object_pointers {
+ void * data_section_object;
+ void * shared_cache_map;
+ void * image_section_object;
+} nt_section_object_pointers;
+
+
+/* reparse guid data buffer */
+typedef struct _nt_reparse_guid_data_buffer {
+ uint32_t reparse_tag;
+ uint16_t reparse_data_length;
+ uint16_t reserved;
+ nt_guid reparse_guid;
+ unsigned char generic_reparse_buffer[];
+} nt_reparse_guid_data_buffer;
+
+
+/* reparse data buffer */
+typedef struct _nt_reparse_data_buffer {
+ uint32_t reparse_tag;
+ uint16_t reparse_data_length;
+ uint16_t reserved;
+
+ union {
+ struct {
+ uint16_t substitute_name_offset;
+ uint16_t substitute_name_length;
+ uint16_t print_name_offset;
+ uint16_t print_name_length;
+ uint32_t flags;
+ } symbolic_link_reparse_buffer;
+
+ struct {
+ uint16_t substitute_name_offset;
+ uint16_t substitute_name_length;
+ uint16_t print_name_offset;
+ uint16_t print_name_length;
+ } mount_point_reparse_buffer;
+ };
+
+ wchar16_t path_buffer[];
+} nt_reparse_data_buffer;
+
+
+/* file object */
+typedef struct _nt_file_object {
+ int16_t type;
+ int16_t size;
+ nt_device_object * dev_obj;
+ nt_vpb vpb;
+ void * fs_context;
+ void * fs_context_2nd;
+ nt_section_object_pointers * sec_obj_ptr;
+ void * private_cache_map;
+ int32_t final_status;
+ struct _nt_file_object * related_file_obj;
+ unsigned char lock_operation;
+ unsigned char delete_pending;
+ unsigned char read_access;
+ unsigned char write_access;
+ unsigned char delete_access;
+ unsigned char shared_read;
+ unsigned char shared_write;
+ unsigned char shared_delete;
+ uint32_t flags;
+ nt_unicode_string file_name;
+ nt_large_integer current_byte_offset;
+ uint32_t waiters;
+ uint32_t busy;
+ void * last_lock;
+ nt_kevent lock;
+ nt_kevent event;
+ nt_io_completion_context * completion_context;
+ uint32_t irp_list_lock;
+ nt_list_entry irp_list;
+ void * file_obj_ext;
+} nt_file_object;
+
+
+
+
+/* file-related function signatures */
+typedef int32_t __stdcall ntapi_zw_create_file(
+ __out void ** hfile,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __out nt_io_status_block * io_status_block,
+ __in nt_large_integer * allocation_size __optional,
+ __in uint32_t file_attr,
+ __in uint32_t share_access,
+ __in uint32_t create_disposition,
+ __in uint32_t create_options,
+ __in void * ea_buffer __optional,
+ __in uint32_t ea_length);
+
+
+typedef int32_t __stdcall ntapi_zw_open_file(
+ __out void ** hfile,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __out nt_io_status_block * io_status_block,
+ __in uint32_t share_access,
+ __in uint32_t open_options);
+
+
+typedef int32_t __stdcall ntapi_zw_delete_file(
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_flush_buffers_file(
+ __in void * hfile,
+ __out nt_io_status_block * io_status_block);
+
+
+typedef int32_t __stdcall ntapi_zw_cancel_io_file(
+ __in void * hfile,
+ __out nt_io_status_block * io_status_block);
+
+
+typedef int32_t __stdcall ntapi_zw_cancel_io_file_ex(
+ __in void * hfile,
+ __in nt_io_status_block * request_iosb __optional,
+ __out nt_io_status_block * cancel_iosb);
+
+
+typedef int32_t __stdcall ntapi_zw_read_file(
+ __in void * hfile,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __out void * buffer,
+ __in uint32_t bytes_to_read,
+ __in nt_large_integer * byte_offset __optional,
+ __in uint32_t * key __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_write_file(
+ __in void * hfile,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __in void * buffer,
+ __in uint32_t bytes_sent,
+ __in nt_large_integer * byte_offset __optional,
+ __in uint32_t * key __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_read_file_scatter(
+ __in void * hfile,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __in nt_file_segment_element * buffer,
+ __in uint32_t bytes_to_read,
+ __in nt_large_integer * byte_offset __optional,
+ __in uint32_t * key __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_write_file_gather(
+ __in void * hfile,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __in nt_file_segment_element * buffer,
+ __in uint32_t bytes_to_read,
+ __in nt_large_integer * byte_offset __optional,
+ __in uint32_t * key __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_lock_file(
+ __in void * hfile,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __in nt_large_integer * lock_offset,
+ __in nt_large_integer * lock_length,
+ __in uint32_t * key,
+ __in unsigned char fail_immediately,
+ __in unsigned char exclusive_lock);
+
+
+typedef int32_t __stdcall ntapi_zw_unlock_file(
+ __in void * hfile,
+ __out nt_io_status_block * io_status_block,
+ __in nt_large_integer * lock_offset,
+ __in nt_large_integer * lock_length,
+ __in uint32_t * key);
+
+
+typedef int32_t __stdcall ntapi_zw_device_io_control_file(
+ __in void * hfile,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __in uint32_t io_control_code,
+ __in void * input_buffer __optional,
+ __in uint32_t input_buffer_length,
+ __out void * output_buffer __optional,
+ __in uint32_t output_buffer_length);
+
+
+typedef int32_t __stdcall ntapi_zw_fs_control_file(
+ __in void * hfile,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __in uint32_t fs_control_code,
+ __in void * input_buffer __optional,
+ __in uint32_t input_buffer_length,
+ __out void * output_buffer __optional,
+ __in uint32_t output_buffer_length);
+
+
+typedef int32_t __stdcall ntapi_zw_notify_change_directory_file(
+ __in void * hfile ,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __out nt_file_notify_information * buffer,
+ __in uint32_t buffer_length,
+ __in uint32_t notify_filter,
+ __in unsigned char watch_subtree);
+
+
+typedef int32_t __stdcall ntapi_zw_query_ea_file(
+ __in void * hfile ,
+ __out nt_io_status_block * io_status_block,
+ __out nt_file_full_ea_information * buffer,
+ __in uint32_t buffer_length,
+ __in unsigned char return_single_entry,
+ __in nt_file_get_ea_information * ea_list __optional,
+ __in uint32_t ea_list_length,
+ __in uint32_t * ea_index __optional,
+ __in unsigned char restart_scan);
+
+
+typedef int32_t __stdcall ntapi_zw_set_ea_file(
+ __in void * hfile ,
+ __out nt_io_status_block * io_status_block,
+ __in nt_file_full_ea_information * buffer,
+ __in uint32_t buffer_length);
+
+
+typedef int32_t __stdcall ntapi_zw_create_named_pipe_file(
+ __out void ** hfile,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __out nt_io_status_block * io_status_block,
+ __in uint32_t share_access,
+ __in uint32_t create_disposition,
+ __in uint32_t create_options,
+ __in uint32_t type_message,
+ __in uint32_t readmode_message,
+ __in uint32_t non_blocking,
+ __in uint32_t max_instances,
+ __in size_t in_buffer_size,
+ __in size_t out_buffer_size,
+ __in nt_large_integer * default_timeout __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_create_mailslot_file(
+ __out void ** hfile,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __out nt_io_status_block * io_status_block,
+ __in uint32_t create_options,
+ __in uint32_t in_buffer_size,
+ __in uint32_t max_message_size,
+ __in nt_large_integer * read_timeout __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_query_volume_information_file(
+ __in void * hfile ,
+ __out nt_io_status_block * io_status_block,
+ __out void * vol_info,
+ __in uint32_t vol_info_length,
+ __in nt_fs_info_class vol_info_class);
+
+
+typedef int32_t __stdcall ntapi_zw_set_volume_information_file(
+ __in void * hfile ,
+ __out nt_io_status_block * io_status_block,
+ __in void * vol_info,
+ __in uint32_t vol_info_length,
+ __in nt_fs_info_class vol_info_class);
+
+
+typedef int32_t __stdcall ntapi_zw_query_quota_information_file(
+ __in void * hfile ,
+ __out nt_io_status_block * io_status_block,
+ __out nt_file_user_quota_information * buffer,
+ __in uint32_t buffer_length,
+ __in unsigned char returning_single_entry,
+ __in nt_file_quota_list_information * sid_list __optional,
+ __in uint32_t sid_list_length,
+ __in nt_sid * start_sid __optional,
+ __in unsigned char restart_scan);
+
+
+typedef int32_t __stdcall ntapi_zw_set_quota_information_file(
+ __in void * hfile ,
+ __out nt_io_status_block * io_status_block,
+ __in nt_file_user_quota_information * buffer,
+ __in uint32_t buffer_length);
+
+
+typedef int32_t __stdcall ntapi_zw_query_attributes_file(
+ __in nt_object_attributes * obj_attr,
+ __out nt_file_basic_information * file_info);
+
+
+typedef int32_t __stdcall ntapi_zw_query_full_attributes_file(
+ __in nt_object_attributes * obj_attr,
+ __out nt_file_network_open_information * file_info);
+
+
+typedef int32_t __stdcall ntapi_zw_query_directory_file(
+ __in void * hfile,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __out void * file_info,
+ __in uint32_t file_info_length,
+ __in nt_file_info_class file_info_class,
+ __in unsigned char return_single_entry,
+ __in nt_unicode_string * file_name __optional,
+ __in unsigned char restart_scan);
+
+
+typedef int32_t __stdcall ntapi_zw_query_information_file(
+ __in void * hfile,
+ __out nt_io_status_block * io_status_block,
+ __out void * file_info,
+ __in uint32_t file_info_length,
+ __in nt_file_info_class file_info_class);
+
+
+typedef int32_t __stdcall ntapi_zw_set_information_file(
+ __in void * hfile,
+ __out nt_io_status_block * io_status_block,
+ __in void * file_info,
+ __in uint32_t file_info_length,
+ __in nt_file_info_class file_info_class);
+
+/* extension functions */
+typedef int32_t __stdcall ntapi_tt_get_file_handle_type(
+ __in void * handle,
+ __out int32_t * type);
+
+typedef int32_t __stdcall ntapi_tt_open_logical_parent_directory(
+ __out void ** hparent,
+ __in void * hdir,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t desired_access,
+ __in uint32_t open_options,
+ __out int32_t * type);
+
+typedef int32_t __stdcall ntapi_tt_open_physical_parent_directory(
+ __out void ** hparent,
+ __in void * hdir,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t desired_access,
+ __in uint32_t open_options,
+ __out int32_t * type);
+
+#endif
diff --git a/include/ntapi/nt_fsctl.h b/include/ntapi/nt_fsctl.h
new file mode 100644
index 0000000..573946a
--- /dev/null
+++ b/include/ntapi/nt_fsctl.h
@@ -0,0 +1,44 @@
+#ifndef _NT_FSCTL_H_
+#define _NT_FSCTL_H_
+
+#define NT_FSCTL_CREATE_OR_GET_OBJECT_ID (0x000900c0)
+#define NT_FSCTL_DELETE_OBJECT_ID (0x000900a0)
+#define NT_FSCTL_DELETE_REPARSE_POINT (0x000900ac)
+#define NT_FSCTL_FILE_LEVEL_TRIM (0x00098208)
+#define NT_FSCTL_FILESYSTEM_GET_STATISTICS (0x00090060)
+#define NT_FSCTL_FIND_FILES_BY_SID (0x0009008f)
+#define NT_FSCTL_GET_COMPRESSION (0x0009003c)
+#define NT_FSCTL_GET_INTEGRITY_INFORMATION (0x0009027c)
+#define NT_FSCTL_GET_NTFS_VOLUME_DATA (0x00090064)
+#define NT_FSCTL_GET_REFS_VOLUME_DATA (0x000902D8)
+#define NT_FSCTL_GET_OBJECT_ID (0x0009009c)
+#define NT_FSCTL_GET_REPARSE_POINT (0x000900a8)
+#define NT_FSCTL_GET_RETRIEVAL_POINTERS (0x00090073)
+#define NT_FSCTL_IS_PATHNAME_VALID (0x0009002c)
+#define NT_FSCTL_LMR_SET_LINK_TRACKING_INFORMATION (0x001400ec)
+#define NT_FSCTL_OFFLOAD_READ (0x00094264)
+#define NT_FSCTL_OFFLOAD_WRITE (0x00098268)
+#define NT_FSCTL_PIPE_PEEK (0x0011400c)
+#define NT_FSCTL_PIPE_TRANSCEIVE (0x0011c017)
+#define NT_FSCTL_PIPE_WAIT (0x00110018)
+#define NT_FSCTL_QUERY_ALLOCATED_RANGES (0x000940cf)
+#define NT_FSCTL_QUERY_FAT_BPB (0x00090058)
+#define NT_FSCTL_QUERY_FILE_REGIONS (0x00090284)
+#define NT_FSCTL_QUERY_ON_DISK_VOLUME_INFO (0x0009013c)
+#define NT_FSCTL_QUERY_SPARING_INFO (0x00090138)
+#define NT_FSCTL_READ_FILE_USN_DATA (0x000900eb)
+#define NT_FSCTL_RECALL_FILE (0x00090117)
+#define NT_FSCTL_SET_COMPRESSION (0x0009c040)
+#define NT_FSCTL_SET_DEFECT_MANAGEMENT (0x00098134)
+#define NT_FSCTL_SET_ENCRYPTION (0x000900D7)
+#define NT_FSCTL_SET_INTEGRITY_INFORMATION (0x0009C280)
+#define NT_FSCTL_SET_OBJECT_ID (0x00090098)
+#define NT_FSCTL_SET_OBJECT_ID_EXTENDED (0x000900bc)
+#define NT_FSCTL_SET_REPARSE_POINT (0x000900a4)
+#define NT_FSCTL_SET_SPARSE (0x000900c4)
+#define NT_FSCTL_SET_ZERO_DATA (0x000980c8)
+#define NT_FSCTL_SET_ZERO_ON_DEALLOCATION (0x00090194)
+#define NT_FSCTL_SIS_COPYFILE (0x00090100)
+#define NT_FSCTL_WRITE_USN_CLOSE_RECORD (0x000900ef)
+
+#endif
diff --git a/include/ntapi/nt_guid.h b/include/ntapi/nt_guid.h
new file mode 100644
index 0000000..332a899
--- /dev/null
+++ b/include/ntapi/nt_guid.h
@@ -0,0 +1,37 @@
+#ifndef _NT_GUID_H_
+#define _NT_GUID_H_
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+
+typedef struct _nt_guid_str_utf16 {
+ wchar16_t lbrace;
+ wchar16_t group1[8];
+ wchar16_t dash1;
+ wchar16_t group2[4];
+ wchar16_t dash2;
+ wchar16_t group3[4];
+ wchar16_t dash3;
+ wchar16_t group4[4];
+ wchar16_t dash4;
+ wchar16_t group5[12];
+ wchar16_t rbrace;
+} nt_guid_str_utf16, nt_uuid_str_utf16;
+
+typedef void __fastcall ntapi_tt_guid_copy(
+ __out nt_guid * pguid_dst,
+ __in const nt_guid * pguid_src);
+
+typedef int32_t __fastcall ntapi_tt_guid_compare(
+ __in const nt_guid * pguid_dst,
+ __in const nt_guid * pguid_src);
+
+typedef void __fastcall ntapi_tt_guid_to_utf16_string(
+ __in const nt_guid * guid,
+ __out nt_guid_str_utf16 * guid_str);
+
+typedef int32_t __fastcall ntapi_tt_utf16_string_to_guid(
+ __in nt_guid_str_utf16 * guid_str,
+ __out nt_guid * guid);
+
+#endif
diff --git a/include/ntapi/nt_hash.h b/include/ntapi/nt_hash.h
new file mode 100644
index 0000000..f0e2492
--- /dev/null
+++ b/include/ntapi/nt_hash.h
@@ -0,0 +1,13 @@
+#ifndef _NT_HASH_H_
+#define _NT_HASH_H_
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_hash.h>
+
+typedef int32_t __cdecl ntapi_tt_populate_hashed_import_table(
+ __in void * image_base,
+ __in void * import_table,
+ __in ntapi_hashed_symbol * hash_table,
+ __in uint32_t hash_table_array_size);
+
+#endif
diff --git a/include/ntapi/nt_ioctl.h b/include/ntapi/nt_ioctl.h
new file mode 100644
index 0000000..994bc95
--- /dev/null
+++ b/include/ntapi/nt_ioctl.h
@@ -0,0 +1,31 @@
+#ifndef _NT_IOCTL_H_
+#define _NT_IOCTL_H_
+
+#define NT_IOCTL_MOUNTDEV_LINK_CREATED (0x004dc010)
+#define NT_IOCTL_MOUNTDEV_LINK_DELETED (0x004dc014)
+#define NT_IOCTL_MOUNTDEV_QUERY_DEVICE_NAME (0x004d0008)
+#define NT_IOCTL_MOUNTDEV_QUERY_STABLE_GUID (0x004d0018)
+#define NT_IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME (0x004d000c)
+#define NT_IOCTL_MOUNTDEV_QUERY_UNIQUE_ID (0x004d0000)
+
+#define NT_IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS (0x006dc014)
+#define NT_IOCTL_MOUNTMGR_BOOT_DL_ASSIGNMENT (0x006dc044)
+#define NT_IOCTL_MOUNTMGR_CHANGE_NOTIFY (0x006d4020)
+#define NT_IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES (0x006d4028)
+#define NT_IOCTL_MOUNTMGR_CREATE_POINT (0x006dc000)
+#define NT_IOCTL_MOUNTMGR_DELETE_POINTS (0x006dc004)
+#define NT_IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY (0x006dc00c)
+#define NT_IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE (0x006dc024)
+#define NT_IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER (0x006dc010)
+#define NT_IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT (0x006d003c)
+#define NT_IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH (0x006d0030)
+#define NT_IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS (0x006d0034)
+#define NT_IOCTL_MOUNTMGR_QUERY_POINTS (0x006d0008)
+#define NT_IOCTL_MOUNTMGR_SCRUB_REGISTRY (0x006dc038)
+#define NT_IOCTL_MOUNTMGR_SET_AUTO_MOUNT (0x006dc040)
+#define NT_IOCTL_MOUNTMGR_TRACELOG_CACHE (0x006d4048)
+#define NT_IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION (0x006d402c)
+#define NT_IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED (0x006dc018)
+#define NT_IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED (0x006dc01c)
+
+#endif
diff --git a/include/ntapi/nt_ipc.h b/include/ntapi/nt_ipc.h
new file mode 100644
index 0000000..6119b8b
--- /dev/null
+++ b/include/ntapi/nt_ipc.h
@@ -0,0 +1,12 @@
+#ifndef _NT_IPC_H_
+#define _NT_IPC_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef int32_t __stdcall ntapi_ipc_create_pipe(
+ __out void ** hpipe_read,
+ __out void ** hpipe_write,
+ __in uint32_t advisory_buffer_size __optional);
+
+#endif
diff --git a/include/ntapi/nt_istat.h b/include/ntapi/nt_istat.h
new file mode 100644
index 0000000..5586628
--- /dev/null
+++ b/include/ntapi/nt_istat.h
@@ -0,0 +1,45 @@
+#ifndef _NT_ISTAT_H_
+#define _NT_ISTAT_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+#include "nt_file.h"
+
+/* ntapi_tt_istat info flag bits */
+#define NT_ISTAT_DEFAULT 0x00000000
+#define NT_ISTAT_COMMON 0x00000001
+#define NT_ISTAT_DEV_NAME_COPY 0x00000002
+#define NT_ISTAT_NEW_HANDLE 0x80000000
+
+typedef struct _nt_istat {
+ void * hfile;
+ nt_fii fii;
+ nt_ftagi ftagi;
+ uint32_t flags_in;
+ uint32_t flags_out;
+ uint32_t dev_name_hash;
+ uint16_t dev_name_strlen;
+ uint16_t dev_name_maxlen;
+ wchar16_t dev_name[];
+} nt_istat;
+
+
+typedef int32_t __stdcall ntapi_tt_istat(
+ __in void * hfile __optional,
+ __in void * hroot __optional,
+ __in nt_unicode_string * path __optional,
+ __out nt_istat * istat,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t open_options,
+ __in uint32_t flags);
+
+
+typedef int32_t __stdcall ntapi_tt_validate_fs_handle(
+ __in void * hfile,
+ __in uint32_t dev_name_hash,
+ __in nt_fii fii,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size);
+
+#endif
diff --git a/include/ntapi/nt_job.h b/include/ntapi/nt_job.h
new file mode 100644
index 0000000..83a561e
--- /dev/null
+++ b/include/ntapi/nt_job.h
@@ -0,0 +1,212 @@
+#ifndef _NT_JOB_H_
+#define _NT_JOB_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_job_object_info_class {
+ NT_JOB_OBJECT_BASIC_ACCOUNTING_INFORMATION = 0x01,
+ NT_JOB_OBJECT_BASIC_LIMIT_INFORMATION = 0x02,
+ NT_JOB_OBJECT_BASIC_PROCESS_ID_LIST = 0x03,
+ NT_JOB_OBJECT_BASIC_U_I_RESTRICTIONS = 0x04,
+ NT_JOB_OBJECT_SECURITY_LIMIT_INFORMATION = 0x05,
+ NT_JOB_OBJECT_END_OF_JOB_TIME_INFORMATION = 0x06,
+ NT_JOB_OBJECT_ASSOCIATE_COMPLETION_PORT_INFORMATION = 0x07,
+ NT_JOB_OBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION = 0x08,
+ NT_JOB_OBJECT_EXTENDED_LIMIT_INFORMATION = 0x09,
+
+ NT_JOB_OBJECT_GROUP_INFORMATION = 0x0B,
+ NT_JOB_OBJECT_NOTIFICATION_LIMIT_INFORMATION = 0x0C,
+ NT_JOB_OBJECT_LIMIT_VIOLATION_INFORMATION = 0x0D,
+ NT_JOB_OBJECT_GROUP_INFORMATION_EX = 0x0E,
+ NT_JOB_OBJECT_CPU_RATE_CONTROL_INFORMATION = 0x0F,
+} nt_job_object_info_class;
+
+/* job access bits */
+#define NT_JOB_OBJECT_ASSIGN_PROCESS 0x000001
+#define NT_JOB_OBJECT_SET_ATTRIBUTES 0x000002
+#define NT_JOB_OBJECT_QUERY 0x000004
+#define NT_JOB_OBJECT_TERMINATE 0x000008
+#define NT_JOB_OBJECT_SET_SECURITY_ATTRIBUTES 0x000010
+#define NT_JOB_OBJECT_ALL_ACCESS 0x1F001F
+
+/* job limit flags */
+#define NT_JOB_OBJECT_LIMIT_WORKINGSET 0x00000001
+#define NT_JOB_OBJECT_LIMIT_PROCESS_TIME 0x00000002
+#define NT_JOB_OBJECT_LIMIT_JOB_TIME 0x00000004
+#define NT_JOB_OBJECT_LIMIT_ACTIVE_PROCESS 0x00000008
+#define NT_JOB_OBJECT_LIMIT_AFFINITY 0x00000010
+#define NT_JOB_OBJECT_LIMIT_PRIORITY_CLASS 0x00000020
+#define NT_JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME 0x00000040
+#define NT_JOB_OBJECT_LIMIT_SCHEDULING_CLASS 0x00000080
+#define NT_JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100
+#define NT_JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200
+#define NT_JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400
+#define NT_JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800
+#define NT_JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000
+#define NT_JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000
+#define NT_JOB_OBJECT_LIMIT_SUBSET_AFFINITY 0x00004000
+
+
+/* job object cpu rate control bits */
+#define NT_JOB_OBJECT_CPU_RATE_CONTROL_ENABLE 0x0001
+#define NT_JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED 0x0002
+#define NT_JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP 0x0004
+#define NT_JOB_OBJECT_CPU_RATE_CONTROL_NOTIFY 0x0008
+
+
+/* job object basic user interface restrictions bits */
+#define NT_JOB_OBJECT_UILIMIT_HANDLES 0x00000001
+#define NT_JOB_OBJECT_UILIMIT_READCLIPBOARD 0x00000002
+#define NT_JOB_OBJECT_UILIMIT_WRITECLIPBOARD 0x00000004
+#define NT_JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS 0x00000008
+#define NT_JOB_OBJECT_UILIMIT_DISPLAYSETTINGS 0x00000010
+#define NT_JOB_OBJECT_UILIMIT_GLOBALATOMS 0x00000020
+#define NT_JOB_OBJECT_UILIMIT_DESKTOP 0x00000040
+#define NT_JOB_OBJECT_UILIMIT_EXITWINDOWS 0x00000080
+
+
+/* job security limit bits */
+#define NT_JOB_OBJECT_SECURITY_NO_ADMIN 0x0001
+#define NT_JOB_OBJECT_SECURITY_RESTRICTED_TOKEN 0x0002
+#define NT_JOB_OBJECT_SECURITY_ONLY_TOKEN 0x0004
+#define NT_JOB_OBJECT_SECURITY_FILTER_TOKENS 0x0008
+
+
+/* end of job actions */
+#define NT_JOB_OBJECT_TERMINATE_AT_END_OF_JOB 0
+#define NT_JOB_OBJECT_POST_AT_END_OF_JOB 1
+
+
+/* job associate completion port events */
+#define NT_JOB_OBJECT_MSG_END_OF_JOB_TIME 1
+#define NT_JOB_OBJECT_MSG_END_OF_PROCESS_TIME 2
+#define NT_JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT 3
+#define NT_JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO 4
+#define NT_JOB_OBJECT_MSG_NEW_PROCESS 6
+#define NT_JOB_OBJECT_MSG_EXIT_PROCESS 7
+#define NT_JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS 8
+#define NT_JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT 9
+#define NT_JOB_OBJECT_MSG_JOB_MEMORY_LIMIT 10
+
+
+typedef struct _nt_job_object_basic_accounting_information {
+ nt_large_integer total_user_time;
+ nt_large_integer total_kernel_time;
+ nt_large_integer this_period_total_user_time;
+ nt_large_integer this_period_total_kernel_time;
+ int32_t total_page_fault_count;
+ int32_t total_processes;
+ int32_t active_processes;
+ int32_t total_terminated_processes;
+} nt_job_object_basic_accounting_information;
+
+
+typedef struct _nt_job_object_basic_limit_information {
+ nt_large_integer per_process_user_time_limit;
+ nt_large_integer per_job_user_time_limit;
+ uint32_t limit_flags;
+ size_t minimum_working_set_size;
+ size_t maximum_working_set_size;
+ uint32_t active_process_limit;
+ uintptr_t affinity;
+ uint32_t priority_class;
+ uint32_t scheduling_class;
+} nt_job_object_basic_limit_information;
+
+
+typedef struct _nt_job_object_basic_and_io_accounting_information {
+ nt_job_object_basic_accounting_information basic_info;
+ nt_io_counters io_info;
+} nt_job_object_basic_and_io_accounting_information;
+
+
+typedef struct _nt_job_object_extended_limit_information {
+ nt_job_object_basic_limit_information basic_limit_information;
+ nt_io_counters io_info;
+ size_t process_memory_limit;
+ size_t job_memory_limit;
+ size_t peak_process_memory_used;
+ size_t peak_job_memory_used;
+} nt_job_object_extended_limit_information;
+
+
+typedef struct _nt_job_object_basic_process_id_list {
+ uint32_t number_of_assigned_processes;
+ uint32_t number_of_process_ids_in_list;
+ uintptr_t process_id_list[];
+} nt_job_object_basic_process_id_list;
+
+
+typedef struct _nt_job_object_basic_ui_restrictions {
+ uint32_t ui_restrictions_class;
+} nt_job_object_basic_ui_restrictions;
+
+
+typedef struct _nt_job_object_security_limit_information {
+ uint32_t security_limit_flags;
+ void * job_token;
+ nt_token_groups * sids_to_disable;
+ nt_token_privileges * privileges_to_delete;
+ nt_token_groups * restricted_sids;
+} nt_job_object_security_limit_information;
+
+
+typedef struct _nt_job_object_end_of_job_time_information {
+ uint32_t end_of_job_time_action;
+} nt_job_object_end_of_job_time_information;
+
+
+typedef struct _nt_job_object_associate_completion_port {
+ void * completion_key;
+ void * completion_port;
+} nt_job_object_associate_completion_port;
+
+
+typedef struct _nt_job_object_cpu_rate_control_information {
+ uint32_t control_flags;
+ union {
+ uint32_t cpu_rate;
+ uint32_t weight;
+ };
+} nt_job_object_cpu_rate_control_information;
+
+
+
+typedef int32_t __stdcall ntapi_zw_create_job_object(
+ __out void ** hjob,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_open_job_object(
+ __out void ** hjob,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_terminate_job_object(
+ __in void * hjob,
+ __in int32_t exit_status);
+
+
+typedef int32_t __stdcall ntapi_zw_assign_process_to_job_object(
+ __in void * hjob,
+ __in void * hprocess);
+
+
+typedef int32_t __stdcall ntapi_zw_query_information_job_object(
+ __in void * hjob,
+ __in nt_job_object_info_class job_info_class,
+ __out void * job_info,
+ __in size_t job_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_set_information_job_object(
+ __in void * hjob,
+ __in nt_job_object_info_class job_info_class,
+ __in void * job_info,
+ __in size_t job_info_length);
+
+#endif
diff --git a/include/ntapi/nt_ldr.h b/include/ntapi/nt_ldr.h
new file mode 100644
index 0000000..09ab179
--- /dev/null
+++ b/include/ntapi/nt_ldr.h
@@ -0,0 +1,33 @@
+#ifndef _NT_LDR_H_
+#define _NT_LDR_H_
+
+#include <psxtypes/psxtypes.h>
+#include <dalist/dalist.h>
+#include <ntapi/nt_object.h>
+
+typedef int32_t __stdcall ntapi_ldr_load_dll(
+ __in wchar16_t * image_path __optional,
+ __in uint32_t * image_flags __optional,
+ __in nt_unicode_string * image_name,
+ __out void ** image_base);
+
+
+typedef int32_t __stdcall ntapi_ldr_unload_dll(
+ __in void * image_base);
+
+
+/* extensions */
+typedef int32_t __stdcall ntapi_ldr_load_system_dll(
+ __in void * hsysdir __optional,
+ __in wchar16_t * base_name,
+ __in uint32_t base_name_size,
+ __in uint32_t * image_flags __optional,
+ __out void ** image_base);
+
+typedef int __cdecl ntapi_ldr_create_state_snapshot(
+ __out struct dalist_ex * ldr_state_snapshot);
+
+typedef int __cdecl ntapi_ldr_revert_state_to_snapshot(
+ __in struct dalist_ex * ldr_state_snapshot);
+
+#endif
diff --git a/include/ntapi/nt_locale.h b/include/ntapi/nt_locale.h
new file mode 100644
index 0000000..7d7ef80
--- /dev/null
+++ b/include/ntapi/nt_locale.h
@@ -0,0 +1,31 @@
+#ifndef _NT_LOCALE_H_
+#define _NT_LOCALE_H_
+
+#include <psxtypes/psxtypes.h>
+
+typedef uint32_t nt_lcid;
+typedef uint16_t nt_langid;
+
+
+typedef int32_t __stdcall ntapi_zw_query_default_locale(
+ __in unsigned char thread_or_system,
+ __out nt_lcid * locale);
+
+
+typedef int32_t __stdcall ntapi_zw_set_default_locale(
+ __in unsigned char thread_or_system,
+ __in nt_lcid * locale);
+
+
+typedef int32_t __stdcall ntapi_zw_query_default_ui_language(
+ __out nt_langid * lang_id);
+
+
+typedef int32_t __stdcall ntapi_zw_set_default_ui_language(
+ __in nt_langid * lang_id);
+
+
+typedef int32_t __stdcall ntapi_zw_query_install_ui_language(
+ __out nt_langid * lang_id);
+
+#endif
diff --git a/include/ntapi/nt_memory.h b/include/ntapi/nt_memory.h
new file mode 100644
index 0000000..72bc452
--- /dev/null
+++ b/include/ntapi/nt_memory.h
@@ -0,0 +1,199 @@
+#ifndef _NT_MEMORY_H_
+#define _NT_MEMORY_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_memory_info_class {
+ NT_MEMORY_BASIC_INFORMATION,
+ NT_MEMORY_WORKING_SET_LIST,
+ NT_MEMORY_SECTION_NAME,
+ NT_MEMORY_BASIC_VLM_INFORMATION
+} nt_memory_info_class;
+
+/* memory allocation granularity: same on all supported systems */
+#define NT_ALLOCATION_GRANULARITY (0x10000)
+
+/* memory (de)allocation types */
+#define NT_MEM_PAGE_GUARD 0x00000100 /* protect */
+#define NT_MEM_COMMIT 0x00001000 /* commit */
+#define NT_MEM_RESERVE 0x00002000 /* reserve only */
+#define NT_MEM_DECOMMIT 0x00004000 /* decommit but maintain reservavion */
+#define NT_MEM_RELEASE 0x00008000 /* decommit and cancel reservation */
+#define NT_MEM_RESET 0x00080000 /* make obsolete */
+#define NT_MEM_TOP_DOWN 0x00100000 /* allocate at highest possible address using a slow and possibly buggy algorithm */
+#define NT_MEM_WRITE_WATCH 0x00200000 /* track writes */
+#define NT_MEM_PHYSICAL 0x00400000 /* physical view */
+#define NT_MEM_RESET_UNDO AVOID 0x01000000 /* only after a successful NT_MEM_RESET */
+#define NT_MEM_LARGE_PAGES 0x20000000 /* use large-page support */
+#define NT_MEM_FREE 0x00010000 /* informational only: nt_memory_basic_information.state */
+#define NT_MEM_IMAGE 0x01000000 /* informational only: nt_memory_basic_information.type */
+#define NT_MEM_MAPPED 0x00040000 /* informational only: nt_memory_basic_information.type */
+#define NT_MEM_PRIVATE 0x00020000 /* informational only: nt_memory_basic_information.type */
+
+
+/* memory page access bits */
+#define NT_PAGE_NOACCESS (uint32_t)0x01
+#define NT_PAGE_READONLY (uint32_t)0x02
+#define NT_PAGE_READWRITE (uint32_t)0x04
+#define NT_PAGE_WRITECOPY (uint32_t)0x08
+#define NT_PAGE_EXECUTE (uint32_t)0x10
+#define NT_PAGE_EXECUTE_READ (uint32_t)0x20
+#define NT_PAGE_EXECUTE_READWRITE (uint32_t)0x40
+#define NT_PAGE_EXECUTE_WRITECOPY (uint32_t)0x80
+
+
+/* working set list entries: basic attributes */
+#define NT_WSLE_PAGE_NOT_ACCESSED 0x0000
+#define NT_WSLE_PAGE_READONLY 0x0001
+#define NT_WSLE_PAGE_EXECUTE 0x0002
+#define NT_WSLE_PAGE_EXECUTE_READ 0x0003
+#define NT_WSLE_PAGE_READWRITE 0x0004
+#define NT_WSLE_PAGE_WRITECOPY 0x0005
+#define NT_WSLE_PAGE_EXECUTE_READWRITE 0x0006
+#define NT_WSLE_PAGE_EXECUTE_WRITECOPY 0x0007
+
+/* working set list entries: extended attributes */
+#define NT_WSLE_PAGE_NO_CACHE 0x0008
+#define NT_WSLE_PAGE_GUARD_PAGE 0x0010
+#define NT_WSLE_PAGE_SHARE_COUNT_MASK 0x00E0
+#define NT_WSLE_PAGE_SHAREABLE 0x0100
+
+/* ntapi_zw_lock_virtual_memory lock types */
+#define NT_LOCK_VM_IN_WSL 0x0001
+#define NT_LOCK_VM_IN_RAM 0x0002
+
+
+typedef struct _nt_memory_basic_information {
+ void * base_address;
+ void * allocation_base;
+ uint32_t allocation_protect;
+ size_t region_size;
+ uint32_t state;
+ uint32_t protect;
+ uint32_t type;
+} nt_memory_basic_information;
+
+
+typedef struct _nt_memory_working_set_list {
+ uintptr_t number_of_pages;
+ uintptr_t nt_working_set_list_entry[];
+} nt_memory_working_set_list;
+
+
+typedef struct _nt_memory_section_name {
+ nt_unicode_string section_name;
+ wchar16_t section_name_buffer[];
+} nt_memory_section_name, nt_mem_sec_name;
+
+
+typedef int32_t __stdcall ntapi_zw_allocate_virtual_memory(
+ __in void * hprocess,
+ __in_out void ** base_address,
+ __in uint32_t zero_bits,
+ __in_out size_t * allocation_size,
+ __in uint32_t allocation_type,
+ __in uint32_t protect);
+
+
+typedef int32_t __stdcall ntapi_zw_free_virtual_memory(
+ __in void * hprocess,
+ __in_out void ** base_address,
+ __in_out size_t * free_size,
+ __in uint32_t deallocation_type);
+
+
+typedef int32_t __stdcall ntapi_zw_query_virtual_memory(
+ __in void * hprocess,
+ __in void * base_address,
+ __in nt_memory_info_class mem_info_class,
+ __out void * mem_info,
+ __in size_t mem_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_protect_virtual_memory(
+ __in void * hprocess,
+ __in void ** base_address,
+ __in size_t * protect_size,
+ __in uint32_t protect_type_new,
+ __out uint32_t * protect_type_old);
+
+
+typedef int32_t __stdcall ntapi_zw_read_virtual_memory(
+ __in void * hprocess,
+ __in void * base_address,
+ __out char * buffer,
+ __in size_t buffer_length,
+ __out size_t * bytes_written);
+
+
+typedef int32_t __stdcall ntapi_zw_write_virtual_memory(
+ __in void * hprocess,
+ __in void * base_address,
+ __in char * buffer,
+ __in size_t buffer_length,
+ __out size_t * bytes_written);
+
+
+typedef int32_t __stdcall ntapi_zw_lock_virtual_memory(
+ __in void * hprocess,
+ __in_out void ** base_address,
+ __in_out size_t * lock_size,
+ __in uint32_t lock_type);
+
+
+typedef int32_t __stdcall ntapi_zw_unlock_virtual_memory(
+ __in void * hprocess,
+ __in_out void ** base_address,
+ __in_out size_t * lock_size,
+ __in uint32_t lock_type);
+
+
+typedef int32_t __stdcall ntapi_zw_flush_virtual_memory(
+ __in void * hprocess,
+ __in_out void ** base_address,
+ __in_out size_t * flush_size,
+ __in nt_io_status_block * flush_type);
+
+
+typedef int32_t __stdcall ntapi_zw_allocate_user_physical_pages(
+ __in void * hprocess,
+ __in_out uintptr_t * number_of_pages,
+ __out uintptr_t * arr_page_frame_numbers);
+
+
+typedef int32_t __stdcall ntapi_zw_free_user_physical_pages(
+ __in void * hprocess,
+ __in_out uintptr_t * number_of_pages,
+ __in uintptr_t * arr_page_frame_numbers);
+
+
+typedef int32_t __stdcall ntapi_zw_map_user_physical_pages(
+ __in void * base_address,
+ __in_out uintptr_t * number_of_pages,
+ __in uintptr_t * arr_page_frame_numbers);
+
+
+typedef int32_t __stdcall ntapi_zw_map_user_physical_pages_scatter(
+ __in void ** virtual_addresses,
+ __in_out uintptr_t * number_of_pages,
+ __in uintptr_t * arr_page_options);
+
+
+typedef uint32_t __stdcall ntapi_zw_get_write_watch(
+ __in void * hprocess,
+ __in uint32_t flags,
+ __in void * base_address,
+ __in size_t region_size,
+ __out uintptr_t * buffer,
+ __in_out uintptr_t * buffer_entries,
+ __out uintptr_t * granularity);
+
+
+typedef uint32_t __stdcall ntapi_zw_reset_write_watch(
+ __in void * hprocess,
+ __in void * base_address,
+ __in size_t region_size);
+
+#endif
diff --git a/include/ntapi/nt_mount.h b/include/ntapi/nt_mount.h
new file mode 100644
index 0000000..8a7258a
--- /dev/null
+++ b/include/ntapi/nt_mount.h
@@ -0,0 +1,135 @@
+#ifndef _NT_MOUNT_H_
+#define _NT_MOUNT_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_ioctl.h"
+#include "nt_statfs.h"
+
+/* hash mark */
+/* {'\\','D','e','v','i','c','e','\\'} */
+#define __DEVICE_PATH_PREFIX_LEN (8 * sizeof(wchar16_t))
+#define __DEVICE_PATH_PREFIX_HASH (0xDA6FA40B)
+
+/* {'\\','?','?','\\','V','o','l','u','m','e','{'} */
+#define __VOLUME_PATH_PREFIX_LEN (11 * sizeof(wchar16_t))
+#define __VOLUME_PATH_PREFIX_HASH (0xFEBA8529)
+
+/* {'\\','D','o','s','D','e','v','i','c','e','s'} */
+#define __DOS_DEVICES_PREFIX_LEN (11 * sizeof(wchar16_t))
+#define __DOS_DEVICES_PREFIX_HASH (0x565D0514)
+
+
+typedef enum _nt_mount_moint_type {
+ NT_MOUNT_POINT_NONE,
+ NT_MOUNT_POINT_DEVICE,
+ NT_MOUNT_POINT_VOLUME,
+ NT_MOUNT_POINT_DIRECTORY
+} nt_mount_moint_type;
+
+/* reparse tag values */
+#define NT_IO_REPARSE_TAG_RESERVED_ZERO (0x00000000)
+#define NT_IO_REPARSE_TAG_RESERVED_ONE (0x00000001)
+#define NT_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003)
+#define NT_IO_REPARSE_TAG_HSM (0xC0000004)
+#define NT_IO_REPARSE_TAG_HSM2 (0x80000006)
+#define NT_IO_REPARSE_TAG_DRIVER_EXTENDER (0x80000005)
+#define NT_IO_REPARSE_TAG_SIS (0x80000007)
+#define NT_IO_REPARSE_TAG_DFS (0x8000000A)
+#define NT_IO_REPARSE_TAG_DFSR (0x80000012)
+#define NT_IO_REPARSE_TAG_FILTER_MANAGER (0x8000000B)
+#define NT_IO_REPARSE_TAG_SYMLINK (0xA000000C)
+
+
+typedef struct _nt_mount_dev_name {
+ uint16_t name_length;
+ wchar16_t name[];
+} nt_mount_dev_name;
+
+
+typedef struct _nt_mount_mgr_mount_point {
+ uint32_t symlink_name_offset;
+ uint16_t symlink_name_length;
+ uint32_t unique_id_offset;
+ uint16_t unique_id_length;
+ uint32_t device_name_offset;
+ uint16_t device_name_length;
+} nt_mount_mgr_mount_point, nt_mount_point;
+
+
+typedef struct _nt_mount_mgr_mount_point_param {
+ uint32_t symlink_name_offset;
+ uint16_t symlink_name_length;
+ uint32_t unique_id_offset;
+ uint16_t unique_id_length;
+ uint32_t device_name_offset;
+ uint16_t device_name_length;
+ uint16_t mount_points_offset;
+ wchar16_t device_name[];
+} nt_mount_mgr_mount_point_param, nt_mount_point_param;
+
+
+typedef struct _nt_mount_mgr_mount_points {
+ uint32_t size;
+ uint32_t number;
+ nt_mount_mgr_mount_point mount_points[];
+} nt_mount_mgr_mount_points, nt_mount_points;
+
+
+typedef struct _nt_mount_point_reparse_buffer {
+ uint32_t reparse_tag;
+ uint16_t reparse_data_length;
+ uint16_t reserved;
+ uint16_t substitute_name_offset;
+ uint16_t substitute_name_length;
+ uint16_t print_name_offset;
+ uint16_t print_name_length;
+ uintptr_t path_buffer[];
+} _nt_mount_point_reparse_buffer, nt_mprb;
+
+
+typedef struct _nt_dos_devices_name {
+ wchar16_t dos_devices_prefix[11];
+ wchar16_t slash;
+ wchar16_t letter;
+ wchar16_t colon;
+} nt_dos_devices_name;
+
+
+typedef int32_t __stdcall ntapi_tt_get_dos_drive_device_handle(
+ __out void ** hdevice,
+ __in wchar16_t * drive_letter);
+
+
+typedef int32_t __stdcall ntapi_tt_get_dos_drive_root_handle(
+ __out void ** hroot,
+ __in wchar16_t * drive_letter);
+
+
+typedef int32_t __stdcall ntapi_tt_get_dos_drive_device_name(
+ __in void * hdevice __optional,
+ __in wchar16_t * drive_letter __optional,
+ __out nt_mount_dev_name * buffer,
+ __in uint32_t buffer_size);
+
+
+typedef int32_t __stdcall ntapi_tt_get_dos_drive_mount_points(
+ __in void * hdevice __optional,
+ __in wchar16_t * drive_letter __optional,
+ __in nt_mount_dev_name * dev_name __optional,
+ __out void * buffer,
+ __in uint32_t buffer_size);
+
+
+typedef int32_t __stdcall ntapi_tt_dev_mount_points_to_statfs(
+ __in nt_mount_points * mount_points,
+ __in_out nt_statfs * statfs);
+
+
+typedef int32_t __stdcall ntapi_tt_get_dos_drive_letter_from_device(
+ __in void * hdevice __optional,
+ __out wchar16_t * drive_letter,
+ __in nt_mount_dev_name * dev_name __optional,
+ __out void * buffer,
+ __in uint32_t buffer_size);
+
+#endif
diff --git a/include/ntapi/nt_object.h b/include/ntapi/nt_object.h
new file mode 100644
index 0000000..bc4df6f
--- /dev/null
+++ b/include/ntapi/nt_object.h
@@ -0,0 +1,514 @@
+#ifndef _NT_OBJECT_H_
+#define _NT_OBJECT_H_
+
+#include <psxtypes/psxtypes.h>
+
+typedef enum _nt_object_info_class {
+ NT_OBJECT_BASIC_INFORMATION = 0,
+ NT_OBJECT_NAME_INFORMATION = 1,
+ NT_OBJECT_TYPE_INFORMATION = 2,
+ NT_OBJECT_ALL_TYPES_INFORMATION = 3,
+ NT_OBJECT_HANDLE_INFORMATION = 4
+} nt_object_info_class;
+
+
+typedef enum _nt_security_impersonation_level {
+ NT_SECURITY_ANONYMOUS = 0,
+ NT_SECURITY_IDENTIFICATION = 1,
+ NT_SECURITY_IMPERSONATION = 2,
+ NT_SECURITY_DELEGATION = 3
+} nt_security_impersonation_level;
+
+
+typedef enum _nt_security_information {
+ NT_OWNER_SECURITY_INFORMATION = 0x01,
+ NT_GROUP_SECURITY_INFORMATION = 0x02,
+ NT_DACL_SECURITY_INFORMATION = 0x04,
+ NT_SACL_SECURITY_INFORMATION = 0x08
+} nt_security_information;
+
+
+
+/* generic access rights */
+#define NT_SEC_DELETE (0x00010000u)
+#define NT_SEC_READ_CONTROL (0x00020000u)
+#define NT_SEC_WRITE_DAC (0x00040000u)
+#define NT_SEC_WRITE_OWNER (0x00080000u)
+#define NT_SEC_SYNCHRONIZE (0x00100000u)
+#define NT_SEC_STANDARD_RIGHTS_REQUIRED (0x000F0000u)
+#define NT_SEC_STANDARD_RIGHTS_READ NT_SEC_READ_CONTROL
+#define NT_SEC_STANDARD_RIGHTS_WRITE NT_SEC_READ_CONTROL
+#define NT_SEC_STANDARD_RIGHTS_EXECUTE NT_SEC_READ_CONTROL
+#define NT_SEC_STANDARD_RIGHTS_ALL (0x001F0000u)
+#define NT_SEC_SPECIFIC_RIGHTS_ALL (0x0000FFFFu)
+
+#define NT_GENERIC_ALL (0x10000000u)
+#define NT_GENERIC_EXECUTE (0x20000000u)
+#define NT_GENERIC_WRITE (0x40000000u)
+#define NT_GENERIC_READ (0x80000000u)
+
+
+/* zw_open_directory access rights */
+#define NT_DIRECTORY_QUERY (0x0001u)
+#define NT_DIRECTORY_TRAVERSE (0x0002u)
+#define NT_DIRECTORY_CREATE_OBJECT (0x0004u)
+#define NT_DIRECTORY_CREATE_SUBDIRECTORY (0x0008u)
+#define NT_DIRECTORY_ALL_ACCESS NT_DIRECTORY_QUERY \
+ | NT_DIRECTORY_TRAVERSE \
+ | NT_DIRECTORY_CREATE_OBJECT \
+ | NT_DIRECTORY_CREATE_SUBDIRECTORY \
+ | NT_SEC_STANDARD_RIGHTS_REQUIRED
+
+/* zw_open_symbolic_link_object access rights */
+#define NT_SYMBOLIC_LINK_QUERY (0x0001u)
+#define NT_SYMBOLIC_LINK_ALL_ACCESS NT_SYMBOLIC_LINK_QUERY \
+ | NT_SEC_STANDARD_RIGHTS_REQUIRED
+
+/* object handles */
+#define NT_HANDLE_FLAG_INHERIT (0x0001u)
+#define NT_HANDLE_FLAG_PROTECT_FROM_CLOSE (0x0002u)
+#define NT_HANDLE_PERMANENT (0x0010u)
+#define NT_HANDLE_EXCLUSIVE (0x0020u)
+#define NT_INVALID_HANDLE_VALUE ((void *)(intptr_t)-1)
+
+/* object attribute bits */
+#define NT_OBJ_INHERIT (0x0002u)
+#define NT_OBJ_PERMANENT (0x0010u)
+#define NT_OBJ_EXCLUSIVE (0x0020u)
+#define NT_OBJ_CASE_INSENSITIVE (0x0040u)
+#define NT_OBJ_OPENIF (0x0080u)
+#define NT_OBJ_OPENLINK (0x0100u)
+#define NT_OBJ_KERNEL_HANDLE (0x0200u)
+
+/* duplicate object bits */
+#define NT_DUPLICATE_CLOSE_SOURCE (0x0001u)
+#define NT_DUPLICATE_SAME_ACCESS (0x0002u)
+#define NT_DUPLICATE_SAME_ATTRIBUTES (0x0004u)
+
+/* nt_security_descriptor constants (IFS open specification) */
+#define NT_SE_OWNER_DEFAULTED (int16_t)0x0001
+#define NT_SE_GROUP_DEFAULTED (int16_t)0x0002
+#define NT_SE_DACL_PRESENT (int16_t)0x0004
+#define NT_SE_DACL_DEFAULTED (int16_t)0x0008
+#define NT_SE_SACL_PRESENT (int16_t)0x0010
+#define NT_SE_SACL_DEFAULTED (int16_t)0x0020
+#define NT_SE_DACL_AUTO_INHERIT_REQ (int16_t)0x0100
+#define NT_SE_SACL_AUTO_INHERIT_REQ (int16_t)0x0200
+#define NT_SE_DACL_AUTO_INHERITED (int16_t)0x0400
+#define NT_SE_SACL_AUTO_INHERITED (int16_t)0x0800
+#define NT_SE_DACL_PROTECTED (int16_t)0x1000
+#define NT_SE_SACL_PROTECTED (int16_t)0x2000
+#define NT_SE_RM_CONTROL_VALID (int16_t)0x4000
+#define NT_SE_SELF_RELATIVE (int16_t)0x8000
+
+/* security tracking */
+#define NT_SECURITY_TRACKING_STATIC 0
+#define NT_SECURITY_TRACKING_DYNAMIC 1
+
+/* predefined security authorities */
+#define NT_SECURITY_NULL_SID_AUTHORITY 0
+#define NT_SECURITY_WORLD_SID_AUTHORITY 1
+#define NT_SECURITY_LOCAL_SID_AUTHORITY 2
+#define NT_SECURITY_CREATOR_SID_AUTHORITY 3
+#define NT_SECURITY_NON_UNIQUE_AUTHORITY 4
+#define NT_SECURITY_NT_AUTHORITY 5
+
+/* token source length */
+#define NT_TOKEN_SOURCE_LENGTH 8
+
+
+typedef struct _nt_unicode_string {
+ uint16_t strlen;
+ uint16_t maxlen;
+ uint16_t * buffer;
+} nt_unicode_string;
+
+
+typedef union _nt_large_integer {
+ struct {
+ uint32_t ulow;
+ int32_t ihigh;
+ };
+ long long quad;
+} nt_large_integer, nt_timeout, nt_filetime, nt_sec_size;
+
+
+typedef struct _nt_io_status_block {
+ union {
+ int32_t status;
+ void * pointer;
+ };
+ intptr_t info;
+} nt_io_status_block, nt_iosb;
+
+
+typedef struct _nt_quota_limits {
+ size_t paged_pool_limit;
+ size_t non_paged_pool_limit;
+ size_t minimum_working_set_size;
+ size_t maximum_working_set_size;
+ size_t pagefile_limit;
+ nt_large_integer time_limit;
+} nt_quota_limits, nt_ql;
+
+
+typedef struct _nt_kernel_user_times {
+ nt_large_integer create_time;
+ nt_large_integer exit_time;
+ nt_large_integer kernel_time;
+ nt_large_integer user_time;
+} nt_kernel_user_times, nt_kut;
+
+
+typedef struct _nt_io_counters {
+ nt_large_integer read_operation_count;
+ nt_large_integer write_operation_count;
+ nt_large_integer other_operation_count;
+ nt_large_integer read_transfer_count;
+ nt_large_integer write_transfer_count;
+ nt_large_integer other_transfer_count;
+} nt_io_counters;
+
+
+typedef struct _nt_vm_counters {
+ size_t peak_virtual_size;
+ size_t virtual_size;
+ size_t page_fault_count;
+ size_t peak_working_set_size;
+ size_t working_set_size;
+ size_t quota_peak_paged_pool_usage;
+ size_t quota_paged_pool_usage;
+ size_t quota_peak_non_paged_pool_usage;
+ size_t quota_non_paged_pool_usage;
+ size_t pagefile_usage;
+ size_t peak_pagefile_usage;
+} nt_vm_counters;
+
+
+typedef struct _nt_pooled_usage_and_limits {
+ size_t peak_paged_pool_usage;
+ size_t paged_pool_usage;
+ size_t paged_pool_limit;
+ size_t peak_non_paged_pool_usage;
+ size_t non_paged_pool_usage;
+ size_t non_paged_pool_limit;
+ size_t peak_pagefile_usage;
+ size_t pagefile_usage;
+ size_t pagefile_limit;
+} nt_pooled_usage_and_limits, nt_pual;
+
+
+typedef struct _nt_client_id {
+ uintptr_t process_id;
+ uintptr_t thread_id;
+} nt_client_id, nt_cid;
+
+
+typedef struct _nt_generic_mapping {
+ uint32_t generic_read;
+ uint32_t generic_write;
+ uint32_t generic_execute;
+ uint32_t generic_all;
+} nt_generic_mapping, nt_gmap;
+
+
+typedef struct _nt_security_attributes {
+ uint32_t length;
+ void * security_descriptor;
+ int32_t inherit_handle;
+} nt_security_attributes, nt_sa;
+
+
+typedef struct _nt_guid {
+ uint32_t data1;
+ uint16_t data2;
+ uint16_t data3;
+ unsigned char data4[8];
+} nt_guid, nt_uuid;
+
+
+typedef struct _nt_uuid_vector {
+ uint32_t count;
+ nt_uuid * uuid[];
+} nt_uuid_vector;
+
+
+typedef struct _nt_acl {
+ unsigned char acl_revision;
+ unsigned char sbz_1st;
+ uint16_t acl_size;
+ uint16_t ace_count;
+ uint16_t sbz_2nd;
+} nt_acl;
+
+
+typedef struct _nt_security_descriptor {
+ unsigned char revision;
+ unsigned char sbz_1st;
+ uint16_t control;
+ uint32_t offset_owner;
+ uint32_t offset_group;
+ uint32_t offset_sacl;
+ uint32_t offset_dacl;
+} nt_security_descriptor, nt_sd;
+
+
+typedef struct _nt_security_quality_of_service {
+ uint32_t length;
+ int32_t impersonation_level;
+ int32_t context_tracking_mode;
+ int32_t effective_only;
+} nt_security_quality_of_service, nt_sqos;
+
+
+typedef struct _nt_sid_identifier_authority {
+ unsigned char value[6];
+} nt_sid_identifier_authority;
+
+
+typedef struct _nt_sid {
+ unsigned char revision;
+ unsigned char sub_authority_count;
+ nt_sid_identifier_authority identifier_authority;
+ uint32_t sub_authority[1];
+} nt_sid;
+
+
+typedef struct _nt_sid_and_attributes {
+ nt_sid * sid;
+ uint32_t attributes;
+} nt_sid_and_attributes;
+
+
+typedef struct _nt_token_user {
+ nt_sid_and_attributes user;
+} nt_token_user;
+
+
+typedef struct _nt_token_owner {
+ nt_sid * owner;
+} nt_token_owner;
+
+
+typedef struct _nt_token_primary_group {
+ nt_sid * primary_group;
+} nt_token_primary_group;
+
+
+typedef struct _nt_token_groups {
+ uint32_t group_count;
+ nt_sid_and_attributes groups[];
+} nt_token_groups;
+
+
+typedef struct _nt_token_default_dacl {
+ nt_acl * default_dacl;
+} nt_token_default_dacl;
+
+
+typedef struct _nt_luid {
+ uint32_t low;
+ int32_t high;
+} nt_luid;
+
+
+typedef struct _nt_token_origin {
+ nt_luid originating_logon_session;
+} nt_token_origin;
+
+
+typedef struct _nt_token_source {
+ char source_name[NT_TOKEN_SOURCE_LENGTH];
+ nt_luid source_identifier;
+} nt_token_source;
+
+
+typedef struct _nt_luid_and_attributes {
+ nt_luid luid;
+ uint32_t attributes;
+} nt_luid_and_attributes;
+
+
+typedef struct _nt_token_privileges {
+ uint32_t privilege_count;
+ nt_luid_and_attributes privileges[];
+} nt_token_privileges;
+
+
+typedef struct _nt_object_attributes {
+ uint32_t len;
+ void * root_dir;
+ nt_unicode_string * obj_name;
+ uint32_t obj_attr;
+ nt_security_descriptor *sec_desc;
+ nt_sqos * sec_qos;
+} nt_object_attributes, nt_oa;
+
+
+typedef struct _nt_object_basic_information {
+ uint32_t attributes;
+ uint32_t granted_access;
+ uint32_t handle_count;
+ uint32_t pointer_count;
+ uint32_t paged_pool_usage;
+ uint32_t non_paged_pool_usage;
+ uint32_t reserved[3];
+ uint32_t name_information_length;
+ uint32_t type_information_length;
+ uint32_t security_descriptor_length;
+ nt_large_integer create_time;
+} nt_object_basic_information;
+
+
+typedef struct _nt_object_name_information {
+ nt_unicode_string name;
+} nt_object_name_information;
+
+
+
+typedef struct _nt_object_handle_information {
+ unsigned char inherit;
+ unsigned char protect_from_close;
+} nt_object_handle_information, nt_ohio;
+
+
+typedef struct _nt_directory_basic_information {
+ nt_unicode_string object_name;
+ nt_unicode_string object_type_name;
+} nt_directory_basic_information;
+
+
+typedef struct _nt_keyed_object_directory_guid {
+ wchar16_t uscore_guid;
+ wchar16_t pgrp_guid[36];
+ wchar16_t uscore_key;
+} nt_keyed_object_directory_guid, nt_keyed_objdir_guid;
+
+typedef struct _nt_keyed_object_directory_name {
+ wchar16_t base_named_objects[17];
+ wchar16_t backslash;
+ wchar16_t prefix[6];
+ nt_keyed_objdir_guid objdir_guid;
+ wchar16_t key[8];
+} nt_keyed_object_directory_name, nt_keyed_objdir_name;
+
+
+typedef void nt_io_apc_routine(
+ void * apc_context,
+ nt_io_status_block * io_status_block,
+ uint32_t reserved);
+
+
+typedef int32_t __stdcall ntapi_zw_query_object(
+ __in void * handle,
+ __in nt_object_info_class obj_info_class,
+ __out void * obj_info,
+ __in size_t obj_info_length,
+ __out uint32_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_set_information_object(
+ __in void * handle,
+ __in nt_object_info_class obj_info_class,
+ __in void * obj_info,
+ __in size_t obj_info_length);
+
+
+typedef int32_t __stdcall ntapi_zw_duplicate_object(
+ __in void * hprocess_src,
+ __in void * handle_src,
+ __in void * hprocess_dst,
+ __out void ** handle_dst __optional,
+ __in uint32_t desired_access,
+ __in uint32_t attributes,
+ __in uint32_t options);
+
+
+typedef int32_t __stdcall ntapi_zw_make_temporary_object(
+ __in void * handle);
+
+
+typedef int32_t __stdcall ntapi_zw_close(
+ __in void * handle);
+
+
+
+typedef int32_t __stdcall ntapi_zw_query_security_object(
+ __in void * handle,
+ __in nt_security_information security_info,
+ __out nt_security_descriptor * security_descriptor,
+ __in size_t security_descriptor_length,
+ __out size_t * returned_length);
+
+
+typedef int32_t __stdcall ntapi_zw_set_security_object(
+ __in void * handle,
+ __in nt_security_information security_info,
+ __out nt_security_descriptor * security_descriptor);
+
+
+
+typedef int32_t __stdcall ntapi_zw_create_directory_object(
+ __out void ** directory_handle,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_open_directory_object(
+ __out void ** directory_handle,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_query_directory_object(
+ __in void * directory_handle,
+ __out void * buffer,
+ __in size_t buffer_length,
+ __in int32_t return_single_entry,
+ __in int32_t return_scan,
+ __in_out uint32_t * context,
+ __out size_t * returned_length);
+
+
+typedef int32_t __stdcall ntapi_zw_create_symbolic_link_object(
+ __out void ** symbolic_link_handle,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in nt_unicode_string * target_name);
+
+
+typedef int32_t __stdcall ntapi_zw_open_symbolic_link_object(
+ __out void ** symbolic_link_handle,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_query_symbolic_link_object(
+ __in void * symbolic_link_handle,
+ __in_out nt_unicode_string * target_name,
+ __out size_t * returned_length);
+
+/* extension functions */
+typedef int32_t __stdcall ntapi_tt_create_keyed_object_directory(
+ __out void ** hdir,
+ __in uint32_t desired_access,
+ __in const wchar16_t prefix[6],
+ __in nt_guid * guid,
+ __in uint32_t key);
+
+typedef int32_t __stdcall ntapi_tt_open_keyed_object_directory(
+ __out void ** hdir,
+ __in uint32_t desired_access,
+ __in const wchar16_t prefix[6],
+ __in nt_guid * guid,
+ __in uint32_t key);
+
+typedef int32_t __stdcall ntapi_tt_create_keyed_object_directory_entry(
+ __out void ** hentry,
+ __in uint32_t desired_access,
+ __in void * hdir,
+ __in void * htarget,
+ __in nt_unicode_string * target_name,
+ __in uint32_t key);
+
+#endif
diff --git a/include/ntapi/nt_os.h b/include/ntapi/nt_os.h
new file mode 100644
index 0000000..2ecd1d4
--- /dev/null
+++ b/include/ntapi/nt_os.h
@@ -0,0 +1,99 @@
+#ifndef _NT_OS_H_
+#define _NT_OS_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+
+typedef enum _nt_hard_error_response_option {
+ NT_OPTION_ABORT_RETRY_IGNORE,
+ NT_OPTION_OK_,
+ NT_OPTION_OK_CANCEL,
+ NT_OPTION_RETRY_CANCEL,
+ NT_OPTION_YES_NO,
+ NT_OPTION_YES_NO_CANCEL,
+ NT_OPTION_SHUTDOWN_SYSTEM
+} nt_hard_error_response_option;
+
+
+typedef enum _nt_hard_error_response {
+ NT_RESPONSE_RETURN_TO_CALLER,
+ NT_RESPONSE_NOT_HANDLED,
+ NT_RESPONSE_ABORT,
+ NT_RESPONSE_CANCEL,
+ NT_RESPONSE_IGNORE,
+ NT_RESPONSE_NO,
+ NT_RESPONSE_OK,
+ NT_RESPONSE_RETRY,
+ NT_RESPONSE_YES
+} nt_hard_error_response;
+
+
+typedef struct _nt_ldt_entry {
+ int32_t limit_low;
+ int32_t base_low;
+
+ union {
+ struct {
+ unsigned char base_mid;
+ unsigned char flags1;
+ unsigned char flags2;
+ unsigned char base_hi;
+ } bytes;
+
+ struct {
+ uint32_t base_mid :8;
+ uint32_t type :5;
+ uint32_t dpl :2;
+ uint32_t pres :1;
+ uint32_t limit_hi :4;
+ uint32_t sys :1;
+ uint32_t reserved :1;
+ uint32_t default_big :1;
+ uint32_t granularity :1;
+ uint32_t base_hi :8;
+ } bits;
+ } high_word;
+} nt_ldt_entry;
+
+
+typedef int32_t __stdcall ntapi_zw_flush_write_buffer(void);
+
+
+/* interface requires further studying */
+typedef int32_t __stdcall ntapi_zw_raise_hard_error(
+ __in int32_t status,
+ __in uint32_t number_of_args,
+ __in uint32_t string_arg_mask,
+ __in uint32_t * args,
+ __in nt_hard_error_response_option response_option,
+ __out nt_hard_error_response * response_received);
+
+
+typedef int32_t __stdcall ntapi_zw_set_default_hard_error_port(
+ __in void * hport);
+
+
+typedef int32_t __stdcall ntapi_zw_display_string(
+ __in nt_unicode_string * display_string);
+
+
+typedef int32_t __stdcall ntapi_zw_create_paging_file(
+ __in nt_unicode_string * file_name,
+ __in nt_large_integer * initial_size,
+ __in nt_large_integer * maximum_size,
+ __in uintptr_t reserved);
+
+
+typedef int32_t __stdcall ntapi_zw_set_ldt_entries(
+ __in uint32_t selector_1st,
+ __in nt_ldt_entry * ldt_entry_1st,
+ __in uint32_t selector_2nd,
+ __in nt_ldt_entry * ldt_entry_2nd);
+
+
+typedef int32_t __stdcall ntapi_zw_vdm_control(
+ __in uint32_t vdm_control_code,
+ __in void * vdm_control_data);
+
+#endif
diff --git a/include/ntapi/nt_pnp.h b/include/ntapi/nt_pnp.h
new file mode 100644
index 0000000..e806baf
--- /dev/null
+++ b/include/ntapi/nt_pnp.h
@@ -0,0 +1,326 @@
+#ifndef _NT_PNP_H_
+#define _NT_PNP_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_latency_time {
+ NT_LT_DONT_CARE,
+ NT_LT_LOWEST_LATENCY
+} nt_latency_time;
+
+
+typedef enum _nt_device_power_state {
+ NT_POWER_DEVICE_UNSPECIFIED,
+ NT_POWER_DEVICE_D0,
+ NT_POWER_DEVICE_D1,
+ NT_POWER_DEVICE_D2,
+ NT_POWER_DEVICE_D3
+} nt_device_power_state;
+
+
+typedef enum _nt_power_action {
+ NT_POWER_ACTION_NONE,
+ NT_POWER_ACTION_RESERVED,
+ NT_POWER_ACTION_SLEEP,
+ NT_POWER_ACTION_HIBERNATE,
+ NT_POWER_ACTION_SHUTDOWN,
+ NT_POWER_ACTION_SHUTDOWN_RESET,
+ NT_POWER_ACTION_SHUTDOWN_OFF,
+} nt_power_action;
+
+
+typedef enum _nt_system_power_state {
+ NT_POWER_SYSTEM_UNSPECIFIED,
+ NT_POWER_SYSTEM_WORKING,
+ NT_POWER_SYSTEM_SLEEPING1,
+ NT_POWER_SYSTEM_SLEEPING2,
+ NT_POWER_SYSTEM_SLEEPING3,
+ NT_POWER_SYSTEM_HIBERNATE,
+ NT_POWER_SYSTEM_SHUTDOWN
+} nt_system_power_state;
+
+
+typedef enum _nt_power_info_level {
+ NT_SYSTEM_POWER_POLICY_AC,
+ NT_SYSTEM_POWER_POLICY_DC,
+ NT_VERIFY_SYSTEM_POLICY_AC,
+ NT_VERIFY_SYSTEM_POLICY_DC,
+ NT_SYSTEM_POWER_CAPABILITIES,
+ NT_SYSTEM_BATTERY_STATE,
+ NT_SYSTEM_POWER_STATE_HANDLER,
+ NT_PROCESSOR_STATE_HANDLER,
+ NT_SYSTEM_POWER_POLICY_CURRENT,
+ NT_ADMINISTRATOR_POWER_POLICY,
+ NT_SYSTEM_RESERVE_HIBER_FILE,
+ NT_PROCESSOR_INFORMATION,
+ NT_SYSTEM_POWER_INFORMATION
+} nt_power_info_level;
+
+
+/* execution state bits */
+#define NT_ES_SYSTEM_REQUIRED (0x00000001)
+#define NT_ES_DISPLAY_REQUIRED (0x00000002)
+#define NT_ES_USER_PRESENT (0x00000004)
+#define NT_ES_AWAYMODE_REQUIRED (0x00000040)
+#define NT_ES_CONTINUOUS (0x80000000)
+
+
+/* power action flag bits */
+#define NT_POWER_ACTION_QUERY_ALLOWED (0x00000001)
+#define NT_POWER_ACTION_UI_ALLOWED (0x00000002)
+#define NT_POWER_ACTION_OVERRIDE_APPS (0x00000004)
+#define NT_POWER_ACTION_LIGHTEST_FIRST (0x10000000)
+#define NT_POWER_ACTION_LOCK_CONSOLE (0x20000000)
+#define NT_POWER_ACTION_DISABLE_WAKES (0x40000000)
+#define NT_POWER_ACTION_CRITICAL (0x80000000)
+
+
+/* power state event codes */
+#define NT_POWER_LEVEL_USER_NOTIFY_TEXT (0x00000001)
+#define NT_POWER_LEVEL_USER_NOTIFY_SOUND (0x00000002)
+#define NT_POWER_LEVEL_USER_NOTIFY_EXEC (0x00000004)
+#define NT_POWER_USER_NOTIFY_BUTTON (0x00000008)
+#define NT_POWER_USER_NOTIFY_SHUTDOWN (0x00000010)
+#define NT_POWER_FORCE_TRIGGER_RESET (0x80000000)
+
+/* system power policy */
+#define NT_NUM_DISCHARGE_POLICIES (0x00000004)
+
+
+
+typedef struct _nt_power_action_policy {
+ nt_power_action action;
+ uint32_t action_flags;
+ uint32_t event_code;
+} nt_power_action_policy;
+
+
+typedef struct _nt_system_power_level {
+ unsigned char enable;
+ unsigned char padding[3];
+ uint32_t battery_level;
+ nt_power_action_policy power_policy;
+ nt_system_power_state min_system_state;
+} nt_system_power_level;
+
+
+typedef struct _nt_system_power_policy {
+ uint32_t revision;
+ nt_power_action_policy power_button;
+ nt_power_action_policy sleep_button;
+ nt_power_action_policy lid_close;
+ nt_system_power_state lid_open_wake;
+ uint32_t reserved_1st;
+ nt_power_action_policy idle;
+ uint32_t idle_timeout;
+ unsigned char idle_sensitivity;
+ unsigned char dynamic_throttle;
+ unsigned char padding[2];
+ nt_system_power_state min_sleep;
+ nt_system_power_state max_sleep;
+ nt_system_power_state reduced_latency_sleep;
+ uint32_t win_logon_flags;
+ uint32_t reserved_2nd;
+ uint32_t doze_s4_timeout;
+ uint32_t broadcast_capacity_resolution;
+ nt_system_power_level discharge_policy[NT_NUM_DISCHARGE_POLICIES];
+ uint32_t video_timeout;
+ unsigned char video_dim_display;
+ uint32_t video_reserved[3];
+ uint32_t spindown_timeout;
+ unsigned char optimize_for_power;
+ unsigned char fan_throttle_tolerance;
+ unsigned char forced_throttle;
+ unsigned char min_throttle;
+ nt_power_action_policy over_throttled;
+} nt_system_power_policy;
+
+
+typedef struct _nt_system_battery_state {
+ unsigned char ac_on_line;
+ unsigned char battery_present;
+ unsigned char charging;
+ unsigned char discharging;
+ unsigned char padding[4];
+ uint32_t max_capacity;
+ uint32_t remaining_capacity;
+ uint32_t rate;
+ uint32_t estimated_time;
+ uint32_t default_alert1;
+ uint32_t default_alert2;
+} nt_system_battery_state;
+
+
+typedef struct _nt_battery_reporting_scale {
+ uint32_t granularity;
+ uint32_t capacity;
+} nt_battery_reporting_scale;
+
+
+typedef struct _nt_system_power_capabilities {
+ unsigned char power_button_present;
+ unsigned char sleep_button_present;
+ unsigned char lid_present;
+ unsigned char system_s1;
+ unsigned char system_s2;
+ unsigned char system_s3;
+ unsigned char system_s4;
+ unsigned char system_s5;
+ unsigned char hiber_file_present;
+ unsigned char full_wake;
+ unsigned char video_dim_present;
+ unsigned char apm_present;
+ unsigned char ups_present;
+ unsigned char thermal_control;
+ unsigned char processor_throttle;
+ unsigned char processor_min_throttle;
+ unsigned char processor_max_throttle;
+ unsigned char fast_system_s4;
+ unsigned char hiber_boot;
+ unsigned char wake_alarm_present;
+ unsigned char ao_ac;
+ unsigned char disk_spin_down;
+ unsigned char padding[8];
+ unsigned char system_batteries_present;
+ unsigned char batteries_are_short_term;
+ nt_battery_reporting_scale battery_scale[3];
+ nt_system_power_state ac_on_line_wake;
+ nt_system_power_state soft_lid_wake;
+ nt_system_power_state rtc_wake;
+ nt_system_power_state min_device_wake_state;
+ nt_system_power_state default_low_latency_wake;
+} nt_system_power_capabilities;
+
+
+typedef struct _nt_system_power_information {
+ uint32_t max_idleness_allowed;
+ uint32_t idleness;
+ uint32_t time_remaining;
+ unsigned char cooling_mode;
+} nt_system_power_information;
+
+
+typedef struct _nt_system_power_status {
+ unsigned char ac_line_status;
+ unsigned char battery_flag;
+ unsigned char battery_life_percent;
+ unsigned char reserved;
+ uint32_t battery_life_time;
+ uint32_t battery_full_life_time;
+} nt_system_power_status;
+
+
+typedef struct _nt_administrator_power_policy {
+ nt_system_power_state min_sleep;
+ nt_system_power_state max_sleep;
+ uint32_t min_video_timeout;
+ uint32_t max_video_timeout;
+ uint32_t min_spindown_timeout;
+ uint32_t max_spindown_timeout;
+} nt_administrator_power_policy;
+
+
+typedef struct _nt_user_power_policy {
+ uint32_t revision;
+ nt_power_action_policy idle_ac;
+ nt_power_action_policy idle_dc;
+ uint32_t idle_timeout_ac;
+ uint32_t idle_timeout_dc;
+ unsigned char idle_sensitivity_ac;
+ unsigned char idle_sensitivity_dc;
+ unsigned char throttle_policy_ac;
+ unsigned char throttle_policy_dc;
+ nt_system_power_state max_sleep_ac;
+ nt_system_power_state max_sleep_dc;
+ uint32_t reserved[2];
+ uint32_t video_timeout_ac;
+ uint32_t video_timeout_dc;
+ uint32_t spindown_timeout_ac;
+ uint32_t spindown_timeout_dc;
+ unsigned char optimize_for_power_ac;
+ unsigned char optimize_for_power_dc;
+ unsigned char fan_throttle_tolerance_ac;
+ unsigned char fan_throttle_tolerance_dc;
+ unsigned char forced_throttle_ac;
+ unsigned char forced_throttle_dc;
+} nt_user_power_policy;
+
+
+typedef struct _nt_processor_power_information {
+ uint32_t number;
+ uint32_t max_mhz;
+ uint32_t current_mhz;
+ uint32_t mhz_limit;
+ uint32_t max_idle_state;
+ uint32_t current_idle_state;
+} nt_processor_power_information;
+
+
+typedef struct _nt_plug_play_notification_header {
+ uint16_t version;
+ uint16_t size;
+ nt_guid event;
+} nt_plug_play_notification_header;
+
+
+/* ZwRequestWakeupLatency: no longer present */
+typedef int32_t __stdcall ntapi_zw_request_wakeup_latency(
+ __in nt_latency_time latency);
+
+
+/* ZwRequestDeviceWakeup: no longer present */
+typedef int32_t __stdcall ntapi_zw_request_device_wakeup(
+ __in void * hdevice);
+
+
+/* ZwCancelDeviceWakeupRequest: no longer present */
+typedef int32_t __stdcall ntapi_zw_cancel_device_wakeup_request(
+ __in void * hdevice);
+
+
+typedef int32_t __stdcall ntapi_zw_is_system_resume_automatic(void);
+
+
+typedef int32_t __stdcall ntapi_zw_set_thread_execution_state(
+ __in uint32_t execution_state,
+ __out uint32_t * prev_execution_state);
+
+
+typedef int32_t __stdcall ntapi_zw_get_device_power_state(
+ __in void * hdevice,
+ __out nt_device_power_state * device_power_state);
+
+
+typedef int32_t __stdcall ntapi_zw_set_system_power_state(
+ __in nt_power_action system_action,
+ __in nt_system_power_state min_system_state,
+ __in uint32_t system_power_state_flags);
+
+
+typedef int32_t __stdcall ntapi_zw_initiate_power_action(
+ __in nt_power_action system_action,
+ __in nt_system_power_state min_system_statem,
+ __in uint32_t system_power_state_flags,
+ __in unsigned char async);
+
+typedef int32_t __stdcall ntapi_zw_power_information(
+ __in nt_power_info_level power_info_level,
+ __in void * input_buffer __optional,
+ __in uint32_t input_buffer_length,
+ __out void * output_buffer __optional,
+ __in uint32_t output_buffer_length);
+
+
+typedef int32_t __stdcall ntapi_zw_plug_play_control(
+ __in uint32_t pnp_control_code,
+ __in_out void * buffer,
+ __in uint32_t buffer_length);
+
+typedef int32_t __stdcall ntapi_zw_get_plug_play_event(
+ __in uint32_t reserved_1st,
+ __in uint32_t reserved_2nd,
+ __out void * buffer,
+ __in uint32_t buffer_length);
+
+#endif
diff --git a/include/ntapi/nt_port.h b/include/ntapi/nt_port.h
new file mode 100644
index 0000000..beb4f32
--- /dev/null
+++ b/include/ntapi/nt_port.h
@@ -0,0 +1,332 @@
+#ifndef _NT_PORT_H_
+#define _NT_PORT_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+#include "nt_process.h"
+
+typedef enum _nt_lpc_type {
+ NT_LPC_NEW_MESSAGE = 0,
+ NT_LPC_REQUEST = 1,
+ NT_LPC_REPLY = 2,
+ NT_LPC_DATAGRAM = 3,
+ NT_LPC_LOST_REPLY = 4,
+ NT_LPC_PORT_CLOSED = 5,
+ NT_LPC_CLIENT_DIED = 6,
+ NT_LPC_EXCEPTION = 7,
+ NT_LPC_DEBUG_EVENT = 8,
+ NT_LPC_ERROR_EVENT = 9,
+ NT_LPC_CONNECTION_REQUEST = 10,
+ NT_ALPC_REQUEST = 0x2000 | NT_LPC_REQUEST,
+ NT_ALPC_CONNECTION_REQUEST = 0x2000 | NT_LPC_CONNECTION_REQUEST,
+} nt_lpc_type;
+
+
+typedef enum _nt_port_info_class {
+ NT_PORT_BASIC_INFORMATION
+} nt_port_info_class;
+
+
+/* friendly port types */
+typedef enum _nt_port_type {
+ NT_PORT_TYPE_DEFAULT, /* {'s','v','c','a','n','y'} */
+ NT_PORT_TYPE_SUBSYSTEM, /* {'n','t','c','t','t','y'} */
+ NT_PORT_TYPE_VMOUNT, /* {'v','m','o','u','n','t'} */
+ NT_PORT_TYPE_DAEMON, /* {'d','a','e','m','o','n'} */
+ NT_PORT_TYPE_CAP
+} nt_port_type;
+
+
+typedef enum _nt_port_subtype {
+ NT_PORT_SUBTYPE_DEFAULT,
+ NT_PORT_SUBTYPE_PRIVATE,
+ NT_PORT_SUBTYPE_CAP
+} nt_port_subtype;
+
+
+/* friendly port guids */
+#define NT_PORT_GUID_DEFAULT {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+#define NT_PORT_GUID_SUBSYSTEM {0xce7f8d40,0x81cd,0x41c6,{0xa4,0xb7,0xb8,0x35,0x67,0xdf,0x15,0xd9}}
+#define NT_PORT_GUID_VMOUNT {0x893d63d2,0x23e8,0x4caa,{0xa8,0x41,0x7f,0x6e,0x77,0x6b,0xd5,0x70}}
+#define NT_PORT_GUID_DAEMON {0xcf765d9e,0x6bd8,0x4a8d,{0x8a,0x21,0x17,0x34,0xcd,0x3a,0x8d,0xa7}}
+
+/* lpc messages */
+#define NT_LPC_REFUSE_CONNECTION 0x0000
+#define NT_LPC_ACCEPT_CONNECTION 0x0001
+#define NT_LPC_MAX_MSG_DATA_SIZE 0x0104
+
+
+typedef struct _nt_port_basic_information {
+ void * dummy_invalid;
+} nt_port_basic_information;
+
+
+typedef struct _nt_port_message {
+ uint16_t data_size;
+ uint16_t msg_size;
+ uint16_t msg_type;
+ uint16_t virtual_ranges_offset;
+ nt_client_id client_id;
+ uint32_t msg_id;
+ size_t section_size;
+} nt_port_message;
+
+
+/* csrss port message structure: new process, first thread */
+typedef struct _nt_port_message_csrss_process {
+ nt_port_message header;
+ uintptr_t unknown_1st;
+ uint32_t opcode;
+ int32_t status;
+ uintptr_t unknown_2nd;
+ void * hprocess;
+ void * hthread;
+ uintptr_t unique_process_id;
+ uintptr_t unique_thread_id;
+ void * reserved[8];
+} nt_port_message_csrss_process;
+
+/* csrss port message structure: existing process, new thread */
+typedef struct _nt_port_message_csrss_thread {
+ nt_port_message header;
+ uintptr_t unknown_1st;
+ uint32_t opcode;
+ int32_t status;
+ uintptr_t unknown_2nd;
+ void * hthread;
+ uintptr_t unique_process_id;
+ uintptr_t unique_thread_id;
+ void * reserved[8];
+} nt_port_message_csrss_thread;
+
+
+typedef struct _nt_port_section_write {
+ uint32_t length;
+ void * hsection;
+ uint32_t offset;
+ size_t view_size;
+ void * view_base;
+ void * target_vew_base;
+} nt_port_section_write;
+
+
+typedef struct _nt_port_section_read {
+ uint32_t length;
+ size_t view_size;
+ void * view_base;
+} nt_port_section_read;
+
+
+/* attributes of a friendly port */
+typedef struct _nt_port_keys {
+ uint32_t reserved;
+ uint32_t key[6];
+ uint32_t padding;
+} nt_port_keys;
+
+typedef struct _nt_port_attr {
+ nt_guid guid;
+ nt_port_type type;
+ nt_port_subtype subtype;
+ int32_t ver_major;
+ int32_t ver_minor;
+ uint32_t options;
+ uint32_t flags;
+ nt_port_keys keys;
+} nt_port_attr;
+
+
+/* guid component of a friendly port name */
+typedef struct _nt_port_guid {
+ wchar16_t uscore_guid;
+ wchar16_t port_guid[36];
+ wchar16_t uscore_keys;
+} nt_port_guid;
+
+/* keys component of a friendly port name */
+typedef struct _nt_port_name_keys {
+ wchar16_t key_1st[8];
+ wchar16_t uscore_1st;
+ wchar16_t key_2nd[8];
+ wchar16_t uscore_2nd;
+ wchar16_t key_3rd[8];
+ wchar16_t uscore_3rd;
+ wchar16_t key_4th[8];
+ wchar16_t uscore_4th;
+ wchar16_t key_5th[8];
+ wchar16_t uscore_5th;
+ wchar16_t key_6th[8];
+} nt_port_name_keys;
+
+
+/* friendly port name */
+typedef struct _nt_port_name {
+ wchar16_t base_named_objects[17];
+ wchar16_t backslash;
+ wchar16_t svc_prefix[6];
+ nt_port_guid port_guid;
+ nt_port_name_keys port_name_keys;
+ wchar16_t null_termination;
+} nt_port_name;
+
+
+typedef int32_t __stdcall ntapi_zw_create_port(
+ __out void ** hport,
+ __in nt_object_attributes * obj_attr,
+ __out uint32_t max_data_size,
+ __out uint32_t max_msg_size,
+ __in_out uint32_t reserved);
+
+
+typedef int32_t __stdcall ntapi_zw_create_waitable_port(
+ __out void ** hport,
+ __in nt_object_attributes * obj_attr,
+ __out uint32_t max_data_size,
+ __out uint32_t max_msg_size,
+ __in_out uint32_t reserved);
+
+
+typedef int32_t __stdcall ntapi_zw_connect_port(
+ __out void ** hport,
+ __in nt_unicode_string * port_name,
+ __in nt_security_quality_of_service * sec_qos,
+ __in_out nt_port_section_write * write_section __optional,
+ __in_out nt_port_section_read * read_section __optional,
+ __out uint32_t * max_msg_size __optional,
+ __in_out void * msg_data __optional,
+ __in_out uint32_t * msg_data_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_secure_connect_port(
+ __out void ** hport,
+ __in nt_unicode_string * port_name,
+ __in nt_security_quality_of_service * sec_qos,
+ __in_out nt_port_section_write * write_section __optional,
+ __in nt_sid * server_dis __optional,
+ __in_out nt_port_section_read * read_section __optional,
+ __out uint32_t * max_msg_size __optional,
+ __in_out void * msg_data __optional,
+ __in_out uint32_t * msg_data_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_listen_port(
+ __in void * hport,
+ __in nt_port_message * port_message);
+
+
+typedef int32_t __stdcall ntapi_zw_accept_connect_port(
+ __out void ** hport,
+ __in intptr_t port_id,
+ __in nt_port_message * port_message,
+ __in int32_t response,
+ __out nt_port_section_write * write_section __optional,
+ __out nt_port_section_read * read_section __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_complete_connect_port(
+ __in void * hport);
+
+
+typedef int32_t __stdcall ntapi_zw_request_port(
+ __in void * hport,
+ __in void * request_msg);
+
+
+typedef int32_t __stdcall ntapi_zw_request_wait_reply_port(
+ __in void * hport,
+ __in void * request_msg,
+ __out void * reply_msg);
+
+
+typedef int32_t __stdcall ntapi_zw_reply_port(
+ __in void * hport,
+ __in nt_port_message * reply_message);
+
+
+typedef int32_t __stdcall ntapi_zw_reply_wait_reply_port(
+ __in void * hport,
+ __in_out nt_port_message * reply_message);
+
+
+typedef int32_t __stdcall ntapi_zw_reply_wait_receive_port(
+ __in void * hport,
+ __out intptr_t * port_id __optional,
+ __in nt_port_message * reply_message __optional,
+ __out nt_port_message * receive_message);
+
+
+typedef int32_t __stdcall ntapi_zw_reply_wait_receive_port_ex(
+ __in void * hport,
+ __out intptr_t * port_id __optional,
+ __in nt_port_message * reply_message __optional,
+ __out nt_port_message * receive_message,
+ __in nt_large_integer * timeout);
+
+typedef int32_t __stdcall ntapi_zw_read_request_data(
+ __in void * hport,
+ __in nt_port_message * message,
+ __in uint32_t index,
+ __out void * buffer,
+ __in size_t buffer_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_write_request_data(
+ __in void * hport,
+ __in nt_port_message * message,
+ __in uint32_t index,
+ __in void * buffer,
+ __in size_t buffer_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_query_information_port(
+ __in void * hport,
+ __in nt_port_info_class port_info_class,
+ __out void * port_info,
+ __in size_t port_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_impersonate_client_of_port(
+ __in void * hport,
+ __in nt_port_message * message);
+
+
+typedef int32_t __stdcall ntapi_csr_client_call_server(
+ __in void * msg_csrss,
+ __in void * msg_unknown,
+ __in uint32_t msg_opcode,
+ __in uint32_t msg_size);
+
+
+typedef void * __cdecl ntapi_csr_port_handle(int32_t * pstatus);
+
+
+/* extensions */
+typedef int32_t __stdcall ntapi_tt_port_guid_from_type(
+ __out nt_guid * guid,
+ __in nt_port_type type,
+ __in nt_port_subtype subtype);
+
+
+typedef int32_t __stdcall ntapi_tt_port_type_from_guid(
+ __out nt_port_type * type,
+ __out nt_port_subtype * subtype,
+ __in nt_guid * guid);
+
+
+typedef int32_t __stdcall ntapi_tt_port_generate_keys(
+ __out nt_port_keys * keys);
+
+
+typedef void __stdcall ntapi_tt_port_format_keys(
+ __in nt_port_keys * keys,
+ __out nt_port_name_keys * name_keys);
+
+
+typedef void __stdcall ntapi_tt_port_name_from_attributes(
+ __out nt_port_name * name,
+ __in nt_port_attr * attr);
+
+#endif
diff --git a/include/ntapi/nt_process.h b/include/ntapi/nt_process.h
new file mode 100644
index 0000000..61afdb5
--- /dev/null
+++ b/include/ntapi/nt_process.h
@@ -0,0 +1,676 @@
+#ifndef _NT_PROCESS_H_
+#define _NT_PROCESS_H_
+
+#include <psxtypes/psxtypes.h>
+#include <pemagine/pemagine.h>
+#include "nt_object.h"
+#include "nt_memory.h"
+#include "nt_section.h"
+
+typedef enum _nt_process_info_class {
+ NT_PROCESS_BASIC_INFORMATION,
+ NT_PROCESS_QUOTA_LIMITS,
+ NT_PROCESS_IO_COUNTERS,
+ NT_PROCESS_VM_COUNTERS,
+ NT_PROCESS_TIMES,
+ NT_PROCESS_BASE_PRIORITY,
+ NT_PROCESS_RAISE_PRIORITY,
+ NT_PROCESS_DEBUG_PORT,
+ NT_PROCESS_EXCEPTION_PORT,
+ NT_PROCESS_ACCESS_TOKEN,
+ NT_PROCESS_LDT_INFORMATION,
+ NT_PROCESS_LDT_SIZE,
+ NT_PROCESS_DEFAULT_HARD_ERROR_MODE,
+ NT_PROCESS_IO_PORT_HANDLERS,
+ NT_PROCESS_POOLED_USAGE_AND_LIMITS,
+ NT_PROCESS_WORKING_SET_WATCH,
+ NT_PROCESS_USER_MODE_IOPL,
+ NT_PROCESS_ENABLE_ALIGNMENT_FAULT_FIXUP,
+ NT_PROCESS_PRIORITY_CLASS,
+ NT_PROCESS_WX86_INFORMATION,
+ NT_PROCESS_HANDLE_COUNT,
+ NT_PROCESS_AFFINITY_MASK,
+ NT_PROCESS_PRIORITY_BOOST,
+ NT_PROCESS_DEVICE_MAP,
+ NT_PROCESS_SESSION_INFORMATION,
+ NT_PROCESS_FOREGROUND_INFORMATION,
+ NT_PROCESS_WOW64_INFORMATION,
+ NT_PROCESS_IMAGE_FILE_NAME
+} nt_process_info_class;
+
+
+typedef enum _nt_process_create_info_class {
+ NT_PROCESS_CREATE_INITIAL_STATE,
+ NT_PROCESS_CREATE_FAIL_ON_FILE_OPEN,
+ NT_PROCESS_CREATE_FAIL_ON_SECTION_CREATE,
+ NT_PROCESS_CREATE_FAIL_EXE_FORMAT,
+ NT_PROCESS_CREATE_FAIL_MACHINE_MISMATCH,
+ NT_PROCESS_CREATE_FAIL_EXE_NAME,
+ NT_PROCESS_CREATE_SUCCESS,
+ NT_PROCESS_CREATE_MAXIMUM_STATES,
+} nt_process_create_info_class;
+
+
+
+/* special handles */
+#define NT_CURRENT_PROCESS_HANDLE (void *)(uintptr_t)-1
+
+
+/* process access bits */
+#define NT_PROCESS_CREATE_PROCESS 0x00000080U
+#define NT_PROCESS_CREATE_THREAD 0x00000002U
+#define NT_PROCESS_DUP_HANDLE 0x00000040U
+#define NT_PROCESS_QUERY_INFORMATION 0x00000400U
+#define NT_PROCESS_SET_INFORMATION 0x00000200U
+#define NT_PROCESS_SET_QUOTA 0x00000100U
+#define NT_PROCESS_SUSPEND_RESUME 0x00000800U
+#define NT_PROCESS_TERMINATE 0x00000001U
+#define NT_PROCESS_VM_OPERATION 0x00000008U
+#define NT_PROCESS_VM_READ 0x00000010U
+#define NT_PROCESS_VM_WRITE 0x00000020U
+#define NT_PROCESS_SYNCHRONIZE 0x00100000U
+#define NT_PROCESS_PRESERVE_AUTHZ_LEVEL 0x02000000U
+#define NT_PROCESS_ALL_ACCESS NT_PROCESS_CREATE_PROCESS \
+ | NT_PROCESS_CREATE_THREAD \
+ | NT_PROCESS_DUP_HANDLE \
+ | NT_PROCESS_QUERY_INFORMATION \
+ | NT_PROCESS_SET_INFORMATION \
+ | NT_PROCESS_SET_QUOTA \
+ | NT_PROCESS_SUSPEND_RESUME \
+ | NT_PROCESS_TERMINATE \
+ | NT_PROCESS_VM_OPERATION \
+ | NT_PROCESS_VM_READ \
+ | NT_PROCESS_VM_WRITE \
+ | NT_PROCESS_SYNCHRONIZE
+
+
+
+/* set error mode */
+#define NT_SEM_FAIL_CRITICAL_ERRORS 0x0001
+#define NT_SEM_NO_GP_FAULT_ERROR_BOX 0x0002
+#define NT_SEM_NO_ALIGNMENT_FAULT_EXCEPT 0x0004
+#define NT_SEM_NO_OPEN_FILE_ERROR_BOX 0x8000
+
+
+/* process priority class (information class) */
+#define NT_PC_IDLE 0x00
+#define NT_PC_NORMAL 0x02
+#define NT_PC_HIGH 0x03
+#define NT_PC_REALTIME 0x04
+#define NT_PC_BELOW_NORMAL 0x05
+#define NT_PC_ABOVE_NORMAL 0x05
+
+
+/* process device map drive type */
+#define NT_DRIVE_UNKNOWN 0x00
+#define NT_NO_ROOT_DIR 0x01
+#define NT_DRIVE_REMOVABLE 0x02
+#define NT_DRIVE_FIXED 0x03
+#define NT_DRIVE_REMOTE 0x04
+#define NT_DRIVE_CDROM 0x05
+#define NT_DRIVE_RAMDISK 0x06
+
+
+/* process debug info class mask */
+#define NT_PDI_MODULES 0x0001
+#define NT_PDI_BACKTRACE 0x0002
+#define NT_PDI_HEAPS 0x0004
+#define NT_PDI_HEAP_TAGS 0x0008
+#define NT_PDI_HEAP_BLOCKS 0x0010
+#define NT_PDI_LOCKS 0x0020
+
+
+/* process debug module information flags */
+#define NT_LDRP_STATIC_LINK 0x00000002
+#define NT_LDRP_IMAGE_DLL 0x00000004
+#define NT_LDRP_LOAD_IN_PROGRESS 0x00001000
+#define NT_LDRP_UNLOAD_IN_PROGRESS 0x00002000
+#define NT_LDRP_ENTRY_PROCESSED 0x00004000
+#define NT_LDRP_ENTRY_INSERTED 0x00008000
+#define NT_LDRP_CURRENT_LOAD 0x00010000
+#define NT_LDRP_FAILED_BUILTIN_LOAD 0x00020000
+#define NT_LDRP_DONT_CALL_FOR_THREADS 0x00040000
+#define NT_LDRP_PROCESS_ATTACH_CALLED 0x00080000
+#define NT_LDRP_DEBUG_SYMBOLS_LOADED 0x00100000
+#define NT_LDRP_IMAGE_NOT_AT_BASE 0x00200000
+#define NT_LDRP_WX86_IGNORE_MACHINETYPE 0x00400000
+
+
+/* create process info bits */
+#define NT_PROCESS_CREATE_INFO_WRITE_OUTPUT 0x00000001
+#define NT_PROCESS_CREATE_INFO_OBTAIN_OUTPUT 0x20000003
+
+/* zw_create_user_process: creation flags */
+#define NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED (0x00000001)
+#define NT_PROCESS_CREATE_FLAGS_RESET_DEBUG_PORT (0x00000002)
+#define NT_PROCESS_CREATE_FLAGS_INHERIT_HANDLES (0x00000004)
+#define NT_PROCESS_CREATE_FLAGS_NO_OBJECT_SYNC (0x00000100)
+
+/* zw_create_user_process: extended parameters */
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_FILE_NAME (0x00020005)
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_VIRTUAL_ADDR_RANGES (0x00020007)
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_BASE_PRIORITY (0x00020008)
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_HARD_ERROR_MODE (0x00020009)
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_CONSOLE_FLAGS (0x0002000A)
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_INHERITED_HANDLES (0x0002000B)
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_PARENT (0x00060000)
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_DEBUG (0x00060001)
+#define NT_CREATE_PROCESS_EXT_PARAM_SET_TOKEN (0x00060002)
+
+#define NT_CREATE_PROCESS_EXT_PARAM_GET_SECTION_IMAGE_INFO (0x00000006)
+#define NT_CREATE_PROCESS_EXT_PARAM_GET_CLIENT_ID (0x00010003)
+#define NT_CREATE_PROCESS_EXT_PARAM_GET_TEB_ADDRESS (0x00010004)
+
+
+/* zw_create_user_process: console flag bits */
+#define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_DEFAULT (0x00)
+#define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_DO_NOT_USE_HANDLES (0x00)
+#define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_INHERIT_HANDLES (0x01)
+#define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_USE_ARG_HANDLES (0x02)
+#define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_INHERIT_STDIN (0x04)
+#define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_INHERIT_STDOUT (0x08)
+#define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_INHERIT_STDERR (0x10)
+
+/* nt_runtime_data_block flag bits */
+#define NT_RUNTIME_DATA_DUPLICATE_SESSION_HANDLES (0x01)
+
+/* tt_get_runtime_data flag bits */
+#define NT_RUNTIME_DATA_ALLOW_BUILTIN_DEFAULT (0x01)
+
+/* runtime data convenience storage */
+#define NT_RUNTIME_DATA_USER_PTRS (0x10)
+#define NT_RUNTIME_DATA_USER_INT32_SLOTS (0x10)
+#define NT_RUNTIME_DATA_USER_INT64_SLOTS (0x10)
+
+/* friendly process guids */
+#define NT_PROCESS_GUID_NTPGRP {0xfa383cc0,0xa25b,0x4448,{0x83,0x45,0x51,0x45,0x4d,0xa8,0x2f,0x30}}
+#define NT_PROCESS_GUID_PIDMAP {0xba054c90,0x8b4f,0x4989,{0xa0,0x52,0x32,0xce,0x41,0x9e,0xbf,0x97}}
+#define NT_PROCESS_GUID_PIDANY {0x431bf6a6,0x65c4,0x4eb0,{0x88,0xca,0x16,0xfe,0xc0,0x18,0xc8,0xb7}}
+
+/* friendly process object directory prefixes */
+#define NT_PROCESS_OBJDIR_PREFIX_NTPGRP {'n','t','p','g','r','p'}
+#define NT_PROCESS_OBJDIR_PREFIX_PIDMAP {'p','i','d','m','a','p'}
+#define NT_PROCESS_OBJDIR_PREFIX_PIDANY {'p','i','d','a','n','y'}
+
+typedef struct _nt_process_information {
+ void * hprocess;
+ void * hthread;
+ uintptr_t process_id;
+ uintptr_t thread_id;
+} nt_process_information, nt_process_info;
+
+
+typedef struct _nt_process_parameters {
+ uint32_t alloc_size;
+ uint32_t used_size;
+ uint32_t flags;
+ uint32_t reserved;
+ void * hconsole;
+ uintptr_t console_flags;
+ void * hstdin;
+ void * hstdout;
+ void * hstderr;
+ nt_unicode_string cwd_name;
+ void * cwd_handle;
+ nt_unicode_string __attr_ptr_size_aligned__ dll_path;
+ nt_unicode_string __attr_ptr_size_aligned__ image_file_name;
+ nt_unicode_string __attr_ptr_size_aligned__ command_line;
+ wchar16_t * environment;
+ uint32_t dwx;
+ uint32_t dwy;
+ uint32_t dwx_size;
+ uint32_t dwy_size;
+ uint32_t dwx_count_chars;
+ uint32_t dwy_count_chars;
+ uint32_t dw_fill_attribute;
+ uint32_t dw_flags;
+ uint32_t wnd_show;
+ nt_unicode_string wnd_title;
+ nt_unicode_string __attr_ptr_size_aligned__ desktop;
+ nt_unicode_string __attr_ptr_size_aligned__ shell_info;
+ nt_unicode_string __attr_ptr_size_aligned__ runtime_data;
+} nt_process_parameters;
+
+
+typedef struct _nt_peb {
+ unsigned char reserved_1st[2];
+ unsigned char debugged;
+ unsigned char reserved_2nd[1];
+ void * reserved_3rd[2];
+ struct pe_peb_ldr_data* peb_ldr_data;
+ nt_process_parameters * process_params;
+ unsigned char reserved_4th[104];
+ void * reserved_5th[52];
+ void * post_process_init_routine;
+ unsigned char reserved_6th[128];
+ void * reserved_7th[1];
+ uint32_t session_id;
+} nt_peb;
+
+
+typedef struct _nt_process_basic_information {
+ int32_t exit_status;
+ nt_peb * peb_base_address;
+ intptr_t affinity_mask;
+ uint32_t base_priority;
+ uintptr_t unique_process_id;
+ uintptr_t inherited_from_unique_process_id;
+} nt_process_basic_information, nt_pbi;
+
+
+typedef struct _nt_process_access_token {
+ void * token;
+ void * thread;
+} nt_process_access_token;
+
+
+typedef struct _nt_process_ws_watch_information {
+ void * faulting_pc;
+ void * faulting_va;
+} nt_process_ws_watch_information;
+
+
+typedef struct _nt_process_priority_class {
+ int32_t foreground;
+ uint32_t priority;
+} nt_process_priority_class;
+
+
+typedef struct _nt_process_device_map_information {
+ union {
+ struct {
+ void * directory_handle;
+ } set;
+
+ struct {
+ uint32_t drive_map;
+ unsigned char drive_type[32];
+ } query;
+ };
+} nt_process_device_map_information;
+
+
+typedef struct _nt_debug_buffer {
+ void * hsection;
+ void * section_base;
+ void * remote_section_base;
+ size_t section_base_delta;
+ void * hevent_pair;
+ void * unknown[2];
+ void * hthread_remote;
+ uint32_t info_class_mask;
+ size_t info_size;
+ size_t allocated_size;
+ size_t section_size;
+ void * module_information;
+ void * back_trace_information;
+ void * heap_information;
+ void * lock_information;
+ void * reserved[8];
+} nt_debug_buffer;
+
+
+typedef struct _nt_debug_module_information {
+ void * reserved[2];
+ size_t base;
+ size_t size;
+ uint32_t flags;
+ uint16_t index;
+ uint16_t unknown;
+ uint16_t load_count;
+ uint16_t module_name_offset;
+ char image_name[256];
+} nt_debug_module_information;
+
+
+typedef struct _nt_debug_heap_information {
+ size_t base;
+ uint32_t flags;
+ uint16_t granularity;
+ uint16_t unknown;
+ size_t allocated;
+ size_t committed;
+ uint32_t tag_count;
+ uint32_t block_count;
+ void * reserved[7];
+ void * tags;
+ void * blocks;
+} nt_debug_heap_information;
+
+
+typedef struct _nt_debug_lock_information {
+ void * address;
+ uint16_t type;
+ uint16_t creator_back_trace_index;
+ uintptr_t owner_thread_id;
+ uint32_t active_count;
+ uint32_t contention_count;
+ uint32_t entry_count;
+ uint32_t recursion_count;
+ uint32_t number_of_share_waiters;
+ uint32_t number_of_exclusive_waiters;
+} nt_debug_lock_information;
+
+
+typedef struct _nt_executable_image {
+ void * hfile;
+ void * hsection;
+ void * addr;
+ size_t size;
+ uint16_t characteristics;
+ uint16_t magic;
+ uint16_t subsystem;
+ uint16_t uflags;
+} nt_executable_image;
+
+
+typedef struct _nt_process_session_information {
+ uintptr_t session_id;
+} nt_process_session_information;
+
+
+typedef struct _nt_create_process_info {
+ size_t size;
+ size_t state;
+
+ union {
+ struct {
+ uint32_t init_flags;
+ uint32_t file_access_ext;
+ uintptr_t unused[8];
+ } init_state;
+
+ struct {
+ uintptr_t output_flags;
+ void * hfile;
+ void * hsection;
+ uint64_t unknown[6];
+ } success_state;
+ };
+} nt_create_process_info;
+
+
+typedef struct _nt_create_process_ext_param {
+ size_t ext_param_type;
+ size_t ext_param_size;
+
+ union {
+ uint32_t ext_param_value;
+ void * ext_param_addr;
+ };
+
+ size_t ext_param_returned_length;
+} nt_create_process_ext_param;
+
+
+typedef struct _nt_create_process_ext_params {
+ size_t ext_params_size;
+ nt_create_process_ext_param ext_param[];
+} nt_create_process_ext_params;
+
+
+typedef struct _nt_user_process_info {
+ uint32_t size;
+ void * hprocess;
+ void * hthread;
+ nt_cid cid;
+ nt_section_image_information sec_image_info;
+} nt_user_process_info;
+
+
+typedef struct _nt_process_alternate_client_id {
+ void * hpgrp;
+ void * hentry;
+ void * hsession;
+ void * hdaemon;
+ void * htarget;
+ void * hevent;
+ int32_t tid;
+ int32_t pid;
+ int32_t pgid;
+ int32_t sid;
+ uintptr_t reserved[8];
+} nt_process_alternate_client_id, nt_alt_cid;
+
+typedef struct _nt_runtime_data {
+ void * hprocess_self;
+ void * hprocess_parent;
+ nt_cid cid_self;
+ nt_cid cid_parent;
+ nt_alt_cid alt_cid_self;
+ nt_alt_cid alt_cid_parent;
+ void * himage;
+ void * hroot;
+ void * hcwd;
+ void * hdrive;
+ void * hstdin;
+ void * hstdout;
+ void * hstderr;
+ void * hjob;
+ void * hsession;
+ void * hdebug;
+ void * hlog;
+ void * hready;
+ void * srv_ready;
+ nt_guid srv_guid;
+ int32_t srv_type;
+ int32_t srv_subtype;
+ uint32_t srv_keys[6];
+ int32_t stdin_type;
+ int32_t stdout_type;
+ int32_t stderr_type;
+ int32_t session_type;
+ uint32_t dbg_type;
+ uint32_t log_type;
+ void * ctx_hsection;
+ void * ctx_addr;
+ size_t ctx_size;
+ size_t ctx_commit;
+ ptrdiff_t ctx_offset;
+ size_t ctx_counter;
+ size_t ctx_meta_size;
+ size_t ctx_buffer_size;
+ uint32_t ctx_options;
+ uint32_t ctx_flags;
+ uint32_t meta_hash;
+ uint32_t block_hash;
+ size_t stack_reserve;
+ size_t stack_commit;
+ size_t heap_reserve;
+ size_t heap_commit;
+ int32_t envc;
+ int32_t argc;
+ char ** argv;
+ char ** envp;
+ wchar16_t ** wargv;
+ wchar16_t ** wenvp;
+ int32_t peb_envc;
+ int32_t peb_argc;
+ wchar16_t ** peb_wargv;
+ wchar16_t ** peb_wenvp;
+ void * uptr [NT_RUNTIME_DATA_USER_PTRS];
+ void * uclose[NT_RUNTIME_DATA_USER_PTRS];
+ int32_t udat32[NT_RUNTIME_DATA_USER_INT32_SLOTS];
+ int64_t udat64[NT_RUNTIME_DATA_USER_INT64_SLOTS];
+ uintptr_t buffer[];
+} nt_runtime_data, nt_rtdata;
+
+
+typedef struct _nt_runtime_data_block {
+ void * addr;
+ size_t size;
+ void * remote_addr;
+ size_t remote_size;
+ int32_t flags;
+} nt_runtime_data_block;
+
+
+typedef struct _nt_create_process_params {
+ __out void * hprocess;
+ __out void * hthread;
+ __out nt_client_id cid;
+ __out nt_process_basic_information pbi;
+ __in void * himage;
+ __in wchar16_t * image_name;
+ __in wchar16_t * cmd_line;
+ __in wchar16_t * environment;
+ __in nt_runtime_data_block * rtblock;
+ __in uint32_t desired_access_process;
+ __in uint32_t desired_access_thread;
+ __in nt_object_attributes * obj_attr_process;
+ __in nt_object_attributes * obj_attr_thread;
+ __in uint32_t creation_flags_process;
+ __in uint32_t creation_flags_thread;
+ __in nt_process_parameters * process_params;
+ __in_out nt_create_process_info * create_process_info;
+ __in nt_create_process_ext_params * create_process_ext_params;
+ __in_out uintptr_t * buffer;
+ __in size_t buflen;
+} nt_create_process_params;
+
+
+typedef int32_t __stdcall ntapi_zw_create_process(
+ __out void ** hprocess,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in void * hinherit_from_process,
+ __in unsigned char inherit_handles,
+ __in void * hsection __optional,
+ __in void * hdebug_port __optional,
+ __in void * hexception_port __optional);
+
+
+/* zw_create_user_process: newer OS versions only */
+typedef int32_t __stdcall ntapi_zw_create_user_process(
+ __out void ** hprocess,
+ __out void ** hthread,
+ __in uint32_t desired_access_process,
+ __in uint32_t desired_access_thread,
+ __in nt_object_attributes * obj_attr_process __optional,
+ __in nt_object_attributes * obj_attr_thread __optional,
+ __in uint32_t creation_flags_process,
+ __in uint32_t creation_flags_thread,
+ __in nt_process_parameters * process_params __optional,
+ __in_out nt_create_process_info * create_process_info,
+ __in nt_create_process_ext_params * create_process_ext_params);
+
+
+typedef int32_t __stdcall ntapi_zw_open_process(
+ __out void ** hprocess,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in nt_client_id * cid __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_terminate_process(
+ __in void * hprocess __optional,
+ __in int32_t status);
+
+
+typedef int32_t __stdcall ntapi_zw_query_information_process(
+ __in void * hprocess,
+ __in nt_process_info_class process_info_class,
+ __out void * process_info,
+ __in size_t process_info_length,
+ __out uint32_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_set_information_process(
+ __in void * hprocess,
+ __in nt_process_info_class process_info_class,
+ __in void * process_info,
+ __in uint32_t process_info_length);
+
+
+typedef int32_t __stdcall ntapi_zw_flush_instruction_cache(
+ __in void * hprocess,
+ __in void * base_addr __optional,
+ __in size_t flush_size);
+
+
+typedef int32_t __stdcall ntapi_rtl_create_process_parameters(
+ __out nt_process_parameters ** process_params,
+ __in nt_unicode_string * image_file,
+ __in nt_unicode_string * dll_path __optional,
+ __in nt_unicode_string * current_directory __optional,
+ __in nt_unicode_string * command_line __optional,
+ __in wchar16_t * environment __optional,
+ __in nt_unicode_string * window_title __optional,
+ __in nt_unicode_string * desktop_info __optional,
+ __in nt_unicode_string * shell_info __optional,
+ __in nt_unicode_string * runtime_info __optional);
+
+
+typedef void * __stdcall ntapi_rtl_normalize_process_params(
+ __in nt_process_parameters * process_params);
+
+
+typedef int32_t __stdcall ntapi_rtl_destroy_process_parameters(
+ __in nt_process_parameters * process_params);
+
+
+typedef nt_debug_buffer * __stdcall ntapi_rtl_create_query_debug_buffer(
+ __in size_t size,
+ __in int32_t event_pair);
+
+
+typedef int32_t __stdcall ntapi_rtl_destroy_query_debug_buffer(
+ __in nt_debug_buffer * debug_buffer);
+
+
+typedef int32_t __stdcall ntapi_rtl_query_process_debug_information(
+ __in uintptr_t process_id,
+ __in uint32_t debug_info_class_mask,
+ __in_out nt_debug_buffer * debug_buffer);
+
+
+typedef int32_t __stdcall ntapi_rtl_clone_user_process(
+ __in uint32_t process_flags,
+ __in nt_sd * process_sec_desc __optional,
+ __in nt_sd * thread_sec_desc __optional,
+ __in void * hport_debug __optional,
+ __out nt_user_process_info * process_info);
+
+
+/* extensions */
+typedef intptr_t __fastcall ntapi_tt_fork(
+ __out void ** hprocess,
+ __out void ** hthread);
+
+
+typedef int32_t __stdcall ntapi_tt_create_remote_process_params(
+ __in void * hprocess,
+ __out nt_process_parameters ** rprocess_params,
+ __in nt_unicode_string * image_file,
+ __in nt_unicode_string * dll_path __optional,
+ __in nt_unicode_string * current_directory __optional,
+ __in nt_unicode_string * command_line __optional,
+ __in wchar16_t * environment __optional,
+ __in nt_unicode_string * window_title __optional,
+ __in nt_unicode_string * desktop_info __optional,
+ __in nt_unicode_string * shell_info __optional,
+ __in nt_unicode_string * runtime_data __optional);
+
+
+typedef int32_t __stdcall ntapi_tt_create_native_process(
+ __out nt_create_process_params * params);
+
+
+typedef int32_t __stdcall ntapi_tt_get_runtime_data(
+ __out nt_runtime_data ** pdata,
+ __in wchar16_t ** argv);
+
+typedef int32_t __stdcall ntapi_tt_init_runtime_data(
+ __in_out nt_runtime_data * rtdata);
+
+typedef int32_t __stdcall ntapi_tt_update_runtime_data(
+ __in_out nt_runtime_data * rtdata);
+
+typedef int32_t __stdcall ntapi_tt_exec_map_image_as_data(
+ __in_out nt_executable_image * image);
+
+
+typedef int32_t __stdcall ntapi_tt_exec_unmap_image(
+ __in nt_executable_image * image);
+
+#endif
diff --git a/include/ntapi/nt_profiling.h b/include/ntapi/nt_profiling.h
new file mode 100644
index 0000000..4c11909
--- /dev/null
+++ b/include/ntapi/nt_profiling.h
@@ -0,0 +1,41 @@
+#ifndef _NT_PROFILING_H_
+#define _NT_PROFILING_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_kprofile_source {
+ NT_PROFILE_TIME
+} nt_kprofile_source;
+
+
+typedef int32_t __stdcall ntapi_zw_create_profile(
+ __out void ** hprofile,
+ __in void * hprocess,
+ __in void * base,
+ __in size_t size,
+ __in uint32_t bucket_shift,
+ __in uint32_t * buffer,
+ __in size_t buffer_length,
+ __in nt_kprofile_source source,
+ __in uint32_t process_mask);
+
+
+typedef int32_t __stdcall ntapi_zw_set_interval_profile(
+ __in uint32_t interval,
+ __in nt_kprofile_source source);
+
+
+typedef int32_t __stdcall ntapi_zw_query_interval_profile(
+ __in nt_kprofile_source source,
+ __out uint32_t * interval);
+
+
+typedef int32_t __stdcall ntapi_zw_start_profile(
+ __in void * hprofile);
+
+
+typedef int32_t __stdcall ntapi_zw_stop_profile(
+ __in void * hprofile);
+
+#endif
diff --git a/include/ntapi/nt_registry.h b/include/ntapi/nt_registry.h
new file mode 100644
index 0000000..7634d8a
--- /dev/null
+++ b/include/ntapi/nt_registry.h
@@ -0,0 +1,339 @@
+#ifndef _NT_REGISTRY_H_
+#define _NT_REGISTRY_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_registry_types {
+ NT_REG_NONE = 0x00,
+ NT_REG_SZ = 0x01,
+ NT_REG_EXPAND_SZ = 0x02,
+ NT_REG_BINARY = 0x03,
+ NT_REG_DWORD = 0x04,
+ NT_REG_DWORD_LITTLE_ENDIAN = 0x04,
+ NT_REG_DWORD_BIG_ENDIAN = 0x05,
+ NT_REG_LINK = 0x06,
+ NT_REG_MULTI_SZ = 0x07,
+ NT_REG_RESOURCE_LIST = 0x08,
+ NT_REG_FULL_RESOURCE_DESCRIPTOR = 0x09,
+ NT_REG_RESOURCE_REQUIREMENTS_LIST = 0x0A,
+ NT_REG_QWORD = 0x0B,
+ NT_REG_QWORD_LITTLE_ENDIAN = 0x0B,
+} nt_registry_types;
+
+
+typedef enum _nt_key_info_class {
+ NT_KEY_BASIC_INFORMATION,
+ NT_KEY_NODE_INFORMATION,
+ NT_KEY_FULL_INFORMATION,
+ NT_KEY_NAME_INFORMATION,
+} nt_key_info_class;
+
+
+typedef enum _nt_key_value_info_class {
+ NT_KEY_VALUE_BASIC_INFORMATION,
+ NT_KEY_VALUE_FULL_INFORMATION,
+ NT_KEY_VALUE_PARTIAL_INFORMATION,
+ NT_KEY_VALUE_FULL_INFORMATION_ALIGN64,
+} nt_key_value_info_class;
+
+
+typedef enum _nt_key_set_info_class {
+ NT_KEY_LAST_WRITE_TIME_INFORMATION = 0
+} nt_key_set_info_class;
+
+
+/* registry key access bits */
+#define NT_KEY_QUERY_VALUE 0x00000001
+#define NT_KEY_SET_VALUE 0x00000002
+#define NT_KEY_CREATE_SUB_NT_KEY 0x00000004
+#define NT_KEY_ENUMERATE_SUB_NT_KEYS 0x00000008
+#define NT_KEY_NOTIFY 0x00000010
+#define NT_KEY_CREATE_LINK 0x00000020
+#define NT_KEY_WOW64_64NT_KEY 0x00000100
+#define NT_KEY_WOW64_32NT_KEY 0x00000200
+#define NT_KEY_WRITE 0x00020006
+#define NT_KEY_READ 0x00020019
+#define NT_KEY_EXECUTE 0x00020019
+#define NT_KEY_ALL_ACCESS 0x000F003F
+
+
+/* registry option bits */
+#define NT_REG_OPTION_NON_VOLATILE 0x00000000L
+#define NT_REG_OPTION_VOLATILE 0x00000001L
+#define NT_REG_OPTION_CREATE_LINK 0x00000002L
+#define NT_REG_OPTION_BACKUP_RESTORE 0x00000004L
+#define NT_REG_OPTION_OPEN_LINK 0x00000008L
+
+
+/* registry hive option bits */
+#define NT_REG_WHOLE_HIVE_VOLATILE 0x00000001L
+#define NT_REG_REFRESH_HIVE 0x00000002L
+#define NT_REG_NO_LAZY_FLUSH 0x00000004L
+#define NT_REG_FORCE_RESTORE 0x00000008L
+
+
+/* registry disposition bits */
+#define NT_REG_CREATED_NEW_KEY 0x00000000L
+#define NT_REG_OPENED_EXISTING_KEY 0x00000001L
+
+
+/* registry monitor bits */
+#define NT_REG_MONITOR_SINGLE_KEY 0x0000
+#define NT_REG_MONITOR_SECOND_KEY 0x0001
+
+
+/* registry key notification bits */
+#define NT_REG_NOTIFY_CHANGE_NAME 0x00000001L
+#define NT_REG_NOTIFY_CHANGE_ATTRIBUTES 0x00000002L
+#define NT_REG_NOTIFY_CHANGE_LAST_SET 0x00000004L
+#define NT_REG_NOTIFY_CHANGE_SECURITY 0x00000008L
+
+#define NT_REG_LEGAL_CHANGE_FILTER NT_REG_NOTIFY_CHANGE_NAME \
+ | NT_REG_NOTIFY_CHANGE_ATTRIBUTES \
+ | NT_REG_NOTIFY_CHANGE_LAST_SET \
+ | NT_REG_NOTIFY_CHANGE_SECURITY
+
+
+typedef struct _nt_key_basic_information {
+ nt_large_integer last_write_time;
+ uint32_t title_index;
+ uint32_t name_length;
+ wchar16_t name[];
+} nt_key_basic_information;
+
+
+typedef struct _nt_key_node_information {
+ nt_large_integer last_write_time;
+ uint32_t title_index;
+ uint32_t class_offset;
+ uint32_t class_length;
+ uint32_t name_length;
+ wchar16_t name[];
+} nt_key_node_information;
+
+
+typedef struct _nt_key_full_information {
+ nt_large_integer last_write_time;
+ uint32_t title_index;
+ uint32_t class_offset;
+ uint32_t class_length;
+ uint32_t sub_keys;
+ uint32_t max_name_len;
+ uint32_t max_class_len;
+ uint32_t values;
+ uint32_t max_value_name_len;
+ uint32_t max_value_data_len;
+ wchar16_t kclass[];
+} nt_key_full_information;
+
+
+typedef struct _nt_key_name_information {
+ uint32_t name_length;
+ wchar16_t name[];
+} nt_key_name_information;
+
+
+typedef struct _nt_key_value_basic_information {
+ uint32_t title_index;
+ uint32_t type;
+ uint32_t name_length;
+ wchar16_t name[];
+} _nt_key_value_basic_information;
+
+
+typedef struct _nt_key_value_full_information {
+ uint32_t title_index;
+ uint32_t type;
+ uint32_t data_offset;
+ uint32_t data_length;
+ uint32_t name_length;
+ wchar16_t name[];
+} nt_key_value_full_information;
+
+
+typedef struct _nt_key_value_partial_information {
+ uint32_t title_index;
+ uint32_t type;
+ uint32_t data_length;
+ unsigned char data[];
+} nt_key_value_partial_information;
+
+
+typedef struct _nt_key_value_entry {
+ nt_unicode_string * value_name;
+ uint32_t data_length;
+ uint32_t data_offset;
+ uint32_t type;
+} nt_key_value_entry;
+
+
+typedef struct _nt_key_last_write_time_information {
+ nt_large_integer last_write_time;
+} nt_key_last_write_time_information;
+
+
+typedef int32_t __stdcall ntapi_zw_create_key(
+ __out void ** hkey,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in uint32_t title_index,
+ __in nt_unicode_string * reg_class __optional,
+ __in uint32_t create_options,
+ __out uint32_t * disposition __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_open_key(
+ __out void ** hkey,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_delete_key(
+ __in void * hkey);
+
+
+typedef int32_t __stdcall ntapi_zw_flush_key(
+ __in void * hkey);
+
+
+typedef int32_t __stdcall ntapi_zw_save_key(
+ __in void * hkey,
+ __in void * hfile);
+
+
+typedef int32_t __stdcall ntapi_zw_save_merged_keys(
+ __in void * hkey_1st,
+ __in void * hkey_2nd,
+ __in void * hfile);
+
+
+typedef int32_t __stdcall ntapi_zw_restore_key(
+ __in void * hkey,
+ __in void * hfile,
+ __in uint32_t flags);
+
+
+typedef int32_t __stdcall ntapi_zw_load_key(
+ __in nt_object_attributes key_obj_attr,
+ __in nt_object_attributes file_obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_load_key2(
+ __in nt_object_attributes key_obj_attr,
+ __in nt_object_attributes file_obj_attr,
+ __in uint32_t flags);
+
+
+typedef int32_t __stdcall ntapi_zw_unload_key(
+ __in nt_object_attributes key_obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_query_open_sub_keys(
+ __in nt_object_attributes key_obj_attr,
+ __out uint32_t * number_of_keys);
+
+
+typedef int32_t __stdcall ntapi_zw_replace_key(
+ __in nt_object_attributes new_file_obj_attr,
+ __in void * hkey,
+ __in nt_object_attributes old_file_obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_set_information_key(
+ __in void * hkey,
+ __in nt_key_set_info_class key_info_class,
+ __in void * key_info,
+ __in uint32_t key_info_length);
+
+
+typedef int32_t __stdcall ntapi_zw_query_key(
+ __in void * hkey,
+ __in nt_key_info_class key_info_class,
+ __out void * key_info,
+ __in uint32_t key_info_length,
+ __out uint32_t * result_length);
+
+
+typedef int32_t __stdcall ntapi_zw_enumerate_key(
+ __in void * hkey,
+ __in uint32_t index,
+ __in nt_key_info_class key_info_class,
+ __out void * key_info,
+ __in uint32_t key_info_length,
+ __out uint32_t * result_length);
+
+
+typedef int32_t __stdcall ntapi_zw_notify_change_key(
+ __in void * hkey,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __in uint32_t notify_filter,
+ __in unsigned char watch_subtree,
+ __in void * buffer,
+ __in uint32_t buffer_length,
+ __in unsigned char asynchronous);
+
+
+typedef int32_t __stdcall ntapi_zw_notify_change_multiple_keys(
+ __in void * hkey,
+ __in uint32_t flags,
+ __in nt_object_attributes * key_obj_attr,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_io_status_block * io_status_block,
+ __in uint32_t notify_filter,
+ __in unsigned char watch_subtree,
+ __in void * buffer,
+ __in uint32_t buffer_length,
+ __in unsigned char asynchronous);
+
+
+typedef int32_t __stdcall ntapi_zw_delete_value_key(
+ __in void * hkey,
+ __in nt_unicode_string * value_name);
+
+
+typedef int32_t __stdcall ntapi_zw_set_value_key(
+ __in void * hkey,
+ __in nt_unicode_string * value_name,
+ __in uint32_t title_index,
+ __in uint32_t type,
+ __in void * data,
+ __in uint32_t data_size);
+
+
+typedef int32_t __stdcall ntapi_zw_query_value_key(
+ __in void * hkey,
+ __in nt_unicode_string * value_name,
+ __in nt_key_value_info_class key_value_info_class,
+ __out void * key_value_info,
+ __in uint32_t key_value_info_length,
+ __out uint32_t * result_length);
+
+
+typedef int32_t __stdcall ntapi_zw_enumerate_value_key(
+ __in void * hkey,
+ __in uint32_t index,
+ __in nt_key_value_info_class key_value_info_class,
+ __out void * key_value_info,
+ __in uint32_t key_value_info_length,
+ __out uint32_t * result_length);
+
+
+typedef int32_t __stdcall ntapi_zw_query_multiple_value_key(
+ __in void * hkey,
+ __in_out nt_key_value_entry * value_list,
+ __in uint32_t number_of_values,
+ __out void * buffer,
+ __in_out uint32_t * buffer_length,
+ __out uint32_t * buffer_nedded);
+
+
+typedef int32_t __stdcall ntapi_zw_initialize_registry(
+ __in unsigned char setup);
+
+#endif
diff --git a/include/ntapi/nt_section.h b/include/ntapi/nt_section.h
new file mode 100644
index 0000000..f1ce381
--- /dev/null
+++ b/include/ntapi/nt_section.h
@@ -0,0 +1,137 @@
+#ifndef _NT_SECTION_H_
+#define _NT_SECTION_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+#include "nt_memory.h"
+
+typedef enum _nt_section_info_class {
+ NT_SECTION_BASIC_INFORMATION,
+ NT_SECTION_IMAGE_INFORMATION
+} nt_section_info_class;
+
+
+typedef enum _nt_section_inherit {
+ NT_VIEW_SHARE = 1,
+ NT_VIEW_UNMAP = 2
+} nt_section_inherit;
+
+/* section attributes */
+#define NT_SEC_BASED 0x00200000
+#define NT_SEC_NO_CHANGE 0x00400000
+#define NT_SEC_FILE 0x00800000
+#define NT_SEC_IMAGE 0x01000000
+#define NT_SEC_VLM 0x02000000
+#define NT_SEC_RESERVE 0x04000000
+#define NT_SEC_COMMIT 0x08000000
+#define NT_SEC_NOCACHE 0x10000000
+#define NT_SEC_IMAGE_NO_EXECUTE 0x11000000
+#define NT_SEC_LARGE_PAGES 0x80000000
+#define NT_SEC_WRITECOMBINE 0x40000000
+
+/* section memory allocation attributes */
+#define NT_SEC_AT_EXTENDABLE_FILE 0x00002000 /* view may exceed section size */
+#define NT_SEC_AT_RESERVED 0x20000000 /* ignored */
+#define NT_SEC_AT_ROUND_TO_PAGE 0x40000000 /* adjust address and/or size as necessary */
+
+
+/* section access bits */
+#define NT_SECTION_QUERY 0x00000001
+#define NT_SECTION_MAP_WRITE 0x00000002
+#define NT_SECTION_MAP_READ 0x00000004
+#define NT_SECTION_MAP_EXECUTE 0x00000008
+#define NT_SECTION_EXTEND_SIZE 0x00000010
+#define NT_SECTION_MAP_EXECUTE_EXPLICIT 0x00000020
+#define NT_STANDARD_RIGHTS_REQUIRED 0x000F0000
+#define NT_SECTION_ALL_ACCESS NT_STANDARD_RIGHTS_REQUIRED \
+ | NT_SECTION_QUERY \
+ | NT_SECTION_MAP_WRITE \
+ | NT_SECTION_MAP_READ \
+ | NT_SECTION_MAP_EXECUTE \
+ | NT_SECTION_EXTEND_SIZE
+
+
+typedef struct _nt_section_basic_information {
+ void * base_address;
+ uint32_t section_attr;
+ nt_large_integer section_size;
+} nt_section_basic_information, nt_sbi;
+
+typedef struct _nt_section_image_information {
+ void * entry_point;
+ uint32_t stack_zero_bits;
+ size_t stack_reserve;
+ size_t stack_commit;
+ uint32_t subsystem;
+ uint16_t subsystem_minor_version;
+ uint16_t subsystem_major_version;
+ uint32_t unknown;
+ uint32_t characteristics;
+ uint16_t image_number;
+ unsigned char executable;
+ unsigned char image_flags;
+ uint32_t loader_flags;
+ uint32_t image_file_size;
+ uint32_t image_checksum;
+} nt_section_image_information, nt_sec_img_inf;
+
+
+typedef int32_t __stdcall ntapi_zw_create_section(
+ __out void ** hsection,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in nt_large_integer * section_size __optional,
+ __in uint32_t section_protect,
+ __in uint32_t section_attr,
+ __in void * hfile);
+
+typedef int32_t __stdcall ntapi_zw_open_section(
+ __out void ** hsection,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_query_section(
+ __in void * hsection,
+ __in nt_section_info_class sec_info_class,
+ __out void * sec_info,
+ __in size_t sec_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_extend_section(
+ __in void * hsection,
+ __in nt_large_integer * section_size);
+
+
+typedef int32_t __stdcall ntapi_zw_map_view_of_section(
+ __in void * hsection,
+ __in void * hprocess,
+ __in_out void ** base_address,
+ __in uint32_t zero_bits,
+ __in size_t commit_size,
+ __in_out nt_large_integer * section_offset __optional,
+ __in_out size_t * view_size,
+ __in nt_section_inherit section_inherit_disposition,
+ __in uint32_t allocation_type,
+ __in uint32_t protect);
+
+
+
+typedef int32_t __stdcall ntapi_zw_unmap_view_of_section(
+ __in void * hprocess,
+ __in void * base_address);
+
+
+typedef int32_t __stdcall ntapi_zw_are_mapped_files_the_same(
+ __in void * addr_1st,
+ __in void * addr_2nd);
+
+
+/* extensions */
+typedef int32_t __stdcall ntapi_tt_get_section_name(
+ __in void * addr,
+ __out nt_mem_sec_name * buffer,
+ __in uint32_t buffer_size);
+
+#endif
diff --git a/include/ntapi/nt_security.h b/include/ntapi/nt_security.h
new file mode 100644
index 0000000..20fa956
--- /dev/null
+++ b/include/ntapi/nt_security.h
@@ -0,0 +1,190 @@
+#ifndef _NT_SECURITY_H_
+#define _NT_SECURITY_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_audit_event_type {
+ NT_AUDIT_EVENT_OBJECT_ACCESS,
+ NT_AUDIT_EVENT_DIRECTORY_SERVICE_ACCESS
+} nt_audit_event_type;
+
+
+/* audit flag bits */
+#define NT_AUDIT_ALLOW_NO_PRIVILEGE 0x01
+
+
+typedef struct _nt_privilege_set {
+ uint32_t privilege_count;
+ uint32_t control;
+ nt_luid_and_attributes privilege[];
+} nt_privilege_set;
+
+
+typedef struct _nt_object_type_list {
+ int32_t level;
+ int32_t sbz;
+ nt_guid * object_type;
+} nt_object_type_list;
+
+
+typedef int32_t __stdcall ntapi_zw_privilege_check(
+ __in void * htoken,
+ __in nt_privilege_set * required_privileges,
+ __out unsigned char * result);
+
+
+typedef int32_t __stdcall ntapi_zw_privilege_object_audit_alarm(
+ __in nt_unicode_string * subsystem_name,
+ __in void * handle_id,
+ __in void * htoken,
+ __in uint32_t desired_access,
+ __in nt_privilege_set * privileges,
+ __in unsigned char access_granted);
+
+
+typedef int32_t __stdcall ntapi_zw_privileged_service_audit_alarm(
+ __in nt_unicode_string * subsystem_name,
+ __in nt_unicode_string * service_name,
+ __in void * htoken,
+ __in nt_privilege_set * privileges,
+ __in unsigned char access_granted);
+
+
+typedef int32_t __stdcall ntapi_zw_access_check(
+ __in nt_security_descriptor * sec_desc,
+ __in void * htoken,
+ __in uint32_t desired_access,
+ __in nt_generic_mapping * generic_mapping,
+ __in nt_privilege_set * privilege_set,
+ __in uint32_t * privilege_set_length,
+ __out uint32_t * granted_access,
+ __out unsigned char * access_status);
+
+
+typedef int32_t __stdcall ntapi_zw_access_check_and_audit_alarm(
+ __in nt_unicode_string * subsystem_name,
+ __in void * handle_id,
+ __in nt_unicode_string * object_type_name,
+ __in nt_unicode_string * object_name,
+ __in nt_security_descriptor * sec_desc,
+ __in uint32_t desired_access,
+ __in nt_generic_mapping * generic_mapping,
+ __in unsigned char object_creation,
+ __out uint32_t * granted_access,
+ __out unsigned char * access_status,
+ __out unsigned char * generate_on_close);
+
+
+typedef int32_t __stdcall ntapi_zw_access_check_by_type(
+ __in nt_security_descriptor * sec_desc,
+ __in nt_sid * principal_self_sid,
+ __in void * htoken,
+ __in uint32_t desired_access,
+ __in nt_object_type_list * obj_type_list,
+ __in uint32_t obj_type_list_length,
+ __in nt_generic_mapping * generic_mapping,
+ __in nt_privilege_set * privilege_set,
+ __in uint32_t * privilege_set_length,
+ __out uint32_t * granted_access,
+ __out unsigned char * access_status);
+
+
+typedef int32_t __stdcall ntapi_zw_access_check_by_type_and_audit_alarm(
+ __in nt_unicode_string * subsystem_name,
+ __in void * handle_id,
+ __in nt_unicode_string * object_type_name,
+ __in nt_unicode_string * object_name,
+ __in nt_security_descriptor * sec_desc,
+ __in nt_sid * principal_self_sid,
+ __in uint32_t desired_access,
+ __in nt_audit_event_type audit_type,
+ __in uint32_t augid_flags,
+ __in nt_object_type_list * obj_type_list,
+ __in uint32_t obj_type_list_length,
+ __in nt_generic_mapping * generic_mapping,
+ __in unsigned char object_creation,
+ __out uint32_t * granted_access,
+ __out uint32_t * access_status,
+ __out unsigned char * generate_on_close);
+
+
+typedef int32_t __stdcall ntapi_zw_access_check_by_type_result_list(
+ __in nt_security_descriptor * sec_desc,
+ __in nt_sid * principal_self_sid,
+ __in void * htoken,
+ __in uint32_t desired_access,
+ __in nt_object_type_list * obj_type_list,
+ __in uint32_t obj_type_list_length,
+ __in nt_generic_mapping * generic_mapping,
+ __in nt_privilege_set * privilege_set,
+ __in uint32_t * privilege_set_length,
+ __out uint32_t * granted_access_list,
+ __out uint32_t * access_status_list);
+
+
+typedef int32_t __stdcall ntapi_zw_access_check_by_type_result_list_and_audit_alarm(
+ __in nt_unicode_string * subsystem_name,
+ __in void * handle_id,
+ __in nt_unicode_string * object_type_name,
+ __in nt_unicode_string * object_name,
+ __in nt_security_descriptor * sec_desc,
+ __in nt_sid * principal_self_sid,
+ __in uint32_t desired_access,
+ __in nt_audit_event_type audit_type,
+ __in uint32_t augid_flags,
+ __in nt_object_type_list * obj_type_list,
+ __in uint32_t obj_type_list_length,
+ __in nt_generic_mapping * generic_mapping,
+ __in unsigned char object_creation,
+ __out uint32_t * granted_access_list,
+ __out uint32_t * access_status_list,
+ __out uint32_t * generate_on_close);
+
+
+typedef int32_t __stdcall ntapi_zw_access_check_by_type_result_list_and_audit_alarm_by_handle(
+ __in nt_unicode_string * subsystem_name,
+ __in void * handle_id,
+ __in void * htoken,
+ __in nt_unicode_string * object_type_name,
+ __in nt_unicode_string * object_name,
+ __in nt_security_descriptor * sec_desc,
+ __in nt_sid * principal_self_sid,
+ __in uint32_t desired_access,
+ __in nt_audit_event_type audit_type,
+ __in uint32_t augid_flags,
+ __in nt_object_type_list * obj_type_list,
+ __in uint32_t obj_type_list_length,
+ __in nt_generic_mapping * generic_mapping,
+ __in unsigned char object_creation,
+ __out uint32_t * granted_access_list,
+ __out uint32_t * access_status_list,
+ __out uint32_t * generate_on_close);
+
+
+typedef int32_t __stdcall ntapi_zw_open_object_audit_alarm(
+ __in nt_unicode_string * subsystem_name,
+ __in void ** handle_id,
+ __in nt_unicode_string * object_type_name,
+ __in nt_unicode_string * object_name,
+ __in nt_security_descriptor * sec_desc,
+ __in void * htoken,
+ __in uint32_t desired_access,
+ __in uint32_t granted_access,
+ __in nt_privilege_set * privileges __optional,
+ __in unsigned char object_creation,
+ __in unsigned char access_granted,
+ __out unsigned char * generate_on_close);
+
+typedef int32_t __stdcall ntapi_zw_close_object_audit_alarm(
+ __in nt_unicode_string * subsystem_name,
+ __in void * handle_id,
+ __out unsigned char * generate_on_close);
+
+
+typedef int32_t __stdcall ntapi_zw_delete_object_audit_alarm(
+ __in nt_unicode_string * subsystem_name,
+ __in void * handle_id,
+ __out unsigned char * generate_on_close);
+
+#endif
diff --git a/include/ntapi/nt_slist.h b/include/ntapi/nt_slist.h
new file mode 100644
index 0000000..edb5a0f
--- /dev/null
+++ b/include/ntapi/nt_slist.h
@@ -0,0 +1,22 @@
+#ifndef _NT_SLIST_H_
+#define _NT_SLIST_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_sync.h"
+
+struct nt_slist;
+struct nt_slist_node;
+
+struct nt_slist_node {
+ struct nt_slist_node * next;
+ uintptr_t data;
+};
+
+struct __attr_aligned__(NT_SYNC_BLOCK_SIZE) nt_slist {
+ struct nt_slist_node * head;
+ intptr_t nitems;
+ intptr_t busy;
+ intptr_t padding[NT_SYNC_BLOCK_SIZE/sizeof(size_t)-3];
+};
+
+#endif
diff --git a/include/ntapi/nt_socket.h b/include/ntapi/nt_socket.h
new file mode 100644
index 0000000..7e08697
--- /dev/null
+++ b/include/ntapi/nt_socket.h
@@ -0,0 +1,429 @@
+#ifndef _NT_SOCKET_H_
+#define _NT_SOCKET_H_
+
+/**
+ * socket api:
+ * -----------
+ * here we provide native libraries and applications
+ * with a minimal socket abstraction layer;
+ * if you are interested in posix socket semantics
+ * then this header is REALLY NOT what you
+ * are looking for, as the most portable scenario
+ * (psxscl+libc) neither requires nor allows for
+ * direct interaction with the below interfaces.
+ *
+ * (additional information for the yet curious...)
+ *
+ * client libraries and applications are responsible
+ * for the entire bookkeeping, which should be
+ * easy using the nt_socket structure.
+ *
+ * kernel sockets are created using ZwCreateFile,
+ * and are then manipulated (bind, connect, send,
+ * recv, listen, accept, getsockname, etc.) using
+ * ZwDeviceIoControlFile. accordingly, the main
+ * objective of the below interfaces is to provide
+ * thin wrappers around the above NT system calls,
+ * thereby releasing you from the tedious task
+ * of formatting control messages according to
+ * individual IOCTL codes, protocol types, or
+ * different versions of the operating system.
+ *
+ * another noteworthy objective is the direct
+ * translation between posix socket semantics on the
+ * one hand, and the interfaces that this module
+ * provides on the other. functions in this module
+ * normally take the same arguments as their
+ * posix equivalents, yet require a pointer
+ * to an nt_socket structure in place of an integer
+ * file descriptor (in the posix library, the task
+ * of converting an integer file descriptor to the
+ * above pointer is a trivial one). for functions
+ * such as send() and recv(), the return value is
+ * the system's native NTSTATUS; the number of bytes
+ * sent or received is then returned in a separate
+ * argument, and can also be obtained, along with
+ * extended status, from the info member of the iosb
+ * argument. last but not least, each function in
+ * this module accepts one or more optional arguments
+ * of questionable relevance:-)
+**/
+
+#include <psxtypes/psxtypes.h>
+#include "nt_status.h"
+#include "nt_object.h"
+#include "nt_tty.h"
+
+/* afd socket domains */
+#define NT_AF_UNSPEC (0x0000u)
+#define NT_AF_UNIX (0x0001u)
+#define NT_AF_INET (0x0002u)
+#define NT_AF_IMPLINK (0x0003u)
+#define NT_AF_PUP (0x0004u)
+#define NT_AF_CHAOS (0x0005u)
+#define NT_AF_NS (0x0006u)
+#define NT_AF_IPX (0x0006u) /* synonym */
+#define NT_AF_ISO (0x0007u)
+#define NT_AF_OSI (0x0007u) /* synonym */
+#define NT_AF_ECMA (0x0008u)
+#define NT_AF_DATAKIT (0x0009u)
+#define NT_AF_CCITT (0x000Au)
+#define NT_AF_SNA (0x000Bu)
+#define NT_AF_DECnet (0x000Cu)
+#define NT_AF_DLI (0x000Du)
+#define NT_AF_LAT (0x000Eu)
+#define NT_AF_HYLINK (0x000Fu)
+#define NT_AF_APPLETALK (0x0010u)
+#define NT_AF_NETBIOS (0x0011u)
+#define NT_AF_VOICEVIEW (0x0012u)
+#define NT_AF_FIREFOX (0x0013u)
+#define NT_AF_UNKNOWN_1ST (0x0014u)
+#define NT_AF_BAN (0x0015u)
+#define NT_AF_ATM (0x0016u)
+#define NT_AF_INET6 (0x0017u)
+#define NT_AF_CLUSTER (0x0018u)
+#define NT_AF_12844 (0x0019u)
+#define NT_AF_IRDA (0x001Au)
+#define NT_AF_NETDES (0x001Cu)
+#define NT_AF_TCNPROCESS (0x001Du)
+#define NT_AF_TCNMESSAGE (0x001Eu)
+#define NT_AF_ICLFXBM (0x001Fu)
+#define NT_AF_BTH (0x0020u)
+#define NT_AF_LINK (0x0021u)
+
+
+/* afd socket types */
+#define NT_SOCK_STREAM (0x0001u)
+#define NT_SOCK_DGRAM (0x0002u)
+#define NT_SOCK_RAW (0x0003u)
+#define NT_SOCK_RDM (0x0004u)
+#define NT_SOCK_SEQPACKET (0x0005u)
+
+
+/* afd socket protocols */
+#define NT_IPPROTO_IP 0
+#define NT_IPPROTO_HOPOPTS 0
+#define NT_IPPROTO_ICMP 1
+#define NT_IPPROTO_IGMP 2
+#define NT_IPPROTO_GGP 3
+#define NT_IPPROTO_IPV4 4
+#define NT_IPPROTO_ST 5
+#define NT_IPPROTO_TCP 6
+#define NT_IPPROTO_CBT 7
+#define NT_IPPROTO_EGP 8
+#define NT_IPPROTO_IGP 9
+#define NT_IPPROTO_PUP 12
+#define NT_IPPROTO_UDP 17
+#define NT_IPPROTO_IDP 22
+#define NT_IPPROTO_RDP 27
+#define NT_IPPROTO_IPV6 41
+#define NT_IPPROTO_ROUTING 43
+#define NT_IPPROTO_FRAGMENT 44
+#define NT_IPPROTO_ESP 50
+#define NT_IPPROTO_AH 51
+#define NT_IPPROTO_ICMPV6 58
+#define NT_IPPROTO_NONE 59
+#define NT_IPPROTO_DSTOPTS 60
+#define NT_IPPROTO_ND 77
+#define NT_IPPROTO_ICLFXBM 78
+#define NT_IPPROTO_PIM 103
+#define NT_IPPROTO_PGM 113
+#define NT_IPPROTO_L2TP 115
+#define NT_IPPROTO_SCTP 132
+#define NT_IPPROTO_RAW 255
+#define NT_IPPROTO_MAX 256
+#define NT_IPPROTO_RESERVED_RAW 257
+#define NT_IPPROTO_RESERVED_IPSEC 258
+#define NT_IPPROTO_RESERVED_IPSECOFFLOAD 259
+#define NT_IPPROTO_RESERVED_WNV 260
+#define NT_IPPROTO_RESERVED_MAX 261
+
+
+
+/* tdi receive modes */
+#define NT_TDI_RECEIVE_BROADCAST (0x0004u)
+#define NT_TDI_RECEIVE_MULTICAST (0x0008u)
+#define NT_TDI_RECEIVE_PARTIAL (0x0010u)
+#define NT_TDI_RECEIVE_NORMAL (0x0020u)
+#define NT_TDI_RECEIVE_EXPEDITED (0x0040u)
+#define NT_TDI_RECEIVE_PEEK (0x0080u)
+#define NT_TDI_RECEIVE_NO_RESPONSE_EXP (0x0100u)
+#define NT_TDI_RECEIVE_COPY_LOOKAHEAD (0x0200u)
+#define NT_TDI_RECEIVE_ENTIRE_MESSAGE (0x0400u)
+#define NT_TDI_RECEIVE_AT_DISPATCH_LEVEL (0x0800u)
+#define NT_TDI_RECEIVE_CONTROL_INFO (0x1000u)
+#define NT_TDI_RECEIVE_FORCE_INDICATION (0x2000u)
+#define NT_TDI_RECEIVE_NO_PUSH (0x4000u)
+
+/* tdi send modes */
+#define NT_TDI_SEND_EXPEDITED (0x0020u)
+#define NT_TDI_SEND_PARTIAL (0x0040u)
+#define NT_TDI_SEND_NO_RESPONSE_EXPECTED (0x0080u)
+#define NT_TDI_SEND_NON_BLOCKING (0x0100u)
+#define NT_TDI_SEND_AND_DISCONNECT (0x0200u)
+
+/* tdi listen modes */
+#define NT_TDI_QUERY_ACCEPT (0x0001u)
+
+/* tdi disconnect modes */
+#define NT_TDI_DISCONNECT_WAIT (0x0001u)
+#define NT_TDI_DISCONNECT_ABORT (0x0002u)
+#define NT_TDI_DISCONNECT_RELEASE (0x0004u)
+
+/* afd ioctl codes */
+#define NT_AFD_IOCTL_BIND (0x12003u)
+#define NT_AFD_IOCTL_CONNECT (0x12007u)
+#define NT_AFD_IOCTL_LISTEN (0x1200Bu)
+#define NT_AFD_IOCTL_ACCEPT (0x1200Cu)
+#define NT_AFD_IOCTL_DUPLICATE (0x12010u)
+#define NT_AFD_IOCTL_SEND (0x1201Fu)
+#define NT_AFD_IOCTL_UDP_SEND (0x12023u)
+#define NT_AFD_IOCTL_RECV (0x12017u)
+#define NT_AFD_IOCTL_DISCONNECT (0x1202Bu)
+#define NT_AFD_IOCTL_SELECT (0x12024u)
+#define NT_AFD_IOCTL_GET_SOCK_NAME (0x1202Fu)
+#define NT_AFD_IOCTL_GET_PEER_NAME (0x1202Fu)
+#define NT_AFD_IOCTL_SET_CONTEXT (0x1202Fu)
+
+/* afd socket shutdown bits */
+#define NT_AFD_DISCONNECT_WR (0x01u)
+#define NT_AFD_DISCONNECT_RD (0x02u)
+
+/* socket portable shutdown options */
+#define NT_SHUT_RD (0x00u)
+#define NT_SHUT_WR (0x01u)
+#define NT_SHUT_RDWR (0x02u)
+
+/* send, sendto, sendmsg: *nix flags and bit place-holders */
+#define NT_MSG_OOB (0x00000001u)
+#define NT_MSG_PEEK (0x00000002u)
+#define NT_MSG_DONTROUTE (0x00000004u)
+#define NT_MSG_CTRUNC (0x00000008u)
+#define NT_MSG_PROXY (0x00000010u)
+#define NT_MSG_TRUNC (0x00000020u)
+#define NT_MSG_DONTWAIT (0x00000040u)
+#define NT_MSG_EOR (0x00000080u)
+#define NT_MSG_WAITALL (0x00000100u)
+#define NT_MSG_FIN (0x00000200u)
+#define NT_MSG_SYN (0x00000400u)
+#define NT_MSG_CONFIRM (0x00000800u)
+#define NT_MSG_RST (0x00001000u)
+#define NT_MSG_ERRQUEUE (0x00002000u)
+#define NT_MSG_NOSIGNAL (0x00004000u)
+#define NT_MSG_MORE (0x00008000u)
+#define NT_MSG_WAITFORONE (0x00010000u)
+#define NT_MSG_CMSG_CLOEXEC (0x40000000u)
+
+
+/* socket structures */
+typedef struct _nt_socket {
+ union {
+ void * hsocket;
+ void * hfile;
+ void * hpipe;
+ nt_pty * hpty;
+ };
+
+ void * hevent;
+ int32_t refcnt; /* reserved for client */
+ uint16_t fdtype; /* reserved for client */
+ uint16_t sctype; /* reserved for client */
+ uint32_t ctxid; /* reserved for client */
+ uint32_t reserved; /* reserved for client */
+ uint32_t psxflags; /* reserved for client */
+ uint32_t ntflags; /* sc_wait alert flags */
+ nt_large_integer timeout;
+ int32_t iostatus;
+ int32_t waitstatus;
+
+ union {
+ struct {
+ uint16_t domain;
+ uint16_t type;
+ uint32_t protocol;
+ };
+
+ void * vfd;
+ void * vmount;
+ void * hpair;
+ void * dirctx;
+ };
+} nt_socket;
+
+
+typedef struct _nt_scope_id{
+ union {
+ struct {
+ uint32_t zone : 28;
+ uint32_t level : 4;
+ };
+
+ uint32_t value;
+ };
+} nt_scope_id;
+
+
+typedef struct _nt_sockaddr_in4 {
+ uint16_t sa_family;
+ char sa_data[14];
+} nt_sockaddr_in4;
+
+
+typedef struct _nt_sockaddr_in6 {
+ uint16_t sa_family;
+ uint16_t sa_port;
+ uint32_t sa_flow;
+ unsigned char sa_data[16];
+ nt_scope_id sa_scope;
+} nt_sockaddr_in6;
+
+
+typedef union _nt_sockaddr {
+ nt_sockaddr_in4 sa_addr_in4;
+ nt_sockaddr_in6 sa_addr_in6;
+} nt_sockaddr;
+
+
+typedef struct _nt_afd_buffer {
+ size_t length;
+ char * buffer;
+} nt_afd_buffer;
+
+
+typedef struct _nt_afd_listen_info {
+ void * unknown_1st;
+ uint32_t backlog;
+ void * unknown_2nd;
+} nt_afd_listen_info;
+
+
+typedef struct _nt_afd_accept_info {
+ uint32_t sequence;
+ nt_sockaddr addr;
+ uint32_t legacy[2];
+} nt_afd_accept_info;
+
+
+typedef struct _nt_afd_duplicate_info {
+ uint32_t unknown;
+ uint32_t sequence;
+ void * hsocket_dedicated;
+} nt_afd_duplicate_info;
+
+
+typedef struct _nt_afd_send_info {
+ nt_afd_buffer * afd_buffer_array;
+ uint32_t buffer_count;
+ uint32_t afd_flags;
+ uint32_t tdi_flags;
+} nt_afd_send_info;
+
+
+typedef struct _nt_afd_recv_info {
+ nt_afd_buffer * afd_buffer_array;
+ uint32_t buffer_count;
+ uint32_t afd_flags;
+ uint32_t tdi_flags;
+} nt_afd_recv_info;
+
+
+typedef struct _nt_afd_disconnect_info {
+ uint32_t shutdown_flags;
+ uint32_t unknown[3];
+} nt_afd_disconnect_info;
+
+
+/* socket functions */
+typedef int32_t __cdecl ntapi_sc_socket(
+ __out nt_socket * hssocket,
+ __in uint16_t domain,
+ __in uint16_t type,
+ __in uint32_t protocol,
+ __in uint32_t desired_access __optional,
+ __in nt_sqos * sqos __optional,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_bind(
+ __in nt_socket * hssocket,
+ __in const nt_sockaddr * addr,
+ __in uintptr_t addrlen,
+ __in uintptr_t service_flags __optional,
+ __out nt_sockaddr * sockaddr __optional,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_listen(
+ __in nt_socket * hssocket,
+ __in uintptr_t backlog,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_accept(
+ __in nt_socket * hssock_listen,
+ __in nt_sockaddr * addr,
+ __in uint16_t * addrlen,
+ __out nt_socket * hssock_dedicated,
+ __in uintptr_t afdflags __optional,
+ __in uintptr_t tdiflags __optional,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_connect(
+ __in nt_socket * hssocket,
+ __in nt_sockaddr * addr,
+ __in uintptr_t addrlen,
+ __in uintptr_t service_flags __optional,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_send(
+ __in nt_socket * hssocket,
+ __in const void * buffer,
+ __in size_t len,
+ __out ssize_t * bytes_sent __optional,
+ __in uintptr_t afdflags __optional,
+ __in uintptr_t tdiflags __optional,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_recv(
+ __in nt_socket * hssocket,
+ __in const void * buffer,
+ __in size_t len,
+ __out ssize_t * bytes_received __optional,
+ __in uintptr_t afdflags __optional,
+ __in uintptr_t tdiflags __optional,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_shutdown(
+ __in nt_socket * hssocket,
+ __in uintptr_t psxhow,
+ __in uintptr_t afdhow,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_getsockname(
+ __in nt_socket * hssocket,
+ __in nt_sockaddr * addr,
+ __in uint16_t * addrlen,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_server_accept_connection(
+ __in nt_socket * hssocket,
+ __out nt_afd_accept_info * accept_info,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_server_duplicate_socket(
+ __in nt_socket * hssock_listen,
+ __in nt_socket * hssock_dedicated,
+ __in nt_afd_accept_info * accept_info,
+ __out nt_io_status_block * iosb __optional);
+
+
+typedef int32_t __cdecl ntapi_sc_wait(nt_socket * hssocket, nt_iosb * iosb, nt_timeout * timeout);
+
+#endif
diff --git a/include/ntapi/nt_stat.h b/include/ntapi/nt_stat.h
new file mode 100644
index 0000000..2bcac79
--- /dev/null
+++ b/include/ntapi/nt_stat.h
@@ -0,0 +1,46 @@
+#ifndef _NT_STAT_H_
+#define _NT_STAT_H_
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_file.h>
+
+/* ntapi_tt_stat info flags bits */
+#define NT_STAT_DEFAULT (0x00000000)
+#define NT_STAT_COMMON (0x00000001)
+#define NT_STAT_DEV_NAME_COPY (0x00000002)
+#define NT_STAT_NEW_HANDLE (0x80000000)
+
+typedef struct _nt_stat {
+ nt_fbi fbi;
+ nt_fsi fsi;
+ nt_fii fii;
+ nt_fei fei;
+ nt_facci facci;
+ nt_fpi fpi;
+ nt_fmi fmi;
+ nt_falii falii;
+ nt_fssi fssi;
+ void * hfile;
+ uint32_t flags_in;
+ uint32_t flags_out;
+ uint32_t file_name_length;
+ uint32_t file_name_hash;
+ uint32_t dev_name_hash;
+ uint16_t dev_name_strlen;
+ uint16_t dev_name_maxlen;
+ wchar16_t dev_name[];
+} nt_stat;
+
+
+typedef int32_t __stdcall ntapi_tt_stat(
+ __in void * hfile __optional,
+ __in void * hroot __optional,
+ __in nt_unicode_string * path __optional,
+ __out nt_stat * stat,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t open_options,
+ __in uint32_t flags);
+
+#endif
diff --git a/include/ntapi/nt_statfs.h b/include/ntapi/nt_statfs.h
new file mode 100644
index 0000000..c2aa6d6
--- /dev/null
+++ b/include/ntapi/nt_statfs.h
@@ -0,0 +1,68 @@
+#ifndef _NT_STATFS_H_
+#define _NT_STATFS_H_
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+
+/* ntapi_tt_statfs info flags bits */
+#define NT_STATFS_DEFAULT (0x00000000)
+#define NT_STATFS_COMMON (0x00000001)
+#define NT_STATFS_DEV_NAME_COPY (0x00000002)
+#define NT_STATFS_VOLUME_GUID (0x00000004)
+#define NT_STATFS_DOS_DRIVE_LETTER NT_STATFS_VOLUME_GUID
+#define NT_STATFS_NEW_HANDLE (0x80000000)
+
+
+#define NT_FS_TYPE_FAT16_NAME_HASH (0x00000000)
+#define NT_FS_TYPE_FAT32_NAME_HASH (0x00000001)
+#define NT_FS_TYPE_HPFS_NAME_HASH (0x00000002)
+#define NT_FS_TYPE_MSDOS_NAME_HASH (0x00000003)
+#define NT_FS_TYPE_NTFS_NAME_HASH (0xbfbc5fdb)
+#define NT_FS_TYPE_SMB_NAME_HASH (0x00000004)
+#define NT_FS_TYPE_UDF_NAME_HASH (0x00000005)
+
+typedef struct _nt_fsid_t {
+ uint32_t __val[2];
+} nt_fsid_t;
+
+typedef struct _nt_statfs {
+ uintptr_t f_type;
+ uintptr_t f_bsize;
+ uint64_t f_blocks;
+ uint64_t f_bfree;
+ uint64_t f_bavail;
+ uint64_t f_files;
+ uint64_t f_ffree;
+ nt_fsid_t f_fsid;
+ uintptr_t f_namelen;
+ uintptr_t f_frsize;
+ uintptr_t f_flags;
+ uintptr_t f_spare[4];
+ uint32_t nt_fstype_hash;
+ uint32_t nt_attr;
+ uint32_t nt_control_flags;
+ wchar16_t nt_drive_letter;
+ wchar16_t nt_padding;
+ nt_guid nt_volume_guid;
+ void * hfile;
+ uint32_t flags_in;
+ uint32_t flags_out;
+ uint16_t record_name_strlen;
+ uint16_t dev_name_strlen;
+ uint16_t dev_name_maxlen;
+ uint32_t dev_name_hash;
+ wchar16_t dev_name[];
+} nt_statfs;
+
+
+typedef int32_t __stdcall ntapi_tt_statfs(
+ __in void * hfile __optional,
+ __in void * hroot __optional,
+ __in nt_unicode_string * path __optional,
+ __out nt_statfs * statfs,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t flags);
+
+
+#endif
diff --git a/include/ntapi/nt_status.h b/include/ntapi/nt_status.h
new file mode 100644
index 0000000..a3d7528
--- /dev/null
+++ b/include/ntapi/nt_status.h
@@ -0,0 +1,1796 @@
+#ifndef _NT_STATUS_H_
+#define _NT_STATUS_H_
+
+#include <psxtypes/psxtypes.h>
+
+typedef int32_t nt_status;
+
+#define NT_STATUS_SUCCESS ((nt_status) 0x00000000)
+
+#define NT_DBG_APP_NOT_IDLE ((nt_status) 0xC0010002)
+#define NT_DBG_COMMAND_EXCEPTION ((nt_status) 0x40010009)
+#define NT_DBG_CONTINUE ((nt_status) 0x00010002)
+#define NT_DBG_CONTROL_BREAK ((nt_status) 0x40010008)
+#define NT_DBG_CONTROL_C ((nt_status) 0x40010005)
+#define NT_DBG_EXCEPTION_HANDLED ((nt_status) 0x00010001)
+#define NT_DBG_EXCEPTION_NOT_HANDLED ((nt_status) 0x80010001)
+#define NT_DBG_NO_STATE_CHANGE ((nt_status) 0xC0010001)
+#define NT_DBG_PRINTEXCEPTION_C ((nt_status) 0x40010006)
+#define NT_DBG_REPLY_LATER ((nt_status) 0x40010001)
+#define NT_DBG_RIPEXCEPTION ((nt_status) 0x40010007)
+#define NT_DBG_TERMINATE_PROCESS ((nt_status) 0x40010004)
+#define NT_DBG_TERMINATE_THREAD ((nt_status) 0x40010003)
+#define NT_DBG_UNABLE_TO_PROVIDE_HANDLE ((nt_status) 0x40010002)
+#define NT_EPT_NT_CANT_CREATE ((nt_status) 0xC002004C)
+#define NT_EPT_NT_CANT_PERFORM_OP ((nt_status) 0xC0020035)
+#define NT_EPT_NT_INVALID_ENTRY ((nt_status) 0xC0020034)
+#define NT_EPT_NT_NOT_REGISTERED ((nt_status) 0xC0020036)
+#define NT_RPC_NT_ADDRESS_ERROR ((nt_status) 0xC0020045)
+#define NT_RPC_NT_ALREADY_LISTENING ((nt_status) 0xC002000E)
+#define NT_RPC_NT_ALREADY_REGISTERED ((nt_status) 0xC002000C)
+#define NT_RPC_NT_BAD_STUB_DATA ((nt_status) 0xC003000C)
+#define NT_RPC_NT_BINDING_HAS_NO_AUTH ((nt_status) 0xC002002F)
+#define NT_RPC_NT_BINDING_INCOMPLETE ((nt_status) 0xC0020051)
+#define NT_RPC_NT_BYTE_COUNT_TOO_SMALL ((nt_status) 0xC003000B)
+#define NT_RPC_NT_CALL_CANCELLED ((nt_status) 0xC0020050)
+#define NT_RPC_NT_CALL_FAILED ((nt_status) 0xC002001B)
+#define NT_RPC_NT_CALL_FAILED_DNE ((nt_status) 0xC002001C)
+#define NT_RPC_NT_CALL_IN_PROGRESS ((nt_status) 0xC0020049)
+#define NT_RPC_NT_CANNOT_SUPPORT ((nt_status) 0xC0020041)
+#define NT_RPC_NT_CANT_CREATE_ENDPOINT ((nt_status) 0xC0020015)
+#define NT_RPC_NT_COMM_FAILURE ((nt_status) 0xC0020052)
+#define NT_RPC_NT_DUPLICATE_ENDPOINT ((nt_status) 0xC0020029)
+#define NT_RPC_NT_ENTRY_ALREADY_EXISTS ((nt_status) 0xC002003D)
+#define NT_RPC_NT_ENTRY_NOT_FOUND ((nt_status) 0xC002003E)
+#define NT_RPC_NT_ENUM_VALUE_OUT_OF_RANGE ((nt_status) 0xC003000A)
+#define NT_RPC_NT_FP_DIV_ZERO ((nt_status) 0xC0020046)
+#define NT_RPC_NT_FP_OVERFLOW ((nt_status) 0xC0020048)
+#define NT_RPC_NT_FP_UNDERFLOW ((nt_status) 0xC0020047)
+#define NT_RPC_NT_GROUP_MEMBER_NOT_FOUND ((nt_status) 0xC002004B)
+#define NT_RPC_NT_INCOMPLETE_NAME ((nt_status) 0xC0020038)
+#define NT_RPC_NT_INTERFACE_NOT_FOUND ((nt_status) 0xC002003C)
+#define NT_RPC_NT_INTERNAL_ERROR ((nt_status) 0xC0020043)
+#define NT_RPC_NT_INVALID_ASYNC_CALL ((nt_status) 0xC0020063)
+#define NT_RPC_NT_INVALID_ASYNC_HANDLE ((nt_status) 0xC0020062)
+#define NT_RPC_NT_INVALID_AUTH_IDENTITY ((nt_status) 0xC0020032)
+#define NT_RPC_NT_INVALID_BINDING ((nt_status) 0xC0020003)
+#define NT_RPC_NT_INVALID_BOUND ((nt_status) 0xC0020023)
+#define NT_RPC_NT_INVALID_ENDPOINT_FORMAT ((nt_status) 0xC0020007)
+#define NT_RPC_NT_INVALID_ES_ACTION ((nt_status) 0xC0030059)
+#define NT_RPC_NT_INVALID_NAF_ID ((nt_status) 0xC0020040)
+#define NT_RPC_NT_INVALID_NAME_SYNTAX ((nt_status) 0xC0020025)
+#define NT_RPC_NT_INVALID_NETWORK_OPTIONS ((nt_status) 0xC0020019)
+#define NT_RPC_NT_INVALID_NET_ADDR ((nt_status) 0xC0020008)
+#define NT_RPC_NT_INVALID_OBJECT ((nt_status) 0xC002004D)
+#define NT_RPC_NT_INVALID_PIPE_OBJECT ((nt_status) 0xC003005C)
+#define NT_RPC_NT_INVALID_PIPE_OPERATION ((nt_status) 0xC003005D)
+#define NT_RPC_NT_INVALID_RPC_PROTSEQ ((nt_status) 0xC0020005)
+#define NT_RPC_NT_INVALID_STRING_BINDING ((nt_status) 0xC0020001)
+#define NT_RPC_NT_INVALID_STRING_UUID ((nt_status) 0xC0020006)
+#define NT_RPC_NT_INVALID_TAG ((nt_status) 0xC0020022)
+#define NT_RPC_NT_INVALID_TIMEOUT ((nt_status) 0xC002000A)
+#define NT_RPC_NT_INVALID_VERS_OPTION ((nt_status) 0xC0020039)
+#define NT_RPC_NT_MAX_CALLS_TOO_SMALL ((nt_status) 0xC002002B)
+#define NT_RPC_NT_NAME_SERVICE_UNAVAILABLE ((nt_status) 0xC002003F)
+#define NT_RPC_NT_NOTHING_TO_EXPORT ((nt_status) 0xC0020037)
+#define NT_RPC_NT_NOT_ALL_OBJS_UNEXPORTED ((nt_status) 0xC002003B)
+#define NT_RPC_NT_NOT_CANCELLED ((nt_status) 0xC0020058)
+#define NT_RPC_NT_NOT_LISTENING ((nt_status) 0xC0020010)
+#define NT_RPC_NT_NOT_RPC_ERROR ((nt_status) 0xC0020055)
+#define NT_RPC_NT_NO_BINDINGS ((nt_status) 0xC0020013)
+#define NT_RPC_NT_NO_CALL_ACTIVE ((nt_status) 0xC002001A)
+#define NT_RPC_NT_NO_CONTEXT_AVAILABLE ((nt_status) 0xC0020042)
+#define NT_RPC_NT_NO_ENDPOINT_FOUND ((nt_status) 0xC0020009)
+#define NT_RPC_NT_NO_ENTRY_NAME ((nt_status) 0xC0020024)
+#define NT_RPC_NT_NO_INTERFACES ((nt_status) 0xC002004F)
+#define NT_RPC_NT_NO_MORE_BINDINGS ((nt_status) 0xC002004A)
+#define NT_RPC_NT_NO_MORE_ENTRIES ((nt_status) 0xC0030001)
+#define NT_RPC_NT_NO_MORE_MEMBERS ((nt_status) 0xC002003A)
+#define NT_RPC_NT_NO_PRINC_NAME ((nt_status) 0xC0020054)
+#define NT_RPC_NT_NO_PROTSEQS ((nt_status) 0xC0020014)
+#define NT_RPC_NT_NO_PROTSEQS_REGISTERED ((nt_status) 0xC002000F)
+#define NT_RPC_NT_NULL_REF_POINTER ((nt_status) 0xC0030009)
+#define NT_RPC_NT_OBJECT_NOT_FOUND ((nt_status) 0xC002000B)
+#define NT_RPC_NT_OUT_OF_RESOURCES ((nt_status) 0xC0020016)
+#define NT_RPC_NT_PIPE_CLOSED ((nt_status) 0xC003005F)
+#define NT_RPC_NT_PIPE_DISCIPLINE_ERROR ((nt_status) 0xC0030060)
+#define NT_RPC_NT_PIPE_EMPTY ((nt_status) 0xC0030061)
+#define NT_RPC_NT_PROCNUM_OUT_OF_RANGE ((nt_status) 0xC002002E)
+#define NT_RPC_NT_PROTOCOL_ERROR ((nt_status) 0xC002001D)
+#define NT_RPC_NT_PROTSEQ_NOT_FOUND ((nt_status) 0xC002002D)
+#define NT_RPC_NT_PROTSEQ_NOT_SUPPORTED ((nt_status) 0xC0020004)
+#define NT_RPC_NT_PROXY_ACCESS_DENIED ((nt_status) 0xC0020064)
+#define NT_RPC_NT_SEC_PKG_ERROR ((nt_status) 0xC0020057)
+#define NT_RPC_NT_SEND_INCOMPLETE ((nt_status) 0x400200AF)
+#define NT_RPC_NT_SERVER_TOO_BUSY ((nt_status) 0xC0020018)
+#define NT_RPC_NT_SERVER_UNAVAILABLE ((nt_status) 0xC0020017)
+#define NT_RPC_NT_SS_CANNOT_GET_CALL_HANDLE ((nt_status) 0xC0030008)
+#define NT_RPC_NT_SS_CHAR_TRANS_OPEN_FAIL ((nt_status) 0xC0030002)
+#define NT_RPC_NT_SS_CHAR_TRANS_SHORT_FILE ((nt_status) 0xC0030003)
+#define NT_RPC_NT_SS_CONTEXT_DAMAGED ((nt_status) 0xC0030006)
+#define NT_RPC_NT_SS_CONTEXT_MISMATCH ((nt_status) 0xC0030005)
+#define NT_RPC_NT_SS_HANDLES_MISMATCH ((nt_status) 0xC0030007)
+#define NT_RPC_NT_SS_IN_NULL_CONTEXT ((nt_status) 0xC0030004)
+#define NT_RPC_NT_STRING_TOO_LONG ((nt_status) 0xC002002C)
+#define NT_RPC_NT_TYPE_ALREADY_REGISTERED ((nt_status) 0xC002000D)
+#define NT_RPC_NT_UNKNOWN_AUTHN_LEVEL ((nt_status) 0xC0020031)
+#define NT_RPC_NT_UNKNOWN_AUTHN_SERVICE ((nt_status) 0xC0020030)
+#define NT_RPC_NT_UNKNOWN_AUTHN_TYPE ((nt_status) 0xC002002A)
+#define NT_RPC_NT_UNKNOWN_AUTHZ_SERVICE ((nt_status) 0xC0020033)
+#define NT_RPC_NT_UNKNOWN_IF ((nt_status) 0xC0020012)
+#define NT_RPC_NT_UNKNOWN_MGR_TYPE ((nt_status) 0xC0020011)
+#define NT_RPC_NT_UNSUPPORTED_AUTHN_LEVEL ((nt_status) 0xC0020053)
+#define NT_RPC_NT_UNSUPPORTED_NAME_SYNTAX ((nt_status) 0xC0020026)
+#define NT_RPC_NT_UNSUPPORTED_TRANS_SYN ((nt_status) 0xC002001F)
+#define NT_RPC_NT_UNSUPPORTED_TYPE ((nt_status) 0xC0020021)
+#define NT_RPC_NT_UUID_LOCAL_ONLY ((nt_status) 0x40020056)
+#define NT_RPC_NT_UUID_NO_ADDRESS ((nt_status) 0xC0020028)
+#define NT_RPC_NT_WRONG_ES_VERSION ((nt_status) 0xC003005A)
+#define NT_RPC_NT_WRONG_KIND_OF_BINDING ((nt_status) 0xC0020002)
+#define NT_RPC_NT_WRONG_PIPE_VERSION ((nt_status) 0xC003005E)
+#define NT_RPC_NT_WRONG_STUB_VERSION ((nt_status) 0xC003005B)
+#define NT_RPC_NT_ZERO_DIVIDE ((nt_status) 0xC0020044)
+#define NT_STATUS_ABANDONED ((nt_status) 0x00000080)
+#define NT_STATUS_ABANDONED_WAIT_0 ((nt_status) 0x00000080)
+#define NT_STATUS_ABANDONED_WAIT_63 ((nt_status) 0x000000BF)
+#define NT_STATUS_ABANDON_HIBERFILE ((nt_status) 0x40000033)
+#define NT_STATUS_ACCESS_AUDIT_BY_POLICY ((nt_status) 0x40000032)
+#define NT_STATUS_ACCESS_DENIED ((nt_status) 0xC0000022)
+#define NT_STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((nt_status) 0xC0000361)
+#define NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((nt_status) 0xC0000364)
+#define NT_STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((nt_status) 0xC0000362)
+#define NT_STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((nt_status) 0xC0000363)
+#define NT_STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY ((nt_status) 0xC0000372)
+#define NT_STATUS_ACCESS_VIOLATION ((nt_status) 0xC0000005)
+#define NT_STATUS_ACCOUNT_DISABLED ((nt_status) 0xC0000072)
+#define NT_STATUS_ACCOUNT_EXPIRED ((nt_status) 0xC0000193)
+#define NT_STATUS_ACCOUNT_LOCKED_OUT ((nt_status) 0xC0000234)
+#define NT_STATUS_ACCOUNT_RESTRICTION ((nt_status) 0xC000006E)
+#define NT_STATUS_ACPI_ACQUIRE_GLOBAL_LOCK ((nt_status) 0xC0140012)
+#define NT_STATUS_ACPI_ADDRESS_NOT_MAPPED ((nt_status) 0xC014000C)
+#define NT_STATUS_ACPI_ALREADY_INITIALIZED ((nt_status) 0xC0140013)
+#define NT_STATUS_ACPI_ASSERT_FAILED ((nt_status) 0xC0140003)
+#define NT_STATUS_ACPI_FATAL ((nt_status) 0xC0140006)
+#define NT_STATUS_ACPI_HANDLER_COLLISION ((nt_status) 0xC014000E)
+#define NT_STATUS_ACPI_INCORRECT_ARGUMENT_COUNT ((nt_status) 0xC014000B)
+#define NT_STATUS_ACPI_INVALID_ACCESS_SIZE ((nt_status) 0xC0140011)
+#define NT_STATUS_ACPI_INVALID_ARGTYPE ((nt_status) 0xC0140008)
+#define NT_STATUS_ACPI_INVALID_ARGUMENT ((nt_status) 0xC0140005)
+#define NT_STATUS_ACPI_INVALID_DATA ((nt_status) 0xC014000F)
+#define NT_STATUS_ACPI_INVALID_EVENTTYPE ((nt_status) 0xC014000D)
+#define NT_STATUS_ACPI_INVALID_INDEX ((nt_status) 0xC0140004)
+#define NT_STATUS_ACPI_INVALID_MUTEX_LEVEL ((nt_status) 0xC0140015)
+#define NT_STATUS_ACPI_INVALID_OBJTYPE ((nt_status) 0xC0140009)
+#define NT_STATUS_ACPI_INVALID_OPCODE ((nt_status) 0xC0140001)
+#define NT_STATUS_ACPI_INVALID_REGION ((nt_status) 0xC0140010)
+#define NT_STATUS_ACPI_INVALID_SUPERNAME ((nt_status) 0xC0140007)
+#define NT_STATUS_ACPI_INVALID_TABLE ((nt_status) 0xC0140019)
+#define NT_STATUS_ACPI_INVALID_TARGETTYPE ((nt_status) 0xC014000A)
+#define NT_STATUS_ACPI_MUTEX_NOT_OWNED ((nt_status) 0xC0140016)
+#define NT_STATUS_ACPI_MUTEX_NOT_OWNER ((nt_status) 0xC0140017)
+#define NT_STATUS_ACPI_NOT_INITIALIZED ((nt_status) 0xC0140014)
+#define NT_STATUS_ACPI_POWER_REQUEST_FAILED ((nt_status) 0xC0140021)
+#define NT_STATUS_ACPI_REG_HANDLER_FAILED ((nt_status) 0xC0140020)
+#define NT_STATUS_ACPI_RS_ACCESS ((nt_status) 0xC0140018)
+#define NT_STATUS_ACPI_STACK_OVERFLOW ((nt_status) 0xC0140002)
+#define NT_STATUS_ADAPTER_HARDWARE_ERROR ((nt_status) 0xC00000C2)
+#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED ((nt_status) 0xC0000238)
+#define NT_STATUS_ADDRESS_ALREADY_EXISTS ((nt_status) 0xC000020A)
+#define NT_STATUS_ADDRESS_CLOSED ((nt_status) 0xC000020B)
+#define NT_STATUS_ADDRESS_NOT_ASSOCIATED ((nt_status) 0xC0000239)
+#define NT_STATUS_ADVANCED_INSTALLER_FAILED ((nt_status) 0xC0150020)
+#define NT_STATUS_AGENTS_EXHAUSTED ((nt_status) 0xC0000085)
+#define NT_STATUS_ALERTED ((nt_status) 0x00000101)
+#define NT_STATUS_ALIAS_EXISTS ((nt_status) 0xC0000154)
+#define NT_STATUS_ALLOCATE_BUCKET ((nt_status) 0xC000022F)
+#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED ((nt_status) 0xC0000099)
+#define NT_STATUS_ALL_SIDS_FILTERED ((nt_status) 0xC000035E)
+#define NT_STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED ((nt_status) 0xC0000402)
+#define NT_STATUS_ALPC_CHECK_COMPLETION_LIST ((nt_status) 0x40000030)
+#define NT_STATUS_ALREADY_COMMITTED ((nt_status) 0xC0000021)
+#define NT_STATUS_ALREADY_DISCONNECTED ((nt_status) 0x80000025)
+#define NT_STATUS_ALREADY_REGISTERED ((nt_status) 0xC0000718)
+#define NT_STATUS_ALREADY_WIN32 ((nt_status) 0x4000001B)
+#define NT_STATUS_AMBIGUOUS_SYSTEM_DEVICE ((nt_status) 0xC0000451)
+#define NT_STATUS_APC_RETURNED_WHILE_IMPERSONATING ((nt_status) 0xC0000711)
+#define NT_STATUS_APPHELP_BLOCK ((nt_status) 0xC000035D)
+#define NT_STATUS_APP_INIT_FAILURE ((nt_status) 0xC0000145)
+#define NT_STATUS_ARBITRATION_UNHANDLED ((nt_status) 0x40000026)
+#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED ((nt_status) 0xC000008C)
+#define NT_STATUS_ASSERTION_FAILURE ((nt_status) 0xC0000420)
+#define NT_STATUS_AUDITING_DISABLED ((nt_status) 0xC0000356)
+#define NT_STATUS_AUDIT_FAILED ((nt_status) 0xC0000244)
+#define NT_STATUS_AUTHENTICATION_FIREWALL_FAILED ((nt_status) 0xC0000413)
+#define NT_STATUS_AUTHIP_FAILURE ((nt_status) 0xC000A086)
+#define NT_STATUS_BACKUP_CONTROLLER ((nt_status) 0xC0000187)
+#define NT_STATUS_BAD_BINDINGS ((nt_status) 0xC000035B)
+#define NT_STATUS_BAD_CLUSTERS ((nt_status) 0xC0000805)
+#define NT_STATUS_BAD_COMPRESSION_BUFFER ((nt_status) 0xC0000242)
+#define NT_STATUS_BAD_CURRENT_DIRECTORY ((nt_status) 0x40000007)
+#define NT_STATUS_BAD_DESCRIPTOR_FORMAT ((nt_status) 0xC00000E7)
+#define NT_STATUS_BAD_DEVICE_TYPE ((nt_status) 0xC00000CB)
+#define NT_STATUS_BAD_DLL_ENTRYPOINT ((nt_status) 0xC0000251)
+#define NT_STATUS_BAD_FILE_TYPE ((nt_status) 0xC0000903)
+#define NT_STATUS_BAD_FUNCTION_TABLE ((nt_status) 0xC00000FF)
+#define NT_STATUS_BAD_IMPERSONATION_LEVEL ((nt_status) 0xC00000A5)
+#define NT_STATUS_BAD_INHERITANCE_ACL ((nt_status) 0xC000007D)
+#define NT_STATUS_BAD_INITIAL_PC ((nt_status) 0xC000000A)
+#define NT_STATUS_BAD_INITIAL_STACK ((nt_status) 0xC0000009)
+#define NT_STATUS_BAD_LOGON_SESSION_STATE ((nt_status) 0xC0000104)
+#define NT_STATUS_BAD_MASTER_BOOT_RECORD ((nt_status) 0xC00000A9)
+#define NT_STATUS_BAD_MCFG_TABLE ((nt_status) 0xC0000908)
+#define NT_STATUS_BAD_NETWORK_NAME ((nt_status) 0xC00000CC)
+#define NT_STATUS_BAD_NETWORK_PATH ((nt_status) 0xC00000BE)
+#define NT_STATUS_BAD_REMOTE_ADAPTER ((nt_status) 0xC00000C5)
+#define NT_STATUS_BAD_SERVICE_ENTRYPOINT ((nt_status) 0xC0000252)
+#define NT_STATUS_BAD_STACK ((nt_status) 0xC0000028)
+#define NT_STATUS_BAD_TOKEN_TYPE ((nt_status) 0xC00000A8)
+#define NT_STATUS_BAD_VALIDATION_CLASS ((nt_status) 0xC00000A7)
+#define NT_STATUS_BAD_WORKING_SET_LIMIT ((nt_status) 0xC000004C)
+#define NT_STATUS_BEGINNING_OF_MEDIA ((nt_status) 0x8000001F)
+#define NT_STATUS_BEYOND_VDL ((nt_status) 0xC0000432)
+#define NT_STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((nt_status) 0xC000016E)
+#define NT_STATUS_BIZRULES_NOT_ENABLED ((nt_status) 0x40000034)
+#define NT_STATUS_BREAKPOINT ((nt_status) 0x80000003)
+#define NT_STATUS_BUFFER_ALL_ZEROS ((nt_status) 0x00000117)
+#define NT_STATUS_BUFFER_OVERFLOW ((nt_status) 0x80000005)
+#define NT_STATUS_BUFFER_TOO_SMALL ((nt_status) 0xC0000023)
+#define NT_STATUS_BUS_RESET ((nt_status) 0x8000001D)
+#define NT_STATUS_CACHE_PAGE_LOCKED ((nt_status) 0x00000115)
+#define NT_STATUS_CALLBACK_BYPASS ((nt_status) 0xC0000503)
+#define NT_STATUS_CALLBACK_POP_STACK ((nt_status) 0xC0000423)
+#define NT_STATUS_CALLBACK_RETURNED_LANG ((nt_status) 0xC000071F)
+#define NT_STATUS_CALLBACK_RETURNED_LDR_LOCK ((nt_status) 0xC000071E)
+#define NT_STATUS_CALLBACK_RETURNED_PRI_BACK ((nt_status) 0xC0000720)
+#define NT_STATUS_CALLBACK_RETURNED_THREAD_AFFINITY ((nt_status) 0xC0000721)
+#define NT_STATUS_CALLBACK_RETURNED_THREAD_PRIORITY ((nt_status) 0xC000071B)
+#define NT_STATUS_CALLBACK_RETURNED_TRANSACTION ((nt_status) 0xC000071D)
+#define NT_STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING ((nt_status) 0xC0000710)
+#define NT_STATUS_CANCELLED ((nt_status) 0xC0000120)
+#define NT_STATUS_CANNOT_ABORT_TRANSACTIONS ((nt_status) 0xC019004D)
+#define NT_STATUS_CANNOT_ACCEPT_TRANSACTED_WORK ((nt_status) 0xC019004C)
+#define NT_STATUS_CANNOT_BREAK_OPLOCK ((nt_status) 0xC0000909)
+#define NT_STATUS_CANNOT_DELETE ((nt_status) 0xC0000121)
+#define NT_STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION ((nt_status) 0xC0190044)
+#define NT_STATUS_CANNOT_IMPERSONATE ((nt_status) 0xC000010D)
+#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE ((nt_status) 0xC0000218)
+#define NT_STATUS_CANNOT_MAKE ((nt_status) 0xC00002EA)
+#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO ((nt_status) 0xC00000DA)
+#define NT_STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY ((nt_status) 0xC0190037)
+#define NT_STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS ((nt_status) 0xC0190026)
+#define NT_STATUS_CANT_CROSS_RM_BOUNDARY ((nt_status) 0xC0190038)
+#define NT_STATUS_CANT_DISABLE_MANDATORY ((nt_status) 0xC000005D)
+#define NT_STATUS_CANT_ENABLE_DENY_ONLY ((nt_status) 0xC00002B3)
+#define NT_STATUS_CANT_OPEN_ANONYMOUS ((nt_status) 0xC00000A6)
+#define NT_STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT ((nt_status) 0xC0190025)
+#define NT_STATUS_CANT_RECOVER_WITH_HANDLE_OPEN ((nt_status) 0x80190031)
+#define NT_STATUS_CANT_TERMINATE_SELF ((nt_status) 0xC00000DB)
+#define NT_STATUS_CANT_WAIT ((nt_status) 0xC00000D8)
+#define NT_STATUS_CARDBUS_NOT_SUPPORTED ((nt_status) 0x40000027)
+#define NT_STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE ((nt_status) 0xC0000714)
+#define NT_STATUS_CHECKING_FILE_SYSTEM ((nt_status) 0x40000014)
+#define NT_STATUS_CHECKOUT_REQUIRED ((nt_status) 0xC0000902)
+#define NT_STATUS_CHILD_MUST_BE_VOLATILE ((nt_status) 0xC0000181)
+#define NT_STATUS_CLEANER_CARTRIDGE_INSTALLED ((nt_status) 0x80000027)
+#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((nt_status) 0xC0000223)
+#define NT_STATUS_CLUSTER_INVALID_NETWORK ((nt_status) 0xC0130010)
+#define NT_STATUS_CLUSTER_INVALID_NETWORK_PROVIDER ((nt_status) 0xC013000B)
+#define NT_STATUS_CLUSTER_INVALID_NODE ((nt_status) 0xC0130001)
+#define NT_STATUS_CLUSTER_INVALID_REQUEST ((nt_status) 0xC013000A)
+#define NT_STATUS_CLUSTER_JOIN_IN_PROGRESS ((nt_status) 0xC0130003)
+#define NT_STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS ((nt_status) 0xC013000F)
+#define NT_STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND ((nt_status) 0xC0130005)
+#define NT_STATUS_CLUSTER_NETINTERFACE_EXISTS ((nt_status) 0xC0130008)
+#define NT_STATUS_CLUSTER_NETINTERFACE_NOT_FOUND ((nt_status) 0xC0130009)
+#define NT_STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE ((nt_status) 0x80130004)
+#define NT_STATUS_CLUSTER_NETWORK_ALREADY_ONLINE ((nt_status) 0x80130003)
+#define NT_STATUS_CLUSTER_NETWORK_EXISTS ((nt_status) 0xC0130006)
+#define NT_STATUS_CLUSTER_NETWORK_NOT_FOUND ((nt_status) 0xC0130007)
+#define NT_STATUS_CLUSTER_NETWORK_NOT_INTERNAL ((nt_status) 0xC0130016)
+#define NT_STATUS_CLUSTER_NODE_ALREADY_DOWN ((nt_status) 0x80130002)
+#define NT_STATUS_CLUSTER_NODE_ALREADY_MEMBER ((nt_status) 0x80130005)
+#define NT_STATUS_CLUSTER_NODE_ALREADY_UP ((nt_status) 0x80130001)
+#define NT_STATUS_CLUSTER_NODE_DOWN ((nt_status) 0xC013000C)
+#define NT_STATUS_CLUSTER_NODE_EXISTS ((nt_status) 0xC0130002)
+#define NT_STATUS_CLUSTER_NODE_NOT_FOUND ((nt_status) 0xC0130004)
+#define NT_STATUS_CLUSTER_NODE_NOT_MEMBER ((nt_status) 0xC013000E)
+#define NT_STATUS_CLUSTER_NODE_NOT_PAUSED ((nt_status) 0xC0130014)
+#define NT_STATUS_CLUSTER_NODE_PAUSED ((nt_status) 0xC0130013)
+#define NT_STATUS_CLUSTER_NODE_UNREACHABLE ((nt_status) 0xC013000D)
+#define NT_STATUS_CLUSTER_NODE_UP ((nt_status) 0xC0130012)
+#define NT_STATUS_CLUSTER_NO_NET_ADAPTERS ((nt_status) 0xC0130011)
+#define NT_STATUS_CLUSTER_NO_SECURITY_CONTEXT ((nt_status) 0xC0130015)
+#define NT_STATUS_CLUSTER_POISONED ((nt_status) 0xC0130017)
+#define NT_STATUS_COMMITMENT_LIMIT ((nt_status) 0xC000012D)
+#define NT_STATUS_COMMITMENT_MINIMUM ((nt_status) 0xC00002C8)
+#define NT_STATUS_COMPRESSION_DISABLED ((nt_status) 0xC0000426)
+#define NT_STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION ((nt_status) 0xC0190056)
+#define NT_STATUS_CONFLICTING_ADDRESSES ((nt_status) 0xC0000018)
+#define NT_STATUS_CONNECTION_ABORTED ((nt_status) 0xC0000241)
+#define NT_STATUS_CONNECTION_ACTIVE ((nt_status) 0xC000023B)
+#define NT_STATUS_CONNECTION_COUNT_LIMIT ((nt_status) 0xC0000246)
+#define NT_STATUS_CONNECTION_DISCONNECTED ((nt_status) 0xC000020C)
+#define NT_STATUS_CONNECTION_INVALID ((nt_status) 0xC000023A)
+#define NT_STATUS_CONNECTION_IN_USE ((nt_status) 0xC0000108)
+#define NT_STATUS_CONNECTION_REFUSED ((nt_status) 0xC0000236)
+#define NT_STATUS_CONNECTION_RESET ((nt_status) 0xC000020D)
+#define NT_STATUS_CONTENT_BLOCKED ((nt_status) 0xC0000804)
+#define NT_STATUS_CONTEXT_MISMATCH ((nt_status) 0xC0000719)
+#define NT_STATUS_CONTROL_C_EXIT ((nt_status) 0xC000013A)
+#define NT_STATUS_CONVERT_TO_LARGE ((nt_status) 0xC000022C)
+#define NT_STATUS_COPY_PROTECTION_FAILURE ((nt_status) 0xC0000305)
+#define NT_STATUS_CORRUPT_SYSTEM_FILE ((nt_status) 0xC00002C4)
+#define NT_STATUS_COULD_NOT_INTERPRET ((nt_status) 0xC00000B9)
+#define NT_STATUS_COULD_NOT_RESIZE_LOG ((nt_status) 0x80190009)
+#define NT_STATUS_CRASH_DUMP ((nt_status) 0x00000116)
+#define NT_STATUS_CRC_ERROR ((nt_status) 0xC000003F)
+#define NT_STATUS_CRED_REQUIRES_CONFIRMATION ((nt_status) 0xC0000440)
+#define NT_STATUS_CRM_PROTOCOL_ALREADY_EXISTS ((nt_status) 0xC019000F)
+#define NT_STATUS_CRM_PROTOCOL_NOT_FOUND ((nt_status) 0xC0190011)
+#define NT_STATUS_CROSSREALM_DELEGATION_FAILURE ((nt_status) 0xC000040B)
+#define NT_STATUS_CRYPTO_SYSTEM_INVALID ((nt_status) 0xC00002F3)
+#define NT_STATUS_CSS_AUTHENTICATION_FAILURE ((nt_status) 0xC0000306)
+#define NT_STATUS_CSS_KEY_NOT_ESTABLISHED ((nt_status) 0xC0000308)
+#define NT_STATUS_CSS_KEY_NOT_PRESENT ((nt_status) 0xC0000307)
+#define NT_STATUS_CSS_REGION_MISMATCH ((nt_status) 0xC000030A)
+#define NT_STATUS_CSS_RESETS_EXHAUSTED ((nt_status) 0xC000030B)
+#define NT_STATUS_CSS_SCRAMBLED_SECTOR ((nt_status) 0xC0000309)
+#define NT_STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE ((nt_status) 0xC0000443)
+#define NT_STATUS_CS_ENCRYPTION_FILE_NOT_CSE ((nt_status) 0xC0000445)
+#define NT_STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE ((nt_status) 0xC0000441)
+#define NT_STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE ((nt_status) 0xC0000444)
+#define NT_STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER ((nt_status) 0xC0000442)
+#define NT_STATUS_CTL_FILE_NOT_SUPPORTED ((nt_status) 0xC0000057)
+#define NT_STATUS_CTX_BAD_VIDEO_MODE ((nt_status) 0xC00A0018)
+#define NT_STATUS_CTX_CDM_CONNECT ((nt_status) 0x400A0004)
+#define NT_STATUS_CTX_CDM_DISCONNECT ((nt_status) 0x400A0005)
+#define NT_STATUS_CTX_CLIENT_LICENSE_IN_USE ((nt_status) 0xC00A0034)
+#define NT_STATUS_CTX_CLIENT_LICENSE_NOT_SET ((nt_status) 0xC00A0033)
+#define NT_STATUS_CTX_CLIENT_QUERY_TIMEOUT ((nt_status) 0xC00A0026)
+#define NT_STATUS_CTX_CLOSE_PENDING ((nt_status) 0xC00A0006)
+#define NT_STATUS_CTX_CONSOLE_CONNECT ((nt_status) 0xC00A0028)
+#define NT_STATUS_CTX_CONSOLE_DISCONNECT ((nt_status) 0xC00A0027)
+#define NT_STATUS_CTX_GRAPHICS_INVALID ((nt_status) 0xC00A0022)
+#define NT_STATUS_CTX_INVALID_MODEMNAME ((nt_status) 0xC00A0009)
+#define NT_STATUS_CTX_INVALID_PD ((nt_status) 0xC00A0002)
+#define NT_STATUS_CTX_INVALID_WD ((nt_status) 0xC00A002E)
+#define NT_STATUS_CTX_LICENSE_CLIENT_INVALID ((nt_status) 0xC00A0012)
+#define NT_STATUS_CTX_LICENSE_EXPIRED ((nt_status) 0xC00A0014)
+#define NT_STATUS_CTX_LICENSE_NOT_AVAILABLE ((nt_status) 0xC00A0013)
+#define NT_STATUS_CTX_LOGON_DISABLED ((nt_status) 0xC00A0037)
+#define NT_STATUS_CTX_MODEM_INF_NOT_FOUND ((nt_status) 0xC00A0008)
+#define NT_STATUS_CTX_MODEM_RESPONSE_BUSY ((nt_status) 0xC00A000E)
+#define NT_STATUS_CTX_MODEM_RESPONSE_NO_CARRIER ((nt_status) 0xC00A000C)
+#define NT_STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE ((nt_status) 0xC00A000D)
+#define NT_STATUS_CTX_MODEM_RESPONSE_TIMEOUT ((nt_status) 0xC00A000B)
+#define NT_STATUS_CTX_MODEM_RESPONSE_VOICE ((nt_status) 0xC00A000F)
+#define NT_STATUS_CTX_NOT_CONSOLE ((nt_status) 0xC00A0024)
+#define NT_STATUS_CTX_NO_OUTBUF ((nt_status) 0xC00A0007)
+#define NT_STATUS_CTX_PD_NOT_FOUND ((nt_status) 0xC00A0003)
+#define NT_STATUS_CTX_RESPONSE_ERROR ((nt_status) 0xC00A000A)
+#define NT_STATUS_CTX_SECURITY_LAYER_ERROR ((nt_status) 0xC00A0038)
+#define NT_STATUS_CTX_SHADOW_DENIED ((nt_status) 0xC00A002A)
+#define NT_STATUS_CTX_SHADOW_DISABLED ((nt_status) 0xC00A0031)
+#define NT_STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE ((nt_status) 0xC00A0035)
+#define NT_STATUS_CTX_SHADOW_INVALID ((nt_status) 0xC00A0030)
+#define NT_STATUS_CTX_SHADOW_NOT_RUNNING ((nt_status) 0xC00A0036)
+#define NT_STATUS_CTX_TD_ERROR ((nt_status) 0xC00A0010)
+#define NT_STATUS_CTX_WD_NOT_FOUND ((nt_status) 0xC00A002F)
+#define NT_STATUS_CTX_WINSTATION_ACCESS_DENIED ((nt_status) 0xC00A002B)
+#define NT_STATUS_CTX_WINSTATION_BUSY ((nt_status) 0xC00A0017)
+#define NT_STATUS_CTX_WINSTATION_NAME_COLLISION ((nt_status) 0xC00A0016)
+#define NT_STATUS_CTX_WINSTATION_NAME_INVALID ((nt_status) 0xC00A0001)
+#define NT_STATUS_CTX_WINSTATION_NOT_FOUND ((nt_status) 0xC00A0015)
+#define NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((nt_status) 0xC00002E9)
+#define NT_STATUS_CURRENT_TRANSACTION_NOT_VALID ((nt_status) 0xC0190018)
+#define NT_STATUS_DATATYPE_MISALIGNMENT ((nt_status) 0x80000002)
+#define NT_STATUS_DATATYPE_MISALIGNMENT_ERROR ((nt_status) 0xC00002C5)
+#define NT_STATUS_DATA_ERROR ((nt_status) 0xC000003E)
+#define NT_STATUS_DATA_LATE_ERROR ((nt_status) 0xC000003D)
+#define NT_STATUS_DATA_LOST_REPAIR ((nt_status) 0x80000803)
+#define NT_STATUS_DATA_NOT_ACCEPTED ((nt_status) 0xC000021B)
+#define NT_STATUS_DATA_OVERRUN ((nt_status) 0xC000003C)
+#define NT_STATUS_DEBUGGER_INACTIVE ((nt_status) 0xC0000354)
+#define NT_STATUS_DEBUG_ATTACH_FAILED ((nt_status) 0xC0000219)
+#define NT_STATUS_DECRYPTION_FAILED ((nt_status) 0xC000028B)
+#define NT_STATUS_DELAY_LOAD_FAILED ((nt_status) 0xC0000412)
+#define NT_STATUS_DELETE_PENDING ((nt_status) 0xC0000056)
+#define NT_STATUS_DESTINATION_ELEMENT_FULL ((nt_status) 0xC0000284)
+#define NT_STATUS_DEVICE_ALREADY_ATTACHED ((nt_status) 0xC0000038)
+#define NT_STATUS_DEVICE_BUSY ((nt_status) 0x80000011)
+#define NT_STATUS_DEVICE_CONFIGURATION_ERROR ((nt_status) 0xC0000182)
+#define NT_STATUS_DEVICE_DATA_ERROR ((nt_status) 0xC000009C)
+#define NT_STATUS_DEVICE_DOES_NOT_EXIST ((nt_status) 0xC00000C0)
+#define NT_STATUS_DEVICE_DOOR_OPEN ((nt_status) 0x80000289)
+#define NT_STATUS_DEVICE_ENUMERATION_ERROR ((nt_status) 0xC0000366)
+#define NT_STATUS_DEVICE_NOT_CONNECTED ((nt_status) 0xC000009D)
+#define NT_STATUS_DEVICE_NOT_PARTITIONED ((nt_status) 0xC0000174)
+#define NT_STATUS_DEVICE_NOT_READY ((nt_status) 0xC00000A3)
+#define NT_STATUS_DEVICE_OFF_LINE ((nt_status) 0x80000010)
+#define NT_STATUS_DEVICE_PAPER_EMPTY ((nt_status) 0x8000000E)
+#define NT_STATUS_DEVICE_POWERED_OFF ((nt_status) 0x8000000F)
+#define NT_STATUS_DEVICE_PROTOCOL_ERROR ((nt_status) 0xC0000186)
+#define NT_STATUS_DEVICE_REMOVED ((nt_status) 0xC00002B6)
+#define NT_STATUS_DEVICE_REQUIRES_CLEANING ((nt_status) 0x80000288)
+#define NT_STATUS_DFS_EXIT_PATH_FOUND ((nt_status) 0xC000009B)
+#define NT_STATUS_DFS_UNAVAILABLE ((nt_status) 0xC000026D)
+#define NT_STATUS_DIRECTORY_IS_A_REPARSE_POINT ((nt_status) 0xC0000281)
+#define NT_STATUS_DIRECTORY_NOT_EMPTY ((nt_status) 0xC0000101)
+#define NT_STATUS_DIRECTORY_NOT_RM ((nt_status) 0xC0190008)
+#define NT_STATUS_DIRECTORY_SERVICE_REQUIRED ((nt_status) 0xC00002B1)
+#define NT_STATUS_DISK_CORRUPT_ERROR ((nt_status) 0xC0000032)
+#define NT_STATUS_DISK_FULL ((nt_status) 0xC000007F)
+#define NT_STATUS_DISK_OPERATION_FAILED ((nt_status) 0xC000016A)
+#define NT_STATUS_DISK_QUOTA_EXCEEDED ((nt_status) 0xC0000802)
+#define NT_STATUS_DISK_RECALIBRATE_FAILED ((nt_status) 0xC0000169)
+#define NT_STATUS_DISK_REPAIR_DISABLED ((nt_status) 0xC0000800)
+#define NT_STATUS_DISK_RESET_FAILED ((nt_status) 0xC000016B)
+#define NT_STATUS_DLL_INIT_FAILED ((nt_status) 0xC0000142)
+#define NT_STATUS_DLL_INIT_FAILED_LOGOFF ((nt_status) 0xC000026B)
+#define NT_STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((nt_status) 0x8000002C)
+#define NT_STATUS_DLL_MIGHT_BE_INSECURE ((nt_status) 0x8000002B)
+#define NT_STATUS_DLL_NOT_FOUND ((nt_status) 0xC0000135)
+#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((nt_status) 0xC0000233)
+#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((nt_status) 0xC000015E)
+#define NT_STATUS_DOMAIN_EXISTS ((nt_status) 0xC00000E0)
+#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED ((nt_status) 0xC00000E1)
+#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT ((nt_status) 0xC000019B)
+#define NT_STATUS_DOWNGRADE_DETECTED ((nt_status) 0xC0000388)
+#define NT_STATUS_DRIVERS_LEAKING_LOCKED_PAGES ((nt_status) 0x4000002D)
+#define NT_STATUS_DRIVER_BLOCKED ((nt_status) 0xC000036C)
+#define NT_STATUS_DRIVER_BLOCKED_CRITICAL ((nt_status) 0xC000036B)
+#define NT_STATUS_DRIVER_CANCEL_TIMEOUT ((nt_status) 0xC000021E)
+#define NT_STATUS_DRIVER_DATABASE_ERROR ((nt_status) 0xC000036D)
+#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((nt_status) 0xC0000263)
+#define NT_STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((nt_status) 0xC000038E)
+#define NT_STATUS_DRIVER_FAILED_SLEEP ((nt_status) 0xC00002C2)
+#define NT_STATUS_DRIVER_INTERNAL_ERROR ((nt_status) 0xC0000183)
+#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND ((nt_status) 0xC0000262)
+#define NT_STATUS_DRIVER_PROCESS_TERMINATED ((nt_status) 0xC0000450)
+#define NT_STATUS_DRIVER_UNABLE_TO_LOAD ((nt_status) 0xC000026C)
+#define NT_STATUS_DS_ADMIN_LIMIT_EXCEEDED ((nt_status) 0xC00002C1)
+#define NT_STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((nt_status) 0xC0000358)
+#define NT_STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((nt_status) 0xC00002A4)
+#define NT_STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((nt_status) 0xC00002A3)
+#define NT_STATUS_DS_BUSY ((nt_status) 0xC00002A5)
+#define NT_STATUS_DS_CANT_MOD_OBJ_CLASS ((nt_status) 0xC00002AE)
+#define NT_STATUS_DS_CANT_MOD_PRIMARYGROUPID ((nt_status) 0xC00002D0)
+#define NT_STATUS_DS_CANT_ON_NON_LEAF ((nt_status) 0xC00002AC)
+#define NT_STATUS_DS_CANT_ON_RDN ((nt_status) 0xC00002AD)
+#define NT_STATUS_DS_CANT_START ((nt_status) 0xC00002E1)
+#define NT_STATUS_DS_CROSS_DOM_MOVE_FAILED ((nt_status) 0xC00002AF)
+#define NT_STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST ((nt_status) 0xC000041A)
+#define NT_STATUS_DS_DOMAIN_RENAME_IN_PROGRESS ((nt_status) 0xC0000801)
+#define NT_STATUS_DS_DUPLICATE_ID_FOUND ((nt_status) 0xC0000405)
+#define NT_STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST ((nt_status) 0xC000041B)
+#define NT_STATUS_DS_GC_NOT_AVAILABLE ((nt_status) 0xC00002B0)
+#define NT_STATUS_DS_GC_REQUIRED ((nt_status) 0xC00002E4)
+#define NT_STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((nt_status) 0xC00002DA)
+#define NT_STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((nt_status) 0xC00002D7)
+#define NT_STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((nt_status) 0xC00002D8)
+#define NT_STATUS_DS_GROUP_CONVERSION_ERROR ((nt_status) 0xC0000406)
+#define NT_STATUS_DS_HAVE_PRIMARY_MEMBERS ((nt_status) 0xC00002DC)
+#define NT_STATUS_DS_INCORRECT_ROLE_OWNER ((nt_status) 0xC00002A9)
+#define NT_STATUS_DS_INIT_FAILURE ((nt_status) 0xC00002E2)
+#define NT_STATUS_DS_INIT_FAILURE_CONSOLE ((nt_status) 0xC00002EC)
+#define NT_STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((nt_status) 0xC00002A2)
+#define NT_STATUS_DS_INVALID_GROUP_TYPE ((nt_status) 0xC00002D4)
+#define NT_STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((nt_status) 0xC00002DB)
+#define NT_STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((nt_status) 0xC00002E5)
+#define NT_STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((nt_status) 0xC00002E7)
+#define NT_STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((nt_status) 0x00000121)
+#define NT_STATUS_DS_NAME_NOT_UNIQUE ((nt_status) 0xC0000404)
+#define NT_STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((nt_status) 0xC00002A1)
+#define NT_STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((nt_status) 0xC00002E6)
+#define NT_STATUS_DS_NO_MORE_RIDS ((nt_status) 0xC00002A8)
+#define NT_STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((nt_status) 0xC00002D5)
+#define NT_STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((nt_status) 0xC00002D6)
+#define NT_STATUS_DS_NO_RIDS_ALLOCATED ((nt_status) 0xC00002A7)
+#define NT_STATUS_DS_OBJ_CLASS_VIOLATION ((nt_status) 0xC00002AB)
+#define NT_STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS ((nt_status) 0xC000A087)
+#define NT_STATUS_DS_OID_NOT_FOUND ((nt_status) 0xC000A088)
+#define NT_STATUS_DS_RIDMGR_INIT_ERROR ((nt_status) 0xC00002AA)
+#define NT_STATUS_DS_SAM_INIT_FAILURE ((nt_status) 0xC00002CB)
+#define NT_STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((nt_status) 0xC00002ED)
+#define NT_STATUS_DS_SENSITIVE_GROUP_VIOLATION ((nt_status) 0xC00002CD)
+#define NT_STATUS_DS_SHUTTING_DOWN ((nt_status) 0x40000370)
+#define NT_STATUS_DS_SRC_SID_EXISTS_IN_FOREST ((nt_status) 0xC0000419)
+#define NT_STATUS_DS_UNAVAILABLE ((nt_status) 0xC00002A6)
+#define NT_STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((nt_status) 0xC00002D9)
+#define NT_STATUS_DS_VERSION_CHECK_FAILURE ((nt_status) 0xC0000355)
+#define NT_STATUS_DUPLICATE_NAME ((nt_status) 0xC00000BD)
+#define NT_STATUS_DUPLICATE_OBJECTID ((nt_status) 0xC000022A)
+#define NT_STATUS_EAS_NOT_SUPPORTED ((nt_status) 0xC000004F)
+#define NT_STATUS_EA_CORRUPT_ERROR ((nt_status) 0xC0000053)
+#define NT_STATUS_EA_LIST_INCONSISTENT ((nt_status) 0x80000014)
+#define NT_STATUS_EA_TOO_LARGE ((nt_status) 0xC0000050)
+#define NT_STATUS_EFS_ALG_BLOB_TOO_BIG ((nt_status) 0xC0000352)
+#define NT_STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION ((nt_status) 0xC019003E)
+#define NT_STATUS_ELEVATION_REQUIRED ((nt_status) 0xC000042C)
+#define NT_STATUS_ENCOUNTERED_WRITE_IN_PROGRESS ((nt_status) 0xC0000433)
+#define NT_STATUS_ENCRYPTION_FAILED ((nt_status) 0xC000028A)
+#define NT_STATUS_END_OF_FILE ((nt_status) 0xC0000011)
+#define NT_STATUS_END_OF_MEDIA ((nt_status) 0x8000001E)
+#define NT_STATUS_ENLISTMENT_NOT_FOUND ((nt_status) 0xC0190050)
+#define NT_STATUS_ENLISTMENT_NOT_SUPERIOR ((nt_status) 0xC0190033)
+#define NT_STATUS_ENTRYPOINT_NOT_FOUND ((nt_status) 0xC0000139)
+#define NT_STATUS_EOM_OVERFLOW ((nt_status) 0xC0000177)
+#define NT_STATUS_EVALUATION_EXPIRATION ((nt_status) 0xC0000268)
+#define NT_STATUS_EVENTLOG_CANT_START ((nt_status) 0xC000018F)
+#define NT_STATUS_EVENTLOG_FILE_CHANGED ((nt_status) 0xC0000197)
+#define NT_STATUS_EVENTLOG_FILE_CORRUPT ((nt_status) 0xC000018E)
+#define NT_STATUS_EVENT_DONE ((nt_status) 0x40000012)
+#define NT_STATUS_EVENT_PENDING ((nt_status) 0x40000013)
+#define NT_STATUS_EXPIRED_HANDLE ((nt_status) 0xC0190060)
+#define NT_STATUS_EXTRANEOUS_INFORMATION ((nt_status) 0x80000017)
+#define NT_STATUS_FAILED_DRIVER_ENTRY ((nt_status) 0xC0000365)
+#define NT_STATUS_FAILED_STACK_SWITCH ((nt_status) 0xC0000373)
+#define NT_STATUS_FAIL_CHECK ((nt_status) 0xC0000229)
+#define NT_STATUS_FAIL_FAST_EXCEPTION ((nt_status) 0xC0000602)
+#define NT_STATUS_FATAL_APP_EXIT ((nt_status) 0x40000015)
+#define NT_STATUS_FILEMARK_DETECTED ((nt_status) 0x8000001B)
+#define NT_STATUS_FILES_OPEN ((nt_status) 0xC0000107)
+#define NT_STATUS_FILE_CHECKED_OUT ((nt_status) 0xC0000901)
+#define NT_STATUS_FILE_CLOSED ((nt_status) 0xC0000128)
+#define NT_STATUS_FILE_CORRUPT_ERROR ((nt_status) 0xC0000102)
+#define NT_STATUS_FILE_DELETED ((nt_status) 0xC0000123)
+#define NT_STATUS_FILE_ENCRYPTED ((nt_status) 0xC0000293)
+#define NT_STATUS_FILE_FORCED_CLOSED ((nt_status) 0xC00000B6)
+#define NT_STATUS_FILE_IDENTITY_NOT_PERSISTENT ((nt_status) 0xC0190036)
+#define NT_STATUS_FILE_INVALID ((nt_status) 0xC0000098)
+#define NT_STATUS_FILE_IS_A_DIRECTORY ((nt_status) 0xC00000BA)
+#define NT_STATUS_FILE_IS_OFFLINE ((nt_status) 0xC0000267)
+#define NT_STATUS_FILE_LOCKED_WITH_ONLY_READERS ((nt_status) 0x0000012A)
+#define NT_STATUS_FILE_LOCKED_WITH_WRITERS ((nt_status) 0x0000012B)
+#define NT_STATUS_FILE_LOCK_CONFLICT ((nt_status) 0xC0000054)
+#define NT_STATUS_FILE_NOT_AVAILABLE ((nt_status) 0xC0000467)
+#define NT_STATUS_FILE_NOT_ENCRYPTED ((nt_status) 0xC0000291)
+#define NT_STATUS_FILE_RENAMED ((nt_status) 0xC00000D5)
+#define NT_STATUS_FILE_SYSTEM_LIMITATION ((nt_status) 0xC0000427)
+#define NT_STATUS_FILE_TOO_LARGE ((nt_status) 0xC0000904)
+#define NT_STATUS_FIRMWARE_UPDATED ((nt_status) 0x4000002C)
+#define NT_STATUS_FLOATED_SECTION ((nt_status) 0xC019004B)
+#define NT_STATUS_FLOAT_DENORMAL_OPERAND ((nt_status) 0xC000008D)
+#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO ((nt_status) 0xC000008E)
+#define NT_STATUS_FLOAT_INEXACT_RESULT ((nt_status) 0xC000008F)
+#define NT_STATUS_FLOAT_INVALID_OPERATION ((nt_status) 0xC0000090)
+#define NT_STATUS_FLOAT_MULTIPLE_FAULTS ((nt_status) 0xC00002B4)
+#define NT_STATUS_FLOAT_MULTIPLE_TRAPS ((nt_status) 0xC00002B5)
+#define NT_STATUS_FLOAT_OVERFLOW ((nt_status) 0xC0000091)
+#define NT_STATUS_FLOAT_STACK_CHECK ((nt_status) 0xC0000092)
+#define NT_STATUS_FLOAT_UNDERFLOW ((nt_status) 0xC0000093)
+#define NT_STATUS_FLOPPY_BAD_REGISTERS ((nt_status) 0xC0000168)
+#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND ((nt_status) 0xC0000165)
+#define NT_STATUS_FLOPPY_UNKNOWN_ERROR ((nt_status) 0xC0000167)
+#define NT_STATUS_FLOPPY_VOLUME ((nt_status) 0xC0000164)
+#define NT_STATUS_FLOPPY_WRONG_CYLINDER ((nt_status) 0xC0000166)
+#define NT_STATUS_FLT_ALREADY_ENLISTED ((nt_status) 0xC01C001B)
+#define NT_STATUS_FLT_BUFFER_TOO_SMALL ((nt_status) 0x801C0001)
+#define NT_STATUS_FLT_CBDQ_DISABLED ((nt_status) 0xC01C000E)
+#define NT_STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND ((nt_status) 0xC01C0016)
+#define NT_STATUS_FLT_CONTEXT_ALREADY_DEFINED ((nt_status) 0xC01C0002)
+#define NT_STATUS_FLT_CONTEXT_ALREADY_LINKED ((nt_status) 0xC01C001C)
+#define NT_STATUS_FLT_DELETING_OBJECT ((nt_status) 0xC01C000B)
+#define NT_STATUS_FLT_DISALLOW_FAST_IO ((nt_status) 0xC01C0004)
+#define NT_STATUS_FLT_DO_NOT_ATTACH ((nt_status) 0xC01C000F)
+#define NT_STATUS_FLT_DO_NOT_DETACH ((nt_status) 0xC01C0010)
+#define NT_STATUS_FLT_DUPLICATE_ENTRY ((nt_status) 0xC01C000D)
+#define NT_STATUS_FLT_FILTER_NOT_FOUND ((nt_status) 0xC01C0013)
+#define NT_STATUS_FLT_FILTER_NOT_READY ((nt_status) 0xC01C0008)
+#define NT_STATUS_FLT_INSTANCE_ALTITUDE_COLLISION ((nt_status) 0xC01C0011)
+#define NT_STATUS_FLT_INSTANCE_NAME_COLLISION ((nt_status) 0xC01C0012)
+#define NT_STATUS_FLT_INSTANCE_NOT_FOUND ((nt_status) 0xC01C0015)
+#define NT_STATUS_FLT_INTERNAL_ERROR ((nt_status) 0xC01C000A)
+#define NT_STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST ((nt_status) 0xC01C0003)
+#define NT_STATUS_FLT_INVALID_CONTEXT_REGISTRATION ((nt_status) 0xC01C0017)
+#define NT_STATUS_FLT_INVALID_NAME_REQUEST ((nt_status) 0xC01C0005)
+#define NT_STATUS_FLT_IO_COMPLETE ((nt_status) 0x001C0001)
+#define NT_STATUS_FLT_MUST_BE_NONPAGED_POOL ((nt_status) 0xC01C000C)
+#define NT_STATUS_FLT_NAME_CACHE_MISS ((nt_status) 0xC01C0018)
+#define NT_STATUS_FLT_NOT_INITIALIZED ((nt_status) 0xC01C0007)
+#define NT_STATUS_FLT_NOT_SAFE_TO_POST_OPERATION ((nt_status) 0xC01C0006)
+#define NT_STATUS_FLT_NO_DEVICE_OBJECT ((nt_status) 0xC01C0019)
+#define NT_STATUS_FLT_NO_HANDLER_DEFINED ((nt_status) 0xC01C0001)
+#define NT_STATUS_FLT_NO_WAITER_FOR_REPLY ((nt_status) 0xC01C0020)
+#define NT_STATUS_FLT_POST_OPERATION_CLEANUP ((nt_status) 0xC01C0009)
+#define NT_STATUS_FLT_VOLUME_ALREADY_MOUNTED ((nt_status) 0xC01C001A)
+#define NT_STATUS_FLT_VOLUME_NOT_FOUND ((nt_status) 0xC01C0014)
+#define NT_STATUS_FORMS_AUTH_REQUIRED ((nt_status) 0xC0000905)
+#define NT_STATUS_FOUND_OUT_OF_SCOPE ((nt_status) 0xC000022E)
+#define NT_STATUS_FREE_VM_NOT_AT_BASE ((nt_status) 0xC000009F)
+#define NT_STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY ((nt_status) 0x00000126)
+#define NT_STATUS_FS_DRIVER_REQUIRED ((nt_status) 0xC000019C)
+#define NT_STATUS_FT_MISSING_MEMBER ((nt_status) 0xC000015F)
+#define NT_STATUS_FT_ORPHANING ((nt_status) 0xC000016D)
+#define NT_STATUS_FT_READ_RECOVERY_FROM_BACKUP ((nt_status) 0x4000000A)
+#define NT_STATUS_FT_WRITE_RECOVERY ((nt_status) 0x4000000B)
+#define NT_STATUS_FULLSCREEN_MODE ((nt_status) 0xC0000159)
+#define NT_STATUS_FVE_ACTION_NOT_ALLOWED ((nt_status) 0xC0210009)
+#define NT_STATUS_FVE_AUTH_INVALID_APPLICATION ((nt_status) 0xC021001B)
+#define NT_STATUS_FVE_AUTH_INVALID_CONFIG ((nt_status) 0xC021001C)
+#define NT_STATUS_FVE_BAD_DATA ((nt_status) 0xC021000A)
+#define NT_STATUS_FVE_BAD_INFORMATION ((nt_status) 0xC0210002)
+#define NT_STATUS_FVE_BAD_METADATA_POINTER ((nt_status) 0xC021001F)
+#define NT_STATUS_FVE_CONV_READ_ERROR ((nt_status) 0xC021000D)
+#define NT_STATUS_FVE_CONV_RECOVERY_FAILED ((nt_status) 0xC0210028)
+#define NT_STATUS_FVE_CONV_WRITE_ERROR ((nt_status) 0xC021000E)
+#define NT_STATUS_FVE_DEBUGGER_ENABLED ((nt_status) 0xC021001D)
+#define NT_STATUS_FVE_DRY_RUN_FAILED ((nt_status) 0xC021001E)
+#define NT_STATUS_FVE_FAILED_AUTHENTICATION ((nt_status) 0xC0210011)
+#define NT_STATUS_FVE_FAILED_BAD_FS ((nt_status) 0xC0210005)
+#define NT_STATUS_FVE_FAILED_SECTOR_SIZE ((nt_status) 0xC0210010)
+#define NT_STATUS_FVE_FAILED_WRONG_FS ((nt_status) 0xC0210004)
+#define NT_STATUS_FVE_FS_MOUNTED ((nt_status) 0xC0210007)
+#define NT_STATUS_FVE_FS_NOT_EXTENDED ((nt_status) 0xC0210006)
+#define NT_STATUS_FVE_KEYFILE_INVALID ((nt_status) 0xC0210014)
+#define NT_STATUS_FVE_KEYFILE_NOT_FOUND ((nt_status) 0xC0210013)
+#define NT_STATUS_FVE_KEYFILE_NO_VMK ((nt_status) 0xC0210015)
+#define NT_STATUS_FVE_LOCKED_VOLUME ((nt_status) 0xC0210000)
+#define NT_STATUS_FVE_NOT_DATA_VOLUME ((nt_status) 0xC021000C)
+#define NT_STATUS_FVE_NOT_ENCRYPTED ((nt_status) 0xC0210001)
+#define NT_STATUS_FVE_NOT_OS_VOLUME ((nt_status) 0xC0210012)
+#define NT_STATUS_FVE_NO_FEATURE_LICENSE ((nt_status) 0xC0210026)
+#define NT_STATUS_FVE_NO_LICENSE ((nt_status) 0xC0210008)
+#define NT_STATUS_FVE_OLD_METADATA_COPY ((nt_status) 0xC0210020)
+#define NT_STATUS_FVE_OVERLAPPED_UPDATE ((nt_status) 0xC021000F)
+#define NT_STATUS_FVE_PARTIAL_METADATA ((nt_status) 0x80210001)
+#define NT_STATUS_FVE_PIN_INVALID ((nt_status) 0xC021001A)
+#define NT_STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED ((nt_status) 0xC0210027)
+#define NT_STATUS_FVE_RAW_ACCESS ((nt_status) 0xC0210022)
+#define NT_STATUS_FVE_RAW_BLOCKED ((nt_status) 0xC0210023)
+#define NT_STATUS_FVE_REBOOT_REQUIRED ((nt_status) 0xC0210021)
+#define NT_STATUS_FVE_TOO_SMALL ((nt_status) 0xC0210003)
+#define NT_STATUS_FVE_TPM_DISABLED ((nt_status) 0xC0210016)
+#define NT_STATUS_FVE_TPM_INVALID_PCR ((nt_status) 0xC0210018)
+#define NT_STATUS_FVE_TPM_NO_VMK ((nt_status) 0xC0210019)
+#define NT_STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO ((nt_status) 0xC0210017)
+#define NT_STATUS_FVE_TRANSIENT_STATE ((nt_status) 0x80210002)
+#define NT_STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG ((nt_status) 0xC0210029)
+#define NT_STATUS_FVE_VOLUME_NOT_BOUND ((nt_status) 0xC021000B)
+#define NT_STATUS_FVE_VOLUME_TOO_SMALL ((nt_status) 0xC0210030)
+#define NT_STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER ((nt_status) 0xC022002C)
+#define NT_STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER ((nt_status) 0xC022002D)
+#define NT_STATUS_FWP_ALREADY_EXISTS ((nt_status) 0xC0220009)
+#define NT_STATUS_FWP_BUILTIN_OBJECT ((nt_status) 0xC0220017)
+#define NT_STATUS_FWP_CALLOUT_NOTIFICATION_FAILED ((nt_status) 0xC0220037)
+#define NT_STATUS_FWP_CALLOUT_NOT_FOUND ((nt_status) 0xC0220001)
+#define NT_STATUS_FWP_CANNOT_PEND ((nt_status) 0xC0220103)
+#define NT_STATUS_FWP_CONDITION_NOT_FOUND ((nt_status) 0xC0220002)
+#define NT_STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT ((nt_status) 0xC022002F)
+#define NT_STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER ((nt_status) 0xC022002E)
+#define NT_STATUS_FWP_DUPLICATE_AUTH_METHOD ((nt_status) 0xC022003C)
+#define NT_STATUS_FWP_DUPLICATE_CONDITION ((nt_status) 0xC022002A)
+#define NT_STATUS_FWP_DUPLICATE_KEYMOD ((nt_status) 0xC022002B)
+#define NT_STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS ((nt_status) 0xC022000B)
+#define NT_STATUS_FWP_EM_NOT_SUPPORTED ((nt_status) 0xC0220032)
+#define NT_STATUS_FWP_FILTER_NOT_FOUND ((nt_status) 0xC0220003)
+#define NT_STATUS_FWP_INCOMPATIBLE_AUTH_CONFIG ((nt_status) 0xC0220038)
+#define NT_STATUS_FWP_INCOMPATIBLE_AUTH_METHOD ((nt_status) 0xC0220030)
+#define NT_STATUS_FWP_INCOMPATIBLE_CIPHER_CONFIG ((nt_status) 0xC0220039)
+#define NT_STATUS_FWP_INCOMPATIBLE_DH_GROUP ((nt_status) 0xC0220031)
+#define NT_STATUS_FWP_INCOMPATIBLE_LAYER ((nt_status) 0xC0220014)
+#define NT_STATUS_FWP_INCOMPATIBLE_SA_STATE ((nt_status) 0xC022001B)
+#define NT_STATUS_FWP_INCOMPATIBLE_TXN ((nt_status) 0xC0220011)
+#define NT_STATUS_FWP_INJECT_HANDLE_CLOSING ((nt_status) 0xC0220101)
+#define NT_STATUS_FWP_INJECT_HANDLE_STALE ((nt_status) 0xC0220102)
+#define NT_STATUS_FWP_INVALID_ACTION_TYPE ((nt_status) 0xC0220024)
+#define NT_STATUS_FWP_INVALID_ENUMERATOR ((nt_status) 0xC022001D)
+#define NT_STATUS_FWP_INVALID_FLAGS ((nt_status) 0xC022001E)
+#define NT_STATUS_FWP_INVALID_INTERVAL ((nt_status) 0xC0220021)
+#define NT_STATUS_FWP_INVALID_NET_MASK ((nt_status) 0xC022001F)
+#define NT_STATUS_FWP_INVALID_PARAMETER ((nt_status) 0xC0220035)
+#define NT_STATUS_FWP_INVALID_RANGE ((nt_status) 0xC0220020)
+#define NT_STATUS_FWP_INVALID_WEIGHT ((nt_status) 0xC0220025)
+#define NT_STATUS_FWP_IN_USE ((nt_status) 0xC022000A)
+#define NT_STATUS_FWP_KM_CLIENTS_ONLY ((nt_status) 0xC0220015)
+#define NT_STATUS_FWP_LAYER_NOT_FOUND ((nt_status) 0xC0220004)
+#define NT_STATUS_FWP_LIFETIME_MISMATCH ((nt_status) 0xC0220016)
+#define NT_STATUS_FWP_MATCH_TYPE_MISMATCH ((nt_status) 0xC0220026)
+#define NT_STATUS_FWP_NET_EVENTS_DISABLED ((nt_status) 0xC0220013)
+#define NT_STATUS_FWP_NEVER_MATCH ((nt_status) 0xC0220033)
+#define NT_STATUS_FWP_NOTIFICATION_DROPPED ((nt_status) 0xC0220019)
+#define NT_STATUS_FWP_NOT_FOUND ((nt_status) 0xC0220008)
+#define NT_STATUS_FWP_NO_TXN_IN_PROGRESS ((nt_status) 0xC022000D)
+#define NT_STATUS_FWP_NULL_DISPLAY_NAME ((nt_status) 0xC0220023)
+#define NT_STATUS_FWP_NULL_POINTER ((nt_status) 0xC022001C)
+#define NT_STATUS_FWP_OUT_OF_BOUNDS ((nt_status) 0xC0220028)
+#define NT_STATUS_FWP_PROVIDER_CONTEXT_MISMATCH ((nt_status) 0xC0220034)
+#define NT_STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND ((nt_status) 0xC0220006)
+#define NT_STATUS_FWP_PROVIDER_NOT_FOUND ((nt_status) 0xC0220005)
+#define NT_STATUS_FWP_RESERVED ((nt_status) 0xC0220029)
+#define NT_STATUS_FWP_SESSION_ABORTED ((nt_status) 0xC0220010)
+#define NT_STATUS_FWP_SUBLAYER_NOT_FOUND ((nt_status) 0xC0220007)
+#define NT_STATUS_FWP_TCPIP_NOT_READY ((nt_status) 0xC0220100)
+#define NT_STATUS_FWP_TIMEOUT ((nt_status) 0xC0220012)
+#define NT_STATUS_FWP_TOO_MANY_BOOTTIME_FILTERS ((nt_status) 0xC0220018)
+#define NT_STATUS_FWP_TOO_MANY_CALLOUTS ((nt_status) 0xC0220018)
+#define NT_STATUS_FWP_TOO_MANY_SUBLAYERS ((nt_status) 0xC0220036)
+#define NT_STATUS_FWP_TRAFFIC_MISMATCH ((nt_status) 0xC022001A)
+#define NT_STATUS_FWP_TXN_ABORTED ((nt_status) 0xC022000F)
+#define NT_STATUS_FWP_TXN_IN_PROGRESS ((nt_status) 0xC022000E)
+#define NT_STATUS_FWP_TYPE_MISMATCH ((nt_status) 0xC0220027)
+#define NT_STATUS_FWP_WRONG_SESSION ((nt_status) 0xC022000C)
+#define NT_STATUS_FWP_ZERO_LENGTH_ARRAY ((nt_status) 0xC0220022)
+#define NT_STATUS_GENERIC_COMMAND_FAILED ((nt_status) 0xC0150026)
+#define NT_STATUS_GENERIC_NOT_MAPPED ((nt_status) 0xC00000E6)
+#define NT_STATUS_GRACEFUL_DISCONNECT ((nt_status) 0xC0000237)
+#define NT_STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED ((nt_status) 0xC01E043B)
+#define NT_STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY ((nt_status) 0xC01E0433)
+#define NT_STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE ((nt_status) 0xC01E0328)
+#define NT_STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET ((nt_status) 0xC01E0329)
+#define NT_STATUS_GRAPHICS_ADAPTER_WAS_RESET ((nt_status) 0xC01E0003)
+#define NT_STATUS_GRAPHICS_ALLOCATION_BUSY ((nt_status) 0xC01E0102)
+#define NT_STATUS_GRAPHICS_ALLOCATION_CLOSED ((nt_status) 0xC01E0112)
+#define NT_STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST ((nt_status) 0xC01E0116)
+#define NT_STATUS_GRAPHICS_ALLOCATION_INVALID ((nt_status) 0xC01E0106)
+#define NT_STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION ((nt_status) 0xC01E035A)
+#define NT_STATUS_GRAPHICS_CANNOTCOLORCONVERT ((nt_status) 0xC01E0008)
+#define NT_STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN ((nt_status) 0xC01E0343)
+#define NT_STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION ((nt_status) 0xC01E0109)
+#define NT_STATUS_GRAPHICS_CANT_LOCK_MEMORY ((nt_status) 0xC01E0101)
+#define NT_STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION ((nt_status) 0xC01E0111)
+#define NT_STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED ((nt_status) 0xC01E0432)
+#define NT_STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON ((nt_status) 0xC01E0435)
+#define NT_STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED ((nt_status) 0xC01E0434)
+#define NT_STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED ((nt_status) 0xC01E0401)
+#define NT_STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET ((nt_status) 0xC01E035C)
+#define NT_STATUS_GRAPHICS_COPP_NOT_SUPPORTED ((nt_status) 0xC01E0501)
+#define NT_STATUS_GRAPHICS_DATASET_IS_EMPTY ((nt_status) 0x401E034B)
+#define NT_STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING ((nt_status) 0xC01E0587)
+#define NT_STATUS_GRAPHICS_DDCCI_INVALID_DATA ((nt_status) 0xC01E0585)
+#define NT_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM ((nt_status) 0xC01E058B)
+#define NT_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND ((nt_status) 0xC01E0589)
+#define NT_STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH ((nt_status) 0xC01E058A)
+#define NT_STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE ((nt_status) 0xC01E0586)
+#define NT_STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED ((nt_status) 0xC01E0584)
+#define NT_STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP ((nt_status) 0xC01E05E2)
+#define NT_STATUS_GRAPHICS_DRIVER_MISMATCH ((nt_status) 0x401E0117)
+#define NT_STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION ((nt_status) 0xC01E0325)
+#define NT_STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET ((nt_status) 0xC01E031F)
+#define NT_STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET ((nt_status) 0xC01E031D)
+#define NT_STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED ((nt_status) 0xC01E0348)
+#define NT_STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE ((nt_status) 0xC01E0200)
+#define NT_STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST ((nt_status) 0xC01E0581)
+#define NT_STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA ((nt_status) 0xC01E0583)
+#define NT_STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA ((nt_status) 0xC01E0582)
+#define NT_STATUS_GRAPHICS_I2C_NOT_SUPPORTED ((nt_status) 0xC01E0580)
+#define NT_STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT ((nt_status) 0xC01E0355)
+#define NT_STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE ((nt_status) 0xC01E0436)
+#define NT_STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER ((nt_status) 0xC01E0001)
+#define NT_STATUS_GRAPHICS_INTERNAL_ERROR ((nt_status) 0xC01E05E7)
+#define NT_STATUS_GRAPHICS_INVALID_ACTIVE_REGION ((nt_status) 0xC01E030B)
+#define NT_STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE ((nt_status) 0xC01E0114)
+#define NT_STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE ((nt_status) 0xC01E0113)
+#define NT_STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE ((nt_status) 0xC01E0110)
+#define NT_STATUS_GRAPHICS_INVALID_CLIENT_TYPE ((nt_status) 0xC01E035B)
+#define NT_STATUS_GRAPHICS_INVALID_COLORBASIS ((nt_status) 0xC01E033E)
+#define NT_STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE ((nt_status) 0xC01E034F)
+#define NT_STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER ((nt_status) 0xC01E0002)
+#define NT_STATUS_GRAPHICS_INVALID_DRIVER_MODEL ((nt_status) 0xC01E0004)
+#define NT_STATUS_GRAPHICS_INVALID_FREQUENCY ((nt_status) 0xC01E030A)
+#define NT_STATUS_GRAPHICS_INVALID_GAMMA_RAMP ((nt_status) 0xC01E0347)
+#define NT_STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM ((nt_status) 0xC01E0356)
+#define NT_STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR ((nt_status) 0xC01E032B)
+#define NT_STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET ((nt_status) 0xC01E032A)
+#define NT_STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN ((nt_status) 0xC01E0357)
+#define NT_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE ((nt_status) 0xC01E031C)
+#define NT_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET ((nt_status) 0xC01E031B)
+#define NT_STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT ((nt_status) 0xC01E0358)
+#define NT_STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET ((nt_status) 0xC01E0321)
+#define NT_STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE ((nt_status) 0xC01E0322)
+#define NT_STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION ((nt_status) 0xC01E0345)
+#define NT_STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE ((nt_status) 0xC01E034E)
+#define NT_STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL ((nt_status) 0xC01E0344)
+#define NT_STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE ((nt_status) 0xC01E058C)
+#define NT_STATUS_GRAPHICS_INVALID_PIXELFORMAT ((nt_status) 0xC01E033D)
+#define NT_STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE ((nt_status) 0xC01E033F)
+#define NT_STATUS_GRAPHICS_INVALID_POINTER ((nt_status) 0xC01E05E4)
+#define NT_STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE ((nt_status) 0xC01E033A)
+#define NT_STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING ((nt_status) 0xC01E0352)
+#define NT_STATUS_GRAPHICS_INVALID_STRIDE ((nt_status) 0xC01E033C)
+#define NT_STATUS_GRAPHICS_INVALID_TOTAL_REGION ((nt_status) 0xC01E030C)
+#define NT_STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET ((nt_status) 0xC01E0315)
+#define NT_STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET ((nt_status) 0xC01E0316)
+#define NT_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE ((nt_status) 0xC01E0304)
+#define NT_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE ((nt_status) 0xC01E0310)
+#define NT_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET ((nt_status) 0xC01E0305)
+#define NT_STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE ((nt_status) 0xC01E0311)
+#define NT_STATUS_GRAPHICS_INVALID_VIDPN ((nt_status) 0xC01E0303)
+#define NT_STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH ((nt_status) 0xC01E0319)
+#define NT_STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET ((nt_status) 0xC01E0308)
+#define NT_STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET ((nt_status) 0xC01E0309)
+#define NT_STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE ((nt_status) 0xC01E032F)
+#define NT_STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY ((nt_status) 0xC01E0300)
+#define NT_STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON ((nt_status) 0xC01E034D)
+#define NT_STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE ((nt_status) 0xC01E033B)
+#define NT_STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED ((nt_status) 0xC01E0431)
+#define NT_STATUS_GRAPHICS_LEADLINK_START_DEFERRED ((nt_status) 0x401E0437)
+#define NT_STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED ((nt_status) 0xC01E0359)
+#define NT_STATUS_GRAPHICS_MCA_INTERNAL_ERROR ((nt_status) 0xC01E0588)
+#define NT_STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED ((nt_status) 0xC01E05E3)
+#define NT_STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET ((nt_status) 0xC01E0314)
+#define NT_STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE ((nt_status) 0xC01E0324)
+#define NT_STATUS_GRAPHICS_MODE_NOT_IN_MODESET ((nt_status) 0xC01E034A)
+#define NT_STATUS_GRAPHICS_MODE_NOT_PINNED ((nt_status) 0x401E0307)
+#define NT_STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET ((nt_status) 0xC01E032D)
+#define NT_STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE ((nt_status) 0xC01E032E)
+#define NT_STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET ((nt_status) 0xC01E032C)
+#define NT_STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER ((nt_status) 0xC01E0334)
+#define NT_STATUS_GRAPHICS_MONITOR_NOT_CONNECTED ((nt_status) 0xC01E0338)
+#define NT_STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS ((nt_status) 0xC01E058D)
+#define NT_STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED ((nt_status) 0xC01E0349)
+#define NT_STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER ((nt_status) 0xC01E0430)
+#define NT_STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER ((nt_status) 0xC01E0000)
+#define NT_STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER ((nt_status) 0xC01E0438)
+#define NT_STATUS_GRAPHICS_NO_ACTIVE_VIDPN ((nt_status) 0xC01E0336)
+#define NT_STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS ((nt_status) 0xC01E0354)
+#define NT_STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET ((nt_status) 0xC01E0333)
+#define NT_STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME ((nt_status) 0xC01E05E1)
+#define NT_STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT ((nt_status) 0xC01E0341)
+#define NT_STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE ((nt_status) 0xC01E05E5)
+#define NT_STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET ((nt_status) 0x401E034C)
+#define NT_STATUS_GRAPHICS_NO_PREFERRED_MODE ((nt_status) 0x401E031E)
+#define NT_STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN ((nt_status) 0xC01E0323)
+#define NT_STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY ((nt_status) 0xC01E031A)
+#define NT_STATUS_GRAPHICS_NO_VIDEO_MEMORY ((nt_status) 0xC01E0100)
+#define NT_STATUS_GRAPHICS_NO_VIDPNMGR ((nt_status) 0xC01E0335)
+#define NT_STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED ((nt_status) 0xC01E05E0)
+#define NT_STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE ((nt_status) 0xC01E0518)
+#define NT_STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR ((nt_status) 0xC01E051E)
+#define NT_STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET ((nt_status) 0xC01E0516)
+#define NT_STATUS_GRAPHICS_OPM_INTERNAL_ERROR ((nt_status) 0xC01E050B)
+#define NT_STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST ((nt_status) 0xC01E0521)
+#define NT_STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS ((nt_status) 0xC01E0503)
+#define NT_STATUS_GRAPHICS_OPM_INVALID_HANDLE ((nt_status) 0xC01E050C)
+#define NT_STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST ((nt_status) 0xC01E051D)
+#define NT_STATUS_GRAPHICS_OPM_INVALID_POINTER ((nt_status) 0xC01E050A)
+#define NT_STATUS_GRAPHICS_OPM_INVALID_SRM ((nt_status) 0xC01E0512)
+#define NT_STATUS_GRAPHICS_OPM_NOT_SUPPORTED ((nt_status) 0xC01E0500)
+#define NT_STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST ((nt_status) 0xC01E0505)
+#define NT_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP ((nt_status) 0xC01E0514)
+#define NT_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA ((nt_status) 0xC01E0515)
+#define NT_STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP ((nt_status) 0xC01E0513)
+#define NT_STATUS_GRAPHICS_OPM_PARAMETER_ARRAY_TOO_SMALL ((nt_status) 0xC01E0504)
+#define NT_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS ((nt_status) 0xC01E051C)
+#define NT_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS ((nt_status) 0xC01E051F)
+#define NT_STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS ((nt_status) 0xC01E051A)
+#define NT_STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH ((nt_status) 0xC01E0517)
+#define NT_STATUS_GRAPHICS_OPM_SESSION_TYPE_CHANGE_IN_PROGRESS ((nt_status) 0xC01E051B)
+#define NT_STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED ((nt_status) 0xC01E0520)
+#define NT_STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED ((nt_status) 0xC01E050F)
+#define NT_STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED ((nt_status) 0xC01E0510)
+#define NT_STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL ((nt_status) 0xC01E05E6)
+#define NT_STATUS_GRAPHICS_PARTIAL_DATA_POPULATED ((nt_status) 0x401E000A)
+#define NT_STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY ((nt_status) 0xC01E0313)
+#define NT_STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED ((nt_status) 0x401E0351)
+#define NT_STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED ((nt_status) 0xC01E0346)
+#define NT_STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY ((nt_status) 0xC01E0327)
+#define NT_STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET ((nt_status) 0xC01E0312)
+#define NT_STATUS_GRAPHICS_POLLING_TOO_FREQUENTLY ((nt_status) 0x401E0439)
+#define NT_STATUS_GRAPHICS_PRESENT_DENIED ((nt_status) 0xC01E0007)
+#define NT_STATUS_GRAPHICS_PRESENT_MODE_CHANGED ((nt_status) 0xC01E0005)
+#define NT_STATUS_GRAPHICS_PRESENT_OCCLUDED ((nt_status) 0xC01E0006)
+#define NT_STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED ((nt_status) 0xC01E000B)
+#define NT_STATUS_GRAPHICS_PRESENT_UNOCCLUDED ((nt_status) 0xC01E000C)
+#define NT_STATUS_GRAPHICS_PVP_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP ((nt_status) 0xC01E0507)
+#define NT_STATUS_GRAPHICS_PVP_HFS_FAILED ((nt_status) 0xC01E0511)
+#define NT_STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH ((nt_status) 0xC01E050E)
+#define NT_STATUS_GRAPHICS_PVP_MIRRORING_DEVICES_NOT_SUPPORTED ((nt_status) 0xC01E0508)
+#define NT_STATUS_GRAPHICS_PVP_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME ((nt_status) 0xC01E0506)
+#define NT_STATUS_GRAPHICS_PVP_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE ((nt_status) 0xC01E050D)
+#define NT_STATUS_GRAPHICS_RESOURCES_NOT_RELATED ((nt_status) 0xC01E0330)
+#define NT_STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS ((nt_status) 0xC01E05E8)
+#define NT_STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET ((nt_status) 0xC01E0317)
+#define NT_STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE ((nt_status) 0xC01E0331)
+#define NT_STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY ((nt_status) 0xC01E0339)
+#define NT_STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED ((nt_status) 0xC01E0400)
+#define NT_STATUS_GRAPHICS_STALE_MODESET ((nt_status) 0xC01E0320)
+#define NT_STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY ((nt_status) 0xC01E0337)
+#define NT_STATUS_GRAPHICS_START_DEFERRED ((nt_status) 0x401E043A)
+#define NT_STATUS_GRAPHICS_TARGET_ALREADY_IN_SET ((nt_status) 0xC01E0318)
+#define NT_STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE ((nt_status) 0xC01E0332)
+#define NT_STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY ((nt_status) 0xC01E0340)
+#define NT_STATUS_GRAPHICS_TOO_MANY_REFERENCES ((nt_status) 0xC01E0103)
+#define NT_STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED ((nt_status) 0xC01E0353)
+#define NT_STATUS_GRAPHICS_TRY_AGAIN_LATER ((nt_status) 0xC01E0104)
+#define NT_STATUS_GRAPHICS_TRY_AGAIN_NOW ((nt_status) 0xC01E0105)
+#define NT_STATUS_GRAPHICS_UAB_NOT_SUPPORTED ((nt_status) 0xC01E0502)
+#define NT_STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS ((nt_status) 0xC01E0350)
+#define NT_STATUS_GRAPHICS_UNKNOWN_CHILD_STATUS ((nt_status) 0x401E042F)
+#define NT_STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE ((nt_status) 0xC01E0107)
+#define NT_STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED ((nt_status) 0xC01E0108)
+#define NT_STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES ((nt_status) 0xC01E0326)
+#define NT_STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED ((nt_status) 0xC01E0306)
+#define NT_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE ((nt_status) 0xC01E0342)
+#define NT_STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED ((nt_status) 0xC01E0302)
+#define NT_STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED ((nt_status) 0xC01E0301)
+#define NT_STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE ((nt_status) 0xC01E0115)
+#define NT_STATUS_GROUP_EXISTS ((nt_status) 0xC0000065)
+#define NT_STATUS_GUARD_PAGE_VIOLATION ((nt_status) 0x80000001)
+#define NT_STATUS_GUIDS_EXHAUSTED ((nt_status) 0xC0000083)
+#define NT_STATUS_GUID_SUBSTITUTION_MADE ((nt_status) 0x8000000C)
+#define NT_STATUS_HANDLES_CLOSED ((nt_status) 0x8000000A)
+#define NT_STATUS_HANDLE_NOT_CLOSABLE ((nt_status) 0xC0000235)
+#define NT_STATUS_HANDLE_NO_LONGER_VALID ((nt_status) 0xC0190028)
+#define NT_STATUS_HARDWARE_MEMORY_ERROR ((nt_status) 0xC0000709)
+#define NT_STATUS_HASH_NOT_PRESENT ((nt_status) 0xC000A101)
+#define NT_STATUS_HASH_NOT_SUPPORTED ((nt_status) 0xC000A100)
+#define NT_STATUS_HEAP_CORRUPTION ((nt_status) 0xC0000374)
+#define NT_STATUS_HIBERNATED ((nt_status) 0x4000002A)
+#define NT_STATUS_HIBERNATION_FAILURE ((nt_status) 0xC0000411)
+#define NT_STATUS_HIVE_UNLOADED ((nt_status) 0xC0000425)
+#define NT_STATUS_HMAC_NOT_SUPPORTED ((nt_status) 0xC000A001)
+#define NT_STATUS_HOPLIMIT_EXCEEDED ((nt_status) 0xC000A012)
+#define NT_STATUS_HOST_DOWN ((nt_status) 0xC0000350)
+#define NT_STATUS_HOST_UNREACHABLE ((nt_status) 0xC000023D)
+#define NT_STATUS_HUNG_DISPLAY_DRIVER_THREAD ((nt_status) 0xC0000415)
+#define NT_STATUS_ILLEGAL_CHARACTER ((nt_status) 0xC0000161)
+#define NT_STATUS_ILLEGAL_DLL_RELOCATION ((nt_status) 0xC0000269)
+#define NT_STATUS_ILLEGAL_ELEMENT_ADDRESS ((nt_status) 0xC0000285)
+#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT ((nt_status) 0xC000014A)
+#define NT_STATUS_ILLEGAL_FUNCTION ((nt_status) 0xC00000AF)
+#define NT_STATUS_ILLEGAL_INSTRUCTION ((nt_status) 0xC000001D)
+#define NT_STATUS_ILL_FORMED_PASSWORD ((nt_status) 0xC000006B)
+#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY ((nt_status) 0xC0000160)
+#define NT_STATUS_IMAGE_ALREADY_LOADED ((nt_status) 0xC000010E)
+#define NT_STATUS_IMAGE_ALREADY_LOADED_AS_DLL ((nt_status) 0xC000019D)
+#define NT_STATUS_IMAGE_CERT_REVOKED ((nt_status) 0xC0000603)
+#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH ((nt_status) 0xC0000221)
+#define NT_STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((nt_status) 0x4000000E)
+#define NT_STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((nt_status) 0x40000023)
+#define NT_STATUS_IMAGE_MP_UP_MISMATCH ((nt_status) 0xC0000249)
+#define NT_STATUS_IMAGE_NOT_AT_BASE ((nt_status) 0x40000003)
+#define NT_STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT ((nt_status) 0xC00001A3)
+#define NT_STATUS_IMPLEMENTATION_LIMIT ((nt_status) 0xC000042B)
+#define NT_STATUS_INCOMPATIBLE_DRIVER_BLOCKED ((nt_status) 0xC0000424)
+#define NT_STATUS_INCOMPATIBLE_FILE_MAP ((nt_status) 0xC000004D)
+#define NT_STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING ((nt_status) 0xC000019E)
+#define NT_STATUS_INDOUBT_TRANSACTIONS_EXIST ((nt_status) 0xC019003A)
+#define NT_STATUS_INFO_LENGTH_MISMATCH ((nt_status) 0xC0000004)
+#define NT_STATUS_INSTANCE_NOT_AVAILABLE ((nt_status) 0xC00000AB)
+#define NT_STATUS_INSTRUCTION_MISALIGNMENT ((nt_status) 0xC00000AA)
+#define NT_STATUS_INSUFFICIENT_LOGON_INFO ((nt_status) 0xC0000250)
+#define NT_STATUS_INSUFFICIENT_NVRAM_RESOURCES ((nt_status) 0xC0000454)
+#define NT_STATUS_INSUFFICIENT_POWER ((nt_status) 0xC00002DE)
+#define NT_STATUS_INSUFFICIENT_RESOURCES ((nt_status) 0xC000009A)
+#define NT_STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE ((nt_status) 0xC0000416)
+#define NT_STATUS_INSUFF_SERVER_RESOURCES ((nt_status) 0xC0000205)
+#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO ((nt_status) 0xC0000094)
+#define NT_STATUS_INTEGER_OVERFLOW ((nt_status) 0xC0000095)
+#define NT_STATUS_INTERNAL_DB_CORRUPTION ((nt_status) 0xC00000E4)
+#define NT_STATUS_INTERNAL_DB_ERROR ((nt_status) 0xC0000158)
+#define NT_STATUS_INTERNAL_ERROR ((nt_status) 0xC00000E5)
+#define NT_STATUS_INTERRUPT_STILL_CONNECTED ((nt_status) 0x00000128)
+#define NT_STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED ((nt_status) 0x00000127)
+#define NT_STATUS_INVALID_ACCOUNT_NAME ((nt_status) 0xC0000062)
+#define NT_STATUS_INVALID_ACE_CONDITION ((nt_status) 0xC00001A2)
+#define NT_STATUS_INVALID_ACL ((nt_status) 0xC0000077)
+#define NT_STATUS_INVALID_ADDRESS ((nt_status) 0xC0000141)
+#define NT_STATUS_INVALID_ADDRESS_COMPONENT ((nt_status) 0xC0000207)
+#define NT_STATUS_INVALID_ADDRESS_WILDCARD ((nt_status) 0xC0000208)
+#define NT_STATUS_INVALID_BLOCK_LENGTH ((nt_status) 0xC0000173)
+#define NT_STATUS_INVALID_BUFFER_SIZE ((nt_status) 0xC0000206)
+#define NT_STATUS_INVALID_CID ((nt_status) 0xC000000B)
+#define NT_STATUS_INVALID_COMPUTER_NAME ((nt_status) 0xC0000122)
+#define NT_STATUS_INVALID_CONNECTION ((nt_status) 0xC0000140)
+#define NT_STATUS_INVALID_CRUNTIME_PARAMETER ((nt_status) 0xC0000417)
+#define NT_STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((nt_status) 0xC0000369)
+#define NT_STATUS_INVALID_DEVICE_REQUEST ((nt_status) 0xC0000010)
+#define NT_STATUS_INVALID_DEVICE_STATE ((nt_status) 0xC0000184)
+#define NT_STATUS_INVALID_DISPOSITION ((nt_status) 0xC0000026)
+#define NT_STATUS_INVALID_DOMAIN_ROLE ((nt_status) 0xC00000DE)
+#define NT_STATUS_INVALID_DOMAIN_STATE ((nt_status) 0xC00000DD)
+#define NT_STATUS_INVALID_EA_FLAG ((nt_status) 0x80000015)
+#define NT_STATUS_INVALID_EA_NAME ((nt_status) 0x80000013)
+#define NT_STATUS_INVALID_FILE_FOR_SECTION ((nt_status) 0xC0000020)
+#define NT_STATUS_INVALID_GROUP_ATTRIBUTES ((nt_status) 0xC00000A4)
+#define NT_STATUS_INVALID_HANDLE ((nt_status) 0xC0000008)
+#define NT_STATUS_INVALID_HW_PROFILE ((nt_status) 0xC0000260)
+#define NT_STATUS_INVALID_IDN_NORMALIZATION ((nt_status) 0xC0000716)
+#define NT_STATUS_INVALID_ID_AUTHORITY ((nt_status) 0xC0000084)
+#define NT_STATUS_INVALID_IMAGE_FORMAT ((nt_status) 0xC000007B)
+#define NT_STATUS_INVALID_IMAGE_HASH ((nt_status) 0xC0000428)
+#define NT_STATUS_INVALID_IMAGE_LE_FORMAT ((nt_status) 0xC000012E)
+#define NT_STATUS_INVALID_IMAGE_NE_FORMAT ((nt_status) 0xC000011B)
+#define NT_STATUS_INVALID_IMAGE_NOT_MZ ((nt_status) 0xC000012F)
+#define NT_STATUS_INVALID_IMAGE_PROTECT ((nt_status) 0xC0000130)
+#define NT_STATUS_INVALID_IMAGE_WIN_16 ((nt_status) 0xC0000131)
+#define NT_STATUS_INVALID_IMAGE_WIN_32 ((nt_status) 0xC0000359)
+#define NT_STATUS_INVALID_IMAGE_WIN_64 ((nt_status) 0xC000035A)
+#define NT_STATUS_INVALID_IMPORT_OF_NON_DLL ((nt_status) 0xC000036F)
+#define NT_STATUS_INVALID_INFO_CLASS ((nt_status) 0xC0000003)
+#define NT_STATUS_INVALID_LABEL ((nt_status) 0xC0000446)
+#define NT_STATUS_INVALID_LDT_DESCRIPTOR ((nt_status) 0xC000011A)
+#define NT_STATUS_INVALID_LDT_OFFSET ((nt_status) 0xC0000119)
+#define NT_STATUS_INVALID_LDT_SIZE ((nt_status) 0xC0000118)
+#define NT_STATUS_INVALID_LEVEL ((nt_status) 0xC0000148)
+#define NT_STATUS_INVALID_LOCK_RANGE ((nt_status) 0xC00001A1)
+#define NT_STATUS_INVALID_LOCK_SEQUENCE ((nt_status) 0xC000001E)
+#define NT_STATUS_INVALID_LOGON_HOURS ((nt_status) 0xC000006F)
+#define NT_STATUS_INVALID_LOGON_TYPE ((nt_status) 0xC000010B)
+#define NT_STATUS_INVALID_MEMBER ((nt_status) 0xC000017B)
+#define NT_STATUS_INVALID_MESSAGE ((nt_status) 0xC0000702)
+#define NT_STATUS_INVALID_NETWORK_RESPONSE ((nt_status) 0xC00000C3)
+#define NT_STATUS_INVALID_OPLOCK_PROTOCOL ((nt_status) 0xC00000E3)
+#define NT_STATUS_INVALID_OWNER ((nt_status) 0xC000005A)
+#define NT_STATUS_INVALID_PAGE_PROTECTION ((nt_status) 0xC0000045)
+#define NT_STATUS_INVALID_PARAMETER ((nt_status) 0xC000000D)
+#define NT_STATUS_INVALID_PARAMETER_1 ((nt_status) 0xC00000EF)
+#define NT_STATUS_INVALID_PARAMETER_10 ((nt_status) 0xC00000F8)
+#define NT_STATUS_INVALID_PARAMETER_11 ((nt_status) 0xC00000F9)
+#define NT_STATUS_INVALID_PARAMETER_12 ((nt_status) 0xC00000FA)
+#define NT_STATUS_INVALID_PARAMETER_2 ((nt_status) 0xC00000F0)
+#define NT_STATUS_INVALID_PARAMETER_3 ((nt_status) 0xC00000F1)
+#define NT_STATUS_INVALID_PARAMETER_4 ((nt_status) 0xC00000F2)
+#define NT_STATUS_INVALID_PARAMETER_5 ((nt_status) 0xC00000F3)
+#define NT_STATUS_INVALID_PARAMETER_6 ((nt_status) 0xC00000F4)
+#define NT_STATUS_INVALID_PARAMETER_7 ((nt_status) 0xC00000F5)
+#define NT_STATUS_INVALID_PARAMETER_8 ((nt_status) 0xC00000F6)
+#define NT_STATUS_INVALID_PARAMETER_9 ((nt_status) 0xC00000F7)
+#define NT_STATUS_INVALID_PARAMETER_MIX ((nt_status) 0xC0000030)
+#define NT_STATUS_INVALID_PIPE_STATE ((nt_status) 0xC00000AD)
+#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((nt_status) 0xC0000261)
+#define NT_STATUS_INVALID_PORT_ATTRIBUTES ((nt_status) 0xC000002E)
+#define NT_STATUS_INVALID_PORT_HANDLE ((nt_status) 0xC0000042)
+#define NT_STATUS_INVALID_PRIMARY_GROUP ((nt_status) 0xC000005B)
+#define NT_STATUS_INVALID_QUOTA_LOWER ((nt_status) 0xC0000031)
+#define NT_STATUS_INVALID_READ_MODE ((nt_status) 0xC00000B4)
+#define NT_STATUS_INVALID_SECURITY_DESCR ((nt_status) 0xC0000079)
+#define NT_STATUS_INVALID_SERVER_STATE ((nt_status) 0xC00000DC)
+#define NT_STATUS_INVALID_SID ((nt_status) 0xC0000078)
+#define NT_STATUS_INVALID_SIGNATURE ((nt_status) 0xC000A000)
+#define NT_STATUS_INVALID_SUB_AUTHORITY ((nt_status) 0xC0000076)
+#define NT_STATUS_INVALID_SYSTEM_SERVICE ((nt_status) 0xC000001C)
+#define NT_STATUS_INVALID_TASK_INDEX ((nt_status) 0xC0000501)
+#define NT_STATUS_INVALID_TASK_NAME ((nt_status) 0xC0000500)
+#define NT_STATUS_INVALID_THREAD ((nt_status) 0xC000071C)
+#define NT_STATUS_INVALID_TRANSACTION ((nt_status) 0xC0190002)
+#define NT_STATUS_INVALID_UNWIND_TARGET ((nt_status) 0xC0000029)
+#define NT_STATUS_INVALID_USER_BUFFER ((nt_status) 0xC00000E8)
+#define NT_STATUS_INVALID_USER_PRINCIPAL_NAME ((nt_status) 0xC000041C)
+#define NT_STATUS_INVALID_VARIANT ((nt_status) 0xC0000232)
+#define NT_STATUS_INVALID_VIEW_SIZE ((nt_status) 0xC000001F)
+#define NT_STATUS_INVALID_VOLUME_LABEL ((nt_status) 0xC0000086)
+#define NT_STATUS_INVALID_WORKSTATION ((nt_status) 0xC0000070)
+#define NT_STATUS_IN_PAGE_ERROR ((nt_status) 0xC0000006)
+#define NT_STATUS_IO_DEVICE_ERROR ((nt_status) 0xC0000185)
+#define NT_STATUS_IO_PRIVILEGE_FAILED ((nt_status) 0xC0000137)
+#define NT_STATUS_IO_REISSUE_AS_CACHED ((nt_status) 0xC0040039)
+#define NT_STATUS_IO_REPARSE_DATA_INVALID ((nt_status) 0xC0000278)
+#define NT_STATUS_IO_REPARSE_TAG_INVALID ((nt_status) 0xC0000276)
+#define NT_STATUS_IO_REPARSE_TAG_MISMATCH ((nt_status) 0xC0000277)
+#define NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED ((nt_status) 0xC0000279)
+#define NT_STATUS_IO_TIMEOUT ((nt_status) 0xC00000B5)
+#define NT_STATUS_IPSEC_AUTH_FIREWALL_DROP ((nt_status) 0xC0360008)
+#define NT_STATUS_IPSEC_BAD_SPI ((nt_status) 0xC0360001)
+#define NT_STATUS_IPSEC_CLEAR_TEXT_DROP ((nt_status) 0xC0360007)
+#define NT_STATUS_IPSEC_DOSP_BLOCK ((nt_status) 0xC0368000)
+#define NT_STATUS_IPSEC_DOSP_INVALID_PACKET ((nt_status) 0xC0368002)
+#define NT_STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED ((nt_status) 0xC0368005)
+#define NT_STATUS_IPSEC_DOSP_MAX_ENTRIES ((nt_status) 0xC0368004)
+#define NT_STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES ((nt_status) 0xC0368006)
+#define NT_STATUS_IPSEC_DOSP_RECEIVED_MULTICAST ((nt_status) 0xC0368001)
+#define NT_STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED ((nt_status) 0xC0368003)
+#define NT_STATUS_IPSEC_INTEGRITY_CHECK_FAILED ((nt_status) 0xC0360006)
+#define NT_STATUS_IPSEC_INVALID_PACKET ((nt_status) 0xC0360005)
+#define NT_STATUS_IPSEC_QUEUE_OVERFLOW ((nt_status) 0xC000A010)
+#define NT_STATUS_IPSEC_REPLAY_CHECK_FAILED ((nt_status) 0xC0360004)
+#define NT_STATUS_IPSEC_SA_LIFETIME_EXPIRED ((nt_status) 0xC0360002)
+#define NT_STATUS_IPSEC_THROTTLE_DROP ((nt_status) 0xC0360009)
+#define NT_STATUS_IPSEC_WRONG_SA ((nt_status) 0xC0360003)
+#define NT_STATUS_IP_ADDRESS_CONFLICT1 ((nt_status) 0xC0000254)
+#define NT_STATUS_IP_ADDRESS_CONFLICT2 ((nt_status) 0xC0000255)
+#define NT_STATUS_ISSUING_CA_UNTRUSTED ((nt_status) 0xC000038A)
+#define NT_STATUS_ISSUING_CA_UNTRUSTED_KDC ((nt_status) 0xC000040D)
+#define NT_STATUS_JOURNAL_DELETE_IN_PROGRESS ((nt_status) 0xC00002B7)
+#define NT_STATUS_JOURNAL_ENTRY_DELETED ((nt_status) 0xC00002CF)
+#define NT_STATUS_JOURNAL_NOT_ACTIVE ((nt_status) 0xC00002B8)
+#define NT_STATUS_KDC_CERT_EXPIRED ((nt_status) 0xC000040E)
+#define NT_STATUS_KDC_CERT_REVOKED ((nt_status) 0xC000040F)
+#define NT_STATUS_KDC_INVALID_REQUEST ((nt_status) 0xC00002FB)
+#define NT_STATUS_KDC_UNABLE_TO_REFER ((nt_status) 0xC00002FC)
+#define NT_STATUS_KDC_UNKNOWN_ETYPE ((nt_status) 0xC00002FD)
+#define NT_STATUS_KEY_DELETED ((nt_status) 0xC000017C)
+#define NT_STATUS_KEY_HAS_CHILDREN ((nt_status) 0xC0000180)
+#define NT_STATUS_LAST_ADMIN ((nt_status) 0xC0000069)
+#define NT_STATUS_LICENSE_QUOTA_EXCEEDED ((nt_status) 0xC0000259)
+#define NT_STATUS_LICENSE_VIOLATION ((nt_status) 0xC000026A)
+#define NT_STATUS_LINK_FAILED ((nt_status) 0xC000013E)
+#define NT_STATUS_LINK_TIMEOUT ((nt_status) 0xC000013F)
+#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((nt_status) 0xC000017F)
+#define NT_STATUS_LOCAL_DISCONNECT ((nt_status) 0xC000013B)
+#define NT_STATUS_LOCAL_USER_SESSION_KEY ((nt_status) 0x40000006)
+#define NT_STATUS_LOCK_NOT_GRANTED ((nt_status) 0xC0000055)
+#define NT_STATUS_LOGIN_TIME_RESTRICTION ((nt_status) 0xC0000247)
+#define NT_STATUS_LOGIN_WKSTA_RESTRICTION ((nt_status) 0xC0000248)
+#define NT_STATUS_LOGON_FAILURE ((nt_status) 0xC000006D)
+#define NT_STATUS_LOGON_NOT_GRANTED ((nt_status) 0xC0000155)
+#define NT_STATUS_LOGON_SERVER_CONFLICT ((nt_status) 0xC0000132)
+#define NT_STATUS_LOGON_SESSION_COLLISION ((nt_status) 0xC0000105)
+#define NT_STATUS_LOGON_SESSION_EXISTS ((nt_status) 0xC00000EE)
+#define NT_STATUS_LOGON_TYPE_NOT_GRANTED ((nt_status) 0xC000015B)
+#define NT_STATUS_LOG_APPENDED_FLUSH_FAILED ((nt_status) 0xC01A002F)
+#define NT_STATUS_LOG_ARCHIVE_IN_PROGRESS ((nt_status) 0xC01A0021)
+#define NT_STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS ((nt_status) 0xC01A0020)
+#define NT_STATUS_LOG_BLOCKS_EXHAUSTED ((nt_status) 0xC01A0006)
+#define NT_STATUS_LOG_BLOCK_INCOMPLETE ((nt_status) 0xC01A0004)
+#define NT_STATUS_LOG_BLOCK_INVALID ((nt_status) 0xC01A000A)
+#define NT_STATUS_LOG_BLOCK_VERSION ((nt_status) 0xC01A0009)
+#define NT_STATUS_LOG_CANT_DELETE ((nt_status) 0xC01A0011)
+#define NT_STATUS_LOG_CLIENT_ALREADY_REGISTERED ((nt_status) 0xC01A0024)
+#define NT_STATUS_LOG_CLIENT_NOT_REGISTERED ((nt_status) 0xC01A0025)
+#define NT_STATUS_LOG_CONTAINER_LIMIT_EXCEEDED ((nt_status) 0xC01A0012)
+#define NT_STATUS_LOG_CONTAINER_OPEN_FAILED ((nt_status) 0xC01A0029)
+#define NT_STATUS_LOG_CONTAINER_READ_FAILED ((nt_status) 0xC01A0027)
+#define NT_STATUS_LOG_CONTAINER_STATE_INVALID ((nt_status) 0xC01A002A)
+#define NT_STATUS_LOG_CONTAINER_WRITE_FAILED ((nt_status) 0xC01A0028)
+#define NT_STATUS_LOG_CORRUPTION_DETECTED ((nt_status) 0xC0190030)
+#define NT_STATUS_LOG_DEDICATED ((nt_status) 0xC01A001F)
+#define NT_STATUS_LOG_EPHEMERAL ((nt_status) 0xC01A0022)
+#define NT_STATUS_LOG_FILE_FULL ((nt_status) 0xC0000188)
+#define NT_STATUS_LOG_FULL ((nt_status) 0xC01A001D)
+#define NT_STATUS_LOG_FULL_HANDLER_IN_PROGRESS ((nt_status) 0xC01A0026)
+#define NT_STATUS_LOG_GROWTH_FAILED ((nt_status) 0xC0190019)
+#define NT_STATUS_LOG_HARD_ERROR ((nt_status) 0x4000001A)
+#define NT_STATUS_LOG_INCONSISTENT_SECURITY ((nt_status) 0xC01A002E)
+#define NT_STATUS_LOG_INVALID_RANGE ((nt_status) 0xC01A0005)
+#define NT_STATUS_LOG_METADATA_CORRUPT ((nt_status) 0xC01A000D)
+#define NT_STATUS_LOG_METADATA_FLUSH_FAILED ((nt_status) 0xC01A002D)
+#define NT_STATUS_LOG_METADATA_INCONSISTENT ((nt_status) 0xC01A000F)
+#define NT_STATUS_LOG_METADATA_INVALID ((nt_status) 0xC01A000E)
+#define NT_STATUS_LOG_MULTIPLEXED ((nt_status) 0xC01A001E)
+#define NT_STATUS_LOG_NOT_ENOUGH_CONTAINERS ((nt_status) 0xC01A0023)
+#define NT_STATUS_LOG_NO_RESTART ((nt_status) 0x401A000C)
+#define NT_STATUS_LOG_PINNED ((nt_status) 0xC01A002C)
+#define NT_STATUS_LOG_PINNED_ARCHIVE_TAIL ((nt_status) 0xC01A0018)
+#define NT_STATUS_LOG_PINNED_RESERVATION ((nt_status) 0xC01A0030)
+#define NT_STATUS_LOG_POLICY_ALREADY_INSTALLED ((nt_status) 0xC01A0014)
+#define NT_STATUS_LOG_POLICY_CONFLICT ((nt_status) 0xC01A0017)
+#define NT_STATUS_LOG_POLICY_INVALID ((nt_status) 0xC01A0016)
+#define NT_STATUS_LOG_POLICY_NOT_INSTALLED ((nt_status) 0xC01A0015)
+#define NT_STATUS_LOG_READ_CONTEXT_INVALID ((nt_status) 0xC01A0007)
+#define NT_STATUS_LOG_READ_MODE_INVALID ((nt_status) 0xC01A000B)
+#define NT_STATUS_LOG_RECORDS_RESERVED_INVALID ((nt_status) 0xC01A001A)
+#define NT_STATUS_LOG_RECORD_NONEXISTENT ((nt_status) 0xC01A0019)
+#define NT_STATUS_LOG_RESERVATION_INVALID ((nt_status) 0xC01A0010)
+#define NT_STATUS_LOG_RESIZE_INVALID_SIZE ((nt_status) 0xC019000B)
+#define NT_STATUS_LOG_RESTART_INVALID ((nt_status) 0xC01A0008)
+#define NT_STATUS_LOG_SECTOR_INVALID ((nt_status) 0xC01A0001)
+#define NT_STATUS_LOG_SECTOR_PARITY_INVALID ((nt_status) 0xC01A0002)
+#define NT_STATUS_LOG_SECTOR_REMAPPED ((nt_status) 0xC01A0003)
+#define NT_STATUS_LOG_SPACE_RESERVED_INVALID ((nt_status) 0xC01A001B)
+#define NT_STATUS_LOG_START_OF_LOG ((nt_status) 0xC01A0013)
+#define NT_STATUS_LOG_STATE_INVALID ((nt_status) 0xC01A002B)
+#define NT_STATUS_LOG_TAIL_INVALID ((nt_status) 0xC01A001C)
+#define NT_STATUS_LONGJUMP ((nt_status) 0x80000026)
+#define NT_STATUS_LOST_WRITEBEHIND_DATA ((nt_status) 0xC0000222)
+#define NT_STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR ((nt_status) 0xC000A082)
+#define NT_STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED ((nt_status) 0xC000A080)
+#define NT_STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR ((nt_status) 0xC000A081)
+#define NT_STATUS_LPC_INVALID_CONNECTION_USAGE ((nt_status) 0xC0000706)
+#define NT_STATUS_LPC_RECEIVE_BUFFER_EXPECTED ((nt_status) 0xC0000705)
+#define NT_STATUS_LPC_REPLY_LOST ((nt_status) 0xC0000253)
+#define NT_STATUS_LPC_REQUESTS_NOT_ALLOWED ((nt_status) 0xC0000707)
+#define NT_STATUS_LUIDS_EXHAUSTED ((nt_status) 0xC0000075)
+#define NT_STATUS_MAGAZINE_NOT_PRESENT ((nt_status) 0xC0000286)
+#define NT_STATUS_MAPPED_ALIGNMENT ((nt_status) 0xC0000220)
+#define NT_STATUS_MAPPED_FILE_SIZE_ZERO ((nt_status) 0xC000011E)
+#define NT_STATUS_MARSHALL_OVERFLOW ((nt_status) 0xC0000231)
+#define NT_STATUS_MAX_REFERRALS_EXCEEDED ((nt_status) 0xC00002F4)
+#define NT_STATUS_MCA_EXCEPTION ((nt_status) 0xC0000713)
+#define NT_STATUS_MCA_OCCURED ((nt_status) 0xC000036A)
+#define NT_STATUS_MEDIA_CHANGED ((nt_status) 0x8000001C)
+#define NT_STATUS_MEDIA_CHECK ((nt_status) 0x80000020)
+#define NT_STATUS_MEDIA_WRITE_PROTECTED ((nt_status) 0xC00000A2)
+#define NT_STATUS_MEMBERS_PRIMARY_GROUP ((nt_status) 0xC0000127)
+#define NT_STATUS_MEMBER_IN_ALIAS ((nt_status) 0xC0000153)
+#define NT_STATUS_MEMBER_IN_GROUP ((nt_status) 0xC0000067)
+#define NT_STATUS_MEMBER_NOT_IN_ALIAS ((nt_status) 0xC0000152)
+#define NT_STATUS_MEMBER_NOT_IN_GROUP ((nt_status) 0xC0000068)
+#define NT_STATUS_MEMORY_NOT_ALLOCATED ((nt_status) 0xC00000A0)
+#define NT_STATUS_MESSAGE_LOST ((nt_status) 0xC0000701)
+#define NT_STATUS_MESSAGE_NOT_FOUND ((nt_status) 0xC0000109)
+#define NT_STATUS_MESSAGE_RETRIEVED ((nt_status) 0x4000002E)
+#define NT_STATUS_MFT_TOO_FRAGMENTED ((nt_status) 0xC0000304)
+#define NT_STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION ((nt_status) 0xC0190024)
+#define NT_STATUS_MISSING_SYSTEMFILE ((nt_status) 0xC0000143)
+#define NT_STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM ((nt_status) 0xC01D0003)
+#define NT_STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK ((nt_status) 0xC01D0009)
+#define NT_STATUS_MONITOR_INVALID_MANUFACTURE_DATE ((nt_status) 0xC01D000A)
+#define NT_STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK ((nt_status) 0xC01D0006)
+#define NT_STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK ((nt_status) 0xC01D0004)
+#define NT_STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK ((nt_status) 0xC01D0007)
+#define NT_STATUS_MONITOR_NO_DESCRIPTOR ((nt_status) 0xC01D0001)
+#define NT_STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA ((nt_status) 0xC01D0008)
+#define NT_STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT ((nt_status) 0xC01D0002)
+#define NT_STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED ((nt_status) 0xC01D0005)
+#define NT_STATUS_MORE_ENTRIES ((nt_status) 0x00000105)
+#define NT_STATUS_MORE_PROCESSING_REQUIRED ((nt_status) 0xC0000016)
+#define NT_STATUS_MOUNT_POINT_NOT_RESOLVED ((nt_status) 0xC0000368)
+#define NT_STATUS_MP_PROCESSOR_MISMATCH ((nt_status) 0x40000029)
+#define NT_STATUS_MUI_FILE_NOT_FOUND ((nt_status) 0xC00B0001)
+#define NT_STATUS_MUI_FILE_NOT_LOADED ((nt_status) 0xC00B0006)
+#define NT_STATUS_MUI_INVALID_FILE ((nt_status) 0xC00B0002)
+#define NT_STATUS_MUI_INVALID_LOCALE_NAME ((nt_status) 0xC00B0004)
+#define NT_STATUS_MUI_INVALID_RC_CONFIG ((nt_status) 0xC00B0003)
+#define NT_STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME ((nt_status) 0xC00B0005)
+#define NT_STATUS_MUST_BE_KDC ((nt_status) 0xC00002F5)
+#define NT_STATUS_MUTANT_LIMIT_EXCEEDED ((nt_status) 0xC0000191)
+#define NT_STATUS_MUTANT_NOT_OWNED ((nt_status) 0xC0000046)
+#define NT_STATUS_MUTUAL_AUTHENTICATION_FAILED ((nt_status) 0xC00002C3)
+#define NT_STATUS_NAME_TOO_LONG ((nt_status) 0xC0000106)
+#define NT_STATUS_NDIS_ADAPTER_NOT_FOUND ((nt_status) 0xC0230006)
+#define NT_STATUS_NDIS_ADAPTER_NOT_READY ((nt_status) 0xC0230011)
+#define NT_STATUS_NDIS_ADAPTER_REMOVED ((nt_status) 0xC0230018)
+#define NT_STATUS_NDIS_ALREADY_MAPPED ((nt_status) 0xC023001D)
+#define NT_STATUS_NDIS_BAD_CHARACTERISTICS ((nt_status) 0xC0230005)
+#define NT_STATUS_NDIS_BAD_VERSION ((nt_status) 0xC0230004)
+#define NT_STATUS_NDIS_BUFFER_TOO_SHORT ((nt_status) 0xC0230016)
+#define NT_STATUS_NDIS_CLOSING ((nt_status) 0xC0230002)
+#define NT_STATUS_NDIS_DEVICE_FAILED ((nt_status) 0xC0230008)
+#define NT_STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED ((nt_status) 0xC0232000)
+#define NT_STATUS_NDIS_DOT11_MEDIA_IN_USE ((nt_status) 0xC0232001)
+#define NT_STATUS_NDIS_DOT11_POWER_STATE_INVALID ((nt_status) 0xC0232002)
+#define NT_STATUS_NDIS_ERROR_READING_FILE ((nt_status) 0xC023001C)
+#define NT_STATUS_NDIS_FILE_NOT_FOUND ((nt_status) 0xC023001B)
+#define NT_STATUS_NDIS_GROUP_ADDRESS_IN_USE ((nt_status) 0xC023001A)
+#define NT_STATUS_NDIS_INDICATION_REQUIRED ((nt_status) 0x40230001)
+#define NT_STATUS_NDIS_INTERFACE_NOT_FOUND ((nt_status) 0xC023002B)
+#define NT_STATUS_NDIS_INVALID_ADDRESS ((nt_status) 0xC0230022)
+#define NT_STATUS_NDIS_INVALID_DATA ((nt_status) 0xC0230015)
+#define NT_STATUS_NDIS_INVALID_DEVICE_REQUEST ((nt_status) 0xC0230010)
+#define NT_STATUS_NDIS_INVALID_LENGTH ((nt_status) 0xC0230014)
+#define NT_STATUS_NDIS_INVALID_OID ((nt_status) 0xC0230017)
+#define NT_STATUS_NDIS_INVALID_PACKET ((nt_status) 0xC023000F)
+#define NT_STATUS_NDIS_INVALID_PORT ((nt_status) 0xC023002D)
+#define NT_STATUS_NDIS_INVALID_PORT_STATE ((nt_status) 0xC023002E)
+#define NT_STATUS_NDIS_LOW_POWER_STATE ((nt_status) 0xC023002F)
+#define NT_STATUS_NDIS_MEDIA_DISCONNECTED ((nt_status) 0xC023001F)
+#define NT_STATUS_NDIS_MULTICAST_EXISTS ((nt_status) 0xC023000A)
+#define NT_STATUS_NDIS_MULTICAST_FULL ((nt_status) 0xC0230009)
+#define NT_STATUS_NDIS_MULTICAST_NOT_FOUND ((nt_status) 0xC023000B)
+#define NT_STATUS_NDIS_NOT_SUPPORTED ((nt_status) 0xC02300BB)
+#define NT_STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED ((nt_status) 0xC0231012)
+#define NT_STATUS_NDIS_OFFLOAD_PATH_REJECTED ((nt_status) 0xC0231013)
+#define NT_STATUS_NDIS_OFFLOAD_POLICY ((nt_status) 0xC023100F)
+#define NT_STATUS_NDIS_OPEN_FAILED ((nt_status) 0xC0230007)
+#define NT_STATUS_NDIS_PAUSED ((nt_status) 0xC023002A)
+#define NT_STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL ((nt_status) 0xC0232004)
+#define NT_STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL ((nt_status) 0xC0232003)
+#define NT_STATUS_NDIS_REQUEST_ABORTED ((nt_status) 0xC023000C)
+#define NT_STATUS_NDIS_RESET_IN_PROGRESS ((nt_status) 0xC023000D)
+#define NT_STATUS_NDIS_RESOURCE_CONFLICT ((nt_status) 0xC023001E)
+#define NT_STATUS_NDIS_UNSUPPORTED_MEDIA ((nt_status) 0xC0230019)
+#define NT_STATUS_NDIS_UNSUPPORTED_REVISION ((nt_status) 0xC023002C)
+#define NT_STATUS_ND_QUEUE_OVERFLOW ((nt_status) 0xC000A011)
+#define NT_STATUS_NETLOGON_NOT_STARTED ((nt_status) 0xC0000192)
+#define NT_STATUS_NETWORK_ACCESS_DENIED ((nt_status) 0xC00000CA)
+#define NT_STATUS_NETWORK_BUSY ((nt_status) 0xC00000BF)
+#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT ((nt_status) 0xC0000195)
+#define NT_STATUS_NETWORK_NAME_DELETED ((nt_status) 0xC00000C9)
+#define NT_STATUS_NETWORK_OPEN_RESTRICTION ((nt_status) 0xC0000201)
+#define NT_STATUS_NETWORK_SESSION_EXPIRED ((nt_status) 0xC000035C)
+#define NT_STATUS_NETWORK_UNREACHABLE ((nt_status) 0xC000023C)
+#define NT_STATUS_NET_WRITE_FAULT ((nt_status) 0xC00000D2)
+#define NT_STATUS_NOINTERFACE ((nt_status) 0xC00002B9)
+#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((nt_status) 0xC0000198)
+#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((nt_status) 0xC000019A)
+#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((nt_status) 0xC0000199)
+#define NT_STATUS_NONCONTINUABLE_EXCEPTION ((nt_status) 0xC0000025)
+#define NT_STATUS_NONEXISTENT_EA_ENTRY ((nt_status) 0xC0000051)
+#define NT_STATUS_NONEXISTENT_SECTOR ((nt_status) 0xC0000015)
+#define NT_STATUS_NONE_MAPPED ((nt_status) 0xC0000073)
+#define NT_STATUS_NOTHING_TO_TERMINATE ((nt_status) 0x00000122)
+#define NT_STATUS_NOTIFICATION_GUID_ALREADY_DEFINED ((nt_status) 0xC00001A4)
+#define NT_STATUS_NOTIFY_CLEANUP ((nt_status) 0x0000010B)
+#define NT_STATUS_NOTIFY_ENUM_DIR ((nt_status) 0x0000010C)
+#define NT_STATUS_NOT_ALL_ASSIGNED ((nt_status) 0x00000106)
+#define NT_STATUS_NOT_A_DIRECTORY ((nt_status) 0xC0000103)
+#define NT_STATUS_NOT_A_REPARSE_POINT ((nt_status) 0xC0000275)
+#define NT_STATUS_NOT_CAPABLE ((nt_status) 0xC0000429)
+#define NT_STATUS_NOT_CLIENT_SESSION ((nt_status) 0xC0000217)
+#define NT_STATUS_NOT_COMMITTED ((nt_status) 0xC000002D)
+#define NT_STATUS_NOT_EXPORT_FORMAT ((nt_status) 0xC0000292)
+#define NT_STATUS_NOT_FOUND ((nt_status) 0xC0000225)
+#define NT_STATUS_NOT_IMPLEMENTED ((nt_status) 0xC0000002)
+#define NT_STATUS_NOT_LOCKED ((nt_status) 0xC000002A)
+#define NT_STATUS_NOT_LOGON_PROCESS ((nt_status) 0xC00000ED)
+#define NT_STATUS_NOT_MAPPED_DATA ((nt_status) 0xC0000088)
+#define NT_STATUS_NOT_MAPPED_VIEW ((nt_status) 0xC0000019)
+#define NT_STATUS_NOT_REGISTRY_FILE ((nt_status) 0xC000015C)
+#define NT_STATUS_NOT_SAFE_MODE_DRIVER ((nt_status) 0xC000035F)
+#define NT_STATUS_NOT_SAME_DEVICE ((nt_status) 0xC00000D4)
+#define NT_STATUS_NOT_SERVER_SESSION ((nt_status) 0xC0000216)
+#define NT_STATUS_NOT_SNAPSHOT_VOLUME ((nt_status) 0xC0190047)
+#define NT_STATUS_NOT_SUPPORTED ((nt_status) 0xC00000BB)
+#define NT_STATUS_NOT_SUPPORTED_ON_SBS ((nt_status) 0xC0000300)
+#define NT_STATUS_NOT_TINY_STREAM ((nt_status) 0xC0000226)
+#define NT_STATUS_NO_BROWSER_SERVERS_FOUND ((nt_status) 0xC000021C)
+#define NT_STATUS_NO_CALLBACK_ACTIVE ((nt_status) 0xC0000258)
+#define NT_STATUS_NO_DATA_DETECTED ((nt_status) 0x80000022)
+#define NT_STATUS_NO_EAS_ON_FILE ((nt_status) 0xC0000052)
+#define NT_STATUS_NO_EFS ((nt_status) 0xC000028E)
+#define NT_STATUS_NO_EVENT_PAIR ((nt_status) 0xC000014E)
+#define NT_STATUS_NO_GUID_TRANSLATION ((nt_status) 0xC000010C)
+#define NT_STATUS_NO_IMPERSONATION_TOKEN ((nt_status) 0xC000005C)
+#define NT_STATUS_NO_INHERITANCE ((nt_status) 0x8000000B)
+#define NT_STATUS_NO_IP_ADDRESSES ((nt_status) 0xC00002F1)
+#define NT_STATUS_NO_KERB_KEY ((nt_status) 0xC0000322)
+#define NT_STATUS_NO_LDT ((nt_status) 0xC0000117)
+#define NT_STATUS_NO_LINK_TRACKING_IN_TRANSACTION ((nt_status) 0xC0190059)
+#define NT_STATUS_NO_LOGON_SERVERS ((nt_status) 0xC000005E)
+#define NT_STATUS_NO_LOG_SPACE ((nt_status) 0xC000017D)
+#define NT_STATUS_NO_MATCH ((nt_status) 0xC0000272)
+#define NT_STATUS_NO_MEDIA ((nt_status) 0xC0000178)
+#define NT_STATUS_NO_MEDIA_IN_DEVICE ((nt_status) 0xC0000013)
+#define NT_STATUS_NO_MEMORY ((nt_status) 0xC0000017)
+#define NT_STATUS_NO_MORE_EAS ((nt_status) 0x80000012)
+#define NT_STATUS_NO_MORE_ENTRIES ((nt_status) 0x8000001A)
+#define NT_STATUS_NO_MORE_FILES ((nt_status) 0x80000006)
+#define NT_STATUS_NO_MORE_MATCHES ((nt_status) 0xC0000273)
+#define NT_STATUS_NO_PAGEFILE ((nt_status) 0xC0000147)
+#define NT_STATUS_NO_PA_DATA ((nt_status) 0xC00002F8)
+#define NT_STATUS_NO_QUOTAS_FOR_ACCOUNT ((nt_status) 0x0000010D)
+#define NT_STATUS_NO_RECOVERY_POLICY ((nt_status) 0xC000028D)
+#define NT_STATUS_NO_S4U_PROT_SUPPORT ((nt_status) 0xC000040A)
+#define NT_STATUS_NO_SAVEPOINT_WITH_OPEN_FILES ((nt_status) 0xC0190048)
+#define NT_STATUS_NO_SECRETS ((nt_status) 0xC0000371)
+#define NT_STATUS_NO_SECURITY_CONTEXT ((nt_status) 0xC000042D)
+#define NT_STATUS_NO_SECURITY_ON_OBJECT ((nt_status) 0xC00000D7)
+#define NT_STATUS_NO_SPOOL_SPACE ((nt_status) 0xC00000C7)
+#define NT_STATUS_NO_SUCH_ALIAS ((nt_status) 0xC0000151)
+#define NT_STATUS_NO_SUCH_DEVICE ((nt_status) 0xC000000E)
+#define NT_STATUS_NO_SUCH_DOMAIN ((nt_status) 0xC00000DF)
+#define NT_STATUS_NO_SUCH_FILE ((nt_status) 0xC000000F)
+#define NT_STATUS_NO_SUCH_GROUP ((nt_status) 0xC0000066)
+#define NT_STATUS_NO_SUCH_LOGON_SESSION ((nt_status) 0xC000005F)
+#define NT_STATUS_NO_SUCH_MEMBER ((nt_status) 0xC000017A)
+#define NT_STATUS_NO_SUCH_PACKAGE ((nt_status) 0xC00000FE)
+#define NT_STATUS_NO_SUCH_PRIVILEGE ((nt_status) 0xC0000060)
+#define NT_STATUS_NO_SUCH_USER ((nt_status) 0xC0000064)
+#define NT_STATUS_NO_TGT_REPLY ((nt_status) 0xC00002EF)
+#define NT_STATUS_NO_TOKEN ((nt_status) 0xC000007C)
+#define NT_STATUS_NO_TRACKING_SERVICE ((nt_status) 0xC000029F)
+#define NT_STATUS_NO_TRUST_LSA_SECRET ((nt_status) 0xC000018A)
+#define NT_STATUS_NO_TRUST_SAM_ACCOUNT ((nt_status) 0xC000018B)
+#define NT_STATUS_NO_TXF_METADATA ((nt_status) 0x80190029)
+#define NT_STATUS_NO_UNICODE_TRANSLATION ((nt_status) 0xC0000717)
+#define NT_STATUS_NO_USER_KEYS ((nt_status) 0xC0000290)
+#define NT_STATUS_NO_USER_SESSION_KEY ((nt_status) 0xC0000202)
+#define NT_STATUS_NO_YIELD_PERFORMED ((nt_status) 0x40000024)
+#define NT_STATUS_NTLM_BLOCKED ((nt_status) 0xC0000418)
+#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((nt_status) 0xC000015D)
+#define NT_STATUS_NULL_LM_PASSWORD ((nt_status) 0x4000000D)
+#define NT_STATUS_OBJECTID_EXISTS ((nt_status) 0xC000022B)
+#define NT_STATUS_OBJECTID_NOT_FOUND ((nt_status) 0xC00002F0)
+#define NT_STATUS_OBJECT_NAME_COLLISION ((nt_status) 0xC0000035)
+#define NT_STATUS_OBJECT_NAME_EXISTS ((nt_status) 0x40000000)
+#define NT_STATUS_OBJECT_NAME_INVALID ((nt_status) 0xC0000033)
+#define NT_STATUS_OBJECT_NAME_NOT_FOUND ((nt_status) 0xC0000034)
+#define NT_STATUS_OBJECT_NO_LONGER_EXISTS ((nt_status) 0xC0190021)
+#define NT_STATUS_OBJECT_PATH_INVALID ((nt_status) 0xC0000039)
+#define NT_STATUS_OBJECT_PATH_NOT_FOUND ((nt_status) 0xC000003A)
+#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD ((nt_status) 0xC000003B)
+#define NT_STATUS_OBJECT_TYPE_MISMATCH ((nt_status) 0xC0000024)
+#define NT_STATUS_ONLY_IF_CONNECTED ((nt_status) 0xC00002CC)
+#define NT_STATUS_OPEN_FAILED ((nt_status) 0xC0000136)
+#define NT_STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION ((nt_status) 0xC019005A)
+#define NT_STATUS_OPLOCK_BREAK_IN_PROGRESS ((nt_status) 0x00000108)
+#define NT_STATUS_OPLOCK_NOT_GRANTED ((nt_status) 0xC00000E2)
+#define NT_STATUS_ORDINAL_NOT_FOUND ((nt_status) 0xC0000138)
+#define NT_STATUS_PAGEFILE_CREATE_FAILED ((nt_status) 0xC0000146)
+#define NT_STATUS_PAGEFILE_QUOTA ((nt_status) 0xC0000007)
+#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED ((nt_status) 0xC000012C)
+#define NT_STATUS_PAGE_FAULT_COPY_ON_WRITE ((nt_status) 0x00000112)
+#define NT_STATUS_PAGE_FAULT_DEMAND_ZERO ((nt_status) 0x00000111)
+#define NT_STATUS_PAGE_FAULT_GUARD_PAGE ((nt_status) 0x00000113)
+#define NT_STATUS_PAGE_FAULT_PAGING_FILE ((nt_status) 0x00000114)
+#define NT_STATUS_PAGE_FAULT_TRANSITION ((nt_status) 0x00000110)
+#define NT_STATUS_PARAMETER_QUOTA_EXCEEDED ((nt_status) 0xC0000410)
+#define NT_STATUS_PARITY_ERROR ((nt_status) 0xC000002B)
+#define NT_STATUS_PARTIAL_COPY ((nt_status) 0x8000000D)
+#define NT_STATUS_PARTITION_FAILURE ((nt_status) 0xC0000172)
+#define NT_STATUS_PASSWORD_EXPIRED ((nt_status) 0xC0000071)
+#define NT_STATUS_PASSWORD_MUST_CHANGE ((nt_status) 0xC0000224)
+#define NT_STATUS_PASSWORD_RESTRICTION ((nt_status) 0xC000006C)
+#define NT_STATUS_PATH_NOT_COVERED ((nt_status) 0xC0000257)
+#define NT_STATUS_PENDING ((nt_status) 0x00000103)
+#define NT_STATUS_PER_USER_TRUST_QUOTA_EXCEEDED ((nt_status) 0xC0000401)
+#define NT_STATUS_PIPE_BROKEN ((nt_status) 0xC000014B)
+#define NT_STATUS_PIPE_BUSY ((nt_status) 0xC00000AE)
+#define NT_STATUS_PIPE_CLOSING ((nt_status) 0xC00000B1)
+#define NT_STATUS_PIPE_CONNECTED ((nt_status) 0xC00000B2)
+#define NT_STATUS_PIPE_DISCONNECTED ((nt_status) 0xC00000B0)
+#define NT_STATUS_PIPE_EMPTY ((nt_status) 0xC00000D9)
+#define NT_STATUS_PIPE_LISTENING ((nt_status) 0xC00000B3)
+#define NT_STATUS_PIPE_NOT_AVAILABLE ((nt_status) 0xC00000AC)
+#define NT_STATUS_PKINIT_CLIENT_FAILURE ((nt_status) 0xC000038C)
+#define NT_STATUS_PKINIT_FAILURE ((nt_status) 0xC0000320)
+#define NT_STATUS_PKINIT_NAME_MISMATCH ((nt_status) 0xC00002F9)
+#define NT_STATUS_PKU2U_CERT_FAILURE ((nt_status) 0xC000042E)
+#define NT_STATUS_PLUGPLAY_NO_DEVICE ((nt_status) 0xC000025E)
+#define NT_STATUS_PLUGPLAY_QUERY_VETOED ((nt_status) 0x80000028)
+#define NT_STATUS_PNP_BAD_MPS_TABLE ((nt_status) 0xC0040035)
+#define NT_STATUS_PNP_INVALID_ID ((nt_status) 0xC0040038)
+#define NT_STATUS_PNP_IRQ_TRANSLATION_FAILED ((nt_status) 0xC0040037)
+#define NT_STATUS_PNP_REBOOT_REQUIRED ((nt_status) 0xC00002D2)
+#define NT_STATUS_PNP_RESTART_ENUMERATION ((nt_status) 0xC00002CE)
+#define NT_STATUS_PNP_TRANSLATION_FAILED ((nt_status) 0xC0040036)
+#define NT_STATUS_POLICY_OBJECT_NOT_FOUND ((nt_status) 0xC000029A)
+#define NT_STATUS_POLICY_ONLY_IN_DS ((nt_status) 0xC000029B)
+#define NT_STATUS_PORT_ALREADY_HAS_COMPLETION_LIST ((nt_status) 0xC000071A)
+#define NT_STATUS_PORT_ALREADY_SET ((nt_status) 0xC0000048)
+#define NT_STATUS_PORT_CLOSED ((nt_status) 0xC0000700)
+#define NT_STATUS_PORT_CONNECTION_REFUSED ((nt_status) 0xC0000041)
+#define NT_STATUS_PORT_DISCONNECTED ((nt_status) 0xC0000037)
+#define NT_STATUS_PORT_MESSAGE_TOO_LONG ((nt_status) 0xC000002F)
+#define NT_STATUS_PORT_NOT_SET ((nt_status) 0xC0000353)
+#define NT_STATUS_PORT_UNREACHABLE ((nt_status) 0xC000023F)
+#define NT_STATUS_POSSIBLE_DEADLOCK ((nt_status) 0xC0000194)
+#define NT_STATUS_POWER_STATE_INVALID ((nt_status) 0xC00002D3)
+#define NT_STATUS_PREDEFINED_HANDLE ((nt_status) 0x40000016)
+#define NT_STATUS_PRENT4_MACHINE_ACCOUNT ((nt_status) 0xC0000357)
+#define NT_STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((nt_status) 0x0000010E)
+#define NT_STATUS_PRINT_CANCELLED ((nt_status) 0xC00000C8)
+#define NT_STATUS_PRINT_QUEUE_FULL ((nt_status) 0xC00000C6)
+#define NT_STATUS_PRIVILEGED_INSTRUCTION ((nt_status) 0xC0000096)
+#define NT_STATUS_PRIVILEGE_NOT_HELD ((nt_status) 0xC0000061)
+#define NT_STATUS_PROCEDURE_NOT_FOUND ((nt_status) 0xC000007A)
+#define NT_STATUS_PROCESS_CLONED ((nt_status) 0x00000129)
+#define NT_STATUS_PROCESS_IN_JOB ((nt_status) 0x00000124)
+#define NT_STATUS_PROCESS_IS_PROTECTED ((nt_status) 0xC0000712)
+#define NT_STATUS_PROCESS_IS_TERMINATING ((nt_status) 0xC000010A)
+#define NT_STATUS_PROCESS_NOT_IN_JOB ((nt_status) 0x00000123)
+#define NT_STATUS_PROFILING_AT_LIMIT ((nt_status) 0xC00000D3)
+#define NT_STATUS_PROFILING_NOT_STARTED ((nt_status) 0xC00000B7)
+#define NT_STATUS_PROFILING_NOT_STOPPED ((nt_status) 0xC00000B8)
+#define NT_STATUS_PROPSET_NOT_FOUND ((nt_status) 0xC0000230)
+#define NT_STATUS_PROTOCOL_NOT_SUPPORTED ((nt_status) 0xC000A013)
+#define NT_STATUS_PROTOCOL_UNREACHABLE ((nt_status) 0xC000023E)
+#define NT_STATUS_PTE_CHANGED ((nt_status) 0xC0000434)
+#define NT_STATUS_PURGE_FAILED ((nt_status) 0xC0000435)
+#define NT_STATUS_PWD_HISTORY_CONFLICT ((nt_status) 0xC000025C)
+#define NT_STATUS_PWD_TOO_RECENT ((nt_status) 0xC000025B)
+#define NT_STATUS_PWD_TOO_SHORT ((nt_status) 0xC000025A)
+#define NT_STATUS_QUOTA_EXCEEDED ((nt_status) 0xC0000044)
+#define NT_STATUS_QUOTA_LIST_INCONSISTENT ((nt_status) 0xC0000266)
+#define NT_STATUS_RANGE_LIST_CONFLICT ((nt_status) 0xC0000282)
+#define NT_STATUS_RANGE_NOT_FOUND ((nt_status) 0xC000028C)
+#define NT_STATUS_RANGE_NOT_LOCKED ((nt_status) 0xC000007E)
+#define NT_STATUS_RDP_PROTOCOL_ERROR ((nt_status) 0xC00A0032)
+#define NT_STATUS_RECEIVE_EXPEDITED ((nt_status) 0x40000010)
+#define NT_STATUS_RECEIVE_PARTIAL ((nt_status) 0x4000000F)
+#define NT_STATUS_RECEIVE_PARTIAL_EXPEDITED ((nt_status) 0x40000011)
+#define NT_STATUS_RECOVERY_FAILURE ((nt_status) 0xC0000227)
+#define NT_STATUS_RECOVERY_NOT_NEEDED ((nt_status) 0x40190034)
+#define NT_STATUS_RECURSIVE_DISPATCH ((nt_status) 0xC0000704)
+#define NT_STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((nt_status) 0x80000023)
+#define NT_STATUS_REDIRECTOR_NOT_STARTED ((nt_status) 0xC00000FB)
+#define NT_STATUS_REDIRECTOR_PAUSED ((nt_status) 0xC00000D1)
+#define NT_STATUS_REDIRECTOR_STARTED ((nt_status) 0xC00000FC)
+#define NT_STATUS_REGISTRY_CORRUPT ((nt_status) 0xC000014C)
+#define NT_STATUS_REGISTRY_HIVE_RECOVERED ((nt_status) 0x8000002A)
+#define NT_STATUS_REGISTRY_IO_FAILED ((nt_status) 0xC000014D)
+#define NT_STATUS_REGISTRY_QUOTA_LIMIT ((nt_status) 0xC0000256)
+#define NT_STATUS_REGISTRY_RECOVERED ((nt_status) 0x40000009)
+#define NT_STATUS_REG_NAT_CONSUMPTION ((nt_status) 0xC00002C9)
+#define NT_STATUS_REINITIALIZATION_NEEDED ((nt_status) 0xC0000287)
+#define NT_STATUS_REMOTE_DISCONNECT ((nt_status) 0xC000013C)
+#define NT_STATUS_REMOTE_FILE_VERSION_MISMATCH ((nt_status) 0xC019000C)
+#define NT_STATUS_REMOTE_NOT_LISTENING ((nt_status) 0xC00000BC)
+#define NT_STATUS_REMOTE_RESOURCES ((nt_status) 0xC000013D)
+#define NT_STATUS_REMOTE_SESSION_LIMIT ((nt_status) 0xC0000196)
+#define NT_STATUS_REMOTE_STORAGE_MEDIA_ERROR ((nt_status) 0xC000029E)
+#define NT_STATUS_REMOTE_STORAGE_NOT_ACTIVE ((nt_status) 0xC000029D)
+#define NT_STATUS_REPARSE ((nt_status) 0x00000104)
+#define NT_STATUS_REPARSE_ATTRIBUTE_CONFLICT ((nt_status) 0xC00002B2)
+#define NT_STATUS_REPARSE_OBJECT ((nt_status) 0x00000118)
+#define NT_STATUS_REPARSE_POINT_NOT_RESOLVED ((nt_status) 0xC0000280)
+#define NT_STATUS_REPLY_MESSAGE_MISMATCH ((nt_status) 0xC000021F)
+#define NT_STATUS_REQUEST_ABORTED ((nt_status) 0xC0000240)
+#define NT_STATUS_REQUEST_CANCELED ((nt_status) 0xC0000703)
+#define NT_STATUS_REQUEST_NOT_ACCEPTED ((nt_status) 0xC00000D0)
+#define NT_STATUS_REQUEST_OUT_OF_SEQUENCE ((nt_status) 0xC000042A)
+#define NT_STATUS_RESOURCEMANAGER_NOT_FOUND ((nt_status) 0xC019004F)
+#define NT_STATUS_RESOURCEMANAGER_READ_ONLY ((nt_status) 0x00000202)
+#define NT_STATUS_RESOURCE_DATA_NOT_FOUND ((nt_status) 0xC0000089)
+#define NT_STATUS_RESOURCE_ENUM_USER_STOP ((nt_status) 0xC00B0007)
+#define NT_STATUS_RESOURCE_IN_USE ((nt_status) 0xC0000708)
+#define NT_STATUS_RESOURCE_LANG_NOT_FOUND ((nt_status) 0xC0000204)
+#define NT_STATUS_RESOURCE_NAME_NOT_FOUND ((nt_status) 0xC000008B)
+#define NT_STATUS_RESOURCE_NOT_OWNED ((nt_status) 0xC0000264)
+#define NT_STATUS_RESOURCE_REQUIREMENTS_CHANGED ((nt_status) 0x00000119)
+#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND ((nt_status) 0xC000008A)
+#define NT_STATUS_RESTART_BOOT_APPLICATION ((nt_status) 0xC0000453)
+#define NT_STATUS_RESUME_HIBERNATION ((nt_status) 0x4000002B)
+#define NT_STATUS_RETRY ((nt_status) 0xC000022D)
+#define NT_STATUS_REVISION_MISMATCH ((nt_status) 0xC0000059)
+#define NT_STATUS_REVOCATION_OFFLINE_C ((nt_status) 0xC000038B)
+#define NT_STATUS_REVOCATION_OFFLINE_KDC ((nt_status) 0xC000040C)
+#define NT_STATUS_RM_ALREADY_STARTED ((nt_status) 0x40190035)
+#define NT_STATUS_RM_DISCONNECTED ((nt_status) 0xC0190032)
+#define NT_STATUS_RM_METADATA_CORRUPT ((nt_status) 0xC0190006)
+#define NT_STATUS_RM_NOT_ACTIVE ((nt_status) 0xC0190005)
+#define NT_STATUS_ROLLBACK_TIMER_EXPIRED ((nt_status) 0xC019003C)
+#define NT_STATUS_RXACT_COMMITTED ((nt_status) 0x0000010A)
+#define NT_STATUS_RXACT_COMMIT_FAILURE ((nt_status) 0xC000011D)
+#define NT_STATUS_RXACT_COMMIT_NECESSARY ((nt_status) 0x80000018)
+#define NT_STATUS_RXACT_INVALID_STATE ((nt_status) 0xC000011C)
+#define NT_STATUS_RXACT_STATE_CREATED ((nt_status) 0x40000004)
+#define NT_STATUS_SAM_INIT_FAILURE ((nt_status) 0xC00002E3)
+#define NT_STATUS_SAM_NEED_BOOTKEY_FLOPPY ((nt_status) 0xC00002E0)
+#define NT_STATUS_SAM_NEED_BOOTKEY_PASSWORD ((nt_status) 0xC00002DF)
+#define NT_STATUS_SECRET_TOO_LONG ((nt_status) 0xC0000157)
+#define NT_STATUS_SECTION_NOT_EXTENDED ((nt_status) 0xC0000087)
+#define NT_STATUS_SECTION_NOT_IMAGE ((nt_status) 0xC0000049)
+#define NT_STATUS_SECTION_PROTECTION ((nt_status) 0xC000004E)
+#define NT_STATUS_SECTION_TOO_BIG ((nt_status) 0xC0000040)
+#define NT_STATUS_SECURITY_STREAM_IS_INCONSISTENT ((nt_status) 0xC00001A0)
+#define NT_STATUS_SEGMENT_NOTIFICATION ((nt_status) 0x40000005)
+#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED ((nt_status) 0xC0000047)
+#define NT_STATUS_SERIAL_COUNTER_TIMEOUT ((nt_status) 0x4000000C)
+#define NT_STATUS_SERIAL_MORE_WRITES ((nt_status) 0x40000008)
+#define NT_STATUS_SERIAL_NO_DEVICE_INITED ((nt_status) 0xC0000150)
+#define NT_STATUS_SERVER_DISABLED ((nt_status) 0xC0000080)
+#define NT_STATUS_SERVER_HAS_OPEN_HANDLES ((nt_status) 0x80000024)
+#define NT_STATUS_SERVER_NOT_DISABLED ((nt_status) 0xC0000081)
+#define NT_STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((nt_status) 0xC00002FF)
+#define NT_STATUS_SERVER_SID_MISMATCH ((nt_status) 0xC00002A0)
+#define NT_STATUS_SERVICE_NOTIFICATION ((nt_status) 0x40000018)
+#define NT_STATUS_SETMARK_DETECTED ((nt_status) 0x80000021)
+#define NT_STATUS_SHARED_IRQ_BUSY ((nt_status) 0xC000016C)
+#define NT_STATUS_SHARED_POLICY ((nt_status) 0xC0000299)
+#define NT_STATUS_SHARING_PAUSED ((nt_status) 0xC00000CF)
+#define NT_STATUS_SHARING_VIOLATION ((nt_status) 0xC0000043)
+#define NT_STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME ((nt_status) 0xC000019F)
+#define NT_STATUS_SHUTDOWN_IN_PROGRESS ((nt_status) 0xC00002FE)
+#define NT_STATUS_SINGLE_STEP ((nt_status) 0x80000004)
+#define NT_STATUS_SMARTCARD_CARD_BLOCKED ((nt_status) 0xC0000381)
+#define NT_STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((nt_status) 0xC0000382)
+#define NT_STATUS_SMARTCARD_CERT_EXPIRED ((nt_status) 0xC000038D)
+#define NT_STATUS_SMARTCARD_CERT_REVOKED ((nt_status) 0xC0000389)
+#define NT_STATUS_SMARTCARD_IO_ERROR ((nt_status) 0xC0000387)
+#define NT_STATUS_SMARTCARD_LOGON_REQUIRED ((nt_status) 0xC00002FA)
+#define NT_STATUS_SMARTCARD_NO_CARD ((nt_status) 0xC0000383)
+#define NT_STATUS_SMARTCARD_NO_CERTIFICATE ((nt_status) 0xC0000385)
+#define NT_STATUS_SMARTCARD_NO_KEYSET ((nt_status) 0xC0000386)
+#define NT_STATUS_SMARTCARD_NO_KEY_CONTAINER ((nt_status) 0xC0000384)
+#define NT_STATUS_SMARTCARD_SILENT_CONTEXT ((nt_status) 0xC000038F)
+#define NT_STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((nt_status) 0xC0000321)
+#define NT_STATUS_SMARTCARD_WRONG_PIN ((nt_status) 0xC0000380)
+#define NT_STATUS_SMI_PRIMITIVE_INSTALLER_FAILED ((nt_status) 0xC0150025)
+#define NT_STATUS_SOME_NOT_MAPPED ((nt_status) 0x00000107)
+#define NT_STATUS_SOURCE_ELEMENT_EMPTY ((nt_status) 0xC0000283)
+#define NT_STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION ((nt_status) 0xC0190049)
+#define NT_STATUS_SPECIAL_ACCOUNT ((nt_status) 0xC0000124)
+#define NT_STATUS_SPECIAL_GROUP ((nt_status) 0xC0000125)
+#define NT_STATUS_SPECIAL_USER ((nt_status) 0xC0000126)
+#define NT_STATUS_STACK_BUFFER_OVERRUN ((nt_status) 0xC0000409)
+#define NT_STATUS_STACK_OVERFLOW ((nt_status) 0xC00000FD)
+#define NT_STATUS_STACK_OVERFLOW_READ ((nt_status) 0xC0000228)
+#define NT_STATUS_STOPPED_ON_SYMLINK ((nt_status) 0x8000002D)
+#define NT_STATUS_STREAM_MINIVERSION_NOT_FOUND ((nt_status) 0xC0190022)
+#define NT_STATUS_STREAM_MINIVERSION_NOT_VALID ((nt_status) 0xC0190023)
+#define NT_STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((nt_status) 0xC00002F6)
+#define NT_STATUS_SUSPEND_COUNT_EXCEEDED ((nt_status) 0xC000004A)
+#define NT_STATUS_SXS_ACTIVATION_CONTEXT_DISABLED ((nt_status) 0xC0150007)
+#define NT_STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT ((nt_status) 0xC015001E)
+#define NT_STATUS_SXS_ASSEMBLY_MISSING ((nt_status) 0xC015000C)
+#define NT_STATUS_SXS_ASSEMBLY_NOT_FOUND ((nt_status) 0xC0150004)
+#define NT_STATUS_SXS_CANT_GEN_ACTCTX ((nt_status) 0xC0150002)
+#define NT_STATUS_SXS_COMPONENT_STORE_CORRUPT ((nt_status) 0xC015001A)
+#define NT_STATUS_SXS_CORRUPTION ((nt_status) 0xC0150015)
+#define NT_STATUS_SXS_CORRUPT_ACTIVATION_STACK ((nt_status) 0xC0150014)
+#define NT_STATUS_SXS_EARLY_DEACTIVATION ((nt_status) 0xC015000F)
+#define NT_STATUS_SXS_FILE_HASH_MISMATCH ((nt_status) 0xC015001B)
+#define NT_STATUS_SXS_FILE_HASH_MISSING ((nt_status) 0xC0150027)
+#define NT_STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY ((nt_status) 0xC015001F)
+#define NT_STATUS_SXS_IDENTITIES_DIFFERENT ((nt_status) 0xC015001D)
+#define NT_STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE ((nt_status) 0xC0150018)
+#define NT_STATUS_SXS_IDENTITY_PARSE_ERROR ((nt_status) 0xC0150019)
+#define NT_STATUS_SXS_INVALID_ACTCTXDATA_FORMAT ((nt_status) 0xC0150003)
+#define NT_STATUS_SXS_INVALID_DEACTIVATION ((nt_status) 0xC0150010)
+#define NT_STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME ((nt_status) 0xC0150017)
+#define NT_STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE ((nt_status) 0xC0150016)
+#define NT_STATUS_SXS_KEY_NOT_FOUND ((nt_status) 0xC0150008)
+#define NT_STATUS_SXS_MANIFEST_FORMAT_ERROR ((nt_status) 0xC0150005)
+#define NT_STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT ((nt_status) 0xC015001C)
+#define NT_STATUS_SXS_MANIFEST_PARSE_ERROR ((nt_status) 0xC0150006)
+#define NT_STATUS_SXS_MANIFEST_TOO_BIG ((nt_status) 0xC0150022)
+#define NT_STATUS_SXS_MULTIPLE_DEACTIVATION ((nt_status) 0xC0150011)
+#define NT_STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET ((nt_status) 0xC015000E)
+#define NT_STATUS_SXS_PROCESS_TERMINATION_REQUESTED ((nt_status) 0xC0150013)
+#define NT_STATUS_SXS_RELEASE_ACTIVATION_CONTEXT ((nt_status) 0x4015000D)
+#define NT_STATUS_SXS_SECTION_NOT_FOUND ((nt_status) 0xC0150001)
+#define NT_STATUS_SXS_SETTING_NOT_REGISTERED ((nt_status) 0xC0150023)
+#define NT_STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY ((nt_status) 0xC0150012)
+#define NT_STATUS_SXS_THREAD_QUERIES_DISABLED ((nt_status) 0xC015000B)
+#define NT_STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE ((nt_status) 0xC0150024)
+#define NT_STATUS_SXS_VERSION_CONFLICT ((nt_status) 0xC0150009)
+#define NT_STATUS_SXS_WRONG_SECTION_TYPE ((nt_status) 0xC015000A)
+#define NT_STATUS_SYMLINK_CLASS_DISABLED ((nt_status) 0xC0000715)
+#define NT_STATUS_SYNCHRONIZATION_REQUIRED ((nt_status) 0xC0000134)
+#define NT_STATUS_SYSTEM_DEVICE_NOT_FOUND ((nt_status) 0xC0000452)
+#define NT_STATUS_SYSTEM_HIVE_TOO_LARGE ((nt_status) 0xC000036E)
+#define NT_STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((nt_status) 0xC00002D1)
+#define NT_STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION ((nt_status) 0x40000031)
+#define NT_STATUS_SYSTEM_POWERSTATE_TRANSITION ((nt_status) 0x4000002F)
+#define NT_STATUS_SYSTEM_PROCESS_TERMINATED ((nt_status) 0xC000021A)
+#define NT_STATUS_SYSTEM_SHUTDOWN ((nt_status) 0xC00002EB)
+#define NT_STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED ((nt_status) 0xC000070E)
+#define NT_STATUS_THREADPOOL_HANDLE_EXCEPTION ((nt_status) 0xC000070A)
+#define NT_STATUS_THREADPOOL_RELEASED_DURING_OPERATION ((nt_status) 0xC000070F)
+#define NT_STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED ((nt_status) 0xC000070D)
+#define NT_STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED ((nt_status) 0xC000070C)
+#define NT_STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED ((nt_status) 0xC000070B)
+#define NT_STATUS_THREAD_ALREADY_IN_TASK ((nt_status) 0xC0000502)
+#define NT_STATUS_THREAD_IS_TERMINATING ((nt_status) 0xC000004B)
+#define NT_STATUS_THREAD_NOT_IN_PROCESS ((nt_status) 0xC000012A)
+#define NT_STATUS_THREAD_WAS_SUSPENDED ((nt_status) 0x40000001)
+#define NT_STATUS_TIMEOUT ((nt_status) 0x00000102)
+#define NT_STATUS_TIMER_NOT_CANCELED ((nt_status) 0xC000000C)
+#define NT_STATUS_TIMER_RESOLUTION_NOT_SET ((nt_status) 0xC0000245)
+#define NT_STATUS_TIMER_RESUME_IGNORED ((nt_status) 0x40000025)
+#define NT_STATUS_TIME_DIFFERENCE_AT_DC ((nt_status) 0xC0000133)
+#define NT_STATUS_TM_IDENTITY_MISMATCH ((nt_status) 0xC019004A)
+#define NT_STATUS_TM_INITIALIZATION_FAILED ((nt_status) 0xC0190004)
+#define NT_STATUS_TM_VOLATILE ((nt_status) 0xC019003B)
+#define NT_STATUS_TOKEN_ALREADY_IN_USE ((nt_status) 0xC000012B)
+#define NT_STATUS_TOO_LATE ((nt_status) 0xC0000189)
+#define NT_STATUS_TOO_MANY_ADDRESSES ((nt_status) 0xC0000209)
+#define NT_STATUS_TOO_MANY_COMMANDS ((nt_status) 0xC00000C1)
+#define NT_STATUS_TOO_MANY_CONTEXT_IDS ((nt_status) 0xC000015A)
+#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED ((nt_status) 0xC0000082)
+#define NT_STATUS_TOO_MANY_LINKS ((nt_status) 0xC0000265)
+#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED ((nt_status) 0xC0000074)
+#define NT_STATUS_TOO_MANY_NAMES ((nt_status) 0xC00000CD)
+#define NT_STATUS_TOO_MANY_NODES ((nt_status) 0xC000020E)
+#define NT_STATUS_TOO_MANY_OPENED_FILES ((nt_status) 0xC000011F)
+#define NT_STATUS_TOO_MANY_PAGING_FILES ((nt_status) 0xC0000097)
+#define NT_STATUS_TOO_MANY_PRINCIPALS ((nt_status) 0xC00002F7)
+#define NT_STATUS_TOO_MANY_SECRETS ((nt_status) 0xC0000156)
+#define NT_STATUS_TOO_MANY_SESSIONS ((nt_status) 0xC00000CE)
+#define NT_STATUS_TOO_MANY_SIDS ((nt_status) 0xC000017E)
+#define NT_STATUS_TOO_MANY_THREADS ((nt_status) 0xC0000129)
+#define NT_STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE ((nt_status) 0xC0190040)
+#define NT_STATUS_TRANSACTIONAL_CONFLICT ((nt_status) 0xC0190001)
+#define NT_STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED ((nt_status) 0xC019003F)
+#define NT_STATUS_TRANSACTIONMANAGER_NOT_FOUND ((nt_status) 0xC0190051)
+#define NT_STATUS_TRANSACTIONMANAGER_NOT_ONLINE ((nt_status) 0xC0190052)
+#define NT_STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION ((nt_status) 0xC0190053)
+#define NT_STATUS_TRANSACTIONS_NOT_FROZEN ((nt_status) 0xC0190045)
+#define NT_STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE ((nt_status) 0xC019000A)
+#define NT_STATUS_TRANSACTION_ABORTED ((nt_status) 0xC000020F)
+#define NT_STATUS_TRANSACTION_ALREADY_ABORTED ((nt_status) 0xC0190015)
+#define NT_STATUS_TRANSACTION_ALREADY_COMMITTED ((nt_status) 0xC0190016)
+#define NT_STATUS_TRANSACTION_FREEZE_IN_PROGRESS ((nt_status) 0xC0190046)
+#define NT_STATUS_TRANSACTION_INTEGRITY_VIOLATED ((nt_status) 0xC019005B)
+#define NT_STATUS_TRANSACTION_INVALID_ID ((nt_status) 0xC0000214)
+#define NT_STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER ((nt_status) 0xC0190017)
+#define NT_STATUS_TRANSACTION_INVALID_TYPE ((nt_status) 0xC0000215)
+#define NT_STATUS_TRANSACTION_NOT_ACTIVE ((nt_status) 0xC0190003)
+#define NT_STATUS_TRANSACTION_NOT_ENLISTED ((nt_status) 0xC0190061)
+#define NT_STATUS_TRANSACTION_NOT_FOUND ((nt_status) 0xC019004E)
+#define NT_STATUS_TRANSACTION_NOT_JOINED ((nt_status) 0xC0190007)
+#define NT_STATUS_TRANSACTION_NOT_REQUESTED ((nt_status) 0xC0190014)
+#define NT_STATUS_TRANSACTION_NOT_ROOT ((nt_status) 0xC0190054)
+#define NT_STATUS_TRANSACTION_NO_MATCH ((nt_status) 0xC0000212)
+#define NT_STATUS_TRANSACTION_NO_RELEASE ((nt_status) 0xC0000211)
+#define NT_STATUS_TRANSACTION_OBJECT_EXPIRED ((nt_status) 0xC0190055)
+#define NT_STATUS_TRANSACTION_PROPAGATION_FAILED ((nt_status) 0xC0190010)
+#define NT_STATUS_TRANSACTION_RECORD_TOO_LONG ((nt_status) 0xC0190058)
+#define NT_STATUS_TRANSACTION_REQUEST_NOT_VALID ((nt_status) 0xC0190013)
+#define NT_STATUS_TRANSACTION_REQUIRED_PROMOTION ((nt_status) 0xC0190043)
+#define NT_STATUS_TRANSACTION_RESPONDED ((nt_status) 0xC0000213)
+#define NT_STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED ((nt_status) 0xC0190057)
+#define NT_STATUS_TRANSACTION_SCOPE_CALLBACKS_NOT_SET ((nt_status) 0x80190042)
+#define NT_STATUS_TRANSACTION_SUPERIOR_EXISTS ((nt_status) 0xC0190012)
+#define NT_STATUS_TRANSACTION_TIMED_OUT ((nt_status) 0xC0000210)
+#define NT_STATUS_TRANSLATION_COMPLETE ((nt_status) 0x00000120)
+#define NT_STATUS_TRANSPORT_FULL ((nt_status) 0xC00002CA)
+#define NT_STATUS_TRUSTED_DOMAIN_FAILURE ((nt_status) 0xC000018C)
+#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE ((nt_status) 0xC000018D)
+#define NT_STATUS_TRUST_FAILURE ((nt_status) 0xC0000190)
+#define NT_STATUS_TS_INCOMPATIBLE_SESSIONS ((nt_status) 0xC00A0039)
+#define NT_STATUS_TXF_ATTRIBUTE_CORRUPT ((nt_status) 0xC019003D)
+#define NT_STATUS_TXF_DIR_NOT_EMPTY ((nt_status) 0xC0190039)
+#define NT_STATUS_TXF_METADATA_ALREADY_PRESENT ((nt_status) 0x80190041)
+#define NT_STATUS_UNABLE_TO_DECOMMIT_VM ((nt_status) 0xC000002C)
+#define NT_STATUS_UNABLE_TO_DELETE_SECTION ((nt_status) 0xC000001B)
+#define NT_STATUS_UNABLE_TO_FREE_VM ((nt_status) 0xC000001A)
+#define NT_STATUS_UNABLE_TO_LOCK_MEDIA ((nt_status) 0xC0000175)
+#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA ((nt_status) 0xC0000176)
+#define NT_STATUS_UNDEFINED_CHARACTER ((nt_status) 0xC0000163)
+#define NT_STATUS_UNEXPECTED_IO_ERROR ((nt_status) 0xC00000E9)
+#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR ((nt_status) 0xC00000EA)
+#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR ((nt_status) 0xC00000EC)
+#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR ((nt_status) 0xC00000EB)
+#define NT_STATUS_UNEXPECTED_NETWORK_ERROR ((nt_status) 0xC00000C4)
+#define NT_STATUS_UNFINISHED_CONTEXT_DELETED ((nt_status) 0xC00002EE)
+#define NT_STATUS_UNHANDLED_EXCEPTION ((nt_status) 0xC0000144)
+#define NT_STATUS_UNKNOWN_REVISION ((nt_status) 0xC0000058)
+#define NT_STATUS_UNMAPPABLE_CHARACTER ((nt_status) 0xC0000162)
+#define NT_STATUS_UNRECOGNIZED_MEDIA ((nt_status) 0xC0000014)
+#define NT_STATUS_UNRECOGNIZED_VOLUME ((nt_status) 0xC000014F)
+#define NT_STATUS_UNSUCCESSFUL ((nt_status) 0xC0000001)
+#define NT_STATUS_UNSUPPORTED_COMPRESSION ((nt_status) 0xC000025F)
+#define NT_STATUS_UNSUPPORTED_PREAUTH ((nt_status) 0xC0000351)
+#define NT_STATUS_UNWIND ((nt_status) 0xC0000027)
+#define NT_STATUS_UNWIND_CONSOLIDATE ((nt_status) 0x80000029)
+#define NT_STATUS_USER2USER_REQUIRED ((nt_status) 0xC0000408)
+#define NT_STATUS_USER_APC ((nt_status) 0x000000C0)
+#define NT_STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED ((nt_status) 0xC0000403)
+#define NT_STATUS_USER_EXISTS ((nt_status) 0xC0000063)
+#define NT_STATUS_USER_MAPPED_FILE ((nt_status) 0xC0000243)
+#define NT_STATUS_USER_SESSION_DELETED ((nt_status) 0xC0000203)
+#define NT_STATUS_VALIDATE_CONTINUE ((nt_status) 0xC0000271)
+#define NT_STATUS_VARIABLE_NOT_FOUND ((nt_status) 0xC0000100)
+#define NT_STATUS_VDM_DISALLOWED ((nt_status) 0xC0000414)
+#define NT_STATUS_VDM_HARD_ERROR ((nt_status) 0xC000021D)
+#define NT_STATUS_VERIFIER_STOP ((nt_status) 0xC0000421)
+#define NT_STATUS_VERIFY_REQUIRED ((nt_status) 0x80000016)
+#define NT_STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH ((nt_status) 0xC03A0017)
+#define NT_STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED ((nt_status) 0xC03A0018)
+#define NT_STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT ((nt_status) 0xC03A0019)
+#define NT_STATUS_VHD_PARENT_VHD_ACCESS_DENIED ((nt_status) 0xC03A0016)
+#define NT_STATUS_VIDEO_DRIVER_DEBUG_REPORT_REQUEST ((nt_status) 0x401B00EC)
+#define NT_STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD ((nt_status) 0xC01B00EA)
+#define NT_STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED ((nt_status) 0x801B00EB)
+#define NT_STATUS_VIRTDISK_NOT_VIRTUAL_DISK ((nt_status) 0xC03A0015)
+#define NT_STATUS_VIRTDISK_PROVIDER_NOT_FOUND ((nt_status) 0xC03A0014)
+#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED ((nt_status) 0xC00000D6)
+#define NT_STATUS_VIRUS_DELETED ((nt_status) 0xC0000907)
+#define NT_STATUS_VIRUS_INFECTED ((nt_status) 0xC0000906)
+#define NT_STATUS_VOLMGR_MIRROR_NOT_SUPPORTED ((nt_status) 0xC038005B)
+#define NT_STATUS_VOLMGR_RAID5_NOT_SUPPORTED ((nt_status) 0xC038005C)
+#define NT_STATUS_VOLSNAP_HIBERNATE_READY ((nt_status) 0x00000125)
+#define NT_STATUS_VOLSNAP_PREPARE_HIBERNATE ((nt_status) 0xC0000407)
+#define NT_STATUS_VOLUME_DIRTY ((nt_status) 0xC0000806)
+#define NT_STATUS_VOLUME_DISMOUNTED ((nt_status) 0xC000026E)
+#define NT_STATUS_VOLUME_MOUNTED ((nt_status) 0x00000109)
+#define NT_STATUS_VOLUME_NOT_UPGRADED ((nt_status) 0xC000029C)
+#define NT_STATUS_WAIT_0 ((nt_status) 0x00000000)
+#define NT_STATUS_WAIT_1 ((nt_status) 0x00000001)
+#define NT_STATUS_WAIT_2 ((nt_status) 0x00000002)
+#define NT_STATUS_WAIT_3 ((nt_status) 0x00000003)
+#define NT_STATUS_WAIT_63 ((nt_status) 0x0000003F)
+#define NT_STATUS_WAIT_CAP ((nt_status) 0x00000040)
+#define NT_STATUS_WAIT_FOR_OPLOCK ((nt_status) 0x00000367)
+#define NT_STATUS_WAKE_SYSTEM ((nt_status) 0x40000294)
+#define NT_STATUS_WAKE_SYSTEM_DEBUGGER ((nt_status) 0x80000007)
+#define NT_STATUS_WAS_LOCKED ((nt_status) 0x40000019)
+#define NT_STATUS_WAS_UNLOCKED ((nt_status) 0x40000017)
+#define NT_STATUS_WMI_ALREADY_DISABLED ((nt_status) 0xC0000302)
+#define NT_STATUS_WMI_ALREADY_ENABLED ((nt_status) 0xC0000303)
+#define NT_STATUS_WMI_GUID_DISCONNECTED ((nt_status) 0xC0000301)
+#define NT_STATUS_WMI_GUID_NOT_FOUND ((nt_status) 0xC0000295)
+#define NT_STATUS_WMI_INSTANCE_NOT_FOUND ((nt_status) 0xC0000296)
+#define NT_STATUS_WMI_ITEMID_NOT_FOUND ((nt_status) 0xC0000297)
+#define NT_STATUS_WMI_NOT_SUPPORTED ((nt_status) 0xC00002DD)
+#define NT_STATUS_WMI_READ_ONLY ((nt_status) 0xC00002C6)
+#define NT_STATUS_WMI_SET_FAILURE ((nt_status) 0xC00002C7)
+#define NT_STATUS_WMI_TRY_AGAIN ((nt_status) 0xC0000298)
+#define NT_STATUS_WORKING_SET_LIMIT_RANGE ((nt_status) 0x40000002)
+#define NT_STATUS_WORKING_SET_QUOTA ((nt_status) 0xC00000A1)
+#define NT_STATUS_WOW_ASSERTION ((nt_status) 0xC0009898)
+#define NT_STATUS_WRONG_COMPARTMENT ((nt_status) 0xC000A085)
+#define NT_STATUS_WRONG_CREDENTIAL_HANDLE ((nt_status) 0xC00002F2)
+#define NT_STATUS_WRONG_EFS ((nt_status) 0xC000028F)
+#define NT_STATUS_WRONG_PASSWORD ((nt_status) 0xC000006A)
+#define NT_STATUS_WRONG_PASSWORD_CORE ((nt_status) 0xC0000149)
+#define NT_STATUS_WRONG_VOLUME ((nt_status) 0xC0000012)
+#define NT_STATUS_WX86_BREAKPOINT ((nt_status) 0x4000001F)
+#define NT_STATUS_WX86_CONTINUE ((nt_status) 0x4000001D)
+#define NT_STATUS_WX86_CREATEWX86TIB ((nt_status) 0x40000028)
+#define NT_STATUS_WX86_EXCEPTION_CHAIN ((nt_status) 0x40000022)
+#define NT_STATUS_WX86_EXCEPTION_CONTINUE ((nt_status) 0x40000020)
+#define NT_STATUS_WX86_EXCEPTION_LASTCHANCE ((nt_status) 0x40000021)
+#define NT_STATUS_WX86_FLOAT_STACK_CHECK ((nt_status) 0xC0000270)
+#define NT_STATUS_WX86_INTERNAL_ERROR ((nt_status) 0xC000026F)
+#define NT_STATUS_WX86_SINGLE_STEP ((nt_status) 0x4000001E)
+#define NT_STATUS_WX86_UNSIMULATE ((nt_status) 0x4000001C)
+#define NT_STATUS_XMLDSIG_ERROR ((nt_status) 0xC000A084)
+#define NT_STATUS_XML_ENCODING_MISMATCH ((nt_status) 0xC0150021)
+#define NT_STATUS_XML_PARSE_ERROR ((nt_status) 0xC000A083)
+
+#endif
diff --git a/include/ntapi/nt_string.h b/include/ntapi/nt_string.h
new file mode 100644
index 0000000..93cd1f6
--- /dev/null
+++ b/include/ntapi/nt_string.h
@@ -0,0 +1,143 @@
+#ifndef _NT_STRING_H_
+#define _NT_STRING_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef void * __cdecl ntapi_memset(
+ void *dest,
+ int c,
+ size_t count);
+
+
+typedef int __cdecl ntapi_sprintf(
+ char * buffer,
+ const char * format,
+ ...);
+
+
+typedef size_t __cdecl ntapi_strlen(const char * str);
+
+
+typedef size_t __cdecl ntapi_wcslen(const wchar16_t * str);
+
+
+typedef void ntapi_rtl_init_unicode_string(
+ __out nt_unicode_string * str_dest,
+ __in wchar16_t * str_src);
+
+
+/* yes, there exists a reason (but feel free to scold me nonetheless) */
+typedef size_t __cdecl ntapi_tt_string_null_offset_multibyte(
+ __in const char * str);
+
+typedef size_t __cdecl ntapi_tt_string_null_offset_short(
+ __in const int16_t * str);
+
+typedef size_t __cdecl ntapi_tt_string_null_offset_dword(
+ __in const int32_t * str);
+
+typedef size_t __cdecl ntapi_tt_string_null_offset_qword(
+ __in const int64_t * str);
+
+typedef size_t __cdecl ntapi_tt_string_null_offset_ptrsize(
+ __in const intptr_t *str);
+
+typedef void __cdecl ntapi_tt_init_unicode_string_from_utf16(
+ __out nt_unicode_string * str_dest,
+ __in wchar16_t * str_src);
+
+
+typedef void * __cdecl ntapi_tt_aligned_block_memset(
+ __in void * block,
+ __in uintptr_t val,
+ __in size_t bytes);
+
+typedef uintptr_t * __cdecl ntapi_tt_aligned_block_memcpy(
+ __in uintptr_t * dst,
+ __in const uintptr_t * src,
+ __in size_t bytes);
+
+
+typedef wchar16_t * __cdecl ntapi_tt_memcpy_utf16(
+ __in wchar16_t * dst,
+ __in const wchar16_t * src,
+ __in size_t bytes);
+
+
+typedef wchar16_t * __cdecl ntapi_tt_aligned_memcpy_utf16(
+ __in uintptr_t * dst,
+ __in const uintptr_t * src,
+ __in size_t bytes);
+
+
+typedef void * __cdecl ntapi_tt_generic_memset(
+ __in void * dst,
+ __in uintptr_t val,
+ __in size_t bytes);
+
+typedef void * __cdecl ntapi_tt_generic_memcpy(
+ __in void * dst,
+ __in const void * src,
+ __in size_t bytes);
+
+typedef void __fastcall ntapi_tt_uint16_to_hex_utf16(
+ __in uint16_t key,
+ __out wchar16_t * formatted_key);
+
+
+typedef void __fastcall ntapi_tt_uint32_to_hex_utf16(
+ __in uint32_t key,
+ __out wchar16_t * formatted_key);
+
+
+typedef void __fastcall ntapi_tt_uint64_to_hex_utf16(
+ __in uint64_t key,
+ __out wchar16_t * formatted_key);
+
+
+typedef void __fastcall ntapi_tt_uintptr_to_hex_utf16(
+ __in uintptr_t key,
+ __out wchar16_t * formatted_key);
+
+
+typedef int32_t __fastcall ntapi_tt_hex_utf16_to_uint16(
+ __in wchar16_t hex_key_utf16[4],
+ __out uint16_t * key);
+
+
+typedef int32_t __fastcall ntapi_tt_hex_utf16_to_uint32(
+ __in wchar16_t hex_key_utf16[8],
+ __out uint32_t * key);
+
+
+typedef int32_t __fastcall ntapi_tt_hex_utf16_to_uint64(
+ __in wchar16_t hex_key_utf16[16],
+ __out uint64_t * key);
+
+
+typedef int32_t __fastcall ntapi_tt_hex_utf16_to_uintptr(
+ __in wchar16_t hex_key_utf16[],
+ __out uintptr_t * key);
+
+
+typedef void __fastcall ntapi_tt_uint16_to_hex_utf8(
+ __in uint32_t key,
+ __out unsigned char * buffer);
+
+
+typedef void __fastcall ntapi_tt_uint32_to_hex_utf8(
+ __in uint32_t key,
+ __out unsigned char * buffer);
+
+
+typedef void __fastcall ntapi_tt_uint64_to_hex_utf8(
+ __in uint64_t key,
+ __out unsigned char * buffer);
+
+
+typedef void __fastcall ntapi_tt_uintptr_to_hex_utf8(
+ __in uintptr_t key,
+ __out unsigned char * buffer);
+
+#endif
diff --git a/include/ntapi/nt_sync.h b/include/ntapi/nt_sync.h
new file mode 100644
index 0000000..ecf5f0c
--- /dev/null
+++ b/include/ntapi/nt_sync.h
@@ -0,0 +1,428 @@
+#ifndef _NT_SYNC_H_
+#define _NT_SYNC_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_wait_type {
+ NT_WAIT_ALL,
+ NT_WAIT_ANY
+} nt_wait_type;
+
+
+typedef enum _nt_timer_type {
+ NT_NOTIFICATION_TIMER,
+ NT_SYNCHRONIZATION_TIMER
+} nt_timer_type;
+
+
+typedef enum _nt_timer_info_class {
+ NT_TIMER_BASIC_INFORMATION
+} nt_timer_info_class;
+
+
+typedef enum _nt_event_type {
+ NT_NOTIFICATION_EVENT,
+ NT_SYNCHRONIZATION_EVENT
+} nt_event_type;
+
+
+typedef enum _nt_event_states {
+ NT_EVENT_NOT_SIGNALED,
+ NT_EVENT_SIGNALED
+} nt_event_states;
+
+
+typedef enum _nt_event_info_class {
+ NT_EVENT_BASIC_INFORMATION
+} nt_event_info_class;
+
+
+typedef enum _nt_semaphore_info_class {
+ NT_SEMAPHORE_BASIC_INFORMATION
+} nt_semaphore_info_class;
+
+
+typedef enum _nt_mutant_info_class {
+ NT_MUTANT_BASIC_INFORMATION
+} nt_mutant_info_class;
+
+
+typedef enum _nt_io_completion_info_class {
+ NT_IO_COMPLETION_BASIC_INFORMATION
+} nt_io_completion_info_class;
+
+
+/* cache block size */
+#define NT_SYNC_BLOCK_SIZE 64
+
+/* timer access bits */
+#define NT_TIMER_QUERY_STATE 0x00000001U
+#define NT_TIMER_MODIFY_STATE 0x00000002U
+#define NT_TIMER_ALL_ACCESS 0x001F0003U
+
+
+/* event access bits */
+#define NT_EVENT_QUERY_STATE 0x00000001U
+#define NT_EVENT_MODIFY_STATE 0x00000002U
+#define NT_EVENT_ALL_ACCESS 0x001F0003U
+
+
+/* semaphore access bits */
+#define NT_SEMAPHORE_QUERY_STATE 0x00000001U
+#define NT_SEMAPHORE_MODIFY_STATE 0x00000002U
+#define NT_SEMAPHORE_ALL_ACCESS 0x001F0003U
+
+
+/* mutant access bits */
+#define NT_MUTANT_QUERY_STATE 0x00000001U
+#define NT_MUTANT_ALL_ACCESS 0x001F0001U
+
+
+/* io completion access bits */
+#define NT_IO_COMPLETION_QUERY_STATE 0x00000001U
+#define NT_IO_COMPLETION_MODIFY_STATE 0x00000002U
+#define NT_IO_COMPLETION_ALL_ACCESS 0x001F0003U
+
+/* alertable threads */
+#define NT_SYNC_NON_ALERTABLE 0x00000000U
+#define NT_SYNC_ALERTABLE 0x00000001U
+
+/* sync block flag bits */
+#define NT_SYNC_BLOCK_YIELD_TO_SERVER 0x00000001U
+
+typedef struct _nt_timer_basic_information {
+ nt_large_integer timer_remaining;
+ int32_t signal_state;
+} nt_timer_basic_information;
+
+
+typedef struct _nt_event_basic_information {
+ nt_event_type event_type;
+ int32_t signal_state;
+} nt_event_basic_information, nt_ebi;
+
+
+typedef struct _nt_semaphore_basic_information {
+ int32_t current_count;
+ int32_t max_count;
+} nt_semaphore_basic_information;
+
+
+typedef struct _nt_mutant_basic_information {
+ int32_t signal_state;
+ int32_t owned;
+ int32_t abandoned;
+} nt_mutant_basic_information;
+
+
+typedef struct _nt_io_completion_basic_information {
+ int32_t signal_state;
+} nt_io_completion_basic_information;
+
+
+typedef union __attr_aligned__(NT_SYNC_BLOCK_SIZE) _nt_sync_block {
+ char cache_line[NT_SYNC_BLOCK_SIZE];
+ struct {
+ int32_t tid;
+ int32_t pid;
+ uint32_t flags;
+ uint32_t srvtid;
+ uint32_t lock_tries;
+ uint32_t ref_cnt;
+ uint32_t busy;
+ int32_t invalid;
+ nt_timeout lock_wait;
+ void * hwait;
+ void * hsignal;
+ void * hserver;
+ };
+} nt_sync_block;
+
+
+typedef void __stdcall nt_timer_apc_routine(
+ void * timer_context,
+ uint32_t timer_low_value,
+ uint32_t timer_high_value);
+
+
+typedef int32_t __stdcall ntapi_zw_wait_for_single_object(
+ __in void * handle,
+ __in int32_t alertable,
+ __in nt_large_integer * timeout __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_signal_and_wait_for_single_object(
+ __in void * handle_to_signal,
+ __in void * handle_to_wait,
+ __in int32_t alertable,
+ __in nt_large_integer * timeout __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_wait_for_multiple_objects(
+ __in uint32_t handle_count,
+ __in void ** handles,
+ __in nt_wait_type wait_type,
+ __in int32_t alertable,
+ __in nt_large_integer * timeout __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_create_timer(
+ __out void ** htimer,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in nt_timer_type timer_type);
+
+
+typedef int32_t __stdcall ntapi_zw_open_timer(
+ __out void ** htimer,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_cancel_timer(
+ __in void * htimer,
+ __out int32_t * previous_state __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_set_timer(
+ __in void * htimer,
+ __in nt_large_integer * due_time,
+ __in nt_timer_apc_routine * timer_apc_routine __optional,
+ __in void * timer_context,
+ __in int32_t resume,
+ __in int32_t period,
+ __out int32_t * previous_state __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_query_timer(
+ __in void * htimer,
+ __in nt_timer_info_class timer_info_class,
+ __out void * timer_info,
+ __in size_t timer_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_create_event(
+ __out void ** hevent,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in nt_event_type event_type,
+ __in int32_t initial_state);
+
+
+typedef int32_t __stdcall ntapi_zw_open_event(
+ __out void ** hevent,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_set_event(
+ __in void * hevent,
+ __out int32_t * previous_state);
+
+
+typedef int32_t __stdcall ntapi_zw_pulse_event(
+ __in void * hevent,
+ __out int32_t * previous_state);
+
+
+typedef int32_t __stdcall ntapi_zw_reset_event(
+ __in void * hevent,
+ __out int32_t * previous_state);
+
+
+typedef int32_t __stdcall ntapi_zw_clear_event(
+ __in void * hevent);
+
+
+typedef int32_t __stdcall ntapi_zw_query_event(
+ __in void * hevent,
+ __in nt_event_info_class event_info_class,
+ __out void * event_info,
+ __in size_t event_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_create_semaphore(
+ __out void ** hsemaphore,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in int32_t initial_count,
+ __in int32_t max_count);
+
+
+typedef int32_t __stdcall ntapi_zw_open_semaphore(
+ __out void ** hsemaphore,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_release_semaphore(
+ __in void * hsemaphore,
+ __in int32_t release_count,
+ __out int32_t * previous_count);
+
+
+typedef int32_t __stdcall ntapi_zw_query_semaphore(
+ __in void * hsemaphore,
+ __in nt_semaphore_info_class semaphore_info_class,
+ __out void * semaphore_info,
+ __in size_t semaphore_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_create_mutant(
+ __out void ** hmutant,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in int32_t initial_owner);
+
+
+typedef int32_t __stdcall ntapi_zw_open_mutant(
+ __out void ** hmutant,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_release_mutant(
+ __in void * hmutant,
+ __out int32_t * previous_state);
+
+
+typedef int32_t __stdcall ntapi_zw_query_mutant(
+ __in void * hmutant,
+ __in nt_mutant_info_class mutant_info_class,
+ __out void * mutant_info,
+ __in size_t mutant_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_create_io_completion(
+ __out void ** hio_completion,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in uint32_t max_concurrent_threads);
+
+
+typedef int32_t __stdcall ntapi_zw_open_io_completion(
+ __out void ** hio_completion,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_set_io_completion(
+ __in void * hio_completion,
+ __in uint32_t completion_key,
+ __in uint32_t completion_value,
+ __in int32_t status,
+ __in uint32_t information);
+
+
+typedef int32_t __stdcall ntapi_zw_remove_io_completion(
+ __in void * hio_completion,
+ __out uint32_t * completion_key,
+ __out uint32_t * completion_value,
+ __out nt_io_status_block * io_status_block,
+ __in nt_large_integer * timeout);
+
+
+typedef int32_t __stdcall ntapi_zw_query_io_completion(
+ __in void * hio_completion,
+ __in nt_io_completion_info_class io_completion_info_class,
+ __out void * io_completion_info,
+ __in size_t io_completion_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_create_event_pair(
+ __out void ** hevent_pair,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_open_event_pair(
+ __out void ** hevent_pair,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr);
+
+
+typedef int32_t __stdcall ntapi_zw_wait_low_event_pair(
+ __in void * hevent_pair);
+
+
+typedef int32_t __stdcall ntapi_zw_set_low_event_pair(
+ __in void * hevent_pair);
+
+
+typedef int32_t __stdcall ntapi_zw_wait_high_event_pair(
+ __in void * hevent_pair);
+
+
+typedef int32_t __stdcall ntapi_zw_set_high_event_pair(
+ __in void * hevent_pair);
+
+
+typedef int32_t __stdcall ntapi_zw_set_low_wait_high_event_pair(
+ __in void * hevent_pair);
+
+
+typedef int32_t __stdcall ntapi_zw_set_high_wait_low_event_pair(
+ __in void * hevent_pair);
+
+
+/* extensions */
+typedef int32_t __stdcall ntapi_tt_create_inheritable_event(
+ __out void ** hevent,
+ __in nt_event_type event_type,
+ __in int32_t initial_state);
+
+
+typedef int32_t __stdcall ntapi_tt_create_private_event(
+ __out void ** hevent,
+ __in nt_event_type event_type,
+ __in int32_t initial_state);
+
+
+typedef void __stdcall ntapi_tt_sync_block_init(
+ __in nt_sync_block * sync_block,
+ __in uint32_t flags __optional,
+ __in int32_t srvtid __optional,
+ __in int32_t default_lock_tries __optional,
+ __in int64_t default_lock_wait __optional,
+ __in void * hsignal __optional);
+
+
+typedef int32_t __stdcall ntapi_tt_sync_block_lock(
+ __in nt_sync_block * sync_block,
+ __in int32_t lock_tries __optional,
+ __in int64_t lock_wait __optional,
+ __in uint32_t * sig_flag __optional);
+
+
+typedef int32_t __stdcall ntapi_tt_sync_block_server_lock(
+ __in nt_sync_block * sync_block,
+ __in int32_t lock_tries __optional,
+ __in int64_t lock_wait __optional,
+ __in uint32_t * sig_flag __optional);
+
+
+typedef int32_t __stdcall ntapi_tt_sync_block_unlock(
+ __in nt_sync_block * sync_block);
+
+
+typedef void __stdcall ntapi_tt_sync_block_validate(
+ __in nt_sync_block * sync_block);
+
+
+typedef int32_t __stdcall ntapi_tt_sync_block_invalidate(
+ __in nt_sync_block * sync_block);
+
+
+typedef int32_t __stdcall ntapi_tt_sync_block_discard(
+ __in nt_sync_block * sync_block);
+
+
+typedef int32_t __stdcall ntapi_tt_wait_for_dummy_event(void);
+
+#endif
diff --git a/include/ntapi/nt_sysinfo.h b/include/ntapi/nt_sysinfo.h
new file mode 100644
index 0000000..b8266e6
--- /dev/null
+++ b/include/ntapi/nt_sysinfo.h
@@ -0,0 +1,796 @@
+#ifndef _NT_SYSINFO_H_
+#define _NT_SYSINFO_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+#include "nt_memory.h"
+
+typedef enum _nt_system_info_class {
+ NT_SYSTEM_INFORMATION_CLASS_MIN = 0,
+ NT_SYSTEM_BASIC_INFORMATION = 0,
+ NT_SYSTEM_PROCESSOR_INFORMATION = 1,
+ NT_SYSTEM_PERFORMANCE_INFORMATION = 2,
+ NT_SYSTEM_TIME_OF_DAY_INFORMATION = 3,
+ NT_SYSTEM_NOT_IMPLEMENTED1 = 4,
+ NT_SYSTEM_PROCESS_INFORMATION = 5,
+ NT_SYSTEM_CALL_COUNTS = 6,
+ NT_SYSTEM_DEVICE_INFORMATION = 7,
+ NT_SYSTEM_PROCESSOR_TIMES = 8,
+ NT_SYSTEM_GLOBAL_FLAG = 9,
+ NT_SYSTEM_NOT_IMPLEMENTED2 = 10,
+ NT_SYSTEM_CALL_TIME_INFORMATION = 10,
+ NT_SYSTEM_MODULE_INFORMATION = 11,
+ NT_SYSTEM_LOCK_INFORMATION = 12,
+ NT_SYSTEM_NOT_IMPLEMENTED3 = 13,
+ NT_SYSTEM_NOT_IMPLEMENTED4 = 14,
+ NT_SYSTEM_NOT_IMPLEMENTED5 = 15,
+ NT_SYSTEM_HANDLE_INFORMATION = 16,
+ NT_SYSTEM_OBJECT_INFORMATION = 17,
+ NT_SYSTEM_PAGE_FILE_INFORMATION = 18,
+ NT_SYSTEM_INSTRUCTION_EMULATION_COUNTS = 19,
+ NT_SYSTEM_INVALID_INFO_CLASS1 = 20,
+ NT_SYSTEM_CACHE_INFORMATION = 21,
+ NT_SYSTEM_POOL_TAG_INFORMATION = 22,
+ NT_SYSTEM_PROCESSOR_STATISTICS = 23,
+ NT_SYSTEM_DPC_INFORMATION = 24,
+ NT_SYSTEM_NOT_IMPLEMENTED6 = 25,
+ NT_SYSTEM_LOAD_IMAGE = 26,
+ NT_SYSTEM_UNLOAD_IMAGE = 27,
+ NT_SYSTEM_TIME_ADJUSTMENT = 28,
+ NT_SYSTEM_NOT_IMPLEMENTED7 = 29,
+ NT_SYSTEM_NOT_IMPLEMENTED8 = 30,
+ NT_SYSTEM_NOT_IMPLEMENTED9 = 31,
+ NT_SYSTEM_CRASH_DUMP_INFORMATION = 32,
+ NT_SYSTEM_EXCEPTION_INFORMATION = 33,
+ NT_SYSTEM_CRASH_DUMP_STATE_INFORMATION = 34,
+ NT_SYSTEM_KERNEL_DEBUGGER_INFORMATION = 35,
+ NT_SYSTEM_CONTEXT_SWITCH_INFORMATION = 36,
+ NT_SYSTEM_REGISTRY_QUOTA_INFORMATION = 37,
+ NT_SYSTEM_LOAD_AND_CALL_IMAGE = 38,
+ NT_SYSTEM_PRIORITY_SEPARATION = 39,
+ NT_SYSTEM_NOT_IMPLEMENTED10 = 40,
+ NT_SYSTEM_NOT_IMPLEMENTED11 = 41,
+ NT_SYSTEM_INVALID_INFO_CLASS2 = 42,
+ NT_SYSTEM_INVALID_INFO_CLASS3 = 43,
+ NT_SYSTEM_CURRENT_TIME_ZONE_INFORMATION = 44,
+ NT_SYSTEM_TIME_ZONE_INFORMATION = 44,
+ NT_SYSTEM_LOOKASIDE_INFORMATION = 45,
+ NT_SYSTEM_SET_TIME_SLIP_EVENT = 46,
+ NT_SYSTEM_CREATE_SESSION = 47,
+ NT_SYSTEM_DELETE_SESSION = 48,
+ NT_SYSTEM_INVALID_INFO_CLASS4 = 49,
+ NT_SYSTEM_RANGE_START_INFORMATION = 50,
+ NT_SYSTEM_VERIFIER_INFORMATION = 51,
+ NT_SYSTEM_ADD_VERIFIER = 52,
+ NT_SYSTEM_SESSION_PROCESSES_INFORMATION = 53,
+ NT_SYSTEM_INFORMATION_CLASS_MAX
+} nt_system_info_class;
+
+
+typedef enum _nt_thread_state {
+ NT_THREAD_STATE_INITIALIZED = 0,
+ NT_THREAD_STATE_READY = 1,
+ NT_THREAD_STATE_RUNNING = 2,
+ NT_THREAD_STATE_STANDBY = 3,
+ NT_THREAD_STATE_TERMINATED = 4,
+ NT_THREAD_STATE_WAIT = 5,
+ NT_THREAD_STATE_TRANSITION = 6,
+ NT_THREAD_STATE_UNKNOWN = 7
+} nt_thread_state;
+
+
+typedef enum _nt_kwait_reason {
+ NT_KWAIT_EXECUTIVE = 0,
+ NT_KWAIT_FREE_PAGE = 1,
+ NT_KWAIT_PAGE_IN = 2,
+ NT_KWAIT_POOL_ALLOCATION = 3,
+ NT_KWAIT_DELAY_EXECUTION = 4,
+ NT_KWAIT_SUSPENDED = 5,
+ NT_KWAIT_USER_REQUEST = 6,
+ NT_KWAIT_WR_EXECUTIVE = 7,
+ NT_KWAIT_WR_FREE_PAGE = 8,
+ NT_KWAIT_WR_PAGE_IN = 9,
+ NT_KWAIT_WR_POOL_ALLOCATION = 10,
+ NT_KWAIT_WR_DELAY_EXECUTION = 11,
+ NT_KWAIT_WR_SUSPENDED = 12,
+ NT_KWAIT_WR_USER_REQUEST = 13,
+ NT_KWAIT_WR_EVENT_PAIR = 14,
+ NT_KWAIT_WR_QUEUE = 15,
+ NT_KWAIT_WR_LPC_RECEIVE = 16,
+ NT_KWAIT_WR_LPC_REPLY = 17,
+ NT_KWAIT_WR_VIRTUAL_MEMORY = 18,
+ NT_KWAIT_WR_PAGE_OUT = 19,
+ NT_KWAIT_WR_RENDEZVOUS = 20,
+ NT_KWAIT_SPARE2 = 21,
+ NT_KWAIT_SPARE3 = 22,
+ NT_KWAIT_SPARE4 = 23,
+ NT_KWAIT_SPARE5 = 24,
+ NT_KWAIT_WR_CALLOUT_STACK = 25,
+ NT_KWAIT_WR_KERNEL = 26,
+ NT_KWAIT_WR_RESOURCE = 27,
+ NT_KWAIT_WR_PUSH_LOCK = 28,
+ NT_KWAIT_WR_MUTEX = 29,
+ NT_KWAIT_WR_QUANTUM_END = 30,
+ NT_KWAIT_WR_DISPATCH_INT = 31,
+ NT_KWAIT_WR_PREEMPTED = 32,
+ NT_KWAIT_WR_YIELD_EXECUTION = 33,
+ NT_KWAIT_WR_FAST_MUTEX = 34,
+ NT_KWAIT_WR_GUARDED_MUTEX = 35,
+ NT_KWAIT_WR_RUNDOWN = 36,
+ NT_KWAIT_MAXIMUM_WAIT_REASON = 37
+} nt_kwait_reason;
+
+
+typedef enum _nt_pool_type {
+ NT_NON_PAGED_POOL,
+ NT_NON_PAGED_POOL_EXECUTE = 0x0000 + NT_NON_PAGED_POOL,
+ NT_PAGED_POOL,
+ NT_NON_PAGED_POOL_MUST_SUCCEED = 0x0002 + NT_NON_PAGED_POOL,
+ NT_DONT_USE_THIS_TYPE,
+ NT_NON_PAGED_POOL_CACHE_ALIGNED = 0x0004 + NT_NON_PAGED_POOL,
+ NT_PAGED_POOL_CACHE_ALIGNED,
+ NT_NON_PAGED_POOL_CACHE_ALIGNED_MUST_S = 0x0006 + NT_NON_PAGED_POOL,
+ NT_MAX_POOL_TYPE,
+ NT_NON_PAGED_POOL_BASE = 0x0000,
+ NT_NON_PAGED_POOL_BASE_MUST_SUCCEED = 0x0002 + NT_NON_PAGED_POOL_BASE,
+ NT_NON_PAGED_POOL_BASE_CACHE_ALIGNED = 0x0004 + NT_NON_PAGED_POOL_BASE,
+ NT_NON_PAGED_POOL_BASE_CACHE_ALIGNED_MUST_S = 0x0006 + NT_NON_PAGED_POOL_BASE,
+ NT_NON_PAGED_POOL_SESSION = 0x0020,
+ NT_PAGED_POOL_SESSION = 0x0001 + NT_NON_PAGED_POOL_SESSION,
+ NT_NON_PAGED_POOL_MUST_SUCCEED_SESSION = 0x0001 + NT_PAGED_POOL_SESSION,
+ NT_DONT_USE_THIS_TYPE_SESSION = 0x0001 + NT_NON_PAGED_POOL_MUST_SUCCEED_SESSION,
+ NT_NON_PAGED_POOL_CACHE_ALIGNED_SESSION = 0x0001 + NT_DONT_USE_THIS_TYPE_SESSION,
+ NT_PAGED_POOL_CACHE_ALIGNED_SESSION = 0x0001 + NT_NON_PAGED_POOL_CACHE_ALIGNED_SESSION,
+ NT_NON_PAGED_POOL_CACHE_ALIGNED_MUST_S_SESSION = 0x0001 + NT_PAGED_POOL_CACHE_ALIGNED_SESSION,
+ NT_NON_PAGED_POOL_NX = 0x0200,
+ NT_NON_PAGED_POOL_NX_CACHE_ALIGNED = 0x0004 + NT_NON_PAGED_POOL_NX,
+ NT_NON_PAGED_POOL_SESSION_NX = 0x0020 + NT_NON_PAGED_POOL_NX
+} nt_pool_type;
+
+
+typedef enum _nt_shutdown_action {
+ NT_SHUTDOWN_NO_REBOOT,
+ NT_SHUTDOWN_REBOOT,
+ NT_SHUTDOWN_POWER_OFF
+} nt_shutdown_action;
+
+
+typedef enum _nt_debug_control_code {
+ NT_DEBUG_GET_TRACE_INFORMATION = 1,
+ NT_DEBUG_SET_INTERNAL_BREAKPOINT,
+ NT_DEBUG_SET_SPECIAL_CALL,
+ NT_DEBUG_CLEAR_SPECIAL_CALLS,
+ NT_DEBUG_QUERY_SPECIAL_CALLS,
+ NT_DEBUG_DBG_BREAK_POINT,
+ NT_DEBUG_MAXIMUM
+} nt_debug_control_code;
+
+
+
+/* nt_system_global_flag constants */
+#define NT_FLGSTOP_ON_EXCEPTION (uint32_t)0x00000001
+#define NT_FLGSHOW_LDR_SNAPS (uint32_t)0x00000002
+#define NT_FLGDEBUG_INITIAL_COMMAND (uint32_t)0x00000004
+#define NT_FLGSTOP_ON_HUNG_GUI (uint32_t)0x00000008
+#define NT_FLGHEAP_ENABLE_TAIL_CHECK (uint32_t)0x00000010
+#define NT_FLGHEAP_ENABLE_FREE_CHECK (uint32_t)0x00000020
+#define NT_FLGHEAP_VALIDATE_PARAMETERS (uint32_t)0x00000040
+#define NT_FLGHEAP_VALIDATE_ALL (uint32_t)0x00000080
+#define NT_FLGPOOL_ENABLE_TAIL_CHECK (uint32_t)0x00000100
+#define NT_FLGPOOL_ENABLE_FREE_CHECK (uint32_t)0x00000200
+#define NT_FLGPOOL_ENABLE_TAGGING (uint32_t)0x00000400
+#define NT_FLGHEAP_ENABLE_TAGGING (uint32_t)0x00000800
+#define NT_FLGUSER_STACK_TRACE_DB (uint32_t)0x00001000
+#define NT_FLGKERNEL_STACK_TRACE_DB (uint32_t)0x00002000
+#define NT_FLGMAINTAIN_OBJECT_TYPELIST (uint32_t)0x00004000
+#define NT_FLGHEAP_ENABLE_TAG_BY_DLL (uint32_t)0x00008000
+#define NT_FLGIGNORE_DEBUG_PRIV (uint32_t)0x00010000
+#define NT_FLGENABLE_CSRDEBUG (uint32_t)0x00020000
+#define NT_FLGENABLE_KDEBUG_SYMBOL_LOAD (uint32_t)0x00040000
+#define NT_FLGDISABLE_PAGE_KERNEL_STACKS (uint32_t)0x00080000
+#define NT_FLGHEAP_ENABLE_CALL_TRACING (uint32_t)0x00100000
+#define NT_FLGHEAP_DISABLE_COALESCING (uint32_t)0x00200000
+#define NT_FLGENABLE_CLOSE_EXCEPTIONS (uint32_t)0x00400000
+#define NT_FLGENABLE_EXCEPTION_LOGGING (uint32_t)0x00800000
+#define NT_FLGENABLE_DBGPRINT_BUFFERING (uint32_t)0x08000000
+
+/* nt_system_handle_information constants */
+/* FIXME: verify that these values are indeed reversed when compared with the flags returned by zw_query_object */
+#define NT_HANDLE_PROTECT_FROM_CLOSE (unsigned char)0x01
+#define NT_HANDLE_INHERIT (unsigned char)0x02
+
+
+/* nt_system_object flag constants */
+#define NT_FLG_SYSTEM_OBJECT_KERNEL_MODE (uint32_t)0x02
+#define NT_FLG_SYSTEM_OBJECT_CREATOR_INFO (uint32_t)0x04
+#define NT_FLG_SYSTEM_OBJECT_EXCLUSIVE (uint32_t)0x08
+#define NT_FLG_SYSTEM_OBJECT_PERMANENT (uint32_t)0x10
+#define NT_FLG_SYSTEM_OBJECT_DEFAULT_SECURITY_QUOTA (uint32_t)0x20
+#define NT_FLG_SYSTEM_OBJECT_SINGLE_HANDLE_ENTRY (uint32_t)0x40
+
+
+typedef struct _nt_system_information_buffer {
+ size_t count;
+ size_t mark;
+} nt_system_information_buffer;
+
+
+typedef struct _nt_system_information_snapshot {
+ nt_system_information_buffer * buffer;
+ void * pcurrent;
+ size_t info_len;
+ size_t max_len;
+ nt_system_info_class sys_info_class;
+} nt_system_information_snapshot;
+
+
+typedef struct _nt_system_basic_information {
+ uint32_t unknown;
+ uint32_t max_increment;
+ uint32_t physical_page_size;
+ uint32_t physical_page_count;
+ uint32_t physical_page_lowest;
+ uint32_t physical_page_highest;
+ uint32_t allocation_granularity;
+ uint32_t user_address_lowest;
+ uint32_t user_address_highest;
+ uint32_t active_processors;
+ unsigned char processor_count;
+} nt_system_basic_information;
+
+
+typedef struct _nt_system_processor_information {
+ uint16_t processor_architecture;
+ uint16_t processor_level;
+ uint16_t processor_revision;
+ uint16_t unknown;
+ uint32_t feature_bits;
+} nt_system_processor_information;
+
+
+typedef struct _nt_system_performance_information {
+ nt_large_integer idle_time;
+ nt_large_integer read_transfer_count;
+ nt_large_integer write_transfer_count;
+ nt_large_integer other_transfer_count;
+ uint32_t read_operation_count;
+ uint32_t write_operation_count;
+ uint32_t other_operation_count;
+ uint32_t available_pages;
+ uint32_t total_committed_pages;
+ uint32_t total_commit_limit;
+ uint32_t peak_commitment;
+ uint32_t page_faults;
+ uint32_t write_copy_faults;
+ uint32_t transition_faults;
+ uint32_t cache_transition_faults;
+ uint32_t demand_zero_faults;
+ uint32_t pages_read;
+ uint32_t page_read_ios;
+ uint32_t cache_reads;
+ uint32_t cache_ios;
+ uint32_t pagefile_pages_written;
+ uint32_t pagefile_page_write_ios;
+ uint32_t mapped_file_pages_written;
+ uint32_t mapped_file_page_write_ios;
+ uint32_t paged_pool_usage;
+ uint32_t non_paged_pool_usage;
+ uint32_t paged_pool_allocs;
+ uint32_t paged_pool_frees;
+ uint32_t non_paged_pool_allocs;
+ uint32_t non_paged_pool_frees;
+ uint32_t total_free_system_ptes;
+ uint32_t system_code_page;
+ uint32_t total_system_driver_pages;
+ uint32_t total_system_code_pages;
+ uint32_t small_non_paged_lookaside_list_allocate_hits;
+ uint32_t small_paged_lookaside_list_allocate_hits;
+ uint32_t reserved3;
+ uint32_t mm_system_cache_page;
+ uint32_t paged_pool_page;
+ uint32_t system_driver_page;
+ uint32_t fast_read_no_wait;
+ uint32_t fast_read_wait;
+ uint32_t fast_read_resource_miss;
+ uint32_t fast_read_not_possible;
+ uint32_t fast_mdl_read_no_wait;
+ uint32_t fast_mdl_read_wait;
+ uint32_t fast_mdl_read_resource_miss;
+ uint32_t fast_mdl_read_not_possible;
+ uint32_t map_data_no_wait;
+ uint32_t map_data_wait;
+ uint32_t map_data_no_wait_miss;
+ uint32_t map_data_wait_miss;
+ uint32_t pin_mapped_data_count;
+ uint32_t pin_read_no_wait;
+ uint32_t pin_read_wait;
+ uint32_t pin_read_no_wait_miss;
+ uint32_t pin_read_wait_miss;
+ uint32_t copy_read_no_wait;
+ uint32_t copy_read_wait;
+ uint32_t copy_read_no_wait_miss;
+ uint32_t copy_read_wait_miss;
+ uint32_t mdl_read_no_wait;
+ uint32_t mdl_read_wait;
+ uint32_t mdl_read_no_wait_miss;
+ uint32_t mdl_read_wait_miss;
+ uint32_t read_ahead_ios;
+ uint32_t lazy_write_ios;
+ uint32_t lazy_write_pages;
+ uint32_t data_flushes;
+ uint32_t data_pages;
+ uint32_t context_switches;
+ uint32_t first_level_tb_fills;
+ uint32_t second_level_tb_fills;
+ uint32_t system_calls;
+} nt_system_performance_information;
+
+
+typedef struct _nt_system_time_of_day_information {
+ nt_large_integer boot_time;
+ nt_large_integer current_time;
+ nt_large_integer time_zone_bias;
+ uint32_t current_time_zone_id;
+} nt_system_time_of_day_information;
+
+
+typedef struct _nt_system_threads {
+ nt_large_integer kernel_time;
+ nt_large_integer user_time;
+ nt_large_integer create_time;
+ uint32_t wait_time;
+ void * start_address;
+ nt_client_id client_id;
+ uint32_t priority;
+ uint32_t base_priority;
+ uint32_t context_switch_count;
+ nt_thread_state state;
+ nt_kwait_reason wait_reason;
+} nt_system_threads;
+
+
+typedef struct _nt_system_processes {
+ uint32_t next_entry_delta;
+ uint32_t thread_count;
+ uint32_t reserved_1st[6];
+ nt_large_integer create_time;
+ nt_large_integer user_time;
+ nt_large_integer kernel_time;
+ nt_unicode_string process_name;
+ uint32_t base_priority;
+ uint32_t process_id;
+ uint32_t inherited_from_process_id;
+ uint32_t handle_count;
+ uint32_t reserved_2nd[2];
+ nt_vm_counters vm_counters;
+ nt_io_counters io_counters;
+ nt_system_threads threads[];
+} nt_system_processes;
+
+
+typedef struct _nt_syscall_information {
+ uint32_t size;
+ uint32_t number_of_descriptor_tables;
+ uint32_t number_of_routines_in_table[1];
+ uint32_t syscall_counts[];
+} nt_syscall_information;
+
+
+typedef struct _nt_system_configuration_information {
+ uint32_t disk_count;
+ uint32_t floppy_count;
+ uint32_t cd_rom_count;
+ uint32_t tape_count;
+ uint32_t serial_count;
+ uint32_t parallel_count;
+} nt_system_configuration_information;
+
+
+typedef struct _nt_system_process_times {
+ nt_large_integer idle_time;
+ nt_large_integer kernel_time;
+ nt_large_integer user_time;
+ nt_large_integer dpc_time;
+ nt_large_integer interrupt_time;
+ uint32_t interrupt_count;
+} nt_system_process_times;
+
+
+typedef struct _nt_system_global_flag {
+ uint32_t global_flag;
+} nt_system_global_flag;
+
+
+typedef struct _nt_system_module_information {
+ uint32_t reserved_1st;
+ uint32_t reserved_2nd;
+ void * base;
+ uint32_t size;
+ uint32_t flags;
+ uint16_t index;
+ uint16_t unknown;
+ uint16_t load_count;
+ uint16_t path_length;
+ char image_name[256];
+} nt_system_module_information_entry;
+
+
+typedef struct _nt_system_lock_information {
+ void * address;
+ uint16_t type;
+ uint16_t reserved_1st;
+ uint32_t exclusive_owner_thread_id;
+ uint32_t active_count;
+ uint32_t contention_count;
+ uint32_t reserved_2nd;
+ uint32_t reserved_3rd;
+ uint32_t number_of_shared_waiters;
+ uint32_t number_of_exclusive_waiters;
+} nt_system_lock_information;
+
+
+typedef struct _nt_system_handle_information {
+ uint32_t process_id;
+ unsigned char object_type_number;
+ unsigned char flags;
+ uint16_t handle;
+ void * object;
+ uint32_t granted_access;
+#if defined (__NT64)
+ uint32_t granted_access_padding;
+#endif
+} nt_system_handle_information;
+
+
+typedef struct _nt_object_type_information {
+ nt_unicode_string name;
+ uint32_t object_count;
+ uint32_t handle_count;
+ uint32_t reserved1[4];
+ uint32_t peak_object_count;
+ uint32_t peak_handle_count;
+ uint32_t reserved2[4];
+ uint32_t invalid_attributes;
+ nt_generic_mapping generic_mapping;
+ uint32_t valid_access;
+ unsigned char unknown;
+ unsigned char maintain_handle_database;
+ nt_pool_type pool_type;
+ uint32_t paged_pool_usage;
+ uint32_t non_paged_pool_usage;
+} nt_object_type_information, nt_oti;
+
+
+typedef struct _nt_system_object_type_information {
+ uint32_t next_entry_offset;
+ uint32_t object_count;
+ uint32_t handle_count;
+ uint32_t type_number;
+ uint32_t invalid_attributes;
+ nt_generic_mapping generic_mapping;
+ uint32_t valid_access_mask;
+ unsigned char pool_type;
+ unsigned char unknown;
+ nt_unicode_string name;
+} nt_system_object_type_information;
+
+
+typedef struct _nt_system_object_information {
+ uint32_t next_entry_offset;
+ void * object;
+ uint32_t creator_process_id;
+ uint16_t unknown;
+ uint16_t flags;
+ uint32_t pointer_count;
+ uint32_t handle_count;
+ uint32_t paged_pool_usage;
+ uint32_t non_paged_pool_usage;
+ uint32_t exclusive_process_id;
+ nt_security_descriptor *security_descriptor;
+ nt_unicode_string name;
+} nt_system_object_information;
+
+
+typedef struct _nt_system_pagefile_information {
+ uint32_t next_entry_offset;
+ uint32_t current_size;
+ uint32_t total_used;
+ uint32_t peak_used;
+ nt_unicode_string file_name;
+} nt_system_pagefile_information;
+
+
+typedef struct _nt_system_instruction_emulation_information {
+ uint32_t segment_not_present;
+ uint32_t two_byte_opcode;
+ uint32_t es_prefix;
+ uint32_t cs_prefix;
+ uint32_t ss_prefix;
+ uint32_t ds_prefix;
+ uint32_t fs_Prefix;
+ uint32_t gs_prefix;
+ uint32_t oper32_prefix;
+ uint32_t addr32_prefix;
+ uint32_t insb;
+ uint32_t insw;
+ uint32_t outsb;
+ uint32_t outsw;
+ uint32_t pushfd;
+ uint32_t popfd;
+ uint32_t int_nn;
+ uint32_t into;
+ uint32_t iretd;
+ uint32_t inb_imm;
+ uint32_t inw_imm;
+ uint32_t outb_imm;
+ uint32_t outw_imm;
+ uint32_t inb;
+ uint32_t inw;
+ uint32_t outb;
+ uint32_t outw;
+ uint32_t lock_prefix;
+ uint32_t repne_prefix;
+ uint32_t rep_prefix;
+ uint32_t hlt;
+ uint32_t cli;
+ uint32_t sti;
+ uint32_t generic_invalid_opcode;
+} nt_system_instruction_emulation_information;
+
+
+typedef struct _nt_system_pool_tag_information {
+ char tag[4];
+ uint32_t paged_pool_allocs;
+ uint32_t paged_pool_frees;
+ uint32_t paged_pool_usage;
+ uint32_t non_paged_pool_allocs;
+ uint32_t non_paged_pool_frees;
+ uint32_t non_paged_pool_usage;
+} nt_system_pool_tag_information;
+
+
+typedef struct _nt_system_processor_statistics {
+ uint32_t context_switches;
+ uint32_t dpc_count;
+ uint32_t dpc_request_rate;
+ uint32_t time_increment;
+ uint32_t dpc_bypass_count;
+ uint32_t apc_bypass_count;
+} nt_system_processor_statistics;
+
+
+typedef struct _nt_system_dpc_information {
+ uint32_t reserved;
+ uint32_t maximum_dpc_queue_depth;
+ uint32_t minimum_dpc_rate;
+ uint32_t adjust_dpc_threshold;
+ uint32_t ideal_dpc_rate;
+} nt_system_dpc_information;
+
+
+typedef struct _nt_system_load_image {
+ nt_unicode_string module_name;
+ void * module_base;
+ void * section_pointer;
+ void * entry_point;
+ void * export_directory;
+} nt_system_load_image;
+
+
+typedef struct _nt_system_unload_image {
+ void * module_base;
+} nt_system_unload_image;
+
+
+typedef struct _nt_system_query_time_adjustment {
+ uint32_t time_adjustment;
+ uint32_t maximum_increment;
+ int32_t time_synchronization;
+} nt_system_query_time_adjustment;
+
+
+typedef struct _nt_system_set_time_adjustment {
+ uint32_t time_adjustment;
+ int32_t time_synchronization;
+} nt_system_set_time_adjustment;
+
+
+typedef struct _nt_system_crash_dump_information {
+ void * crash_dump_section_handle;
+ void * unknown;
+} nt_system_crash_dump_information;
+
+
+typedef struct _nt_system_exception_information {
+ uint32_t alignment_fixup_count;
+ uint32_t exception_dispatch_count;
+ uint32_t floating_emulation_count;
+ uint32_t reserved;
+} nt_system_exception_information;
+
+
+typedef struct _nt_system_crash_dump_state_information {
+ uint32_t crash_dump_section_exists;
+ uint32_t unknown;
+} nt_system_crash_dump_state_information;
+
+
+typedef struct _nt_system_kernel_debugger_information {
+ unsigned char debugger_enabled;
+ unsigned char debugger_not_present;
+} nt_system_kernel_debugger_information;
+
+
+typedef struct _nt_system_context_switch_information {
+ uint32_t context_switches;
+ uint32_t context_switch_counters[11];
+} nt_system_context_switch_information;
+
+
+typedef struct _nt_system_registry_quota_information {
+ uint32_t registry_quota;
+ uint32_t registry_quota_in_use;
+ uint32_t paged_pool_size;
+} nt_system_registry_quota_information;
+
+
+typedef struct _nt_system_load_and_call_image {
+ nt_unicode_string module_name;
+} nt_system_load_and_call_image;
+
+
+typedef struct _nt_system_priority_separation {
+ uint32_t priority_separation;
+} nt_system_priority_separation;
+
+
+typedef struct _nt_system_time_zone_information {
+ int32_t bias;
+ wchar16_t standard_name[32];
+ nt_large_integer standard_date;
+ int32_t standard_bias;
+ wchar16_t daylight_name[32];
+ nt_large_integer daylight_date;
+ int32_t daylight_bias;
+} nt_system_time_zone_information;
+
+
+typedef struct _nt_system_lookaside_information {
+ uint16_t depth;
+ uint16_t maximum_depth;
+ uint32_t total_allocates;
+ uint32_t allocate_misses;
+ uint32_t total_frees;
+ uint32_t free_misses;
+ nt_pool_type type;
+ uint32_t tag;
+ uint32_t size;
+} nt_system_lookaside_information;
+
+
+typedef struct _nt_system_set_time_slip_event {
+ void * time_slip_event;
+} nt_system_set_time_slip_event;
+
+
+typedef struct _nt_system_create_session {
+ uint32_t session_id;
+} nt_system_create_session;
+
+
+typedef struct _nt_system_delete_session {
+ uint32_t session_id;
+} nt_system_delete_session;
+
+
+typedef struct _nt_system_range_start_information {
+ void * system_range_start;
+} nt_system_range_start_information;
+
+
+typedef struct _nt_system_session_processes_information {
+ uint32_t session_id;
+ uint32_t buffer_size;
+ void * buffer;
+} nt_system_session_processes_information;
+
+
+typedef struct _nt_system_pool_block {
+ int32_t allocated;
+ uint16_t unknown;
+ uint32_t size;
+ char tag[4];
+} nt_system_pool_block;
+
+
+typedef struct _nt_system_pool_blocks_information {
+ uint32_t pool_size;
+ void * pool_base;
+ uint16_t unknown;
+ uint32_t number_of_blocks;
+ nt_system_pool_block pool_blocks[];
+} nt_system_pool_blocks_information;
+
+
+typedef struct _nt_system_memory_usage {
+ void * name;
+ uint16_t valid;
+ uint16_t standby;
+ uint16_t modified;
+ uint16_t page_tables;
+} nt_system_memory_usage;
+
+
+typedef struct _nt_system_memory_usage_information {
+ uint32_t reserved;
+ void * end_of_data;
+ nt_system_memory_usage memory_usage[];
+} nt_system_memory_usage_information;
+
+
+
+typedef int32_t __stdcall ntapi_zw_query_system_information(
+ __in nt_system_info_class sys_info_class,
+ __in_out void * sys_info,
+ __in size_t sys_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_set_system_information(
+ __in nt_system_info_class sys_info_class,
+ __in_out void * sys_info,
+ __in uint32_t sys_info_length);
+
+
+typedef int32_t __stdcall ntapi_zw_query_system_environment_value(
+ __in nt_unicode_string * name,
+ __out void * value,
+ __in size_t value_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_set_system_environment_value(
+ __in nt_unicode_string * name,
+ __in nt_unicode_string * value);
+
+
+typedef int32_t __stdcall ntapi_zw_shutdown_system(
+ __in nt_shutdown_action action);
+
+
+typedef int32_t __stdcall ntapi_zw_system_debug_control(
+ __in nt_debug_control_code control_code,
+ __in void * input_buffer __optional,
+ __in uint32_t input_buffer_length,
+ __out void * output_buffer __optional,
+ __in uint32_t output_buffer_length,
+ __out uint32_t * returned_length __optional);
+
+/* extension functions */
+typedef int32_t __stdcall ntapi_tt_get_system_directory_native_path(
+ __out nt_mem_sec_name * buffer,
+ __in uint32_t buffer_size,
+ __in wchar16_t * base_name,
+ __in uint32_t base_name_size,
+ __out nt_unicode_string * nt_path __optional);
+
+
+typedef int32_t __stdcall ntapi_tt_get_system_directory_dos_path(
+ __in void * hsysdir __optional,
+ __out wchar16_t * buffer,
+ __in uint32_t buffer_size,
+ __in wchar16_t * base_name,
+ __in uint32_t base_name_size,
+ __out nt_unicode_string * nt_path __optional);
+
+
+typedef int32_t __stdcall ntapi_tt_get_system_directory_handle(
+ __out void ** hsysdir,
+ __out nt_mem_sec_name * buffer __optional,
+ __in uint32_t buffer_size __optional);
+
+
+typedef int32_t __stdcall ntapi_tt_get_system_info_snapshot(
+ __in_out nt_system_information_snapshot * sys_info_snapshot);
+
+#endif
diff --git a/include/ntapi/nt_termios.h b/include/ntapi/nt_termios.h
new file mode 100644
index 0000000..4d381d2
--- /dev/null
+++ b/include/ntapi/nt_termios.h
@@ -0,0 +1,305 @@
+#ifndef _NT_TERMIOS_H_
+#define _NT_TERMIOS_H_
+
+#include <psxtypes/psxtypes.h>
+
+/* tty friendly guids */
+#define TTY_PTM_GUID {0x21b51c45,0x3388,0x4dd9,{0x82,0x9a,0x5b,0x67,0x4e,0x3e,0x31,0x55}}
+#define TTY_PTS_GUID {0xa038ed3e,0x7bcc,0x4a53,{0xb2,0x94,0x01,0xdf,0x87,0xf6,0x94,0x70}}
+#define TTY_DBG_GUID {0x5ad03536,0xde3c,0x451a,{0xa4,0x32,0xf6,0xfd,0x95,0x97,0x5c,0x52}}
+
+/* cc_chars */
+#define TTY_NCCS 32
+
+#define TTY_VINTR 0x00
+#define TTY_VQUIT 0x01
+#define TTY_VERASE 0x02
+#define TTY_VKILL 0x03
+#define TTY_VEOF 0x04
+#define TTY_VTIME 0x05
+#define TTY_VMIN 0x06
+#define TTY_VSWTC 0x07
+#define TTY_VSTART 0x08
+#define TTY_VSTOP 0x09
+#define TTY_VSUSP 0x0a
+#define TTY_VEOL 0x0b
+#define TTY_VREPRINT 0x0c
+#define TTY_VDISCARD 0x0d
+#define TTY_VWERASE 0x0e
+#define TTY_VLNEXT 0x0f
+#define TTY_VEOL2 0x10
+
+/* c_iflag bits */
+#define TTY_IGNBRK 0000001
+#define TTY_BRKINT 0000002
+#define TTY_IGNPAR 0000004
+#define TTY_PARMRK 0000010
+#define TTY_INPCK 0000020
+#define TTY_ISTRIP 0000040
+#define TTY_INLCR 0000100
+#define TTY_IGNCR 0000200
+#define TTY_ICRNL 0000400
+#define TTY_IUCLC 0001000
+#define TTY_IXON 0002000
+#define TTY_IXANY 0004000
+#define TTY_IXOFF 0010000
+#define TTY_IMAXBEL 0020000
+#define TTY_IUTF8 0040000
+
+/* c_oflag bits */
+#define TTY_OPOST 0000001
+#define TTY_OLCUC 0000002
+#define TTY_ONLCR 0000004
+#define TTY_OCRNL 0000010
+#define TTY_ONOCR 0000020
+#define TTY_ONLRET 0000040
+#define TTY_OFILL 0000100
+#define TTY_OFDEL 0000200
+#define TTY_NLDLY 0000400
+#define TTY_NL0 0000000
+#define TTY_NL1 0000400
+#define TTY_CRDLY 0003000
+#define TTY_CR0 0000000
+#define TTY_CR1 0001000
+#define TTY_CR2 0002000
+#define TTY_CR3 0003000
+#define TTY_TABDLY 0014000
+#define TTY_TAB0 0000000
+#define TTY_TAB1 0004000
+#define TTY_TAB2 0010000
+#define TTY_TAB3 0014000
+#define TTY_BSDLY 0020000
+#define TTY_BS0 0000000
+#define TTY_BS1 0020000
+#define TTY_FFDLY 0100000
+#define TTY_FF0 0000000
+#define TTY_FF1 0100000
+
+#define TTY_VTDLY 0040000
+#define TTY_VT0 0000000
+#define TTY_VT1 0040000
+
+/* c_lflag bits */
+#define TTY_ISIG 0000001
+#define TTY_ICANON 0000002
+#define TTY_ECHO 0000010
+#define TTY_ECHOE 0000020
+#define TTY_ECHOK 0000040
+#define TTY_ECHONL 0000100
+#define TTY_NOFLSH 0000200
+#define TTY_TOSTOP 0000400
+#define TTY_IEXTEN 0100000
+
+#define TTY_ECHOCTL 0001000
+#define TTY_ECHOPRT 0002000
+#define TTY_ECHOKE 0004000
+#define TTY_FLUSHO 0010000
+#define TTY_PENDIN 0040000
+
+/* c_cflag bits */
+#define TTY_CBAUD 0010017
+#define TTY_CSIZE 0000060
+#define TTY_CS5 0000000
+#define TTY_CS6 0000020
+#define TTY_CS7 0000040
+#define TTY_CS8 0000060
+#define TTY_CSTOPB 0000100
+#define TTY_CREAD 0000200
+#define TTY_PARENB 0000400
+#define TTY_PARODD 0001000
+#define TTY_HUPCL 0002000
+#define TTY_CLOCAL 0004000
+
+/* control flow */
+#define TTY_TCOOFF 0
+#define TTY_TCOON 1
+#define TTY_TCIOFF 2
+#define TTY_TCION 3
+
+/* flush */
+#define TTY_TCIFLUSH 0
+#define TTY_TCOFLUSH 1
+#define TTY_TCIOFLUSH 2
+
+/* tty ioctl */
+#define TTY_TCSANOW 0
+#define TTY_TCSADRAIN 1
+#define TTY_TCSAFLUSH 2
+
+/* tty ioctl codes */
+#define TTY_TCGETS 0x5401
+#define TTY_TCSETS 0x5402
+#define TTY_TCSETSW 0x5403
+#define TTY_TCSETSF 0x5404
+#define TTY_TCGETA 0x5405
+#define TTY_TCSETA 0x5406
+#define TTY_TCSETAW 0x5407
+#define TTY_TCSETAF 0x5408
+#define TTY_TCSBRK 0x5409
+#define TTY_TCXONC 0x540A
+#define TTY_TCFLSH 0x540B
+#define TTY_TIOCEXCL 0x540C
+#define TTY_TIOCNXCL 0x540D
+#define TTY_TIOCSCTTY 0x540E
+#define TTY_TIOCGPGRP 0x540F
+#define TTY_TIOCSPGRP 0x5410
+#define TTY_TIOCOUTQ 0x5411
+#define TTY_TIOCSTI 0x5412
+#define TTY_TIOCGWINSZ 0x5413
+#define TTY_TIOCSWINSZ 0x5414
+#define TTY_TIOCMGET 0x5415
+#define TTY_TIOCMBIS 0x5416
+#define TTY_TIOCMBIC 0x5417
+#define TTY_TIOCMSET 0x5418
+#define TTY_TIOCGSOFTCAR 0x5419
+#define TTY_TIOCSSOFTCAR 0x541A
+#define TTY_FIONREAD 0x541B
+#define TTY_TIOCINQ FIONREAD
+#define TTY_TIOCLINUX 0x541C
+#define TTY_TIOCCONS 0x541D
+#define TTY_TIOCGSERIAL 0x541E
+#define TTY_TIOCSSERIAL 0x541F
+#define TTY_TIOCPKT 0x5420
+#define TTY_FIONBIO 0x5421
+#define TTY_TIOCNOTTY 0x5422
+#define TTY_TIOCSETD 0x5423
+#define TTY_TIOCGETD 0x5424
+#define TTY_TCSBRKP 0x5425
+#define TTY_TIOCTTYGSTRUCT 0x5426
+#define TTY_TIOCSBRK 0x5427
+#define TTY_TIOCCBRK 0x5428
+#define TTY_TIOCGSID 0x5429
+#define TTY_TIOCGPTN 0x5430
+#define TTY_TIOCSPTLCK 0x5431
+#define TTY_TCGETX 0x5432
+#define TTY_TCSETX 0x5433
+#define TTY_TCSETXF 0x5434
+#define TTY_TCSETXW 0x5435
+
+/* packet mode */
+#define TTY_TIOCPKT_DATA 0x00
+#define TTY_TIOCPKT_FLUSHREAD 0x01
+#define TTY_TIOCPKT_FLUSHWRITE 0x02
+#define TTY_TIOCPKT_STOP 0x04
+#define TTY_TIOCPKT_START 0x08
+#define TTY_TIOCPKT_NOSTOP 0x10
+#define TTY_TIOCPKT_DOSTOP 0x20
+#define TTY_TIOCPKT_IOCTL 0x40
+
+/* transmitter empty */
+#define TTY_TIOCSER_TEMT 0x01
+
+/* baud rate... :-) */
+#define TTY_B0 0000000
+#define TTY_B50 0000001
+#define TTY_B75 0000002
+#define TTY_B110 0000003
+#define TTY_B134 0000004
+#define TTY_B150 0000005
+#define TTY_B200 0000006
+#define TTY_B300 0000007
+#define TTY_B600 0000010
+#define TTY_B1200 0000011
+#define TTY_B1800 0000012
+#define TTY_B2400 0000013
+#define TTY_B4800 0000014
+#define TTY_B9600 0000015
+#define TTY_B19200 0000016
+#define TTY_B38400 0000017
+
+#define TTY_B57600 0010001
+#define TTY_B115200 0010002
+#define TTY_B230400 0010003
+#define TTY_B460800 0010004
+#define TTY_B500000 0010005
+#define TTY_B576000 0010006
+#define TTY_B921600 0010007
+#define TTY_B1000000 0010010
+#define TTY_B1152000 0010011
+#define TTY_B1500000 0010012
+#define TTY_B2000000 0010013
+#define TTY_B2500000 0010014
+#define TTY_B3000000 0010015
+#define TTY_B3500000 0010016
+#define TTY_B4000000 0010017
+
+/* special characters */
+#define TTY_CTRL_AT 0x00
+#define TTY_CTRL_A 0x01
+#define TTY_CTRL_B 0x02
+#define TTY_CTRL_C 0x03
+#define TTY_CTRL_D 0x04
+#define TTY_CTRL_E 0x05
+#define TTY_CTRL_F 0x06
+#define TTY_CTRL_G 0x07
+#define TTY_CTRL_H 0x08
+#define TTY_CTRL_I 0x09
+#define TTY_CTRL_J 0x0a
+#define TTY_CTRL_K 0x0b
+#define TTY_CTRL_L 0x0c
+#define TTY_CTRL_M 0x0d
+#define TTY_CTRL_N 0x0e
+#define TTY_CTRL_O 0x0f
+#define TTY_CTRL_P 0x10
+#define TTY_CTRL_Q 0x11
+#define TTY_CTRL_R 0x12
+#define TTY_CTRL_S 0x13
+#define TTY_CTRL_T 0x14
+#define TTY_CTRL_U 0x15
+#define TTY_CTRL_V 0x16
+#define TTY_CTRL_W 0x17
+#define TTY_CTRL_X 0x18
+#define TTY_CTRL_Y 0x19
+#define TTY_CTRL_Z 0x1a
+#define TTY_CTRL_LBRACKET 0x1b
+#define TTY_CTRL_BSLASH 0x1c
+#define TTY_CTRL_RBRACKET 0x1d
+#define TTY_CTRL_CTRL 0x1e
+#define TTY_CTRL_USCORE 0x1f
+#define TTY_CTRL_QMARK 0x7f
+
+/* tty properties */
+struct tty_termios {
+ uint32_t c_iflag;
+ uint32_t c_oflag;
+ uint32_t c_cflag;
+ uint32_t c_lflag;
+ unsigned char c_line;
+ unsigned char c_cc[TTY_NCCS];
+ uint32_t __c_ispeed;
+ uint32_t __c_ospeed;
+};
+
+
+/* tty window properties */
+struct tty_winsize {
+ uint16_t ws_row;
+ uint16_t ws_col;
+ uint16_t ws_xpixel;
+ uint16_t ws_ypixel;
+};
+
+
+struct tty_winbuffer {
+ uint16_t wb_row;
+ uint16_t wb_col;
+ uint16_t wb_prev_row;
+ uint16_t wb_prev_col;
+};
+
+
+struct tty_winpos {
+ uint16_t wp_x;
+ uint16_t wp_y;
+ uint16_t wp_prev_x;
+ uint16_t wp_prev_y;
+};
+
+
+struct tty_winprops {
+ struct tty_winsize winsize;
+ struct tty_winbuffer winbuffer;
+ struct tty_winpos winpos;
+};
+
+#endif
diff --git a/include/ntapi/nt_thread.h b/include/ntapi/nt_thread.h
new file mode 100644
index 0000000..7e39c96
--- /dev/null
+++ b/include/ntapi/nt_thread.h
@@ -0,0 +1,263 @@
+#ifndef _NT_THREAD_H_
+#define _NT_THREAD_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+#include "bits/i386/nt_thread_i386.h"
+#include "bits/x86_64/nt_thread_x86_64.h"
+
+typedef enum _nt_thread_info_class {
+ NT_THREAD_BASIC_INFORMATION,
+ NT_THREAD_TIMES,
+ NT_THREAD_PRIORITY,
+ NT_THREAD_BASE_PRIORITY,
+ NT_THREAD_AFFINITY_MASK,
+ NT_THREAD_IMPERSONATION_TOKEN,
+ NT_THREAD_DESCRIPTOR_TABLE_ENTRY,
+ NT_THREAD_ENABLE_ALIGNMENT_FAULT_FIXUP,
+ NT_THREAD_EVENT_PAIR,
+ NT_THREAD_QUERY_SET_WIN32_START_ADDRESS,
+ NT_THREAD_ZERO_TLS_CELL,
+ NT_THREAD_PERFORMANCE_COUNT,
+ NT_THREAD_AM_I_LASTNT_THREAD,
+ NT_THREAD_IDEAL_PROCESSOR,
+ NT_THREAD_PRIORITY_BOOST,
+ NT_THREAD_SET_TLS_ARRAY_ADDRESS,
+ NT_THREAD_IS_IO_PENDING,
+ NT_THREAD_HIDE_FROM_DEBUGGER
+} nt_thread_info_class;
+
+typedef enum _nt_exception_disposition {
+ NT_EXCEPTION_CONTINUE_EXECUTION,
+ NT_EXCEPTION_CONTINUE_SEARCH,
+ NT_EXCEPTION_NESTED_EXCEPTION,
+ NT_EXCEPTION_COLLIDED_UNWIND
+} nt_exception_disposition;
+
+
+/* special handles */
+#define NT_CURRENT_THREAD_HANDLE (void *)(uintptr_t)-2
+
+/* thread access bits */
+#define NT_THREAD_TERMINATE 0x00000001
+#define NT_THREAD_SUSPEND_RESUME 0x00000002
+#define NT_THREAD_ALERT 0x00000004 /* fits right in the middle... */
+#define NT_THREAD_GET_CONTEXT 0x00000008
+#define NT_THREAD_SET_CONTEXT 0x00000010
+#define NT_THREAD_SET_INFORMATION 0x00000020
+#define NT_THREAD_QUERY_INFORMATION 0x00000040
+#define NT_THREAD_SET_THREAD_TOKEN 0x00000080
+#define NT_THREAD_IMPERSONATE 0x00000100
+#define NT_THREAD_DIRECT_IMPERSONATION 0x00000200
+#define NT_THREAD_SYNCHRONIZE 0x00100000
+
+#define NT_THREAD_ALL_ACCESS NT_THREAD_TERMINATE \
+ | NT_THREAD_SUSPEND_RESUME \
+ | NT_THREAD_ALERT \
+ | NT_THREAD_GET_CONTEXT \
+ | NT_THREAD_SET_CONTEXT \
+ | NT_THREAD_SET_INFORMATION \
+ | NT_THREAD_QUERY_INFORMATION \
+ | NT_THREAD_SET_THREAD_TOKEN \
+ | NT_THREAD_IMPERSONATE \
+ | NT_THREAD_DIRECT_IMPERSONATION \
+ | NT_THREAD_SYNCHRONIZE
+
+/* library-specific thread creation flags */
+#define NT_THREAD_RUN_IMMEDIATELY 0x00000000
+#define NT_CREATE_SUSPENDED 0x00000004
+#define NT_CREATE_FIRST_THREAD_OF_PROCESS 0x00008000
+#define NT_CREATE_LOCAL_THREAD 0x00010000
+#define NT_STACK_SIZE_PARAM_IS_A_RESERVATION 0x00800000
+#define NT_CLOSE_THREAD_HANDLE 0x01000000
+
+
+/* thread context */
+#define NT_CONTEXT_JUST_EVERYTHING (intptr_t)-1
+
+
+/* source mark: arch-specific code: begin */
+#if defined(__NT32) && defined (__X86_MODEL)
+typedef struct _nt_thread_context_i386 nt_thread_context;
+#elif defined(__NT64) && defined (__X86_64_MODEL)
+typedef nt_mcontext_x86_64_t nt_thread_context;
+typedef nt_mcontext_x86_64_t nt_mcontext_t;
+#endif
+/* source mark: arch-specific code: end */
+
+
+typedef struct _nt_user_stack {
+ void * fixed_stack_base;
+ void * fixed_stack_limit;
+ void * expandable_stack_base;
+ void * expandable_stack_limit;
+ void * expandable_stack_bottom;
+} nt_user_stack;
+
+
+typedef struct _nt_exception_registration_record {
+ struct _nt_exception_registration_record * next;
+ nt_exception_disposition * handler;
+} nt_exception_registration_record;
+
+
+typedef struct _nt_tib {
+ nt_exception_registration_record * exception_list;
+ void * stack_base;
+ void * stack_limit;
+ void * sub_system_tib;
+
+ union {
+ void * fiber_data;
+ uint32_t version;
+ };
+
+ void * arbitrary_user_pointer;
+ struct _nt_tib * self;
+} nt_tib;
+
+
+typedef struct _nt_thread_basic_information {
+ int32_t exit_status;
+ nt_tib * teb_base_address;
+ nt_client_id cid;
+ intptr_t affinity_mask;
+ int32_t priority;
+ int32_t base_priority;
+} nt_thread_basic_information;
+
+
+typedef int32_t __stdcall nt_thread_start_routine(void * context);
+
+
+typedef struct _nt_thread_params {
+ __in void * hprocess;
+ __out void * hthread;
+ __in nt_thread_start_routine * start;
+ __in void * arg __optional;
+ __in void * ext_ctx __optional;
+ __in size_t ext_ctx_size;
+ __in nt_object_attributes * obj_attr __optional;
+ __in uint32_t creation_flags;
+ __in uint32_t stack_zero_bits;
+ __in size_t stack_size_commit;
+ __in size_t stack_size_reserve;
+ __in nt_user_stack * stack_info __optional;
+ __in nt_thread_context * reg_context __optional;
+ __out int32_t csrss_status;
+ __out uint32_t thread_id;
+ __in void * reserved[2];
+} nt_thread_params;
+
+
+typedef void __stdcall nt_knormal_routine(
+ void * apc_context,
+ void * arg_1st,
+ void * arg_2nd);
+
+
+typedef int32_t __stdcall ntapi_zw_create_thread(
+ __out void ** hthread,
+ __in uintptr_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in void * hprocess,
+ __out nt_client_id * hclient_id,
+ __in nt_thread_context * context,
+ __in nt_user_stack * user_stack,
+ __in uintptr_t suspended_flag);
+
+
+typedef int32_t __stdcall ntapi_zw_open_thread(
+ __out void ** hthread,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in nt_client_id * hclient_id);
+
+
+typedef int32_t __stdcall ntapi_zw_terminate_thread(
+ __in void * hthread,
+ __in int32_t exit_status);
+
+
+typedef int32_t __stdcall ntapi_zw_query_information_thread(
+ __in void * hthread,
+ __in nt_thread_info_class thread_info_class,
+ __out void * thread_info,
+ __in size_t thread_info_length,
+ __out size_t * returned_length __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_set_information_thread(
+ __in void * hthread,
+ __in nt_thread_info_class thread_info_class,
+ __in void * thread_info,
+ __in size_t thread_info_length);
+
+
+typedef int32_t __stdcall ntapi_zw_suspend_thread(
+ __in void * hthread,
+ __out uint32_t * prev_suspend_count __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_resume_thread(
+ __in void * hthread,
+ __out uint32_t * prev_suspend_count __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_get_context_thread(
+ __in void * hthread,
+ __out void * context);
+
+
+typedef int32_t __stdcall ntapi_zw_set_context_thread(
+ __in void * hthread,
+ __in void * context);
+
+
+typedef int32_t __stdcall ntapi_zw_queue_apc_thread(
+ __in void * hthread,
+ __in nt_knormal_routine * apc_routine,
+ __in void * apc_context,
+ __in void * arg_1st,
+ __in void * arg_2nd);
+
+
+typedef int32_t __stdcall ntapi_zw_test_alert(void);
+
+
+typedef int32_t __stdcall ntapi_zw_alert_thread(
+ __in void * hthread);
+
+
+typedef int32_t __stdcall ntapi_zw_alert_resume_thread(
+ __in void * hthread,
+ __out uint32_t * prev_suspend_count __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_register_thread_terminate_port(
+ __in void * port_handle);
+
+
+typedef int32_t __stdcall ntapi_zw_impersonate_thread(
+ __in void * hthread,
+ __in void * target_thread_handle,
+ __in nt_security_quality_of_service * sec_qos);
+
+
+typedef int32_t __stdcall ntapi_zw_impersonate_anonymous_token(
+ __in void * hthread);
+
+
+/* extension functions */
+typedef int32_t __stdcall ntapi_tt_create_local_thread(
+ __in_out nt_thread_params * params);
+
+
+typedef int32_t __stdcall ntapi_tt_create_remote_thread(
+ __in_out nt_thread_params * params);
+
+
+typedef int32_t __stdcall ntapi_tt_create_thread(
+ __in_out nt_thread_params * params);
+
+#endif
diff --git a/include/ntapi/nt_time.h b/include/ntapi/nt_time.h
new file mode 100644
index 0000000..b8ddd41
--- /dev/null
+++ b/include/ntapi/nt_time.h
@@ -0,0 +1,45 @@
+#ifndef _NT_TIME_H_
+#define _NT_TIME_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef struct _nt_itimerval {
+ nt_timeout interval;
+ nt_timeout value;
+} nt_itimerval;
+
+typedef int32_t __stdcall ntapi_zw_query_system_time(
+ __out nt_large_integer * current_time);
+
+
+typedef int32_t __stdcall ntapi_zw_set_system_time(
+ __in nt_large_integer * new_time,
+ __out nt_large_integer * old_time __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_query_performance_counter(
+ __out nt_large_integer * performance_count,
+ __out nt_large_integer * performance_frequency __optional);
+
+
+typedef int32_t __stdcall ntapi_zw_set_timer_resolution(
+ __in uint32_t requested_resolution,
+ __in int32_t set,
+ __out uint32_t * actual_resolution);
+
+
+typedef int32_t __stdcall ntapi_zw_query_timer_resolution(
+ __out uint32_t * coarsest_resolution,
+ __out uint32_t * finest_resolution,
+ __out uint32_t * actual_resolution);
+
+
+typedef int32_t __stdcall ntapi_zw_delay_execution(
+ __in int32_t * alertable,
+ __in nt_large_integer * interval);
+
+typedef int32_t __stdcall ntapi_zw_yield_execution(void);
+
+
+#endif
diff --git a/include/ntapi/nt_token.h b/include/ntapi/nt_token.h
new file mode 100644
index 0000000..aa2df2c
--- /dev/null
+++ b/include/ntapi/nt_token.h
@@ -0,0 +1,161 @@
+#ifndef _NT_TOKEN_H_
+#define _NT_TOKEN_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef enum _nt_token_type {
+ NT_TOKEN_PRIMARY = 1,
+ NT_TOKEN_IMPERSONATION = 2,
+} nt_token_type;
+
+
+typedef enum _nt_token_info_class {
+ NT_TOKEN_USER = 1,
+ NT_TOKEN_GROUPS = 2,
+ NT_TOKEN_PRIVILEGES = 3,
+ NT_TOKEN_OWNER = 4,
+ NT_TOKEN_PRIMARY_GROUP = 5,
+ NT_TOKEN_DEFAULT_DACL = 6,
+ NT_TOKEN_SOURCE = 7,
+ NT_TOKEN_TYPE = 8,
+ NT_TOKEN_IMPERSONATION_LEVEL = 9,
+ NT_TOKEN_STATISTICS = 10,
+ NT_TOKEN_RESTRICTED_SIDS = 11,
+ NT_TOKEN_SESSION_ID = 12,
+} nt_token_info_class;
+
+
+/* token access bits */
+#define NT_TOKEN_ASSIGN_PRIMARY 0x00000001U
+#define NT_TOKEN_DUPLICATE 0x00000002U
+#define NT_TOKEN_IMPERSONATE 0x00000004U
+#define NT_TOKEN_QUERY 0x00000008U
+#define NT_TOKEN_QUERY_SOURCE 0x00000010U
+#define NT_TOKEN_ADJUST_PRIVILEGES 0x00000020U
+#define NT_TOKEN_ADJUST_GROUPS 0x00000040U
+#define NT_TOKEN_ADJUST_DEFAULT 0x00000080U
+#define NT_TOKEN_ADJUST_SESSIONID 0x00000100U
+
+#define NT_TOKEN_ALL_ACCESS NT_SEC_STANDARD_RIGHTS_REQUIRED \
+ | NT_TOKEN_ASSIGN_PRIMARY \
+ | NT_TOKEN_DUPLICATE \
+ | NT_TOKEN_IMPERSONATE \
+ | NT_TOKEN_QUERY \
+ | NT_TOKEN_QUERY_SOURCE \
+ | NT_TOKEN_ADJUST_PRIVILEGES \
+ | NT_TOKEN_ADJUST_GROUPS \
+ | NT_TOKEN_ADJUST_SESSIONID \
+ | NT_TOKEN_ADJUST_DEFAULT
+
+
+#define NT_TOKEN_READ NT_SEC_STANDARD_RIGHTS_READ \
+ | NT_TOKEN_QUERY
+
+
+#define NT_TOKEN_WRITE NT_SEC_STANDARD_RIGHTS_WRITE \
+ | TOKEN_ADJUST_PRIVILEGES \
+ | NT_OKEN_ADJUST_GROUPS \
+ | NT_TOKEN_ADJUST_DEFAULT
+
+#define NT_TOKEN_EXECUTE NT_SEC_STANDARD_RIGHTS_EXECUTE
+
+
+/* filtered token flags */
+#define NT_DISABLE_MAX_PRIVILEGE 0x01
+
+
+typedef struct _nt_token_statistics {
+ nt_luid token_id;
+ nt_luid authentication_id;
+ nt_large_integer expiration_time;
+ nt_token_type token_type;
+ nt_security_impersonation_level impersonation_level;
+ uint32_t dynamic_charged;
+ uint32_t dynamic_available;
+ uint32_t group_count;
+ uint32_t privilege_count;
+ nt_luid modified_id;
+} nt_token_statistics;
+
+
+typedef int32_t __stdcall ntapi_zw_create_token(
+ __out void ** htoken,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in nt_token_type type,
+ __in nt_luid * authentication_id,
+ __in nt_large_integer * expiration_time,
+ __in nt_token_user * user,
+ __in nt_token_groups * groups,
+ __in nt_token_privileges * privileges,
+ __in nt_token_owner * owner,
+ __in nt_token_primary_group * primary_group,
+ __in nt_token_default_dacl * default_dacl,
+ __in nt_token_source * source);
+
+
+typedef int32_t __stdcall ntapi_zw_open_process_token(
+ __in void * hprocess,
+ __in uint32_t desired_access,
+ __out void ** htoken);
+
+
+typedef int32_t __stdcall ntapi_zw_open_thread_token(
+ __in void * hthread,
+ __in uint32_t desired_access,
+ __in int32_t open_as_self,
+ __out void ** htoken);
+
+
+typedef int32_t __stdcall ntapi_zw_duplicate_token(
+ __in void * htoken_existing,
+ __in uint32_t desired_access,
+ __in nt_object_attributes * obj_attr,
+ __in int32_t effective_only,
+ __in nt_token_type token_type,
+ __out void ** htoken_new);
+
+
+typedef int32_t __stdcall ntapi_zw_filter_token(
+ __in void * htoken_existing,
+ __in uint32_t flags,
+ __in nt_token_groups * sids_to_disable,
+ __in nt_token_privileges * privileges_to_delete,
+ __in nt_token_groups * sids_to_restrict,
+ __out void ** htoken_new);
+
+
+typedef int32_t __stdcall ntapi_zw_adjust_privileges_token(
+ __in void * htoken,
+ __in int32_t disable_all_privileges,
+ __in nt_token_privileges * new_state,
+ __in size_t buffer_length,
+ __in nt_token_privileges * prev_state __optional,
+ __out size_t * returned_length);
+
+
+typedef int32_t __stdcall ntapi_zw_adjust_groups_token(
+ __in void * htoken,
+ __in int32_t reset_to_default,
+ __in nt_token_groups * new_state,
+ __in size_t buffer_length,
+ __in nt_token_groups * prev_state __optional,
+ __out size_t * returned_length);
+
+
+typedef int32_t __stdcall ntapi_zw_query_information_token(
+ __in void * htoken,
+ __in nt_token_info_class token_info_class,
+ __out void * token_info,
+ __in size_t token_info_length,
+ __out size_t * returned_length);
+
+
+typedef int32_t __stdcall ntapi_zw_set_information_token(
+ __in void * htoken,
+ __in nt_token_info_class token_info_class,
+ __in void * token_info,
+ __in size_t token_info_length);
+
+#endif
diff --git a/include/ntapi/nt_tty.h b/include/ntapi/nt_tty.h
new file mode 100644
index 0000000..4783eb6
--- /dev/null
+++ b/include/ntapi/nt_tty.h
@@ -0,0 +1,438 @@
+#ifndef _NT_TTY_H_
+#define _NT_TTY_H_
+
+/**
+ * tty api:
+ * -----------
+ * this header describes the tty interfaces that are used
+ * by native applications and libraries to communicate with
+ * ntctty, the project's native subsystem and pty server.
+**/
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+#include "nt_port.h"
+#include "nt_termios.h"
+
+typedef enum _nt_tty_opcode {
+ NT_TTY_CLIENT_OPCODE_BASE = 0x40000,
+ /* primary connection */
+ NT_TTY_CLIENT_SESSION_CONNECT = NT_TTY_CLIENT_OPCODE_BASE,
+ NT_TTY_CLIENT_SESSION_DISCONNECT,
+ NT_TTY_CLIENT_SESSION_QUERY,
+ NT_TTY_CLIENT_SESSION_SET,
+ /* process registration */
+ NT_TTY_CLIENT_PROCESS_REGISTER,
+ NT_TTY_CLIENT_PROCESS_UNREGISTER,
+ /* session information */
+ NT_TTY_QUERY_INFORMATION_SERVER,
+ NT_TTY_QUERY_INFORMATION_SESSION,
+ NT_TTY_QUERY_INFORMATION_PROCESS,
+ NT_TTY_QUERY_INFORMATION_THREAD,
+ NT_TTY_QUERY_INFORMATION_SECTION,
+ NT_TTY_QUERY_INFORMATION_PTY,
+ /* peer daemon calls */
+ NT_TTY_REQUEST_PEER,
+ NT_TTY_SIGNAL_PEER,
+ /* pty */
+ NT_TTY_PTY_OPEN,
+ NT_TTY_PTY_CLOSE,
+ NT_TTY_PTY_READ,
+ NT_TTY_PTY_WRITE,
+ NT_TTY_PTY_QUERY,
+ NT_TTY_PTY_SET,
+ NT_TTY_PTY_FCNTL,
+ NT_TTY_PTY_IOCTL,
+ NT_TTY_PTY_CANCEL,
+ NT_TTY_PTY_PEEK,
+ /* virtual mount system */
+ NT_TTY_VMS_QUERY,
+ NT_TTY_VMS_REQUEST,
+ /* exclusive upper limit */
+ NT_TTY_CLIENT_OPCODE_CAP
+} nt_tty_opcode;
+
+
+typedef enum _nt_tty_session_type {
+ NT_TTY_SESSION_PRIMARY,
+ NT_TTY_SESSION_PRIVATE
+} nt_tty_session_type;
+
+
+typedef enum _nt_tty_info_class {
+ NT_TTY_SESSION_INFORMATION,
+ NT_TTY_INFORMATION_CAP
+} nt_tty_info_class;
+
+
+typedef enum _nt_pty_info_class {
+ NT_PTY_BASIC_INFORMATION,
+ NT_PTY_CLIENT_INFORMATION,
+ NT_PTY_INFORMATION_CAP
+} nt_pty_info_class;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_msg_info {
+ uintptr_t msg_id;
+ uint32_t opcode;
+ int32_t status;
+ void * reserved;
+} nt_tty_msg_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_register_info {
+ uintptr_t process_id;
+ uintptr_t thread_id;
+ uintptr_t flags;
+ uintptr_t reserved;
+} nt_tty_register_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_server_info {
+ nt_port_attr attr;
+ intptr_t pid;
+ intptr_t tid;
+} nt_tty_server_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_vms_info {
+ void * hroot;
+ uint32_t hash;
+ uint32_t flags;
+ int64_t key;
+ nt_guid vms_guid;
+ nt_port_keys vms_keys;
+} nt_tty_vms_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_peer_info {
+ uint32_t opcode;
+ uint32_t flags;
+ nt_guid service;
+ nt_port_attr peer;
+} nt_tty_peer_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_sigctl_info {
+ void * hpty;
+ nt_guid guid;
+ nt_luid luid;
+ uint32_t ctlcode;
+ int32_t cccode;
+ nt_client_id cid;
+ uintptr_t ctxarg[4];
+ struct tty_termios terminfo;
+ struct tty_winsize winsize;
+ nt_iosb iosb;
+} nt_tty_sigctl_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_pty_fd_info {
+ void * hpty;
+ void * section;
+ void * section_addr;
+ size_t section_size;
+ nt_guid guid;
+ nt_luid luid;
+ uint32_t access;
+ uint32_t flags;
+ uint32_t share;
+ uint32_t options;
+ intptr_t state;
+ void * hevent[2];
+} nt_pty_fd_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_pty_io_info {
+ void * hpty;
+ void * hevent;
+ void * reserved;
+ void * apc_routine;
+ void * apc_context;
+ nt_iosb * riosb;
+ void * raddr;
+ nt_iosb iosb;
+ off_t offset;
+ size_t nbytes;
+ uint32_t key;
+ uint32_t npending;
+ nt_guid guid;
+ nt_luid luid;
+} nt_pty_io_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_pty_client_info {
+ uintptr_t any[4];
+} nt_pty_client_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_session_info {
+ int32_t pid;
+ int32_t pgid;
+ int32_t sid;
+ int32_t reserved;
+} nt_tty_session_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_register_msg {
+ nt_port_message header;
+ struct {
+ nt_tty_msg_info ttyinfo;
+ nt_tty_register_info reginfo;
+ } data;
+} nt_tty_register_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_server_msg {
+ nt_port_message header;
+ struct {
+ nt_tty_msg_info ttyinfo;
+ nt_tty_server_info srvinfo;
+ } data;
+} nt_tty_server_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_vms_msg {
+ nt_port_message header;
+ struct {
+ nt_tty_msg_info ttyinfo;
+ nt_tty_vms_info vmsinfo;
+ } data;
+} nt_tty_vms_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_peer_msg {
+ nt_port_message header;
+ struct {
+ nt_tty_msg_info ttyinfo;
+ nt_tty_peer_info peerinfo;
+ } data;
+} nt_tty_peer_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_pty_fd_msg {
+ nt_port_message header;
+ struct {
+ nt_tty_msg_info ttyinfo;
+ nt_pty_fd_info fdinfo;
+ } data;
+} nt_pty_fd_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_pty_io_msg {
+ nt_port_message header;
+ struct {
+ nt_tty_msg_info ttyinfo;
+ nt_pty_io_info ioinfo;
+ } data;
+} nt_pty_io_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_pty_sigctl_msg {
+ nt_port_message header;
+ struct {
+ nt_tty_msg_info ttyinfo;
+ nt_tty_sigctl_info ctlinfo;
+ } data;
+} nt_pty_sigctl_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_session_msg {
+ nt_port_message header;
+ struct {
+ nt_tty_msg_info ttyinfo;
+ nt_tty_session_info sessioninfo;
+ } data;
+} nt_tty_session_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_port_msg {
+ nt_port_message header;
+ nt_tty_msg_info ttyinfo;
+ union {
+ nt_tty_register_info reginfo;
+ nt_tty_vms_info vmsinfo;
+ nt_tty_peer_info peerinfo;
+ nt_tty_sigctl_info ctlinfo;
+ nt_pty_fd_info fdinfo;
+ nt_pty_io_info ioinfo;
+ nt_pty_client_info clientinfo;
+ nt_tty_session_info sessioninfo;
+ };
+} nt_tty_port_msg;
+
+
+__assert_aligned_size(nt_tty_msg_info, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_tty_register_info, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_tty_vms_info, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_tty_peer_info, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_tty_sigctl_info, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_pty_fd_info, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_pty_io_info, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_tty_register_msg, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_tty_vms_msg, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_tty_peer_msg, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_pty_sigctl_msg, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_pty_fd_msg, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_pty_io_msg, __SIZEOF_POINTER__);
+__assert_aligned_size(nt_tty_port_msg, __SIZEOF_POINTER__);
+
+
+/* tty session */
+typedef int32_t __stdcall ntapi_tty_create_session(
+ __out void ** hport,
+ __out nt_port_name * port_name,
+ __in nt_tty_session_type type,
+ __in const nt_guid * guid __optional,
+ __in wchar16_t * image_name __optional);
+
+
+typedef int32_t __stdcall ntapi_tty_join_session(
+ __out void ** hport,
+ __out nt_port_name * port_name,
+ __in nt_port_attr * port_attr,
+ __in nt_tty_session_type type);
+
+
+typedef int32_t __stdcall ntapi_tty_connect(
+ __out void ** hport,
+ __in wchar16_t * tty_port_name,
+ __in int32_t impersonation_level);
+
+
+typedef int32_t __stdcall ntapi_tty_client_session_query(
+ __in void * hport,
+ __out nt_tty_session_info * sessioninfo);
+
+
+typedef int32_t __stdcall ntapi_tty_client_session_set(
+ __in void * hport,
+ __in nt_tty_session_info * sessioninfo);
+
+
+typedef int32_t __stdcall ntapi_tty_client_process_register(
+ __in void * hport,
+ __in uintptr_t process_id,
+ __in uintptr_t thread_id,
+ __in uintptr_t flags,
+ __in nt_large_integer * reserved);
+
+
+typedef int32_t __stdcall ntapi_tty_query_information_server(
+ __in void * hport,
+ __out nt_tty_server_info * srvinfo);
+
+
+/* pty api */
+typedef struct nt_pty_context nt_pty;
+
+typedef int32_t __stdcall ntapi_pty_open(
+ __in void * hport,
+ __out nt_pty ** pty,
+ __in uint32_t desired_access,
+ __in nt_object_attributes* obj_attr,
+ __out nt_iosb * iosb,
+ __in uint32_t share_access,
+ __in uint32_t open_options);
+
+
+typedef int32_t __stdcall ntapi_pty_reopen(
+ __in void * hport,
+ __in nt_pty * pty);
+
+
+typedef int32_t __stdcall ntapi_pty_close(
+ __in nt_pty * pty);
+
+
+typedef int32_t __stdcall ntapi_pty_read(
+ __in nt_pty * pty,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_iosb * iosb,
+ __out void * buffer,
+ __in uint32_t nbytes,
+ __in nt_large_integer * offset __optional,
+ __in uint32_t * key __optional);
+
+
+typedef int32_t __stdcall ntapi_pty_write(
+ __in nt_pty * pty,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_iosb * iosb,
+ __in void * buffer,
+ __in uint32_t nbytes,
+ __in nt_large_integer * offset __optional,
+ __in uint32_t * key __optional);
+
+
+typedef int32_t __stdcall ntapi_pty_fcntl(
+ __in nt_pty * pty,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_iosb * iosb,
+ __in uint32_t fs_control_code,
+ __in void * input_buffer __optional,
+ __in uint32_t input_buffer_length,
+ __out void * output_buffer __optional,
+ __in uint32_t output_buffer_length);
+
+
+typedef int32_t __stdcall ntapi_pty_ioctl(
+ __in nt_pty * pty,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_iosb * iosb,
+ __in uint32_t io_control_code,
+ __in void * input_buffer __optional,
+ __in uint32_t input_buffer_length,
+ __out void * output_buffer __optional,
+ __in uint32_t output_buffer_length);
+
+
+typedef int32_t __stdcall ntapi_pty_query(
+ __in nt_pty * pty,
+ __out nt_io_status_block * iosb,
+ __out void * pty_info,
+ __in uint32_t pty_info_length,
+ __in nt_pty_info_class pty_info_class);
+
+
+typedef int32_t __stdcall ntapi_pty_set(
+ __in nt_pty * hfile,
+ __out nt_io_status_block * iosb,
+ __in void * pty_info,
+ __in uint32_t pty_info_length,
+ __in nt_pty_info_class pty_info_class);
+
+
+typedef int32_t __stdcall ntapi_pty_cancel(
+ __in nt_pty * pty,
+ __out nt_iosb * iosb);
+
+
+/* peer daemon calls */
+typedef int32_t __stdcall ntapi_tty_request_peer(
+ __in void * hport,
+ __in int32_t opcode,
+ __in uint32_t flags,
+ __in const nt_guid * service,
+ __in nt_port_attr * peer);
+
+
+/* virtual mount system */
+typedef int32_t __stdcall ntapi_tty_vms_query(
+ __in void * hport,
+ __in nt_tty_vms_info * vmsinfo);
+
+
+typedef int32_t __stdcall ntapi_tty_vms_request(
+ __in void * hport,
+ __in nt_tty_vms_info * vmsinfo);
+
+#endif
diff --git a/include/ntapi/nt_unicode.h b/include/ntapi/nt_unicode.h
new file mode 100644
index 0000000..346b744
--- /dev/null
+++ b/include/ntapi/nt_unicode.h
@@ -0,0 +1,146 @@
+#ifndef _NT_UNICODE_H_
+#define _NT_UNICODE_H_
+
+/**
+ * the conversion functions are based on the validation functions;
+ * each of the conversion functions passes its peer validation
+ * function an array of callback handlers, with each member of
+ * the array corresponding to the number of units making the
+ * current code point in utf-8, be that source or destination.
+ * following this logic, then, callback_fn[1] handles 1-byte
+ * code points [00..7F], callback_fn[2] handles 2-byte code
+ * points [C2..DF,80..BF], and so on. the first member of
+ * the array, callback_fn[0], is invoked once the null
+ * termination of the source stream has been reached.
+**/
+
+typedef struct _nt_utf8_callback_args {
+ const unsigned char * src;
+ void * dst;
+ void * dst_cap;
+ uint32_t byte_count;
+ uint32_t code_point;
+ size_t bytes_written;
+} nt_utf8_callback_args;
+
+
+typedef struct _nt_utf16_callback_args {
+ const wchar16_t * src;
+ void * dst;
+ void * dst_cap;
+ uint32_t byte_count;
+ uint32_t code_point;
+ size_t bytes_written;
+} nt_utf16_callback_args;
+
+
+typedef struct _nt_unicode_conversion_params_utf8_to_utf16 {
+ const unsigned char * src;
+ size_t src_size_in_bytes;
+ wchar16_t * dst;
+ size_t dst_size_in_bytes;
+ size_t code_points;
+ size_t bytes_written;
+ void * addr_failed;
+ uintptr_t leftover_count;
+ uintptr_t leftover_bytes;
+} nt_unicode_conversion_params_utf8_to_utf16, nt_strconv_mbtonative;
+
+
+typedef struct _nt_unicode_conversion_params_utf8_to_utf32 {
+ const unsigned char * src;
+ size_t src_size_in_bytes;
+ wchar32_t * dst;
+ size_t dst_size_in_bytes;
+ size_t code_points;
+ size_t bytes_written;
+ void * addr_failed;
+ uintptr_t leftover_count;
+ uintptr_t leftover_bytes;
+} nt_unicode_conversion_params_utf8_to_utf32, nt_strconv_mbtowide;
+
+
+typedef struct _nt_unicode_conversion_params_utf16_to_utf8 {
+ const wchar16_t * src;
+ size_t src_size_in_bytes;
+ unsigned char * dst;
+ size_t dst_size_in_bytes;
+ size_t code_points;
+ size_t bytes_written;
+ void * addr_failed;
+ uintptr_t leftover_count;
+ uintptr_t leftover_bytes;
+} nt_unicode_conversion_params_utf16_to_utf8, nt_strconv_nativetomb;
+
+
+typedef struct _nt_unicode_conversion_params_utf16_to_utf32 {
+ const wchar16_t * src;
+ size_t src_size_in_bytes;
+ wchar32_t * dst;
+ size_t dst_size_in_bytes;
+ size_t code_points;
+ size_t bytes_written;
+ void * addr_failed;
+ uintptr_t leftover_count;
+ uintptr_t leftover_bytes;
+} nt_unicode_conversion_params_utf16_to_utf32, nt_strconv_nativetowide;
+
+__assert_aligned_size(nt_utf8_callback_args,__SIZEOF_POINTER__);
+__assert_aligned_size(nt_utf16_callback_args,__SIZEOF_POINTER__);
+__assert_aligned_size(nt_unicode_conversion_params_utf8_to_utf16,__SIZEOF_POINTER__);
+__assert_aligned_size(nt_unicode_conversion_params_utf8_to_utf32,__SIZEOF_POINTER__);
+__assert_aligned_size(nt_unicode_conversion_params_utf16_to_utf8,__SIZEOF_POINTER__);
+__assert_aligned_size(nt_unicode_conversion_params_utf16_to_utf32,__SIZEOF_POINTER__);
+
+
+typedef int32_t __fastcall ntapi_uc_utf8_callback_fn(
+ __in nt_utf8_callback_args * callback_args);
+
+
+typedef int32_t __fastcall ntapi_uc_utf16_callback_fn(
+ __in nt_utf16_callback_args * callback_args);
+
+
+typedef int32_t __stdcall ntapi_uc_validate_unicode_stream_utf8(
+ __in const unsigned char * ch,
+ __in size_t size_in_bytes __optional,
+ __out size_t * code_points __optional,
+ __out void ** addr_failed __optional,
+ __in ntapi_uc_utf8_callback_fn ** callback_fn __optional,
+ __in nt_utf8_callback_args * callback_args __optional);
+
+
+typedef int32_t __stdcall ntapi_uc_validate_unicode_stream_utf16(
+ __in const wchar16_t * wch,
+ __in size_t size_in_bytes __optional,
+ __out size_t * code_points __optional,
+ __out void ** addr_failed __optional,
+ __in ntapi_uc_utf16_callback_fn ** callback_fn __optional,
+ __in nt_utf16_callback_args * callback_args __optional);
+
+
+typedef int __stdcall ntapi_uc_get_code_point_byte_count_utf8(
+ __in uint32_t code_point);
+
+
+typedef int __stdcall ntapi_uc_get_code_point_byte_count_utf16(
+ __in uint32_t code_point);
+
+
+typedef int32_t __stdcall ntapi_uc_convert_unicode_stream_utf8_to_utf16(
+ __in_out nt_unicode_conversion_params_utf8_to_utf16 * params);
+
+
+typedef int32_t __stdcall ntapi_uc_convert_unicode_stream_utf8_to_utf32(
+ __in_out nt_unicode_conversion_params_utf8_to_utf32 * params);
+
+
+typedef int32_t __stdcall ntapi_uc_convert_unicode_stream_utf16_to_utf8(
+ __in_out nt_unicode_conversion_params_utf16_to_utf8 * params);
+
+
+typedef int32_t __stdcall ntapi_uc_convert_unicode_stream_utf16_to_utf32(
+ __in_out nt_unicode_conversion_params_utf16_to_utf32 * params);
+
+
+#endif
diff --git a/include/ntapi/nt_uuid.h b/include/ntapi/nt_uuid.h
new file mode 100644
index 0000000..c4b4cde
--- /dev/null
+++ b/include/ntapi/nt_uuid.h
@@ -0,0 +1,22 @@
+#ifndef _NT_UUID_H_
+#define _NT_UUID_H_
+
+#include <psxtypes/psxtypes.h>
+#include "nt_object.h"
+
+typedef int32_t __stdcall ntapi_zw_allocate_locally_unique_id(
+ __out nt_luid * luid);
+
+
+/* insufficient for version 4 uuid's */
+typedef int32_t __stdcall ntapi_zw_allocate_uuids(
+ __out nt_large_integer * uuid_last_time_allocated,
+ __out uint32_t * uuid_delta_time,
+ __out uint32_t * uuid_sequence_number,
+ __out unsigned char * uuid_seed);
+
+
+typedef int32_t __stdcall ntapi_zw_set_uuid_seed(
+ __in unsigned char * uuid_seed);
+
+#endif
diff --git a/include/ntapi/nt_vfd.h b/include/ntapi/nt_vfd.h
new file mode 100644
index 0000000..18185aa
--- /dev/null
+++ b/include/ntapi/nt_vfd.h
@@ -0,0 +1,20 @@
+#ifndef _NT_VFD_H_
+#define _NT_VFD_H_
+
+#include <psxtypes/psxtypes.h>
+#include <dalist/dalist.h>
+#include "nt_object.h"
+#include "nt_guid.h"
+
+typedef struct _nt_vfd_dev_name {
+ nt_unicode_string name;
+ wchar16_t prefix[8];
+ nt_guid_str_utf16 guid;
+} nt_vfd_dev_name;
+
+
+typedef void __stdcall ntapi_vfd_dev_name_init(
+ __out nt_vfd_dev_name * devname,
+ __in const nt_guid * guid);
+
+#endif
diff --git a/include/ntapi/nt_vmount.h b/include/ntapi/nt_vmount.h
new file mode 100644
index 0000000..8c5db0c
--- /dev/null
+++ b/include/ntapi/nt_vmount.h
@@ -0,0 +1,329 @@
+#ifndef _NT_VMOUNT_H_
+#define _NT_VMOUNT_H_
+
+#include <psxtypes/psxtypes.h>
+#include <dalist/dalist.h>
+#include "nt_port.h"
+#include "nt_file.h"
+#include "nt_statfs.h"
+#include "nt_tty.h"
+
+/**
+ * vmount api:
+ * -----------
+ * this header provides an api that can be used to
+ * implement a virtual mount system. note, however,
+ * that this library does not (and should not)
+ * provide the server-side implementation of the
+ * system, but only the client-side functionality.
+ * in the larger-scale midipix project, for
+ * instance, a session-wide virtual mount system
+ * is provided by the subsystem ntctty; if you
+ * are writing a free-standing midipix application,
+ * then you may either use the interfaces provided
+ * by ntctty, or roll your own.
+**/
+
+
+/** virtual mount system: concepts
+ * ------------------------------
+ * elements of the virtual mount system are exposed to the
+ * client in terms of offsets from the virtual mount system
+ * base address, rather than absolute pointers. when using
+ * a shared memory section, this allows each client to map
+ * the virtual mount system at an address that is independent
+ * of all other clients. most importantly, clients are only
+ * granted read-only access to the section, and it is hence
+ * impossible for a malformed client to trash the contents
+ * of the virtual mount system.
+ *
+ * to locate information regarding a particular mount point,
+ * the client traverses the virtual mount system using several
+ * numeric keys.
+ *
+ * the server_key member of the virtual mount system structure,
+ * in combination with the node-specific server keys, allow clients
+ * to efficiently use a single ref_counter server call at the end of
+ * the path resolution process.
+ *
+ * in the larger-scale midipix project, the above call fails only when
+ * a referenced mount point has in the meantime become invalid; in other
+ * words, the call shall succeed even if the queried mount point is
+ * no longer found at the top of the target directory stack.
+**/
+
+
+typedef intptr_t nt_vms_offset;
+typedef struct nt_vms_cache_interface * nt_vms_cache;
+
+
+typedef struct _nt_vms_flags {
+ uint16_t rel_depth;
+ uint16_t attr;
+} nt_vms_flags;
+
+typedef struct __attr_ptr_size_aligned__ _nt_vms_point {
+ intptr_t target;
+ intptr_t source;
+ nt_vms_offset parent;
+ nt_vms_offset prev;
+ nt_vms_offset next;
+ int32_t fstype;
+ nt_vms_flags flags;
+ nt_luid luid;
+ intptr_t ref_count;
+ intptr_t server_key;
+ int32_t stack_index;
+ int32_t status;
+ nt_fii fii;
+ uint32_t dev_name_hash;
+ uint16_t dev_name_strlen;
+ uint16_t dev_name_maxlen;
+ nt_vms_offset dev_name;
+ uint32_t end_component_hash;
+ uint16_t end_component_strlen;
+ uint16_t end_component_maxlen;
+ nt_vms_offset end_component;
+ uint32_t src_fstype_hash;
+ uint32_t src_attr;
+ uint32_t src_control_flags;
+ wchar16_t src_drive_letter;
+ wchar16_t src_padding;
+ nt_guid src_volume_guid;
+ nt_fii src_fii;
+ uint32_t src_dev_name_hash;
+ uint32_t reserved;
+} nt_vms_point;
+
+
+typedef struct _nt_vms_node {
+ nt_vms_offset prev;
+ nt_vms_offset next;
+ uint32_t end_component_hash;
+ uint32_t dev_name_hash;
+ nt_large_integer index_number;
+ nt_vms_offset stack;
+} nt_vms_node;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_vms_system {
+ intptr_t client_key;
+ intptr_t server_key;
+ void * hroot;
+ intptr_t vms_points_cap;
+ nt_vms_offset dev_name_head_node; /* dev_name_hash, fii.index_number */
+ nt_vms_offset end_component_head_node; /* end_component_hash, dev_name_hash, fii.index_number */
+} nt_vms_system;
+
+
+typedef enum _nt_vms_opcodes {
+ NT_VMS_CLIENT_OPCODE_BASE = 0x80000,
+ /* virtual mount system daemon opcodes */
+ NT_VMS_CLIENT_CONNECT = NT_VMS_CLIENT_OPCODE_BASE,
+ NT_VMS_CLIENT_DISCONNECT,
+ NT_VMS_CLIENT_UNSHARE,
+ NT_VMS_CLIENT_CONFIG,
+ NT_VMS_POINT_ATTACH,
+ NT_VMS_POINT_DETACH,
+ NT_VMS_POINT_GET_HANDLES,
+ NT_VMS_POINT_GET_VOLINFO,
+ NT_VMS_REF_COUNT_INC,
+ NT_VMS_REF_COUNT_DEC,
+ NT_VMS_TABLE_QUERY,
+ NT_VMS_TABLE_CLONE,
+ /* client opcodes: exclusive upper limit */
+ NT_VMS_CLIENT_OPCODE_CAP
+} nt_vms_opcodes;
+
+typedef struct __attr_ptr_size_aligned__ _nt_vms_msg_info {
+ uintptr_t msg_id;
+ uint32_t opcode;
+ int32_t status;
+ uintptr_t msg_key;
+} nt_vms_msg_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_vms_daemon_info {
+ nt_guid daemon_guid;
+ uint32_t srv_pid;
+ uint32_t srv_tid;
+ uint32_t session;
+ uint32_t instance;
+ uint32_t ver_maj;
+ uint32_t ver_min;
+ uint32_t section_size;
+ uint32_t advisory_size;
+ uint32_t points_mounted;
+ uint32_t points_available;
+ void * section_handle;
+} nt_vms_daemon_info;
+
+
+/* attach/detach */
+typedef struct __attr_ptr_size_aligned__ _nt_vms_point_info {
+ nt_vms_point point;
+ nt_fii src_fii;
+ uint32_t src_dev_name_hash;
+ uint32_t src_flags;
+} nt_vms_point_info;
+
+
+/* inc/dec */
+typedef struct __attr_ptr_size_aligned__ _nt_vms_ref_count_info {
+ nt_vms_offset ref_point;
+ nt_luid luid;
+ intptr_t server_key;
+ intptr_t ref_count;
+ nt_fii fii;
+ uint32_t dev_name_hash;
+ int32_t stack_index;
+ void * hsource;
+ void * htarget;
+} nt_vms_ref_count_info;
+
+
+/* query/clone */
+typedef struct __attr_ptr_size_aligned__ _nt_vms_table_info {
+ intptr_t client_key;
+ intptr_t client_section_addr;
+ intptr_t client_section_size;
+ intptr_t reserved;
+} nt_vms_table_info;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_vms_daemon_msg {
+ nt_port_message header;
+ struct {
+ nt_vms_msg_info msginfo;
+
+ union {
+ nt_vms_daemon_info vmsinfo;
+ nt_vms_point_info pointinfo;
+ nt_vms_ref_count_info refcntinfo;
+ };
+ } data;
+} nt_vms_daemon_msg;
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_vms_port_msg {
+ nt_port_message header;
+ nt_vms_msg_info msginfo;
+
+ union {
+ nt_vms_daemon_info vmsinfo;
+ nt_vms_point_info pointinfo;
+ nt_vms_ref_count_info refcntinfo;
+ };
+} nt_vms_port_msg;
+
+
+/* vms helper functions */
+typedef nt_vms_node * __stdcall ntapi_vms_get_end_component_first_node(
+ __in nt_vms_system * pvms_sys,
+ __in uint32_t end_component_hash);
+
+
+typedef nt_vms_node * __stdcall ntapi_vms_get_node_by_dev_name(
+ __in nt_vms_system * pvms_sys,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number);
+
+
+typedef nt_vms_node * __stdcall ntapi_vms_get_node_by_end_component(
+ __in nt_vms_system * pvms_sys,
+ __in uint32_t end_component_hash,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number);
+
+
+typedef nt_vms_point * __stdcall ntapi_vms_get_top_of_stack_mount_point(
+ __in nt_vms_system * pvms_sys,
+ __in nt_vms_node * node);
+
+
+/* vms optional cache functions */
+typedef nt_vms_cache __stdcall ntapi_vms_cache_alloc(
+ __in nt_vms_system * vms_sys,
+ __in uint32_t flags __reserved,
+ __in void * options __reserved,
+ __out int32_t * status __optional);
+
+
+typedef int32_t __stdcall ntapi_vms_cache_free(
+ __in nt_vms_cache cache);
+
+
+typedef int32_t __stdcall ntapi_vms_cache_record_append(
+ __in nt_vms_cache cache,
+ __in void * hfile,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number,
+ __in intptr_t client_key,
+ __in intptr_t server_key);
+
+
+typedef int32_t __stdcall ntapi_vms_cache_record_remove(
+ __in nt_vms_cache cache,
+ __in void * hfile);
+
+
+/* vms server calls */
+typedef int32_t __stdcall ntapi_vms_client_connect(
+ __out void ** hvms,
+ __in nt_tty_vms_info * vmsinfo);
+
+
+typedef int32_t __stdcall ntapi_vms_client_disconnect(
+ __in void * hvms);
+
+
+typedef int32_t __stdcall ntapi_vms_client_unshare(
+ __in void * hvms,
+ __out nt_tty_vms_info * vmsinfo);
+
+
+typedef int32_t __stdcall ntapi_vms_client_config(
+ __in void * hvms);
+
+
+typedef int32_t __stdcall ntapi_vms_point_attach(
+ __in void * hvms,
+ __in nt_vms_point_info * point_info);
+
+
+typedef int32_t __stdcall ntapi_vms_point_detach(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info);
+
+
+typedef int32_t __stdcall ntapi_vms_point_get_handles(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info);
+
+
+typedef int32_t __stdcall ntapi_vms_point_get_volinfo(
+ __in void * hvms,
+ __in nt_vms_point_info * point_info);
+
+
+typedef int32_t __stdcall ntapi_vms_ref_count_inc(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info);
+
+
+typedef int32_t __stdcall ntapi_vms_ref_count_dec(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info);
+
+
+typedef int32_t __stdcall ntapi_vms_table_query(
+ __in void * hvms,
+ __in nt_vms_daemon_info * vms_info);
+
+
+typedef int32_t __stdcall ntapi_vms_table_clone(
+ __in void * hvms,
+ __in nt_vms_daemon_info * vms_info);
+
+
+#endif
diff --git a/include/ntapi/ntapi.h b/include/ntapi/ntapi.h
new file mode 100644
index 0000000..7978786
--- /dev/null
+++ b/include/ntapi/ntapi.h
@@ -0,0 +1,596 @@
+#ifndef _NTAPI_H_
+#define _NTAPI_H_
+
+#if defined (NTAPI_BUILD)
+#define __ntapi_api __attr_export__
+#elif defined (NTAPI_SHARED)
+#define __ntapi_api __attr_import__
+#elif defined (NTAPI_STATIC)
+#define __ntapi_api
+#else
+#define __ntapi_api
+#endif
+
+#include <psxtypes/psxtypes.h>
+#include "nt_status.h"
+#include "nt_crc32.h"
+#include "nt_object.h"
+#include "nt_sysinfo.h"
+#include "nt_memory.h"
+#include "nt_section.h"
+#include "nt_thread.h"
+#include "nt_process.h"
+#include "nt_job.h"
+#include "nt_token.h"
+#include "nt_sync.h"
+#include "nt_time.h"
+#include "nt_profiling.h"
+#include "nt_port.h"
+#include "nt_device.h"
+#include "nt_file.h"
+#include "nt_registry.h"
+#include "nt_security.h"
+#include "nt_pnp.h"
+#include "nt_exception.h"
+#include "nt_locale.h"
+#include "nt_uuid.h"
+#include "nt_atom.h"
+#include "nt_os.h"
+#include "nt_ipc.h"
+#include "nt_ldr.h"
+#include "nt_string.h"
+#include "nt_guid.h"
+#include "nt_argv.h"
+#include "nt_blitter.h"
+#include "nt_unicode.h"
+#include "nt_socket.h"
+#include "nt_mount.h"
+#include "nt_istat.h"
+#include "nt_stat.h"
+#include "nt_statfs.h"
+#include "nt_daemon.h"
+#include "nt_vfd.h"
+#include "nt_tty.h"
+#include "nt_vmount.h"
+#include "nt_hash.h"
+#include "nt_debug.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct _ntapi_vtbl {
+ /* imported symbols: head */
+ /* nt_object.h */
+ ntapi_zw_query_object * zw_query_object;
+ ntapi_zw_set_information_object * zw_set_information_object;
+ ntapi_zw_duplicate_object * zw_duplicate_object;
+ ntapi_zw_make_temporary_object * zw_make_temporary_object;
+ ntapi_zw_close * zw_close;
+ ntapi_zw_query_security_object * zw_query_security_object;
+ ntapi_zw_set_security_object * zw_set_security_object;
+ ntapi_zw_create_directory_object * zw_create_directory_object;
+ ntapi_zw_open_directory_object * zw_open_directory_object;
+ ntapi_zw_query_directory_object * zw_query_directory_object;
+ ntapi_zw_create_symbolic_link_object * zw_create_symbolic_link_object;
+ ntapi_zw_open_symbolic_link_object * zw_open_symbolic_link_object;
+ ntapi_zw_query_symbolic_link_object * zw_query_symbolic_link_object;
+
+ /* nt_sysinfo.h */
+ ntapi_zw_query_system_information * zw_query_system_information;
+ ntapi_zw_set_system_information * zw_set_system_information;
+ ntapi_zw_query_system_environment_value * zw_query_system_environment_value;
+ ntapi_zw_set_system_environment_value * zw_set_system_environment_value;
+ ntapi_zw_shutdown_system * zw_shutdown_system;
+ ntapi_zw_system_debug_control * zw_system_debug_control;
+
+ /* nt_memory.h */
+ ntapi_zw_allocate_virtual_memory * zw_allocate_virtual_memory;
+ ntapi_zw_free_virtual_memory * zw_free_virtual_memory;
+ ntapi_zw_query_virtual_memory * zw_query_virtual_memory;
+ ntapi_zw_protect_virtual_memory * zw_protect_virtual_memory;
+ ntapi_zw_read_virtual_memory * zw_read_virtual_memory;
+ ntapi_zw_write_virtual_memory * zw_write_virtual_memory;
+ ntapi_zw_lock_virtual_memory * zw_lock_virtual_memory;
+ ntapi_zw_unlock_virtual_memory * zw_unlock_virtual_memory;
+ ntapi_zw_flush_virtual_memory * zw_flush_virtual_memory;
+ ntapi_zw_allocate_user_physical_pages * zw_allocate_user_physical_pages;
+ ntapi_zw_free_user_physical_pages * zw_free_user_physical_pages;
+ ntapi_zw_map_user_physical_pages * zw_map_user_physical_pages;
+ ntapi_zw_get_write_watch * zw_get_write_watch;
+ ntapi_zw_reset_write_watch * zw_reset_write_watch;
+
+ /* nt_section.h */
+ ntapi_zw_create_section * zw_create_section;
+ ntapi_zw_open_section * zw_open_section;
+ ntapi_zw_query_section * zw_query_section;
+ ntapi_zw_extend_section * zw_extend_section;
+ ntapi_zw_map_view_of_section * zw_map_view_of_section;
+ ntapi_zw_unmap_view_of_section * zw_unmap_view_of_section;
+ ntapi_zw_are_mapped_files_the_same * zw_are_mapped_files_the_same;
+
+ /* nt_thread.h */
+ ntapi_zw_create_thread * zw_create_thread;
+ ntapi_zw_open_thread * zw_open_thread;
+ ntapi_zw_terminate_thread * zw_terminate_thread;
+ ntapi_zw_query_information_thread * zw_query_information_thread;
+ ntapi_zw_set_information_thread * zw_set_information_thread;
+ ntapi_zw_suspend_thread * zw_suspend_thread;
+ ntapi_zw_resume_thread * zw_resume_thread;
+ ntapi_zw_get_context_thread * zw_get_context_thread;
+ ntapi_zw_set_context_thread * zw_set_context_thread;
+ ntapi_zw_queue_apc_thread * zw_queue_apc_thread;
+ ntapi_zw_test_alert * zw_test_alert;
+ ntapi_zw_alert_thread * zw_alert_thread;
+ ntapi_zw_alert_resume_thread * zw_alert_resume_thread;
+ ntapi_zw_register_thread_terminate_port * zw_register_thread_terminate_port;
+ ntapi_zw_impersonate_thread * zw_impersonate_thread;
+ ntapi_zw_impersonate_anonymous_token * zw_impersonate_anonymous_token;
+
+ /* nt_process.h */
+ ntapi_zw_create_process * zw_create_process;
+ ntapi_zw_create_user_process * zw_create_user_process;
+ ntapi_zw_open_process * zw_open_process;
+ ntapi_zw_terminate_process * zw_terminate_process;
+ ntapi_zw_query_information_process * zw_query_information_process;
+ ntapi_zw_set_information_process * zw_set_information_process;
+ ntapi_zw_flush_instruction_cache * zw_flush_instruction_cache;
+ ntapi_rtl_create_process_parameters * rtl_create_process_parameters;
+ ntapi_rtl_destroy_process_parameters * rtl_destroy_process_parameters;
+ ntapi_rtl_normalize_process_params * rtl_normalize_process_params;
+ ntapi_rtl_create_query_debug_buffer * rtl_create_query_debug_buffer;
+ ntapi_rtl_destroy_query_debug_buffer * rtl_destroy_query_debug_buffer;
+ ntapi_rtl_query_process_debug_information * rtl_query_process_debug_information;
+
+ /* nt_job.h */
+ ntapi_zw_create_job_object * zw_create_job_object;
+ ntapi_zw_open_job_object * zw_open_job_object;
+ ntapi_zw_terminate_job_object * zw_terminate_job_object;
+ ntapi_zw_assign_process_to_job_object * zw_assign_process_to_job_object;
+ ntapi_zw_query_information_job_object * zw_query_information_job_object;
+ ntapi_zw_set_information_job_object * zw_set_information_job_object;
+
+ /* nt_token.h */
+ ntapi_zw_create_token * zw_create_token;
+ ntapi_zw_open_process_token * zw_open_process_token;
+ ntapi_zw_open_thread_token * zw_open_thread_token;
+ ntapi_zw_duplicate_token * zw_duplicate_token;
+ ntapi_zw_filter_token * zw_filter_token;
+ ntapi_zw_adjust_privileges_token * zw_adjust_privileges_token;
+ ntapi_zw_adjust_groups_token * zw_adjust_groups_token;
+ ntapi_zw_query_information_token * zw_query_information_token;
+ ntapi_zw_set_information_token * zw_set_information_token;
+
+ /* nt_sync.h */
+ ntapi_zw_wait_for_single_object * zw_wait_for_single_object;
+ ntapi_zw_signal_and_wait_for_single_object * zw_signal_and_wait_for_single_object;
+ ntapi_zw_wait_for_multiple_objects * zw_wait_for_multiple_objects;
+ ntapi_zw_create_timer * zw_create_timer;
+ ntapi_zw_open_timer * zw_open_timer;
+ ntapi_zw_cancel_timer * zw_cancel_timer;
+ ntapi_zw_set_timer * zw_set_timer;
+ ntapi_zw_query_timer * zw_query_timer;
+ ntapi_zw_create_event * zw_create_event;
+ ntapi_zw_open_event * zw_open_event;
+ ntapi_zw_set_event * zw_set_event;
+ ntapi_zw_pulse_event * zw_pulse_event;
+ ntapi_zw_reset_event * zw_reset_event;
+ ntapi_zw_clear_event * zw_clear_event;
+ ntapi_zw_query_event * zw_query_event;
+ ntapi_zw_create_semaphore * zw_create_semaphore;
+ ntapi_zw_open_semaphore * zw_open_semaphore;
+ ntapi_zw_release_semaphore * zw_release_semaphore;
+ ntapi_zw_query_semaphore * zw_query_semaphore;
+ ntapi_zw_create_mutant * zw_create_mutant;
+ ntapi_zw_open_mutant * zw_open_mutant;
+ ntapi_zw_release_mutant * zw_release_mutant;
+ ntapi_zw_query_mutant * zw_query_mutant;
+ ntapi_zw_create_io_completion * zw_create_io_completion;
+ ntapi_zw_open_io_completion * zw_open_io_completion;
+ ntapi_zw_set_io_completion * zw_set_io_completion;
+ ntapi_zw_remove_io_completion * zw_remove_io_completion;
+ ntapi_zw_query_io_completion * zw_query_io_completion;
+ ntapi_zw_create_event_pair * zw_create_event_pair;
+ ntapi_zw_open_event_pair * zw_open_event_pair;
+ ntapi_zw_wait_low_event_pair * zw_wait_low_event_pair;
+ ntapi_zw_set_low_event_pair * zw_set_low_event_pair;
+ ntapi_zw_wait_high_event_pair * zw_wait_high_event_pair;
+ ntapi_zw_set_high_event_pair * zw_set_high_event_pair;
+ ntapi_zw_set_low_wait_high_event_pair * zw_set_low_wait_high_event_pair;
+ ntapi_zw_set_high_wait_low_event_pair * zw_set_high_wait_low_event_pair;
+
+ /* nt_time.h */
+ ntapi_zw_query_system_time * zw_query_system_time;
+ ntapi_zw_set_system_time * zw_set_system_time;
+ ntapi_zw_query_performance_counter * zw_query_performance_counter;
+ ntapi_zw_set_timer_resolution * zw_set_timer_resolution;
+ ntapi_zw_query_timer_resolution * zw_query_timer_resolution;
+ ntapi_zw_delay_execution * zw_delay_execution;
+ ntapi_zw_yield_execution * zw_yield_execution;
+
+ /* nt_profiling.h */
+ ntapi_zw_create_profile * zw_create_profile;
+ ntapi_zw_set_interval_profile * zw_set_interval_profile;
+ ntapi_zw_query_interval_profile * zw_query_interval_profile;
+ ntapi_zw_start_profile * zw_start_profile;
+ ntapi_zw_stop_profile * zw_stop_profile;
+
+ /* nt_port.h */
+ ntapi_zw_create_port * zw_create_port;
+ ntapi_zw_create_waitable_port * zw_create_waitable_port;
+ ntapi_zw_connect_port * zw_connect_port;
+ ntapi_zw_secure_connect_port * zw_secure_connect_port;
+ ntapi_zw_listen_port * zw_listen_port;
+ ntapi_zw_accept_connect_port * zw_accept_connect_port;
+ ntapi_zw_complete_connect_port * zw_complete_connect_port;
+ ntapi_zw_request_port * zw_request_port;
+ ntapi_zw_request_wait_reply_port * zw_request_wait_reply_port;
+ ntapi_zw_reply_port * zw_reply_port;
+ ntapi_zw_reply_wait_reply_port * zw_reply_wait_reply_port;
+ ntapi_zw_reply_wait_receive_port * zw_reply_wait_receive_port;
+ ntapi_zw_reply_wait_receive_port_ex * zw_reply_wait_receive_port_ex;
+ ntapi_zw_read_request_data * zw_read_request_data;
+ ntapi_zw_write_request_data * zw_write_request_data;
+ ntapi_zw_query_information_port * zw_query_information_port;
+ ntapi_zw_impersonate_client_of_port * zw_impersonate_client_of_port;
+ ntapi_csr_client_call_server * csr_client_call_server;
+ ntapi_csr_port_handle * csr_port_handle;
+
+ /* nt_device.h */
+ ntapi_zw_load_driver * zw_load_driver;
+ ntapi_zw_unload_driver * zw_unload_driver;
+
+ /* nt_file.h */
+ ntapi_zw_create_file * zw_create_file;
+ ntapi_zw_open_file * zw_open_file;
+ ntapi_zw_delete_file * zw_delete_file;
+ ntapi_zw_flush_buffers_file * zw_flush_buffers_file;
+ ntapi_zw_cancel_io_file * zw_cancel_io_file;
+ ntapi_zw_cancel_io_file_ex * zw_cancel_io_file_ex;
+ ntapi_zw_read_file * zw_read_file;
+ ntapi_zw_write_file * zw_write_file;
+ ntapi_zw_read_file_scatter * zw_read_file_scatter;
+ ntapi_zw_write_file_gather * zw_write_file_gather;
+ ntapi_zw_lock_file * zw_lock_file;
+ ntapi_zw_unlock_file * zw_unlock_file;
+ ntapi_zw_device_io_control_file * zw_device_io_control_file;
+ ntapi_zw_fs_control_file * zw_fs_control_file;
+ ntapi_zw_notify_change_directory_file * zw_notify_change_directory_file;
+ ntapi_zw_query_ea_file * zw_query_ea_file;
+ ntapi_zw_set_ea_file * zw_set_ea_file;
+ ntapi_zw_create_named_pipe_file * zw_create_named_pipe_file;
+ ntapi_zw_create_mailslot_file * zw_create_mailslot_file;
+ ntapi_zw_query_volume_information_file * zw_query_volume_information_file;
+ ntapi_zw_set_volume_information_file * zw_set_volume_information_file;
+ ntapi_zw_query_quota_information_file * zw_query_quota_information_file;
+ ntapi_zw_set_quota_information_file * zw_set_quota_information_file;
+ ntapi_zw_query_attributes_file * zw_query_attributes_file;
+ ntapi_zw_query_full_attributes_file * zw_query_full_attributes_file;
+ ntapi_zw_query_directory_file * zw_query_directory_file;
+ ntapi_zw_query_information_file * zw_query_information_file;
+ ntapi_zw_set_information_file * zw_set_information_file;
+
+ /* nt_resistry.h */
+ ntapi_zw_create_key * zw_create_key;
+ ntapi_zw_open_key * zw_open_key;
+ ntapi_zw_delete_key * zw_delete_key;
+ ntapi_zw_flush_key * zw_flush_key;
+ ntapi_zw_save_key * zw_save_key;
+ ntapi_zw_save_merged_keys * zw_save_merged_keys;
+ ntapi_zw_restore_key * zw_restore_key;
+ ntapi_zw_load_key * zw_load_key;
+ ntapi_zw_load_key2 * zw_load_key2;
+ ntapi_zw_unload_key * zw_unload_key;
+ ntapi_zw_query_open_sub_keys * zw_query_open_sub_keys;
+ ntapi_zw_replace_key * zw_replace_key;
+ ntapi_zw_set_information_key * zw_set_information_key;
+ ntapi_zw_query_key * zw_query_key;
+ ntapi_zw_enumerate_key * zw_enumerate_key;
+ ntapi_zw_notify_change_key * zw_notify_change_key;
+ ntapi_zw_notify_change_multiple_keys * zw_notify_change_multiple_keys;
+ ntapi_zw_delete_value_key * zw_delete_value_key;
+ ntapi_zw_set_value_key * zw_set_value_key;
+ ntapi_zw_query_value_key * zw_query_value_key;
+ ntapi_zw_enumerate_value_key * zw_enumerate_value_key;
+ ntapi_zw_query_multiple_value_key * zw_query_multiple_value_key;
+ ntapi_zw_initialize_registry * zw_initialize_registry;
+
+ /* nt_security.h */
+ ntapi_zw_privilege_check * zw_privilege_check;
+ ntapi_zw_privilege_object_audit_alarm * zw_privilege_object_audit_alarm;
+ ntapi_zw_privileged_service_audit_alarm * zw_privileged_service_audit_alarm;
+ ntapi_zw_access_check * zw_access_check;
+ ntapi_zw_access_check_and_audit_alarm * zw_access_check_and_audit_alarm;
+ ntapi_zw_access_check_by_type * zw_access_check_by_type;
+ ntapi_zw_access_check_by_type_result_list * zw_access_check_by_type_result_list;
+ ntapi_zw_open_object_audit_alarm * zw_open_object_audit_alarm;
+ ntapi_zw_close_object_audit_alarm * zw_close_object_audit_alarm;
+ ntapi_zw_delete_object_audit_alarm * zw_delete_object_audit_alarm;
+
+ ntapi_zw_access_check_by_type_and_audit_alarm * zw_access_check_by_type_and_audit_alarm;
+
+ ntapi_zw_access_check_by_type_result_list_and_audit_alarm * zw_access_check_by_type_result_list_and_audit_alarm;
+ ntapi_zw_access_check_by_type_result_list_and_audit_alarm_by_handle * zw_access_check_by_type_result_list_and_audit_alarm_by_handle;
+
+ /* nt_pnp.h */
+ ntapi_zw_is_system_resume_automatic * zw_is_system_resume_automatic;
+ ntapi_zw_set_thread_execution_state * zw_set_thread_execution_state;
+ ntapi_zw_get_device_power_state * zw_get_device_power_state;
+ ntapi_zw_set_system_power_state * zw_set_system_power_state;
+ ntapi_zw_initiate_power_action * zw_initiate_power_action;
+ ntapi_zw_power_information * zw_power_information;
+ ntapi_zw_plug_play_control * zw_plug_play_control;
+ ntapi_zw_get_plug_play_event * zw_get_plug_play_event;
+
+ /* nt_exception */
+ ntapi_zw_raise_exception * zw_raise_exception;
+ ntapi_zw_continue * zw_continue;
+
+ /* nt_locale */
+ ntapi_zw_query_default_locale * zw_query_default_locale;
+ ntapi_zw_set_default_locale * zw_set_default_locale;
+ ntapi_zw_query_default_ui_language * zw_query_default_ui_language;
+ ntapi_zw_set_default_ui_language * zw_set_default_ui_language;
+ ntapi_zw_query_install_ui_language * zw_query_install_ui_language;
+
+ /* nt_uuid.h */
+ ntapi_zw_allocate_locally_unique_id * zw_allocate_locally_unique_id;
+ ntapi_zw_allocate_uuids * zw_allocate_uuids;
+ ntapi_zw_set_uuid_seed * zw_set_uuid_seed;
+
+ /* nt_atom.h */
+ ntapi_zw_add_atom * zw_add_atom;
+ ntapi_zw_find_atom * zw_find_atom;
+ ntapi_zw_delete_atom * zw_delete_atom;
+ ntapi_zw_query_information_atom * zw_query_information_atom;
+
+ /* nt_os.h */
+ ntapi_zw_flush_write_buffer * zw_flush_write_buffer;
+ ntapi_zw_raise_hard_error * zw_raise_hard_error;
+ ntapi_zw_set_default_hard_error_port * zw_set_default_hard_error_port;
+ ntapi_zw_display_string * zw_display_string;
+ ntapi_zw_create_paging_file * zw_create_paging_file;
+ ntapi_zw_set_ldt_entries * zw_set_ldt_entries;
+ ntapi_zw_vdm_control * zw_vdm_control;
+
+ /* nt_ldr.h */
+ ntapi_ldr_load_dll * ldr_load_dll;
+ ntapi_ldr_unload_dll * ldr_unload_dll;
+
+ /* nt_string.h */
+ ntapi_memset * memset;
+ ntapi_sprintf * sprintf;
+ ntapi_strlen * strlen;
+ /* imported symbols: tail */
+
+ /* alternate implementation */
+ /* nt_string.h */
+ ntapi_wcslen * wcslen;
+ ntapi_rtl_init_unicode_string * rtl_init_unicode_string;
+
+ /* extension functions */
+ /* nt_object.h */
+ ntapi_tt_create_keyed_object_directory * tt_create_keyed_object_directory;
+ ntapi_tt_open_keyed_object_directory * tt_open_keyed_object_directory;
+ ntapi_tt_create_keyed_object_directory_entry * tt_create_keyed_object_directory_entry;
+
+ /* nt_crc32.h */
+ ntapi_tt_buffer_crc32 * tt_buffer_crc32;
+ ntapi_tt_mbstr_crc32 * tt_mbstr_crc32;
+ ntapi_tt_crc32_table * tt_crc32_table;
+
+ /* nt_file.h */
+ ntapi_tt_get_file_handle_type * tt_get_file_handle_type;
+ ntapi_tt_open_logical_parent_directory * tt_open_logical_parent_directory;
+ ntapi_tt_open_physical_parent_directory * tt_open_physical_parent_directory;
+
+ /* nt_ipc.h */
+ ntapi_ipc_create_pipe * ipc_create_pipe;
+
+ /* nt_ldr.h */
+ ntapi_ldr_load_system_dll * ldr_load_system_dll;
+ ntapi_ldr_create_state_snapshot * ldr_create_state_snapshot;
+ ntapi_ldr_revert_state_to_snapshot * ldr_revert_state_to_snapshot;
+
+ /* nt_string.h */
+ ntapi_tt_string_null_offset_multibyte * tt_string_null_offset_multibyte;
+ ntapi_tt_string_null_offset_short * tt_string_null_offset_short;
+ ntapi_tt_string_null_offset_dword * tt_string_null_offset_dword;
+ ntapi_tt_string_null_offset_qword * tt_string_null_offset_qword;
+ ntapi_tt_string_null_offset_ptrsize * tt_string_null_offset_ptrsize;
+ ntapi_tt_aligned_block_memset * tt_aligned_block_memset;
+ ntapi_tt_aligned_block_memcpy * tt_aligned_block_memcpy;
+ ntapi_tt_aligned_memcpy_utf16 * tt_aligned_memcpy_utf16;
+ ntapi_tt_memcpy_utf16 * tt_memcpy_utf16;
+ ntapi_tt_generic_memset * tt_generic_memset;
+ ntapi_tt_generic_memcpy * tt_generic_memcpy;
+ ntapi_tt_uint16_to_hex_utf16 * tt_uint16_to_hex_utf16;
+ ntapi_tt_uint32_to_hex_utf16 * tt_uint32_to_hex_utf16;
+ ntapi_tt_uint64_to_hex_utf16 * tt_uint64_to_hex_utf16;
+ ntapi_tt_uintptr_to_hex_utf16 * tt_uintptr_to_hex_utf16;
+ ntapi_tt_hex_utf16_to_uint16 * tt_hex_utf16_to_uint16;
+ ntapi_tt_hex_utf16_to_uint32 * tt_hex_utf16_to_uint32;
+ ntapi_tt_hex_utf16_to_uint64 * tt_hex_utf16_to_uint64;
+ ntapi_tt_hex_utf16_to_uintptr * tt_hex_utf16_to_uintptr;
+ ntapi_tt_uint16_to_hex_utf8 * tt_uint16_to_hex_utf8;
+ ntapi_tt_uint32_to_hex_utf8 * tt_uint32_to_hex_utf8;
+ ntapi_tt_uint64_to_hex_utf8 * tt_uint64_to_hex_utf8;
+ ntapi_tt_uintptr_to_hex_utf8 * tt_uintptr_to_hex_utf8;
+ ntapi_tt_init_unicode_string_from_utf16* tt_init_unicode_string_from_utf16;
+
+ /* nt_guid.h */
+ ntapi_tt_guid_copy * tt_guid_copy;
+ ntapi_tt_guid_compare * tt_guid_compare;
+ ntapi_tt_guid_to_utf16_string * tt_guid_to_utf16_string;
+ ntapi_tt_utf16_string_to_guid * tt_utf16_string_to_guid;
+
+ /* nt_sysinfo.h */
+ ntapi_tt_get_system_directory_native_path * tt_get_system_directory_native_path;
+ ntapi_tt_get_system_directory_dos_path * tt_get_system_directory_dos_path;
+ ntapi_tt_get_system_directory_handle * tt_get_system_directory_handle;
+ ntapi_tt_get_system_info_snapshot * tt_get_system_info_snapshot;
+
+ /* nt_thread.h */
+ ntapi_tt_create_thread * tt_create_thread;
+ ntapi_tt_create_local_thread * tt_create_local_thread;
+ ntapi_tt_create_remote_thread * tt_create_remote_thread;
+
+ /* nt_process.h */
+ ntapi_tt_fork * tt_fork;
+ ntapi_tt_create_remote_process_params * tt_create_remote_process_params;
+ ntapi_tt_create_native_process * tt_create_native_process;
+ ntapi_tt_get_runtime_data * tt_get_runtime_data;
+ ntapi_tt_init_runtime_data * tt_init_runtime_data;
+ ntapi_tt_update_runtime_data * tt_update_runtime_data;
+ ntapi_tt_exec_map_image_as_data * tt_exec_map_image_as_data;
+ ntapi_tt_exec_unmap_image * tt_exec_unmap_image;
+
+ /* nt_section.h */
+ ntapi_tt_get_section_name * tt_get_section_name;
+
+ /* nt_sync.h */
+ ntapi_tt_create_inheritable_event * tt_create_inheritable_event;
+ ntapi_tt_create_private_event * tt_create_private_event;
+ ntapi_tt_sync_block_init * tt_sync_block_init;
+ ntapi_tt_sync_block_lock * tt_sync_block_lock;
+ ntapi_tt_sync_block_server_lock * tt_sync_block_server_lock;
+ ntapi_tt_sync_block_unlock * tt_sync_block_unlock;
+ ntapi_tt_sync_block_invalidate * tt_sync_block_invalidate;
+ ntapi_tt_wait_for_dummy_event * tt_wait_for_dummy_event;
+
+ /* nt_port.h */
+ ntapi_tt_port_guid_from_type * tt_port_guid_from_type;
+ ntapi_tt_port_type_from_guid * tt_port_type_from_guid;
+ ntapi_tt_port_generate_keys * tt_port_generate_keys;
+ ntapi_tt_port_format_keys * tt_port_format_keys;
+ ntapi_tt_port_name_from_attributes * tt_port_name_from_attributes;
+
+ /* nt_argv.h */
+ ntapi_tt_get_cmd_line_utf16 * tt_get_cmd_line_utf16;
+ ntapi_tt_get_peb_env_block_utf16 * tt_get_peb_env_block_utf16;
+ ntapi_tt_parse_cmd_line_args_utf16 * tt_parse_cmd_line_args_utf16;
+ ntapi_tt_get_argv_envp_utf8 * tt_get_argv_envp_utf8;
+ ntapi_tt_get_argv_envp_utf16 * tt_get_argv_envp_utf16;
+ ntapi_tt_get_env_var_meta_utf16 * tt_get_env_var_meta_utf16;
+ ntapi_tt_get_short_option_meta_utf16 * tt_get_short_option_meta_utf16;
+ ntapi_tt_get_long_option_meta_utf16 * tt_get_long_option_meta_utf16;
+ ntapi_tt_array_copy_utf8 * tt_array_copy_utf8;
+ ntapi_tt_array_copy_utf16 * tt_array_copy_utf16;
+ ntapi_tt_array_convert_utf8_to_utf16 * tt_array_convert_utf8_to_utf16;
+ ntapi_tt_array_convert_utf16_to_utf8 * tt_array_convert_utf16_to_utf8;
+
+ /* nt_blitter.h */
+ ntapi_blt_alloc * blt_alloc;
+ ntapi_blt_free * blt_free;
+ ntapi_blt_acquire * blt_acquire;
+ ntapi_blt_obtain * blt_obtain;
+ ntapi_blt_possess * blt_possess;
+ ntapi_blt_release * blt_release;
+ ntapi_blt_get * blt_get;
+ ntapi_blt_set * blt_set;
+
+ /* nt_unicode.h */
+ ntapi_uc_validate_unicode_stream_utf8 * uc_validate_unicode_stream_utf8;
+ ntapi_uc_validate_unicode_stream_utf16 * uc_validate_unicode_stream_utf16;
+ ntapi_uc_get_code_point_byte_count_utf8 * uc_get_code_point_byte_count_utf8;
+ ntapi_uc_get_code_point_byte_count_utf16 * uc_get_code_point_byte_count_utf16;
+ ntapi_uc_convert_unicode_stream_utf8_to_utf16 * uc_convert_unicode_stream_utf8_to_utf16;
+ ntapi_uc_convert_unicode_stream_utf8_to_utf32 * uc_convert_unicode_stream_utf8_to_utf32;
+ ntapi_uc_convert_unicode_stream_utf16_to_utf8 * uc_convert_unicode_stream_utf16_to_utf8;
+ ntapi_uc_convert_unicode_stream_utf16_to_utf32 *uc_convert_unicode_stream_utf16_to_utf32;
+
+ /* nt_daemon.h */
+ ntapi_dsr_init * dsr_init;
+ ntapi_dsr_start * dsr_start;
+ ntapi_dsr_create_port * dsr_create_port;
+ ntapi_dsr_connect_internal_client * dsr_connect_internal_client;
+ ntapi_dsr_internal_client_connect * dsr_internal_client_connect;
+
+ /* nt_vfd.h */
+ ntapi_vfd_dev_name_init * vfd_dev_name_init;
+
+ /* nt_tty.h */
+ ntapi_tty_create_session * tty_create_session;
+ ntapi_tty_join_session * tty_join_session;
+ ntapi_tty_connect * tty_connect;
+ ntapi_tty_client_session_query * tty_client_session_query;
+ ntapi_tty_client_session_set * tty_client_session_set;
+ ntapi_tty_client_process_register * tty_client_process_register;
+ ntapi_tty_query_information_server * tty_query_information_server;
+ ntapi_tty_request_peer * tty_request_peer;
+ ntapi_tty_vms_query * tty_vms_query;
+ ntapi_tty_vms_request * tty_vms_request;
+ ntapi_pty_open * pty_open;
+ ntapi_pty_reopen * pty_reopen;
+ ntapi_pty_close * pty_close;
+ ntapi_pty_read * pty_read;
+ ntapi_pty_write * pty_write;
+ ntapi_pty_fcntl * pty_fcntl;
+ ntapi_pty_ioctl * pty_ioctl;
+ ntapi_pty_query * pty_query;
+ ntapi_pty_set * pty_set;
+ ntapi_pty_cancel * pty_cancel;
+
+ /* nt_socket.h */
+ ntapi_sc_socket * sc_socket;
+ ntapi_sc_bind * sc_bind;
+ ntapi_sc_listen * sc_listen;
+ ntapi_sc_accept * sc_accept;
+ ntapi_sc_connect * sc_connect;
+ ntapi_sc_send * sc_send;
+ ntapi_sc_recv * sc_recv;
+ ntapi_sc_shutdown * sc_shutdown;
+ ntapi_sc_getsockname * sc_getsockname;
+ ntapi_sc_server_accept_connection * sc_server_accept_connection;
+ ntapi_sc_server_duplicate_socket * sc_server_duplicate_socket;
+ ntapi_sc_wait * sc_wait;
+
+ /* nt_mount.h */
+ ntapi_tt_get_dos_drive_device_handle * tt_get_dos_drive_device_handle;
+ ntapi_tt_get_dos_drive_root_handle * tt_get_dos_drive_root_handle;
+ ntapi_tt_get_dos_drive_device_name * tt_get_dos_drive_device_name;
+ ntapi_tt_get_dos_drive_mount_points * tt_get_dos_drive_mount_points;
+ ntapi_tt_dev_mount_points_to_statfs * tt_dev_mount_points_to_statfs;
+ ntapi_tt_get_dos_drive_letter_from_device * tt_get_dos_drive_letter_from_device;
+
+ /* nt_istat.h */
+ ntapi_tt_istat * tt_istat;
+ ntapi_tt_validate_fs_handle * tt_validate_fs_handle;
+
+ /* nt_stat.h */
+ ntapi_tt_stat * tt_stat;
+
+ /* nt_statfs.h */
+ ntapi_tt_statfs * tt_statfs;
+
+ /* nt_vmount.h */
+ ntapi_vms_get_node_by_dev_name * vms_get_node_by_dev_name;
+ ntapi_vms_get_node_by_end_component * vms_get_node_by_end_component;
+ ntapi_vms_cache_alloc * vms_cache_alloc;
+ ntapi_vms_cache_free * vms_cache_free;
+ ntapi_vms_client_connect * vms_client_connect;
+ ntapi_vms_client_disconnect * vms_client_disconnect;
+ ntapi_vms_point_attach * vms_point_attach;
+ ntapi_vms_point_get_handles * vms_point_get_handles;
+ ntapi_vms_ref_count_inc * vms_ref_count_inc;
+ ntapi_vms_ref_count_dec * vms_ref_count_dec;
+ ntapi_vms_table_query * vms_table_query;
+
+ /* nt_debug.h */
+ ntapi_dbg_write * dbg_write;
+ ntapi_dbg_fn_call * dbg_fn_call;
+ ntapi_dbg_msg * dbg_msg;
+} ntapi_vtbl;
+
+
+__ntapi_api
+int32_t __fastcall ntapi_init(ntapi_vtbl ** pvtbl);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ntapi.lzy b/ntapi.lzy
new file mode 100644
index 0000000..8ce26c8
--- /dev/null
+++ b/ntapi.lzy
@@ -0,0 +1,113 @@
+lz_project_rules()
+{
+ lz_rules="all install"
+}
+
+lz_project_definitions()
+{
+ ntapi_lib_name=libntapi
+ ntapi_so_name="$lz_build_dir/lib/$ntapi_lib_name$lz_dylib_ext"
+ ntapi_a_name="$lz_build_dir/lib/$ntapi_lib_name$lz_stlib_ext"
+ ntapi_so_def_name="$lz_build_dir/lib/$ntapi_lib_name$lz_libdef_ext"
+ ntapi_implib_name="$lz_build_dir/lib/$ntapi_lib_name$lz_implib_ext"
+
+ lz_cflags_common="-DMIDIPIX_FREESTANDING
+ -D__NT$lz_arch_bits \
+ -UWIN32 -U_WIN32 -U__WIN32 -U__WIN32__ \
+ -UWIN64 -U_WIN64 -U__WIN64 -U__WIN64__ \
+ -Werror=all -fno-builtin -ffreestanding"
+
+
+ # lz_cflags_extra="-Os -fno-stack-protector -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables"
+
+ ntapi_so_ldflags="-shared --image-base=0x800000 \
+ --entry "$lz_default_underscore"__ntapi_entry@12 \
+ --exclude-all-symbols \
+ --output-def $ntapi_so_def_name \
+ --out-implib $ntapi_implib_name \
+ --subsystem=windows"
+
+ lz_cflags_include_first="-I$lz_project_dir/src/internal -I$lz_project_dir/include"
+
+ if [ "$MIDIPIX_ROOT"x != x ]; then
+ lz_cflags_include_common="$lz_cflags_include_common -I$MIDIPIX_ROOT/include"
+ fi
+
+ ntapi_so_obj_list=ntapi.so.objs
+ ntapi_so_src_list=ntapi.so.src.lst
+
+ ntapi_a_obj_list=ntapi.a.objs
+ ntapi_a_src_list=ntapi.a.src.lst
+}
+
+ntapi_shared()
+{
+ lz_src_dirs="src"
+ lz_cflags_step="-DNTAPI_BUILD \
+ -DPE_SHARED \
+ -DDALIST_SHARED"
+
+ if ! [ "$lz_pecoff_winnt"x = yesx ]; then
+ lz_cflags_step="$lz_cflags_step -fpic"
+ fi
+
+ lz_compile "$ntapi_so_obj_list" "$ntapi_so_src_list" "$lz_dyobj_ext"
+ lz_link "$ntapi_so_obj_list" "$ntapi_so_src_list" "$ntapi_so_name" \
+ "$ntapi_so_ldflags" \
+ "$lz_ldflags_cmdline -lpemagine -ldalist"
+}
+
+
+ntapi_static()
+{
+ lz_src_dirs="src"
+
+ lz_compile "$ntapi_a_obj_list" "$ntapi_a_src_list" "$lz_stobj_ext"
+ lz_archive "$ntapi_a_obj_list" "$ntapi_a_src_list" "$ntapi_a_name"
+}
+
+
+ntapi_install_headers()
+{
+ lz_pushd $lz_project_dir
+
+ cp -r -t $lz_prefix/include include/$lz_project_name
+
+ lz_popd
+}
+
+
+ntapi_install_shared()
+{
+ lz_pushd $lz_build_dir/lib
+
+ cp -t $lz_prefix/lib $ntapi_lib_name$lz_dylib_ext
+ cp -t $lz_prefix/lib $ntapi_lib_name$lz_implib_ext
+
+ lz_popd
+}
+
+
+ntapi_install_static()
+{
+ lz_pushd $lz_build_dir/lib
+
+ cp -t $lz_prefix/lib $ntapi_lib_name$lz_stlib_ext
+
+ lz_popd
+}
+
+ntapi_all()
+{
+ lz_step ntapi_shared
+ lz_step ntapi_static
+}
+
+
+ntapi_install()
+{
+ lz_step ntapi_all
+ lz_step ntapi_install_shared
+ lz_step ntapi_install_static
+ lz_step ntapi_install_headers
+}
diff --git a/src/argv/ntapi_tt_argv_envp.c b/src/argv/ntapi_tt_argv_envp.c
new file mode 100644
index 0000000..bfa0cd2
--- /dev/null
+++ b/src/argv/ntapi_tt_argv_envp.c
@@ -0,0 +1,717 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+/**
+ * rules for parsing the process's command line arguments
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+ *
+ * delimiters:
+ * -----------
+ * + white space (ascii 0x20)
+ * + horizontal tab (ascii 0x09)
+ *
+ * quoted strings, and special characters
+ * --------------------------------------
+ * + delimiter characters within a quoted string ("string with white space",
+ * or string" with white "space), stand for their literal respective
+ * characters.
+ *
+ * + a backslash followed by a double quote (\") stands for a literal
+ * double quote.
+ *
+ * + unless followed by a double quote, a backslash is just a (literal)
+ * backslash.
+ *
+ * + when followed by a double quotation mark, an even sequence of 2 or
+ * more backslashes (2n) should be interpreted as a sequence of n literal
+ * backslashes. The double quotation mark then designates the start
+ * or end of a double quoted string.
+ *
+ * + when followed by a double quotation mark, an odd sequence of 2 or
+ * more backslashes (2n+1) should be interpreted as a sequence of n
+ * literal backslashes, followed by a single literal double quote.
+ *
+ * + if found within a double quoted string, a sequence of two double
+ * quotation marks should be interpreted as a single literal double
+ * quote.
+ *
+ * + balanced nesting of syntactic double quotes is permitted.
+ *
+**/
+
+/* free-standing process runtime data */
+static nt_runtime_data __rtdata;
+
+int32_t __stdcall __ntapi_tt_parse_cmd_line_args_utf16(
+ __in wchar16_t * cmd_line,
+ __out int * arg_count,
+ __in wchar16_t * args_buffer,
+ __in size_t args_buffer_len,
+ __out size_t * args_bytes_written __optional,
+ __in wchar16_t ** argv_buffer,
+ __in size_t argv_buffer_len,
+ __in uint32_t arg_flags)
+{
+ /**
+ * parse the command line arguments pointed to by cmd_line,
+ * copy the parsed arguments to args_buffer,
+ * and return 0 upon success.
+ *
+ * cmd_line must be a valid pointer to a command line string,
+ * and args_buffer, argv_buffer, and arg_count should
+ * all be aligned; furthermore, args_buffer_len and
+ * and argv_buffer_len must be exact multiples of sizeof(size_t).
+ *
+ * In case of an error, report failure using the appropriate
+ * native status code.
+ **/
+
+ /**
+ * UTF-16: no need to fully determine the code point of the
+ * current character; all we need to do is validate the
+ * character or surrogate pair, and set the value of
+ * wch_next accordingly.
+ **/
+
+ #define HORIZONTAL_TAB 0x09
+ #define WHITE_SPACE 0x20
+ #define DOUBLE_QUOTE 0x22
+ #define SINGLE_QUOTE 0x27
+ #define BACKSLASH 0x5C
+
+ #define IS_DELIMITER(x) ((x == HORIZONTAL_TAB) || (x == WHITE_SPACE))
+
+ #define TEST_ARGS_BUFFER(nbytes) \
+ if ((uintptr_t)arg + nbytes \
+ > (uintptr_t)args_buffer + args_buffer_len) { \
+ return NT_STATUS_BUFFER_TOO_SMALL; \
+ }
+
+ #define ADD_N_BACKSLASHES \
+ TEST_ARGS_BUFFER(backslash_count * sizeof(wchar16_t)); \
+ for (islash = 0; \
+ islash < backslash_count; \
+ islash++) { \
+ *arg = BACKSLASH; \
+ arg++; \
+ } \
+ backslash_count = 0;
+
+ #define ADD_SINGLE_WCHAR16_t(x) \
+ TEST_ARGS_BUFFER(sizeof(wchar16_t)); \
+ *arg = x; \
+ arg++;
+
+ wchar16_t * arg; /* null-terminated, copied to buffer */
+ wchar16_t ** parg; /* next pointer in the argv array */
+ wchar16_t * wch; /* character being processed */
+ wchar16_t * wch_next;
+ unsigned int backslash_count;
+ unsigned int islash;
+ unsigned char quoted_state;
+
+ /* check parameters for validity and alignment */
+ if ((!(uintptr_t)cmd_line) || (*cmd_line == 0))
+ /* we require at least one argument */
+ return NT_STATUS_INVALID_PARAMETER_1;
+
+ else if (__NT_IS_MISALIGNED_BUFFER(args_buffer))
+ return NT_STATUS_INVALID_PARAMETER_2;
+
+ else if (__NT_IS_MISALIGNED_LENGTH(args_buffer_len))
+ return NT_STATUS_INVALID_PARAMETER_3;
+
+ else if (__NT_IS_MISALIGNED_BUFFER(argv_buffer))
+ return NT_STATUS_INVALID_PARAMETER_5;
+
+ else if (__NT_IS_MISALIGNED_LENGTH(argv_buffer_len))
+ return NT_STATUS_INVALID_PARAMETER_6;
+
+ else if (__NT_IS_MISALIGNED_BUFFER(arg_count))
+ return NT_STATUS_INVALID_PARAMETER_7;
+
+ /* zero-out the aligned buffers */
+ __ntapi->tt_aligned_block_memset(args_buffer,0,args_buffer_len);
+ __ntapi->tt_aligned_block_memset(argv_buffer,0,argv_buffer_len);
+
+ /* initialize */
+ wch = cmd_line;
+ arg = args_buffer;
+ parg = argv_buffer;
+ *parg = arg;
+ *arg_count = 0;
+ quoted_state = 0;
+ backslash_count = 0;
+
+ /* arg points to the first character of a command line argument */
+ /* parg points to the next pointer in argv_buffer */
+ while (*wch) {
+ if (!(quoted_state) && (IS_DELIMITER(*wch))) {
+ /* pending backslashes? */
+ if (backslash_count)
+ ADD_N_BACKSLASHES;
+
+ /* reached a delimiter outside of a quoted string */
+ /* argument: alignment and null-termination */
+ arg = (wchar16_t *)((((uintptr_t)arg + sizeof(size_t))
+ | (sizeof(size_t) - 1))
+ ^ (sizeof(size_t) - 1));
+
+ /* skip this and remaining delimiters */
+ wch_next = wch + 1;
+ while ((*wch_next) && (IS_DELIMITER(*wch_next)))
+ wch_next++;
+
+ /* keep going? */
+ if (*wch_next == 0) {
+ /* no more characters to process */
+ /* nothing to do */
+ } else if ((uintptr_t)parg >= \
+ (uintptr_t)argv_buffer \
+ + argv_buffer_len) {
+ /* argv_buffer is too small */
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ } else if ((uintptr_t)arg >= \
+ (uintptr_t)args_buffer \
+ + args_buffer_len) {
+ /* args_buffer is too small */
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ } else {
+ /* advance parg, set last member */
+ parg++;
+ *parg = arg;
+ }
+ } else {
+ /* the current character is not a delimiter... */
+ /* determine wch_next */
+ if (((*wch >= 0x0000) && (*wch < 0xD800)) \
+ || ((*wch >= 0xE000) && (*wch < 0x10000))) {
+ /* in the BMP, single 16-bit representation */
+ wch_next = wch + 1;
+ } else if ((*wch >= 0xD800) && (*wch < 0xDC00)) {
+ /* validate surrogate pair */
+ wch_next = wch + 1;
+
+ if ((*wch_next >= 0xDC00) && (*wch_next < 0xE000))
+ /* this is a valid surrogate pair */
+ wch_next++;
+ else
+ return NT_STATUS_ILLEGAL_CHARACTER;
+ } else
+ return NT_STATUS_ILLEGAL_CHARACTER;
+
+ /* we now know the position of this and the next character */
+ /* continue with special cases */
+
+ if (quoted_state && (*wch == DOUBLE_QUOTE) \
+ && (*wch_next == DOUBLE_QUOTE)) {
+ /**
+ * two consecutive double quotation marks
+ * within a quoted string:
+ * add a single quotation mark to the argument
+ **/
+ ADD_SINGLE_WCHAR16_t(DOUBLE_QUOTE);
+ wch_next++;
+ } else if (((backslash_count % 2) == 0) \
+ && (*wch == BACKSLASH) \
+ && (*wch_next == DOUBLE_QUOTE)) {
+ /* 2n+1 backslashes followed by a double quote */
+ backslash_count /= 2;
+ /* add n backslashes */
+ ADD_N_BACKSLASHES;
+ /* add a literal double quotation mark */
+ ADD_SINGLE_WCHAR16_t(DOUBLE_QUOTE);
+ /* get ready for next character */
+ wch_next++;
+ } else if (backslash_count && (*wch == DOUBLE_QUOTE)) {
+ /* 2n backslashes followed by a double quote */
+ backslash_count /= 2;
+ /* add n backslashes */
+ ADD_N_BACKSLASHES;
+ /* turn quoted_state on/off */
+ quoted_state = !quoted_state;
+ } else if ((*wch == BACKSLASH) \
+ && (*wch_next == BACKSLASH)) {
+ /* this is a sequence of two backslashes */
+ backslash_count += 2;
+ wch_next++;
+ } else {
+ /* copy pending backslashes as needed */
+ if (backslash_count)
+ ADD_N_BACKSLASHES;
+
+ if (*wch == DOUBLE_QUOTE) {
+ /* turn quoted_state on/off */
+ quoted_state = !quoted_state;
+ } else {
+ /* copy either two or four bytes */
+ ADD_SINGLE_WCHAR16_t(*wch);
+ wch++;
+
+ /* surrogate pair? */
+ if (wch < wch_next) {
+ ADD_SINGLE_WCHAR16_t(*wch);
+ }
+ }
+ }
+ }
+
+ /* proceed to the next character (or null termination) */
+ wch = wch_next;
+ }
+
+ /* pending backslashes? */
+ if (backslash_count)
+ ADD_N_BACKSLASHES;
+
+ /* null termination */
+ ADD_SINGLE_WCHAR16_t(0);
+
+ /* how many arguments did you say? */
+ *arg_count = (int)(((uintptr_t)parg - (uintptr_t)argv_buffer)
+ / sizeof(size_t) + 1);
+
+ /* output bytes written */
+ if (args_bytes_written)
+ *args_bytes_written = (uintptr_t)arg - (uintptr_t)args_buffer;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_get_argv_envp_utf16(
+ __out int * argc,
+ __out wchar16_t *** wargv,
+ __out wchar16_t *** wenvp,
+ __in uint32_t flags,
+ __in void * ext_params __optional,
+ __out void * reserved __optional)
+{
+ nt_runtime_data * rtdata;
+ nt_argv_envp_block_info main_params_internal;
+ nt_argv_envp_block_info * main_params;
+ nt_get_argv_envp_ext_params * __ext_params;
+ ntapi_internals * __internals;
+
+ unsigned idx;
+ int32_t status;
+ uintptr_t addr;
+ intptr_t offset;
+ wchar16_t * wch_s;
+ wchar16_t * wch_dst;
+ wchar16_t ** wch_p;
+ char ** ch_p;
+ uintptr_t * psrc;
+ uintptr_t * pdst;
+ uintptr_t * paligned;
+ wchar16_t * pboundary;
+
+ /* init */
+ __internals = __ntapi_internals();
+
+ /* use internal buffer? */
+ if (flags & NT_GET_ARGV_ENVP_USE_CALLER_BUFFER) {
+ __ext_params = (nt_get_argv_envp_ext_params *)ext_params;
+ main_params = &(__ext_params->argv_envp_block_info);
+ } else {
+ /* pointers to internal/local structures */
+ main_params = &main_params_internal;
+
+ /* init */
+ __ntapi->tt_aligned_block_memset(
+ main_params,0,
+ sizeof(*main_params));
+
+ /* use internal buffer */
+ main_params->cmd_line = __ntapi_tt_get_cmd_line_utf16();
+ main_params->wargv_buffer = __internals->ntapi_img_sec_bss->argv_envp_array;
+ main_params->wargv_buffer_len = __NT_BSS_ARGV_BUFFER_SIZE;
+ main_params->argv_envp_ptr_total = (int)(main_params->wargv_buffer_len
+ / sizeof(uintptr_t));
+ main_params->wargs_buffer = (wchar16_t *)&(__internals->ntapi_img_sec_bss->args_envs_buffer);
+ main_params->wargs_buffer_len = __NT_BSS_ARGS_BUFFER_SIZE;
+ }
+
+ /* (__ntapi_parse_cmd_line_args_utf16 will zero-out both buffers) */
+ status = __ntapi_tt_parse_cmd_line_args_utf16(
+ main_params->cmd_line,
+ &main_params->argc,
+ main_params->wargs_buffer,
+ main_params->wargs_buffer_len,
+ &main_params->wargs_bytes_written,
+ main_params->wargv_buffer,
+ main_params->wargv_buffer_len,
+ 0);
+
+ if (status) return status;
+
+ /* argv[] needs a terminating null pointer */
+ if (main_params->argc == main_params->argv_envp_ptr_total)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ /* set idx to the envp[0] array index */
+ idx = main_params->argc + 1;
+
+ /* set wenvp[] to its starting address */
+ main_params->wenvp_buffer = &main_params->wargv_buffer[idx];
+
+ /* update wargv_buffer_len and envp_buffer_len */
+ main_params->wenvp_buffer_len = main_params->wargv_buffer_len
+ - (idx * sizeof(uintptr_t));
+
+ main_params->wargv_buffer_len = idx * sizeof(uintptr_t);
+
+ /* align wenvs at pointer-size boundary */
+ main_params->wargs_bytes_written += sizeof(uintptr_t) - 1;
+ main_params->wargs_bytes_written /= sizeof(uintptr_t);
+ main_params->wargs_bytes_written *= sizeof(uintptr_t);
+
+ /* book-keeping */
+ main_params->wenvs_buffer = main_params->wargs_buffer
+ + main_params->wargs_bytes_written;
+
+ main_params->wenvs_buffer_len = main_params->wargs_buffer_len
+ - main_params->wargs_bytes_written;
+
+ main_params->wargs_buffer_len = main_params->wargs_bytes_written;
+
+
+ /* peb environment block (read-only) */
+ wch_s = __ntapi_tt_get_peb_env_block_utf16();
+
+ if ((!wch_s) || (!*wch_s))
+ return NT_STATUS_DLL_INIT_FAILED;
+
+ /* populate the envp[] array */
+ while ((*wch_s) && (idx < main_params->argv_envp_ptr_total)) {
+ main_params->envc++;
+ wch_p = &(main_params->wargv_buffer[idx]);
+ *wch_p = wch_s;
+
+ /* skip the rest of the environment variable */
+ while (*++wch_s);
+
+ /* advance to the next variable (or final null termination) */
+ wch_s++;
+ idx++;
+ }
+
+ /* envp[] needs a terminating null pointer */
+ if ((*wch_s) && (idx = main_params->argv_envp_ptr_total))
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ /* copy environment? */
+ if (flags & NT_GET_ARGV_ENVP_COPY_ENVIRONMENT) {
+ /* wch_s now points at the final null termination */
+ main_params->wenvs_bytes_used =
+ ((uintptr_t)wch_s
+ - (uintptr_t)(*main_params->wenvp_buffer));
+
+ /* do we have enough room? */
+ if (main_params->wenvs_buffer_len < main_params->wenvs_bytes_used)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ /* upper boundary */
+ pboundary = ++wch_s;
+
+ /* you'd expect the peb environment block to be aligned,
+ but one can never know... */
+ wch_s = *main_params->wenvp_buffer;
+ wch_dst = main_params->wenvs_buffer;
+
+ while ((uintptr_t)wch_s % sizeof(uintptr_t)) {
+ *wch_dst = *wch_s;
+ wch_s++;
+ wch_dst++;
+ }
+
+ /* copy the aligned portion of the environment block */
+ addr = (uintptr_t)(pboundary);
+ addr /= sizeof(uintptr_t);
+ addr *= sizeof(uintptr_t);
+ paligned = (uintptr_t *)addr;
+
+ psrc = (uintptr_t *)wch_s;
+ pdst = (uintptr_t *)wch_dst;
+
+ while (psrc < paligned) {
+ *pdst = *psrc;
+ psrc++;
+ pdst++;
+ }
+
+ /* copy any remaining bytes */
+ wch_s = (wchar16_t *)paligned;
+ wch_dst = (wchar16_t *)pdst;
+
+ while (wch_s < pboundary) {
+ *wch_dst = *wch_s;
+ wch_s++;
+ wch_dst++;
+ }
+
+ /* finally, we update the envp[] pointers */
+ offset = (intptr_t)main_params->wenvs_buffer
+ - (intptr_t)*main_params->wenvp_buffer;
+
+ wch_p = main_params->wenvp_buffer;
+
+ while (*wch_p) {
+ addr = ((uintptr_t)*wch_p) + offset;
+ *wch_p = (wchar16_t *)addr;
+ wch_p++;
+ }
+ }
+
+ /* (command line arguments always get validated) */
+ /* validate the environment block? */
+ if (flags & NT_GET_ARGV_ENVP_VALIDATE_UTF16) {
+ wch_p = main_params->wenvp_buffer;
+
+ while (*wch_p) {
+ status = __ntapi->uc_validate_unicode_stream_utf16(
+ *wch_p,
+ 0,0,0,0,0);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+ else
+ wch_p++;
+ }
+ }
+
+ /* once */
+ if (!__internals->rtdata) {
+ __ntapi->tt_get_runtime_data(
+ &__internals->rtdata,
+ main_params->wargv_buffer);
+
+ if (!__internals->rtdata) {
+ __internals->rtdata = &__rtdata;
+
+ if ((status =__ntapi->tt_init_runtime_data(&__rtdata)))
+ return status;
+
+ } else if ((status =__ntapi->tt_update_runtime_data(__internals->rtdata)))
+ return status;
+
+ rtdata = __internals->rtdata;
+
+ rtdata->peb_envc = main_params->envc;
+ rtdata->peb_argc = main_params->argc;
+ rtdata->peb_wargv = main_params->wargv_buffer;
+ rtdata->peb_wenvp = main_params->wenvp_buffer;
+
+ /* integral wargv, wenvp, argv, envp */
+ if (rtdata->wargv) {
+ rtdata->wargv += (uintptr_t)rtdata / sizeof(wchar16_t *);
+
+ for (wch_p=rtdata->wargv; *wch_p; wch_p++)
+ *wch_p += (uintptr_t)rtdata / sizeof(wchar16_t);
+ };
+
+ if (rtdata->wenvp) {
+ rtdata->wenvp += (uintptr_t)rtdata / sizeof(wchar16_t *);
+
+ for (wch_p=rtdata->wenvp; *wch_p; wch_p++)
+ *wch_p += (uintptr_t)rtdata / sizeof(wchar16_t);
+ }
+
+ if (rtdata->argv) {
+ rtdata->argv += (uintptr_t)rtdata / sizeof(char *);
+
+ for (ch_p=rtdata->argv; *ch_p; ch_p++)
+ *ch_p += (uintptr_t)rtdata;
+
+ rtdata->argc = (int32_t)(ch_p - rtdata->argv);
+ };
+
+ if (rtdata->envp) {
+ rtdata->envp += (uintptr_t)rtdata / sizeof(char *);
+
+ for (ch_p=rtdata->envp; *ch_p; ch_p++)
+ *ch_p += (uintptr_t)rtdata;
+
+ rtdata->envc = (int32_t)(ch_p - rtdata->envp);
+ };
+ }
+
+ /* we're good */
+ *argc = main_params->argc;
+ *wargv = main_params->wargv_buffer;
+ *wenvp = main_params->wenvp_buffer;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_get_argv_envp_utf8(
+ __out int * argc,
+ __out char *** argv,
+ __out char *** envp,
+ __in uint32_t flags,
+ __in void * ext_params __optional,
+ __out void * reserved __optional)
+{
+ int32_t status;
+ ntapi_internals * __internals;
+
+ wchar16_t ** wargv;
+ wchar16_t ** wenvp;
+ uint32_t pcount;
+
+ nt_get_argv_envp_ext_params __ext_params_internal;
+ nt_get_argv_envp_ext_params * __ext_params;
+ nt_argv_envp_block_info * main_params;
+
+ /* use internal buffer? */
+ if (flags & NT_GET_ARGV_ENVP_USE_CALLER_BUFFER) {
+ __ext_params = (nt_get_argv_envp_ext_params *)ext_params;
+ main_params = &__ext_params->argv_envp_block_info;
+ } else {
+ /* pointers to internal/local structures */
+ __ext_params = &__ext_params_internal;
+ main_params = &__ext_params->argv_envp_block_info;
+
+ /* init */
+ __ntapi->tt_aligned_block_memset(
+ main_params,0,
+ sizeof(*main_params));
+
+ __internals = __ntapi_internals();
+
+ /* use internal buffer */
+ main_params->cmd_line = __ntapi_tt_get_cmd_line_utf16();
+ main_params->wargv_buffer = __internals->ntapi_img_sec_bss->argv_envp_array;
+ main_params->wargv_buffer_len = __NT_BSS_ARGV_BUFFER_SIZE;
+ main_params->argv_envp_ptr_total = (int)(main_params->wargv_buffer_len
+ / sizeof(uintptr_t));
+ main_params->wargs_buffer = (wchar16_t *)&(__internals->ntapi_img_sec_bss->args_envs_buffer);
+ main_params->wargs_buffer_len = __NT_BSS_ARGS_BUFFER_SIZE;
+ }
+
+ /* start with obtaining the utf-16 environment */
+ status = __ntapi->tt_get_argv_envp_utf16(
+ argc,
+ &wargv,
+ &wenvp,
+ flags | NT_GET_ARGV_ENVP_USE_CALLER_BUFFER,
+ __ext_params,
+ reserved);
+
+ if (status) return status;
+
+ /* enough pointers left? */
+ pcount = main_params->argc + 1 + main_params->envc + 1;
+
+ if (pcount > (main_params->argv_envp_ptr_total / 2))
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ else if ((main_params->wenvs_buffer_len - main_params->wenvs_bytes_used)
+ < sizeof(uintptr_t))
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ /* first args byte should be aligned at pointer-size boundary */
+ main_params->wenvs_bytes_used += sizeof(uintptr_t) - 1;
+ main_params->wenvs_bytes_used /= sizeof(uintptr_t);
+ main_params->wenvs_bytes_used *= sizeof(uintptr_t);
+
+ /* book-keeping */
+ /* block reminder: wargs -- wenvs -- args -- envs */
+ main_params->argv = (char **)main_params->wenvp_buffer;
+ main_params->argv += main_params->envc + 1;
+
+ main_params->args_buffer = (char *)main_params->wenvs_buffer;
+ main_params->args_buffer += main_params->wenvs_bytes_used;
+
+ main_params->args_buffer_len = main_params->wenvs_buffer_len
+ - main_params->wenvs_bytes_used;
+
+ main_params->wenvs_buffer_len = main_params->wenvs_bytes_used;
+
+ /* create a utf-8 argv[] array */
+ status = __ntapi_tt_array_convert_utf16_to_utf8(
+ main_params->wargv_buffer,
+ main_params->argv,
+ 0,
+ main_params->args_buffer,
+ main_params->args_buffer_len,
+ &main_params->args_bytes_written);
+
+ if (status) return status;
+
+ /* first envs byte should be aligned to pointer-size boundary */
+ main_params->args_bytes_written += sizeof(uintptr_t) - 1;
+ main_params->args_bytes_written /= sizeof(uintptr_t);
+ main_params->args_bytes_written *= sizeof(uintptr_t);
+
+ /* book-keeping */
+ main_params->envp = main_params->argv + main_params->argc + 1;
+
+ main_params->envs_buffer = main_params->args_buffer
+ + main_params->args_bytes_written;
+
+ main_params->envs_buffer_len = main_params->args_buffer_len
+ - main_params->args_bytes_written;
+
+ main_params->args_buffer_len = main_params->args_bytes_written;
+
+ /* subsequent streams (if any) should be aligned to pointer-size boundary */
+ main_params->envs_bytes_used += sizeof(uintptr_t) - 1;
+ main_params->envs_bytes_used /= sizeof(uintptr_t);
+ main_params->envs_bytes_used *= sizeof(uintptr_t);
+
+ /* create a utf-8 envp[] array */
+ status = __ntapi_tt_array_convert_utf16_to_utf8(
+ main_params->wenvp_buffer,
+ main_params->envp,
+ 0,
+ main_params->envs_buffer,
+ main_params->envs_buffer_len,
+ &main_params->envs_bytes_used);
+
+ if (status) return status;
+
+ /* we're good */
+ *argc = main_params->argc;
+ *argv = main_params->argv;
+ *envp = main_params->envp;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+wchar16_t * __stdcall __ntapi_tt_get_cmd_line_utf16(void)
+{
+ nt_peb * peb;
+ nt_unicode_string cmd_line;
+
+ peb = (nt_peb *)pe_get_peb_address();
+
+ if (peb) {
+ cmd_line = peb->process_params->command_line;
+ return cmd_line.buffer;
+ } else
+ return (wchar16_t *)0;
+}
+
+
+wchar16_t * __stdcall __ntapi_tt_get_peb_env_block_utf16(void)
+{
+ nt_peb * peb;
+
+ peb = (nt_peb *)pe_get_peb_address();
+
+ if (peb)
+ return peb->process_params->environment;
+ else
+ return (wchar16_t *)0;
+}
diff --git a/src/argv/ntapi_tt_array_utf16.c b/src/argv/ntapi_tt_array_utf16.c
new file mode 100644
index 0000000..d8bbb8b
--- /dev/null
+++ b/src/argv/ntapi_tt_array_utf16.c
@@ -0,0 +1,258 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_argv.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+/**
+ * scenario: program -e app [arg1 arg2 ... argn]
+ * input: a utf-16 argument vector
+ * output: a utf-16 cmd_line string
+ * example: tty_pipe_create_child_process
+**/
+
+int32_t __stdcall __ntapi_tt_array_copy_utf16(
+ __out int * argc,
+ __in const wchar16_t ** wargv,
+ __in const wchar16_t ** wenvp,
+ __in const wchar16_t * image_name __optional,
+ __in const wchar16_t * interpreter __optional,
+ __in const wchar16_t * optarg __optional,
+ __in void * base,
+ __out void * buffer,
+ __in size_t buflen,
+ __out size_t * blklen)
+{
+ const wchar16_t ** parg;
+ const wchar16_t * warg;
+ const wchar16_t * dummy;
+ wchar16_t * wch;
+ ptrdiff_t diff;
+ ptrdiff_t ptrs;
+ size_t needed;
+
+ /* fallback */
+ dummy = 0;
+ wargv = wargv ? wargv : &dummy;
+ wenvp = wenvp ? wenvp : &dummy;
+
+ /* ptrs, needed */
+ ptrs = 0;
+ needed = 0;
+
+ if (image_name) {
+ ptrs++;
+ needed += sizeof(wchar16_t *)
+ + __ntapi->tt_string_null_offset_short((const int16_t *)image_name)
+ + sizeof(wchar16_t);
+ }
+
+ for (parg=wargv; *parg; parg++)
+ needed += sizeof(wchar16_t *)
+ + __ntapi->tt_string_null_offset_short((const int16_t *)*parg)
+ + sizeof(wchar16_t);
+
+ ptrs += (parg - wargv);
+ *argc = (int)ptrs;
+
+ for (parg=wenvp; *parg; parg++)
+ needed += sizeof(wchar16_t *)
+ + __ntapi->tt_string_null_offset_short((const int16_t *)*parg)
+ + sizeof(wchar16_t);
+
+ ptrs += (parg - wenvp);
+
+ ptrs += 2;
+ needed += 2*sizeof(wchar16_t *);
+ blklen = blklen ? blklen : &needed;
+ *blklen = needed;
+
+ if (buflen < needed)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ /* init */
+ parg = (const wchar16_t **)buffer;
+ wch = (wchar16_t *)(parg+ptrs);
+ diff = (uintptr_t)base / sizeof(wchar16_t);
+
+ /* image_name */
+ if (image_name) {
+ *parg++ = wch-diff;
+ for (warg=image_name; *warg; warg++,wch++)
+ *wch = *warg;
+ *wch++ = '\0';
+ }
+
+ /* argv */
+ for (; *wargv; wargv++) {
+ *parg++=wch-diff;
+ for (warg=*wargv; *warg; warg++,wch++)
+ *wch = *warg;
+ *wch++ = '\0';
+ }
+
+ *parg++ = 0;
+
+ /* envp */
+ for (; *wenvp; wenvp++) {
+ *parg++=wch-diff;
+ for (warg=*wenvp; *warg; warg++,wch++)
+ *wch = *warg;
+ *wch++ = '\0';
+ }
+
+ *parg++ = 0;
+
+ return NT_STATUS_SUCCESS;
+}
+
+int32_t __stdcall __ntapi_tt_array_convert_utf16_to_utf8(
+ __in wchar16_t ** warrv,
+ __in char ** arrv,
+ __in void * base,
+ __in char * buffer,
+ __in size_t buffer_len,
+ __out size_t * bytes_written)
+{
+ uint8_t * ubound;
+ uint8_t * ch;
+ wchar16_t * wch;
+ wchar16_t wx;
+ wchar16_t wy;
+ wchar16_t wz;
+ wchar16_t wy_low;
+ wchar16_t wy_high;
+ wchar16_t ww;
+ wchar16_t uuuuu;
+ wchar16_t u_low;
+ wchar16_t u_high;
+ ptrdiff_t diff;
+
+ #define __UTF8_MAX_CODE_POINT_BYTES (4)
+
+ ch = (uint8_t *)buffer;
+ ubound = (uint8_t *)buffer + buffer_len - __UTF8_MAX_CODE_POINT_BYTES;
+ diff = (uintptr_t)base / sizeof(wchar16_t);
+
+ while (warrv && *warrv) {
+ *arrv = (char *)(ch-(uintptr_t)base);
+ wch = *warrv + diff;
+
+ /* all utf-16 streams at stake have been validated */
+ while (*wch && (ch < ubound)) {
+ if (*wch <= 0x7F) {
+ /* from: 00000000 0xxxxxxx (little endian) */
+ /* to: 0xxxxxxx (utf-8) */
+ *ch = (char)(*wch);
+ } else if (*wch <= 0x7FF) {
+ /* from: 00000yyy yyxxxxxx (little endian) */
+ /* to: 110yyyyy 10xxxxxx (utf-8) */
+ wy = *wch;
+ wy >>= 6;
+
+ wx = *wch;
+ wx <<= 10;
+ wx >>= 10;
+
+ /* write the y part */
+ *ch = (char)(0xC0 | wy);
+ ch++;
+
+ /* write the x part */
+ *ch = (char)(0x80 | wx);
+ } else if ((*wch < 0xD800) || (*wch >= 0xE000)) {
+ /* from: zzzzyyyy yyxxxxxx (little endian) */
+ /* to: 1110zzzz 10yyyyyy 10xxxxxx (utf-8) */
+ wz = *wch;
+ wz >>= 12;
+
+ wy = *wch;
+ wy <<= 4;
+ wy >>= 10;
+
+ wx = *wch;
+ wx <<= 10;
+ wx >>= 10;
+
+ /* write the z part */
+ *ch = (char)(0xE0 | wz);
+ ch++;
+
+ /* write the y part */
+ *ch = (char)(0x80 | wy);
+ ch++;
+
+ /* write the x part */
+ *ch = (char)(0x80 | wx);
+ } else {
+ /* from: 110110ww wwzzzzyy 110111yy yyxxxxxx (little endian) */
+ /* to: 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx (utf-8) */
+
+ /* low two bytes */
+ wx = *wch;
+ wx <<= 10;
+ wx >>= 10;
+
+ wy_low = *wch;
+ wy_low <<= 6;
+ wy_low >>= 12;
+
+ /* (surrogate pair) */
+ wch++;
+
+ /* high two bytes */
+ wy_high = *wch;
+ wy_high <<= 14;
+ wy_high >>= 10;
+
+ wz = *wch;
+ wz <<= 10;
+ wz >>= 12;
+ wz <<= 2;
+
+ ww = *wch;
+ ww <<= 6;
+ ww >>= 12;
+
+ uuuuu = ww + 1;
+ u_high = uuuuu >> 2;
+ u_low = ((uuuuu << 14) >> 10);
+
+ /* 1st byte: 11110uuu */
+ *ch = (char)(0xF0 | u_high);
+ ch++;
+
+ /* 2nd byte: 10uuzzzz */
+ *ch = (char)(0x80 | u_low | wz);
+ ch++;
+
+ /* 3rd byte: 10yyyyyy */
+ *ch = (char)(0x80 | wy_low | wy_high);
+ ch++;
+
+ /* 4th byte: 10xxxxxx */
+ *ch = (char)(0x80 | wx);
+ }
+
+ ch++;
+ wch++;
+ }
+
+ if (*wch)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ ch++;
+ arrv++;
+ warrv++;
+ }
+
+ *bytes_written = (size_t)(ch - (uint8_t *)buffer);
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/argv/ntapi_tt_array_utf8.c b/src/argv/ntapi_tt_array_utf8.c
new file mode 100644
index 0000000..8d3b837
--- /dev/null
+++ b/src/argv/ntapi_tt_array_utf8.c
@@ -0,0 +1,117 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_argv.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_array_copy_utf8(
+ __out int * argc,
+ __in const char ** argv,
+ __in const char ** envp,
+ __in const char * image_name __optional,
+ __in const char * interpreter __optional,
+ __in const char * optarg __optional,
+ __in void * base,
+ __out void * buffer,
+ __in size_t buflen,
+ __out size_t * blklen)
+{
+ const char ** parg;
+ const char * arg;
+ const char * dummy;
+ char * ch;
+ ptrdiff_t diff;
+ ptrdiff_t ptrs;
+ size_t needed;
+
+ /* fallback */
+ dummy = 0;
+ argv = argv ? argv : &dummy;
+ envp = envp ? envp : &dummy;
+
+ /* ptrs, needed */
+ ptrs = 0;
+ needed = 0;
+
+ if (image_name) {
+ ptrs++;
+ needed += sizeof(char *)
+ + __ntapi->tt_string_null_offset_multibyte(image_name)
+ + sizeof(char);
+ }
+
+ for (parg=argv; *parg; parg++)
+ needed += sizeof(char *)
+ + __ntapi->tt_string_null_offset_multibyte(*parg)
+ + sizeof(char);
+
+ ptrs += (parg - argv);
+ *argc = (int)ptrs;
+
+ for (parg=envp; *parg; parg++)
+ needed += sizeof(char *)
+ + __ntapi->tt_string_null_offset_multibyte(*parg)
+ + sizeof(char);
+
+ ptrs += (parg - envp);
+
+ ptrs += 2;
+ needed += 2*sizeof(char *);
+ blklen = blklen ? blklen : &needed;
+ *blklen = needed;
+
+ if (buflen < needed)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ /* init */
+ parg = (const char **)buffer;
+ ch = (char *)(parg+ptrs);
+ diff = (ptrdiff_t)base;
+
+ /* image_name */
+ if (image_name) {
+ *parg++ = ch-diff;
+ for (arg=image_name; *arg; arg++,ch++)
+ *ch = *arg;
+ *ch++ = '\0';
+ }
+
+ /* argv */
+ for (; *argv; argv++) {
+ *parg++=ch-diff;
+ for (arg=*argv; *arg; arg++,ch++)
+ *ch = *arg;
+ *ch++ = '\0';
+ }
+
+ *parg++ = 0;
+
+ /* envp */
+ for (; *envp; envp++) {
+ *parg++=ch-diff;
+ for (arg=*envp; *arg; arg++,ch++)
+ *ch = *arg;
+ *ch++ = '\0';
+ }
+
+ *parg++ = 0;
+
+ return NT_STATUS_SUCCESS;
+}
+
+int32_t __stdcall __ntapi_tt_array_convert_utf8_to_utf16(
+ __in char ** arrv,
+ __in wchar16_t ** arra,
+ __in void * base,
+ __in wchar16_t * buffer,
+ __in size_t buffer_len,
+ __out size_t * bytes_written)
+{
+ return NT_STATUS_SUCCESS;
+}
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;
+}
+
diff --git a/src/argv/ntapi_tt_get_option.c b/src/argv/ntapi_tt_get_option.c
new file mode 100644
index 0000000..e6f0748
--- /dev/null
+++ b/src/argv/ntapi_tt_get_option.c
@@ -0,0 +1,451 @@
+/********************************************************/
+/* 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"
+
+
+/**
+ * a simple facility for minimal programs or system libraries
+ * with no libc available at the time of invocation, as well
+ * as applications using the midipix free-standing development
+ * environment.
+ *
+ * the approach taken by this module to the support of short
+ * and long options reflects the above constraint, namely
+ * the absence of a callable libc at the time of invocation;
+ * there is no intent for interfaces in this module to
+ * be POSIXLY correct or otherwise portable. the sole
+ * purpose of all functions in this module is to serve
+ * internal or otherwise free-standing midipix applications,
+ * and their relevance otherwise is accordingly non-existent.
+ *
+ * all options are encoded in utf-16; note, however, that
+ * short options may only use code points that are located
+ * in the basic multilingual plane.
+ *
+ * option values are either required or not allowed altogether,
+ * and the first character of an option value may not be a hyphen.
+ * if you need the first character of an option value to be a
+ * hyphen, then make sure you escape it somehow (for instance by
+ * enclosing it in quotation marks).
+ *
+ * a short option and its value must reside in two separate
+ * argv[] elements (in other words: -ooutput is illegal).
+ *
+ * a long option and its value must reside in the same argv[]
+ * element and be separated by a single equal sign.
+ *
+ * Examples of valid options and option values:
+ * --------------------------------------------
+ * -o
+ * -o value
+ * --long-option-with-no-value
+ * --long-option=value
+**/
+
+#define HYPHEN 0x2D
+#define EQUAL_SIGN 0x3D
+
+
+static int __inline__ __fastcall __is_bmp_code_point(wchar16_t code_point)
+{
+ return (((code_point >= 0x0000) && (code_point < 0xD800)) \
+ || ((code_point >= 0xE000) && (code_point < 0x10000)));
+}
+
+
+static int __inline__ __fastcall __is_last_program_option(
+ __in nt_program_option * option)
+{
+ return (!(option->short_name_code))
+ && (!(option->long_name))
+ && (!(option->long_name_hash));
+}
+
+
+static int __fastcall __is_short_option(wchar16_t * wch)
+{
+ return ((wch) && (*wch == HYPHEN)
+ && __is_bmp_code_point(*++wch)
+ && (*++wch == 0));
+}
+
+static int __fastcall __is_long_option(wchar16_t * wch)
+{
+ return ((wch) && (*wch == HYPHEN)
+ && (++wch) && (*wch == HYPHEN)
+ && (*++wch));
+}
+
+
+static int __fastcall __is_last_option_argument(wchar16_t * wch)
+{
+ return ((wch) && (*wch == HYPHEN)
+ && (*++wch == HYPHEN)
+ && (*++wch == 0));
+}
+
+
+static uint32_t __fastcall __compute_crc32_utf16_str(
+ __in const uint32_t * crc32_table,
+ __in wchar16_t * wch)
+{
+ uint32_t crc32;
+ unsigned char * byte_buffer;
+
+ /* crc32 hash... */
+ crc32 = 0 ^ 0xFFFFFFFF;
+
+ /* initialize byte_buffer */
+ byte_buffer = (unsigned char *)wch;
+
+ /* 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++;
+ }
+
+ return crc32;
+}
+
+
+static uint32_t __fastcall __compute_crc32_long_option_name(
+ __in const uint32_t * crc32_table,
+ __in wchar16_t * wch_arg,
+ __in wchar16_t * wch_termination)
+{
+ uint32_t crc32;
+ unsigned char * byte_buffer;
+
+ /* crc32 hash... */
+ crc32 = 0 ^ 0xFFFFFFFF;
+
+ /* initialize byte_buffer */
+ byte_buffer = (unsigned char *)wch_arg;
+
+ /* iterate */
+ while ((uintptr_t)byte_buffer < (uintptr_t)wch_termination) {
+ /* 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++;
+ }
+
+ return crc32;
+}
+
+
+static void __fastcall __init_cmd_option_meta_utf16(
+ __in nt_cmd_option_meta_utf16 * cmd_opt_meta)
+{
+ cmd_opt_meta->short_name = (wchar16_t *)0;
+ cmd_opt_meta->short_name_code = 0;
+ cmd_opt_meta->long_name = (wchar16_t *)0;
+ cmd_opt_meta->long_name_hash = 0;
+ cmd_opt_meta->value = (wchar16_t *)0;
+ cmd_opt_meta->value_hash = 0;
+ cmd_opt_meta->argv_index = 0;
+ cmd_opt_meta->flags = 0;
+
+ return;
+}
+
+
+int32_t __stdcall __ntapi_tt_get_short_option_meta_utf16(
+ __in const uint32_t * crc32_table,
+ __in wchar16_t option_name,
+ __in wchar16_t * argv[],
+ __out nt_cmd_option_meta_utf16 * cmd_opt_meta)
+{
+ int idx;
+ wchar16_t * wch;
+
+ if (!crc32_table)
+ return NT_STATUS_INVALID_PARAMETER_1;
+ else if (!option_name)
+ return NT_STATUS_INVALID_PARAMETER_2;
+ else if (!argv)
+ return NT_STATUS_INVALID_PARAMETER_3;
+
+ /* initialize cmd_opt_meta */
+ __init_cmd_option_meta_utf16(cmd_opt_meta);
+
+ /* step 1: attempt to find the short option in argv[] */
+ idx = 0;
+ while (argv[idx] && (!cmd_opt_meta->short_name_code)) {
+ wch = argv[idx];
+
+ /* is this our option? */
+ if ((*wch == HYPHEN)
+ && (*++wch == option_name)
+ && (*++wch == 0)) {
+
+ /* found it, get ready to hash the value */
+ cmd_opt_meta->short_name_code = option_name;
+ cmd_opt_meta->short_name = argv[idx];
+ cmd_opt_meta->argv_index = idx;
+ } else {
+ idx++;
+ }
+ }
+
+ /* if the next argument is also an option (or is null), just exit */
+ idx++;
+ if ((!argv[idx]) || (*argv[idx] == HYPHEN))
+ return NT_STATUS_SUCCESS;
+
+ /* step 2: hash the value */
+ cmd_opt_meta->value = argv[idx];
+ cmd_opt_meta->value_hash =
+ __compute_crc32_utf16_str(
+ crc32_table,
+ argv[idx]);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_get_long_option_meta_utf16(
+ __in const uint32_t * crc32_table,
+ __in wchar16_t * option_name,
+ __in uint32_t option_name_hash __optional,
+ __in wchar16_t * argv[],
+ __out nt_cmd_option_meta_utf16 * cmd_opt_meta)
+{
+ /**
+ * option_name must always include the two-hyphen prefix;
+ * and the option value must be preceded by an equal sign.
+ *
+ * the only valid long option forms in argv[] are therefore:
+ * --long-option
+ * --long-option=value
+ **/
+
+ int idx;
+ uint32_t crc32;
+ wchar16_t * wch;
+
+ /* validation */
+ if (!crc32_table)
+ return NT_STATUS_INVALID_PARAMETER_1;
+ else if ((!option_name) && (!option_name_hash))
+ return NT_STATUS_INVALID_PARAMETER;
+ else if ((option_name) && (option_name_hash))
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ else if (!argv)
+ return NT_STATUS_INVALID_PARAMETER_4;
+
+ /* initialize cmd_opt_meta */
+ __init_cmd_option_meta_utf16(cmd_opt_meta);
+
+ /* step 1: crc32 of the target option_name */
+ if (option_name_hash)
+ crc32 = option_name_hash;
+ else
+ option_name_hash =
+ __compute_crc32_utf16_str(
+ crc32_table,
+ option_name);
+
+ /* step 2: attempt to find the long option in argv[] */
+ idx = 0;
+ while (argv[idx] && (!cmd_opt_meta->value)) {
+ wch = argv[idx];
+
+ if (__is_long_option(wch)) {
+ /* find the equal sign or null termination */
+ while ((*wch) && (*wch != EQUAL_SIGN))
+ wch++;
+
+ crc32 = __compute_crc32_long_option_name(
+ crc32_table,
+ argv[idx],
+ wch);
+
+ if (crc32 == option_name_hash) {
+ /* found it, get ready to hash the value */
+ cmd_opt_meta->long_name_hash = option_name_hash;
+ cmd_opt_meta->long_name = argv[idx];
+ cmd_opt_meta->argv_index = idx;
+
+ if (*wch)
+ /* skip the equal sign */
+ wch++;
+
+ cmd_opt_meta->value = wch;
+ } else
+ idx++;
+ }
+ }
+
+ if (cmd_opt_meta->value)
+ cmd_opt_meta->value_hash =
+ __compute_crc32_utf16_str(
+ crc32_table,
+ cmd_opt_meta->value);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_validate_program_options(
+ __in const uint32_t * crc32_table,
+ __in wchar16_t * argv[],
+ __in nt_program_option * options[],
+ __in nt_program_options_meta * options_meta)
+{
+ int idx;
+ int idx_arg;
+ int idx_option;
+ int idx_max;
+ uint32_t crc32;
+ nt_program_option * option;
+ wchar16_t * parg;
+ wchar16_t * pvalue;
+
+ /* validation */
+ if (!crc32_table)
+ return NT_STATUS_INVALID_PARAMETER_1;
+ else if (!argv)
+ return NT_STATUS_INVALID_PARAMETER_2;
+ else if (!options)
+ return NT_STATUS_INVALID_PARAMETER_3;
+ else if (!options_meta)
+ return NT_STATUS_INVALID_PARAMETER_4;
+
+
+ /* step 1: validate options[] hash the long option names */
+ idx = 0;
+ idx_option = 0;
+ option = options[0];
+ pvalue = (wchar16_t *)0;
+
+ while (!__is_last_program_option(option)) {
+ if (option->short_name_code) {
+ if (!(__is_bmp_code_point(option->short_name_code))) {
+ options_meta->idx_invalid_short_name = idx;
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ }
+
+ if (option->long_name) {
+ if (!(__is_long_option(option->long_name))) {
+ options_meta->idx_invalid_long_name = idx;
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* update the long name hash (unconditionally) */
+ option->long_name_hash =
+ __compute_crc32_utf16_str(
+ crc32_table,
+ option->long_name);
+ }
+
+ idx++;
+ option++;
+ }
+
+ /* book keeping */
+ idx_max = idx;
+
+ /* step 2: validate argv[] */
+ parg = argv[0];
+ idx_arg = 0;
+
+ while ((parg) && (!(__is_last_option_argument(parg)))) {
+ if (__is_short_option(parg)) {
+ idx = 0;
+ idx_option = 0;
+
+ while ((idx < idx_max) && (!idx_option)) {
+ option = options[idx];
+
+ if (*(parg+1) == option->short_name_code)
+ idx_option = idx;
+ else
+ idx++;
+ }
+
+ if (idx == idx_max) {
+ options_meta->idx_invalid_argument = idx_arg;
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
+ /* get ready for the next element (or value) */
+ parg++;
+ idx_arg++;
+ pvalue = parg;
+ }
+ } else if (__is_long_option(parg)) {
+ idx = 0;
+ idx_option = 0;
+ /* find the equal sign or null termination */
+ pvalue = parg;
+ while ((*pvalue) && (*pvalue != EQUAL_SIGN))
+ pvalue++;
+
+ while ((idx < idx_max) && (!idx_option)) {
+ option = options[idx];
+ crc32 = __compute_crc32_long_option_name(
+ crc32_table,
+ parg,
+ pvalue);
+
+ if (crc32 == option->long_name_hash)
+ idx_option = idx;
+ else
+ idx++;
+ }
+
+ if (idx == idx_max) {
+ options_meta->idx_invalid_argument = idx_arg;
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
+ if (*pvalue != EQUAL_SIGN)
+ /* skip the equal sign */
+ pvalue++;
+ pvalue = (wchar16_t *)0;
+ }
+ }
+
+ /* validate the occurrence */
+ if (idx_option) {
+ if (option->flags && NT_OPTION_ALLOWED_ONCE) {
+ if (option->option_count) {
+ options_meta->idx_invalid_argument
+ = idx_arg;
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
+ option->option_count++;
+ }
+ }
+
+ if (option->flags && NT_OPTION_VALUE_REQUIRED) {
+ if ((!(*pvalue)) || (*pvalue == HYPHEN)) {
+ options_meta->idx_missing_option_value
+ = idx_arg;
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
+ option->value = pvalue;
+ option->value_hash =
+ __compute_crc32_utf16_str(
+ crc32_table,
+ option->value);
+ }
+ }
+ }
+
+ parg++;
+ idx_arg++;
+ }
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/blitter/ntapi_blt_alloc.c b/src/blitter/ntapi_blt_alloc.c
new file mode 100644
index 0000000..4ba6f2c
--- /dev/null
+++ b/src/blitter/ntapi_blt_alloc.c
@@ -0,0 +1,149 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_blitter.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_atomic.h>
+#include "ntapi_blitter.h"
+#include "ntapi_impl.h"
+
+static int __blt_popcount(uintptr_t mask)
+{
+ /* todo: check cpuid, use at_popcount */
+ int i,ret;
+
+ for (i=0,ret=0; i<8*sizeof(uintptr_t); i++)
+ if (mask & ((uintptr_t)1<<i))
+ ret++;
+
+ return ret;
+}
+
+
+int32_t __fastcall __ntapi_blt_alloc(
+ __out nt_blitter ** blitter,
+ __in nt_blitter_params * params)
+{
+ int32_t status;
+ nt_blitter * blt_ctx;
+ size_t blt_ctx_size;
+ size_t params_size;
+ size_t ptrs,i;
+
+ /* alignment */
+ if ((params->block_size % sizeof(uintptr_t)) || (params->block_count % sizeof(uintptr_t)))
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* blt control block allocation */
+ ptrs = params->block_count / (8 * sizeof(uintptr_t));
+ blt_ctx = (nt_blitter *)0;
+ blt_ctx_size = (size_t)&((nt_blitter *)0)->bits;
+
+ /* user-provided bitmap? */
+ if (!params->bitmap)
+ blt_ctx_size += ptrs * sizeof(uintptr_t);
+
+ /* alloc */
+ status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&blt_ctx,
+ 0,
+ &blt_ctx_size,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (status) return (status);
+
+ /* init control block */
+ __ntapi->tt_aligned_block_memset(
+ blt_ctx,
+ 0,(size_t)&((nt_blitter *)0)->bits);
+
+ blt_ctx->addr = blt_ctx;
+ blt_ctx->size = blt_ctx_size;
+ blt_ctx->ptrs = ptrs;
+
+ /* init bitmap */
+ blt_ctx->bitmap = params->bitmap
+ ? (uintptr_t *)params->bitmap
+ : blt_ctx->bits;
+
+ if (!(params->flags & NT_BLITTER_PRESERVE_BITS))
+ __ntapi->tt_aligned_block_memset(
+ blt_ctx->bitmap,
+ (intptr_t)0xFFFFFFFFFFFFFFFF,
+ ptrs * sizeof(uintptr_t));
+
+ /* info structure */
+ blt_ctx->info.info_size = sizeof(nt_blitter_info);
+ blt_ctx->info.block_count = params->block_count;
+ blt_ctx->info.block_size = params->block_size;
+
+ if (params->flags & NT_BLITTER_ENABLE_BLOCK_ARRAY)
+ /* allocate in place */
+ blt_ctx->info.region_size = params->block_count * params->block_size;
+ else
+ /* use pointer array */
+ blt_ctx->info.region_size = params->block_count * sizeof(uintptr_t);
+
+ /* allocate region */
+ if (params->region)
+ blt_ctx->info.region_addr = params->region;
+ else
+ status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &blt_ctx->info.region_addr,
+ 0,
+ &blt_ctx->info.region_size,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (status) {
+ __ntapi->blt_free(blt_ctx);
+ return status;
+ }
+
+ if (params->flags & NT_BLITTER_PRESERVE_BITS)
+ for (i=0,blt_ctx->info.blocks_avail=0; i<ptrs; i++)
+ blt_ctx->info.blocks_avail += __blt_popcount(blt_ctx->bitmap[i]);
+ else
+ blt_ctx->info.blocks_avail = params->block_count;
+
+ if (params->flags & NT_BLITTER_ENABLE_BLOCK_ARRAY)
+ blt_ctx->info.blocks_cached = params->block_count;
+
+ /* init block array */
+ if (!params->region)
+ __ntapi->tt_aligned_block_memset(
+ blt_ctx->info.region_addr,
+ 0,blt_ctx->info.region_size);
+
+ /* copy params */
+ if (params->params_size < sizeof(nt_blitter_params))
+ params_size = params->params_size;
+ else
+ params_size = sizeof(nt_blitter_params);
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)&blt_ctx->params,
+ (uintptr_t *)params,
+ params_size);
+
+ /* update params */
+ blt_ctx->params.lock_tries = params->lock_tries
+ ? params->lock_tries
+ : __NT_BLITTER_DEFAULT_LOCK_TRIES;
+
+ blt_ctx->params.round_trips = params->round_trips
+ ? params->round_trips
+ : __NT_BLITTER_DEFAULT_ROUND_TRIPS;
+
+ *blitter = blt_ctx;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/blitter/ntapi_blt_block.c b/src/blitter/ntapi_blt_block.c
new file mode 100644
index 0000000..879eb1b
--- /dev/null
+++ b/src/blitter/ntapi_blt_block.c
@@ -0,0 +1,204 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_blitter.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_atomic.h>
+#include "ntapi_blitter.h"
+#include "ntapi_impl.h"
+
+static int32_t __fastcall __blt_bitbite(
+ __in nt_blitter * blitter,
+ __in unsigned int bit,
+ __in size_t byte)
+{
+ uint32_t locktry;
+ uintptr_t test;
+ uintptr_t cmp;
+ uintptr_t xchg;
+ uintptr_t mask;
+
+ mask = ((uintptr_t)1 << bit);
+ locktry = blitter->params.lock_tries;
+
+ for (; locktry; locktry--) {
+ cmp = blitter->bitmap[byte] | mask;
+ xchg = cmp ^ mask;
+
+ test = at_locked_cas(
+ (intptr_t *)&blitter->bitmap[byte],
+ cmp,xchg);
+
+ if (test == cmp) {
+ at_locked_dec(&blitter->info.blocks_avail);
+ at_locked_inc(&blitter->info.blocks_used);
+ return NT_STATUS_SUCCESS;
+
+ } else if (test ^ mask)
+ return NT_STATUS_TRANSACTIONAL_CONFLICT;
+ }
+
+ if (!locktry) {
+ blitter->info.busy = 1;
+ blitter->info.lock_tries = blitter->params.lock_tries;
+ return NT_STATUS_DEVICE_BUSY;
+ }
+
+ return NT_STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static int32_t __fastcall __blt_acquire(
+ __in nt_blitter * blitter,
+ __out intptr_t * blkid)
+{
+ unsigned int bit;
+ uintptr_t i,n;
+
+ if (blitter->info.blocks_avail == 0)
+ return NT_STATUS_ALLOCATE_BUCKET;
+
+ for (n=0,bit=0; blitter->info.blocks_avail && (n < blitter->params.round_trips); n++) {
+ for (i=*blkid/(8*sizeof(size_t)); (i<blitter->ptrs); i++)
+ if (at_bsf(&bit,blitter->bitmap[i]))
+ break;
+
+ if (i == blitter->ptrs)
+ return NT_STATUS_ALLOCATE_BUCKET;
+
+ switch (__blt_bitbite(blitter,bit,i)) {
+ case NT_STATUS_SUCCESS:
+ *blkid = bit + (i * 8 * sizeof(size_t));
+ return NT_STATUS_SUCCESS;
+
+ case NT_STATUS_DEVICE_BUSY:
+ return NT_STATUS_DEVICE_BUSY;
+
+ default:
+ break;
+ }
+ }
+
+ return NT_STATUS_ALLOCATE_BUCKET;
+}
+
+
+int32_t __fastcall __ntapi_blt_obtain(
+ __in nt_blitter * blitter,
+ __out intptr_t * blkid)
+{
+ unsigned int bit;
+ uintptr_t i,n;
+ uintptr_t mask;
+
+ if (blitter->info.blocks_avail == 0)
+ return NT_STATUS_ALLOCATE_BUCKET;
+ else if ((bit = *blkid % sizeof(size_t)) == 0)
+ return __ntapi_blt_acquire(blitter,blkid);
+
+ for (n=0,mask=(uintptr_t)-1; n<bit; n++)
+ mask ^= ((size_t)1 << n);
+
+ i = *blkid / (8*sizeof(size_t));
+
+ for (n=0; blitter->info.blocks_avail && (n < blitter->params.round_trips); n++) {
+ if (!(at_bsf(&bit,(mask & blitter->bitmap[i]))))
+ break;
+
+ switch (__blt_bitbite(blitter,bit,i)) {
+ case NT_STATUS_SUCCESS:
+ *blkid = bit + (i * 8 * sizeof(size_t));
+ return NT_STATUS_SUCCESS;
+
+ case NT_STATUS_DEVICE_BUSY:
+ return NT_STATUS_DEVICE_BUSY;
+
+ default:
+ break;
+ }
+ }
+
+ *blkid = ++i * 8 * sizeof(size_t);
+ return __blt_acquire(blitter,blkid);
+}
+
+
+int32_t __fastcall __ntapi_blt_possess(
+ __in nt_blitter * blitter,
+ __out intptr_t * blkid)
+{
+ int bit;
+ size_t byte;
+ uintptr_t test;
+ uintptr_t mask;
+
+ bit = *blkid % (8*sizeof(size_t));
+ byte = *blkid / (8*sizeof(size_t));
+
+ mask = ((uintptr_t)1 << bit);
+ test = at_locked_and(
+ (intptr_t *)&blitter->bitmap[byte],
+ ~mask);
+
+ if (test & mask) {
+ at_locked_dec(&blitter->info.blocks_avail);
+ at_locked_inc(&blitter->info.blocks_used);
+ }
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __fastcall __ntapi_blt_acquire(
+ __in nt_blitter * blitter,
+ __out intptr_t * blkid)
+{
+ *blkid = 0;
+ return __blt_acquire(blitter,blkid);
+}
+
+
+int32_t __fastcall __ntapi_blt_release(
+ __in nt_blitter * blitter,
+ __out intptr_t blkid)
+{
+ size_t i;
+ unsigned int idx;
+ uintptr_t bit;
+
+ i = blkid / (8 * sizeof(uintptr_t));
+ idx = blkid % (8 * sizeof(uintptr_t));
+ bit = ((uintptr_t)1 << idx);
+
+ at_locked_or((intptr_t *)&blitter->bitmap[i],bit);
+ at_locked_dec(&blitter->info.blocks_used);
+ at_locked_inc(&blitter->info.blocks_avail);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+void * __fastcall __ntapi_blt_get(
+ __in const nt_blitter * blitter,
+ __in intptr_t block_id)
+{
+ size_t * addr = (size_t *)blitter->info.region_addr;
+ addr += block_id;
+ return addr;
+}
+
+
+void __fastcall __ntapi_blt_set(
+ __in const nt_blitter * blitter,
+ __in intptr_t block_id,
+ __in void * val)
+{
+ size_t * addr = (size_t *)blitter->info.region_addr;
+ addr += block_id;
+ *addr = (size_t)val;
+ return;
+}
diff --git a/src/blitter/ntapi_blt_free.c b/src/blitter/ntapi_blt_free.c
new file mode 100644
index 0000000..a5956b1
--- /dev/null
+++ b/src/blitter/ntapi_blt_free.c
@@ -0,0 +1,48 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_blitter.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_blitter.h"
+#include "ntapi_impl.h"
+
+int32_t __fastcall __ntapi_blt_free(nt_blitter * blt_ctx)
+{
+ int32_t status;
+ void * region_addr;
+ size_t region_size;
+
+ /* validation */
+ if (!blt_ctx) return NT_STATUS_INVALID_PARAMETER;
+
+ /* free blt block */
+ region_addr = blt_ctx->info.region_addr;
+ region_size = blt_ctx->info.region_size;
+
+ if (region_size && !blt_ctx->params.region) {
+ status = __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &region_addr,
+ &region_size,
+ NT_MEM_RELEASE);
+
+ if (status) return status;
+ }
+
+ /* free blt control block */
+ region_addr = blt_ctx->addr;
+ region_size = blt_ctx->size;
+
+ status = __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &region_addr,
+ &region_size,
+ NT_MEM_RELEASE);
+
+ return status;
+}
diff --git a/src/daemon/ntapi_dsr_init.c b/src/daemon/ntapi_dsr_init.c
new file mode 100644
index 0000000..889de6b
--- /dev/null
+++ b/src/daemon/ntapi_dsr_init.c
@@ -0,0 +1,189 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_port.h>
+#include <ntapi/nt_daemon.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+static void __stdcall __ntapi_dsr_once(nt_daemon_params * params);
+
+int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params)
+{
+ int32_t status;
+
+ nt_thread_params tparams;
+ nt_large_integer timeout;
+
+ /* port_keys */
+ if (params->flags & NT_DSR_INIT_GENERATE_KEYS)
+ if ((status = __ntapi->tt_port_generate_keys(params->port_keys)))
+ return status;
+
+ /* port_name_keys */
+ if (params->flags & NT_DSR_INIT_FORMAT_KEYS)
+ __ntapi->tt_port_format_keys(
+ params->port_keys,
+ params->port_name_keys);
+
+ /* 'daemon-is-ready' event */
+ if (!params->hevent_daemon_ready) {
+ if ((status = __ntapi->tt_create_private_event(
+ &params->hevent_daemon_ready,
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED)))
+ return status;
+
+ if (params->pevent_daemon_ready)
+ *(params->pevent_daemon_ready) = params->hevent_daemon_ready;
+ }
+
+ /* 'internal-client-is-ready' event */
+ if (!params->hevent_internal_client_ready) {
+ if ((status = __ntapi->tt_create_inheritable_event(
+ &params->hevent_internal_client_ready,
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED)))
+ return status;
+
+ if (params->pevent_internal_client_ready)
+ *(params->pevent_internal_client_ready) = params->hevent_internal_client_ready;
+ }
+
+ /* daemon dedicated thread: general parameters */
+ __ntapi->tt_aligned_block_memset(
+ &tparams,0,sizeof(tparams));
+
+ tparams.start = (nt_thread_start_routine *)__ntapi_dsr_start;
+ tparams.arg = params;
+
+ /* daemon dedicated thread: stack parameters (optional) */
+ tparams.stack_size_commit = params->stack_size_commit;
+ tparams.stack_size_reserve = params->stack_size_reserve;
+ tparams.stack_info = params->stack_info;
+
+ /* daemon dedicated thread: create */
+ status = __ntapi->tt_create_local_thread(&tparams);
+ params->hthread_daemon_loop = tparams.hthread;
+ if (status) return status;
+
+ /* daemon dedicated thread: actual stack size */
+ params->stack_size_commit = tparams.stack_size_commit;
+ params->stack_size_reserve = tparams.stack_size_reserve;
+
+
+ /* establish internal connection */
+ __ntapi->tt_aligned_block_memset(
+ &tparams,0,sizeof(tparams));
+
+ tparams.start = (nt_thread_start_routine *)__ntapi_dsr_internal_client_connect;
+ tparams.arg = params;
+
+ status = __ntapi->tt_create_local_thread(&tparams);
+ params->hthread_internal_client = tparams.hthread;
+ if (status) return status;
+
+ /* wait until the internal connection had been established */
+ timeout.quad = NT_DSR_INIT_MAX_WAIT;
+
+ status = __ntapi->zw_wait_for_single_object(
+ params->hevent_internal_client_ready,
+ 0,
+ &timeout);
+
+ if (params->flags & NT_DSR_INIT_CLOSE_EVENTS) {
+ __ntapi->zw_close(params->hevent_daemon_ready);
+ __ntapi->zw_close(params->hevent_internal_client_ready);
+ }
+
+ return status;
+}
+
+
+/* __ntapi_dsr_start executes in the daemon's dedicated thread */
+int32_t __stdcall __ntapi_dsr_start(nt_daemon_params * params)
+{
+ __ntapi_dsr_once(params);
+ __ntapi_dsr_create_port(params);
+ __ntapi_dsr_connect_internal_client(params);
+ params->daemon_loop_routine(params->daemon_loop_context);
+
+ /* (no return) */
+ return NT_STATUS_INTERNAL_ERROR;
+}
+
+/* __ntapi_dsr_once executes in the daemon's dedicated thread */
+static void __stdcall __ntapi_dsr_once(nt_daemon_params * params)
+{
+ int32_t status;
+
+ if (!params->daemon_once_routine)
+ return;
+
+ if ((status = params->daemon_once_routine(params->daemon_loop_context))) {
+ params->exit_code_daemon_start = status;
+ __ntapi->zw_terminate_thread(NT_CURRENT_THREAD_HANDLE,status);
+ }
+}
+
+/* __ntapi_dsr_create_port executes in the daemon's dedicated thread */
+int32_t __stdcall __ntapi_dsr_create_port(nt_daemon_params * params)
+{
+ int32_t * pstatus;
+ nt_object_attributes oa;
+ nt_security_quality_of_service sqos;
+ nt_unicode_string server_name;
+
+ pstatus = &params->exit_code_daemon_start;
+
+ /* init server_name */
+ server_name.strlen = (uint16_t)__ntapi->tt_string_null_offset_short((const int16_t *)params->port_name);
+ server_name.maxlen = 0;
+ server_name.buffer = (uint16_t *)params->port_name;
+
+ /* init security structure */
+ sqos.length = sizeof(sqos);
+ sqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ sqos.effective_only = 1;
+
+ /* init the port's object attributes */
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &server_name;
+ oa.obj_attr = 0;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = &sqos;
+
+ /* create the port */
+ *pstatus = __ntapi->zw_create_port(
+ &params->hport_daemon,
+ &oa,0,(uint32_t)params->port_msg_size,
+ 0);
+
+ if (*pstatus != NT_STATUS_SUCCESS)
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ *pstatus);
+
+ /* return port info */
+ if (params->pport_daemon)
+ *(params->pport_daemon) = params->hport_daemon;
+
+ /* signal the daemon-is-ready event */
+ *pstatus = __ntapi->zw_set_event(
+ params->hevent_daemon_ready,
+ (int32_t *)0);
+
+ if (*pstatus != NT_STATUS_SUCCESS)
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ *pstatus);
+
+ return *pstatus;
+}
diff --git a/src/daemon/ntapi_dsr_internal_connection.c b/src/daemon/ntapi_dsr_internal_connection.c
new file mode 100644
index 0000000..7726b3f
--- /dev/null
+++ b/src/daemon/ntapi_dsr_internal_connection.c
@@ -0,0 +1,142 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_port.h>
+#include <ntapi/nt_daemon.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+/* __ntapi_dsr_connect_internal_client executes in the daemon's dedicated thread */
+int32_t __stdcall __ntapi_dsr_connect_internal_client(nt_daemon_params * params)
+{
+ int32_t * pstatus;
+
+ intptr_t port_id;
+ nt_port_message port_msg;
+ nt_large_integer timeout;
+ void * _hport_client;
+
+ pstatus = &params->exit_code_daemon_start;
+
+ /* timeout-enabled first connection */
+ timeout.quad = NT_DSR_INIT_MAX_WAIT;
+
+ *pstatus = __ntapi->zw_reply_wait_receive_port_ex(
+ params->hport_daemon,
+ &port_id,
+ (nt_port_message *)0,
+ (nt_port_message *)&port_msg,
+ &timeout);
+
+ if (*pstatus != NT_STATUS_SUCCESS)
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ *pstatus);
+
+ /* the internal client must be first */
+ if (port_msg.client_id.process_id != pe_get_current_process_id())
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ NT_STATUS_PORT_CONNECTION_REFUSED);
+
+ /* accept connection request */
+ *pstatus = __ntapi->zw_accept_connect_port(
+ &_hport_client,
+ port_msg.client_id.process_id,
+ (nt_port_message *)&port_msg,
+ NT_LPC_ACCEPT_CONNECTION,
+ (nt_port_section_write *)0,
+ (nt_port_section_read *)0);
+
+ if (*pstatus != NT_STATUS_SUCCESS)
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ *pstatus);
+
+ /* finalize connection */
+ *pstatus = __ntapi->zw_complete_connect_port(_hport_client);
+
+ if (*pstatus != NT_STATUS_SUCCESS)
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ *pstatus);
+
+ return *pstatus;
+}
+
+
+/* __ntapi_dsr_internal_client_connect executes in its own temporary thread */
+int32_t __stdcall __ntapi_dsr_internal_client_connect(nt_daemon_params * params)
+{
+ int32_t * pstatus;
+
+ nt_unicode_string server_name;
+ nt_object_attributes oa;
+ nt_security_quality_of_service sqos;
+ nt_large_integer timeout;
+
+ pstatus = &params->exit_code_internal_client;
+
+ /* init server_name */
+ server_name.strlen = (uint16_t)__ntapi->tt_string_null_offset_short((const int16_t *)params->port_name);
+ server_name.maxlen = 0;
+ server_name.buffer = (uint16_t *)params->port_name;
+
+ /* init security structure */
+ sqos.length = sizeof(sqos);
+ sqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ sqos.effective_only = 1;
+
+ /* init the port's object attributes */
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &server_name;
+ oa.obj_attr = 0;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = &sqos;
+
+ /* wait for the server to be ready */
+ timeout.quad = NT_DSR_INIT_MAX_WAIT;
+
+ if ((*pstatus = __ntapi->zw_wait_for_single_object(
+ params->hevent_daemon_ready,
+ 0,&timeout)))
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ *pstatus);
+
+ /* establish internal connection */
+ *pstatus = __ntapi->zw_connect_port(
+ &params->hport_internal_client,
+ &server_name,
+ &sqos,
+ 0,0,0,0,0);
+
+ if (*pstatus != NT_STATUS_SUCCESS)
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ *pstatus);
+
+ /* return port info */
+ if (params->pport_internal_client)
+ *(params->pport_internal_client) = params->hport_internal_client;
+
+ /* signal the 'internal-client-is-ready' event */
+ *pstatus = __ntapi->zw_set_event(
+ params->hevent_internal_client_ready,
+ 0);
+
+ /* exit the task-specific thread */
+ __ntapi->zw_terminate_thread(
+ NT_CURRENT_THREAD_HANDLE,
+ *pstatus);
+
+ /* (no return) */
+ return NT_STATUS_INTERNAL_ERROR;
+}
diff --git a/src/fs/ntapi_tt_get_file_handle_type.c b/src/fs/ntapi_tt_get_file_handle_type.c
new file mode 100644
index 0000000..e1175a5
--- /dev/null
+++ b/src/fs/ntapi_tt_get_file_handle_type.c
@@ -0,0 +1,83 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_file.h>
+#include "ntapi_impl.h"
+
+typedef int __stdcall winapi_get_console_mode(void * handle, uint32_t * mode);
+
+int32_t __stdcall __ntapi_tt_get_file_handle_type(
+ __in void * handle,
+ __out int32_t * type)
+{
+ int32_t status;
+ uint32_t info;
+ nt_iosb iosb;
+ nt_fsssi fsssi;
+ nt_file_directory_information fdi;
+ nt_file_pipe_information fpi;
+ nt_object_basic_information obi;
+
+ void * hkernel32;
+ char str_get_con_mode[32] = "GetConsoleMode";
+ winapi_get_console_mode * pfn_get_con_mode;
+
+ /* validation */
+ if (!handle) return NT_STATUS_INVALID_HANDLE;
+
+ /* file-system directory? */
+ if (!(status = __ntapi->zw_query_information_file(
+ handle,
+ &iosb,&fdi,sizeof(fdi),
+ NT_FILE_DIRECTORY_INFORMATION))) {
+ *type = NT_FILE_TYPE_DIRECTORY;
+ return 0;
+ }
+
+ /* file-system file? */
+ if (!(status = __ntapi->zw_query_volume_information_file(
+ handle,
+ &iosb,&fsssi,sizeof(fsssi),
+ NT_FILE_FS_SECTOR_SIZE_INFORMATION))) {
+ *type = NT_FILE_TYPE_FILE;
+ return 0;
+ }
+
+ /* pipe? */
+ if (!(status = __ntapi->zw_query_information_file(
+ handle,
+ &iosb,&fpi,sizeof(fpi),
+ NT_FILE_PIPE_INFORMATION))) {
+ *type = NT_FILE_TYPE_PIPE;
+ return 0;
+ }
+
+
+ /* csrss? */
+ if (!(hkernel32 = pe_get_kernel32_module_handle()))
+ return NT_STATUS_DLL_INIT_FAILED;
+ else if (!(pfn_get_con_mode = (winapi_get_console_mode *)pe_get_procedure_address(
+ hkernel32,str_get_con_mode)))
+ return NT_STATUS_DLL_INIT_FAILED;
+
+
+ /* (console functions return non-zero on success) */
+ if ((pfn_get_con_mode(handle,&info))) {
+ *type = NT_FILE_TYPE_CSRSS;
+ return 0;
+ }
+
+ /* invalid handle? */
+ if ((status = __ntapi->zw_query_object(
+ handle,NT_OBJECT_BASIC_INFORMATION,
+ &obi,sizeof(obi),&info)))
+ return status;
+
+ /* unknown object */
+ *type = NT_FILE_TYPE_UNKNOWN;
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/fs/ntapi_tt_istat.c b/src/fs/ntapi_tt_istat.c
new file mode 100644
index 0000000..bd2029d
--- /dev/null
+++ b/src/fs/ntapi_tt_istat.c
@@ -0,0 +1,155 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_fsctl.h>
+#include <ntapi/nt_mount.h>
+#include <ntapi/nt_istat.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_istat(
+ __in void * hfile,
+ __in void * hroot __optional,
+ __in nt_unicode_string * path,
+ __out nt_istat * istat,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t open_options,
+ __in uint32_t flags)
+{
+ int32_t status;
+
+ nt_oa oa;
+ nt_iosb iosb;
+ nt_unicode_string * sdev;
+ uint32_t hash;
+ wchar16_t * wch;
+ wchar16_t * wch_mark;
+
+ /* validaton */
+ if (!hfile && !path)
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* hfile */
+ if (!hfile) {
+ /* oa */
+ oa.len = sizeof(nt_oa);
+ oa.root_dir = hroot;
+ oa.obj_name = path;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = 0;
+
+ /* open file/folder */
+ status = __ntapi->zw_open_file(
+ &hfile,
+ NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_ACCESS,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ open_options | NT_FILE_SYNCHRONOUS_IO_ALERT);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ istat->flags_out = NT_STAT_NEW_HANDLE;
+ }
+
+ istat->hfile = hfile;
+ istat->flags_in = flags;
+
+ /* file index number */
+ status = __ntapi->zw_query_information_file(
+ hfile,
+ &iosb,
+ &istat->fii,
+ sizeof(istat->fii),
+ NT_FILE_INTERNAL_INFORMATION);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* attributes & reparse tag information */
+ status = __ntapi->zw_query_information_file(
+ hfile,
+ &iosb,
+ &istat->ftagi,
+ sizeof(istat->ftagi),
+ NT_FILE_ATTRIBUTE_TAG_INFORMATION);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* TODO: consolidate with statfs */
+ /* system-unique device name */
+ iosb.info = 0;
+ status = __ntapi->zw_query_object(
+ hfile,
+ NT_OBJECT_NAME_INFORMATION,
+ buffer,
+ buffer_size,
+ (uint32_t *)&iosb.info);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ sdev = (nt_unicode_string *)buffer;
+
+ if (sdev->strlen < __DEVICE_PATH_PREFIX_LEN)
+ return NT_STATUS_INVALID_HANDLE;
+
+ hash = __ntapi->tt_buffer_crc32(
+ 0,
+ sdev->buffer,
+ __DEVICE_PATH_PREFIX_LEN);
+
+ if (hash != __DEVICE_PATH_PREFIX_HASH)
+ return NT_STATUS_INVALID_HANDLE;
+
+ wch_mark = sdev->buffer + __DEVICE_PATH_PREFIX_LEN/sizeof(wchar16_t);
+ wch = wch_mark;
+ while (*wch != '\\') wch++;
+ istat->dev_name_strlen = (uint16_t)((wch - sdev->buffer) * sizeof(uint16_t));
+
+ istat->dev_name_hash = __ntapi->tt_buffer_crc32(
+ hash,
+ wch_mark,
+ (uintptr_t)wch - (uintptr_t)wch_mark);
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_validate_fs_handle(
+ __in void * hfile,
+ __in uint32_t dev_name_hash,
+ __in nt_fii fii,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size)
+{
+ int32_t status;
+ nt_istat istat;
+
+ status = __ntapi->tt_istat(
+ hfile,
+ (void *)0,
+ (nt_unicode_string *)0,
+ &istat,
+ buffer,
+ buffer_size,
+ 0,
+ NT_ISTAT_DEFAULT);
+
+ if (status) return status;
+
+ if (istat.fii.index_number.quad != fii.index_number.quad)
+ return NT_STATUS_CONTEXT_MISMATCH;
+ else if (istat.dev_name_hash != dev_name_hash)
+ return NT_STATUS_CONTEXT_MISMATCH;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/fs/ntapi_tt_mount.c b/src/fs/ntapi_tt_mount.c
new file mode 100644
index 0000000..1718750
--- /dev/null
+++ b/src/fs/ntapi_tt_mount.c
@@ -0,0 +1,358 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_mount.h>
+#include <ntapi/nt_atomic.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef enum __dos_drive_handle_type {
+ __DOS_DRIVE_DEVICE_HANDLE,
+ __DOS_DRIVE_ROOT_HANDLE
+} _dos_drive_handle_type;
+
+typedef struct __dos_name_buffer {
+ wchar16_t global_prefix[4];
+ wchar16_t dos_letter;
+ wchar16_t colon;
+ wchar16_t root;
+ wchar16_t null_termination;
+} _dos_name_buffer;
+
+
+static int32_t __stdcall __tt_connect_to_mount_point_manager(void)
+{
+ int32_t status;
+
+ void * hdev;
+ void * hdev_prev;
+ nt_oa oa;
+ nt_iosb iosb;
+ nt_unicode_string dev_name;
+ uint16_t dev_name_buffer[] = {
+ '\\','?','?','\\',
+ 'M','o','u','n','t',
+ 'P','o','i','n','t',
+ 'M','a','n','a','g','e','r',0};
+
+ dev_name.strlen = sizeof(wchar16_t) * (4+5+5+7);
+ dev_name.maxlen = 0;
+ dev_name.buffer = dev_name_buffer;
+
+ oa.len = sizeof(nt_oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &dev_name;
+ oa.obj_attr = NT_OBJ_CASE_INSENSITIVE;
+ oa.sec_desc = (nt_sd *)0;
+ oa.sec_qos = (nt_sqos *)0;
+
+ status = __ntapi->zw_create_file(
+ &hdev,
+ NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES,
+ &oa,
+ &iosb,
+ 0,
+ NT_FILE_ATTRIBUTE_NORMAL,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_OPEN,
+ NT_FILE_NON_DIRECTORY_FILE | NT_FILE_SYNCHRONOUS_IO_NONALERT,
+ (void *)0,
+ 0);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ hdev_prev = (void *)at_locked_cas(
+ (intptr_t *)&__ntapi_internals()->hdev_mount_point_mgr,
+ 0,(intptr_t)hdev);
+
+ if (hdev_prev)
+ __ntapi->zw_close(hdev);
+
+ return status;
+}
+
+
+static int32_t __stdcall __tt_get_dos_drive_device_or_root_handle(
+ __out void ** hdrive,
+ __in wchar16_t * drive_letter,
+ __in _dos_drive_handle_type handle_type)
+{
+ #define __common_mode (NT_FILE_SYNCHRONOUS_IO_ALERT)
+ #define __common_access (NT_SEC_SYNCHRONIZE \
+ | NT_FILE_READ_ATTRIBUTES)
+
+ int32_t status;
+
+ nt_oa oa;
+ nt_iosb iosb;
+ uint32_t open_flags;
+ uint32_t access_flags;
+ nt_unicode_string dos_name;
+ _dos_name_buffer dos_name_buffer = {
+ {'\\','?','?','\\'},
+ '_',':',0,0};
+
+ if (!hdrive || !drive_letter)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if ((*drive_letter>='A') && (*drive_letter<='Z'))
+ dos_name_buffer.dos_letter = *drive_letter;
+ else if ((*drive_letter>='a') && (*drive_letter<='z'))
+ dos_name_buffer.dos_letter = *drive_letter + 'A' - 'a';
+ else
+ return NT_STATUS_INVALID_PARAMETER_2;
+
+ dos_name.strlen = ((size_t)(&((_dos_name_buffer *)0)->root));
+ dos_name.maxlen = 0;
+ dos_name.buffer = &(dos_name_buffer.global_prefix[0]);
+
+ switch (handle_type) {
+ case __DOS_DRIVE_DEVICE_HANDLE:
+ open_flags = __common_mode;
+ access_flags = __common_access;
+ break;
+
+ case __DOS_DRIVE_ROOT_HANDLE:
+ open_flags = __common_mode | NT_FILE_DIRECTORY_FILE;
+ access_flags = __common_access | NT_FILE_READ_ACCESS;
+ dos_name_buffer.root = '\\';
+ dos_name.strlen += sizeof(wchar16_t);
+ break;
+ default:
+ open_flags = 0;
+ access_flags = 0;
+ break;
+ }
+
+ oa.len = sizeof(nt_oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &dos_name;
+ oa.obj_attr = NT_OBJ_INHERIT;
+ oa.sec_desc = (nt_sd *)0;
+ oa.sec_qos = (nt_sqos *)0;
+
+ status = __ntapi->zw_open_file(
+ hdrive,
+ access_flags,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ open_flags);
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_get_dos_drive_device_handle(
+ __out void ** hdevice,
+ __in wchar16_t * drive_letter)
+{
+ return __tt_get_dos_drive_device_or_root_handle(
+ hdevice,
+ drive_letter,
+ __DOS_DRIVE_DEVICE_HANDLE);
+}
+
+
+int32_t __stdcall __ntapi_tt_get_dos_drive_root_handle(
+ __out void ** hroot,
+ __in wchar16_t * drive_letter)
+{
+ return __tt_get_dos_drive_device_or_root_handle(
+ hroot,
+ drive_letter,
+ __DOS_DRIVE_ROOT_HANDLE);
+}
+
+
+
+int32_t __stdcall __ntapi_tt_get_dos_drive_device_name(
+ __in void * hdevice __optional,
+ __in wchar16_t * drive_letter __optional,
+ __out nt_mount_dev_name * buffer,
+ __in uint32_t buffer_size)
+{
+ int32_t status;
+ nt_iosb iosb;
+
+ if (!hdevice && (status = __tt_get_dos_drive_device_or_root_handle(
+ &hdevice,
+ drive_letter,
+ __DOS_DRIVE_DEVICE_HANDLE)))
+ return status;
+
+ return __ntapi->zw_device_io_control_file(
+ hdevice,
+ (void *)0,
+ (nt_io_apc_routine *)0,
+ (void *)0,
+ &iosb,
+ NT_IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
+ (void *)0,
+ 0,
+ buffer,
+ buffer_size);
+}
+
+
+int32_t __stdcall __ntapi_tt_get_dos_drive_mount_points(
+ __in void * hdevice __optional,
+ __in wchar16_t * drive_letter __optional,
+ __in nt_mount_dev_name * dev_name __optional,
+ __out void * buffer,
+ __in uint32_t buffer_size)
+{
+ int32_t status;
+ nt_iosb iosb;
+ wchar16_t dev_name_buffer[64];
+ nt_mount_point_param * dev_mount_point;
+ nt_mount_points * dev_mount_points;
+ uintptr_t addr;
+
+ if (!dev_name) {
+ dev_name = (nt_mount_dev_name *)&dev_name_buffer;
+ if ((status = __ntapi_tt_get_dos_drive_device_name(
+ hdevice,
+ drive_letter,
+ dev_name,
+ sizeof(dev_name_buffer))))
+ return status;
+ }
+
+ if (buffer_size < sizeof(nt_mount_mgr_mount_point) \
+ + sizeof(nt_mount_dev_name) \
+ + sizeof(dev_name->name_length))
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ dev_mount_point = (nt_mount_point_param *)buffer;
+ dev_mount_point->symlink_name_offset = 0;
+ dev_mount_point->symlink_name_length = 0;
+ dev_mount_point->unique_id_offset = 0;
+ dev_mount_point->unique_id_length = 0;
+ dev_mount_point->device_name_offset = ((size_t)(&((nt_mount_point_param *)0)->device_name));
+ dev_mount_point->device_name_length = dev_name->name_length;
+ dev_mount_point->mount_points_offset = 0;
+
+ __ntapi->tt_memcpy_utf16(
+ dev_mount_point->device_name,
+ dev_name->name,
+ dev_name->name_length);
+
+ addr = (uintptr_t)(dev_mount_point->device_name) + dev_name->name_length;
+ addr += sizeof(uintptr_t) - 1;
+ addr /= sizeof(uintptr_t);
+ addr *= sizeof(uintptr_t);
+ dev_mount_points = (nt_mount_points *)addr;
+
+
+ if (!__ntapi_internals()->hdev_mount_point_mgr)
+ status = __tt_connect_to_mount_point_manager();
+
+ if (!__ntapi_internals()->hdev_mount_point_mgr)
+ return status;
+
+
+ status = __ntapi->zw_device_io_control_file(
+ __ntapi_internals()->hdev_mount_point_mgr,
+ (void *)0,
+ (nt_io_apc_routine *)0,
+ (void *)0,
+ &iosb,
+ NT_IOCTL_MOUNTMGR_QUERY_POINTS,
+ dev_mount_point,
+ (uint32_t)(uintptr_t)&(((nt_mount_point_param *)0)->device_name) + dev_name->name_length,
+ dev_mount_points,
+ (uint32_t)((uintptr_t)buffer + buffer_size - addr));
+
+ dev_mount_point->mount_points_offset = (uint16_t)((uintptr_t)addr - (uintptr_t)buffer);
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_dev_mount_points_to_statfs(
+ __in nt_mount_points * mount_points,
+ __in_out nt_statfs * statfs)
+{
+ int32_t status;
+ uint32_t hash;
+ uint32_t i;
+
+ nt_mount_mgr_mount_point * mount_point;
+ char * symlink;
+
+ mount_point = mount_points->mount_points;
+ statfs->nt_drive_letter = 0;
+
+
+ for (i = 0; i < mount_points->number; i++, mount_point++) {
+ symlink = (char *)mount_points + mount_point->symlink_name_offset;
+
+ /* both prefixes of interest happen to be of the same length */
+ hash = __ntapi->tt_buffer_crc32(
+ 0, symlink, __DOS_DEVICES_PREFIX_LEN);
+
+ if (hash == __DOS_DEVICES_PREFIX_HASH)
+ statfs->nt_drive_letter = ((nt_dos_devices_name *)(symlink))->letter;
+ else if (hash == __VOLUME_PATH_PREFIX_HASH) {
+ status = __ntapi_tt_utf16_string_to_guid(
+ (nt_guid_str_utf16 *)(symlink \
+ + __VOLUME_PATH_PREFIX_LEN \
+ - sizeof(wchar16_t)),
+ &statfs->nt_volume_guid);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t __stdcall __ntapi_tt_get_dos_drive_letter_from_device(
+ __in void * hdevice __optional,
+ __out wchar16_t * drive_letter,
+ __in nt_mount_dev_name * dev_name __optional,
+ __out void * buffer,
+ __in uint32_t buffer_size)
+{
+ int32_t status;
+ wchar16_t dev_name_buffer[128];
+ nt_statfs statfs;
+ uint32_t offset;
+ nt_mount_points * mnt_points;
+
+ if (!dev_name) {
+ dev_name = (nt_mount_dev_name *)&dev_name_buffer;
+ status = __ntapi_tt_get_dos_drive_device_name(
+ hdevice,
+ (wchar16_t *)0,
+ dev_name,
+ sizeof(dev_name_buffer));
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+ }
+
+
+ offset = ((nt_mount_point_param *)buffer)->mount_points_offset;
+ mnt_points = (nt_mount_points *)((uintptr_t)buffer + offset);
+
+ status = __ntapi_tt_dev_mount_points_to_statfs(
+ mnt_points,
+ &statfs);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ *drive_letter = statfs.nt_drive_letter;
+
+ return status;
+}
diff --git a/src/fs/ntapi_tt_open_logical_parent_directory.c b/src/fs/ntapi_tt_open_logical_parent_directory.c
new file mode 100644
index 0000000..c20d05b
--- /dev/null
+++ b/src/fs/ntapi_tt_open_logical_parent_directory.c
@@ -0,0 +1,21 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_file.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_open_logical_parent_directory(
+ __out void ** hparent,
+ __in void * hdir,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t desired_access,
+ __in uint32_t open_options,
+ __out int32_t * type)
+{
+ return NT_STATUS_MORE_PROCESSING_REQUIRED;
+}
diff --git a/src/fs/ntapi_tt_open_physical_parent_directory.c b/src/fs/ntapi_tt_open_physical_parent_directory.c
new file mode 100644
index 0000000..68d282b
--- /dev/null
+++ b/src/fs/ntapi_tt_open_physical_parent_directory.c
@@ -0,0 +1,69 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_file.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_open_physical_parent_directory(
+ __out void ** hparent,
+ __in void * hdir,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t desired_access,
+ __in uint32_t open_options,
+ __out int32_t * type)
+{
+ int32_t status;
+ nt_oa oa;
+ nt_iosb iosb;
+ wchar16_t * wch;
+ nt_unicode_string * path;
+ uint32_t len;
+
+ path = (nt_unicode_string *)buffer;
+
+ if ((status = __ntapi->zw_query_object(
+ hdir,
+ NT_OBJECT_NAME_INFORMATION,
+ path,
+ buffer_size,
+ &len)))
+ return status;
+ else if (len == sizeof(nt_unicode_string))
+ return NT_STATUS_BAD_FILE_TYPE;
+
+ wch = path->buffer + (path->strlen / sizeof(uint16_t));
+ while ((--wch >= path->buffer) && (*wch != '\\'));
+
+ if (wch == path->buffer )
+ return NT_STATUS_MORE_PROCESSING_REQUIRED;
+
+ path->strlen = sizeof(uint16_t) * (uint16_t)(wch-path->buffer);
+ path->maxlen = 0;
+
+ /* oa */
+ oa.len = sizeof(nt_oa);
+ oa.root_dir = 0;
+ oa.obj_name = path;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = 0;
+
+ /* default access */
+ desired_access = desired_access
+ ? desired_access
+ : NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_ACCESS;
+
+ /* open parent directory */
+ return __ntapi->zw_open_file(
+ hparent,
+ desired_access,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ open_options | NT_FILE_DIRECTORY_FILE);
+}
diff --git a/src/fs/ntapi_tt_stat.c b/src/fs/ntapi_tt_stat.c
new file mode 100644
index 0000000..51cc55a
--- /dev/null
+++ b/src/fs/ntapi_tt_stat.c
@@ -0,0 +1,129 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_fsctl.h>
+#include <ntapi/nt_mount.h>
+#include <ntapi/nt_stat.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_stat(
+ __in void * hfile,
+ __in void * hroot __optional,
+ __in nt_unicode_string * path,
+ __out nt_stat * stat,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t open_options,
+ __in uint32_t flags)
+{
+ int32_t status;
+ nt_oa oa;
+ nt_iosb iosb;
+ nt_unicode_string * sdev;
+ nt_fai * fai;
+
+ /* validation */
+ if (!hfile && !path)
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* hfile */
+ if (!hfile) {
+ /* oa */
+ oa.len = sizeof(nt_oa);
+ oa.root_dir = hroot;
+ oa.obj_name = path;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = 0;
+
+ /* open file/folder */
+ status = __ntapi->zw_open_file(
+ &hfile,
+ NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_ACCESS,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ open_options | NT_FILE_SYNCHRONOUS_IO_ALERT);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ stat->flags_out = NT_STAT_NEW_HANDLE;
+ }
+
+ stat->hfile = hfile;
+ stat->flags_in = flags;
+
+ /* system-unique device name */
+ status = __ntapi->zw_query_information_file(
+ hfile,
+ &iosb,
+ buffer,
+ buffer_size,
+ NT_FILE_ALL_INFORMATION);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* copy file info minus name */
+ fai = (nt_fai *)buffer;
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)stat,
+ (uintptr_t *)fai,
+ ((size_t)(&((nt_fai *)0)->name_info)));
+
+ /* record the file name length, but do not hash */
+ stat->file_name_length = fai->name_info.file_name_length;
+ stat->file_name_hash = 0;
+
+
+ /* file system size information */
+ status = __ntapi->zw_query_volume_information_file(
+ hfile,
+ &iosb,
+ &(stat->fssi),
+ sizeof(stat->fssi),
+ NT_FILE_FS_SIZE_INFORMATION);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* system-unique device name (simpler than statfs) */
+ iosb.info = 0;
+ status = __ntapi->zw_query_object(
+ hfile,
+ NT_OBJECT_NAME_INFORMATION,
+ buffer,
+ buffer_size,
+ (uint32_t *)&iosb.info);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ sdev = (nt_unicode_string *)buffer;
+ stat->dev_name_strlen = sdev->strlen - (uint16_t)stat->file_name_length;
+
+ stat->dev_name_hash = __ntapi->tt_buffer_crc32(
+ 0,
+ sdev->buffer,
+ stat->dev_name_strlen);
+
+ if (flags & NT_STAT_DEV_NAME_COPY) {
+ if (stat->dev_name_maxlen < sdev->strlen)
+ /* does not justify failure */
+ *stat->dev_name = 0;
+ else
+ __ntapi->tt_memcpy_utf16(
+ (wchar16_t *)stat->dev_name,
+ (wchar16_t *)sdev->buffer,
+ stat->dev_name_strlen);
+ } else
+ *stat->dev_name = 0;
+
+ return status;
+}
diff --git a/src/fs/ntapi_tt_statfs.c b/src/fs/ntapi_tt_statfs.c
new file mode 100644
index 0000000..114cc8e
--- /dev/null
+++ b/src/fs/ntapi_tt_statfs.c
@@ -0,0 +1,225 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_fsctl.h>
+#include <ntapi/nt_mount.h>
+#include <ntapi/nt_statfs.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_statfs(
+ __in void * hfile,
+ __in void * hroot __optional,
+ __in nt_unicode_string * path,
+ __out nt_statfs * statfs,
+ __out uintptr_t * buffer,
+ __in uint32_t buffer_size,
+ __in uint32_t flags)
+{
+ int32_t status;
+ nt_oa oa;
+ nt_iosb iosb;
+ nt_unicode_string * sdev;
+ uint32_t hash;
+ wchar16_t * wch;
+ wchar16_t * wch_mark;
+ uint32_t offset;
+ void * mnt_points_buffer;
+ nt_mount_points * mnt_points;
+ nt_fsai * fsai;
+ nt_fsfsi * fsfsi;
+ uint32_t * fsid;
+ uint64_t * pguid;
+
+ /* validation */
+ if (!hfile && !path)
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* hfile */
+ if (!hfile) {
+ /* oa */
+ oa.len = sizeof(nt_oa);
+ oa.root_dir = hroot;
+ oa.obj_name = path;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = 0;
+
+ /* open file/folder */
+ status = __ntapi->zw_open_file(
+ &hfile,
+ NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_ACCESS,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_SYNCHRONOUS_IO_ALERT);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ statfs->flags_out = NT_STATFS_NEW_HANDLE;
+ }
+
+ statfs->hfile = hfile;
+ statfs->flags_in = flags;
+
+ /* maximum component length, file system type */
+ status = __ntapi->zw_query_volume_information_file(
+ hfile,
+ &iosb,
+ buffer,
+ buffer_size,
+ NT_FILE_FS_ATTRIBUTE_INFORMATION);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ fsai = (nt_fsai *)buffer;
+ statfs->f_type = 0;
+ statfs->f_namelen = fsai->maximum_component_name_length;
+ statfs->nt_fstype_hash = __ntapi->tt_buffer_crc32(
+ 0,
+ &fsai->file_system_name,
+ fsai->file_system_name_length);
+
+ /* max files per volume */
+ switch (statfs->nt_fstype_hash) {
+ case NT_FS_TYPE_HPFS_NAME_HASH:
+ case NT_FS_TYPE_NTFS_NAME_HASH:
+ case NT_FS_TYPE_SMB_NAME_HASH:
+ case NT_FS_TYPE_UDF_NAME_HASH:
+ statfs->f_files = 0xFFFFFFFF;
+ break;
+
+ case NT_FS_TYPE_FAT16_NAME_HASH:
+ statfs->f_files = 0x10000;
+ break;
+
+ case NT_FS_TYPE_FAT32_NAME_HASH:
+ statfs->f_files = 0x400000;
+ break;
+
+ default:
+ /* pretend there is no limitation */
+ statfs->f_files = (-1);
+ break;
+ }
+
+ /* number of free file records on volume */
+ /* (skip, yet indicate that the volume is not empty) */
+ statfs->f_ffree = (size_t)statfs->f_files >> 4 << 3;
+
+ /* file system size information */
+ status = __ntapi->zw_query_volume_information_file(
+ hfile,
+ &iosb,
+ buffer,
+ buffer_size,
+ NT_FILE_FS_FULL_SIZE_INFORMATION);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ fsfsi = (nt_fsfsi *)buffer;
+ statfs->f_blocks = fsfsi->total_allocation_units.quad;
+ statfs->f_bfree = fsfsi->actual_available_allocation_units.quad;
+ statfs->f_bavail = fsfsi->caller_available_allocation_units.quad;
+ statfs->f_bsize = fsfsi->sectors_per_allocation_unit * fsfsi->bytes_per_sector;
+ statfs->f_frsize = fsfsi->bytes_per_sector;
+
+ /* TODO: consolidate with istat */
+ /* system-unique device name */
+ iosb.info = 0;
+ status = __ntapi->zw_query_object(
+ hfile,
+ NT_OBJECT_NAME_INFORMATION,
+ buffer,
+ buffer_size,
+ (uint32_t *)&iosb.info);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ sdev = (nt_unicode_string *)buffer;
+
+ if (sdev->strlen < __DEVICE_PATH_PREFIX_LEN)
+ return NT_STATUS_INVALID_HANDLE;
+
+ hash = __ntapi->tt_buffer_crc32(
+ 0,
+ sdev->buffer,
+ __DEVICE_PATH_PREFIX_LEN);
+
+ if (hash != __DEVICE_PATH_PREFIX_HASH)
+ return NT_STATUS_INVALID_HANDLE;
+
+ wch_mark = sdev->buffer + __DEVICE_PATH_PREFIX_LEN/sizeof(wchar16_t);
+ wch = wch_mark;
+ while (*wch != '\\') wch++;
+ statfs->dev_name_strlen = (uint16_t)((wch - sdev->buffer) * sizeof(uint16_t));
+ statfs->record_name_strlen = sdev->strlen - statfs->dev_name_strlen;
+
+ statfs->dev_name_hash = __ntapi->tt_buffer_crc32(
+ hash,wch_mark,
+ sizeof(wchar16_t) * (wch - wch_mark));
+
+ /* copy device name (optional, no failure) */
+ if (flags & NT_STATFS_DEV_NAME_COPY) {
+ if (statfs->dev_name_maxlen < sdev->strlen)
+ *statfs->dev_name = 0;
+ else
+ __ntapi->tt_memcpy_utf16(
+ (wchar16_t *)statfs->dev_name,
+ (wchar16_t *)sdev->buffer,
+ sdev->strlen);
+ } else
+ *statfs->dev_name = 0;
+
+ /* f_fsid: hash of the system-unique device name */
+ /* (never use the volume serial number) */
+ fsid = (uint32_t *)&(statfs->f_fsid);
+ fsid[0] = statfs->dev_name_hash;
+ fsid[1] = 0;
+
+ /* f_flags, nt_attr, nt_control_flags (todo?) */
+ statfs->f_flags = 0;
+ statfs->nt_attr = 0;
+ statfs->nt_control_flags = 0;
+ statfs->nt_padding = 0;
+
+ if (!(flags & NT_STATFS_VOLUME_GUID)) {
+ statfs->nt_drive_letter = 0;
+ pguid = (uint64_t *)&(statfs->nt_volume_guid);
+ *pguid = 0; *(++pguid) = 0;
+ return NT_STATUS_SUCCESS;
+ }
+
+ /* dos device letter and volume guid */
+ wch = (wchar16_t *)sdev->buffer;
+ mnt_points_buffer = (void *)((uintptr_t)wch + statfs->dev_name_strlen);
+
+ *(--wch) = statfs->dev_name_strlen;
+ offset = sizeof(nt_unicode_string) + statfs->dev_name_strlen;
+
+ status = __ntapi->tt_get_dos_drive_mount_points(
+ (void *)0,
+ (wchar16_t *)0,
+ (nt_mount_dev_name *)wch,
+ mnt_points_buffer,
+ buffer_size - offset);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ offset = ((nt_mount_point_param *)mnt_points_buffer)->mount_points_offset;
+ mnt_points = (nt_mount_points *)((uintptr_t)mnt_points_buffer + offset);
+
+ status = __ntapi->tt_dev_mount_points_to_statfs(
+ mnt_points,
+ statfs);
+
+ return status;
+}
diff --git a/src/guid/ntapi_tt_guid.c b/src/guid/ntapi_tt_guid.c
new file mode 100644
index 0000000..07cd938
--- /dev/null
+++ b/src/guid/ntapi_tt_guid.c
@@ -0,0 +1,182 @@
+/********************************************************/
+/* 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/nt_time.h>
+#include <ntapi/nt_guid.h>
+#include "ntapi_impl.h"
+
+
+void __fastcall __ntapi_tt_guid_copy(
+ __out nt_guid * pguid_dst,
+ __in const nt_guid * pguid_src)
+{
+ uint64_t * dst;
+ uint64_t * src;
+
+ dst = (uint64_t *)pguid_dst;
+ src = (uint64_t *)pguid_src;
+
+ *dst = *src;
+ src++; dst++;
+ *dst = *src;
+}
+
+
+void __fastcall __ntapi_tt_guid_to_utf16_string(
+ __in const nt_guid * guid,
+ __out nt_guid_str_utf16 * guid_str)
+{
+ uint16_t key;
+ wchar16_t * wch;
+
+ wch = &(guid_str->group5[0]);
+
+ __ntapi_tt_uint32_to_hex_utf16(
+ guid->data1,
+ &guid_str->group1[0]);
+
+ __ntapi_tt_uint16_to_hex_utf16(
+ guid->data2,
+ &guid_str->group2[0]);
+
+ __ntapi_tt_uint16_to_hex_utf16(
+ guid->data3,
+ &guid_str->group3[0]);
+
+ key = guid->data4[0] * 0x100 + guid->data4[1];
+
+ __ntapi_tt_uint16_to_hex_utf16(
+ key,
+ &guid_str->group4[0]);
+
+ key = guid->data4[2] * 0x100 + guid->data4[3];
+
+ __ntapi_tt_uint16_to_hex_utf16(
+ key,
+ &guid_str->group5[0]);
+
+ key = guid->data4[4] * 0x100 + guid->data4[5];
+
+ __ntapi_tt_uint16_to_hex_utf16(
+ key,
+ &(wch[4]));
+
+ key = guid->data4[6] * 0x100 + guid->data4[7];
+
+ __ntapi_tt_uint16_to_hex_utf16(
+ key,
+ &(wch[8]));
+
+ guid_str->lbrace = '{';
+ guid_str->rbrace = '}';
+ guid_str->dash1 = '-';
+ guid_str->dash2 = '-';
+ guid_str->dash3 = '-';
+ guid_str->dash4 = '-';
+
+ return;
+}
+
+
+int32_t __fastcall __ntapi_tt_guid_compare(
+ __in const nt_guid * pguid_dst,
+ __in const nt_guid * pguid_src)
+{
+ uint64_t * dst;
+ uint64_t * src;
+
+ dst = (uint64_t *)pguid_dst;
+ src = (uint64_t *)pguid_src;
+
+ if ((*dst != *src) || (*(++dst) != *(++src)))
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __fastcall __ntapi_tt_utf16_string_to_guid(
+ __out nt_guid_str_utf16 * guid_str,
+ __in nt_guid * guid)
+{
+ int32_t status;
+ wchar16_t * wch;
+ uint16_t key;
+
+ if ((guid_str->lbrace != '{')
+ || (guid_str->rbrace != '}')
+ || (guid_str->dash1 != '-')
+ || (guid_str->dash2 != '-')
+ || (guid_str->dash3 != '-')
+ || (guid_str->dash4 != '-'))
+ return NT_STATUS_INVALID_PARAMETER;
+
+ wch = &(guid_str->group5[0]);
+
+ status = __ntapi_tt_hex_utf16_to_uint32(
+ guid_str->group1,
+ &guid->data1);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ status = __ntapi_tt_hex_utf16_to_uint16(
+ guid_str->group2,
+ &guid->data2);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ status = __ntapi_tt_hex_utf16_to_uint16(
+ guid_str->group3,
+ &guid->data3);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ status = __ntapi_tt_hex_utf16_to_uint16(
+ guid_str->group4,
+ &key);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ guid->data4[0] = key / 0x100;
+ guid->data4[1] = key % 0x100;
+
+ status = __ntapi_tt_hex_utf16_to_uint16(
+ &(wch[0]),
+ &key);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ guid->data4[2] = key / 0x100;
+ guid->data4[3] = key % 0x100;
+
+ status = __ntapi_tt_hex_utf16_to_uint16(
+ &(wch[4]),
+ &key);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ guid->data4[4] = key / 0x100;
+ guid->data4[5] = key % 0x100;
+
+ status = __ntapi_tt_hex_utf16_to_uint16(
+ &(wch[8]),
+ &key);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ guid->data4[6] = key / 0x100;
+ guid->data4[7] = key % 0x100;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/hash/ntapi_tt_crc32.c b/src/hash/ntapi_tt_crc32.c
new file mode 100644
index 0000000..7ce25d3
--- /dev/null
+++ b/src/hash/ntapi_tt_crc32.c
@@ -0,0 +1,50 @@
+/********************************************************/
+/* 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/nt_crc32.h>
+
+static const uint32_t crc32_table[256] = NTAPI_CRC32_TABLE;
+
+uint32_t __ntapi_tt_buffer_crc32(
+ uint32_t prev_hash,
+ const void * buffer,
+ size_t size)
+{
+ unsigned char * ch;
+ uint32_t crc32;
+
+ crc32 = prev_hash ^ 0xFFFFFFFF;
+ ch = (unsigned char *)buffer;
+
+ for (; size; size--,ch++)
+ crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *ch) & 0xFF];
+
+ return (crc32 ^ 0xFFFFFFFF);
+}
+
+
+uint32_t __cdecl __ntapi_tt_mbstr_crc32(const void * str)
+{
+ uint32_t crc32;
+ unsigned char * ch;
+
+ crc32 = 0 ^ 0xFFFFFFFF;
+ ch = (unsigned char *)str;
+
+ while (*ch) {
+ crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *ch) & 0xFF];
+ ch++;
+ }
+
+ return (crc32 ^ 0xFFFFFFFF);
+}
+
+
+const uint32_t * __cdecl __ntapi_tt_crc32_table(void)
+{
+ return crc32_table;
+}
diff --git a/src/hash/ntapi_tt_populate_hashed_import_table.c b/src/hash/ntapi_tt_populate_hashed_import_table.c
new file mode 100644
index 0000000..a36ed2f
--- /dev/null
+++ b/src/hash/ntapi_tt_populate_hashed_import_table.c
@@ -0,0 +1,95 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_crc32.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+struct callback_ctx {
+ void * import_table;
+ ntapi_hashed_symbol * hash_table;
+ uint32_t hash_table_array_size;
+};
+
+
+static int __process_exported_symbol(
+ const void * base,
+ struct pe_export_hdr * exp_hdr,
+ struct pe_export_sym * exp_item,
+ enum pe_callback_reason reason,
+ void * context)
+{
+ uint32_t hash_value;
+ struct callback_ctx * ctx;
+ ntapi_hashed_symbol * hashed_symbol;
+ uintptr_t * fnptr;
+
+ /* binary search variables */
+ uint32_t lower;
+ uint32_t upper;
+ uint32_t idx;
+
+ if (reason != PE_CALLBACK_REASON_ITEM)
+ return 1;
+
+ ctx = (struct callback_ctx *)context;
+ hash_value = __ntapi_tt_mbstr_crc32(exp_item->name);
+
+ /* zero-based array, binary search, idx < upper is guaranteed */
+ lower = 0;
+ upper = ctx->hash_table_array_size;
+
+ /* binary search */
+ while (lower < upper) {
+ idx = (lower + upper) / 2;
+ hashed_symbol = (ntapi_hashed_symbol *)
+ ((uintptr_t)ctx->hash_table
+ + idx * sizeof(ntapi_hashed_symbol));
+
+ if (hash_value == hashed_symbol->crc32_hash) {
+ fnptr = (uintptr_t *)(
+ (uintptr_t)ctx->import_table
+ + (sizeof(uintptr_t)
+ * hashed_symbol->ordinal));
+ *fnptr = (uintptr_t)exp_item->addr;
+ return 1;
+ }
+
+ else {
+ if (hash_value > hashed_symbol->crc32_hash)
+ lower = idx + 1;
+ else
+ upper = idx;
+ }
+ }
+
+ return 1;
+}
+
+int32_t __cdecl __ntapi_tt_populate_hashed_import_table(
+ __in void * image_base,
+ __in void * import_table,
+ __in ntapi_hashed_symbol * hash_table,
+ __in uint32_t hash_table_array_size)
+{
+ struct pe_export_sym exp_item;
+ struct callback_ctx ctx;
+
+ ctx.import_table = import_table;
+ ctx.hash_table = hash_table;
+ ctx.hash_table_array_size = hash_table_array_size;
+
+ pe_enum_image_exports(
+ image_base,
+ &__process_exported_symbol,
+ &exp_item,
+ &ctx);
+
+ return 0;
+}
diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c
new file mode 100644
index 0000000..2340c47
--- /dev/null
+++ b/src/internal/ntapi.c
@@ -0,0 +1,411 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_crc32.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_sysinfo.h>
+#include <ntapi/nt_memory.h>
+#include <ntapi/nt_section.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/nt_job.h>
+#include <ntapi/nt_token.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/nt_time.h>
+#include <ntapi/nt_profiling.h>
+#include <ntapi/nt_port.h>
+#include <ntapi/nt_device.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_registry.h>
+#include <ntapi/nt_security.h>
+#include <ntapi/nt_pnp.h>
+#include <ntapi/nt_exception.h>
+#include <ntapi/nt_locale.h>
+#include <ntapi/nt_uuid.h>
+#include <ntapi/nt_atom.h>
+#include <ntapi/nt_os.h>
+#include <ntapi/nt_ldr.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/nt_guid.h>
+#include <ntapi/nt_argv.h>
+#include <ntapi/nt_blitter.h>
+#include <ntapi/nt_unicode.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/nt_mount.h>
+#include <ntapi/nt_istat.h>
+#include <ntapi/nt_stat.h>
+#include <ntapi/nt_statfs.h>
+#include <ntapi/nt_daemon.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/nt_hash.h>
+#include <ntapi/nt_debug.h>
+#include <ntapi/nt_atomic.h>
+#include <ntapi/ntapi.h>
+
+#include "ntapi_impl.h"
+#include "ntapi_hash_table.h"
+
+/* simplified once mechanism for free-standing applications */
+typedef int32_t __fastcall __ntapi_init_fn(ntapi_vtbl ** pvtbl);
+
+static __ntapi_init_fn __ntapi_init_once;
+static __ntapi_init_fn __ntapi_init_pending;
+static __ntapi_init_fn __ntapi_init_completed;
+
+static intptr_t __ntapi_init_idx = 0;
+static __ntapi_init_fn * __ntapi_init_vtbl[3] = {
+ __ntapi_init_once,
+ __ntapi_init_pending,
+ __ntapi_init_completed};
+
+/* accessor */
+ntapi_vtbl ___ntapi = {0};
+ntapi_vtbl ___ntapi_shadow = {0};
+
+/* .bss */
+static __ntapi_img_sec_bss __ntapi_img_bss;
+
+/* .rdata */
+static union __ntapi_img_rdata __ntapi_rdata = {{
+ {__NTAPI_HASH_TABLE}, /* __ntapi_import_table */
+ 0, /* __ntapi */
+ {{0}}, /* __session_name */
+ 0}}; /* __internals */
+
+#define internals __ntapi_rdata.img_sec_data.__internals
+#define import_table __ntapi_rdata.img_sec_data.__ntapi_import_table
+
+
+static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl)
+{
+ int32_t status;
+ void * hntdll;
+ size_t block_size;
+ ntapi_zw_allocate_virtual_memory * pfn_zw_allocate_virtual_memory;
+ char fname_allocate_virtual_memory[] =
+ "ZwAllocateVirtualMemory";
+ /* once */
+ at_locked_inc(&__ntapi_init_idx);
+
+ /* pvtbl */
+ if (!(pvtbl))
+ return NT_STATUS_INVALID_PARAMETER;
+ else
+ *pvtbl = (ntapi_vtbl *)0;
+
+ /* ntdll */
+ if (!(hntdll = pe_get_ntdll_module_handle()))
+ return NT_STATUS_DLL_INIT_FAILED;
+
+ pfn_zw_allocate_virtual_memory = (ntapi_zw_allocate_virtual_memory *)
+ pe_get_procedure_address(
+ hntdll,
+ fname_allocate_virtual_memory);
+
+ if (!pfn_zw_allocate_virtual_memory)
+ return NT_STATUS_DLL_INIT_FAILED;
+
+ /* ntapi_internals: alloc */
+ block_size = sizeof(ntapi_internals);
+ status = pfn_zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&internals,
+ 0,
+ &block_size,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* hashed import table */
+ __ntapi_tt_populate_hashed_import_table(
+ pe_get_ntdll_module_handle(),
+ __ntapi,
+ import_table,
+ __NT_IMPORTED_SYMBOLS_ARRAY_SIZE);
+
+ /* alternate implementation */
+ __ntapi->rtl_init_unicode_string = __ntapi_tt_init_unicode_string_from_utf16;
+
+ /* extension functions */
+ /* nt_object.h */
+ __ntapi->tt_create_keyed_object_directory = __ntapi_tt_create_keyed_object_directory;
+ __ntapi->tt_open_keyed_object_directory = __ntapi_tt_open_keyed_object_directory;
+ __ntapi->tt_create_keyed_object_directory_entry = __ntapi_tt_create_keyed_object_directory_entry;
+
+ /* nt_crc32.h */
+ __ntapi->tt_buffer_crc32 = __ntapi_tt_buffer_crc32;
+ __ntapi->tt_mbstr_crc32 = __ntapi_tt_mbstr_crc32;
+ __ntapi->tt_crc32_table = __ntapi_tt_crc32_table;
+
+ /* nt_file.h */
+ __ntapi->tt_get_file_handle_type = __ntapi_tt_get_file_handle_type;
+ __ntapi->tt_open_logical_parent_directory = __ntapi_tt_open_logical_parent_directory;
+ __ntapi->tt_open_physical_parent_directory = __ntapi_tt_open_physical_parent_directory;
+
+ /* nt_ldr.h */
+ __ntapi->ldr_load_system_dll = __ntapi_ldr_load_system_dll;
+ __ntapi->ldr_create_state_snapshot = __ntapi_ldr_create_state_snapshot;
+ __ntapi->ldr_revert_state_to_snapshot = __ntapi_ldr_revert_state_to_snapshot;
+
+ /* nt_string.h */
+ __ntapi->tt_string_null_offset_multibyte = __ntapi_tt_string_null_offset_multibyte;
+ __ntapi->tt_string_null_offset_short = __ntapi_tt_string_null_offset_short;
+ __ntapi->tt_string_null_offset_dword = __ntapi_tt_string_null_offset_dword;
+ __ntapi->tt_string_null_offset_qword = __ntapi_tt_string_null_offset_qword;
+ __ntapi->tt_string_null_offset_ptrsize = __ntapi_tt_string_null_offset_ptrsize;
+ __ntapi->strlen = __ntapi_tt_string_null_offset_multibyte;
+ __ntapi->wcslen = __ntapi_wcslen;
+ __ntapi->tt_aligned_block_memset = __ntapi_tt_aligned_block_memset;
+ __ntapi->tt_aligned_block_memcpy = __ntapi_tt_aligned_block_memcpy;
+ __ntapi->tt_memcpy_utf16 = __ntapi_tt_memcpy_utf16;
+ __ntapi->tt_aligned_memcpy_utf16 = __ntapi_tt_aligned_memcpy_utf16;
+ __ntapi->tt_generic_memset = __ntapi_tt_generic_memset;
+ __ntapi->tt_generic_memcpy = __ntapi_tt_generic_memcpy;
+ __ntapi->tt_uint16_to_hex_utf16 = __ntapi_tt_uint16_to_hex_utf16;
+ __ntapi->tt_uint32_to_hex_utf16 = __ntapi_tt_uint32_to_hex_utf16;
+ __ntapi->tt_uint64_to_hex_utf16 = __ntapi_tt_uint64_to_hex_utf16;
+ __ntapi->tt_uintptr_to_hex_utf16 = __ntapi_tt_uintptr_to_hex_utf16;
+ __ntapi->tt_hex_utf16_to_uint16 = __ntapi_tt_hex_utf16_to_uint16;
+ __ntapi->tt_hex_utf16_to_uint32 = __ntapi_tt_hex_utf16_to_uint32;
+ __ntapi->tt_hex_utf16_to_uint64 = __ntapi_tt_hex_utf16_to_uint64;
+ __ntapi->tt_hex_utf16_to_uintptr = __ntapi_tt_hex_utf16_to_uintptr;
+ __ntapi->tt_init_unicode_string_from_utf16 = __ntapi_tt_init_unicode_string_from_utf16;
+ __ntapi->tt_uint16_to_hex_utf8 = __ntapi_tt_uint16_to_hex_utf8;
+ __ntapi->tt_uint32_to_hex_utf8 = __ntapi_tt_uint32_to_hex_utf8;
+ __ntapi->tt_uint64_to_hex_utf8 = __ntapi_tt_uint64_to_hex_utf8;
+ __ntapi->tt_uintptr_to_hex_utf8 = __ntapi_tt_uintptr_to_hex_utf8;
+
+ /* nt_guid.h */
+ __ntapi->tt_guid_copy = __ntapi_tt_guid_copy;
+ __ntapi->tt_guid_compare = __ntapi_tt_guid_compare;
+ __ntapi->tt_guid_to_utf16_string = __ntapi_tt_guid_to_utf16_string;
+ __ntapi->tt_utf16_string_to_guid = __ntapi_tt_utf16_string_to_guid;
+
+ /* nt_sysinfo.h */
+ __ntapi->tt_get_system_directory_native_path = __ntapi_tt_get_system_directory_native_path;
+ __ntapi->tt_get_system_directory_dos_path = __ntapi_tt_get_system_directory_dos_path;
+ __ntapi->tt_get_system_directory_handle = __ntapi_tt_get_system_directory_handle;
+ __ntapi->tt_get_system_info_snapshot = __ntapi_tt_get_system_info_snapshot;
+
+ /* nt_thread.h */
+ __ntapi->tt_create_local_thread = __ntapi_tt_create_local_thread;
+ __ntapi->tt_create_remote_thread = __ntapi_tt_create_remote_thread;
+ __ntapi->tt_create_thread = __ntapi_tt_create_thread;
+
+ /* nt_process.h */
+ __ntapi->tt_create_remote_process_params = __ntapi_tt_create_remote_process_params;
+ __ntapi->tt_get_runtime_data = __ntapi_tt_get_runtime_data;
+ __ntapi->tt_init_runtime_data = __ntapi_tt_init_runtime_data;
+ __ntapi->tt_update_runtime_data = __ntapi_tt_update_runtime_data;
+ __ntapi->tt_exec_map_image_as_data = __ntapi_tt_exec_map_image_as_data;
+ __ntapi->tt_exec_unmap_image = __ntapi_tt_exec_unmap_image;
+
+ /* nt_section.h */
+ __ntapi->tt_get_section_name = __ntapi_tt_get_section_name;
+
+ /* nt_sync.h */
+ __ntapi->tt_create_inheritable_event = __ntapi_tt_create_inheritable_event;
+ __ntapi->tt_create_private_event = __ntapi_tt_create_private_event;
+ __ntapi->tt_wait_for_dummy_event = __ntapi_tt_wait_for_dummy_event;
+ __ntapi->tt_sync_block_init = __ntapi_tt_sync_block_init;
+ __ntapi->tt_sync_block_lock = __ntapi_tt_sync_block_lock;
+ __ntapi->tt_sync_block_server_lock = __ntapi_tt_sync_block_server_lock;
+ __ntapi->tt_sync_block_unlock = __ntapi_tt_sync_block_unlock;
+ __ntapi->tt_sync_block_invalidate = __ntapi_tt_sync_block_invalidate;
+
+ /* nt_port.h */
+ __ntapi->csr_port_handle = __ntapi_csr_port_handle;
+ __ntapi->tt_port_guid_from_type = __ntapi_tt_port_guid_from_type;
+ __ntapi->tt_port_type_from_guid = __ntapi_tt_port_type_from_guid;
+ __ntapi->tt_port_generate_keys = __ntapi_tt_port_generate_keys;
+ __ntapi->tt_port_format_keys = __ntapi_tt_port_format_keys;
+ __ntapi->tt_port_name_from_attributes = __ntapi_tt_port_name_from_attributes;
+
+ /* nt_argv.h */
+ __ntapi->tt_get_cmd_line_utf16 = __ntapi_tt_get_cmd_line_utf16;
+ __ntapi->tt_get_peb_env_block_utf16 = __ntapi_tt_get_peb_env_block_utf16;
+ __ntapi->tt_parse_cmd_line_args_utf16 = __ntapi_tt_parse_cmd_line_args_utf16;
+ __ntapi->tt_get_argv_envp_utf8 = __ntapi_tt_get_argv_envp_utf8;
+ __ntapi->tt_get_argv_envp_utf16 = __ntapi_tt_get_argv_envp_utf16;
+ __ntapi->tt_get_env_var_meta_utf16 = __ntapi_tt_get_env_var_meta_utf16;
+ __ntapi->tt_get_short_option_meta_utf16 = __ntapi_tt_get_short_option_meta_utf16;
+ __ntapi->tt_get_long_option_meta_utf16 = __ntapi_tt_get_long_option_meta_utf16;
+ __ntapi->tt_array_copy_utf16 = __ntapi_tt_array_copy_utf16;
+ __ntapi->tt_array_copy_utf8 = __ntapi_tt_array_copy_utf8;
+ __ntapi->tt_array_convert_utf8_to_utf16 = __ntapi_tt_array_convert_utf8_to_utf16;
+ __ntapi->tt_array_convert_utf16_to_utf8 = __ntapi_tt_array_convert_utf16_to_utf8;
+
+ /* nt_blitter.h */
+ __ntapi->blt_alloc = __ntapi_blt_alloc;
+ __ntapi->blt_free = __ntapi_blt_free;
+ __ntapi->blt_acquire = __ntapi_blt_acquire;
+ __ntapi->blt_obtain = __ntapi_blt_obtain;
+ __ntapi->blt_possess = __ntapi_blt_possess;
+ __ntapi->blt_release = __ntapi_blt_release;
+ __ntapi->blt_get = __ntapi_blt_get;
+ __ntapi->blt_set = __ntapi_blt_set;
+
+ /* nt_unicode.h */
+ __ntapi->uc_validate_unicode_stream_utf8 = __ntapi_uc_validate_unicode_stream_utf8;
+ __ntapi->uc_validate_unicode_stream_utf16 = __ntapi_uc_validate_unicode_stream_utf16;
+ __ntapi->uc_get_code_point_byte_count_utf8 = __ntapi_uc_get_code_point_byte_count_utf8;
+ __ntapi->uc_get_code_point_byte_count_utf16 = __ntapi_uc_get_code_point_byte_count_utf16;
+ __ntapi->uc_convert_unicode_stream_utf8_to_utf16 = __ntapi_uc_convert_unicode_stream_utf8_to_utf16;
+ __ntapi->uc_convert_unicode_stream_utf8_to_utf32 = __ntapi_uc_convert_unicode_stream_utf8_to_utf32;
+ __ntapi->uc_convert_unicode_stream_utf16_to_utf8 = __ntapi_uc_convert_unicode_stream_utf16_to_utf8;
+ __ntapi->uc_convert_unicode_stream_utf16_to_utf32 = __ntapi_uc_convert_unicode_stream_utf16_to_utf32;
+
+ /* nt_daemon.h */
+ __ntapi->dsr_init = __ntapi_dsr_init;
+ __ntapi->dsr_start = __ntapi_dsr_start;
+ __ntapi->dsr_create_port = __ntapi_dsr_create_port;
+ __ntapi->dsr_connect_internal_client = __ntapi_dsr_connect_internal_client;
+ __ntapi->dsr_internal_client_connect = __ntapi_dsr_internal_client_connect;
+
+ /* nt_vfd.h */
+ __ntapi->vfd_dev_name_init = __ntapi_vfd_dev_name_init;
+
+ /* nt_tty.h */
+ __ntapi->tty_create_session = __ntapi_tty_create_session;
+ __ntapi->tty_join_session = __ntapi_tty_join_session;
+ __ntapi->tty_connect = __ntapi_tty_connect;
+ __ntapi->tty_client_session_query = __ntapi_tty_client_session_query;
+ __ntapi->tty_client_session_set = __ntapi_tty_client_session_set;
+ __ntapi->tty_client_process_register = __ntapi_tty_client_process_register;
+ __ntapi->tty_query_information_server = __ntapi_tty_query_information_server;
+ __ntapi->tty_request_peer = __ntapi_tty_request_peer;
+ __ntapi->tty_vms_query = __ntapi_tty_vms_query;
+ __ntapi->tty_vms_request = __ntapi_tty_vms_request;
+ __ntapi->pty_open = __ntapi_pty_open;
+ __ntapi->pty_reopen = __ntapi_pty_reopen;
+ __ntapi->pty_close = __ntapi_pty_close;
+ __ntapi->pty_read = __ntapi_pty_read;
+ __ntapi->pty_write = __ntapi_pty_write;
+ __ntapi->pty_ioctl = __ntapi_pty_ioctl;
+ __ntapi->pty_query = __ntapi_pty_query;
+ __ntapi->pty_set = __ntapi_pty_set;
+ __ntapi->pty_cancel = __ntapi_pty_cancel;
+
+ /* nt_socket.h */
+ __ntapi->sc_listen = __ntapi_sc_listen;
+ __ntapi->sc_accept = __ntapi_sc_accept;
+ __ntapi->sc_send = __ntapi_sc_send;
+ __ntapi->sc_recv = __ntapi_sc_recv;
+ __ntapi->sc_shutdown = __ntapi_sc_shutdown;
+ __ntapi->sc_server_duplicate_socket = __ntapi_sc_server_duplicate_socket;
+ __ntapi->sc_wait = __ntapi_sc_wait;
+
+ /* nt_mount.h */
+ __ntapi->tt_get_dos_drive_device_handle = __ntapi_tt_get_dos_drive_device_handle;
+ __ntapi->tt_get_dos_drive_root_handle = __ntapi_tt_get_dos_drive_root_handle;
+ __ntapi->tt_get_dos_drive_device_name = __ntapi_tt_get_dos_drive_device_name;
+ __ntapi->tt_get_dos_drive_mount_points = __ntapi_tt_get_dos_drive_mount_points;
+ __ntapi->tt_dev_mount_points_to_statfs = __ntapi_tt_dev_mount_points_to_statfs;
+ __ntapi->tt_get_dos_drive_letter_from_device = __ntapi_tt_get_dos_drive_letter_from_device;
+
+ /* nt_istat.h */
+ __ntapi->tt_istat = __ntapi_tt_istat;
+ __ntapi->tt_validate_fs_handle = __ntapi_tt_validate_fs_handle;
+
+ /* nt_stat.h */
+ __ntapi->tt_stat = __ntapi_tt_stat;
+
+ /* nt_statfs.h */
+ __ntapi->tt_statfs = __ntapi_tt_statfs;
+
+ /* nt_vmount.h */
+ __ntapi->vms_get_node_by_dev_name = __ntapi_vms_get_node_by_dev_name;
+ __ntapi->vms_get_node_by_end_component = __ntapi_vms_get_node_by_end_component;
+ __ntapi->vms_cache_alloc = __ntapi_vms_cache_alloc;
+ __ntapi->vms_cache_free = __ntapi_vms_cache_free;
+ __ntapi->vms_client_connect = __ntapi_vms_client_connect;
+ __ntapi->vms_client_disconnect = __ntapi_vms_client_disconnect;
+ __ntapi->vms_point_attach = __ntapi_vms_point_attach;
+ __ntapi->vms_point_get_handles = __ntapi_vms_point_get_handles;
+ __ntapi->vms_ref_count_inc = __ntapi_vms_ref_count_inc;
+ __ntapi->vms_ref_count_dec = __ntapi_vms_ref_count_dec;
+ __ntapi->vms_table_query = __ntapi_vms_table_query;
+
+ /* nt_debug.h */
+ #ifdef __DEBUG
+ __ntapi->dbg_write = __dbg_write;
+ __ntapi->dbg_fn_call = __dbg_fn_call;
+ __ntapi->dbg_msg = __dbg_msg;
+ #endif
+
+
+ /* OS version dependent functions */
+ if (__ntapi->zw_create_user_process) {
+ __ntapi->tt_fork = __ntapi_tt_fork_v2;
+ __ntapi->tt_create_native_process = __ntapi_tt_create_native_process_v2;
+ __ntapi->ipc_create_pipe = __ntapi_ipc_create_pipe_v2;
+ __ntapi->sc_socket = __ntapi_sc_socket_v2;
+ __ntapi->sc_bind = __ntapi_sc_bind_v2;
+ __ntapi->sc_connect = __ntapi_sc_connect_v2;
+ __ntapi->sc_server_accept_connection = __ntapi_sc_server_accept_connection_v2;
+ __ntapi->sc_getsockname = __ntapi_sc_getsockname_v2;
+ } else {
+ __ntapi->tt_fork = __ntapi_tt_fork_v1;
+ __ntapi->tt_create_native_process = __ntapi_tt_create_native_process_v1;
+ __ntapi->ipc_create_pipe = __ntapi_ipc_create_pipe_v1;
+ __ntapi->sc_socket = __ntapi_sc_socket_v1;
+ __ntapi->sc_bind = __ntapi_sc_bind_v1;
+ __ntapi->sc_connect = __ntapi_sc_connect_v1;
+ __ntapi->sc_server_accept_connection = __ntapi_sc_server_accept_connection_v1;
+ __ntapi->sc_getsockname = __ntapi_sc_getsockname_v1;
+ }
+
+ /* internals */
+ internals->ntapi_img_sec_bss = &__ntapi_img_bss;
+ internals->subsystem = &__ntapi_rdata.img_sec_data.__session_name;
+
+ internals->tt_get_csr_port_handle_addr_by_logic = __GET_CSR_PORT_HANDLE_BY_LOGIC;
+ internals->csr_port_handle_addr = __GET_CSR_PORT_HANDLE_BY_LOGIC();
+
+ /* shadow copy for client libraries */
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)&___ntapi_shadow,
+ (uintptr_t *)&___ntapi,
+ sizeof(ntapi_vtbl));
+
+ /* done */
+ *pvtbl = &___ntapi_shadow;
+ at_locked_inc(&__ntapi_init_idx);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __ntapi_init_pending(ntapi_vtbl ** pvtbl)
+{
+ return NT_STATUS_PENDING;
+}
+
+static int32_t __fastcall __ntapi_init_completed(ntapi_vtbl ** pvtbl)
+{
+ *pvtbl = __ntapi;
+ return NT_STATUS_SUCCESS;
+};
+
+
+__ntapi_api
+int32_t __fastcall ntapi_init(ntapi_vtbl ** pvtbl)
+{
+ return __ntapi_init_vtbl[__ntapi_init_idx](pvtbl);
+}
+
+
+ntapi_internals * __cdecl __ntapi_internals(void)
+{
+ return internals;
+}
diff --git a/src/internal/ntapi_blitter.h b/src/internal/ntapi_blitter.h
new file mode 100644
index 0000000..9a285d9
--- /dev/null
+++ b/src/internal/ntapi_blitter.h
@@ -0,0 +1,27 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#ifndef ___NTAPI_BLITTER_H_
+#define ___NTAPI_BLITTER_H_
+
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_blitter.h>
+#include <ntapi/nt_sync.h>
+
+#define __NT_BLITTER_DEFAULT_LOCK_TRIES 256
+#define __NT_BLITTER_DEFAULT_ROUND_TRIPS 64
+
+typedef struct nt_blitter_context {
+ struct nt_blitter_context * addr;
+ size_t size;
+ uintptr_t ptrs;
+ nt_blitter_info info;
+ nt_blitter_params params;
+ uintptr_t * bitmap;
+ uintptr_t bits[];
+} nt_blitter;
+
+#endif
diff --git a/src/internal/ntapi_context.h b/src/internal/ntapi_context.h
new file mode 100644
index 0000000..4020158
--- /dev/null
+++ b/src/internal/ntapi_context.h
@@ -0,0 +1,55 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#ifndef ___NTAPI_CONTEXT_H_
+#define ___NTAPI_CONTEXT_H_
+
+#if defined(__X86_MODEL)
+ /* csr port handle */
+ #define __GET_CSR_PORT_HANDLE_BY_LOGIC __ntapi_tt_get_csr_port_handle_addr_by_logic_i386
+
+ /* register names */
+ #define STACK_POINTER_REGISTER uc_esp
+ #define INSTRUCTION_POINTER_REGISTER uc_eip
+ #define FAST_CALL_ARG0 uc_ecx
+ #define FAST_CALL_ARG1 uc_edx
+
+ /* thread context initialization */
+ #define __INIT_CONTEXT(context) \
+ context.uc_context_flags = NT_CONTEXT_JUST_EVERYTHING; \
+ context.uc_seg_gs = 0x00; \
+ context.uc_seg_fs = 0x3b; \
+ context.uc_seg_es = 0x23; \
+ context.uc_seg_ds = 0x23; \
+ context.uc_seg_ss = 0x23; \
+ context.uc_seg_cs = 0x1b; \
+ context.uc_eflags = 0x200
+
+#elif defined (__X86_64_MODEL)
+ /* csr port handle */
+ #define __GET_CSR_PORT_HANDLE_BY_LOGIC __ntapi_tt_get_csr_port_handle_addr_by_logic_x86_64
+
+ /* register names */
+ #define STACK_POINTER_REGISTER uc_rsp
+ #define INSTRUCTION_POINTER_REGISTER uc_rip
+ #define FAST_CALL_ARG0 uc_rcx
+ #define FAST_CALL_ARG1 uc_rdx
+
+ /* thread context initialization */
+ #define __INIT_CONTEXT(context) \
+ context.uc_context_flags= NT_CONTEXT_JUST_EVERYTHING; \
+ context.uc_seg_cs = 0x33; \
+ context.uc_seg_ds = 0x2b; \
+ context.uc_seg_es = 0x2b; \
+ context.uc_seg_fs = 0x53; \
+ context.uc_seg_gs = 0x2b; \
+ context.uc_seg_ss = 0x2b; \
+ context.uc_eflags = 0x200; \
+ context.uc_mx_csr = 0x1f80
+
+#endif
+
+#endif
diff --git a/src/internal/ntapi_debug.c b/src/internal/ntapi_debug.c
new file mode 100644
index 0000000..cb56c64
--- /dev/null
+++ b/src/internal/ntapi_debug.c
@@ -0,0 +1,170 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#ifdef __DEBUG
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+char dbg_buf[0x1000];
+
+ssize_t __cdecl __dbg_write(
+ __in void * hfile,
+ __in const void * buf,
+ __in size_t bytes)
+{
+ nt_iosb iosb;
+ int32_t status;
+
+ status = __ntapi->zw_write_file(
+ hfile,
+ (void *)0,
+ (nt_io_apc_routine *)0,
+ (void *)0,
+ &iosb,
+ (void *)buf,
+ (uint32_t)bytes,
+ (nt_large_integer *)0,
+ (uint32_t *)0);
+
+ if (status == NT_STATUS_SUCCESS)
+ return iosb.info;
+ else
+ return -1;
+}
+
+
+int32_t __cdecl __dbg_fn_call(
+ __in void * hfile __optional,
+ __in char * fn_caller_name,
+ __in void * fn_callee_addr,
+ __in uintptr_t fn_ret,
+ __in ntapi_dbg_write* pfn_dbg_write __optional,
+ __in char * source __optional,
+ __in int line __optional)
+{
+ struct pe_ldr_tbl_entry * image_meta;
+ void * image_base;
+ char * fn_name;
+ size_t bytes;
+ char dbg_buf[256];
+
+ if (!pfn_dbg_write)
+ pfn_dbg_write = __dbg_write;
+
+ image_meta = pe_get_symbol_module_info(fn_callee_addr);
+ fn_name = (char *)0;
+
+ if (image_meta)
+ image_base = image_meta->dll_base;
+ else
+ image_base = (void *)0;
+
+
+ if (image_base)
+ fn_name = pe_get_symbol_name(
+ image_base,
+ fn_callee_addr);
+
+ if (!fn_name)
+ fn_name = pe_get_import_symbol_info(
+ fn_callee_addr,
+ (void **)0,
+ (char **)0,
+ &image_meta);
+
+ if (source && fn_name)
+ bytes = __ntapi->sprintf(
+ dbg_buf,
+ "%s: (%s:%d):\n"
+ "--> %s returned 0x%08x\n\n",
+ fn_caller_name, source, line, fn_name, fn_ret);
+ else if (fn_name)
+ bytes = __ntapi->sprintf(
+ dbg_buf,
+ "%s: %s returned 0x%08x\n\n",
+ fn_caller_name, fn_name, fn_ret);
+ else if (source)
+ bytes = __ntapi->sprintf(
+ dbg_buf,
+ "%s: (%s:%d):\n"
+ "--> calling 0x%08x returned 0x%08x\n\n",
+ fn_caller_name, source, line, fn_callee_addr, fn_ret);
+ else
+ bytes = __ntapi->sprintf(
+ dbg_buf,
+ "%s: calling 0x%08x returned 0x%08x\n\n",
+ fn_caller_name, fn_callee_addr, fn_ret);
+
+ if (bytes) {
+ bytes = __ntapi->strlen(dbg_buf);
+
+ if (bytes == pfn_dbg_write(hfile,dbg_buf,bytes))
+ return NT_STATUS_SUCCESS;
+ else
+ return NT_STATUS_UNSUCCESSFUL;
+ } else
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+
+int32_t __cdecl __dbg_msg(
+ __in void * hfile __optional,
+ __in char * source __optional,
+ __in int line __optional,
+ __in char * fn_caller_name,
+ __in char * fmt,
+ __in uintptr_t arg1,
+ __in uintptr_t arg2,
+ __in uintptr_t arg3,
+ __in uintptr_t arg4,
+ __in uintptr_t arg5,
+ __in uintptr_t arg6,
+ __in ntapi_dbg_write* pfn_dbg_write __optional)
+{
+ char * buffer;
+ size_t bytes;
+
+ if (!pfn_dbg_write)
+ pfn_dbg_write = __dbg_write;
+
+ bytes = 0;
+ buffer = dbg_buf;
+
+ if (source)
+ bytes = __ntapi->sprintf(
+ buffer,
+ "%s: (%s:%d):\n--> ",
+ fn_caller_name,source,line);
+ else if (fn_caller_name)
+ bytes = __ntapi->sprintf(
+ buffer,
+ "%s: ",
+ fn_caller_name);
+ else
+ dbg_buf[0] = '\0';
+
+ if (bytes >= 0)
+ buffer += __ntapi->strlen(dbg_buf);
+ else
+ return NT_STATUS_UNSUCCESSFUL;
+
+ bytes = __ntapi->sprintf(buffer,fmt,arg1,arg2,arg3,arg4,arg5,arg6);
+
+ if (bytes) {
+ bytes = __ntapi->strlen(dbg_buf);
+
+ if (bytes == pfn_dbg_write(hfile,dbg_buf,bytes))
+ return NT_STATUS_SUCCESS;
+ else
+ return NT_STATUS_UNSUCCESSFUL;
+ } else
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+#endif
diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h
new file mode 100644
index 0000000..4474334
--- /dev/null
+++ b/src/internal/ntapi_fnapi.h
@@ -0,0 +1,262 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#ifndef ___NTAPI_FNAPI_H_
+#define ___NTAPI_FNAPI_H_
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_hash_table.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* internal prototypes */
+typedef int32_t __stdcall ntapi_tt_create_remote_runtime_data(
+ __in void * hprocess,
+ __in_out nt_runtime_data_block * runtime_data);
+
+typedef void ** __cdecl ntapi_tt_get_csr_port_handle_addr_by_logic(void);
+
+/* nt_object.h */
+ntapi_tt_create_keyed_object_directory __ntapi_tt_create_keyed_object_directory;
+ntapi_tt_open_keyed_object_directory __ntapi_tt_open_keyed_object_directory;
+ntapi_tt_create_keyed_object_directory_entry __ntapi_tt_create_keyed_object_directory_entry;
+
+/* nt_crc32.h */
+ntapi_tt_buffer_crc32 __ntapi_tt_buffer_crc32;
+ntapi_tt_mbstr_crc32 __ntapi_tt_mbstr_crc32;
+ntapi_tt_crc32_table __ntapi_tt_crc32_table;
+
+/* nt_file.h */
+ntapi_tt_get_file_handle_type __ntapi_tt_get_file_handle_type;
+ntapi_tt_open_logical_parent_directory __ntapi_tt_open_logical_parent_directory;
+ntapi_tt_open_physical_parent_directory __ntapi_tt_open_physical_parent_directory;
+
+
+/* nt_ipc.h */
+ntapi_ipc_create_pipe __ntapi_ipc_create_pipe_v1;
+ntapi_ipc_create_pipe __ntapi_ipc_create_pipe_v2;
+
+/* nt_ldr */
+ntapi_ldr_load_system_dll __ntapi_ldr_load_system_dll;
+ntapi_ldr_create_state_snapshot __ntapi_ldr_create_state_snapshot;
+ntapi_ldr_revert_state_to_snapshot __ntapi_ldr_revert_state_to_snapshot;
+
+/* nt_string.h */
+ntapi_tt_string_null_offset_multibyte __ntapi_tt_string_null_offset_multibyte;
+ntapi_tt_string_null_offset_short __ntapi_tt_string_null_offset_short;
+ntapi_tt_string_null_offset_dword __ntapi_tt_string_null_offset_dword;
+ntapi_tt_string_null_offset_qword __ntapi_tt_string_null_offset_qword;
+ntapi_tt_string_null_offset_ptrsize __ntapi_tt_string_null_offset_ptrsize;
+ntapi_wcslen __ntapi_wcslen;
+ntapi_tt_aligned_block_memset __ntapi_tt_aligned_block_memset;
+ntapi_tt_aligned_block_memcpy __ntapi_tt_aligned_block_memcpy;
+ntapi_tt_init_unicode_string_from_utf16 __ntapi_tt_init_unicode_string_from_utf16;
+ntapi_tt_memcpy_utf16 __ntapi_tt_memcpy_utf16;
+ntapi_tt_aligned_memcpy_utf16 __ntapi_tt_aligned_memcpy_utf16;
+ntapi_tt_generic_memset __ntapi_tt_generic_memset;
+ntapi_tt_generic_memcpy __ntapi_tt_generic_memcpy;
+ntapi_tt_uint16_to_hex_utf16 __ntapi_tt_uint16_to_hex_utf16;
+ntapi_tt_uint32_to_hex_utf16 __ntapi_tt_uint32_to_hex_utf16;
+ntapi_tt_uint64_to_hex_utf16 __ntapi_tt_uint64_to_hex_utf16;
+ntapi_tt_uintptr_to_hex_utf16 __ntapi_tt_uintptr_to_hex_utf16;
+ntapi_tt_hex_utf16_to_uint16 __ntapi_tt_hex_utf16_to_uint16;
+ntapi_tt_hex_utf16_to_uint32 __ntapi_tt_hex_utf16_to_uint32;
+ntapi_tt_hex_utf16_to_uint64 __ntapi_tt_hex_utf16_to_uint64;
+ntapi_tt_hex_utf16_to_uintptr __ntapi_tt_hex_utf16_to_uintptr;
+ntapi_tt_uint16_to_hex_utf8 __ntapi_tt_uint16_to_hex_utf8;
+ntapi_tt_uint32_to_hex_utf8 __ntapi_tt_uint32_to_hex_utf8;
+ntapi_tt_uint64_to_hex_utf8 __ntapi_tt_uint64_to_hex_utf8;
+ntapi_tt_uintptr_to_hex_utf8 __ntapi_tt_uintptr_to_hex_utf8;
+
+/* nt_guid.h */
+ntapi_tt_guid_to_utf16_string __ntapi_tt_guid_to_utf16_string;
+ntapi_tt_utf16_string_to_guid __ntapi_tt_utf16_string_to_guid;
+
+/* nt_sysinfo.h */
+ntapi_tt_get_system_directory_native_path __ntapi_tt_get_system_directory_native_path;
+ntapi_tt_get_system_directory_dos_path __ntapi_tt_get_system_directory_dos_path;
+ntapi_tt_get_system_directory_handle __ntapi_tt_get_system_directory_handle;
+ntapi_tt_get_system_info_snapshot __ntapi_tt_get_system_info_snapshot;
+
+/* nt_thread.h */
+ntapi_tt_create_thread __ntapi_tt_create_thread;
+ntapi_tt_create_local_thread __ntapi_tt_create_local_thread;
+ntapi_tt_create_remote_thread __ntapi_tt_create_remote_thread;
+
+/* nt_process.h */
+ntapi_tt_fork __ntapi_tt_fork_v1;
+ntapi_tt_fork __ntapi_tt_fork_v2;
+ntapi_tt_create_remote_process_params __ntapi_tt_create_remote_process_params;
+ntapi_tt_create_remote_runtime_data __ntapi_tt_create_remote_runtime_data;
+ntapi_tt_create_native_process __ntapi_tt_create_native_process_v1;
+ntapi_tt_create_native_process __ntapi_tt_create_native_process_v2;
+ntapi_tt_get_runtime_data __ntapi_tt_get_runtime_data;
+ntapi_tt_init_runtime_data __ntapi_tt_init_runtime_data;
+ntapi_tt_update_runtime_data __ntapi_tt_update_runtime_data;
+ntapi_tt_exec_map_image_as_data __ntapi_tt_exec_map_image_as_data;
+ntapi_tt_exec_unmap_image __ntapi_tt_exec_unmap_image;
+
+/* nt_section.h */
+ntapi_tt_get_section_name __ntapi_tt_get_section_name;
+
+/* nt_sync.h */
+ntapi_tt_create_inheritable_event __ntapi_tt_create_inheritable_event;
+ntapi_tt_create_private_event __ntapi_tt_create_private_event;
+ntapi_tt_wait_for_dummy_event __ntapi_tt_wait_for_dummy_event;
+ntapi_tt_sync_block_init __ntapi_tt_sync_block_init;
+ntapi_tt_sync_block_lock __ntapi_tt_sync_block_lock;
+ntapi_tt_sync_block_server_lock __ntapi_tt_sync_block_server_lock;
+ntapi_tt_sync_block_unlock __ntapi_tt_sync_block_unlock;
+ntapi_tt_sync_block_invalidate __ntapi_tt_sync_block_invalidate;
+
+/* nt_port.h */
+ntapi_tt_port_guid_from_type __ntapi_tt_port_guid_from_type;
+ntapi_tt_port_type_from_guid __ntapi_tt_port_type_from_guid;
+ntapi_tt_port_generate_keys __ntapi_tt_port_generate_keys;
+ntapi_tt_port_format_keys __ntapi_tt_port_format_keys;
+ntapi_tt_port_name_from_attributes __ntapi_tt_port_name_from_attributes;
+
+/* nt_argv.h */
+ntapi_tt_get_cmd_line_utf16 __ntapi_tt_get_cmd_line_utf16;
+ntapi_tt_get_peb_env_block_utf16 __ntapi_tt_get_peb_env_block_utf16;
+ntapi_tt_parse_cmd_line_args_utf16 __ntapi_tt_parse_cmd_line_args_utf16;
+ntapi_tt_get_argv_envp_utf8 __ntapi_tt_get_argv_envp_utf8;
+ntapi_tt_get_argv_envp_utf16 __ntapi_tt_get_argv_envp_utf16;
+ntapi_tt_get_env_var_meta_utf16 __ntapi_tt_get_env_var_meta_utf16;
+ntapi_tt_get_short_option_meta_utf16 __ntapi_tt_get_short_option_meta_utf16;
+ntapi_tt_get_long_option_meta_utf16 __ntapi_tt_get_long_option_meta_utf16;
+ntapi_tt_array_copy_utf8 __ntapi_tt_array_copy_utf8;
+ntapi_tt_array_copy_utf16 __ntapi_tt_array_copy_utf16;
+ntapi_tt_array_convert_utf8_to_utf16 __ntapi_tt_array_convert_utf8_to_utf16;
+ntapi_tt_array_convert_utf16_to_utf8 __ntapi_tt_array_convert_utf16_to_utf8;
+
+/* nt_blitter.h */
+ntapi_blt_alloc __ntapi_blt_alloc;
+ntapi_blt_free __ntapi_blt_free;
+ntapi_blt_acquire __ntapi_blt_acquire;
+ntapi_blt_obtain __ntapi_blt_obtain;
+ntapi_blt_possess __ntapi_blt_possess;
+ntapi_blt_release __ntapi_blt_release;
+ntapi_blt_get __ntapi_blt_get;
+ntapi_blt_set __ntapi_blt_set;
+
+/* nt_unicode.h */
+ntapi_uc_validate_unicode_stream_utf8 __ntapi_uc_validate_unicode_stream_utf8;
+ntapi_uc_validate_unicode_stream_utf16 __ntapi_uc_validate_unicode_stream_utf16;
+ntapi_uc_get_code_point_byte_count_utf8 __ntapi_uc_get_code_point_byte_count_utf8;
+ntapi_uc_get_code_point_byte_count_utf16 __ntapi_uc_get_code_point_byte_count_utf16;
+ntapi_uc_convert_unicode_stream_utf8_to_utf16 __ntapi_uc_convert_unicode_stream_utf8_to_utf16;
+ntapi_uc_convert_unicode_stream_utf8_to_utf32 __ntapi_uc_convert_unicode_stream_utf8_to_utf32;
+ntapi_uc_convert_unicode_stream_utf16_to_utf8 __ntapi_uc_convert_unicode_stream_utf16_to_utf8;
+ntapi_uc_convert_unicode_stream_utf16_to_utf32 __ntapi_uc_convert_unicode_stream_utf16_to_utf32;
+
+
+/* nt_daemon.h */
+ntapi_dsr_init __ntapi_dsr_init;
+ntapi_dsr_start __ntapi_dsr_start;
+ntapi_dsr_create_port __ntapi_dsr_create_port;
+ntapi_dsr_connect_internal_client __ntapi_dsr_connect_internal_client;
+ntapi_dsr_internal_client_connect __ntapi_dsr_internal_client_connect;
+
+/* nt_vfd.h */
+ntapi_vfd_dev_name_init __ntapi_vfd_dev_name_init;
+
+/* nt_tty.h */
+ntapi_tty_create_session __ntapi_tty_create_session;
+ntapi_tty_join_session __ntapi_tty_join_session;
+ntapi_tty_connect __ntapi_tty_connect;
+ntapi_tty_client_session_query __ntapi_tty_client_session_query;
+ntapi_tty_client_session_set __ntapi_tty_client_session_set;
+ntapi_tty_client_process_register __ntapi_tty_client_process_register;
+ntapi_tty_query_information_server __ntapi_tty_query_information_server;
+ntapi_tty_request_peer __ntapi_tty_request_peer;
+ntapi_tty_vms_query __ntapi_tty_vms_query;
+ntapi_tty_vms_request __ntapi_tty_vms_request;
+ntapi_pty_open __ntapi_pty_open;
+ntapi_pty_reopen __ntapi_pty_reopen;
+ntapi_pty_close __ntapi_pty_close;
+ntapi_pty_read __ntapi_pty_read;
+ntapi_pty_write __ntapi_pty_write;
+ntapi_pty_ioctl __ntapi_pty_ioctl;
+ntapi_pty_query __ntapi_pty_query;
+ntapi_pty_set __ntapi_pty_set;
+ntapi_pty_cancel __ntapi_pty_cancel;
+
+/* nt_socket.h */
+ntapi_sc_socket __ntapi_sc_socket_v1;
+ntapi_sc_socket __ntapi_sc_socket_v2;
+ntapi_sc_bind __ntapi_sc_bind_v1;
+ntapi_sc_bind __ntapi_sc_bind_v2;
+ntapi_sc_connect __ntapi_sc_connect_v1;
+ntapi_sc_connect __ntapi_sc_connect_v2;
+ntapi_sc_getsockname __ntapi_sc_getsockname_v1;
+ntapi_sc_getsockname __ntapi_sc_getsockname_v2;
+ntapi_sc_server_accept_connection __ntapi_sc_server_accept_connection_v1;
+ntapi_sc_server_accept_connection __ntapi_sc_server_accept_connection_v2;
+ntapi_sc_server_duplicate_socket __ntapi_sc_server_duplicate_socket;
+ntapi_sc_listen __ntapi_sc_listen;
+ntapi_sc_accept __ntapi_sc_accept;
+ntapi_sc_send __ntapi_sc_send;
+ntapi_sc_recv __ntapi_sc_recv;
+ntapi_sc_shutdown __ntapi_sc_shutdown;
+ntapi_sc_wait __ntapi_sc_wait;
+
+/* nt_mount.h */
+ntapi_tt_get_dos_drive_device_handle __ntapi_tt_get_dos_drive_device_handle;
+ntapi_tt_get_dos_drive_root_handle __ntapi_tt_get_dos_drive_root_handle;
+ntapi_tt_get_dos_drive_device_name __ntapi_tt_get_dos_drive_device_name;
+ntapi_tt_get_dos_drive_mount_points __ntapi_tt_get_dos_drive_mount_points;
+ntapi_tt_dev_mount_points_to_statfs __ntapi_tt_dev_mount_points_to_statfs;
+ntapi_tt_get_dos_drive_letter_from_device __ntapi_tt_get_dos_drive_letter_from_device;
+
+/* nt_istat.h */
+ntapi_tt_istat __ntapi_tt_istat;
+ntapi_tt_validate_fs_handle __ntapi_tt_validate_fs_handle;
+
+/* nt_stat.h */
+ntapi_tt_stat __ntapi_tt_stat;
+
+/* nt_statfs.h */
+ntapi_tt_statfs __ntapi_tt_statfs;
+
+/* nt_vmount.h */
+ntapi_vms_get_node_by_dev_name __ntapi_vms_get_node_by_dev_name;
+ntapi_vms_get_node_by_end_component __ntapi_vms_get_node_by_end_component;
+ntapi_vms_cache_alloc __ntapi_vms_cache_alloc;
+ntapi_vms_cache_free __ntapi_vms_cache_free;
+ntapi_vms_client_connect __ntapi_vms_client_connect;
+ntapi_vms_client_disconnect __ntapi_vms_client_disconnect;
+ntapi_vms_point_attach __ntapi_vms_point_attach;
+ntapi_vms_point_get_handles __ntapi_vms_point_get_handles;
+ntapi_vms_ref_count_inc __ntapi_vms_ref_count_inc;
+ntapi_vms_ref_count_dec __ntapi_vms_ref_count_dec;
+ntapi_vms_table_query __ntapi_vms_table_query;
+
+/* nt_hashes.h */
+ntapi_tt_populate_hashed_import_table __ntapi_tt_populate_hashed_import_table;
+
+/* nt_guid.h */
+ntapi_tt_guid_copy __ntapi_tt_guid_copy;
+ntapi_tt_guid_compare __ntapi_tt_guid_compare;
+ntapi_tt_guid_to_utf16_string __ntapi_tt_guid_to_utf16_string;
+ntapi_tt_utf16_string_to_guid __ntapi_tt_utf16_string_to_guid;
+
+/* debug */
+ntapi_dbg_write __dbg_write;
+ntapi_dbg_fn_call __dbg_fn_call;
+ntapi_dbg_msg __dbg_msg;
+
+/* csrss */
+ntapi_tt_get_csr_port_handle_addr_by_logic __GET_CSR_PORT_HANDLE_BY_LOGIC;
+ntapi_csr_port_handle __ntapi_csr_port_handle;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/internal/ntapi_hash_table.h b/src/internal/ntapi_hash_table.h
new file mode 100644
index 0000000..727e4f2
--- /dev/null
+++ b/src/internal/ntapi_hash_table.h
@@ -0,0 +1,266 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#ifndef ___NTAPI_HASH_TABLE_H_
+#define ___NTAPI_HASH_TABLE_H_
+
+#include <psxtypes/psxtypes.h>
+
+#define __NTAPI_HASH_TABLE \
+ {0x000f6dee, (150)}, /* CsrPortHandle */ \
+ {0x00b3a87b, (30)}, /* ZwMapUserPhysicalPages */ \
+ {0x011c4489, (95)}, /* ZwPulseEvent */ \
+ {0x02513506, (39)}, /* ZwAreMappedFilesTheSame */ \
+ {0x034a4430, (63)}, /* RtlCreateProcessParameters */ \
+ {0x03bb7a3c, (187)}, /* ZwRestoreKey */ \
+ {0x04e21f45, (75)}, /* ZwCreateToken */ \
+ {0x04f94dc4, (190)}, /* ZwUnloadKey */ \
+ {0x06125322, (216)}, /* ZwAccessCheckByTypeResultListAndAuditAlarmByHandle */ \
+ {0x06b550e3, (146)}, /* ZwWriteRequestData */ \
+ {0x0708114b, (50)}, /* ZwTestAlert */ \
+ {0x08087626, (34)}, /* ZwOpenSection */ \
+ {0x08b1918f, (45)}, /* ZwSuspendThread */ \
+ {0x097e0efd, (154)}, /* ZwOpenFile */ \
+ {0x0a7a10d0, (88)}, /* ZwOpenTimer */ \
+ {0x0a83f5d6, (191)}, /* ZwQueryOpenSubKeys */ \
+ {0x0bd77556, (218)}, /* ZwSetThreadExecutionState */ \
+ {0x0c5cf449, (168)}, /* ZwQueryEaFile */ \
+ {0x0d638bd2, (74)}, /* ZwSetInformationJobObject */ \
+ {0x0e629eed, (102)}, /* ZwQuerySemaphore */ \
+ {0x11fcbb7c, (23)}, /* ZwReadVirtualMemory */ \
+ {0x124a301e, (16)}, /* ZwSetSystemEnvironmentValue */ \
+ {0x12ec66eb, (227)}, /* ZwQueryDefaultLocale */ \
+ {0x1742c5c9, (162)}, /* ZwWriteFileGather */ \
+ {0x177157e3, (42)}, /* ZwTerminateThread */ \
+ {0x1af41c1a, (22)}, /* ZwProtectVirtualMemory */ \
+ {0x1c0197e6, (233)}, /* ZwAllocateUuids */ \
+ {0x1c7a90a1, (5)}, /* ZwQuerySecurityObject */ \
+ {0x1cf668c5, (194)}, /* ZwQueryKey */ \
+ {0x2259fc62, (2)}, /* ZwDuplicateObject */ \
+ {0x24e09c64, (18)}, /* ZwSystemDebugControl */ \
+ {0x255bf138, (142)}, /* ZwReplyWaitReplyPort */ \
+ {0x25684721, (76)}, /* ZwOpenProcessToken */ \
+ {0x25d91d90, (71)}, /* ZwTerminateJobObject */ \
+ {0x26e1170e, (193)}, /* ZwSetInformationKey */ \
+ {0x27dd46c3, (29)}, /* ZwFreeUserPhysicalPages */ \
+ {0x2812eb3c, (232)}, /* ZwAllocateLocallyUniqueId */ \
+ {0x28574a3f, (77)}, /* ZwOpenThreadToken */ \
+ {0x29b5ea3d, (140)}, /* ZwRequestWaitReplyPort */ \
+ {0x2a6ac6fb, (26)}, /* ZwUnlockVirtualMemory */ \
+ {0x2aad9aed, (83)}, /* ZwSetInformationToken */ \
+ {0x2b2356f7, (52)}, /* ZwAlertResumeThread */ \
+ {0x2c0f001a, (230)}, /* ZwSetDefaultUILanguage */ \
+ {0x2f22b634, (96)}, /* ZwResetEvent */ \
+ {0x30309daa, (170)}, /* ZwCreateNamedPipeFile */ \
+ {0x3064d37b, (68)}, /* RtlQueryProcessDebugInformation */ \
+ {0x30911e3f, (196)}, /* ZwNotifyChangeKey */ \
+ {0x32ad44f5, (73)}, /* ZwQueryInformationJobObject */ \
+ {0x33a33c40, (163)}, /* ZwLockFile */ \
+ {0x357f8a82, (36)}, /* ZwExtendSection */ \
+ {0x3753c2c8, (198)}, /* ZwDeleteValueKey */ \
+ {0x379a6717, (93)}, /* ZwOpenEvent */ \
+ {0x391b8d79, (157)}, /* ZwCancelIoFile */ \
+ {0x3928a4cc, (20)}, /* ZwFreeVirtualMemory */ \
+ {0x39bea937, (89)}, /* ZwCancelTimer */ \
+ {0x3abffc38, (239)}, /* ZwFlushWriteBuffer */ \
+ {0x3b1f8d85, (124)}, /* ZwQueryTimerResolution */ \
+ {0x3d4aceeb, (248)}, /* memset */ \
+ {0x3e1d331d, (44)}, /* ZwSetInformationThread */ \
+ {0x3f62370b, (204)}, /* ZwPrivilegeCheck */ \
+ {0x416c4024, (118)}, /* ZwSetLowWaitHighEventPair */ \
+ {0x43c1745d, (92)}, /* ZwCreateEvent */ \
+ {0x43d65de2, (231)}, /* ZwQueryInstallUILanguage */ \
+ {0x45d7086f, (108)}, /* ZwOpenIoCompletion */ \
+ {0x465977c0, (129)}, /* ZwQueryIntervalProfile */ \
+ {0x47b3fd39, (8)}, /* ZwOpenDirectoryObject */ \
+ {0x47dd6896, (171)}, /* ZwCreateMailslotFile */ \
+ {0x49d62b40, (246)}, /* LdrLoadDll */ \
+ {0x4a638203, (91)}, /* ZwQueryTimer */ \
+ {0x4c51093e, (189)}, /* ZwLoadKey2 */ \
+ {0x4cb0ea34, (206)}, /* ZwPrivilegedServiceAuditAlarm */ \
+ {0x4cc741f4, (222)}, /* ZwPowerInformation */ \
+ {0x4d0aa736, (207)}, /* ZwAccessCheck */ \
+ {0x4d361035, (181)}, /* ZwCreateKey */ \
+ {0x4de0faef, (10)}, /* ZwCreateSymbolicLinkObject */ \
+ {0x4e049b9b, (72)}, /* ZwAssignProcessToJobObject */ \
+ {0x4ed4c833, (0)}, /* ZwQueryObject */ \
+ {0x4efff89a, (166)}, /* ZwFsControlFile */ \
+ {0x4fe5a956, (49)}, /* ZwQueueApcThread */ \
+ {0x50f7777d, (84)}, /* ZwWaitForSingleObject */ \
+ {0x513877ab, (61)}, /* ZwSetInformationProcess */ \
+ {0x51d5c98d, (137)}, /* ZwAcceptConnectPort */ \
+ {0x51ddffce, (242)}, /* ZwDisplayString */ \
+ {0x51fbe1c4, (165)}, /* ZwDeviceIoControlFile */ \
+ {0x52334a05, (213)}, /* ZwDeleteObjectAuditAlarm */ \
+ {0x5288a7cf, (46)}, /* ZwResumeThread */ \
+ {0x54a89e87, (131)}, /* ZwStopProfile */ \
+ {0x56ada303, (185)}, /* ZwSaveKey */ \
+ {0x57dd87c6, (114)}, /* ZwWaitLowEventPair */ \
+ {0x5879157d, (241)}, /* ZwSetDefaultHardErrorPort */ \
+ {0x58b766a7, (200)}, /* ZwQueryValueKey */ \
+ {0x59d0cf7f, (9)}, /* ZwQueryDirectoryObject */ \
+ {0x5a201018, (180)}, /* ZwSetInformationFile */ \
+ {0x5b24a650, (155)}, /* ZwDeleteFile */ \
+ {0x5cc5b0cc, (149)}, /* CsrClientCallServer */ \
+ {0x5ccb443b, (245)}, /* ZwVdmControl */ \
+ {0x5d5b0c74, (15)}, /* ZwQuerySystemEnvironmentValue */ \
+ {0x5dcf9e33, (205)}, /* ZwPrivilegeObjectAuditAlarm */ \
+ {0x5f3fb511, (164)}, /* ZwUnlockFile */ \
+ {0x60ebf65f, (120)}, /* ZwQuerySystemTime */ \
+ {0x63033516, (244)}, /* ZwSetLdtEntries */ \
+ {0x63cc9e64, (66)}, /* RtlCreateQueryDebugBuffer */ \
+ {0x64a2ceb5, (56)}, /* ZwCreateProcess */ \
+ {0x654da6fd, (143)}, /* ZwReplyWaitReceivePort */ \
+ {0x6570064e, (243)}, /* ZwCreatePagingFile */ \
+ {0x65b5374b, (14)}, /* ZwSetSystemInformation */ \
+ {0x6a2d88fc, (126)}, /* ZwYieldExecution */ \
+ {0x6c1b25c0, (97)}, /* ZwClearEvent */ \
+ {0x6db16208, (238)}, /* ZwQueryInformationAtom */ \
+ {0x6e0c0f9d, (65)}, /* RtlNormalizeProcessParams */ \
+ {0x6f11895e, (217)}, /* ZwIsSystemResumeAutomatic */ \
+ {0x7160272d, (144)}, /* ZwReplyWaitReceivePortEx */ \
+ {0x72f83a29, (67)}, /* RtlDestroyQueryDebugBuffer */ \
+ {0x73349dea, (160)}, /* ZwWriteFile */ \
+ {0x75e01428, (111)}, /* ZwQueryIoCompletion */ \
+ {0x75e970e4, (115)}, /* ZwSetLowEventPair */ \
+ {0x7683000f, (38)}, /* ZwUnmapViewOfSection */ \
+ {0x76d9a68b, (159)}, /* ZwReadFile */ \
+ {0x7783f5c4, (98)}, /* ZwQueryEvent */ \
+ {0x78327b0d, (173)}, /* ZwSetVolumeInformationFile */ \
+ {0x78a28538, (80)}, /* ZwAdjustPrivilegesToken */ \
+ {0x7b9f9b64, (182)}, /* ZwOpenKey */ \
+ {0x7ccd8968, (138)}, /* ZwCompleteConnectPort */ \
+ {0x7dfb3677, (169)}, /* ZwSetEaFile */ \
+ {0x7e21039a, (87)}, /* ZwCreateTimer */ \
+ {0x7ec723c2, (122)}, /* ZwQueryPerformanceCounter */ \
+ {0x7f99ab33, (145)}, /* ZwReadRequestData */ \
+ {0x81b18dcd, (21)}, /* ZwQueryVirtualMemory */ \
+ {0x842e9cbb, (43)}, /* ZwQueryInformationThread */ \
+ {0x84d52359, (112)}, /* ZwCreateEventPair */ \
+ {0x84e3898f, (183)}, /* ZwDeleteKey */ \
+ {0x850106f7, (7)}, /* ZwCreateDirectoryObject */ \
+ {0x8548dfbd, (106)}, /* ZwQueryMutant */ \
+ {0x85f069ec, (197)}, /* ZwNotifyChangeMultipleKeys */ \
+ {0x87763935, (249)}, /* sprintf */ \
+ {0x87fd0a60, (24)}, /* ZwWriteVirtualMemory */ \
+ {0x8a1989d8, (136)}, /* ZwListenPort */ \
+ {0x8afaa2ca, (31)}, /* ZwGetWriteWatch */ \
+ {0x8b3aacc6, (174)}, /* ZwQueryQuotaInformationFile */ \
+ {0x8bf01eb2, (135)}, /* ZwSecureConnectPort */ \
+ {0x8c4a9ca2, (100)}, /* ZwOpenSemaphore */ \
+ {0x8cb632f5, (17)}, /* ZwShutdownSystem */ \
+ {0x8d31519d, (58)}, /* ZwOpenProcess */ \
+ {0x8d5b0647, (53)}, /* ZwRegisterThreadTerminatePort */ \
+ {0x8df4b3ed, (158)}, /* ZwCancelIoFileEx */ \
+ {0x8e80b080, (119)}, /* ZwSetHighWaitLowEventPair */ \
+ {0x8eb2c33b, (121)}, /* ZwSetSystemTime */ \
+ {0x8fe01ce6, (4)}, /* ZwClose */ \
+ {0x8ffaebe4, (70)}, /* ZwOpenJobObject */ \
+ {0x90bf911c, (177)}, /* ZwQueryFullAttributesFile */ \
+ {0x920b0183, (116)}, /* ZwWaitHighEventPair */ \
+ {0x9331fae3, (25)}, /* ZwLockVirtualMemory */ \
+ {0x9384c236, (103)}, /* ZwCreateMutant */ \
+ {0x93e64266, (130)}, /* ZwStartProfile */ \
+ {0x949f76b6, (19)}, /* ZwAllocateVirtualMemory */ \
+ {0x956ba548, (11)}, /* ZwOpenSymbolicLinkObject */ \
+ {0x963cafbc, (229)}, /* ZwQueryDefaultUILanguage */ \
+ {0x9731aded, (178)}, /* ZwQueryDirectoryFile */ \
+ {0x978855cd, (37)}, /* ZwMapViewOfSection */ \
+ {0x98058c5c, (86)}, /* ZwWaitForMultipleObjects */ \
+ {0x997388d8, (237)}, /* ZwDeleteAtom */ \
+ {0x9bf04a73, (172)}, /* ZwQueryVolumeInformationFile */ \
+ {0x9c805856, (167)}, /* ZwNotifyChangeDirectoryFile */ \
+ {0x9d9c64db, (186)}, /* ZwSaveMergedKeys */ \
+ {0x9fb42181, (79)}, /* ZwFilterToken */ \
+ {0x9fce5072, (57)}, /* ZwCreateUserProcess */ \
+ {0xa09dea3c, (192)}, /* ZwReplaceKey */ \
+ {0xa313f9b0, (220)}, /* ZwSetSystemPowerState */ \
+ {0xa34a43e1, (48)}, /* ZwSetContextThread */ \
+ {0xa51616fd, (156)}, /* ZwFlushBuffersFile */ \
+ {0xa589ce00, (226)}, /* ZwContinue */ \
+ {0xa5b2c609, (117)}, /* ZwSetHighEventPair */ \
+ {0xa8720028, (153)}, /* ZwCreateFile */ \
+ {0xa93301f4, (110)}, /* ZwRemoveIoCompletion */ \
+ {0xa9e5e651, (199)}, /* ZwSetValueKey */ \
+ {0xabc87b74, (32)}, /* ZwResetWriteWatch */ \
+ {0xac5765bd, (211)}, /* ZwOpenObjectAuditAlarm */ \
+ {0xac77c9d4, (47)}, /* ZwGetContextThread */ \
+ {0xaccf3eee, (214)}, /* ZwAccessCheckByTypeAndAuditAlarm */ \
+ {0xacdddfe2, (176)}, /* ZwQueryAttributesFile */ \
+ {0xafe64c80, (179)}, /* ZwQueryInformationFile */ \
+ {0xb28fcd19, (1)}, /* ZwSetInformationObject */ \
+ {0xb2adc219, (209)}, /* ZwAccessCheckByType */ \
+ {0xb32b8a16, (41)}, /* ZwOpenThread */ \
+ {0xb39f2b58, (128)}, /* ZwSetIntervalProfile */ \
+ {0xb3a5ef4c, (64)}, /* RtlDestroyProcessParameters */ \
+ {0xb3d90f63, (60)}, /* ZwQueryInformationProcess */ \
+ {0xb3f8b8ba, (184)}, /* ZwFlushKey */ \
+ {0xb468e7d0, (225)}, /* ZwRaiseException */ \
+ {0xb4f463e1, (175)}, /* ZwSetQuotaInformationFile */ \
+ {0xb5ce95b0, (109)}, /* ZwSetIoCompletion */ \
+ {0xb677bd15, (219)}, /* ZwGetDevicePowerState */ \
+ {0xb891d19c, (141)}, /* ZwReplyPort */ \
+ {0xba08cfed, (221)}, /* ZwInitiatePowerAction */ \
+ {0xba5bdfc3, (234)}, /* ZwSetUuidSeed */ \
+ {0xbc310050, (133)}, /* ZwCreateWaitablePort */ \
+ {0xbde7d8d1, (151)}, /* ZwLoadDriver */ \
+ {0xbe9990b9, (134)}, /* ZwConnectPort */ \
+ {0xc0040fd0, (90)}, /* ZwSetTimer */ \
+ {0xc00fc05c, (240)}, /* ZwRaiseHardError */ \
+ {0xc4bd0fda, (99)}, /* ZwCreateSemaphore */ \
+ {0xc524def2, (148)}, /* ZwImpersonateClientOfPort */ \
+ {0xc6a277e0, (236)}, /* ZwFindAtom */ \
+ {0xc6de9ce3, (139)}, /* ZwRequestPort */ \
+ {0xc707f028, (27)}, /* ZwFlushVirtualMemory */ \
+ {0xc70d789c, (69)}, /* ZwCreateJobObject */ \
+ {0xc71b989a, (78)}, /* ZwDuplicateToken */ \
+ {0xc7835b75, (195)}, /* ZwEnumerateKey */ \
+ {0xc7d8afa4, (85)}, /* ZwSignalAndWaitForSingleObject */ \
+ {0xc94ea8a6, (81)}, /* ZwAdjustGroupsToken */ \
+ {0xc9f42a5d, (235)}, /* ZwAddAtom */ \
+ {0xca250552, (210)}, /* ZwAccessCheckByTypeResultList */ \
+ {0xcaf1f803, (152)}, /* ZwUnloadDriver */ \
+ {0xcb3c8251, (223)}, /* ZwPlugPlayControl */ \
+ {0xcc22b021, (113)}, /* ZwOpenEventPair */ \
+ {0xcdb98ed4, (59)}, /* ZwTerminateProcess */ \
+ {0xced9d11d, (123)}, /* ZwSetTimerResolution */ \
+ {0xd4191071, (127)}, /* ZwCreateProfile */ \
+ {0xd48a2bbc, (40)}, /* ZwCreateThread */ \
+ {0xd517401d, (54)}, /* ZwImpersonateThread */ \
+ {0xd5a16cee, (51)}, /* ZwAlertThread */ \
+ {0xd628c8f6, (228)}, /* ZwSetDefaultLocale */ \
+ {0xd7fef93d, (201)}, /* ZwEnumerateValueKey */ \
+ {0xda57df71, (247)}, /* LdrUnloadDll */ \
+ {0xdaa7575e, (215)}, /* ZwAccessCheckByTypeResultListAndAuditAlarm */ \
+ {0xde07d08f, (224)}, /* ZwGetPlugPlayEvent */ \
+ {0xde5468ed, (202)}, /* ZwQueryMultipleValueKey */ \
+ {0xdf8698ed, (13)}, /* ZwQuerySystemInformation */ \
+ {0xdf86b31f, (6)}, /* ZwSetSecurityObject */ \
+ {0xe0c1d02e, (55)}, /* ZwImpersonateAnonymousToken */ \
+ {0xe1562f17, (3)}, /* ZwMakeTemporaryObject */ \
+ {0xe19be90e, (33)}, /* ZwCreateSection */ \
+ {0xe23ef886, (161)}, /* ZwReadFileScatter */ \
+ {0xe2ff4b82, (188)}, /* ZwLoadKey */ \
+ {0xe3521fd4, (101)}, /* ZwReleaseSemaphore */ \
+ {0xe3624a9b, (212)}, /* ZwCloseObjectAuditAlarm */ \
+ {0xe3ae76c7, (132)}, /* ZwCreatePort */ \
+ {0xe43a3a6f, (147)}, /* ZwQueryInformationPort */ \
+ {0xe624ac47, (12)}, /* ZwQuerySymbolicLinkObject */ \
+ {0xe6a6cc2d, (208)}, /* ZwAccessCheckAndAuditAlarm */ \
+ {0xe8d1aec4, (105)}, /* ZwReleaseMutant */ \
+ {0xeb69e74d, (62)}, /* ZwFlushInstructionCache */ \
+ {0xed4a67c1, (28)}, /* ZwAllocateUserPhysicalPages */ \
+ {0xed5deedd, (107)}, /* ZwCreateIoCompletion */ \
+ {0xedac7230, (203)}, /* ZwInitializeRegistry */ \
+ {0xee535edc, (35)}, /* ZwQuerySection */ \
+ {0xee5cdc2d, (82)}, /* ZwQueryInformationToken */ \
+ {0xf3d1faa7, (125)}, /* ZwDelayExecution */ \
+ {0xf425639c, (104)}, /* ZwOpenMutant */ \
+ {0xfde47817, (94)}, /* ZwSetEvent */ \
+
+#define __NT_IMPORTED_SYMBOLS_ARRAY_SIZE 250
+
+#endif
diff --git a/src/internal/ntapi_impl.h b/src/internal/ntapi_impl.h
new file mode 100644
index 0000000..b60fc66
--- /dev/null
+++ b/src/internal/ntapi_impl.h
@@ -0,0 +1,120 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#ifndef ___NTAPI_IMPL_H_
+#define ___NTAPI_IMPL_H_
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_sysinfo.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_hash_table.h"
+#include "ntapi_context.h"
+#include "ntapi_fnapi.h"
+
+#define __NT_BASED_NAMED_OBJECTS {'\\','B','a','s','e', \
+ 'N','a','m','e','d', \
+ 'O','b','j','e','c','t','s'}
+
+/* helper macros */
+#define __NT_ROUND_UP_TO_POWER_OF_2(x,y)(x + (y-1)) & ~(y-1)
+#define __NT_IS_MISALIGNED_BUFFER(x) ((!(uintptr_t)x) || ((uintptr_t)x % sizeof(size_t)))
+#define __NT_IS_MISALIGNED_LENGTH(x) (x % sizeof(size_t))
+#define __NT_FILE_SYNC_IO (NT_FILE_SYNCHRONOUS_IO_ALERT|NT_FILE_SYNCHRONOUS_IO_NONALERT)
+
+/* user-defined options: head */
+#ifndef __NT_TTY_MONITORS
+#define __NT_TTY_MONITORS 0x10
+#endif
+
+#ifndef __NT_FORK_CHILD_WAIT_MILLISEC
+#define __NT_FORK_CHILD_WAIT_MILLISEC 60000
+#endif
+
+#ifndef __NT_SYNC_BLOCK_LOCK_TRIES
+#define __NT_SYNC_BLOCK_LOCK_TRIES 1024
+#endif
+/* user-defined options: tail */
+
+/* internal page size */
+#ifndef __NT_INTERNAL_PAGE_SIZE
+#define __NT_INTERNAL_PAGE_SIZE 4096
+#endif
+
+/* .bss section */
+#ifndef __NT_BSS_RESERVED_PAGES
+#define __NT_BSS_RESERVED_PAGES 8
+#endif
+
+/* runtime buffers */
+#define __NT_BSS_ARGV_BUFFER_SIZE __NT_INTERNAL_PAGE_SIZE * 2
+
+#define __NT_BSS_ARGV_MAX_IDX __NT_BSS_ARGV_BUFFER_SIZE \
+ / sizeof(uintptr_t)
+
+#define __NT_BSS_ARGS_BUFFER_SIZE __NT_INTERNAL_PAGE_SIZE \
+ * __NT_BSS_RESERVED_PAGES \
+ - __NT_BSS_ARGV_BUFFER_SIZE
+
+/* ntapi .bss section structure */
+typedef struct ___ntapi_img_sec_bss {
+ wchar16_t * argv_envp_array[__NT_BSS_ARGV_MAX_IDX];
+ char args_envs_buffer[__NT_BSS_ARGS_BUFFER_SIZE];
+} __ntapi_img_sec_bss;
+
+
+/* ntapi library internals */
+typedef struct __attr_ptr_size_aligned__ _ntapi_internals {
+ nt_runtime_data * rtdata;
+ nt_port_name * subsystem;
+ void * hport_tty_session;
+ void * hport_tty_daemon;
+ void * hport_tty_debug;
+ void * hport_tty_monitor[__NT_TTY_MONITORS];
+ size_t nt_mem_page_size;
+ size_t nt_mem_allocation_granularity;
+ size_t ntapi_internals_alloc_size;
+ void ** csr_port_handle_addr;
+ void * hdev_mount_point_mgr;
+ void * hany[8];
+ intptr_t hlock;
+ uintptr_t v1_pipe_counter;
+ ntapi_tt_get_csr_port_handle_addr_by_logic * tt_get_csr_port_handle_addr_by_logic;
+ __ntapi_img_sec_bss * ntapi_img_sec_bss;
+} ntapi_internals;
+
+
+/* __ntapi_img_sec_data */
+typedef struct __attr_ptr_size_aligned__ ___ntapi_img_sec_rdata {
+ ntapi_hashed_symbol __ntapi_import_table[__NT_IMPORTED_SYMBOLS_ARRAY_SIZE];
+ ntapi_vtbl * __ntapi;
+ nt_port_name __session_name;
+ ntapi_internals * __internals;
+} __ntapi_img_sec_rdata;
+
+union __ntapi_img_rdata {
+ __ntapi_img_sec_rdata img_sec_data;
+ char buffer[__NT_INTERNAL_PAGE_SIZE];
+};
+
+
+/* accessor table */
+extern ntapi_vtbl ___ntapi;
+extern ntapi_vtbl ___ntapi_shadow;
+#define __ntapi (&___ntapi)
+
+
+/* access to library internals */
+ntapi_internals * __cdecl __ntapi_internals(void);
+
+
+/* debug */
+#define __ntidx(x) (&(((ntapi_vtbl *)0)->x)) / sizeof(size_t)
+
+
+#endif
diff --git a/src/internal/ntapi_lib_entry_point.c b/src/internal/ntapi_lib_entry_point.c
new file mode 100644
index 0000000..8b857c8
--- /dev/null
+++ b/src/internal/ntapi_lib_entry_point.c
@@ -0,0 +1,12 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+
+int __stdcall __ntapi_entry(void * hinstance, uint32_t reason, void * reserved)
+{
+ return 1;
+}
diff --git a/src/internal/ntapi_pty.h b/src/internal/ntapi_pty.h
new file mode 100644
index 0000000..ff85b3a
--- /dev/null
+++ b/src/internal/ntapi_pty.h
@@ -0,0 +1,37 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#ifndef ___NTAPI_PTY_H_
+#define ___NTAPI_PTY_H_
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_guid.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/nt_tty.h>
+
+#define __PTY_READ 0
+#define __PTY_WRITE 1
+
+typedef struct nt_pty_context {
+ nt_sync_block sync[2];
+ void * addr;
+ size_t size;
+ void * hport;
+ void * hpty;
+ void * section;
+ void * section_addr;
+ size_t section_size;
+ nt_guid guid;
+ nt_luid luid;
+ uint32_t access;
+ uint32_t flags;
+ uint32_t share;
+ uint32_t options;
+ nt_iosb iosb;
+} nt_pty;
+
+#endif
diff --git a/src/ipc/ntapi_tt_create_pipe_v1.c b/src/ipc/ntapi_tt_create_pipe_v1.c
new file mode 100644
index 0000000..3185fbd
--- /dev/null
+++ b/src/ipc/ntapi_tt_create_pipe_v1.c
@@ -0,0 +1,164 @@
+/********************************************************/
+/* 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/nt_file.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/nt_atomic.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+typedef struct __attr_ptr_size_aligned__ _nt_tty_pipe_name {
+ wchar16_t pipe_dir[8];
+ wchar16_t back_slash;
+ wchar16_t key_1st[8];
+ wchar16_t uscore_1st;
+ wchar16_t key_2nd[8];
+ wchar16_t uscore_2nd;
+ wchar16_t key_3rd[8];
+ wchar16_t uscore_3rd;
+ wchar16_t key_4th[8];
+ wchar16_t uscore_4th;
+ wchar16_t key_5th[8];
+ wchar16_t uscore_5th;
+ wchar16_t key_6th[8];
+ wchar16_t null_termination;
+} nt_tty_pipe_name;
+
+
+int32_t __stdcall __ntapi_ipc_create_pipe_v1(
+ __out void ** hpipe_read,
+ __out void ** hpipe_write,
+ __in uint32_t advisory_buffer_size __optional)
+{
+ int32_t status;
+
+ void * hread;
+ void * hwrite;
+
+ nt_object_attributes oa;
+ nt_io_status_block iosb;
+ nt_unicode_string nt_name;
+ nt_security_quality_of_service sqos;
+ nt_large_integer timeout;
+ intptr_t * counter;
+
+ nt_tty_pipe_name pipe_name = {
+ {'\\','?','?','\\','p','i','p','e'},
+ '\\',
+ {0},'_',
+ {0},'_',
+ {0},'_',
+ {0},'_',
+ {0},'_',
+ {0},
+ 0
+ };
+
+ /* pipe_count */
+ counter = (intptr_t *)&__ntapi_internals()->v1_pipe_counter;
+ at_locked_inc(counter);
+
+ /* get system time */
+ status = __ntapi->zw_query_system_time(&timeout);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* pipe name (no anonymous pipe prior to vista) */
+ __ntapi->tt_uint32_to_hex_utf16( pe_get_current_process_id(),pipe_name.key_1st);
+ __ntapi->tt_uint32_to_hex_utf16( pe_get_current_thread_id(),pipe_name.key_2nd);
+
+ __ntapi->tt_uint32_to_hex_utf16( timeout.ihigh + (uint32_t)*counter,pipe_name.key_3rd);
+ __ntapi->tt_uint32_to_hex_utf16(timeout.ulow + (uint32_t)*counter,pipe_name.key_4th);
+
+ __ntapi->tt_uint32_to_hex_utf16(
+ __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)),
+ pipe_name.key_5th);
+
+ __ntapi->tt_uint32_to_hex_utf16(
+ __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)),
+ pipe_name.key_6th);
+
+ __ntapi->tt_uint32_to_hex_utf16(
+ __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)),
+ pipe_name.key_1st);
+
+ __ntapi->tt_uint32_to_hex_utf16(
+ __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)),
+ pipe_name.key_2nd);
+
+ __ntapi->tt_uint32_to_hex_utf16(
+ __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)),
+ pipe_name.key_3rd);
+
+ __ntapi->tt_uint32_to_hex_utf16(
+ __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)),
+ pipe_name.key_4th);
+
+ /* nt_name */
+ nt_name.strlen = (uint16_t)(sizeof(pipe_name) - sizeof(wchar16_t));
+ nt_name.maxlen = (uint16_t)(sizeof(pipe_name));
+ nt_name.buffer = (uint16_t *)&pipe_name;
+
+ /* init security structure */
+ sqos.length = sizeof(sqos);
+ sqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ sqos.effective_only = 1;
+
+ /* oa */
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &nt_name;
+ oa.obj_attr = 0x0;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = &sqos;
+
+ timeout.ihigh = 0xffffffff;
+ timeout.ulow = 0x0;
+
+ /* the reading end */
+ status = __ntapi->zw_create_named_pipe_file(
+ &hread,
+ NT_GENERIC_READ | NT_SEC_SYNCHRONIZE | NT_FILE_WRITE_ATTRIBUTES,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_CREATE,
+ NT_FILE_ASYNCHRONOUS_IO,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0x2000,
+ 0x2000,
+ &timeout);
+
+ if (status != NT_STATUS_SUCCESS) {
+ return status;
+ }
+
+ /* the writing end(s) */
+ status = __ntapi->zw_open_file(
+ &hwrite,
+ NT_GENERIC_WRITE | NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_WRITE_THROUGH | NT_FILE_ASYNCHRONOUS_IO | NT_FILE_NON_DIRECTORY_FILE);
+
+ if (status != NT_STATUS_SUCCESS) {
+ __ntapi->zw_close(hread);
+ return status;
+ }
+
+ *hpipe_read = hread;
+ *hpipe_write = hwrite;
+
+ return status;
+}
diff --git a/src/ipc/ntapi_tt_create_pipe_v2.c b/src/ipc/ntapi_tt_create_pipe_v2.c
new file mode 100644
index 0000000..c1f4b4b
--- /dev/null
+++ b/src/ipc/ntapi_tt_create_pipe_v2.c
@@ -0,0 +1,116 @@
+/********************************************************/
+/* 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/nt_file.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_ipc_create_pipe_v2(
+ __out void ** hpipe_read,
+ __out void ** hpipe_write,
+ __in uint32_t advisory_buffer_size __optional)
+{
+ int32_t status;
+
+ void * hdevpipes;
+ void * hwrite;
+ void * hread;
+
+ nt_object_attributes oa;
+ nt_io_status_block iosb;
+ nt_sqos sqos;
+ nt_unicode_string nt_name;
+ nt_large_integer timeout;
+
+ const wchar16_t pipe_dir[] = {
+ '\\','D','e','v','i','c','e',
+ '\\','N','a','m','e','d','P','i','p','e','\\',0
+ };
+
+ /* nt_name: pipe device directory */
+ nt_name.strlen = (uint16_t)(sizeof(pipe_dir) - sizeof(wchar16_t));
+ nt_name.maxlen = 0;
+ nt_name.buffer = (uint16_t *)pipe_dir;
+
+ /* init security structure */
+ sqos.length = sizeof(sqos);
+ sqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ sqos.effective_only = 1;
+
+ /* oa */
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &nt_name;
+ oa.obj_attr = NT_OBJ_CASE_INSENSITIVE | NT_OBJ_INHERIT;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = &sqos;
+
+ status = __ntapi->zw_open_file(
+ &hdevpipes,
+ NT_GENERIC_READ | NT_SEC_SYNCHRONIZE,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_DIRECTORY_FILE);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ timeout.ihigh = 0xffffffff;
+ timeout.ulow = 0x0;
+
+ oa.root_dir = hdevpipes;
+
+ nt_name.strlen=0;
+ nt_name.buffer = (uint16_t *)0;
+
+ status = __ntapi->zw_create_named_pipe_file(
+ &hread,
+ NT_GENERIC_READ | NT_SEC_SYNCHRONIZE | NT_FILE_WRITE_ATTRIBUTES,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_CREATE,
+ NT_FILE_ASYNCHRONOUS_IO,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0X2000,
+ 0x2000,
+ &timeout);
+
+ if (status != NT_STATUS_SUCCESS) {
+ __ntapi->zw_close(hdevpipes);
+ return status;
+ }
+
+ /* the pipe is now our root directory */
+ oa.root_dir = hread;
+
+ status = __ntapi->zw_open_file(
+ &hwrite,
+ NT_GENERIC_WRITE | NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_WRITE_THROUGH | NT_FILE_ASYNCHRONOUS_IO | NT_FILE_NON_DIRECTORY_FILE);
+
+ if (status != NT_STATUS_SUCCESS) {
+ __ntapi->zw_close(hdevpipes);
+ __ntapi->zw_close(hread);
+ return status;
+ }
+
+ *hpipe_read = hread;
+ *hpipe_write = hwrite;
+
+ return status;
+}
diff --git a/src/ldr/ntapi_ldr_create_state_snapshot.c b/src/ldr/ntapi_ldr_create_state_snapshot.c
new file mode 100644
index 0000000..74a916c
--- /dev/null
+++ b/src/ldr/ntapi_ldr_create_state_snapshot.c
@@ -0,0 +1,69 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <dalist/dalist.h>
+#include <ntapi/ntapi.h>
+
+struct callback_ctx {
+ struct dalist_ex * ldr_state_snapshot;
+ int32_t status;
+};
+
+static int __cdecl __add_module_base_address_to_list(
+ struct pe_ldr_tbl_entry * ldr_tbl_entry,
+ enum pe_callback_reason int_callback_reason,
+ void * context)
+{
+ struct dalist_node * node;
+ struct callback_ctx * ctx;
+
+ ctx = (struct callback_ctx *)context;
+
+ if (int_callback_reason == PE_CALLBACK_REASON_ERROR) {
+ ctx->status = NT_STATUS_UNSUCCESSFUL;
+ return ctx->status;
+ } else if (int_callback_reason != PE_CALLBACK_REASON_ITEM) {
+ ctx->status = NT_STATUS_SUCCESS;
+ return 1;
+ } else if (!ldr_tbl_entry->dll_base) {
+ ctx->status = NT_STATUS_SUCCESS;
+ return 1;
+ }
+
+ ctx->status = dalist_get_node_by_key(
+ ctx->ldr_state_snapshot,
+ (struct dalist_node_ex **)&node,
+ (uintptr_t)ldr_tbl_entry->dll_base,
+ DALIST_NODE_TYPE_NEW,
+ 0);
+
+ if (ctx->status != DALIST_OK)
+ return -1;
+ else
+ return 1;
+}
+
+
+int __cdecl __ntapi_ldr_create_state_snapshot(
+ __out struct dalist_ex * ldr_state_snapshot)
+{
+ struct callback_ctx ctx;
+
+ if (!ldr_state_snapshot->free && !ldr_state_snapshot->memfn_ptr)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ else if (ldr_state_snapshot->info.list_nodes)
+ return NT_STATUS_INVALID_USER_BUFFER;
+
+ ctx.ldr_state_snapshot = ldr_state_snapshot;
+
+ pe_enum_modules_in_load_order(
+ __add_module_base_address_to_list,
+ &ctx);
+
+ return ctx.status;
+}
diff --git a/src/ldr/ntapi_ldr_load_system_dll.c b/src/ldr/ntapi_ldr_load_system_dll.c
new file mode 100644
index 0000000..d417590
--- /dev/null
+++ b/src/ldr/ntapi_ldr_load_system_dll.c
@@ -0,0 +1,44 @@
+/********************************************************/
+/* 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/nt_ldr.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_ldr_load_system_dll(
+ __in void * hsysdir __optional,
+ __in wchar16_t * base_name,
+ __in uint32_t base_name_size,
+ __in uint32_t * image_flags __optional,
+ __out void ** image_base)
+{
+ int32_t status;
+ nt_unicode_string nt_image_name;
+ uintptr_t buffer[0x80];
+
+ /* stack buffer */
+ __ntapi->tt_aligned_block_memset(buffer,0,sizeof(buffer));
+
+ status = __ntapi->tt_get_system_directory_dos_path(
+ hsysdir,
+ (wchar16_t *)buffer,
+ sizeof(buffer),
+ base_name,
+ base_name_size,
+ &nt_image_name);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ status = __ntapi->ldr_load_dll(
+ 0,
+ 0,
+ &nt_image_name,
+ image_base);
+
+ return status;
+}
diff --git a/src/ldr/ntapi_ldr_revert_state_to_snapshot.c b/src/ldr/ntapi_ldr_revert_state_to_snapshot.c
new file mode 100644
index 0000000..2ca5087
--- /dev/null
+++ b/src/ldr/ntapi_ldr_revert_state_to_snapshot.c
@@ -0,0 +1,104 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <dalist/dalist.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+struct callback_ctx {
+ struct dalist_ex * ldr_state_snapshot;
+ struct pe_ldr_tbl_entry * ldr_tbl_entry;
+ void * image_base;
+ uint32_t load_count;
+ int32_t status;
+};
+
+static int __cdecl __find_next_module_to_unload(
+ struct pe_ldr_tbl_entry * ldr_tbl_entry,
+ enum pe_callback_reason int_callback_reason,
+ void * context)
+{
+ struct dalist_node * node;
+ struct callback_ctx * ctx;
+
+ ctx = (struct callback_ctx *)context;
+
+ if (int_callback_reason == PE_CALLBACK_REASON_ERROR) {
+ ctx->status = NT_STATUS_UNSUCCESSFUL;
+ return ctx->status;
+ } else if (int_callback_reason != PE_CALLBACK_REASON_ITEM) {
+ ctx->status = NT_STATUS_SUCCESS;
+ return 1;
+ } else if (!ldr_tbl_entry->dll_base) {
+ ctx->status = NT_STATUS_SUCCESS;
+ return 1;
+ }
+
+
+ ctx->status = dalist_get_node_by_key(
+ ctx->ldr_state_snapshot,
+ (struct dalist_node_ex **)&node,
+ (uintptr_t)ldr_tbl_entry->dll_base,
+ DALIST_NODE_TYPE_EXISTING,
+ 0);
+
+ if (ctx->status != DALIST_OK)
+ return -1;
+ else if (node)
+ return 1;
+ else if (!ctx->image_base || (ldr_tbl_entry->load_count < ctx->load_count)) {
+ ctx->image_base = ldr_tbl_entry->dll_base;
+ ctx->load_count = ldr_tbl_entry->load_count;
+ ctx->ldr_tbl_entry = ldr_tbl_entry;
+ }
+
+ return 1;
+}
+
+
+int __cdecl __ntapi_ldr_revert_state_to_snapshot(
+ __in struct dalist_ex * ldr_state_snapshot)
+{
+ struct callback_ctx ctx;
+ uint32_t i;
+
+ if (!ldr_state_snapshot->free && !ldr_state_snapshot->memfn_ptr)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ ctx.ldr_state_snapshot = ldr_state_snapshot;
+ ctx.image_base = (void *)0;
+ ctx.load_count = 0;
+
+ pe_enum_modules_in_load_order(
+ __find_next_module_to_unload,
+ &ctx);
+
+ while ((ctx.image_base) && (ctx.status == NT_STATUS_SUCCESS)) {
+ if (ctx.load_count == 0xffff) {
+ ctx.load_count = 1;
+ ctx.ldr_tbl_entry->load_count = 1;
+ ctx.ldr_tbl_entry->entry_point = (void *)0;
+ ctx.ldr_tbl_entry->flags = 0;
+ }
+
+ for (i=0; i<ctx.load_count; i++)
+ __ntapi->ldr_unload_dll(ctx.image_base);
+
+ __ntapi->zw_unmap_view_of_section(
+ NT_CURRENT_PROCESS_HANDLE,
+ ctx.image_base);
+ ctx.image_base = (void *)0;
+ ctx.load_count = 0;
+
+ pe_enum_modules_in_load_order(
+ __find_next_module_to_unload,
+ &ctx);
+ }
+
+ return ctx.status;
+}
diff --git a/src/object/ntapi_tt_keyed_object_directory.c b/src/object/ntapi_tt_keyed_object_directory.c
new file mode 100644
index 0000000..7f2da40
--- /dev/null
+++ b/src/object/ntapi_tt_keyed_object_directory.c
@@ -0,0 +1,134 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_guid.h>
+#include <ntapi/nt_string.h>
+#include "ntapi_impl.h"
+
+typedef ntapi_zw_open_directory_object objdir_open_fn;
+
+static int32_t __stdcall __tt_create_keyed_object_directory(
+ __out void ** hdir,
+ __in uint32_t desired_access,
+ __in const wchar16_t prefix[6],
+ __in nt_guid * guid,
+ __in uint32_t key,
+ __in objdir_open_fn * openfn)
+{
+ nt_keyed_objdir_name objdir_name = {__NT_BASED_NAMED_OBJECTS};
+ nt_unicode_string name;
+ nt_oa oa;
+ nt_sqos sqos = {
+ sizeof(sqos),
+ NT_SECURITY_IMPERSONATION,
+ NT_SECURITY_TRACKING_DYNAMIC,
+ 1};
+
+ __ntapi->tt_memcpy_utf16(
+ objdir_name.prefix,
+ prefix,
+ sizeof(objdir_name.prefix));
+
+ __ntapi->tt_guid_to_utf16_string(
+ guid,
+ (nt_guid_str_utf16 *)&objdir_name.objdir_guid);
+
+ __ntapi->tt_uint32_to_hex_utf16(
+ key,objdir_name.key);
+
+ objdir_name.backslash = '\\';
+ objdir_name.objdir_guid.uscore_guid = '_';
+ objdir_name.objdir_guid.uscore_key = '_';
+
+ name.strlen = sizeof(objdir_name);
+ name.maxlen = 0;
+ name.buffer = (uint16_t *)&objdir_name;
+
+ oa.len = sizeof(oa);
+ oa.root_dir = 0;
+ oa.obj_name = &name;
+ oa.obj_attr = NT_OBJ_INHERIT;
+ oa.sec_desc = 0;
+ oa.sec_qos = &sqos;
+
+ return openfn(hdir,desired_access,&oa);
+}
+
+
+int32_t __stdcall __ntapi_tt_create_keyed_object_directory_entry(
+ __out void ** hentry,
+ __in uint32_t desired_access,
+ __in void * hdir,
+ __in void * htarget,
+ __in nt_unicode_string * target_name,
+ __in uint32_t key)
+{
+ int32_t status;
+ nt_oa oa;
+ nt_unicode_string name;
+ wchar16_t keystr[8];
+ uintptr_t buffer[2048/sizeof(uintptr_t)];
+ nt_sqos sqos = {
+ sizeof(sqos),
+ NT_SECURITY_IMPERSONATION,
+ NT_SECURITY_TRACKING_DYNAMIC,
+ 1};
+
+ if (!target_name) {
+ if ((status = __ntapi->zw_query_object(
+ htarget,
+ NT_OBJECT_NAME_INFORMATION,
+ buffer,sizeof(buffer),0)))
+ return status;
+ target_name = (nt_unicode_string *)buffer;
+ }
+
+ __ntapi->tt_uint32_to_hex_utf16(key,keystr);
+
+ name.strlen = sizeof(keystr);
+ name.maxlen = 0;
+ name.buffer = keystr;
+
+ oa.len = sizeof(oa);
+ oa.root_dir = hdir;
+ oa.obj_name = &name;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = &sqos;
+
+ return __ntapi->zw_create_symbolic_link_object(
+ hentry,
+ desired_access,
+ &oa,target_name);
+}
+
+int32_t __stdcall __ntapi_tt_create_keyed_object_directory(
+ __out void ** hdir,
+ __in uint32_t desired_access,
+ __in const wchar16_t prefix[6],
+ __in nt_guid * guid,
+ __in uint32_t key)
+{
+ return __tt_create_keyed_object_directory(
+ hdir,desired_access,
+ prefix,guid,key,
+ __ntapi->zw_create_directory_object);
+}
+
+int32_t __stdcall __ntapi_tt_open_keyed_object_directory(
+ __out void ** hdir,
+ __in uint32_t desired_access,
+ __in const wchar16_t prefix[6],
+ __in nt_guid * guid,
+ __in uint32_t key)
+{
+ return __tt_create_keyed_object_directory(
+ hdir,desired_access,
+ prefix,guid,key,
+ __ntapi->zw_open_directory_object);
+}
diff --git a/src/port/ntapi_port_name_helper.c b/src/port/ntapi_port_name_helper.c
new file mode 100644
index 0000000..3084cf6
--- /dev/null
+++ b/src/port/ntapi_port_name_helper.c
@@ -0,0 +1,167 @@
+/********************************************************/
+/* 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/nt_guid.h>
+#include <ntapi/nt_port.h>
+#include <ntapi/nt_string.h>
+#include "ntapi_impl.h"
+
+typedef wchar16_t __port_service_prefix[6];
+
+static const __port_service_prefix __port_service_null = {0};
+static const __port_service_prefix __port_service_prefixes[4][NT_PORT_TYPE_CAP][NT_PORT_SUBTYPE_CAP] = {
+ {{{'s','v','c','a','n','y'}}},
+ {{{'n','t','c','t','t','y'}}},
+ {{{'v','m','o','u','n','t'}}},
+ {{{'d','a','e','m','o','n'}}}};
+
+static const nt_guid __port_guids[NT_PORT_TYPE_CAP][NT_PORT_SUBTYPE_CAP] = {
+ {NT_PORT_GUID_DEFAULT},
+ {NT_PORT_GUID_SUBSYSTEM},
+ {NT_PORT_GUID_VMOUNT},
+ {NT_PORT_GUID_DAEMON}};
+
+int32_t __stdcall __ntapi_tt_port_guid_from_type(
+ __out nt_guid * guid,
+ __in nt_port_type type,
+ __in nt_port_subtype subtype)
+{
+ const nt_guid * src_guid;
+
+ if ((type >= NT_PORT_TYPE_CAP) || (subtype >= NT_PORT_SUBTYPE_CAP))
+ return NT_STATUS_INVALID_PARAMETER;
+
+ src_guid = &(__port_guids[type][subtype]);
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)guid,
+ (uintptr_t *)src_guid,
+ sizeof(nt_guid));
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_port_type_from_guid(
+ __out nt_port_type * type,
+ __out nt_port_subtype * subtype,
+ __in nt_guid * guid)
+{
+ int itype;
+ int isubtype;
+ const nt_guid * src_guid;
+ uint32_t guid_hash;
+ uint32_t src_hash;
+
+ guid_hash = __ntapi->tt_buffer_crc32(0,guid,sizeof(nt_guid));
+
+ for (itype=0; itype<NT_PORT_TYPE_CAP; itype++) {
+ for (isubtype=0; isubtype<NT_PORT_SUBTYPE_CAP; isubtype++) {
+ src_guid = &(__port_guids[itype][isubtype]);
+ src_hash = __ntapi->tt_buffer_crc32(0,src_guid,sizeof(nt_guid));
+
+ if (guid_hash == src_hash) {
+ *type = (nt_port_type)itype;
+ *subtype = (nt_port_subtype)isubtype;
+
+ return NT_STATUS_SUCCESS;
+ }
+ }
+ }
+
+ return NT_STATUS_INVALID_PARAMETER;
+
+}
+
+
+int32_t __stdcall __ntapi_tt_port_generate_keys(
+ __out nt_port_keys * keys)
+{
+ int32_t status;
+ nt_large_integer systime;
+ nt_luid luid;
+
+ status = __ntapi->zw_query_system_time(&systime);
+ if (status) return status;
+
+ status = __ntapi->zw_allocate_locally_unique_id(&luid);
+ if (status) return status;
+
+ keys->key[0] = pe_get_current_process_id();
+ keys->key[1] = pe_get_current_thread_id();
+ keys->key[2] = systime.ihigh;
+ keys->key[3] = systime.ulow;
+ keys->key[4] = luid.high;
+ keys->key[5] = luid.low;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+void __stdcall __ntapi_tt_port_format_keys(
+ __in nt_port_keys * keys,
+ __out nt_port_name_keys * name_keys)
+{
+ __ntapi->tt_uint32_to_hex_utf16(keys->key[0],name_keys->key_1st);
+ __ntapi->tt_uint32_to_hex_utf16(keys->key[1],name_keys->key_2nd);
+ __ntapi->tt_uint32_to_hex_utf16(keys->key[2],name_keys->key_3rd);
+ __ntapi->tt_uint32_to_hex_utf16(keys->key[3],name_keys->key_4th);
+ __ntapi->tt_uint32_to_hex_utf16(keys->key[4],name_keys->key_5th);
+ __ntapi->tt_uint32_to_hex_utf16(keys->key[5],name_keys->key_6th);
+
+ return;
+}
+
+
+void __stdcall __ntapi_tt_port_name_from_attributes(
+ __out nt_port_name * name,
+ __in nt_port_attr * attr)
+{
+ wchar16_t bno[] = __NT_BASED_NAMED_OBJECTS;
+
+ /* base named objects */
+ __ntapi->tt_memcpy_utf16(
+ name->base_named_objects,
+ bno,sizeof(bno));
+
+ /* service prefix */
+ if (attr && (attr->type < NT_PORT_TYPE_CAP) && (attr->subtype < NT_PORT_SUBTYPE_CAP))
+ __ntapi->tt_memcpy_utf16(
+ name->svc_prefix,
+ &(__port_service_prefixes[attr->type][attr->subtype][0][0]),
+ sizeof(name->svc_prefix));
+ else
+ __ntapi->tt_memcpy_utf16(
+ name->svc_prefix,
+ __port_service_null,
+ sizeof(name->svc_prefix));
+
+ /* port guid */
+ __ntapi->tt_guid_to_utf16_string(
+ &attr->guid,
+ (nt_guid_str_utf16 *)&name->port_guid);
+
+ /* port name keys */
+ __ntapi_tt_port_format_keys(
+ &attr->keys,
+ &name->port_name_keys);
+
+ /* backslash and underscores */
+ name->backslash = '\\';
+ name->port_guid.uscore_guid = '_';
+ name->port_guid.uscore_keys = '_';
+ name->port_name_keys.uscore_1st = '_';
+ name->port_name_keys.uscore_2nd = '_';
+ name->port_name_keys.uscore_3rd = '_';
+ name->port_name_keys.uscore_4th = '_';
+ name->port_name_keys.uscore_5th = '_';
+
+ /* null termination */
+ name->null_termination = 0;
+
+ return;
+}
diff --git a/src/process/nt32/tt_fork_v1.s b/src/process/nt32/tt_fork_v1.s
new file mode 100644
index 0000000..2e2f01d
--- /dev/null
+++ b/src/process/nt32/tt_fork_v1.s
@@ -0,0 +1,60 @@
+##########################################################
+## ntapi: Native API core library ##
+## Copyright (C) 2013,2014,2015 Z. Gilboa ##
+## Released under GPLv2 and GPLv3; see COPYING.NTAPI. ##
+##########################################################
+
+.section .text
+
+.global ___tt_fork
+.global ___tt_fork_child_entry_point
+.global @__tt_fork_child_entry_point@4
+.global ___tt_fork_child_entry_point_adj
+.global @__tt_fork_child_entry_point_adj@4
+
+___tt_fork:
+___tt_fork_prolog:
+ push %ebp
+ mov %esp, %ebp
+
+___tt_fork_save_regs:
+ push %ecx
+ push %edx
+ push %ebx
+ push %esi
+ push %edi
+
+___tt_fork_impl_call:
+ mov %esp, %ecx
+ mov $0, %edx
+ call @__tt_fork_impl@8
+
+___tt_fork_restore_regs:
+ pop %edi
+ pop %esi
+ pop %ebx
+ pop %edx
+ pop %ecx
+
+___tt_fork_epilog:
+ mov %ebp, %esp
+ pop %ebp
+ ret
+
+___tt_fork_child_entry_point:
+@__tt_fork_child_entry_point@4:
+___tt_fork_child_entry_point_adj:
+@__tt_fork_child_entry_point_adj@4:
+ xor %eax, %eax
+ mov %ecx, %esp
+
+___tt_fork_child_restore_regs:
+ pop %edi
+ pop %esi
+ pop %ebx
+ pop %edx
+ pop %ecx
+
+___tt_fork_child_epilog:
+ pop %ebp
+ ret
diff --git a/src/process/nt32/tt_fork_v1_i386.c b/src/process/nt32/tt_fork_v1_i386.c
new file mode 100644
index 0000000..34b813e
--- /dev/null
+++ b/src/process/nt32/tt_fork_v1_i386.c
@@ -0,0 +1,66 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+
+#if (__COMPILER__ == __MSVC__) && defined(__X86_MODEL)
+
+intptr_t __fastcall __tt_fork_impl(
+ __in uintptr_t saved_regs_stack_pointer,
+ __in uintptr_t stack_adjustment);
+
+int32_t __declspec(naked) __cdecl __tt_fork(void)
+{
+ __asm {
+ push ebp
+ mov ebp, esp
+
+ push ecx
+ push edx
+ push ebx
+ push esi
+ push edi
+
+ mov ecx, esp
+ call __tt_fork_impl
+
+ pop edi
+ pop esi
+ pop ebx
+ pop edx
+ pop ecx
+
+ mov esp, ebp
+ pop ebp
+ ret
+ };
+}
+
+void __declspec(naked) __fastcall __tt_fork_child_entry_point(uintptr_t esp_saved)
+{
+ __asm {
+ xor eax, eax
+ mov esp, ecx
+
+ pop edi
+ pop esi
+ pop ebx
+ pop edx
+ pop ecx
+
+ pop ebp
+ ret
+ };
+}
+
+void __declspec(naked) __fastcall __tt_fork_child_entry_point_adj(uintptr_t esp_saved)
+{
+ __asm {
+ jmp __tt_fork_child_entry_point
+ };
+}
+
+#endif
diff --git a/src/process/nt64/tt_fork_v1.s b/src/process/nt64/tt_fork_v1.s
new file mode 100644
index 0000000..5f09463
--- /dev/null
+++ b/src/process/nt64/tt_fork_v1.s
@@ -0,0 +1,134 @@
+##########################################################
+## ntapi: Native API core library ##
+## Copyright (C) 2013,2014,2015 Z. Gilboa ##
+## Released under GPLv2 and GPLv3; see COPYING.NTAPI. ##
+##########################################################
+
+.section .text
+
+.global __tt_fork_v1
+.global __tt_fork_child_entry_point
+.global __tt_fork_child_entry_point_adj
+
+__tt_fork_v1:
+__tt_fork_save_regs:
+ push %rbp
+ push %rcx
+ push %rdx
+ push %rbx
+ push %rsi
+ push %rdi
+ push %r8
+ push %r9
+ push %r10
+ push %r11
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ sub 0x40,%rsp
+
+ mov %rsp, %rdx
+ and $0xf, %rdx
+ test %rdx, %rdx
+ jne __tt_fork_impl_adj_call
+
+__tt_fork_impl_call:
+ mov %rsp, %rcx
+ call __tt_fork_impl_v1
+
+ add 0x40,%rsp
+
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %r11
+ pop %r10
+ pop %r9
+ pop %r8
+ pop %rdi
+ pop %rsi
+ pop %rbx
+ pop %rdx
+ pop %rcx
+ pop %rbp
+
+ ret
+
+__tt_fork_impl_adj_call:
+ push %rdi
+
+ mov %rsp, %rcx
+ call __tt_fork_impl_v1
+
+ pop %rdi
+
+ add 0x40,%rsp
+
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %r11
+ pop %r10
+ pop %r9
+ pop %r8
+ pop %rdi
+ pop %rsi
+ pop %rbx
+ pop %rdx
+ pop %rcx
+ pop %rbp
+
+ ret
+
+
+__tt_fork_child_entry_point:
+ xor %rax, %rax
+ mov %rcx, %rsp
+
+ add 0x40,%rsp
+
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %r11
+ pop %r10
+ pop %r9
+ pop %r8
+ pop %rdi
+ pop %rsi
+ pop %rbx
+ pop %rdx
+ pop %rcx
+ pop %rbp
+
+ ret
+
+__tt_fork_child_entry_point_adj:
+ xor %rax, %rax
+ mov %rcx, %rsp
+
+ pop %rdi
+
+ add 0x40,%rsp
+
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %r11
+ pop %r10
+ pop %r9
+ pop %r8
+ pop %rdi
+ pop %rsi
+ pop %rbx
+ pop %rdx
+ pop %rcx
+ pop %rbp
+
+ ret
diff --git a/src/process/nt64/tt_fork_v1_x86_64.asm b/src/process/nt64/tt_fork_v1_x86_64.asm
new file mode 100644
index 0000000..f79131e
--- /dev/null
+++ b/src/process/nt64/tt_fork_v1_x86_64.asm
@@ -0,0 +1,136 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+TITLE tt_fork_x86_64
+
+.data
+__tt_fork_impl_v1 PROTO C
+
+.code
+__tt_fork_v1 PROC
+ push rbp
+ push rcx
+ push rdx
+ push rbx
+ push rsi
+ push rdi
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+
+ sub rsp, 40h
+
+ mov rdx, rsp
+ and rdx, 15
+ test rdx, rdx
+ jne __tt_fork_impl_adj_call
+
+ mov rcx, rsp
+ call __tt_fork_impl_v1
+
+ add rsp, 40h
+
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rdi
+ pop rsi
+ pop rbx
+ pop rdx
+ pop rcx
+ pop rbp
+ ret
+__tt_fork_v1 ENDP
+
+__tt_fork_impl_adj_call PROC
+ push rdi
+
+ mov rcx, rsp
+ mov rdx, 1
+ call __tt_fork_impl_v1
+
+ pop rdi
+
+ add rsp, 40h
+
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rdi
+ pop rsi
+ pop rbx
+ pop rdx
+ pop rcx
+ pop rbp
+ ret
+__tt_fork_impl_adj_call ENDP
+
+
+__tt_fork_child_entry_point PROC
+ xor rax, rax
+ mov rsp, rcx
+
+ add rsp, 40h
+
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rdi
+ pop rsi
+ pop rbx
+ pop rdx
+ pop rcx
+ pop rbp
+ ret
+__tt_fork_child_entry_point ENDP
+
+
+__tt_fork_child_entry_point_adj PROC
+ xor rax, rax
+ mov rsp, rcx
+
+ pop rdi
+
+ add rsp, 40h
+
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rdi
+ pop rsi
+ pop rbx
+ pop rdx
+ pop rcx
+ pop rbp
+ ret
+__tt_fork_child_entry_point_adj ENDP
+
+END
diff --git a/src/process/nt64/tt_fork_v2_x86_64.asm b/src/process/nt64/tt_fork_v2_x86_64.asm
new file mode 100644
index 0000000..cc6e353
--- /dev/null
+++ b/src/process/nt64/tt_fork_v2_x86_64.asm
@@ -0,0 +1,50 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+TITLE tt_fork_x86_64
+
+.data
+__tt_fork_impl_v2 PROTO C
+
+.code
+__tt_fork_v2 PROC
+ push rbp
+ push rcx
+ push rdx
+ push rbx
+ push rsi
+ push rdi
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+
+ sub rsp, 40h
+ call __tt_fork_impl_v2
+ add rsp, 40h
+
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rdi
+ pop rsi
+ pop rbx
+ pop rdx
+ pop rcx
+ pop rbp
+ ret
+__tt_fork_v2 ENDP
+
+END
diff --git a/src/process/ntapi_tt_create_native_process_v1.c b/src/process/ntapi_tt_create_native_process_v1.c
new file mode 100644
index 0000000..b2572cc
--- /dev/null
+++ b/src/process/ntapi_tt_create_native_process_v1.c
@@ -0,0 +1,258 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+static int32_t __tt_create_process_cancel(nt_create_process_params * params, void * hsection, int32_t status)
+{
+ if (params->hprocess) {
+ __ntapi->zw_terminate_process(params->hprocess,NT_STATUS_INTERNAL_ERROR);
+ __ntapi->zw_close(params->hprocess);
+ }
+
+ if (params->hthread)
+ __ntapi->zw_close(params->hthread);
+
+ if (hsection)
+ __ntapi->zw_close(hsection);
+
+ return status;
+}
+
+int32_t __stdcall __ntapi_tt_create_native_process_v1(nt_create_process_params * params)
+{
+ int32_t status;
+ void * hfile;
+ void * hsection;
+
+ nt_object_attributes oa_file;
+ nt_object_attributes oa_process;
+ nt_object_attributes oa_thread;
+
+ nt_unicode_string nt_image;
+ nt_unicode_string nt_cmd_line;
+ nt_process_parameters * rprocess_params;
+ nt_thread_params tparams;
+
+ nt_io_status_block iosb;
+ nt_section_image_information sii;
+
+ wchar16_t * cmd_line_runtime_buffer;
+ size_t cmd_line_runtime_buffer_size;
+ int fresume_thread;
+
+ #if defined (__NT32)
+ wchar16_t runtime_arg[12] = {
+ ' ','-','r',' ',
+ 'i','n','t','e','g','r','a','l'};
+ #elif defined (__NT64)
+ wchar16_t runtime_arg[20] = {
+ ' ','-','r',' ',
+ 'i','n','t','e','g','r','a','l',
+ '-','r','u','n','t','i','m','e'};
+ #endif
+
+ /* validation */
+ if (params->cmd_line && params->process_params)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ else if (params->cmd_line && params->rtblock)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ else if (params->environment && params->process_params)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+
+ /* tparams */
+ __ntapi->tt_aligned_block_memset(
+ &tparams, 0, sizeof(tparams));
+
+ /* image_name */
+ __ntapi->rtl_init_unicode_string(
+ &nt_image,
+ params->image_name);
+
+ /* oa_process */
+ if (!params->obj_attr_process) {
+ __ntapi->tt_aligned_block_memset(
+ &oa_process,0,sizeof(oa_process));
+
+ oa_process.len = sizeof(oa_process);
+ params->obj_attr_process = &oa_process;
+ }
+
+ /* oa_thread */
+ if (!params->obj_attr_thread) {
+ __ntapi->tt_aligned_block_memset(
+ &oa_thread,0,sizeof(oa_thread));
+
+ oa_thread.len = sizeof(oa_thread);
+ params->obj_attr_thread = &oa_thread;
+ }
+
+ /* legacy tasks */
+ /* init the oa_file structure */
+ oa_file.len = sizeof(nt_object_attributes);
+ oa_file.root_dir = (void *)0;
+ oa_file.obj_name = &nt_image;
+ oa_file.obj_attr = 0;
+ oa_file.sec_desc = (nt_security_descriptor *)0;
+ oa_file.sec_qos = (nt_sqos *)0;
+
+ /* open the file */
+ if ((status = __ntapi->zw_open_file(
+ &hfile,
+ NT_FILE_EXECUTE | NT_PROCESS_SYNCHRONIZE,
+ &oa_file,
+ &iosb,
+ NT_FILE_SHARE_READ,
+ NT_FILE_SYNCHRONOUS_IO_NONALERT)))
+ return status;
+
+ /* create the executable section */
+ hsection = 0;
+ oa_file.obj_name = 0;
+
+ status = __ntapi->zw_create_section(
+ &hsection,
+ NT_SECTION_ALL_ACCESS,
+ &oa_file,0,
+ NT_PAGE_EXECUTE,
+ NT_SEC_IMAGE,
+ hfile);
+
+ __ntapi->zw_close(hfile);
+ if (status) return status;
+
+ /* create the process */
+ if ((status = __ntapi->zw_create_process(
+ &params->hprocess,
+ NT_PROCESS_ALL_ACCESS,
+ &oa_process,
+ NT_CURRENT_PROCESS_HANDLE,
+ 1,hsection,0,0)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ /* obtain stack/heap and entry point information */
+ if ((status = __ntapi->zw_query_section(
+ hsection,
+ NT_SECTION_IMAGE_INFORMATION,
+ &sii,sizeof(sii),0)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ /* obtain process information */
+ if ((status = __ntapi->zw_query_information_process(
+ tparams.hprocess,
+ NT_PROCESS_BASIC_INFORMATION,
+ &params->pbi,sizeof(params->pbi),
+ 0)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ /* create remote process parameters block */
+ if (!params->process_params) {
+ /* cmd_line */
+ if (!params->cmd_line) {
+ params->cmd_line = params->image_name;
+ }
+
+ __ntapi->rtl_init_unicode_string(
+ &nt_cmd_line,
+ params->cmd_line);
+
+ /* rtblock */
+ if (params->rtblock) {
+ cmd_line_runtime_buffer = (wchar16_t *)0;
+ cmd_line_runtime_buffer_size = nt_cmd_line.maxlen
+ + sizeof(runtime_arg);
+
+ if ((status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&cmd_line_runtime_buffer,
+ 0,&cmd_line_runtime_buffer_size,
+ NT_MEM_RESERVE | NT_MEM_COMMIT,
+ NT_PAGE_READWRITE)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ __ntapi->tt_memcpy_utf16(
+ (wchar16_t *)cmd_line_runtime_buffer,
+ (wchar16_t *)nt_cmd_line.buffer,
+ nt_cmd_line.strlen);
+
+ __ntapi->tt_memcpy_utf16(
+ (wchar16_t *)pe_va_from_rva(
+ cmd_line_runtime_buffer,
+ nt_cmd_line.strlen),
+ (wchar16_t *)runtime_arg,
+ sizeof(runtime_arg));
+
+ nt_cmd_line.strlen += sizeof(runtime_arg);
+ nt_cmd_line.maxlen += sizeof(runtime_arg);
+ nt_cmd_line.buffer = cmd_line_runtime_buffer;
+ }
+
+ /* environment */
+ if (!params->environment) {
+ params->environment = __ntapi->tt_get_peb_env_block_utf16();
+ }
+ }
+
+ fresume_thread = (params->creation_flags_thread ^ 0x01) & 0x01;
+
+ /* create target thread */
+ tparams.hprocess = params->hprocess;
+ tparams.start = (nt_thread_start_routine *)sii.entry_point;
+ tparams.obj_attr = &oa_thread;
+ tparams.creation_flags = NT_CREATE_SUSPENDED | NT_CREATE_FIRST_THREAD_OF_PROCESS;
+ tparams.stack_size_commit = sii.stack_commit;
+ tparams.stack_size_reserve = sii.stack_reserve;
+
+ if ((status = __ntapi->tt_create_remote_thread(&tparams)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ /* remote process params */
+ if ((status = __ntapi->tt_create_remote_process_params(
+ tparams.hprocess,
+ &rprocess_params,
+ &nt_image,
+ (nt_unicode_string *)0,
+ (nt_unicode_string *)0,
+ &nt_cmd_line,
+ params->environment,
+ (nt_unicode_string *)0,
+ (nt_unicode_string *)0,
+ (nt_unicode_string *)0,
+ (nt_unicode_string *)0)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ /* update the target process environment block: */
+ /* make process_params point to rparams_block */
+ if ((status = __ntapi->zw_write_virtual_memory(
+ tparams.hprocess,
+ (char *)((uintptr_t)params->pbi.peb_base_address
+ + (uintptr_t)&(((nt_peb *)0)->process_params)),
+ (char *)&rprocess_params,
+ sizeof(uintptr_t),0)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ /* rtdata */
+ if (params->rtblock && (status = __ntapi_tt_create_remote_runtime_data(tparams.hprocess,params->rtblock)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ if (fresume_thread && (status = __ntapi->zw_resume_thread(tparams.hthread,0)))
+ return __tt_create_process_cancel(params,hsection,status);
+
+ /* all done */
+ params->hthread = tparams.hthread;
+ params->cid.process_id = params->pbi.unique_process_id;
+ params->cid.thread_id = tparams.thread_id;
+
+ return status;
+}
diff --git a/src/process/ntapi_tt_create_native_process_v2.c b/src/process/ntapi_tt_create_native_process_v2.c
new file mode 100644
index 0000000..49fbaf7
--- /dev/null
+++ b/src/process/ntapi_tt_create_native_process_v2.c
@@ -0,0 +1,233 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+static int32_t __tt_create_process_cancel(nt_create_process_params * params, int32_t status)
+{
+ if (params->hprocess) {
+ __ntapi->zw_terminate_process(params->hprocess,NT_STATUS_INTERNAL_ERROR);
+ __ntapi->zw_close(params->hprocess);
+ }
+
+ if (params->hthread)
+ __ntapi->zw_close(params->hthread);
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_create_native_process_v2(
+ __in_out nt_create_process_params * params)
+{
+ int32_t status;
+
+ nt_object_attributes oa_process;
+ nt_object_attributes oa_thread;
+
+ nt_unicode_string nt_image;
+ nt_unicode_string nt_cmd_line;
+ wchar16_t * cmd_line_runtime_buffer;
+ size_t cmd_line_runtime_buffer_size;
+
+ nt_create_process_info nt_process_info;
+ int fresume_thread;
+
+ struct {
+ size_t size_in_bytes;
+ nt_create_process_ext_param file_info;
+ } ext_params;
+
+ #if defined (__NT32)
+ wchar16_t runtime_arg[12] = {
+ ' ','-','r',' ',
+ 'i','n','t','e','g','r','a','l'};
+ #elif defined (__NT64)
+ wchar16_t runtime_arg[20] = {
+ ' ','-','r',' ',
+ 'i','n','t','e','g','r','a','l',
+ '-','r','u','n','t','i','m','e'};
+ #endif
+
+ /* validation */
+ if (params->cmd_line && params->process_params)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ else if (params->cmd_line && params->rtblock)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ else if (params->environment && params->process_params)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+
+ /* image_name */
+ __ntapi->rtl_init_unicode_string(
+ &nt_image,
+ params->image_name);
+
+ /* oa_process */
+ if (!params->obj_attr_process) {
+ __ntapi->tt_aligned_block_memset(
+ &oa_process,0,sizeof(oa_process));
+
+ oa_process.len = sizeof(oa_process);
+ params->obj_attr_process = &oa_process;
+ }
+
+ /* oa_thread */
+ if (!params->obj_attr_thread) {
+ __ntapi->tt_aligned_block_memset(
+ &oa_thread,0,sizeof(oa_thread));
+
+ oa_thread.len = sizeof(oa_thread);
+ params->obj_attr_thread = &oa_thread;
+ }
+
+ /* process_params */
+ if (!params->process_params) {
+ /* cmd_line */
+ if (!params->cmd_line) {
+ params->cmd_line = params->image_name;
+ }
+
+ __ntapi->rtl_init_unicode_string(
+ &nt_cmd_line,
+ params->cmd_line);
+
+ /* rtdata (alternative to cmd_line) */
+ if (params->rtblock) {
+ cmd_line_runtime_buffer = (wchar16_t *)0;
+ cmd_line_runtime_buffer_size = nt_cmd_line.maxlen
+ + sizeof(runtime_arg);
+
+ if ((status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&cmd_line_runtime_buffer,
+ 0,&cmd_line_runtime_buffer_size,
+ NT_MEM_RESERVE | NT_MEM_COMMIT,
+ NT_PAGE_READWRITE)))
+ return status;
+
+ __ntapi->tt_memcpy_utf16(
+ (wchar16_t *)cmd_line_runtime_buffer,
+ (wchar16_t *)nt_cmd_line.buffer,
+ nt_cmd_line.strlen);
+
+ __ntapi->tt_memcpy_utf16(
+ (wchar16_t *)pe_va_from_rva(
+ cmd_line_runtime_buffer,
+ nt_cmd_line.strlen),
+ (wchar16_t *)runtime_arg,
+ sizeof(runtime_arg));
+
+ nt_cmd_line.strlen += sizeof(runtime_arg);
+ nt_cmd_line.maxlen += sizeof(runtime_arg);
+ nt_cmd_line.buffer = cmd_line_runtime_buffer;
+ }
+
+
+ /* environment */
+ if (!params->environment)
+ params->environment = __ntapi->tt_get_peb_env_block_utf16();
+
+ if ((status = __ntapi->rtl_create_process_parameters(
+ &params->process_params,
+ &nt_image,
+ (nt_unicode_string *)0,
+ (nt_unicode_string *)0,
+ &nt_cmd_line,
+ params->environment,
+ (nt_unicode_string *)0,
+ (nt_unicode_string *)0,
+ (nt_unicode_string *)0,
+ (nt_unicode_string *)0)))
+ return status;
+
+ __ntapi->rtl_normalize_process_params(params->process_params);
+ }
+
+ /* create_process_info */
+ if (!params->create_process_info) {
+ __ntapi->tt_aligned_block_memset(
+ &nt_process_info,0,sizeof(nt_process_info));
+
+ nt_process_info.size = sizeof(nt_create_process_info);
+ nt_process_info.state = NT_PROCESS_CREATE_INITIAL_STATE;
+ nt_process_info.init_state.init_flags = NT_PROCESS_CREATE_INFO_OBTAIN_OUTPUT;
+ nt_process_info.init_state.file_access_ext = NT_FILE_READ_ATTRIBUTES|NT_FILE_READ_ACCESS;
+
+ params->create_process_info = &nt_process_info;
+ }
+
+ /* create_process_ext_params */
+ if (!params->create_process_ext_params) {
+ __ntapi->tt_aligned_block_memset(
+ &ext_params,0,sizeof(ext_params));
+
+ ext_params.size_in_bytes = sizeof(ext_params);
+
+ /* file_info */
+ ext_params.file_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_SET_FILE_NAME;
+ ext_params.file_info.ext_param_size = nt_image.strlen;
+ ext_params.file_info.ext_param_addr = nt_image.buffer;
+
+ params->create_process_ext_params = (nt_create_process_ext_params *)&ext_params;
+ }
+
+ params->hprocess = 0;
+ params->hthread = 0;
+ fresume_thread = 0;
+
+ if (params->rtblock) {
+ fresume_thread = (params->creation_flags_thread ^ 0x01) & 0x01;
+ params->creation_flags_thread |= 0x01;
+ }
+
+ if (!params->desired_access_process)
+ params->desired_access_process = NT_PROCESS_ALL_ACCESS;
+
+ if (!params->desired_access_thread)
+ params->desired_access_thread = NT_THREAD_ALL_ACCESS;
+
+ if ((status = __ntapi->zw_create_user_process(
+ &params->hprocess,
+ &params->hthread,
+ params->desired_access_process,
+ params->desired_access_thread,
+ params->obj_attr_process,
+ params->obj_attr_thread,
+ params->creation_flags_process,
+ params->creation_flags_thread,
+ params->process_params,
+ params->create_process_info,
+ params->create_process_ext_params)))
+ return status;
+
+ if ((status = __ntapi->zw_query_information_process(
+ params->hprocess,
+ NT_PROCESS_BASIC_INFORMATION,
+ &params->pbi,sizeof(params->pbi),
+ 0)))
+ return __tt_create_process_cancel(params,status);
+
+ if (!params->rtblock)
+ return NT_STATUS_SUCCESS;
+
+ /* rtdata */
+ if ((status = __ntapi_tt_create_remote_runtime_data(params->hprocess,params->rtblock)))
+ return __tt_create_process_cancel(params,status);
+
+ /* conditional resume */
+ if (fresume_thread && (status = __ntapi->zw_resume_thread(params->hthread,0)))
+ return __tt_create_process_cancel(params,status);
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/process/ntapi_tt_create_remote_process_params.c b/src/process/ntapi_tt_create_remote_process_params.c
new file mode 100644
index 0000000..3ff8711
--- /dev/null
+++ b/src/process/ntapi_tt_create_remote_process_params.c
@@ -0,0 +1,331 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_create_remote_process_params(
+ __in void * hprocess,
+ __out nt_process_parameters ** rprocess_params,
+ __in nt_unicode_string * image_file,
+ __in nt_unicode_string * dll_path __optional,
+ __in nt_unicode_string * current_directory __optional,
+ __in nt_unicode_string * command_line __optional,
+ __in wchar16_t * environment __optional,
+ __in nt_unicode_string * window_title __optional,
+ __in nt_unicode_string * desktop_info __optional,
+ __in nt_unicode_string * shell_info __optional,
+ __in nt_unicode_string * runtime_data __optional)
+{
+ #define __ALIGN_ALLOC_SIZE \
+ process_params.alloc_size += sizeof(uintptr_t) - 1; \
+ process_params.alloc_size /= sizeof(uintptr_t); \
+ process_params.alloc_size *= sizeof(uintptr_t);
+
+ int32_t status;
+
+ ptrdiff_t d_image;
+ ptrdiff_t d_dll_path;
+ ptrdiff_t d_cwd;
+ ptrdiff_t d_cmd_line;
+ ptrdiff_t d_environment;
+ ptrdiff_t d_runtime;
+ /*
+ ptrdiff_t d_wnd_title;
+ ptrdiff_t d_desktop;
+ ptrdiff_t d_shell;
+ */
+
+ wchar16_t * wch;
+ size_t env_block_size;
+ size_t params_block_size;
+ size_t bytes_written;
+
+ nt_process_parameters process_params;
+ nt_process_parameters * params_block;
+ nt_process_parameters * rparams_block;
+ nt_process_parameters * params_default;
+
+ /* make the compiler happy */
+ d_image = 0;
+ d_dll_path = 0;
+ d_cwd = 0;
+ d_cmd_line = 0;
+ d_environment = 0;
+ d_runtime = 0;
+ env_block_size = 0;
+
+ /* initialize */
+ __ntapi->tt_aligned_block_memset(
+ &process_params,
+ 0,sizeof(nt_process_parameters));
+
+ /* allow for extended structures (newer OS versions) */
+ process_params.alloc_size = sizeof(nt_process_parameters)
+ + 8 * sizeof(uintptr_t);
+
+ params_default = ((nt_peb *)pe_get_peb_address())->process_params;
+
+ /* image_file */
+ if (image_file) {
+ /* check alignment and sanity */
+ if ((uintptr_t)image_file->buffer % sizeof(uintptr_t))
+ return NT_STATUS_INVALID_PARAMETER_2;
+ else if (image_file->maxlen < image_file->strlen)
+ return NT_STATUS_INVALID_PARAMETER_2;
+
+ process_params.image_file_name.strlen = image_file->strlen;
+ process_params.image_file_name.maxlen = image_file->maxlen;
+
+ /* store offset and update alloc_size */
+ d_image = process_params.alloc_size;
+ process_params.alloc_size += image_file->maxlen;
+ __ALIGN_ALLOC_SIZE;
+ }
+
+ /* dll_path */
+ if (!dll_path)
+ dll_path = &(params_default->dll_path);
+
+ if (dll_path) {
+ /* check alignment and sanity */
+ if ((uintptr_t)dll_path->buffer % sizeof(uintptr_t))
+ return NT_STATUS_INVALID_PARAMETER_3;
+ else if (dll_path->maxlen < dll_path->strlen)
+ return NT_STATUS_INVALID_PARAMETER_3;
+
+ process_params.dll_path.strlen = dll_path->strlen;
+ process_params.dll_path.maxlen = dll_path->maxlen;
+
+ /* store offset and update alloc_size */
+ d_dll_path = process_params.alloc_size;
+ process_params.alloc_size += dll_path->maxlen;
+ __ALIGN_ALLOC_SIZE;
+ }
+
+ /* current_directory */
+ if (!current_directory)
+ current_directory = &(params_default->cwd_name);
+
+ if (current_directory) {
+ /* check alignment and sanity */
+ if ((uintptr_t)current_directory->buffer % sizeof(uintptr_t))
+ return NT_STATUS_INVALID_PARAMETER_4;
+ else if (current_directory->maxlen < current_directory->strlen)
+ return NT_STATUS_INVALID_PARAMETER_4;
+
+ process_params.cwd_name.strlen = current_directory->strlen;
+ process_params.cwd_name.maxlen = current_directory->maxlen;
+
+ /* store offset and update alloc_size */
+ d_cwd = process_params.alloc_size;
+ process_params.alloc_size += current_directory->maxlen;
+ __ALIGN_ALLOC_SIZE;
+ }
+
+ /* command_line */
+ if (command_line) {
+ /* check alignment and sanity */
+ if ((uintptr_t)command_line->buffer % sizeof(uintptr_t))
+ return NT_STATUS_INVALID_PARAMETER_5;
+ else if (command_line->maxlen < command_line->strlen)
+ return NT_STATUS_INVALID_PARAMETER_5;
+
+ process_params.command_line.strlen = command_line->strlen;
+ process_params.command_line.maxlen = command_line->maxlen;
+
+ /* store offset and update alloc_size */
+ d_cmd_line = process_params.alloc_size;
+ process_params.alloc_size += command_line->maxlen;
+ __ALIGN_ALLOC_SIZE;
+ }
+
+ /* environment */
+ if (environment) {
+ /* check alignment */
+ if ((uintptr_t)environment % sizeof(uintptr_t))
+ return NT_STATUS_INVALID_PARAMETER_6;
+
+ /* obtain size of environment block */
+ wch = environment;
+
+ while (*wch) {
+ /* reach the end of the current variable */
+ while (*wch++)
+ /* proceed to the next variable */
+ wch++;
+ }
+
+ env_block_size = (uintptr_t)wch - (uintptr_t)environment;
+
+ /* store offset and update alloc_size */
+ d_environment = process_params.alloc_size;
+ process_params.alloc_size += (uint32_t)env_block_size + 0x1000;
+ __ALIGN_ALLOC_SIZE;
+ }
+
+ /* runtime_data */
+ if (runtime_data) {
+ /* check alignment and sanity */
+ if ((uintptr_t)runtime_data->buffer % sizeof(uintptr_t))
+ return NT_STATUS_INVALID_PARAMETER_5;
+ else if (runtime_data->maxlen < runtime_data->strlen)
+ return NT_STATUS_INVALID_PARAMETER_5;
+
+ process_params.runtime_data.strlen = runtime_data->strlen;
+ process_params.runtime_data.maxlen = runtime_data->maxlen;
+
+ /* store offset and update alloc_size */
+ d_runtime = process_params.alloc_size;
+ process_params.alloc_size += runtime_data->maxlen;
+ __ALIGN_ALLOC_SIZE;
+ }
+
+ /* allocate local and remote process parameters blocks */
+ params_block = (nt_process_parameters *)0;
+ rparams_block = (nt_process_parameters *)0;
+
+ process_params.used_size = process_params.alloc_size;
+ params_block_size = process_params.alloc_size;
+
+ /* local block */
+ status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&params_block,
+ 0,
+ &params_block_size,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ process_params.alloc_size = (uint32_t)params_block_size;
+ __ntapi->tt_aligned_block_memset(params_block,0,params_block_size);
+
+ /* remote block */
+ status = __ntapi->zw_allocate_virtual_memory(
+ hprocess,
+ (void **)&rparams_block,
+ 0,
+ &params_block_size,
+ NT_MEM_RESERVE | NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (status != NT_STATUS_SUCCESS) {
+ __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&params_block,
+ (size_t *)&process_params.alloc_size,
+ NT_MEM_RELEASE);
+
+ return status;
+ }
+
+ /* copy the process_params structure */
+ __ntapi->tt_aligned_memcpy_utf16(
+ (uintptr_t *)params_block,
+ (uintptr_t *)&process_params,
+ sizeof(nt_process_parameters));
+
+ /* image_file */
+ if (image_file) {
+ params_block->image_file_name.buffer =
+ (uint16_t *)pe_va_from_rva(rparams_block,d_image);
+
+ __ntapi->tt_aligned_memcpy_utf16(
+ (uintptr_t *)pe_va_from_rva(params_block,d_image),
+ (uintptr_t *)image_file->buffer,
+ image_file->strlen);
+ }
+
+ /* dll_path */
+ if (dll_path) {
+ params_block->dll_path.buffer =
+ (uint16_t *)pe_va_from_rva(rparams_block,d_dll_path);
+
+ __ntapi->tt_aligned_memcpy_utf16(
+ (uintptr_t *)pe_va_from_rva(params_block,d_dll_path),
+ (uintptr_t *)dll_path->buffer,
+ dll_path->strlen);
+ }
+
+ /* current_directory */
+ if (current_directory) {
+ params_block->cwd_name.buffer =
+ (uint16_t *)pe_va_from_rva(rparams_block,d_cwd);
+
+ __ntapi->tt_aligned_memcpy_utf16(
+ (uintptr_t *)pe_va_from_rva(params_block,d_cwd),
+ (uintptr_t *)current_directory->buffer,
+ current_directory->strlen);
+ }
+
+ /* command_line */
+ if (command_line) {
+ params_block->command_line.buffer =
+ (uint16_t *)pe_va_from_rva(rparams_block,d_cmd_line);
+
+ __ntapi->tt_aligned_memcpy_utf16(
+ (uintptr_t *)pe_va_from_rva(params_block,d_cmd_line),
+ (uintptr_t *)command_line->buffer,
+ command_line->strlen);
+ }
+
+ /* environment */
+ if (environment) {
+ params_block->environment =
+ (wchar16_t *)pe_va_from_rva(rparams_block,d_environment);
+
+ __ntapi->tt_aligned_memcpy_utf16(
+ (uintptr_t *)pe_va_from_rva(params_block,d_environment),
+ (uintptr_t *)environment,
+ env_block_size);
+ }
+
+ /* runtime_data */
+ if (runtime_data) {
+ params_block->runtime_data.buffer =
+ (uint16_t *)pe_va_from_rva(rparams_block,d_runtime);
+
+ __ntapi->tt_aligned_memcpy_utf16(
+ (uintptr_t *)pe_va_from_rva(params_block,d_runtime),
+ (uintptr_t *)runtime_data->buffer,
+ runtime_data->strlen);
+ }
+
+ params_block->flags = 1; /* normalized */
+
+ /* copy the local params block to the remote process */
+ status = __ntapi->zw_write_virtual_memory(
+ hprocess,
+ rparams_block,
+ (char *)params_block,
+ process_params.alloc_size,
+ &bytes_written);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* free the local params block */
+ __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&params_block,
+ (size_t *)&process_params.alloc_size,
+ NT_MEM_RELEASE);
+
+ /* all done */
+ *rprocess_params = rparams_block;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/process/ntapi_tt_create_remote_runtime_data.c b/src/process/ntapi_tt_create_remote_runtime_data.c
new file mode 100644
index 0000000..d3cf9ca
--- /dev/null
+++ b/src/process/ntapi_tt_create_remote_runtime_data.c
@@ -0,0 +1,178 @@
+/********************************************************/
+/* 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/nt_memory.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_process_basic_information nt_pbi;
+
+int32_t __stdcall __ntapi_tt_create_remote_runtime_data(
+ __in void * hprocess,
+ __in_out nt_runtime_data_block * rtblock)
+{
+ int32_t status;
+
+ size_t bytes_written;
+ nt_pbi rpbi;
+ nt_process_parameters * rprocess_params;
+ nt_unicode_string rcmd_line;
+ uint32_t runtime_arg_hash;
+ nt_runtime_data * rtdata;
+ void * srv_ready;
+
+ #if defined (__NT32)
+ wchar16_t runtime_arg[8] = {
+ 'i','n','t','e','g','r','a','l'};
+ #elif defined (__NT64)
+ wchar16_t runtime_arg[16] = {
+ 'i','n','t','e','g','r','a','l',
+ '-','r','u','n','t','i','m','e'};
+ #endif
+
+ /* validation */
+ if (!hprocess)
+ return NT_STATUS_INVALID_PARAMETER_1;
+ else if (!rtblock)
+ return NT_STATUS_INVALID_PARAMETER_2;
+ else if (!rtblock->addr)
+ return NT_STATUS_INVALID_PARAMETER_2;
+ else if (!rtblock->size)
+ return NT_STATUS_INVALID_PARAMETER_2;
+
+ runtime_arg_hash = __ntapi->tt_buffer_crc32(
+ 0,
+ (char *)runtime_arg,
+ sizeof(runtime_arg));
+
+ /* obtain process information */
+ status = __ntapi->zw_query_information_process(
+ hprocess,
+ NT_PROCESS_BASIC_INFORMATION,
+ (void *)&rpbi,
+ sizeof(nt_process_basic_information),
+ 0);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ status = __ntapi->zw_read_virtual_memory(
+ hprocess,
+ pe_va_from_rva(
+ rpbi.peb_base_address,
+ (uintptr_t)&(((nt_peb *)0)->process_params)),
+ (char *)&rprocess_params,
+ sizeof(uintptr_t),
+ &bytes_written);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ status = __ntapi->zw_read_virtual_memory(
+ hprocess,
+ &rprocess_params->command_line,
+ (char *)&rcmd_line,
+ sizeof(nt_unicode_string),
+ &bytes_written);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ if (rcmd_line.buffer == 0)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ else if (rcmd_line.strlen < sizeof(runtime_arg) + 4*sizeof(wchar16_t))
+ return NT_STATUS_INVALID_USER_BUFFER;
+
+ status = __ntapi->zw_read_virtual_memory(
+ hprocess,
+ pe_va_from_rva(
+ rcmd_line.buffer,
+ rcmd_line.strlen - sizeof(runtime_arg)),
+ (char *)&runtime_arg,
+ sizeof(runtime_arg),
+ &bytes_written);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* verify remote process compatibility */
+ runtime_arg_hash ^= __ntapi->tt_buffer_crc32(
+ 0,
+ (char *)runtime_arg,
+ sizeof(runtime_arg));
+
+ if (runtime_arg_hash)
+ return NT_STATUS_INVALID_SIGNATURE;
+
+ /* remote block */
+ rtblock->remote_size = rtblock->size;
+ status = __ntapi->zw_allocate_virtual_memory(
+ hprocess,
+ &rtblock->remote_addr,
+ 0,
+ &rtblock->remote_size,
+ NT_MEM_RESERVE | NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* session handles */
+ if (rtblock->flags & NT_RUNTIME_DATA_DUPLICATE_SESSION_HANDLES) {
+ rtdata = (nt_runtime_data *)rtblock->addr;
+ srv_ready = rtdata->srv_ready;
+
+ status = __ntapi->zw_duplicate_object(
+ NT_CURRENT_PROCESS_HANDLE,
+ srv_ready,
+ hprocess,
+ &rtdata->srv_ready,
+ 0,0,NT_DUPLICATE_SAME_ATTRIBUTES | NT_DUPLICATE_SAME_ACCESS);
+ if (status) return status;
+ } else
+ srv_ready = 0;
+
+ /* copy local block to remote process */
+ status = __ntapi->zw_write_virtual_memory(
+ hprocess,
+ rtblock->remote_addr,
+ (char *)rtblock->addr,
+ rtblock->size,
+ &bytes_written);
+
+ /* restore rtdata */
+ if (srv_ready)
+ rtdata->srv_ready = srv_ready;
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* runtime_arg */
+ __ntapi->tt_uintptr_to_hex_utf16(
+ (uintptr_t)rtblock->remote_addr,
+ runtime_arg);
+
+ /* update remote runtime arg */
+ status = __ntapi->zw_write_virtual_memory(
+ hprocess,
+ pe_va_from_rva(
+ rcmd_line.buffer,
+ rcmd_line.strlen - sizeof(runtime_arg)),
+ (char *)&runtime_arg,
+ sizeof(runtime_arg),
+ &bytes_written);
+
+ if (status)
+ __ntapi->zw_free_virtual_memory(
+ hprocess,
+ &rtblock->remote_addr,
+ &rtblock->remote_size,
+ NT_MEM_RELEASE);
+
+ return status;
+}
diff --git a/src/process/ntapi_tt_fork_v1.c b/src/process/ntapi_tt_fork_v1.c
new file mode 100644
index 0000000..de917ef
--- /dev/null
+++ b/src/process/ntapi_tt_fork_v1.c
@@ -0,0 +1,218 @@
+/********************************************************/
+/* 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/nt_atomic.h>
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_memory.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+intptr_t __cdecl __attr_hidden__ __tt_fork_v1(void);
+uint32_t __fastcall __attr_hidden__ __tt_fork_child_entry_point(uintptr_t saved_regs_stack_pointer);
+uint32_t __fastcall __attr_hidden__ __tt_fork_child_entry_point_adj(uintptr_t saved_regs_stack_pointer);
+
+/** legacy fork chronology:
+ *
+ * parent:
+ * __ntapi_tt_fork ->
+ * __tt_fork ->
+ * __tt_fork_impl ->
+ * return to __tt_fork -->
+ * __ntapi_tt_fork
+ * -> return to caller
+ *
+ * child:
+ * __tt_fork_child_entry_point[_adj] ->
+ * __ntapi_tt_fork (internal return) ->
+ * -> return to caller
+**/
+
+
+static intptr_t __tt_fork_cancel(void * hprocess,int32_t status)
+{
+ __ntapi->zw_terminate_process(hprocess, status);
+ __ntapi->zw_close(hprocess);
+ return (intptr_t)(-1);
+}
+
+intptr_t __fastcall __tt_fork_impl_v1(
+ uintptr_t saved_regs_stack_pointer,
+ uintptr_t stack_adjustment)
+{
+ int32_t status;
+ void * hprocess;
+ void * hthread;
+ void ** hport_session;
+ ntapi_internals * __internals;
+
+ nt_object_attributes oa;
+ nt_process_basic_information pbi;
+ nt_thread_context context;
+ nt_user_stack stack;
+ nt_memory_basic_information mbi;
+ nt_client_id cid;
+ nt_large_integer timeout;
+
+ hprocess = hthread = (void *)0;
+
+ oa.len = sizeof(nt_object_attributes);
+ oa.root_dir = 0;
+ oa.obj_name = 0;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = 0;
+
+ if ((status = __ntapi->zw_create_process(
+ &hprocess,
+ NT_PROCESS_ALL_ACCESS,
+ &oa,
+ NT_CURRENT_PROCESS_HANDLE,
+ 1,0,0,0)))
+ return (intptr_t)(-1);
+
+ if ((status = __ntapi->zw_query_information_process(
+ hprocess,
+ NT_PROCESS_BASIC_INFORMATION,
+ (void *)&pbi,
+ sizeof(nt_process_basic_information),
+ 0)))
+ return __tt_fork_cancel(hprocess,status);
+
+
+
+ __ntapi->tt_aligned_block_memset(
+ &context,0,sizeof(nt_thread_context));
+
+ __INIT_CONTEXT(context);
+ context.STACK_POINTER_REGISTER = saved_regs_stack_pointer;
+ context.FAST_CALL_ARG0 = saved_regs_stack_pointer;
+
+ context.INSTRUCTION_POINTER_REGISTER = stack_adjustment
+ ? (uintptr_t)__tt_fork_child_entry_point_adj
+ : (uintptr_t)__tt_fork_child_entry_point;
+
+
+
+ if ((status = __ntapi->zw_query_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void *)context.STACK_POINTER_REGISTER,
+ NT_MEMORY_BASIC_INFORMATION,
+ &mbi,sizeof(nt_memory_basic_information),0)))
+ return __tt_fork_cancel(hprocess,status);
+
+ stack.fixed_stack_base = (void *)0;
+ stack.fixed_stack_limit = (void *)0;
+ stack.expandable_stack_base = (void *)((uintptr_t)mbi.base_address + mbi.region_size);
+ stack.expandable_stack_limit = (void *)mbi.base_address;
+ stack.expandable_stack_bottom = (void *)mbi.allocation_base;
+
+
+
+ __internals = __ntapi_internals();
+ hport_session = &__internals->hport_tty_session;
+ timeout.quad = (-1) * 10 * 1000 * __NT_FORK_CHILD_WAIT_MILLISEC;
+
+ if (hport_session && *hport_session)
+ if ((status = __ntapi->tty_client_process_register(
+ *hport_session,
+ pbi.unique_process_id,
+ 0, 0, &timeout)))
+ return __tt_fork_cancel(hprocess,status);
+
+
+ if ((status = __ntapi->zw_create_thread(
+ &hthread,
+ NT_THREAD_ALL_ACCESS,
+ &oa,hprocess,&cid,
+ &context,&stack,0)))
+ return __tt_fork_cancel(hprocess,status);
+
+
+ if (cid.process_id > 0) {
+ __internals->hany[0] = hprocess;
+ __internals->hany[1] = hthread;
+ } else {
+ __internals->hany[0] = 0;
+ __internals->hany[1] = 0;
+ }
+
+ /* hoppla */
+ return (int32_t)cid.process_id;
+}
+
+intptr_t __fastcall __ntapi_tt_fork_v1(
+ __out void ** hprocess,
+ __out void ** hthread)
+{
+ int32_t status;
+ intptr_t pid;
+ nt_large_integer timeout;
+ void ** hport_session;
+ void * hevent_tty_connected;
+ ntapi_internals * __internals;
+
+ __internals = __ntapi_internals();
+ hport_session = &__internals->hport_tty_session;
+ timeout.quad = (-1) * 10 * 1000 * __NT_FORK_CHILD_WAIT_MILLISEC;
+
+ if (at_locked_cas(&__internals->hlock,0,1))
+ return (intptr_t)(-1);
+
+ if (hport_session && *hport_session)
+ if (__ntapi_tt_create_inheritable_event(
+ &hevent_tty_connected,
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED))
+ return (intptr_t)(-1);
+
+ pid = __tt_fork_v1();
+
+ *hprocess = __internals->hany[0];
+ *hthread = __internals->hany[1];
+
+ at_store(&__internals->hlock,0);
+
+ if (hport_session && *hport_session) {
+ if (pid == 0) {
+ if ((status = __ntapi->tty_connect(
+ hport_session,
+ __internals->subsystem->base_named_objects,
+ NT_SECURITY_IMPERSONATION)))
+ return __tt_fork_cancel(NT_CURRENT_PROCESS_HANDLE,status);
+
+ __internals->hdev_mount_point_mgr = 0;
+
+ if (__internals->rtdata)
+ __internals->rtdata->hsession = *hport_session;
+
+ __ntapi->zw_set_event(
+ hevent_tty_connected,
+ 0);
+
+ } else if (pid > 0) {
+ status = __ntapi->zw_wait_for_single_object(
+ hevent_tty_connected,
+ NT_SYNC_NON_ALERTABLE,
+ &timeout);
+
+ if (status && __PSX_DEBUG)
+ if ((status = __ntapi->zw_wait_for_single_object(
+ hevent_tty_connected,
+ NT_SYNC_NON_ALERTABLE,
+ 0)))
+ pid = __tt_fork_cancel(*hprocess,status);
+ }
+
+ __ntapi->zw_close(hevent_tty_connected);
+ }
+
+ return pid;
+}
diff --git a/src/process/ntapi_tt_fork_v2.c b/src/process/ntapi_tt_fork_v2.c
new file mode 100644
index 0000000..e483554
--- /dev/null
+++ b/src/process/ntapi_tt_fork_v2.c
@@ -0,0 +1,183 @@
+/********************************************************/
+/* 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/nt_status.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_memory.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+static intptr_t __tt_fork_cancel(void * hprocess,int32_t status)
+{
+ __ntapi->zw_terminate_process(hprocess, status);
+ __ntapi->zw_close(hprocess);
+ return (intptr_t)(-1);
+}
+
+intptr_t __fastcall __tt_fork_impl_v2(
+ __out void ** hprocess,
+ __out void ** hthread)
+{
+ int32_t status;
+ void ** hport_session;
+ nt_object_attributes oa_process;
+ nt_object_attributes oa_thread;
+ nt_create_process_info process_info;
+ nt_cid cid;
+ nt_sec_img_inf sec_img_inf;
+ nt_timeout timeout;
+ ntapi_internals * __internals;
+
+ struct {
+ size_t size_in_bytes;
+ nt_create_process_ext_param process_info;
+ nt_create_process_ext_param section_info;
+ } ext_params;
+
+
+ oa_process.len = sizeof(nt_object_attributes);
+ oa_process.root_dir = 0;
+ oa_process.obj_name = 0;
+ oa_process.obj_attr = 0;
+ oa_process.sec_desc = 0;
+ oa_process.sec_qos = 0;
+
+ oa_thread.len = sizeof(nt_object_attributes);
+ oa_thread.root_dir = 0;
+ oa_thread.obj_name = 0;
+ oa_thread.obj_attr = 0;
+ oa_thread.sec_desc = 0;
+ oa_thread.sec_qos = 0;
+
+
+ __ntapi->tt_aligned_block_memset(
+ &process_info,0,sizeof(process_info));
+
+ process_info.size = sizeof(process_info);
+ process_info.state = NT_PROCESS_CREATE_INITIAL_STATE;
+ process_info.init_state.init_flags = NT_PROCESS_CREATE_FLAGS_NO_OBJECT_SYNC;
+
+ __ntapi->tt_aligned_block_memset(&ext_params,0,sizeof(ext_params));
+ __ntapi->tt_aligned_block_memset(&cid,0,sizeof(cid));
+ __ntapi->tt_aligned_block_memset(&sec_img_inf,0,sizeof(sec_img_inf));
+ ext_params.size_in_bytes = sizeof(ext_params);
+
+ ext_params.process_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_GET_CLIENT_ID;
+ ext_params.process_info.ext_param_size = sizeof(cid);
+ ext_params.process_info.ext_param_addr = &cid;
+
+ ext_params.section_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_GET_SECTION_IMAGE_INFO;
+ ext_params.section_info.ext_param_size = sizeof(sec_img_inf);
+ ext_params.section_info.ext_param_addr = &sec_img_inf;
+
+
+ /* [thou shalt remember the single step paradox] */
+ status = __ntapi->zw_create_user_process(
+ hprocess,
+ hthread,
+ NT_PROCESS_ALL_ACCESS,
+ NT_THREAD_ALL_ACCESS,
+ &oa_process,
+ &oa_thread,
+ NT_PROCESS_CREATE_FLAGS_INHERIT_HANDLES,
+ NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED,
+ (nt_process_parameters *)0,
+ &process_info,
+ (nt_create_process_ext_params *)&ext_params);
+
+ if (status == NT_STATUS_PROCESS_CLONED)
+ return 0;
+ else if (status)
+ return (intptr_t)(-1);
+
+ __internals = __ntapi_internals();
+ hport_session = &__internals->hport_tty_session;
+ timeout.quad = (-1) * 10 * 1000 * __NT_FORK_CHILD_WAIT_MILLISEC;
+
+ if (hport_session && *hport_session)
+ if ((status = __ntapi->tty_client_process_register(
+ *hport_session,
+ cid.process_id,
+ 0,0,&timeout)))
+ return __tt_fork_cancel(*hprocess,status);
+
+ /* [thou shalt remember the single step paradox] */
+ if ((status = __ntapi->zw_resume_thread(
+ *hthread,0)))
+ return __tt_fork_cancel(*hprocess,status);
+
+ /* hoppla */
+ return (int32_t)cid.process_id;
+}
+
+intptr_t __fastcall __ntapi_tt_fork_v2(
+ __out void ** hprocess,
+ __out void ** hthread)
+{
+ int32_t status;
+ intptr_t pid;
+ nt_large_integer timeout;
+ void ** hport_session;
+ void * hevent_tty_connected;
+ ntapi_internals * __internals;
+
+ __internals = __ntapi_internals();
+ hport_session = &__internals->hport_tty_session;
+ timeout.quad = (-1) * 10 * 1000 * __NT_FORK_CHILD_WAIT_MILLISEC;
+
+ if (hport_session && *hport_session)
+ if (__ntapi_tt_create_inheritable_event(
+ &hevent_tty_connected,
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED))
+ return (intptr_t)(-1);
+
+ pid = __tt_fork_impl_v2(hprocess,hthread);
+
+ if (!hport_session || !*hport_session)
+ return pid;
+ else if (pid < 0)
+ return pid;
+
+ if (pid == 0) {
+ if ((status = __ntapi->tty_connect(
+ hport_session,
+ __internals->subsystem->base_named_objects,
+ NT_SECURITY_IMPERSONATION)))
+ return __tt_fork_cancel(NT_CURRENT_PROCESS_HANDLE,status);
+
+ __internals->hdev_mount_point_mgr = 0;
+
+ if (__internals->rtdata)
+ __internals->rtdata->hsession = *hport_session;
+
+ __ntapi->zw_set_event(
+ hevent_tty_connected,
+ 0);
+ } else {
+ status = __ntapi->zw_wait_for_single_object(
+ hevent_tty_connected,
+ NT_SYNC_NON_ALERTABLE,
+ &timeout);
+
+ if (status && __PSX_DEBUG)
+ if ((status = __ntapi->zw_wait_for_single_object(
+ hevent_tty_connected,
+ NT_SYNC_NON_ALERTABLE,
+ 0)))
+ pid = __tt_fork_cancel(*hprocess,status);
+ }
+
+
+ __ntapi->zw_close(hevent_tty_connected);
+
+ return pid;
+}
diff --git a/src/process/ntapi_tt_get_runtime_data.c b/src/process/ntapi_tt_get_runtime_data.c
new file mode 100644
index 0000000..92b4b2b
--- /dev/null
+++ b/src/process/ntapi_tt_get_runtime_data.c
@@ -0,0 +1,83 @@
+/********************************************************/
+/* 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/nt_memory.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+#if defined (__NT32)
+static wchar16_t runtime_arg[12] = {
+ ' ','-','r',' ',
+ 'i','n','t','e','g','r','a','l'};
+#elif defined (__NT64)
+static wchar16_t runtime_arg[20] = {
+ ' ','-','r',' ',
+ 'i','n','t','e','g','r','a','l',
+ '-','r','u','n','t','i','m','e'};
+#endif
+
+int32_t __stdcall __ntapi_tt_get_runtime_data(
+ __out nt_runtime_data ** rtdata,
+ __in wchar16_t ** argv)
+{
+ int32_t status;
+ nt_process_parameters * process_params;
+ nt_cmd_option_meta_utf16 cmd_opt_meta;
+ nt_runtime_data buffer;
+ nt_runtime_data * prtdata;
+ ntapi_internals * __internals;
+
+ /* init */
+ __internals = __ntapi_internals();
+
+ /* once? */
+ if (__internals->rtdata) {
+ *rtdata = __internals->rtdata;
+ return NT_STATUS_SUCCESS;
+ }
+
+ if (!(argv = argv ? argv : __internals->ntapi_img_sec_bss->argv_envp_array))
+ return NT_STATUS_INVALID_PARAMETER_2;
+
+ /* integral process? */
+ if ((status = __ntapi->tt_get_short_option_meta_utf16(
+ __ntapi->tt_crc32_table(),
+ 'r',
+ argv,
+ &cmd_opt_meta)))
+ return status;
+
+ else if (argv[3])
+ status = NT_STATUS_INVALID_PARAMETER_MIX;
+
+ if ((status = __ntapi->tt_hex_utf16_to_uintptr(
+ cmd_opt_meta.value,
+ (uintptr_t *)&prtdata)))
+ return status;
+
+ if ((status = __ntapi->zw_read_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ prtdata,
+ (char *)&buffer,
+ sizeof(buffer),0)))
+ return status;
+
+ /* avoid confusion :-) */
+ process_params = ((nt_peb *)pe_get_peb_address())->process_params;
+
+ __ntapi->tt_memcpy_utf16(
+ (wchar16_t *)pe_va_from_rva(
+ process_params->command_line.buffer,
+ process_params->command_line.strlen - sizeof(runtime_arg)),
+ runtime_arg,
+ sizeof(runtime_arg));
+
+ *rtdata = prtdata;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/process/ntapi_tt_init_runtime_data.c b/src/process/ntapi_tt_init_runtime_data.c
new file mode 100644
index 0000000..c7c2603
--- /dev/null
+++ b/src/process/ntapi_tt_init_runtime_data.c
@@ -0,0 +1,82 @@
+/********************************************************/
+/* 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/nt_memory.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_update_runtime_data(nt_runtime_data * rtdata)
+{
+ int32_t status;
+ nt_process_basic_information pbi;
+ uint32_t ret;
+ nt_oa oa = {sizeof(oa)};
+
+ /* process (self) */
+ rtdata->cid_self.process_id = pe_get_current_process_id();
+ rtdata->cid_self.thread_id = 0;
+
+ if ((status = __ntapi->zw_open_process(
+ &rtdata->hprocess_self,
+ NT_PROCESS_ALL_ACCESS,
+ &oa,&rtdata->cid_self)))
+ return status;
+
+ if (rtdata->cid_parent.process_id)
+ return NT_STATUS_SUCCESS;
+
+ /* process (parent) */
+ if ((status = __ntapi->zw_query_information_process(
+ rtdata->hprocess_self,
+ NT_PROCESS_BASIC_INFORMATION,
+ &pbi,sizeof(pbi),&ret)))
+ return status;
+
+ rtdata->cid_parent.process_id = pbi.inherited_from_unique_process_id;
+ rtdata->cid_parent.thread_id = 0;
+ rtdata->hprocess_parent = 0;
+
+ return NT_STATUS_SUCCESS;
+}
+
+int32_t __stdcall __ntapi_tt_init_runtime_data(nt_runtime_data * rtdata)
+{
+ int32_t status;
+ nt_peb * peb;
+ nt_oa oa = {sizeof(oa)};
+
+ /* init */
+ __ntapi->tt_aligned_block_memset(rtdata,0,sizeof(*rtdata));
+ peb = (nt_peb *)(pe_get_peb_address());
+
+ /* pid (self,parent) */
+ if ((status = __ntapi_tt_update_runtime_data(rtdata)))
+ return status;
+
+ /* std handles */
+ rtdata->hstdin = peb->process_params->hstdin;
+ rtdata->hstdout = peb->process_params->hstdout;
+ rtdata->hstderr = peb->process_params->hstderr;
+
+ if (__ntapi->tt_get_file_handle_type(rtdata->hstdin,&rtdata->stdin_type)) {
+ rtdata->hstdin = NT_INVALID_HANDLE_VALUE;
+ rtdata->stdin_type = 0;
+ }
+
+ if (__ntapi->tt_get_file_handle_type(rtdata->hstdout,&rtdata->stdout_type)) {
+ rtdata->hstdout = NT_INVALID_HANDLE_VALUE;
+ rtdata->stdout_type = 0;
+ }
+
+ if (__ntapi->tt_get_file_handle_type(rtdata->hstderr,&rtdata->stderr_type)) {
+ rtdata->hstderr = NT_INVALID_HANDLE_VALUE;
+ rtdata->stderr_type = 0;
+ }
+
+ return 0;
+}
diff --git a/src/process/ntapi_tt_map_image_as_data.c b/src/process/ntapi_tt_map_image_as_data.c
new file mode 100644
index 0000000..864f9cc
--- /dev/null
+++ b/src/process/ntapi_tt_map_image_as_data.c
@@ -0,0 +1,120 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_section.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+static nt_sqos const sqos = {
+ sizeof(sqos),
+ NT_SECURITY_IMPERSONATION,
+ NT_SECURITY_TRACKING_DYNAMIC,
+ 1};
+
+static int32_t __tt_exec_unmap_image(nt_executable_image * image, void * base, int32_t status)
+{
+ int32_t ret;
+
+ if (base)
+ if ((ret = __ntapi->zw_unmap_view_of_section(
+ NT_CURRENT_PROCESS_HANDLE,
+ base)))
+ return ret;
+
+ if (image->hsection)
+ if ((ret = __ntapi->zw_close(image->hsection)))
+ return ret;
+
+ return status;
+}
+
+int32_t __stdcall __ntapi_tt_exec_unmap_image(nt_executable_image * image)
+{
+ return __tt_exec_unmap_image(image,image->addr,0);
+}
+
+
+int32_t __stdcall __ntapi_tt_exec_map_image_as_data(nt_executable_image * image)
+{
+ int32_t status;
+ uint16_t * pi16;
+ uint32_t * pi32;
+ nt_sec_size sec_size;
+ size_t view_size;
+ void * base;
+ void * hsection;
+
+ struct pe_image_dos_hdr * dos;
+ struct pe_coff_file_hdr * coff;
+ union pe_opt_hdr * opt;
+ struct pe_sec_hdr * sec;
+
+ nt_oa oa = {sizeof(oa),
+ 0,0,0,0,(nt_sqos *)&sqos};
+
+ base = 0;
+ sec_size.quad = 0;
+ view_size = image->size;
+
+ if ((status = __ntapi->zw_create_section(
+ &hsection,
+ NT_SECTION_MAP_READ,
+ &oa,
+ &sec_size,
+ NT_PAGE_READONLY,
+ NT_SEC_RESERVE,image->hfile)))
+ return status;
+
+ if ((status = __ntapi->zw_map_view_of_section(
+ hsection,
+ NT_CURRENT_PROCESS_HANDLE,
+ &base,
+ 0,0,0,
+ &view_size,
+ NT_VIEW_UNMAP,0,
+ NT_PAGE_READONLY)))
+ return __tt_exec_unmap_image(
+ image,base,status);
+
+ if (!(dos = pe_get_image_dos_hdr_addr(base)))
+ return 0;
+
+ pi32 = (uint32_t *)dos->dos_lfanew;
+ if ((*pi32 + sizeof(*coff)) > view_size)
+ return __tt_exec_unmap_image(
+ image,base,NT_STATUS_INVALID_IMAGE_FORMAT);
+
+ if (!(coff = pe_get_image_coff_hdr_addr(base)))
+ return 0;
+
+ if (!(opt = pe_get_image_opt_hdr_addr(base)))
+ return 0;
+
+ sec = pe_get_image_section_tbl_addr(base);
+ pi16 = (uint16_t *)coff->num_of_sections;
+ if (((size_t)sec-(size_t)base + *pi16 * sizeof(*sec)) > view_size)
+ return __tt_exec_unmap_image(
+ image,base,NT_STATUS_INVALID_IMAGE_FORMAT);
+
+ /* subsystem: same offset (pe32, pe32+) */
+ pi16 = (uint16_t *)opt;
+ image->magic = *pi16;
+
+ pi16 = (uint16_t *)opt->opt_hdr_32.subsystem;
+ image->subsystem = *pi16;
+
+ pi16 = (uint16_t *)coff->characteristics;
+ image->characteristics = *pi16;
+
+ image->hsection = hsection;
+ image->addr = base;
+ image->size = view_size;
+
+ return status;
+}
diff --git a/src/process/tt_fork_v1.c b/src/process/tt_fork_v1.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/process/tt_fork_v1.c
diff --git a/src/pty/ntapi_pty_cancel.c b/src/pty/ntapi_pty_cancel.c
new file mode 100644
index 0000000..4bfbb79
--- /dev/null
+++ b/src/pty/ntapi_pty_cancel.c
@@ -0,0 +1,46 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+#include "ntapi_pty.h"
+
+int32_t __stdcall __ntapi_pty_cancel(
+ nt_pty * pty,
+ nt_iosb * iosb)
+{
+ int32_t status;
+ nt_pty_io_msg msg;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_PTY_CANCEL;
+
+ msg.data.ioinfo.hpty = pty->hpty;
+ msg.data.ioinfo.luid.high = pty->luid.high;
+ msg.data.ioinfo.luid.low = pty->luid.low;
+
+ __ntapi->tt_guid_copy(
+ &msg.data.ioinfo.guid,
+ &pty->guid);
+
+ if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ iosb->info = msg.data.ioinfo.iosb.info;
+ iosb->status = msg.data.ioinfo.iosb.status;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/pty/ntapi_pty_fd.c b/src/pty/ntapi_pty_fd.c
new file mode 100644
index 0000000..ee0b426
--- /dev/null
+++ b/src/pty/ntapi_pty_fd.c
@@ -0,0 +1,232 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+#include "ntapi_pty.h"
+
+static int32_t __stdcall __ntapi_pty_open_close(
+ nt_pty * pty,
+ nt_iosb * iosb,
+ int32_t opcode)
+{
+ int32_t status;
+ nt_pty_fd_msg msg;
+
+ __ntapi->tt_aligned_block_memset(&msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = opcode;
+
+ msg.data.fdinfo.hpty = pty->hpty;
+ msg.data.fdinfo.access = pty->access;
+ msg.data.fdinfo.flags = pty->flags;
+ msg.data.fdinfo.share = pty->share;
+ msg.data.fdinfo.options = pty->options;
+
+ msg.data.fdinfo.luid.high = pty->luid.high;
+ msg.data.fdinfo.luid.low = pty->luid.low;
+
+ __ntapi_tt_guid_copy(
+ &msg.data.fdinfo.guid,
+ &pty->guid);
+
+ if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ pty->hpty = msg.data.fdinfo.hpty;
+ pty->section = msg.data.fdinfo.section;
+ pty->section_size = msg.data.fdinfo.section_size;
+ pty->luid.high = msg.data.fdinfo.luid.high;
+ pty->luid.low = msg.data.fdinfo.luid.low;
+ iosb->status = msg.data.ttyinfo.status;
+ iosb->info = 0;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __ntapi_pty_free(nt_pty * pty)
+{
+ void * addr;
+ size_t size;
+
+ /* unmap section */
+ if (pty->section_addr)
+ __ntapi->zw_unmap_view_of_section(
+ NT_CURRENT_PROCESS_HANDLE,
+ pty->section_addr);
+
+ /* free control block */
+ addr = pty->addr;
+ size = pty->size;
+
+ return __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &addr,
+ &size,
+ NT_MEM_RELEASE);
+}
+
+
+static int32_t __fastcall __ntapi_pty_fail(nt_pty * pty,int32_t status)
+{
+ __ntapi_pty_free(pty);
+ return status;
+}
+
+
+static int32_t __fastcall __ntapi_pty_alloc(nt_pty ** pty)
+{
+ int32_t status;
+ nt_pty * ctx;
+ size_t ctx_size;
+
+ /* allocate control block */
+ ctx = 0;
+ ctx_size = sizeof(nt_pty);
+
+ if ((status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&ctx,
+ 0,&ctx_size,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE)))
+ return status;
+
+ /* init control block */
+ __ntapi->tt_aligned_block_memset(
+ ctx,0,ctx_size);
+
+ ctx->addr = ctx;
+ ctx->size = ctx_size;
+
+ *pty = ctx;
+ return NT_STATUS_SUCCESS;
+}
+
+static int32_t __ntapi_pty_connect(
+ void * hport,
+ nt_pty * ctx,
+ nt_iosb * iosb)
+{
+ int32_t status;
+
+ ctx->hport = hport
+ ? hport
+ : __ntapi_internals()->hport_tty_session;
+
+ /* request */
+ iosb = iosb ? iosb : &ctx->iosb;
+
+ if ((status = __ntapi_pty_open_close(ctx,iosb,NT_TTY_PTY_OPEN)))
+ return __ntapi_pty_fail(ctx,status);
+
+ /* map section */
+ if ((status = __ntapi->zw_map_view_of_section(
+ ctx->section,
+ NT_CURRENT_PROCESS_HANDLE,
+ &ctx->section_addr,
+ 0,ctx->section_size,
+ 0,&ctx->section_size,
+ NT_VIEW_UNMAP,0,
+ NT_PAGE_READWRITE)))
+ return __ntapi_pty_fail(ctx,status);
+
+ /* assume conforming clients, config for single lock try */
+ __ntapi->tt_sync_block_init(&ctx->sync[__PTY_READ],0,0,1,0,0);
+ __ntapi->tt_sync_block_init(&ctx->sync[__PTY_WRITE],0,0,1,0,0);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_pty_open(
+ void * hport,
+ nt_pty ** pty,
+ uint32_t desired_access,
+ nt_object_attributes* obj_attr,
+ nt_iosb * iosb,
+ uint32_t share_access,
+ uint32_t open_options)
+{
+ int32_t status;
+ uint32_t hash;
+ nt_guid guid;
+ nt_uuid_str_utf16 * guid_str;
+ nt_pty * ctx;
+
+ if (!obj_attr || !obj_attr->obj_name || !obj_attr->obj_name->buffer)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if (obj_attr->obj_name->strlen != __DEVICE_PATH_PREFIX_LEN + sizeof(nt_guid_str_utf16))
+ return NT_STATUS_OBJECT_PATH_INVALID;
+
+ hash = __ntapi->tt_buffer_crc32(
+ 0,
+ obj_attr->obj_name->buffer,
+ __DEVICE_PATH_PREFIX_LEN);
+
+ if (hash != __DEVICE_PATH_PREFIX_HASH)
+ return NT_STATUS_OBJECT_PATH_INVALID;
+
+ guid_str = (nt_uuid_str_utf16 *)
+ ((uintptr_t)obj_attr->obj_name->buffer + __DEVICE_PATH_PREFIX_LEN);
+
+ if (__ntapi->tt_utf16_string_to_guid(guid_str,&guid))
+ return NT_STATUS_OBJECT_NAME_INVALID;
+
+ /* control block */
+ if ((status = __ntapi_pty_alloc(&ctx)))
+ return status;
+
+ __ntapi_tt_guid_copy(
+ &ctx->guid,
+ &guid);
+
+ ctx->access = desired_access;
+ ctx->flags = obj_attr->obj_attr;
+ ctx->share = share_access;
+ ctx->options = open_options;
+
+ /* pts */
+ if (obj_attr->root_dir) {
+ ctx->luid.high = ((nt_pty *)obj_attr->root_dir)->luid.high;
+ ctx->luid.low = ((nt_pty *)obj_attr->root_dir)->luid.low;
+ }
+
+ if ((status = __ntapi_pty_connect(hport,ctx,iosb)))
+ return status;
+
+ *pty = ctx;
+
+ return NT_STATUS_SUCCESS;
+}
+
+int32_t __stdcall __ntapi_pty_reopen(
+ __in void * hport,
+ __in nt_pty * pty)
+{
+ return __ntapi_pty_connect(hport,pty,0);
+}
+
+int32_t __stdcall __ntapi_pty_close(nt_pty * pty)
+{
+ if (!pty || (pty->addr != pty))
+ return NT_STATUS_INVALID_PARAMETER;
+
+ __ntapi_pty_open_close(
+ pty,&pty->iosb,NT_TTY_PTY_CLOSE);
+
+ return __ntapi_pty_free(pty);
+}
diff --git a/src/pty/ntapi_pty_io.c b/src/pty/ntapi_pty_io.c
new file mode 100644
index 0000000..f110371
--- /dev/null
+++ b/src/pty/ntapi_pty_io.c
@@ -0,0 +1,130 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+#include "ntapi_pty.h"
+
+static int32_t __stdcall __ntapi_pty_read_write(
+ nt_pty * pty,
+ void * hevent,
+ nt_io_apc_routine * apc_routine,
+ void * apc_context,
+ nt_iosb * iosb,
+ void * buffer,
+ size_t nbytes,
+ nt_large_integer * offset,
+ uint32_t * key,
+ int32_t opcode)
+{
+ int32_t status;
+ nt_pty_io_msg msg;
+ off_t soffset;
+ int mode;
+
+ mode = opcode - NT_TTY_PTY_READ;
+ soffset = mode * pty->section_size / 2;
+
+ if (offset && offset->quad)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ else if (__ntapi->tt_sync_block_lock(&pty->sync[mode],1,0,0))
+ return NT_STATUS_RESOURCE_NOT_OWNED;
+
+ nbytes = nbytes <= pty->section_size / 2
+ ? nbytes
+ : pty->section_size / 2;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = opcode;
+
+ msg.data.ioinfo.hpty = pty->hpty;
+ msg.data.ioinfo.hevent = hevent;
+ msg.data.ioinfo.apc_routine = apc_routine;
+ msg.data.ioinfo.apc_context = apc_context;
+ msg.data.ioinfo.key = key ? *key : 0;
+
+ msg.data.ioinfo.luid.high = pty->luid.high;
+ msg.data.ioinfo.luid.low = pty->luid.low;
+
+ msg.data.ioinfo.riosb = iosb;
+ msg.data.ioinfo.raddr = buffer;
+
+ __ntapi->tt_guid_copy(
+ &msg.data.ioinfo.guid,
+ &pty->guid);
+
+ msg.data.ioinfo.nbytes = nbytes;
+ msg.data.ioinfo.offset = soffset;
+
+ if (mode == __PTY_WRITE)
+ __ntapi->tt_generic_memcpy(
+ (char *)pty->section_addr + soffset,
+ (char *)buffer,
+ nbytes);
+
+ if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ if (mode == __PTY_READ)
+ __ntapi->tt_generic_memcpy(
+ (char *)buffer,
+ (char *)pty->section_addr + soffset,
+ msg.data.ioinfo.iosb.info);
+
+ iosb->info = msg.data.ioinfo.iosb.info;
+ iosb->status = msg.data.ioinfo.iosb.status;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_pty_read(
+ __in nt_pty * pty,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_iosb * iosb,
+ __out void * buffer,
+ __in uint32_t nbytes,
+ __in nt_large_integer * offset __optional,
+ __in uint32_t * key __optional)
+{
+ return __ntapi_pty_read_write(
+ pty,
+ hevent,apc_routine,apc_context,
+ iosb,buffer,nbytes,offset,key,
+ NT_TTY_PTY_READ);
+}
+
+
+int32_t __stdcall __ntapi_pty_write(
+ __in nt_pty * pty,
+ __in void * hevent __optional,
+ __in nt_io_apc_routine * apc_routine __optional,
+ __in void * apc_context __optional,
+ __out nt_iosb * iosb,
+ __in void * buffer,
+ __in uint32_t nbytes,
+ __in nt_large_integer * offset __optional,
+ __in uint32_t * key __optional)
+{
+ return __ntapi_pty_read_write(
+ pty,
+ hevent,apc_routine,apc_context,
+ iosb,buffer,nbytes,offset,key,
+ NT_TTY_PTY_WRITE);
+}
diff --git a/src/pty/ntapi_pty_ioctl.c b/src/pty/ntapi_pty_ioctl.c
new file mode 100644
index 0000000..f828753
--- /dev/null
+++ b/src/pty/ntapi_pty_ioctl.c
@@ -0,0 +1,92 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/nt_termios.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+#include "ntapi_pty.h"
+
+int32_t __stdcall __ntapi_pty_ioctl(
+ nt_pty * pty,
+ void * hevent __optional,
+ nt_io_apc_routine * apc_routine __optional,
+ void * apc_context __optional,
+ nt_iosb * iosb,
+ uint32_t ctlcode,
+ void * input_buffer __optional,
+ uint32_t input_buffer_length,
+ void * output_buffer __optional,
+ uint32_t output_buffer_length)
+{
+ int32_t status;
+ nt_pty_sigctl_msg msg;
+ nt_tty_sigctl_info * input;
+ nt_tty_sigctl_info * output;
+
+ if ((uintptr_t)input_buffer % sizeof(uintptr_t))
+ return NT_STATUS_DATATYPE_MISALIGNMENT_ERROR;
+ else if (input_buffer_length != sizeof(nt_tty_sigctl_info))
+ return NT_STATUS_INVALID_BUFFER_SIZE;
+ else if (!output_buffer)
+ return NT_STATUS_ACCESS_DENIED;
+ else if ((uintptr_t)output_buffer % sizeof(uintptr_t))
+ return NT_STATUS_DATATYPE_MISALIGNMENT_ERROR;
+ else if (output_buffer_length < sizeof(nt_tty_sigctl_info))
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ input = (nt_tty_sigctl_info *)input_buffer;
+ output = (nt_tty_sigctl_info *)output_buffer;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_PTY_IOCTL;
+
+ msg.data.ctlinfo.hpty = pty->hpty;
+ msg.data.ctlinfo.luid.high = pty->luid.high;
+ msg.data.ctlinfo.luid.low = pty->luid.low;
+ msg.data.ctlinfo.ctlcode = ctlcode;
+
+ __ntapi->tt_guid_copy(
+ &msg.data.ctlinfo.guid,
+ &pty->guid);
+
+ msg.data.ctlinfo.ctxarg[0] = input->ctxarg[0];
+ msg.data.ctlinfo.ctxarg[1] = input->ctxarg[1];
+ msg.data.ctlinfo.ctxarg[2] = input->ctxarg[2];
+ msg.data.ctlinfo.ctxarg[3] = input->ctxarg[3];
+
+ __ntapi->tt_generic_memcpy(
+ (char *)&input->terminfo,
+ (char *)&msg.data.ctlinfo.terminfo,
+ sizeof(input->terminfo));
+
+ __ntapi->tt_generic_memcpy(
+ (char *)&input->winsize,
+ (char *)&msg.data.ctlinfo.winsize,
+ sizeof(input->winsize));
+
+ if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)output,
+ (uintptr_t *)&msg.data.ctlinfo,
+ sizeof(*output));
+
+ iosb->info = msg.data.ctlinfo.iosb.info;
+ iosb->status = msg.data.ctlinfo.iosb.status;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/pty/ntapi_pty_query.c b/src/pty/ntapi_pty_query.c
new file mode 100644
index 0000000..57d31ee
--- /dev/null
+++ b/src/pty/ntapi_pty_query.c
@@ -0,0 +1,64 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+#include "ntapi_pty.h"
+
+int32_t __stdcall __ntapi_pty_query(
+ nt_pty * pty,
+ nt_io_status_block * iosb,
+ void * pty_info,
+ uint32_t pty_info_length,
+ nt_pty_info_class pty_info_class)
+{
+ int32_t status;
+ nt_pty_sigctl_msg msg;
+ uintptr_t * info;
+
+ if ((pty_info_class<NT_PTY_BASIC_INFORMATION) || (pty_info_class>=NT_PTY_INFORMATION_CAP))
+ return NT_STATUS_INVALID_INFO_CLASS;
+ else if (pty_info_class == NT_PTY_BASIC_INFORMATION)
+ return NT_STATUS_NOT_IMPLEMENTED;
+ else if ((pty_info_class == NT_PTY_CLIENT_INFORMATION) && (pty_info_length != sizeof(nt_pty_client_info)))
+ return NT_STATUS_INVALID_PARAMETER;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_PTY_QUERY;
+
+ msg.data.ctlinfo.hpty = pty->hpty;
+ msg.data.ctlinfo.luid.high = pty->luid.high;
+ msg.data.ctlinfo.luid.low = pty->luid.low;
+ msg.data.ctlinfo.ctlcode = pty_info_class;
+
+ __ntapi->tt_guid_copy(
+ &msg.data.ctlinfo.guid,
+ &pty->guid);
+
+ if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ iosb->info = msg.data.ctlinfo.iosb.info;
+ iosb->status = msg.data.ctlinfo.iosb.status;
+
+ info = (uintptr_t *)pty_info;
+ info[0] = msg.data.ctlinfo.ctxarg[0];
+ info[1] = msg.data.ctlinfo.ctxarg[1];
+ info[2] = msg.data.ctlinfo.ctxarg[2];
+ info[3] = msg.data.ctlinfo.ctxarg[3];
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/pty/ntapi_pty_set.c b/src/pty/ntapi_pty_set.c
new file mode 100644
index 0000000..1543e7c
--- /dev/null
+++ b/src/pty/ntapi_pty_set.c
@@ -0,0 +1,64 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+#include "ntapi_pty.h"
+
+int32_t __stdcall __ntapi_pty_set(
+ nt_pty * pty,
+ nt_io_status_block * iosb,
+ void * pty_info,
+ uint32_t pty_info_length,
+ nt_pty_info_class pty_info_class)
+{
+ int32_t status;
+ nt_pty_sigctl_msg msg;
+ uintptr_t * info;
+
+ if ((pty_info_class<NT_PTY_BASIC_INFORMATION) || (pty_info_class>=NT_PTY_INFORMATION_CAP))
+ return NT_STATUS_INVALID_INFO_CLASS;
+ else if (pty_info_class == NT_PTY_BASIC_INFORMATION)
+ return NT_STATUS_NOT_IMPLEMENTED;
+ else if ((pty_info_class == NT_PTY_CLIENT_INFORMATION) && (pty_info_length != sizeof(nt_pty_client_info)))
+ return NT_STATUS_INVALID_PARAMETER;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_PTY_SET;
+
+ msg.data.ctlinfo.hpty = pty->hpty;
+ msg.data.ctlinfo.luid.high = pty->luid.high;
+ msg.data.ctlinfo.luid.low = pty->luid.low;
+ msg.data.ctlinfo.ctlcode = pty_info_class;
+
+ __ntapi->tt_guid_copy(
+ &msg.data.ctlinfo.guid,
+ &pty->guid);
+
+ info = (uintptr_t *)pty_info;
+ msg.data.ctlinfo.ctxarg[0] = info[0];
+ msg.data.ctlinfo.ctxarg[1] = info[1];
+ msg.data.ctlinfo.ctxarg[2] = info[2];
+ msg.data.ctlinfo.ctxarg[3] = info[3];
+
+ if ((status = __ntapi->zw_request_wait_reply_port(pty->hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ iosb->info = msg.data.ctlinfo.iosb.info;
+ iosb->status = msg.data.ctlinfo.iosb.status;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/section/ntapi_tt_get_section_name.c b/src/section/ntapi_tt_get_section_name.c
new file mode 100644
index 0000000..744bfe7
--- /dev/null
+++ b/src/section/ntapi_tt_get_section_name.c
@@ -0,0 +1,32 @@
+/********************************************************/
+/* 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/nt_memory.h>
+#include <ntapi/nt_section.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_get_section_name(
+ __in void * addr,
+ __out nt_mem_sec_name * buffer,
+ __in uint32_t buffer_size)
+{
+ size_t len;
+
+ /* init buffer */
+ buffer->section_name.strlen = 0;
+ buffer->section_name.maxlen = (uint16_t)(buffer_size - sizeof(nt_unicode_string));
+ buffer->section_name.buffer = buffer->section_name_buffer;
+
+ return __ntapi->zw_query_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ addr,
+ NT_MEMORY_SECTION_NAME,
+ buffer,
+ buffer_size,
+ &len);
+}
diff --git a/src/socket/ntapi_sc_accept.c b/src/socket/ntapi_sc_accept.c
new file mode 100644
index 0000000..a9f0a4e
--- /dev/null
+++ b/src/socket/ntapi_sc_accept.c
@@ -0,0 +1,79 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct __addr_memcpy {
+ uint64_t d0;
+ uint64_t d1;
+} _addr_memcpy;
+
+
+int32_t __cdecl __ntapi_sc_accept(
+ __in nt_socket * hssock_listen,
+ __out nt_sockaddr * addr,
+ __out uint16_t * addrlen,
+ __out nt_socket * hssock_dedicated,
+ __in uintptr_t afdflags __optional,
+ __in uintptr_t tdiflags __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ int32_t status;
+
+ nt_afd_accept_info accept_info;
+ nt_io_status_block siosb;
+
+ _addr_memcpy * src;
+ _addr_memcpy * dst;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* establish kernel connection */
+ if ((status = __ntapi->sc_server_accept_connection(
+ hssock_listen,
+ &accept_info,
+ iosb)))
+ return status;
+
+ /* create connection-dedicated socket handle */
+ if ((status = __ntapi->sc_socket(
+ hssock_dedicated,
+ hssock_listen->domain,
+ hssock_listen->type,
+ hssock_listen->protocol,
+ 0,
+ 0,
+ 0)))
+ return status;
+
+ /* associate the dedicated handle with the connection */
+ if ((status = __ntapi->sc_server_duplicate_socket(
+ hssock_listen,
+ hssock_dedicated,
+ &accept_info,
+ 0)))
+ return status;
+
+ /* return address information */
+ if (addr) {
+ src = (_addr_memcpy *)&(accept_info.addr);
+ dst = (_addr_memcpy *)addr;
+
+ dst->d0 = src->d0;
+ dst->d1 = src->d1;
+ }
+
+ /* return address length information */
+ if (addrlen)
+ *addrlen = sizeof(nt_sockaddr);
+
+ return status;
+}
diff --git a/src/socket/ntapi_sc_bind_v1.c b/src/socket/ntapi_sc_bind_v1.c
new file mode 100644
index 0000000..df66656
--- /dev/null
+++ b/src/socket/ntapi_sc_bind_v1.c
@@ -0,0 +1,101 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_afd_bind_msg {
+ uint32_t domain;
+ uint32_t type;
+ uint32_t service_flags;
+ char sa_data[14];
+} nt_afd_bind_msg;
+
+
+typedef struct __addr_memcpy {
+ uint16_t d0;
+ uint16_t d1;
+ uint16_t d2;
+ uint16_t d3;
+ uint16_t d4;
+ uint16_t d5;
+ uint16_t d6;
+ uint16_t d7;
+} _addr_memcpy;
+
+
+int32_t __cdecl __ntapi_sc_bind_v1(
+ __in nt_socket * hssocket,
+ __in const nt_sockaddr * addr,
+ __in uintptr_t addrlen,
+ __in uintptr_t service_flags __optional,
+ __out nt_sockaddr * sockaddr __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_io_status_block siosb;
+ nt_afd_bind_msg afd_bind_req;
+ nt_afd_bind_msg afd_bind_rep;
+
+ _addr_memcpy * src;
+ _addr_memcpy * dst;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* service_flags */
+ if (!service_flags)
+ service_flags = 0x2000E;
+
+ /* afd_bind_req */
+ afd_bind_req.domain = hssocket->domain;
+ afd_bind_req.type = hssocket->type;
+ afd_bind_req.service_flags = (uint32_t)service_flags;
+
+ src = (_addr_memcpy *)addr;
+ dst = (_addr_memcpy *)&(afd_bind_req.sa_data);
+
+ dst->d0 = src->d1;
+ dst->d1 = src->d2;
+ dst->d2 = src->d3;
+ dst->d3 = src->d4;
+ dst->d4 = src->d5;
+ dst->d5 = src->d6;
+ dst->d6 = src->d7;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_BIND,
+ &afd_bind_req,
+ sizeof(afd_bind_req),
+ &afd_bind_rep,
+ sizeof(afd_bind_rep));
+
+ __ntapi->sc_wait(hssocket,iosb,0);
+
+ if (!hssocket->iostatus && sockaddr) {
+ src = (_addr_memcpy *)&(afd_bind_rep.sa_data);
+ dst = (_addr_memcpy *)sockaddr;
+
+ dst->d1 = src->d0;
+ dst->d2 = src->d1;
+ dst->d3 = src->d2;
+ dst->d4 = src->d3;
+ dst->d5 = src->d4;
+ dst->d6 = src->d5;
+ dst->d7 = src->d6;
+
+ sockaddr->sa_addr_in4.sa_family = hssocket->domain;
+ }
+
+ return hssocket->iostatus;
+}
diff --git a/src/socket/ntapi_sc_bind_v2.c b/src/socket/ntapi_sc_bind_v2.c
new file mode 100644
index 0000000..f9b503b
--- /dev/null
+++ b/src/socket/ntapi_sc_bind_v2.c
@@ -0,0 +1,85 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_afd_bind_request {
+ uint32_t unknown;
+ nt_sockaddr addr;
+} nt_afd_bind_request;
+
+typedef struct _nt_afd_bind_reply {
+ nt_sockaddr addr;
+} nt_afd_bind_reply;
+
+typedef struct __addr_memcpy {
+ uint32_t d0;
+ uint32_t d1;
+ uint32_t d2;
+ uint32_t d3;
+} _addr_memcpy;
+
+
+int32_t __cdecl __ntapi_sc_bind_v2(
+ __in nt_socket * hssocket,
+ __in const nt_sockaddr * addr,
+ __in uintptr_t addrlen,
+ __in uintptr_t service_flags __optional,
+ __out nt_sockaddr * sockaddr __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_io_status_block siosb;
+ nt_afd_bind_request afd_bind_req;
+ nt_afd_bind_reply afd_bind_rep;
+
+ _addr_memcpy * src;
+ _addr_memcpy * dst;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* request */
+ afd_bind_req.unknown = hssocket->domain;
+
+ src = (_addr_memcpy *)addr;
+ dst = (_addr_memcpy *)&(afd_bind_req.addr);
+
+ dst->d0 = src->d0;
+ dst->d1 = src->d1;
+ dst->d2 = src->d2;
+ dst->d3 = src->d3;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_BIND,
+ &afd_bind_req,
+ sizeof(afd_bind_req),
+ &afd_bind_rep,
+ sizeof(afd_bind_rep));
+
+ __ntapi->sc_wait(hssocket,iosb,0);
+
+ if (!hssocket->iostatus && sockaddr) {
+ /* return updated address information */
+ src = (_addr_memcpy *)&(afd_bind_rep);
+ dst = (_addr_memcpy *)sockaddr;
+
+ dst->d0 = src->d0;
+ dst->d1 = src->d1;
+ dst->d2 = src->d2;
+ dst->d3 = src->d3;
+ }
+
+ return hssocket->iostatus;
+}
diff --git a/src/socket/ntapi_sc_connect_v1.c b/src/socket/ntapi_sc_connect_v1.c
new file mode 100644
index 0000000..380dbc9
--- /dev/null
+++ b/src/socket/ntapi_sc_connect_v1.c
@@ -0,0 +1,93 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+/* weed in Redmond during the 1990's anyone? */
+typedef struct _nt_afd_connect_request {
+ uintptr_t unknown;
+ void * paddr;
+ void * hasync;
+ uint32_t type;
+ uint32_t service_flags;
+ char sa_data[14];
+ uint16_t hangover;
+ uint32_t unused;
+} nt_afd_connect_request;
+
+typedef struct __addr_memcpy {
+ uint16_t d0;
+ uint16_t d1;
+ uint16_t d2;
+ uint16_t d3;
+ uint16_t d4;
+ uint16_t d5;
+ uint16_t d6;
+ uint16_t d7;
+} _addr_memcpy;
+
+int32_t __cdecl __ntapi_sc_connect_v1(
+ __in nt_socket * hssocket,
+ __in nt_sockaddr * addr,
+ __in uintptr_t addrlen,
+ __in uintptr_t service_flags __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_io_status_block siosb;
+ nt_afd_connect_request afd_connect_req;
+
+ _addr_memcpy * src;
+ _addr_memcpy * dst;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* service_flags */
+ if (!service_flags)
+ service_flags = 0x2000E;
+
+ /* afd_connect_req */
+ afd_connect_req.type = hssocket->type;
+ afd_connect_req.service_flags = (uint32_t)service_flags;
+
+ afd_connect_req.paddr = (void *)0;
+ afd_connect_req.hasync = (void *)0;
+
+ afd_connect_req.unknown = 0;
+ afd_connect_req.unused = 0;
+ afd_connect_req.hangover = 0;
+
+ src = (_addr_memcpy *)addr;
+ dst = (_addr_memcpy *)&(afd_connect_req.sa_data);
+
+ dst->d0 = src->d1;
+ dst->d1 = src->d2;
+ dst->d2 = src->d3;
+ dst->d3 = src->d4;
+ dst->d4 = src->d5;
+ dst->d5 = src->d6;
+ dst->d6 = src->d7;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_CONNECT,
+ &afd_connect_req,
+ sizeof(afd_connect_req),
+ (void *)0,
+ 0);
+
+ return hssocket->iostatus
+ ? __ntapi->sc_wait(hssocket,iosb,0)
+ : NT_STATUS_SUCCESS;
+}
diff --git a/src/socket/ntapi_sc_connect_v2.c b/src/socket/ntapi_sc_connect_v2.c
new file mode 100644
index 0000000..3857f6f
--- /dev/null
+++ b/src/socket/ntapi_sc_connect_v2.c
@@ -0,0 +1,69 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_afd_connect_request {
+ uintptr_t unknown[2];
+ void * paddr;
+ nt_sockaddr addr;
+} nt_afd_connect_request;
+
+typedef struct __addr_memcpy {
+ uint64_t d0;
+ uint64_t d1;
+} _addr_memcpy;
+
+
+int32_t __cdecl __ntapi_sc_connect_v2(
+ __in nt_socket * hssocket,
+ __in nt_sockaddr * addr,
+ __in uintptr_t addrlen,
+ __in uintptr_t service_flags __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_io_status_block siosb;
+ nt_afd_connect_request afd_connect_req;
+
+ _addr_memcpy * src;
+ _addr_memcpy * dst;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* afd_connect_req */
+ afd_connect_req.unknown[0] = 0;
+ afd_connect_req.unknown[1] = 0;
+
+ src = (_addr_memcpy *)addr;
+ dst = (_addr_memcpy *)&(afd_connect_req.addr);
+
+ dst->d0 = src->d0;
+ dst->d1 = src->d1;
+
+ afd_connect_req.paddr = &(afd_connect_req.addr);
+ afd_connect_req.addr.sa_addr_in4.sa_family = hssocket->domain;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_CONNECT,
+ &afd_connect_req,
+ sizeof(afd_connect_req),
+ (void *)0,
+ 0);
+
+ return hssocket->iostatus
+ ? __ntapi->sc_wait(hssocket,iosb,0)
+ : NT_STATUS_SUCCESS;
+}
diff --git a/src/socket/ntapi_sc_getsockname_v1.c b/src/socket/ntapi_sc_getsockname_v1.c
new file mode 100644
index 0000000..85a9357
--- /dev/null
+++ b/src/socket/ntapi_sc_getsockname_v1.c
@@ -0,0 +1,80 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_afd_server_socket_name_info {
+ uint32_t unknown;
+ uint32_t type;
+ uint32_t service_flags;
+ char sa_data[14];
+} nt_afd_server_socket_name_info;
+
+
+struct __addr_memcpy {
+ uint16_t d0;
+ uint16_t d1;
+ uint16_t d2;
+ uint16_t d3;
+ uint16_t d4;
+ uint16_t d5;
+ uint16_t d6;
+ uint16_t d7;
+};
+
+
+int32_t __cdecl __ntapi_sc_getsockname_v1(
+ __in nt_socket * hssocket,
+ __in nt_sockaddr * addr,
+ __in uint16_t * addrlen,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_io_status_block siosb;
+ nt_afd_server_socket_name_info sock_name_info;
+
+ struct __addr_memcpy * asrc;
+ struct __addr_memcpy * adst;
+
+ iosb = iosb ? iosb : &siosb;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_GET_SOCK_NAME,
+ 0,
+ 0,
+ &sock_name_info,
+ sizeof(sock_name_info));
+
+ __ntapi->sc_wait(hssocket,iosb,0);
+
+ if (!hssocket->iostatus) {
+ addr->sa_addr_in4.sa_family = hssocket->domain;
+
+ asrc = (struct __addr_memcpy *)&(sock_name_info.sa_data);
+ adst = (struct __addr_memcpy *)addr;
+
+ adst->d1 = asrc->d0;
+ adst->d2 = asrc->d1;
+ adst->d3 = asrc->d2;
+ adst->d4 = asrc->d3;
+ adst->d5 = asrc->d4;
+ adst->d6 = asrc->d5;
+ adst->d7 = asrc->d6;
+
+ *addrlen = (uint16_t)iosb->info;
+ };
+
+ return hssocket->iostatus;
+}
diff --git a/src/socket/ntapi_sc_getsockname_v2.c b/src/socket/ntapi_sc_getsockname_v2.c
new file mode 100644
index 0000000..07313ac
--- /dev/null
+++ b/src/socket/ntapi_sc_getsockname_v2.c
@@ -0,0 +1,42 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __cdecl __ntapi_sc_getsockname_v2(
+ __in nt_socket * hssocket,
+ __in nt_sockaddr * addr,
+ __in uint16_t * addrlen,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_iosb siosb;
+
+ iosb = iosb ? iosb : &siosb;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_GET_SOCK_NAME,
+ 0,
+ 0,
+ addr,
+ sizeof(*addr));
+
+ __ntapi->sc_wait(hssocket,iosb,0);
+
+ if (!hssocket->iostatus)
+ *addrlen = (uint16_t)iosb->info;
+
+ return hssocket->iostatus;
+}
diff --git a/src/socket/ntapi_sc_listen.c b/src/socket/ntapi_sc_listen.c
new file mode 100644
index 0000000..cc3e66a
--- /dev/null
+++ b/src/socket/ntapi_sc_listen.c
@@ -0,0 +1,44 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __cdecl __ntapi_sc_listen(
+ __in nt_socket * hssocket,
+ __in uintptr_t backlog,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_afd_listen_info afd_listen;
+ nt_io_status_block siosb;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* afd_listen */
+ afd_listen.unknown_1st = 0;
+ afd_listen.unknown_2nd = 0;
+ afd_listen.backlog = (uint32_t)backlog;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_LISTEN,
+ &afd_listen,
+ sizeof(afd_listen),
+ 0,
+ 0);
+
+ return hssocket->iostatus
+ ? __ntapi->sc_wait(hssocket,iosb,0)
+ : NT_STATUS_SUCCESS;
+}
diff --git a/src/socket/ntapi_sc_recv.c b/src/socket/ntapi_sc_recv.c
new file mode 100644
index 0000000..8db3426
--- /dev/null
+++ b/src/socket/ntapi_sc_recv.c
@@ -0,0 +1,63 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __cdecl __ntapi_sc_recv(
+ __in nt_socket * hssocket,
+ __in const void * buffer,
+ __in size_t len,
+ __out ssize_t * bytes_received __optional,
+ __in uintptr_t afdflags __optional,
+ __in uintptr_t tdiflags __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_afd_buffer afd_buffer;
+ nt_afd_recv_info afd_recv;
+ nt_io_status_block siosb;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* tdiflags */
+ if (tdiflags == 0)
+ tdiflags = NT_TDI_RECEIVE_NORMAL;
+
+ /* afd_buffer */
+ afd_buffer.length = len;
+ afd_buffer.buffer = (char *)buffer;
+
+ /* afd_recv */
+ afd_recv.afd_buffer_array = &afd_buffer;
+ afd_recv.buffer_count = 1;
+
+ afd_recv.afd_flags = (uint32_t)afdflags;
+ afd_recv.tdi_flags = (uint32_t)tdiflags;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_RECV,
+ &afd_recv,
+ sizeof(afd_recv),
+ 0,
+ 0);
+
+ if (hssocket->iostatus && (hssocket->ntflags & __NT_FILE_SYNC_IO))
+ __ntapi->sc_wait(hssocket,iosb,&hssocket->timeout);
+
+ if (!hssocket->iostatus && bytes_received)
+ *bytes_received = iosb->info;
+
+ return hssocket->iostatus;
+}
diff --git a/src/socket/ntapi_sc_send.c b/src/socket/ntapi_sc_send.c
new file mode 100644
index 0000000..2286d65
--- /dev/null
+++ b/src/socket/ntapi_sc_send.c
@@ -0,0 +1,59 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __cdecl __ntapi_sc_send(
+ __in nt_socket * hssocket,
+ __in const void * buffer,
+ __in size_t len,
+ __out ssize_t * bytes_sent __optional,
+ __in uintptr_t afdflags __optional,
+ __in uintptr_t tdiflags __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_afd_buffer afd_buffer;
+ nt_afd_send_info afd_send;
+ nt_io_status_block siosb;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* afd_buffer */
+ afd_buffer.length = len;
+ afd_buffer.buffer = (char *)buffer;
+
+ /* afd_send */
+ afd_send.afd_buffer_array = &afd_buffer;
+ afd_send.buffer_count = 1;
+
+ afd_send.afd_flags = (uint32_t)afdflags;
+ afd_send.tdi_flags = (uint32_t)tdiflags;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_SEND,
+ &afd_send,
+ sizeof(afd_send),
+ 0,
+ 0);
+
+ if (hssocket->iostatus && (hssocket->ntflags & __NT_FILE_SYNC_IO))
+ __ntapi->sc_wait(hssocket,iosb,&hssocket->timeout);
+
+ if (!hssocket->iostatus && bytes_sent)
+ *bytes_sent = iosb->info;
+
+ return hssocket->iostatus;
+}
diff --git a/src/socket/ntapi_sc_server_accept_connection_v1.c b/src/socket/ntapi_sc_server_accept_connection_v1.c
new file mode 100644
index 0000000..0154ef7
--- /dev/null
+++ b/src/socket/ntapi_sc_server_accept_connection_v1.c
@@ -0,0 +1,78 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_afd_server_accept_info {
+ uint32_t sequence;
+ uint32_t unknown;
+ uint32_t service_flags;
+ char sa_data[14];
+} nt_afd_server_accept_info;
+
+typedef struct __addr_memcpy {
+ uint16_t d0;
+ uint16_t d1;
+ uint16_t d2;
+ uint16_t d3;
+ uint16_t d4;
+ uint16_t d5;
+ uint16_t d6;
+ uint16_t d7;
+} _addr_memcpy;
+
+int32_t __cdecl __ntapi_sc_server_accept_connection_v1(
+ __in nt_socket * hssocket,
+ __out nt_afd_accept_info * accept_info,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_io_status_block siosb;
+ nt_afd_server_accept_info accept_info_buffer;
+
+ _addr_memcpy * asrc;
+ _addr_memcpy * adst;
+
+ iosb = iosb ? iosb : &siosb;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_ACCEPT,
+ 0,
+ 0,
+ &accept_info_buffer,
+ sizeof(accept_info_buffer));
+
+ if (hssocket->iostatus && (hssocket->ntflags & __NT_FILE_SYNC_IO))
+ __ntapi->sc_wait(hssocket,iosb,&hssocket->timeout);
+
+ if (hssocket->iostatus)
+ return hssocket->iostatus;
+
+ accept_info->sequence = accept_info_buffer.sequence;
+ accept_info->addr.sa_addr_in4.sa_family = hssocket->domain;
+
+ asrc = (_addr_memcpy *)&(accept_info_buffer.sa_data);
+ adst = (_addr_memcpy *)&(accept_info->addr);
+
+ adst->d1 = asrc->d0;
+ adst->d2 = asrc->d1;
+ adst->d3 = asrc->d2;
+ adst->d4 = asrc->d3;
+ adst->d5 = asrc->d4;
+ adst->d6 = asrc->d5;
+ adst->d7 = asrc->d6;
+
+ return hssocket->iostatus;
+}
diff --git a/src/socket/ntapi_sc_server_accept_connection_v2.c b/src/socket/ntapi_sc_server_accept_connection_v2.c
new file mode 100644
index 0000000..3520c75
--- /dev/null
+++ b/src/socket/ntapi_sc_server_accept_connection_v2.c
@@ -0,0 +1,44 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_afd_server_accept_info {
+ uint32_t sequence;
+ nt_sockaddr addr;
+} nt_afd_server_accept_info;
+
+int32_t __cdecl __ntapi_sc_server_accept_connection_v2(
+ __in nt_socket * hssocket,
+ __out nt_afd_accept_info * accept_info,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_io_status_block siosb;
+
+ iosb = iosb ? iosb : &siosb;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_ACCEPT,
+ 0,
+ 0,
+ accept_info,
+ sizeof(nt_afd_server_accept_info));
+
+ if (hssocket->iostatus && (hssocket->ntflags & __NT_FILE_SYNC_IO))
+ __ntapi->sc_wait(hssocket,iosb,&hssocket->timeout);
+
+ return hssocket->iostatus;
+}
diff --git a/src/socket/ntapi_sc_server_duplicate_socket.c b/src/socket/ntapi_sc_server_duplicate_socket.c
new file mode 100644
index 0000000..4084593
--- /dev/null
+++ b/src/socket/ntapi_sc_server_duplicate_socket.c
@@ -0,0 +1,45 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __cdecl __ntapi_sc_server_duplicate_socket(
+ __in nt_socket * hssock_listen,
+ __in nt_socket * hssock_dedicated,
+ __in nt_afd_accept_info * accept_info,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_afd_duplicate_info duplicate_info;
+ nt_io_status_block siosb;
+
+ iosb = iosb ? iosb : &siosb;
+
+ /* duplicate_info */
+ duplicate_info.unknown = 0;
+ duplicate_info.sequence = accept_info->sequence;
+ duplicate_info.hsocket_dedicated = hssock_dedicated->hsocket;
+
+ hssock_dedicated->iostatus = __ntapi->zw_device_io_control_file(
+ hssock_listen->hsocket,
+ hssock_dedicated->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_DUPLICATE,
+ &duplicate_info,
+ sizeof(duplicate_info),
+ 0,
+ 0);
+
+ return hssock_dedicated->iostatus
+ ? __ntapi->sc_wait(hssock_dedicated,iosb,0)
+ : NT_STATUS_SUCCESS;
+}
diff --git a/src/socket/ntapi_sc_shutdown.c b/src/socket/ntapi_sc_shutdown.c
new file mode 100644
index 0000000..115214c
--- /dev/null
+++ b/src/socket/ntapi_sc_shutdown.c
@@ -0,0 +1,65 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __cdecl __ntapi_sc_shutdown(
+ __in nt_socket * hssocket,
+ __in uintptr_t psxhow,
+ __in uintptr_t afdhow,
+ __out nt_io_status_block * iosb __optional)
+{
+ nt_afd_disconnect_info afd_disconnect;
+ nt_io_status_block siosb;
+
+ iosb = iosb ? iosb : &siosb;
+
+ if (afdhow == 0) {
+ switch (psxhow) {
+ case NT_SHUT_RD:
+ afdhow = NT_AFD_DISCONNECT_RD;
+ break;
+
+ case NT_SHUT_WR:
+ afdhow = NT_AFD_DISCONNECT_WR;
+ break;
+
+ case NT_SHUT_RDWR:
+ afdhow = NT_AFD_DISCONNECT_RD | NT_AFD_DISCONNECT_WR;
+ break;
+
+ default:
+ return NT_STATUS_INVALID_PARAMETER_2;
+ break;
+ }
+ }
+
+ afd_disconnect.shutdown_flags = (uint32_t)afdhow;
+ afd_disconnect.unknown[0] = 0xff;
+ afd_disconnect.unknown[1] = 0xff;
+ afd_disconnect.unknown[2] = 0xff;
+
+ hssocket->iostatus = __ntapi->zw_device_io_control_file(
+ hssocket->hsocket,
+ hssocket->hevent,
+ 0,
+ 0,
+ iosb,
+ NT_AFD_IOCTL_DISCONNECT,
+ &afd_disconnect,
+ sizeof(afd_disconnect),
+ 0,
+ 0);
+
+ return hssocket->iostatus
+ ? __ntapi->sc_wait(hssocket,iosb,0)
+ : NT_STATUS_SUCCESS;
+}
diff --git a/src/socket/ntapi_sc_socket_v1.c b/src/socket/ntapi_sc_socket_v1.c
new file mode 100644
index 0000000..d57f212
--- /dev/null
+++ b/src/socket/ntapi_sc_socket_v1.c
@@ -0,0 +1,118 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_afd_socket_ea {
+ uint32_t next_entry_offset;
+ unsigned char ea_flags;
+ unsigned char ea_name_length;
+ uint16_t ea_value_length;
+ char afd_open_packet[0x10];
+ uint32_t value_1st;
+ uint32_t value_2nd;
+ uint32_t device_name_length;
+ wchar16_t device_name[0x0b];
+ uint32_t ea_ext[4];
+} nt_afd_socket_ea;
+
+int32_t __cdecl __ntapi_sc_socket_v1(
+ __out nt_socket * hssocket,
+ __in uint16_t domain,
+ __in uint16_t type,
+ __in uint32_t protocol,
+ __in uint32_t desired_access __optional,
+ __in nt_sqos * sqos __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ int32_t status;
+ nt_object_attributes oa;
+ nt_io_status_block siosb;
+ nt_sqos ssqos;
+ nt_unicode_string nt_afdep;
+ uint32_t ea_length;
+ void * _hsocket;
+
+ wchar16_t afd_end_point[] = {
+ '\\','D','e','v','i','c','e',
+ '\\','A','f','d',
+ '\\','E','n','d','P','o','i','n','t',
+ 0};
+
+ /* tcp as default extended attribute */
+ nt_afd_socket_ea afd_ea = {
+ 0,
+ 0,
+ 0x0f,
+ 0x28,
+ {'A','f','d','O','p','e','n','P','a','c','k','e','t','X','X',0},
+ 0,0,
+ 0x16,
+ {'\\','D','e','v','i','c','e','\\','T','c','p'},
+ {0}};
+
+ ea_length = 0x43;
+
+ __ntapi->rtl_init_unicode_string(&nt_afdep,afd_end_point);
+
+ if (!desired_access)
+ desired_access = NT_GENERIC_READ \
+ | NT_GENERIC_WRITE \
+ | NT_SEC_SYNCHRONIZE \
+ | NT_SEC_WRITE_DAC;
+
+ if (!sqos) {
+ ssqos.length = sizeof(ssqos);
+ ssqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ ssqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ ssqos.effective_only = 1;
+ sqos = &ssqos;
+ }
+
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &nt_afdep;
+ oa.obj_attr = NT_OBJ_CASE_INSENSITIVE | NT_OBJ_INHERIT;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = sqos;
+
+ iosb = iosb ? iosb : &siosb;
+
+ if ((status = __ntapi->zw_create_file(
+ &_hsocket,
+ desired_access,
+ &oa,
+ iosb,
+ 0,
+ 0,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_OPEN_IF,
+ 0,
+ &afd_ea,
+ ea_length)))
+ return status;
+
+ oa.obj_name = 0;
+ oa.obj_attr = 0;
+
+ if (status == NT_STATUS_SUCCESS) {
+ hssocket->hsocket = _hsocket;
+ hssocket->ntflags = 0;
+ hssocket->domain = domain;
+ hssocket->type = type;
+ hssocket->protocol = protocol;
+ hssocket->timeout.quad = 0;
+ hssocket->iostatus = NT_STATUS_SUCCESS;
+ hssocket->waitstatus = NT_STATUS_SUCCESS;
+ }
+
+ return status;
+}
diff --git a/src/socket/ntapi_sc_socket_v2.c b/src/socket/ntapi_sc_socket_v2.c
new file mode 100644
index 0000000..069c596
--- /dev/null
+++ b/src/socket/ntapi_sc_socket_v2.c
@@ -0,0 +1,124 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_file.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+typedef struct _nt_socket_attr {
+ uint32_t datagram;
+ uint32_t unknown;
+ uint32_t domain;
+ uint32_t type;
+ uint32_t protocol;
+} nt_socket_attr;
+
+typedef struct _nt_afd_socket_ea {
+ uint32_t next_entry_offset;
+ unsigned char ea_flags;
+ unsigned char ea_name_length;
+ uint16_t ea_value_length;
+ char afd_open_packet[16];
+ nt_socket_attr sattr;
+ uint32_t ea_ext[4];
+} nt_afd_socket_ea;
+
+int32_t __cdecl __ntapi_sc_socket_v2(
+ __out nt_socket * hssocket,
+ __in uint16_t domain,
+ __in uint16_t type,
+ __in uint32_t protocol,
+ __in uint32_t desired_access __optional,
+ __in nt_sqos * sqos __optional,
+ __out nt_io_status_block * iosb __optional)
+{
+ int32_t status;
+ nt_object_attributes oa;
+ nt_io_status_block siosb;
+ nt_sqos ssqos;
+ nt_unicode_string nt_afdep;
+ uint32_t ea_length;
+ void * _hsocket;
+
+ wchar16_t afd_end_point[] = {
+ '\\','D','e','v','i','c','e',
+ '\\','A','f','d',
+ '\\','E','n','d','P','o','i','n','t',
+ 0};
+
+ nt_afd_socket_ea afd_ea = {
+ 0,
+ 0,
+ 0x0f,
+ 0x20,
+ {'A','f','d','O','p','e','n','P','a','c','k','e','t','X','X',0},
+ {0},
+ {0}};
+
+ ea_length = sizeof(afd_ea);
+
+ afd_ea.sattr.domain = domain;
+ afd_ea.sattr.type = type;
+ afd_ea.sattr.protocol = protocol;
+
+ afd_ea.sattr.datagram = (type == NT_SOCK_DGRAM) ? protocol : 0;
+
+ __ntapi->rtl_init_unicode_string(&nt_afdep,afd_end_point);
+
+ if (!desired_access)
+ desired_access = NT_GENERIC_READ \
+ | NT_GENERIC_WRITE \
+ | NT_SEC_SYNCHRONIZE \
+ | NT_SEC_WRITE_DAC;
+
+ if (!sqos) {
+ ssqos.length = sizeof(ssqos);
+ ssqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ ssqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ ssqos.effective_only = 1;
+ sqos = &ssqos;
+ }
+
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &nt_afdep;
+ oa.obj_attr = NT_OBJ_CASE_INSENSITIVE | NT_OBJ_INHERIT;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = sqos;
+
+ iosb = iosb ? iosb : &siosb;
+
+ if ((status = __ntapi->zw_create_file(
+ &_hsocket,
+ desired_access,
+ &oa,
+ iosb,
+ 0,
+ 0,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_OPEN_IF,
+ 0,
+ &afd_ea,
+ ea_length)))
+ return status;
+
+ oa.obj_name = 0;
+ oa.obj_attr = 0;
+
+ hssocket->hsocket = _hsocket;
+ hssocket->ntflags = 0;
+ hssocket->domain = domain;
+ hssocket->type = type;
+ hssocket->protocol = protocol;
+ hssocket->timeout.quad = 0;
+ hssocket->iostatus = NT_STATUS_SUCCESS;
+ hssocket->waitstatus = NT_STATUS_SUCCESS;
+
+ return status;
+}
diff --git a/src/socket/ntapi_sc_wait.c b/src/socket/ntapi_sc_wait.c
new file mode 100644
index 0000000..3bfad28
--- /dev/null
+++ b/src/socket/ntapi_sc_wait.c
@@ -0,0 +1,42 @@
+/********************************************************/
+/* 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/nt_sync.h>
+#include <ntapi/nt_socket.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __cdecl __ntapi_sc_wait(nt_socket * hssocket, nt_iosb * iosb, nt_timeout * timeout)
+{
+ nt_iosb cancel;
+
+ timeout = (timeout && timeout->quad)
+ ? timeout
+ : 0;
+
+ if (hssocket->hevent && (hssocket->iostatus == NT_STATUS_PENDING)) {
+ hssocket->waitstatus = __ntapi->zw_wait_for_single_object(
+ hssocket->hevent,
+ !!(hssocket->ntflags & NT_FILE_SYNCHRONOUS_IO_ALERT),
+ timeout);
+
+ switch (hssocket->waitstatus) {
+ case NT_STATUS_SUCCESS:
+ hssocket->iostatus = NT_STATUS_SUCCESS;
+ break;
+
+ case NT_STATUS_ALERTED:
+ hssocket->iostatus = NT_STATUS_ALERTED;
+ __ntapi->zw_cancel_io_file(
+ hssocket->hsocket,
+ &cancel);
+ break;
+ }
+ }
+
+ return hssocket->iostatus;
+}
diff --git a/src/string/ntapi_tt_aligned_block_memcpy.c b/src/string/ntapi_tt_aligned_block_memcpy.c
new file mode 100644
index 0000000..43e1a49
--- /dev/null
+++ b/src/string/ntapi_tt_aligned_block_memcpy.c
@@ -0,0 +1,50 @@
+/********************************************************/
+/* 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/nt_string.h>
+
+uintptr_t * __cdecl __ntapi_tt_aligned_block_memcpy(
+ __in uintptr_t * dst,
+ __in uintptr_t * src,
+ __in size_t bytes)
+{
+ uintptr_t * ptr = (uintptr_t *)dst;
+
+ for (bytes/=sizeof(uintptr_t); bytes; bytes--)
+ *dst++ = *src++;
+
+ return ptr;
+}
+
+
+void * __cdecl __ntapi_tt_generic_memcpy(
+ __in void * dst,
+ __in const void * src,
+ __in size_t bytes)
+{
+ char * ch_dst;
+ const char * ch_src;
+
+ if (!bytes)
+ return dst;
+
+ else if (!(bytes % sizeof(size_t))
+ && (!(uintptr_t)dst % sizeof(size_t))
+ && (!(uintptr_t)src % sizeof(size_t)))
+ return __ntapi_tt_aligned_block_memcpy(
+ (uintptr_t *)dst,
+ (uintptr_t *)src,
+ bytes);
+
+ ch_dst = (char *)dst;
+ ch_src = (const char *)src;
+
+ for (; bytes; bytes--)
+ *ch_dst++ = *ch_src++;
+
+ return dst;
+}
diff --git a/src/string/ntapi_tt_aligned_block_memset.c b/src/string/ntapi_tt_aligned_block_memset.c
new file mode 100644
index 0000000..8e64360
--- /dev/null
+++ b/src/string/ntapi_tt_aligned_block_memset.c
@@ -0,0 +1,57 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+
+void * __cdecl __ntapi_tt_aligned_block_memset(
+ __in void * block,
+ __in uintptr_t val,
+ __in size_t bytes)
+{
+ uintptr_t * ptr = (uintptr_t *)block;
+
+ for (bytes/=sizeof(uintptr_t); bytes; bytes--)
+ *ptr++=val;
+
+ return block;
+}
+
+void * __cdecl __ntapi_tt_generic_memset(
+ __in void * dst,
+ __in uintptr_t val,
+ __in size_t bytes)
+{
+ char c;
+ char * ch;
+ int i;
+ size_t abytes;
+
+ if (!bytes)
+ return dst;
+
+ else if (!(bytes % sizeof(size_t))
+ && (!(uintptr_t)dst % sizeof(size_t)))
+ return __ntapi_tt_aligned_block_memset(
+ dst,val,bytes);
+
+ c = (char)val;
+ for (i=0; i<sizeof(size_t); i++, val <<= 8)
+ val += c;
+
+ for (ch=(char *)dst; (size_t)ch % sizeof(size_t); ch++, bytes--)
+ *ch = c;
+
+ abytes = bytes / sizeof(size_t) * sizeof(size_t);
+ __ntapi_tt_aligned_block_memset(ch,val,abytes);
+
+ bytes -= abytes;
+ ch += abytes;
+
+ for (; bytes; ch++, bytes--)
+ *ch = c;
+
+ return dst;
+}
diff --git a/src/string/ntapi_tt_aligned_memcpy_utf16.c b/src/string/ntapi_tt_aligned_memcpy_utf16.c
new file mode 100644
index 0000000..2035814
--- /dev/null
+++ b/src/string/ntapi_tt_aligned_memcpy_utf16.c
@@ -0,0 +1,70 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+
+wchar16_t * __cdecl __ntapi_tt_aligned_memcpy_utf16(
+ __in uintptr_t * dst,
+ __in uintptr_t * src,
+ __in size_t bytes)
+{
+ size_t aligned_block;
+ size_t copied;
+
+ wchar16_t * wch_src;
+ wchar16_t * wch_dst;
+
+ #if defined (__X86_64_MODEL)
+ uint32_t * uint32_src;
+ uint32_t * uint32_dst;
+ #endif
+
+ aligned_block = bytes;
+ aligned_block /= sizeof(uintptr_t);
+ aligned_block *= sizeof(uintptr_t);
+
+ copied = 0;
+
+ while (copied < aligned_block) {
+ *dst = *src;
+ src++;
+ dst++;
+ copied += sizeof(uintptr_t);
+ }
+
+ #if defined (__X86_64_MODEL)
+ switch (bytes % sizeof(uintptr_t)) {
+ case 6:
+ uint32_src = (uint32_t *)src;
+ uint32_dst = (uint32_t *)dst;
+ *uint32_dst = *uint32_src;
+
+ uint32_src++;
+ uint32_dst++;
+
+ /* make the compiler happy */
+ wch_src = (wchar16_t *)uint32_src;
+ wch_dst = (wchar16_t *)uint32_dst;
+ *wch_dst = *wch_src;
+ break;
+
+ case 4:
+ uint32_src = (uint32_t *)src;
+ uint32_dst = (uint32_t *)dst;
+ *uint32_dst = *uint32_src;
+ break;
+ }
+ #endif
+
+ if (bytes % sizeof(uintptr_t)) {
+ /* the remainder must be 2 */
+ wch_src = (wchar16_t *)src;
+ wch_dst = (wchar16_t *)dst;
+ *wch_dst = *wch_src;
+ }
+
+ return (wchar16_t *)dst;
+}
diff --git a/src/string/ntapi_tt_hex_utf16_to_uintptr.c b/src/string/ntapi_tt_hex_utf16_to_uintptr.c
new file mode 100644
index 0000000..3b1f354
--- /dev/null
+++ b/src/string/ntapi_tt_hex_utf16_to_uintptr.c
@@ -0,0 +1,124 @@
+/********************************************************/
+/* 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/nt_status.h>
+
+int32_t __fastcall __ntapi_tt_hex_utf16_to_uint32(
+ __in 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 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 wchar16_t hex_key_utf16[],
+ __out uintptr_t * key)
+{
+ #if defined (__NT32)
+ return __ntapi_tt_hex_utf16_to_uint32(hex_key_utf16,key);
+ #elif defined (__NT64)
+ return __ntapi_tt_hex_utf16_to_uint64(hex_key_utf16,key);
+ #endif
+}
+
+
+int32_t __fastcall __ntapi_tt_hex_utf16_to_uint16(
+ __in 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;
+}
diff --git a/src/string/ntapi_tt_init_unicode_string_from_utf16.c b/src/string/ntapi_tt_init_unicode_string_from_utf16.c
new file mode 100644
index 0000000..96673b4
--- /dev/null
+++ b/src/string/ntapi_tt_init_unicode_string_from_utf16.c
@@ -0,0 +1,26 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+void __ntapi_tt_init_unicode_string_from_utf16(
+ __out nt_unicode_string * str_dest,
+ __in wchar16_t * str_src)
+{
+ if ((intptr_t)str_src) {
+ str_dest->strlen = (uint16_t)__ntapi->tt_string_null_offset_short((const int16_t *)str_src);
+ str_dest->maxlen = str_dest->strlen + sizeof(uint16_t);
+ str_dest->buffer = (uint16_t *)str_src;
+ } else {
+ str_dest->strlen = 0;
+ str_dest->maxlen = 0;
+ str_dest->buffer = (uint16_t *)0;
+ }
+} \ No newline at end of file
diff --git a/src/string/ntapi_tt_memcpy_utf16.c b/src/string/ntapi_tt_memcpy_utf16.c
new file mode 100644
index 0000000..0a2b7af
--- /dev/null
+++ b/src/string/ntapi_tt_memcpy_utf16.c
@@ -0,0 +1,28 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+
+wchar16_t * __cdecl __ntapi_tt_memcpy_utf16(
+ __in wchar16_t * dst,
+ __in wchar16_t * src,
+ __in size_t bytes)
+{
+ wchar16_t * wch_cap;
+ wchar16_t * wch_ret;
+
+ wch_cap = (wchar16_t *)((uintptr_t)src + bytes);
+ wch_ret = dst;
+
+ while (src < wch_cap) {
+ *dst = *src;
+ src++;
+ dst++;
+ }
+
+ return wch_ret;
+}
diff --git a/src/string/ntapi_tt_string_null_offset.c b/src/string/ntapi_tt_string_null_offset.c
new file mode 100644
index 0000000..3565acb
--- /dev/null
+++ b/src/string/ntapi_tt_string_null_offset.c
@@ -0,0 +1,93 @@
+/********************************************************/
+/* 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/nt_string.h>
+#include "ntapi_impl.h"
+
+size_t __cdecl __ntapi_tt_string_null_offset_multibyte(
+ __in const char * str)
+{
+ const char * cap;
+ const uintptr_t * ptr;
+
+ #define HIGH_BIT_TEST (uintptr_t)0x0101010101010101
+ #define AND_BITS (uintptr_t)0x8080808080808080
+
+ cap = str;
+ while ((uintptr_t)cap % sizeof(uintptr_t)) {
+ if (!(*cap))
+ return cap - str;
+ cap++;
+ }
+
+ ptr = (uintptr_t *)cap;
+ while (!((*ptr - HIGH_BIT_TEST) & ~(*ptr) & AND_BITS))
+ ptr++;
+
+ cap = (const char *)ptr;
+ while (*cap)
+ cap++;
+
+ return cap - str;
+}
+
+
+size_t __cdecl __ntapi_tt_string_null_offset_short(
+ __in const int16_t * str)
+{
+ const int16_t * cap;
+
+ cap = str;
+ while (*cap)
+ cap++;
+
+ return (size_t)cap - (size_t)str;
+}
+
+
+size_t __cdecl __ntapi_tt_string_null_offset_dword(
+ __in const int32_t * str)
+{
+ const int32_t * cap;
+
+ cap = str;
+ while (*cap)
+ cap++;
+
+ return (size_t)cap - (size_t)str;
+}
+
+size_t __cdecl __ntapi_tt_string_null_offset_qword(
+ __in const int64_t * str)
+{
+ const int64_t * cap;
+
+ cap = str;
+ while (*cap)
+ cap++;
+
+ return (size_t)cap - (size_t)str;
+}
+
+size_t __cdecl __ntapi_tt_string_null_offset_ptrsize(
+ __in const intptr_t *str)
+{
+ const intptr_t * cap;
+
+ cap = str;
+ while (*cap)
+ cap++;
+
+ return (size_t)cap - (size_t)str;
+}
+
+size_t __cdecl __ntapi_wcslen(const wchar16_t * str)
+{
+ size_t len;
+ len = __ntapi_tt_string_null_offset_short((const int16_t *)str);
+ return len / 2;
+}
diff --git a/src/string/ntapi_tt_uintptr_to_hex_utf16.c b/src/string/ntapi_tt_uintptr_to_hex_utf16.c
new file mode 100644
index 0000000..59e063f
--- /dev/null
+++ b/src/string/ntapi_tt_uintptr_to_hex_utf16.c
@@ -0,0 +1,87 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+
+static void __fastcall __ntapi_tt_uint_to_hex_utf16(
+ __in uint64_t key,
+ __out wchar16_t * buffer,
+ __in unsigned bits)
+{
+ unsigned i;
+ uint32_t hex_buf[4];
+ unsigned char * hex_chars;
+ unsigned char * uch;
+ unsigned offset;
+ unsigned bytes;
+
+ hex_buf[0] = ('3' << 24) | ('2' << 16) | ('1' << 8) | '0';
+ hex_buf[1] = ('7' << 24) | ('6' << 16) | ('5' << 8) | '4';
+ hex_buf[2] = ('b' << 24) | ('a' << 16) | ('9' << 8) | '8';
+ hex_buf[3] = ('f' << 24) | ('e' << 16) | ('d' << 8) | 'c';
+
+ uch = (unsigned char *)&key;
+ hex_chars = (unsigned char *)&hex_buf;
+
+ bytes = bits / 8;
+ offset = bits / 4;
+
+ for (i = 0; i < bytes; i++) {
+ buffer[offset - 1 - (i*2)] = hex_chars[uch[i] % 16];
+ buffer[offset - 2 - (i*2)] = hex_chars[uch[i] / 16];
+ }
+}
+
+
+void __fastcall __ntapi_tt_uint16_to_hex_utf16(
+ __in uint32_t key,
+ __out wchar16_t * formatted_key)
+{
+ __ntapi_tt_uint_to_hex_utf16(
+ key,
+ formatted_key,
+ 16);
+}
+
+
+void __fastcall __ntapi_tt_uint32_to_hex_utf16(
+ __in uint32_t key,
+ __out wchar16_t * formatted_key)
+{
+ __ntapi_tt_uint_to_hex_utf16(
+ key,
+ formatted_key,
+ 32);
+}
+
+
+void __fastcall __ntapi_tt_uint64_to_hex_utf16(
+ __in uint64_t key,
+ __out wchar16_t * formatted_key)
+{
+ __ntapi_tt_uint_to_hex_utf16(
+ key,
+ formatted_key,
+ 64);
+}
+
+
+void __fastcall __ntapi_tt_uintptr_to_hex_utf16(
+ __in uintptr_t key,
+ __out wchar16_t * formatted_key)
+{
+ #if defined (__NT32)
+ __ntapi_tt_uint_to_hex_utf16(
+ key,
+ formatted_key,
+ 32);
+ #elif defined (__NT64)
+ __ntapi_tt_uint_to_hex_utf16(
+ key,
+ formatted_key,
+ 64);
+ #endif
+}
diff --git a/src/string/ntapi_tt_uintptr_to_hex_utf8.c b/src/string/ntapi_tt_uintptr_to_hex_utf8.c
new file mode 100644
index 0000000..b1e3141
--- /dev/null
+++ b/src/string/ntapi_tt_uintptr_to_hex_utf8.c
@@ -0,0 +1,73 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+
+static void __fastcall __ntapi_tt_uint_to_hex_utf8(
+ __in uint64_t key,
+ __out unsigned char * buffer,
+ __in unsigned bits)
+{
+ unsigned i;
+ uint32_t hex_buf[4];
+ unsigned char * hex_chars;
+ unsigned char * uch;
+ unsigned offset;
+ unsigned bytes;
+
+ /* avoid using .rdata for that one */
+ hex_buf[0] = ('3' << 24) | ('2' << 16) | ('1' << 8) | '0';
+ hex_buf[1] = ('7' << 24) | ('6' << 16) | ('5' << 8) | '4';
+ hex_buf[2] = ('B' << 24) | ('A' << 16) | ('9' << 8) | '8';
+ hex_buf[3] = ('F' << 24) | ('E' << 16) | ('D' << 8) | 'C';
+
+ uch = (unsigned char *)&key;
+ hex_chars = (unsigned char *)&hex_buf;
+
+ bytes = bits / 8;
+ offset = bits / 4;
+
+ for (i = 0; i < bytes; i++) {
+ buffer[offset - 1 - (i*2)] = hex_chars[uch[i] % 16];
+ buffer[offset - 2 - (i*2)] = hex_chars[uch[i] / 16];
+ }
+}
+
+
+void __fastcall __ntapi_tt_uint16_to_hex_utf8(
+ __in uint32_t key,
+ __out unsigned char * buffer)
+{
+ __ntapi_tt_uint_to_hex_utf8(key,buffer,16);
+}
+
+
+void __fastcall __ntapi_tt_uint32_to_hex_utf8(
+ __in uint32_t key,
+ __out unsigned char * buffer)
+{
+ __ntapi_tt_uint_to_hex_utf8(key,buffer,32);
+}
+
+
+void __fastcall __ntapi_tt_uint64_to_hex_utf8(
+ __in uint64_t key,
+ __out unsigned char * buffer)
+{
+ __ntapi_tt_uint_to_hex_utf8(key,buffer,64);
+}
+
+
+void __fastcall __ntapi_tt_uintptr_to_hex_utf8(
+ __in uintptr_t key,
+ __out unsigned char * buffer)
+{
+ #if defined (__NT32)
+ __ntapi_tt_uint_to_hex_utf8(key,buffer,32);
+ #elif defined (__NT64)
+ __ntapi_tt_uint_to_hex_utf8(key,buffer,64);
+ #endif
+}
diff --git a/src/sync/ntapi_tt_create_event.c b/src/sync/ntapi_tt_create_event.c
new file mode 100644
index 0000000..3d81938
--- /dev/null
+++ b/src/sync/ntapi_tt_create_event.c
@@ -0,0 +1,76 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+static int32_t __cdecl __tt_create_event(
+ __out void ** hevent,
+ __in nt_event_type event_type,
+ __in int32_t initial_state,
+ __in uint32_t obj_attr)
+{
+ int32_t status;
+ nt_sqos sqos;
+ nt_oa oa;
+
+ /* validation */
+ if (!hevent)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* security structure */
+ sqos.length = sizeof(sqos);
+ sqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ sqos.effective_only = 1;
+
+ /* object attributes */
+ oa.len = sizeof(nt_object_attributes);
+ oa.root_dir = (void *)0;
+ oa.obj_name = (nt_unicode_string *)0;
+ oa.obj_attr = obj_attr;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = &sqos;
+
+ status = __ntapi->zw_create_event(
+ hevent,
+ NT_EVENT_ALL_ACCESS,
+ &oa,
+ event_type,
+ initial_state);
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_create_inheritable_event(
+ __out void ** hevent,
+ __in nt_event_type event_type,
+ __in int32_t initial_state)
+{
+ return __tt_create_event(
+ hevent,
+ event_type,
+ initial_state,
+ NT_OBJ_INHERIT);
+}
+
+
+int32_t __stdcall __ntapi_tt_create_private_event(
+ __out void ** hevent,
+ __in nt_event_type event_type,
+ __in int32_t initial_state)
+{
+ return __tt_create_event(
+ hevent,
+ event_type,
+ initial_state,
+ 0);
+}
diff --git a/src/sync/ntapi_tt_sync_block.c b/src/sync/ntapi_tt_sync_block.c
new file mode 100644
index 0000000..e52dd77
--- /dev/null
+++ b/src/sync/ntapi_tt_sync_block.c
@@ -0,0 +1,283 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/nt_atomic.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+void __stdcall __ntapi_tt_sync_block_init(
+ __in nt_sync_block * sync_block,
+ __in uint32_t flags __optional,
+ __in int32_t srvtid __optional,
+ __in int32_t default_lock_tries __optional,
+ __in int64_t default_lock_wait __optional,
+ __in void * hsignal __optional)
+{
+ __ntapi->tt_aligned_block_memset(
+ sync_block,
+ 0,sizeof(*sync_block));
+
+ sync_block->lock_tries = default_lock_tries
+ ? default_lock_tries
+ : __NT_SYNC_BLOCK_LOCK_TRIES;
+
+ sync_block->lock_wait.quad = default_lock_wait
+ ? default_lock_wait
+ : (-1);
+
+ sync_block->flags = flags;
+ sync_block->srvtid = srvtid;
+ sync_block->hsignal = hsignal;
+
+ return;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_lock(
+ __in nt_sync_block * sync_block,
+ __in int32_t lock_tries __optional,
+ __in int64_t lock_wait __optional,
+ __in uint32_t * sig_flag __optional)
+{
+ int32_t status;
+ int32_t tid;
+ intptr_t lock;
+ void * hwait[2];
+ nt_timeout timeout;
+
+ /* validation */
+ if (sync_block->invalid)
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* already owned? */
+ tid = pe_get_current_thread_id();
+ if (sync_block->tid == tid) return NT_STATUS_SUCCESS;
+
+ /* yield to server? */
+ if ((sync_block->flags & NT_SYNC_BLOCK_YIELD_TO_SERVER) && (tid != sync_block->srvtid)) {
+ hwait[0] = sync_block->hserver;
+ hwait[1] = sync_block->hsignal;
+
+ /* signal support */
+ if (sig_flag && *sig_flag)
+ return NT_STATUS_ALERTED;
+
+ /* wait */
+ status = __ntapi->zw_wait_for_multiple_objects(
+ 2,
+ hwait,
+ NT_WAIT_ANY,
+ NT_SYNC_NON_ALERTABLE,
+ (nt_timeout *)0);
+
+ /* signal support */
+ if (sig_flag && *sig_flag)
+ return NT_STATUS_ALERTED;
+ }
+
+ /* first try */
+ lock = at_locked_cas_32(&sync_block->tid,0,tid);
+ if (lock && !--lock_tries) return NT_STATUS_NOT_LOCKED;
+
+ /* first-time contended case? */
+ if (lock && !sync_block->hwait) {
+ status = __ntapi->tt_create_inheritable_event(
+ &hwait[0],
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED);
+
+ if (status) return status;
+
+ lock = at_locked_cas(
+ (intptr_t *)&sync_block->hwait,
+ 0,(intptr_t)hwait);
+
+ if (lock)
+ __ntapi->zw_close(hwait);
+
+ /* try again without a wait */
+ lock = at_locked_cas_32(&sync_block->tid,0,tid);
+ }
+
+ /* contended case? */
+ if (lock) {
+ hwait[0] = sync_block->hwait;
+ hwait[1] = sync_block->hsignal;
+
+ lock_tries = lock_tries
+ ? lock_tries
+ : sync_block->lock_tries;
+
+ timeout.quad = lock_wait
+ ? lock_wait
+ : sync_block->lock_wait.quad;
+
+ for (; lock && lock_tries; lock_tries--) {
+ /* signal support */
+ if (sig_flag && *sig_flag)
+ return NT_STATUS_ALERTED;
+
+ /* wait */
+ status = __ntapi->zw_wait_for_multiple_objects(
+ 2,
+ &sync_block->hwait,
+ NT_WAIT_ANY,
+ NT_SYNC_NON_ALERTABLE,
+ &timeout);
+
+ /* check status */
+ if ((status != NT_STATUS_TIMEOUT) && ((uint32_t)status >= NT_STATUS_WAIT_CAP))
+ return status;
+
+ /* signal support */
+ if (sig_flag && *sig_flag)
+ return NT_STATUS_ALERTED;
+
+ /* try again */
+ lock = at_locked_cas_32(&sync_block->tid,0,tid);
+ };
+ }
+
+ if (lock) return NT_STATUS_NOT_LOCKED;
+
+ /* shared section support */
+ sync_block->pid = pe_get_current_process_id();
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_server_lock(
+ __in nt_sync_block * sync_block,
+ __in int32_t lock_tries __optional,
+ __in int64_t lock_wait __optional,
+ __in uint32_t * sig_flag __optional)
+{
+ int32_t status;
+
+ /* validation */
+ if (sync_block->invalid)
+ return NT_STATUS_INVALID_HANDLE;
+
+ else if (sync_block->srvtid != pe_get_current_thread_id())
+ return NT_STATUS_RESOURCE_NOT_OWNED;
+
+ /* try once without yield request */
+ status = __ntapi_tt_sync_block_lock(
+ sync_block,
+ 1,
+ lock_wait,
+ sig_flag);
+
+ if (status == NT_STATUS_SUCCESS)
+ return status;
+
+ /* hserver */
+ if (!sync_block->hserver) {
+ status = __ntapi->tt_create_inheritable_event(
+ &sync_block->hserver,
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED);
+
+ if (status) return status;
+ } else {
+ status = __ntapi->zw_reset_event(
+ &sync_block->hserver,
+ (int32_t *)0);
+
+ if (status) return status;
+ }
+
+ /* yield request: set */
+ sync_block->flags |= NT_SYNC_BLOCK_YIELD_TO_SERVER;
+
+ /* try again */
+ status = __ntapi_tt_sync_block_lock(
+ sync_block,
+ lock_tries,
+ lock_wait,
+ sig_flag);
+
+ /* yield request: unset */
+ sync_block->flags ^= NT_SYNC_BLOCK_YIELD_TO_SERVER;
+
+ __ntapi->zw_set_event(
+ sync_block->hserver,
+ (int32_t *)0);
+
+ /* (locking not guaranteed) */
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_unlock(
+ __in nt_sync_block * sync_block)
+{
+ int64_t cmp;
+
+ if (sync_block->invalid)
+ return NT_STATUS_INVALID_HANDLE;
+
+ cmp = (int64_t)(pe_get_current_process_id()) << 32;
+ cmp += pe_get_current_thread_id();
+
+ if (cmp != at_locked_cas_64(
+ (int64_t *)&sync_block->tid,
+ cmp,0))
+ return NT_STATUS_RESOURCE_NOT_OWNED;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+void __stdcall __ntapi_tt_sync_block_validate(
+ __in nt_sync_block * sync_block)
+{
+ at_store_32(&sync_block->invalid,0);
+
+ return;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_invalidate(
+ __in nt_sync_block * sync_block)
+{
+ int32_t invalid;
+
+ if (!sync_block)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ invalid = at_locked_cas_32(
+ &sync_block->invalid,
+ 0,
+ 1);
+
+ if (invalid)
+ return NT_STATUS_INVALID_HANDLE;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_sync_block_discard(
+ __in nt_sync_block * sync_block)
+{
+ if (!sync_block)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if (sync_block->hwait)
+ __ntapi->zw_close(sync_block->hwait);
+
+ if (sync_block->hserver)
+ __ntapi->zw_close(sync_block->hserver);
+
+ __ntapi->tt_aligned_block_memset(sync_block,-1,sizeof(*sync_block));
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/sync/ntapi_tt_wait_for_dummy_event.c b/src/sync/ntapi_tt_wait_for_dummy_event.c
new file mode 100644
index 0000000..c7680c7
--- /dev/null
+++ b/src/sync/ntapi_tt_wait_for_dummy_event.c
@@ -0,0 +1,31 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_sync.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_wait_for_dummy_event(void)
+{
+ /* wait forever without setting a break point and without spinning */
+
+ int32_t status;
+ void * hevent;
+
+ status = __ntapi->tt_create_inheritable_event(
+ &hevent,
+ NT_NOTIFICATION_EVENT,
+ NT_EVENT_NOT_SIGNALED);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ return __ntapi->zw_wait_for_single_object(hevent,0,0);
+
+ return status;
+}
diff --git a/src/system/ntapi_tt_get_csr_port_handle_addr_by_logic.c b/src/system/ntapi_tt_get_csr_port_handle_addr_by_logic.c
new file mode 100644
index 0000000..3f38067
--- /dev/null
+++ b/src/system/ntapi_tt_get_csr_port_handle_addr_by_logic.c
@@ -0,0 +1,197 @@
+/********************************************************/
+/* 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"
+
+/************************************************************/
+/* beginning with version 6.0, explicit thread registration */
+/* with csrss is no longer required. the code below should */
+/* work with all known versions of NT, however it will only */
+/* be used when run on the now-obsolete versions of the OS. */
+/************************************************************/
+
+/**
+ Nebbett was pretty much right in his interpretation of
+ the csrss port message; and as long as one changes
+ uint32_t to uintptr_t (especially when it comes to the
+ unknown parameters), then the structures behave as
+ expected according to his book.
+
+ SysInternals: ProcessExplorer: csrss.exe: the stack shows
+ a thread in csrsrv.dll that has CsrUnhandledExceptionFilter
+ as its start address, and ntdll!NtReplyWaitReceivePort as
+ its next function call. This suggests that csrss still
+ uses LPC (at least to some extent) for communication with
+ user processes.
+
+ Given the above, we may deduce that CsrClientCallServer
+ contains a call to ZwRequestWaitReplyPort. Assuming
+ the machine code in ntdll is as optimized as possible,
+ we may then conclude that on x86 machines, this would be
+ an E8 call using relative 32-bit addressing on both NT32
+ and NT64.
+
+ On the 32-bit variant of the operating system, the first
+ argument is passed on the stack, and is normally expressed
+ in terms of an offset from the ds register.
+
+ On the 64-bit variant of the operating system, the first
+ argument is passed in the rcx register. Here, again,
+ machine code optimization suggests that the address of
+ CsrPortHandle will be provided as a 32-bit relative address,
+ or else the code will be larger by several bytes.
+
+ The rest is based on simple logic and straight-forward
+ heuristics. Since we know the addresses of CsrClientCallSertver
+ and ZwRequestWaitReplyPort, we first find the call to the latter
+ function within the former. Once we have found that call, we
+ start going back to look for the argument-passing
+ opcode, and finally do the math to obtain the address of
+ CsrPortHandle.
+**/
+
+
+#if defined(__X86_MODEL)
+void ** __cdecl __ntapi_tt_get_csr_port_handle_addr_by_logic_i386(void)
+{
+ #define MAX_BYTES_BETWEEN_ARG1_PUSH_AND_E8_CALL 0x20
+ #define MAX_FN_BYTES_TO_TEST 0x800
+
+ typedef struct __attr_aligned__ (1) __attr_packed__ __x86_e8_call_signature {
+ unsigned char __opcode_current_e8;
+ unsigned char __addr_relative[4];
+ unsigned char __opcode_next_any;
+ } _x86_e8_call_signature;
+
+ typedef struct __attr_aligned__ (1) __attr_packed__ __x86_push_ds_signature {
+ unsigned char __push;
+ unsigned char __ds;
+ unsigned char __push_ds_arg;
+ } _x86_push_ds_signature;
+
+ unsigned char * ptr_test;
+ _x86_e8_call_signature * ptr_e8_call;
+ _x86_push_ds_signature * ptr_push_ds;
+ int32_t offset;
+
+ /* type-punned tyrants */
+ int32_t * prelative;
+ int32_t relative;
+ uintptr_t * pport_addr;
+
+
+ /* calling a function within the same library: assume E8 call */
+ for (offset = 0; offset < MAX_FN_BYTES_TO_TEST; offset++) {
+ ptr_test = (unsigned char *)__ntapi->csr_client_call_server
+ + offset;
+
+ if (*ptr_test == 0xE8) {
+ ptr_e8_call = (_x86_e8_call_signature *)ptr_test;
+
+ /* make our type-punned tyrant compiler happy */
+ prelative = (int32_t *)&(ptr_e8_call->__addr_relative);
+ relative = *prelative;
+
+ /* are we calling ZwRequestWaitReplyPort? */
+ if ((uintptr_t)(__ntapi->zw_request_wait_reply_port) ==
+ (uintptr_t)&(ptr_e8_call->__opcode_next_any)
+ + relative) {
+ /* assume ds relative address for arg1, go back to find it */
+ for (offset = 0; offset < MAX_BYTES_BETWEEN_ARG1_PUSH_AND_E8_CALL; offset++) {
+ ptr_push_ds = (_x86_push_ds_signature *)((uintptr_t)ptr_e8_call - offset);
+
+ if ((ptr_push_ds->__push == 0xFF) &&
+ (ptr_push_ds->__ds == 0x35)) {
+ /* bingo */
+ /* make our type-punned tyrant compiler happy */
+ pport_addr = (uintptr_t *)&(ptr_push_ds->__push_ds_arg);
+
+ /* all done */
+ return *(void ***)pport_addr;
+ }
+ }
+ }
+ }
+ }
+
+ /* CsrPortHandle not found */
+ return (void **)0;
+}
+#endif
+
+
+#if defined(__X86_64_MODEL)
+void ** __ntapi_tt_get_csr_port_handle_addr_by_logic_x86_64(void)
+{
+ #define MAX_BYTES_BETWEEN_ARG1_PUSH_AND_E8_CALL 0x20
+ #define MAX_FN_BYTES_TO_TEST 0x800
+
+ typedef struct __attr_aligned__ (1) __attr_packed__ __x86_e8_call_signature {
+ unsigned char __opcode_current_e8;
+ unsigned char __addr_relative[4];
+ unsigned char __opcode_next_any;
+ } _x86_e8_call_signature;
+
+ typedef struct __attr_aligned__ (1) __attr_packed__ __x86_move_rcx_rel_signature {
+ unsigned char __move;
+ unsigned char __rcx;
+ unsigned char __relative;
+ unsigned char __arg_32_relative[4];
+ unsigned char __opcode_next_any;
+ } _x86_move_rcx_rel_signature;
+
+ unsigned char * ptr_test;
+ _x86_e8_call_signature * ptr_e8_call;
+ _x86_move_rcx_rel_signature * ptr_move_rcx_rel;
+ int32_t offset;
+ int32_t relative;
+ int32_t * prelative; /* for type-punned tyrants */
+
+
+ /* calling a function within the same library: assume E8 call and 32-bit relative addressing */
+ for (offset = 0; offset < MAX_FN_BYTES_TO_TEST; offset++) {
+ ptr_test = (unsigned char *)__ntapi->csr_client_call_server
+ + offset;
+
+ if (*ptr_test == 0xE8) {
+ ptr_e8_call = (_x86_e8_call_signature *)ptr_test;
+
+ /* please our type-punned tyrant compiler */
+ prelative = (int32_t *)&(ptr_e8_call->__addr_relative);
+ relative = *prelative;
+
+ /* are we calling ZwRequestWaitReplyPort? */
+ /* comparing, not writing; ignore type-punned msgs. */
+ if ((uintptr_t)(__ntapi->zw_request_wait_reply_port) ==
+ (uintptr_t)&(ptr_e8_call->__opcode_next_any)
+ + relative) {
+ /* arg1 must be passed in rcx, so go back to find it */
+ for (offset = 0; offset < MAX_BYTES_BETWEEN_ARG1_PUSH_AND_E8_CALL; offset++) {
+ ptr_move_rcx_rel = (_x86_move_rcx_rel_signature *)((uintptr_t)ptr_e8_call - offset);
+
+ if ((ptr_move_rcx_rel->__move == 0x48) &&
+ (ptr_move_rcx_rel->__rcx == 0x8b) &&
+ (ptr_move_rcx_rel->__relative == 0x0d))
+ /* bingo */
+ /* make our type-punned tyrant compiler happy */
+ prelative = (int32_t *)&(ptr_move_rcx_rel->__arg_32_relative);
+ relative = *prelative;
+
+ /* all done */
+ return (void **)(
+ (uintptr_t)&ptr_move_rcx_rel->__opcode_next_any
+ + relative);
+ }
+ }
+ }
+ }
+
+ /* CsrPortHandle not found */
+ return (void **)0;
+}
+#endif
diff --git a/src/system/ntapi_tt_get_system_directory.c b/src/system/ntapi_tt_get_system_directory.c
new file mode 100644
index 0000000..28b9745
--- /dev/null
+++ b/src/system/ntapi_tt_get_system_directory.c
@@ -0,0 +1,257 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_sysinfo.h>
+#include <ntapi/nt_memory.h>
+#include <ntapi/ntapi.h>
+#include <ntapi/nt_atomic.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_get_system_directory_native_path(
+ __out nt_mem_sec_name * buffer,
+ __in uint32_t buffer_size,
+ __in wchar16_t * base_name,
+ __in uint32_t base_name_size,
+ __out nt_unicode_string * nt_path __optional)
+{
+ int32_t status;
+ wchar16_t * wch_src;
+ wchar16_t * wch_dst;
+ wchar16_t * wch_cap;
+ size_t maxlen_saved;
+ size_t info_size;
+
+ /* validation */
+ if (!buffer || !buffer_size)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ else if (base_name && !base_name_size)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+
+ /* init buffer */
+ buffer->section_name.strlen = 0;
+ buffer->section_name.maxlen = (uint16_t)(buffer_size - sizeof(nt_unicode_string));
+ buffer->section_name.buffer = buffer->section_name_buffer;
+
+ maxlen_saved = buffer->section_name.maxlen;
+ info_size = 0;
+
+ status = __ntapi->zw_query_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ pe_get_ntdll_module_handle(),
+ NT_MEMORY_SECTION_NAME,
+ buffer,
+ buffer_size,
+ &info_size);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* find directory portion */
+ wch_dst = buffer->section_name.buffer + (buffer->section_name.strlen / sizeof(wchar16_t));
+ wch_dst--;
+
+ while ((*wch_dst != '\\') && (wch_dst > buffer->section_name.buffer))
+ wch_dst--;
+
+ if (wch_dst == buffer->section_name.buffer)
+ return NT_STATUS_INTERNAL_ERROR;
+
+ /* base_name */
+ if (base_name) {
+ wch_dst++;
+ wch_src = base_name;
+ wch_cap = (wchar16_t *)((uintptr_t)wch_dst + base_name_size);
+
+ if ((uintptr_t)wch_cap - (uintptr_t)(buffer->section_name.buffer) > maxlen_saved)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ while (wch_dst < wch_cap) {
+ *wch_dst = *wch_src;
+ wch_dst++;
+ wch_src++;
+ }
+ }
+
+ /* null termination */
+ *wch_dst = 0;
+
+ /* nt_path */
+ if (nt_path)
+ __ntapi->rtl_init_unicode_string(
+ nt_path,
+ buffer->section_name.buffer);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_get_system_directory_handle(
+ __out void ** hsysdir,
+ __out nt_mem_sec_name * buffer __optional,
+ __in uint32_t buffer_size __optional)
+{
+ int32_t status;
+ nt_oa oa;
+ nt_iosb iosb;
+ nt_unicode_string path;
+ char _buffer[256];
+
+ /* validation */
+ if (!hsysdir)
+ return NT_STATUS_INVALID_PARAMETER_1;
+ else if (buffer_size && buffer_size < 0x20)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ /* buffer */
+ if (!buffer) {
+ buffer = (nt_mem_sec_name *)_buffer;
+ buffer_size = sizeof(_buffer);
+ __ntapi->tt_aligned_block_memset(buffer,0,sizeof(buffer));
+ }
+
+ /* sysdir path */
+ status = __ntapi_tt_get_system_directory_native_path(
+ buffer,
+ buffer_size,
+ (wchar16_t *)0,
+ 0,
+ &path);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* oa */
+ oa.len = sizeof(nt_oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &path;
+ oa.obj_attr = 0;
+ oa.sec_desc = 0;
+ oa.sec_qos = 0;
+
+ /* open file/folder */
+ status = __ntapi->zw_open_file(
+ hsysdir,
+ NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_ACCESS,
+ &oa,
+ &iosb,
+ NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
+ NT_FILE_DIRECTORY_FILE | NT_FILE_SYNCHRONOUS_IO_ALERT);
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_get_system_directory_dos_path(
+ __in void * hsysdir __optional,
+ __out wchar16_t * buffer,
+ __in uint32_t buffer_size,
+ __in wchar16_t * base_name,
+ __in uint32_t base_name_size,
+ __out nt_unicode_string * nt_path __optional)
+{
+ int32_t status;
+ nt_statfs statfs;
+ wchar16_t * wch;
+ wchar16_t * wch_src;
+ wchar16_t * wch_cap;
+ nt_iosb iosb;
+ nt_fni * fni;
+ uint32_t fni_length;
+
+ /* validation */
+ if (!buffer)
+ return NT_STATUS_INVALID_PARAMETER_2;
+
+ /* hsysdir */
+ if (!hsysdir) {
+ status = __ntapi_tt_get_system_directory_handle(
+ &hsysdir,
+ (nt_mem_sec_name *)buffer,
+ buffer_size);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+ }
+
+ /* statfs */
+ status = __ntapi->tt_statfs(
+ hsysdir,
+ (void *)0,
+ (nt_unicode_string *)0,
+ &statfs,
+ (uintptr_t *)buffer,
+ buffer_size,
+ NT_STATFS_DOS_DRIVE_LETTER);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* dos path name (always shorter than the native path, so buffer_size must be ok) */
+ wch = buffer;
+ *wch = '\\'; wch++;
+ *wch = '?'; wch++;
+ *wch = '?'; wch++;
+ *wch = '\\'; wch++;
+ *wch = statfs.nt_drive_letter; wch++;
+ *wch = ':'; wch++;
+
+ /* alignment */
+ fni = (nt_fni *)((uintptr_t)buffer + 0x10);
+
+ status = __ntapi->zw_query_information_file(
+ hsysdir,
+ &iosb,
+ fni,
+ buffer_size - 8 * sizeof(wchar16_t),
+ NT_FILE_NAME_INFORMATION);
+
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* fni->file_name_length: save */
+ fni_length = fni->file_name_length;
+
+ /* overwrite */
+ wch_src = fni->file_name;
+ wch_cap = (wchar16_t *)((uintptr_t)wch_src + fni_length);
+
+ while (wch_src < wch_cap) {
+ *wch = *wch_src;
+ wch++;
+ wch_src++;
+ }
+
+ /* ultimate path separator */
+ *wch = '\\'; wch++;
+
+ /* base_name */
+ if (base_name) {
+ wch_src = base_name;
+ wch_cap = (wchar16_t *)((uintptr_t)wch + base_name_size);
+
+ if ((uintptr_t)wch_cap - (uintptr_t)buffer - sizeof(wchar16_t) > buffer_size)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ while (wch < wch_cap) {
+ *wch = *wch_src;
+ wch++;
+ wch_src++;
+ }
+ }
+
+ /* null termination */
+ *wch = 0;
+
+ /* nt_path */
+ if (nt_path)
+ __ntapi->rtl_init_unicode_string(
+ nt_path,
+ buffer);
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/system/ntapi_tt_get_system_info_snapshot.c b/src/system/ntapi_tt_get_system_info_snapshot.c
new file mode 100644
index 0000000..bfe2978
--- /dev/null
+++ b/src/system/ntapi_tt_get_system_info_snapshot.c
@@ -0,0 +1,89 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_sysinfo.h>
+#include <ntapi/nt_memory.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tt_get_system_info_snapshot(
+ __in_out nt_system_information_snapshot * sys_info_snapshot)
+{
+ int32_t status;
+
+ /* pre-allocated buffer? */
+ if (sys_info_snapshot->buffer)
+ status = __ntapi->zw_query_system_information(
+ sys_info_snapshot->sys_info_class,
+ sys_info_snapshot->buffer,
+ sys_info_snapshot->max_len,
+ &sys_info_snapshot->info_len);
+ else {
+ /* set initial buffer size */
+ sys_info_snapshot->max_len = NT_ALLOCATION_GRANULARITY;
+
+ /* allocate initial buffer */
+ status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&sys_info_snapshot->buffer,
+ 0,
+ &sys_info_snapshot->max_len,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ /* verification */
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* loop until buffer is large enough to satisfy the system */
+ while ((status = __ntapi->zw_query_system_information(
+ sys_info_snapshot->sys_info_class,
+ sys_info_snapshot->buffer,
+ sys_info_snapshot->max_len,
+ &sys_info_snapshot->info_len))
+ == NT_STATUS_INFO_LENGTH_MISMATCH) {
+
+ /* free previously allocated memory */
+ status = __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&sys_info_snapshot->buffer,
+ &sys_info_snapshot->max_len,
+ NT_MEM_RELEASE);
+
+ /* verification */
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+
+ /* reset buffer and increase buffer size */
+ sys_info_snapshot->buffer = (nt_system_information_buffer *)0;
+ sys_info_snapshot->max_len += NT_ALLOCATION_GRANULARITY;
+
+ /* reallocate buffer memory */
+ status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ (void **)&sys_info_snapshot->buffer,
+ 0,
+ &sys_info_snapshot->max_len,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ /* verification */
+ if (status != NT_STATUS_SUCCESS)
+ return status;
+ }
+ }
+
+ /* verification */
+ if (status == NT_STATUS_SUCCESS) {
+ sys_info_snapshot->pcurrent = &sys_info_snapshot->buffer->mark;
+ return NT_STATUS_SUCCESS;
+ } else {
+ sys_info_snapshot->pcurrent = (void *)0;
+ return status;
+ }
+}
diff --git a/src/thread/ntapi_tt_create_thread.c b/src/thread/ntapi_tt_create_thread.c
new file mode 100644
index 0000000..4fbe68f
--- /dev/null
+++ b/src/thread/ntapi_tt_create_thread.c
@@ -0,0 +1,418 @@
+/********************************************************/
+/* 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 <pemagine/pemagine.h>
+#include <ntapi/nt_status.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_memory.h>
+#include <ntapi/nt_thread.h>
+#include <ntapi/nt_process.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+/* (no planned support of alpha processors, use constant values) */
+#define __PAGE_SIZE 0x001000
+#define __GRANULARITY 0x010000
+#define __RESERVE_ROUND_UP 0x100000
+
+static int32_t __stdcall __create_thread_fail(
+ void * hprocess,
+ void * stack_bottom,
+ size_t stack_size,
+ int32_t status)
+{
+ __ntapi->zw_free_virtual_memory(
+ hprocess,
+ &stack_bottom,
+ &stack_size,
+ NT_MEM_RELEASE);
+ return status;
+}
+
+int32_t __stdcall __ntapi_tt_create_thread(
+ __in_out nt_thread_params * params)
+{
+ int32_t status;
+ ntapi_internals * __internals;
+
+ nt_client_id cid;
+ nt_port_message_csrss_process csrss_msg;
+ nt_port_message_csrss_process * csrss_msg_1st;
+ nt_port_message_csrss_thread * csrss_msg_any;
+
+ void * stack_system_limit;
+ uint32_t protect_type_old;
+
+ nt_user_stack stack;
+ nt_thread_context context;
+ uintptr_t fsuspended;
+ uintptr_t * parg;
+
+ if (!(params->stack_size_commit))
+ return NT_STATUS_INVALID_PARAMETER;
+ else if (!(params->stack_size_reserve))
+ return NT_STATUS_INVALID_PARAMETER;
+ else if (params->ext_ctx_size > __NT_INTERNAL_PAGE_SIZE)
+ return NT_STATUS_INVALID_PARAMETER;
+ else if (params->ext_ctx_size % sizeof(intptr_t))
+ return NT_STATUS_INVALID_PARAMETER;
+ else if (params->arg && params->ext_ctx)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+ else if (params->ext_ctx && !params->ext_ctx_size)
+ return NT_STATUS_INVALID_PARAMETER_MIX;
+
+ /* init */
+ __internals = __ntapi_internals();
+ params->stack_size_commit = __NT_ROUND_UP_TO_POWER_OF_2(params->stack_size_commit+params->ext_ctx_size, __PAGE_SIZE);
+ params->stack_size_reserve = __NT_ROUND_UP_TO_POWER_OF_2(params->stack_size_reserve,__GRANULARITY);
+
+ /* compare, round-up as needed */
+ if (params->stack_size_commit >= params->stack_size_reserve)
+ params->stack_size_reserve = __NT_ROUND_UP_TO_POWER_OF_2(params->stack_size_commit,__RESERVE_ROUND_UP);
+
+ /**
+ *
+ * --------- BASE ----------
+ *
+ * ---- (COMMITED AREA) ----
+ *
+ * --------- LIMIT ---------
+ *
+ * ------ GUARD PAGE -------
+ *
+ * ------ ACTUAL LIMIT -----
+ *
+ * ---- (RESERVED AREA) ----
+ *
+ * -------- BOTTOM ---------
+ *
+ **/
+
+ /* stack structure: unused fields */
+ stack.fixed_stack_base = (void *)0;
+ stack.fixed_stack_limit = (void *)0;
+
+ /* first we reserve */
+ stack.expandable_stack_bottom = (void *)0;
+ status = __ntapi->zw_allocate_virtual_memory(
+ params->hprocess,
+ &stack.expandable_stack_bottom,
+ params->stack_zero_bits,
+ &params->stack_size_reserve,
+ NT_MEM_RESERVE,
+ NT_PAGE_READWRITE);
+
+ if (status) return status;
+
+ /* calculate base and limit */
+ stack.expandable_stack_base =
+ (void *)((intptr_t)stack.expandable_stack_bottom
+ + params->stack_size_reserve);
+
+ stack.expandable_stack_limit =
+ (void *)((intptr_t)stack.expandable_stack_base
+ - params->stack_size_commit);
+
+ /* guard page */
+ params->stack_size_commit += __PAGE_SIZE;
+ stack_system_limit =
+ (void *)((intptr_t)stack.expandable_stack_base
+ - params->stack_size_commit);
+
+ /* then we commit */
+ status = __ntapi->zw_allocate_virtual_memory(
+ params->hprocess,
+ &stack_system_limit,
+ 0,
+ &params->stack_size_commit,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (status) return __create_thread_fail(
+ params->hprocess,
+ stack.expandable_stack_bottom,
+ params->stack_size_reserve,
+ status);
+
+ /* finally we protect the guard page */
+ params->stack_size_commit = __PAGE_SIZE;
+ status = __ntapi->zw_protect_virtual_memory(
+ params->hprocess,
+ &stack_system_limit,
+ &params->stack_size_commit,
+ NT_PAGE_READWRITE | NT_MEM_PAGE_GUARD,
+ &protect_type_old);
+
+ if (status) return __create_thread_fail(
+ params->hprocess,
+ stack.expandable_stack_bottom,
+ params->stack_size_reserve,
+ status);
+
+ /* context */
+ if (!params->reg_context) {
+ params->reg_context = &context;
+ __ntapi->tt_aligned_block_memset(&context,0,sizeof(nt_thread_context));
+ __INIT_CONTEXT(context);
+ context.INSTRUCTION_POINTER_REGISTER = (uintptr_t)params->start;
+ context.STACK_POINTER_REGISTER = (uintptr_t)(stack.expandable_stack_base)
+ - sizeof(intptr_t);
+ }
+
+
+
+
+
+
+
+/*****************************************************************************/
+/*-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/
+/* */
+/* */
+/* INNOVATION IN THE FIELD OF MULTI-THREADED COMPUTER PROGRAMMING */
+/* */
+/* A "RAPUNZEL" TOP-OF-STACK, VARIABLE-SIZE ENTRY-ROUTINE CONTEXT */
+/* */
+/* COPYRIGHT (C) 2013,2014,2015 ZVI GILBOA */
+/* */
+/* */
+/* */
+/* Laß mir dein Haar herunter.« */
+/**/ if (params->ext_ctx) { /**/
+/**/ context.STACK_POINTER_REGISTER -= params->ext_ctx_size; /**/
+/**/ params->arg = (void *)context.STACK_POINTER_REGISTER; /**/
+/**/ /**/
+/**/ if (params->creation_flags & NT_CREATE_LOCAL_THREAD) /**/
+/**/ __ntapi->tt_aligned_block_memcpy( /**/
+/**/ (uintptr_t *)params->arg, /**/
+/**/ (uintptr_t *)params->ext_ctx, /**/
+/**/ params->ext_ctx_size); /**/
+/**/ else { /**/
+/**/ status = __ntapi->zw_write_virtual_memory( /**/
+/**/ params->hprocess, /**/
+/**/ params->arg, /**/
+/**/ (char *)params->ext_ctx, /**/
+/**/ params->ext_ctx_size, /**/
+/**/ 0); /**/
+/**/ /**/
+/**/ if (status) return __create_thread_fail( /**/
+/**/ params->hprocess, /**/
+/**/ stack.expandable_stack_bottom, /**/
+/**/ params->stack_size_reserve, /**/
+/**/ status); /**/
+/**/ } /**/
+/**/ } /**/
+/**/ /**/
+/**/ /**/
+/**/ /**/
+/* entry-routine argument address and stack pointer adjustment */
+/**/ if (sizeof(intptr_t) == 4) { /**/
+/**/ context.STACK_POINTER_REGISTER -= sizeof(intptr_t); /**/
+/**/ parg = (uintptr_t *)context.STACK_POINTER_REGISTER; /**/
+/**/ } else /**/
+/**/ parg = &context.FAST_CALL_ARG0; /**/
+/**/ /**/
+/**/ /**/
+/* write entry-routine argument */
+/**/ if ((sizeof(size_t) == 8) /**/
+/**/ || (params->creation_flags&NT_CREATE_LOCAL_THREAD))/**/
+/**/ *parg = (uintptr_t)params->arg; /**/
+/**/ else { /**/
+/**/ status = __ntapi->zw_write_virtual_memory( /**/
+/**/ params->hprocess, /**/
+/**/ parg, /**/
+/**/ (char *)&params->arg, /**/
+/**/ sizeof(uintptr_t), /**/
+/**/ 0); /**/
+/**/ /**/
+/**/ if (status) return __create_thread_fail( /**/
+/**/ params->hprocess, /**/
+/**/ stack.expandable_stack_bottom, /**/
+/**/ params->stack_size_reserve, /**/
+/**/ status); /**/
+/**/ } /**/
+/**/ /**/
+/**/ /**/
+/*-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/
+/*****************************************************************************/
+
+
+
+
+
+
+
+
+
+
+
+ /* create thread */
+ if ((!__ntapi->zw_create_user_process) | (params->creation_flags & NT_CREATE_SUSPENDED))
+ fsuspended = 1;
+ else
+ fsuspended = 0;
+
+ status = __ntapi->zw_create_thread(
+ &params->hthread,
+ NT_THREAD_ALL_ACCESS,
+ params->obj_attr,
+ params->hprocess,
+ &cid,
+ params->reg_context,
+ &stack,
+ fsuspended);
+
+ if (status) return __create_thread_fail(
+ params->hprocess,
+ stack.expandable_stack_bottom,
+ params->stack_size_reserve,
+ status);
+
+ /* for os versions prior to hasta la */
+ if (!__ntapi->zw_create_user_process) {
+ __ntapi->tt_aligned_block_memset(&csrss_msg,0,sizeof(csrss_msg));
+
+ if (params->creation_flags & NT_CREATE_FIRST_THREAD_OF_PROCESS) {
+ /* nt_port_message_csrss_process is the larger structure */
+ csrss_msg_1st = &csrss_msg;
+
+ csrss_msg_1st->header.data_size = sizeof(nt_port_message_csrss_process) - sizeof(nt_port_message);
+ csrss_msg_1st->header.msg_size = sizeof(nt_port_message_csrss_process);
+ csrss_msg_1st->opcode = 0x10000;
+ csrss_msg_1st->hprocess = params->hprocess;
+ csrss_msg_1st->hthread = params->hthread;
+ csrss_msg_1st->unique_process_id = cid.process_id;
+ csrss_msg_1st->unique_thread_id = cid.thread_id;
+ } else {
+ /* nt_port_message_csrss_thread is the smaller structure */
+ csrss_msg_any = (nt_port_message_csrss_thread *)&csrss_msg;
+
+ csrss_msg_any->header.data_size = sizeof(nt_port_message_csrss_thread) - sizeof(nt_port_message);
+ csrss_msg_any->header.msg_size = sizeof(nt_port_message_csrss_thread);
+ csrss_msg_any->opcode = 0x10001;
+ csrss_msg_any->hthread = params->hthread;
+ csrss_msg_any->unique_process_id = cid.process_id;
+ csrss_msg_any->unique_thread_id = cid.thread_id;
+ }
+
+ /* send csrss a new-thread notification */
+ if (__internals->csr_port_handle_addr) {
+ status = __ntapi->zw_request_wait_reply_port(
+ *__internals->csr_port_handle_addr,
+ &csrss_msg,&csrss_msg);
+ }
+
+ /* output csrss_status to caller */
+ params->csrss_status = status
+ ? status
+ : csrss_msg.status;
+ }
+
+ /* resume thread, close handle as needed */
+ if (fsuspended && !(params->creation_flags & NT_CREATE_SUSPENDED))
+ status = __ntapi->zw_resume_thread(params->hthread,0);
+
+ if (params->creation_flags & NT_CLOSE_THREAD_HANDLE)
+ __ntapi->zw_close(params->hthread);
+
+ /* and finally */
+ params->thread_id = (uint32_t)cid.thread_id;
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_tt_create_local_thread(
+ __in_out nt_thread_params * params)
+{
+ void * image_base;
+ struct pe_stack_heap_info stack_heap_info;
+ nt_client_id cid;
+ nt_object_attributes oa;
+ nt_status status;
+
+ /* oa init */
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = (nt_unicode_string *)0;
+ oa.obj_attr = 0;
+ oa.sec_desc = (nt_sd *)0;
+ oa.sec_qos = (nt_sqos *)0;
+
+ /* init cid */
+ cid.process_id = pe_get_current_process_id();
+ cid.thread_id = pe_get_current_thread_id();
+
+ /* obtain a handle to our own process */
+ /* TODO: use cached handle, no close */
+ status = __ntapi->zw_open_process(
+ &params->hprocess,
+ NT_PROCESS_ALL_ACCESS,
+ &oa,
+ &cid);
+
+ if (status) return status;
+
+ /* retrieve the stack defaults as needed */
+ if (!(params->stack_size_commit && params->stack_size_reserve) && !(params->stack_info)) {
+ /* image_base*/
+ image_base = pe_get_first_module_handle();
+
+ if (!(intptr_t)image_base)
+ return NT_STATUS_INVALID_IMPORT_OF_NON_DLL;
+
+ status = pe_get_image_stack_heap_info(
+ image_base,
+ &stack_heap_info);
+
+ if (status)
+ return NT_STATUS_INVALID_IMAGE_FORMAT;
+
+ /* stack_size_commit */
+ if (!params->stack_size_commit)
+ params->stack_size_commit = stack_heap_info.size_of_stack_commit;
+
+ /* stack_size_reserve */
+ if (!params->stack_size_reserve)
+ params->stack_size_reserve = stack_heap_info.size_of_stack_reserve;
+
+ if (!(params->stack_size_commit && params->stack_size_reserve))
+ return NT_STATUS_INVALID_IMAGE_FORMAT;
+ }
+
+ params->creation_flags |= NT_CREATE_LOCAL_THREAD;
+ status = __ntapi_tt_create_thread(params);
+
+ /* TODO: use cached handle, no close */
+ __ntapi->zw_close(params->hprocess);
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_tt_create_remote_thread(
+ __in_out nt_thread_params * params)
+{
+ return __ntapi_tt_create_thread(params);
+}
+
+
+void * __cdecl __ntapi_csr_port_handle(nt_status * pstatus)
+{
+ ntapi_internals * __internals;
+
+ __internals = __ntapi_internals();
+
+ if (__internals->csr_port_handle_addr) {
+ if (pstatus)
+ *pstatus = NT_STATUS_SUCCESS;
+ return *__internals->csr_port_handle_addr;
+ } else {
+ if (pstatus)
+ *pstatus = NT_STATUS_UNSUCCESSFUL;
+ return (void *)0;
+ }
+}
diff --git a/src/tty/ntapi_tty_client_process_register.c b/src/tty/ntapi_tty_client_process_register.c
new file mode 100644
index 0000000..935cf1e
--- /dev/null
+++ b/src/tty/ntapi_tty_client_process_register.c
@@ -0,0 +1,37 @@
+/********************************************************/
+/* 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_tty_client_process_register(
+ __in void * hport,
+ __in uintptr_t process_id,
+ __in uintptr_t thread_id,
+ __in uintptr_t flags,
+ __in nt_large_integer * reserved)
+{
+ nt_status status;
+ nt_tty_register_msg msg;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_CLIENT_PROCESS_REGISTER;
+
+ msg.data.reginfo.process_id = process_id;
+ msg.data.reginfo.thread_id = thread_id;
+ msg.data.reginfo.flags = flags;
+
+ if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
+ return status;
+
+ return msg.data.ttyinfo.status;
+}
diff --git a/src/tty/ntapi_tty_client_session_query.c b/src/tty/ntapi_tty_client_session_query.c
new file mode 100644
index 0000000..1d0dbe8
--- /dev/null
+++ b/src/tty/ntapi_tty_client_session_query.c
@@ -0,0 +1,40 @@
+/********************************************************/
+/* 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/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tty_client_session_query(
+ __in void * hport,
+ __out nt_tty_session_info * sessioninfo)
+{
+ int32_t status;
+ nt_tty_session_msg msg;
+
+ hport = hport ? hport : __ntapi_internals()->hport_tty_session;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_CLIENT_SESSION_QUERY;
+
+ if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ sessioninfo->pid = msg.data.sessioninfo.pid;
+ sessioninfo->pgid = msg.data.sessioninfo.pgid;
+ sessioninfo->sid = msg.data.sessioninfo.sid;
+ sessioninfo->reserved = msg.data.sessioninfo.reserved;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/tty/ntapi_tty_client_session_set.c b/src/tty/ntapi_tty_client_session_set.c
new file mode 100644
index 0000000..600fd5e
--- /dev/null
+++ b/src/tty/ntapi_tty_client_session_set.c
@@ -0,0 +1,38 @@
+/********************************************************/
+/* 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/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tty_client_session_set(
+ __in void * hport,
+ __in nt_tty_session_info * sessioninfo)
+{
+ int32_t status;
+ nt_tty_session_msg msg;
+
+ hport = hport ? hport : __ntapi_internals()->hport_tty_session;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_CLIENT_SESSION_SET;
+
+ msg.data.sessioninfo.pid = sessioninfo->pid;
+ msg.data.sessioninfo.pgid = sessioninfo->pgid;
+ msg.data.sessioninfo.sid = sessioninfo->sid;
+ msg.data.sessioninfo.reserved = sessioninfo->reserved;
+
+ if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
+ return status;
+
+ return msg.data.ttyinfo.status;
+}
diff --git a/src/tty/ntapi_tty_connect.c b/src/tty/ntapi_tty_connect.c
new file mode 100644
index 0000000..4ef198c
--- /dev/null
+++ b/src/tty/ntapi_tty_connect.c
@@ -0,0 +1,47 @@
+/********************************************************/
+/* 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/nt_object.h>
+#include <ntapi/nt_port.h>
+#include <ntapi/nt_string.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tty_connect(
+ __out void ** hport,
+ __in wchar16_t * tty_port_name,
+ __in int32_t impersonation_level)
+{
+ nt_object_attributes oa;
+ nt_unicode_string name;
+ nt_security_quality_of_service sqos;
+
+ __ntapi->tt_init_unicode_string_from_utf16(
+ &name,tty_port_name);
+
+ sqos.length = sizeof(sqos);
+ sqos.impersonation_level = impersonation_level;
+ sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ sqos.effective_only = 1;
+
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &name;
+ oa.obj_attr = 0;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = &sqos;
+
+ return __ntapi->zw_connect_port(
+ hport,
+ &name,
+ &sqos,
+ (nt_port_section_write *)0,
+ (nt_port_section_read *)0,
+ (uint32_t *)0,
+ (void *)0,
+ (uint32_t *)0);
+}
diff --git a/src/tty/ntapi_tty_create_session.c b/src/tty/ntapi_tty_create_session.c
new file mode 100644
index 0000000..176b2fb
--- /dev/null
+++ b/src/tty/ntapi_tty_create_session.c
@@ -0,0 +1,166 @@
+/********************************************************/
+/* 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"
+
+static int32_t __fastcall __tty_create_session_return(
+ nt_create_process_params * params,
+ int32_t status)
+{
+ if (status)
+ __ntapi->zw_terminate_process(
+ params->hprocess,
+ NT_STATUS_UNEXPECTED_IO_ERROR);
+
+ __ntapi->zw_close(params->hprocess);
+ __ntapi->zw_close(params->hthread);
+
+ return status;
+}
+
+int32_t __stdcall __ntapi_tty_create_session(
+ __out void ** hport,
+ __out nt_port_name * port_name,
+ __in nt_tty_session_type type,
+ __in const nt_guid * guid __optional,
+ __in wchar16_t * image_name __optional)
+{
+ nt_status status;
+ ntapi_internals * __internals;
+
+ nt_port_attr port_attr;
+ nt_runtime_data ssattr;
+ nt_runtime_data_block rtblock;
+ nt_create_process_params params;
+
+ wchar16_t __attr_aligned__(8) __tty_image_name_fallback[] = {
+ '\\','?','?','\\',
+ 'C',':',
+ '\\','m','i','d','i','p','i','x',
+ '\\','b','i','n',
+ '\\','n','t','c','t','t','y',
+ '.','e','x','e',
+ 0};
+
+ /* init */
+ __internals = __ntapi_internals();
+
+ __ntapi->tt_aligned_block_memset(
+ &port_attr,0,sizeof(port_attr));
+
+ switch (type) {
+ case NT_TTY_SESSION_PRIMARY:
+ port_attr.type = NT_PORT_TYPE_SUBSYSTEM;
+ port_attr.subtype = NT_PORT_SUBTYPE_DEFAULT;
+
+ if (!hport)
+ hport = &__internals->hport_tty_session;
+
+ if (!port_name)
+ port_name = __internals->subsystem;
+
+ if (!image_name)
+ image_name = __tty_image_name_fallback;
+
+ break;
+
+ case NT_TTY_SESSION_PRIVATE:
+ port_attr.type = NT_PORT_TYPE_SUBSYSTEM;
+ port_attr.subtype = NT_PORT_SUBTYPE_PRIVATE;
+ break;
+
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* port guid */
+ if (guid)
+ __ntapi->tt_guid_copy(
+ &port_attr.guid,
+ guid);
+ else
+ __ntapi->tt_port_guid_from_type(
+ &port_attr.guid,
+ port_attr.type,
+ port_attr.subtype);
+
+ /* port keys */
+ if ((status = __ntapi->tt_port_generate_keys(&port_attr.keys)))
+ return status;
+
+ /* port name */
+ __ntapi->tt_port_name_from_attributes(
+ port_name,
+ &port_attr);
+
+ /* subsystem attributes */
+ __ntapi->tt_aligned_block_memset(
+ &ssattr,0,sizeof(ssattr));
+
+ ssattr.srv_type = port_attr.type;
+ ssattr.srv_subtype = port_attr.subtype;
+ ssattr.srv_keys[0] = port_attr.keys.key[0];
+ ssattr.srv_keys[1] = port_attr.keys.key[1];
+ ssattr.srv_keys[2] = port_attr.keys.key[2];
+ ssattr.srv_keys[3] = port_attr.keys.key[3];
+ ssattr.srv_keys[4] = port_attr.keys.key[4];
+ ssattr.srv_keys[5] = port_attr.keys.key[5];
+
+ __ntapi->tt_guid_copy(
+ &ssattr.srv_guid,
+ &port_attr.guid);
+
+ if ((status = __ntapi->tt_create_private_event(
+ &ssattr.srv_ready,
+ NT_SYNCHRONIZATION_EVENT,
+ NT_EVENT_NOT_SIGNALED)))
+ return status;
+
+ /* create subsystem process */
+ rtblock.addr = &ssattr;
+ rtblock.size = sizeof(ssattr);
+ rtblock.remote_addr = 0;
+ rtblock.remote_size = 0;
+ rtblock.flags = NT_RUNTIME_DATA_DUPLICATE_SESSION_HANDLES;
+
+ __ntapi->tt_aligned_block_memset(
+ &params,0,sizeof(params));
+
+ params.image_name = image_name;
+ params.rtblock = &rtblock;
+
+ if ((status = __ntapi->tt_create_native_process(&params)))
+ return status;
+
+ if ((status = __ntapi->zw_wait_for_single_object(
+ ssattr.srv_ready,
+ NT_SYNC_NON_ALERTABLE,
+ 0)))
+ return __tty_create_session_return(&params,status);
+
+ /* connect to subsystem */
+ if ((status = __ntapi->tty_connect(
+ hport,
+ &port_name->base_named_objects[0],
+ NT_SECURITY_IMPERSONATION)))
+ return __tty_create_session_return(&params,status);
+
+ /* finalize primary session */
+ if (type == NT_TTY_SESSION_PRIMARY) {
+ if (hport != &__internals->hport_tty_session)
+ __internals->hport_tty_session = *hport;
+
+ if (port_name != __internals->subsystem)
+ __ntapi->tt_memcpy_utf16(
+ __internals->subsystem->base_named_objects,
+ port_name->base_named_objects,
+ sizeof(*port_name));
+ };
+
+ return __tty_create_session_return(&params,NT_STATUS_SUCCESS);
+}
diff --git a/src/tty/ntapi_tty_join_session.c b/src/tty/ntapi_tty_join_session.c
new file mode 100644
index 0000000..e88b9cb
--- /dev/null
+++ b/src/tty/ntapi_tty_join_session.c
@@ -0,0 +1,53 @@
+/********************************************************/
+/* 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_tty_join_session(
+ __out void ** hport,
+ __out nt_port_name * port_name,
+ __in nt_port_attr * port_attr,
+ __in nt_tty_session_type type)
+{
+ nt_status status;
+ ntapi_internals * __internals;
+
+ /* init */
+ __internals = __ntapi_internals();
+
+ if (type == NT_TTY_SESSION_PRIMARY) {
+ hport = hport ? hport : &__internals->hport_tty_session;
+ port_name = port_name ? port_name : __internals->subsystem;
+ }
+
+ /* port name */
+ __ntapi->tt_port_name_from_attributes(
+ port_name,
+ port_attr);
+
+ /* connect to subsystem */
+ if ((status = __ntapi->tty_connect(
+ hport,
+ (wchar16_t *)port_name,
+ NT_SECURITY_IMPERSONATION)))
+ return status;
+
+ /* finalize primary session */
+ if (type == NT_TTY_SESSION_PRIMARY) {
+ if (hport != &__internals->hport_tty_session)
+ __internals->hport_tty_session = *hport;
+
+ if (port_name != __internals->subsystem)
+ __ntapi->tt_memcpy_utf16(
+ __internals->subsystem->base_named_objects,
+ port_name->base_named_objects,
+ sizeof(*port_name));
+ };
+
+ return status;
+}
diff --git a/src/tty/ntapi_tty_query_information_server.c b/src/tty/ntapi_tty_query_information_server.c
new file mode 100644
index 0000000..7930413
--- /dev/null
+++ b/src/tty/ntapi_tty_query_information_server.c
@@ -0,0 +1,40 @@
+/********************************************************/
+/* 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/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tty_query_information_server(
+ __in void * hport,
+ __in nt_tty_server_info * srvinfo)
+{
+ int32_t status;
+ nt_tty_server_msg msg;
+
+ hport = hport ? hport : __ntapi_internals()->hport_tty_session;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_QUERY_INFORMATION_SERVER;
+
+ if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)srvinfo,
+ (uintptr_t *)&(msg.data.srvinfo),
+ sizeof(*srvinfo));
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/tty/ntapi_tty_request_peer.c b/src/tty/ntapi_tty_request_peer.c
new file mode 100644
index 0000000..9f6550d
--- /dev/null
+++ b/src/tty/ntapi_tty_request_peer.c
@@ -0,0 +1,46 @@
+/********************************************************/
+/* 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/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tty_request_peer(
+ __in void * hport,
+ __in int32_t opcode,
+ __in uint32_t flags,
+ __in const nt_guid * service,
+ __in nt_port_attr * peer)
+{
+ int32_t status;
+ nt_tty_peer_msg msg;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_REQUEST_PEER;
+
+ msg.data.peerinfo.opcode= opcode;
+ msg.data.peerinfo.flags = flags;
+
+ if (service) __ntapi->tt_guid_copy(
+ &msg.data.peerinfo.service,
+ service);
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)&msg.data.peerinfo.peer,
+ (uintptr_t *)peer,
+ sizeof(*peer));
+
+ if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
+ return status;
+
+ return msg.data.ttyinfo.status;
+}
diff --git a/src/tty/ntapi_tty_vms_query.c b/src/tty/ntapi_tty_vms_query.c
new file mode 100644
index 0000000..08e3212
--- /dev/null
+++ b/src/tty/ntapi_tty_vms_query.c
@@ -0,0 +1,40 @@
+/********************************************************/
+/* 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/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tty_vms_query(
+ __in void * hport,
+ __in nt_tty_vms_info * vmsinfo)
+{
+ int32_t status;
+ nt_tty_vms_msg msg;
+
+ hport = hport ? hport : __ntapi_internals()->hport_tty_session;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_VMS_QUERY;
+
+ if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)vmsinfo,
+ (uintptr_t *)&(msg.data.vmsinfo),
+ sizeof(*vmsinfo));
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/tty/ntapi_tty_vms_request.c b/src/tty/ntapi_tty_vms_request.c
new file mode 100644
index 0000000..74dbf5b
--- /dev/null
+++ b/src/tty/ntapi_tty_vms_request.c
@@ -0,0 +1,46 @@
+/********************************************************/
+/* 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/nt_tty.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+int32_t __stdcall __ntapi_tty_vms_request(
+ __in void * hport,
+ __in nt_tty_vms_info * vmsinfo)
+{
+ int32_t status;
+ nt_tty_vms_msg msg;
+
+ hport = hport ? hport : __ntapi_internals()->hport_tty_session;
+
+ __ntapi->tt_aligned_block_memset(
+ &msg,0,
+ sizeof(nt_port_message) + sizeof(nt_tty_msg_info));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.ttyinfo.opcode = NT_TTY_VMS_REQUEST;
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)&(msg.data.vmsinfo),
+ (uintptr_t *)vmsinfo,
+ sizeof(*vmsinfo));
+
+ if ((status = __ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
+ return status;
+ else if (msg.data.ttyinfo.status)
+ return msg.data.ttyinfo.status;
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)vmsinfo,
+ (uintptr_t *)&(msg.data.vmsinfo),
+ sizeof(*vmsinfo));
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/unicode/ntapi_uc_unicode_conversion_from_utf16.c b/src/unicode/ntapi_uc_unicode_conversion_from_utf16.c
new file mode 100644
index 0000000..102a24d
--- /dev/null
+++ b/src/unicode/ntapi_uc_unicode_conversion_from_utf16.c
@@ -0,0 +1,287 @@
+/********************************************************/
+/* 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/nt_status.h>
+#include <ntapi/nt_unicode.h>
+#include "ntapi_impl.h"
+
+
+static int32_t __fastcall __utf16_to_utf8_handler_1byte_or_null_termination(nt_utf16_callback_args * args)
+{
+ /*******************************************/
+ /* from: 00000000 0xxxxxxx (little endian) */
+ /* to: 0xxxxxxx (utf-8) */
+ /*******************************************/
+
+ uint8_t * dst;
+
+ if (args->dst >= args->dst_cap)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ dst = (uint8_t *)args->dst;
+ *dst = *(uint8_t *)(args->src);
+
+ /* advance source and destination buffer */
+ args->src++;
+ args->dst = (void *)((uintptr_t)(args->dst) + 1);
+
+ /* bytes_written */
+ args->bytes_written++;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __utf16_to_utf8_handler_2bytes(nt_utf16_callback_args * args)
+{
+ /*******************************************/
+ /* from: 00000yyy yyxxxxxx (little endian) */
+ /* to: 110yyyyy 10xxxxxx (utf-8) */
+ /*******************************************/
+
+ const wchar16_t * src;
+ uint8_t * dst;
+
+ wchar16_t wx;
+ wchar16_t wy;
+
+ if ((uintptr_t)(args->dst) + 1 >= (uintptr_t)(args->dst_cap))
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ src = args->src;
+ dst = (uint8_t *)args->dst;
+
+ wy = *src;
+ wy >>= 6;
+
+ wx = *src;
+ wx <<= 10;
+ wx >>= 10;
+
+ /* write the y part */
+ *dst = (char)(0xC0 | wy);
+ dst++;
+
+ /* write the x part */
+ *dst = (char)(0x80 | wx);
+
+ /* advance source and destination buffer */
+ args->src++;
+ args->dst = (void *)((uintptr_t)(args->dst) + 2);
+
+ /* bytes_written */
+ args->bytes_written += 2;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __utf16_to_utf8_handler_3bytes(nt_utf16_callback_args * args)
+{
+ /********************************************/
+ /* from: zzzzyyyy yyxxxxxx (little endian) */
+ /* to: 1110zzzz 10yyyyyy 10xxxxxx (utf-8) */
+ /********************************************/
+
+ const wchar16_t * src;
+ uint8_t * dst;
+
+ wchar16_t wx;
+ wchar16_t wy;
+ wchar16_t wz;
+
+ if ((uintptr_t)(args->dst) + 2 >= (uintptr_t)(args->dst_cap))
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ src = args->src;
+ dst = (uint8_t *)args->dst;
+
+ wz = *src;
+ wz >>= 12;
+
+ wy = *src;
+ wy <<= 4;
+ wy >>= 10;
+
+ wx = *src;
+ wx <<= 10;
+ wx >>= 10;
+
+ /* write the z part */
+ *dst = (char)(0xE0 | wz);
+ dst++;
+
+ /* write the y part */
+ *dst = (char)(0x80 | wy);
+ dst++;
+
+ /* write the x part */
+ *dst = (char)(0x80 | wx);
+
+ /* advance source and destination buffer */
+ args->src++;
+ args->dst = (void *)((uintptr_t)(args->dst) + 3);
+
+ /* bytes_written */
+ args->bytes_written += 3;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __utf16_to_utf8_handler_4bytes(nt_utf16_callback_args * args)
+{
+ /****************************************************************/
+ /* from: 110110ww wwzzzzyy 110111yy yyxxxxxx (little endian) */
+ /* to: 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx (utf-8) */
+ /****************************************************************/
+
+ const wchar16_t * src;
+ uint8_t * dst;
+
+ wchar16_t wx;
+ wchar16_t wz;
+
+ wchar16_t wy_low;
+ wchar16_t wy_high;
+ wchar16_t ww;
+ wchar16_t uuuuu;
+ wchar16_t u_low;
+ wchar16_t u_high;
+
+ if ((uintptr_t)(args->dst) + 3 >= (uintptr_t)(args->dst_cap))
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ src = args->src;
+ dst = (uint8_t *)args->dst;
+
+ /* low two bytes */
+ wx = *src;
+ wx <<= 10;
+ wx >>= 10;
+
+ wy_low = *src;
+ wy_low <<= 6;
+ wy_low >>= 12;
+
+ /* (surrogate pair) */
+ src++;
+
+ /* high two bytes */
+ wy_high = *src;
+ wy_high <<= 14;
+ wy_high >>= 10;
+
+ wz = *src;
+ wz <<= 10;
+ wz >>= 12;
+ wz <<= 2;
+
+ ww = *src;
+ ww <<= 6;
+ ww >>= 12;
+
+ uuuuu = ww + 1;
+ u_high = uuuuu >> 2;
+ u_low = ((uuuuu << 14) >> 10);
+
+ /* 1st byte: 11110uuu */
+ *dst = (char)(0xF0 | u_high);
+ dst++;
+
+ /* 2nd byte: 10uuzzzz */
+ *dst = (char)(0x80 | u_low | wz);
+ dst++;
+
+ /* 3rd byte: 10yyyyyy */
+ *dst = (char)(0x80 | wy_low | wy_high);
+ dst++;
+
+ /* 4th byte: 10xxxxxx */
+ *dst = (char)(0x80 | wx);
+
+ /* advance source and destination buffer */
+ args->src += 2;
+ args->dst = (void *)((uintptr_t)(args->dst) + 4);
+
+ /* bytes_written */
+ args->bytes_written += 4;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __update_stream_leftover_info_utf16(
+ __in_out nt_unicode_conversion_params_utf16_to_utf8 * params)
+{
+ int32_t status;
+ ptrdiff_t offset;
+ wchar16_t * wlead;
+
+ offset = (uintptr_t)params->src + (uintptr_t)params->src_size_in_bytes - (uintptr_t)params->addr_failed;
+ wlead = (wchar16_t *)params->addr_failed;
+
+
+ if ((offset == 2) && (*wlead >= 0xD800) && (*wlead < 0xDC00)) {
+ /* possibly the lead of a surrogate pair lead */
+ params->leftover_count = 2;
+ params->leftover_bytes = *wlead;
+ params->leftover_bytes <<= 16;
+ status = NT_STATUS_SUCCESS;
+ } else {
+ params->leftover_count = 0;
+ params->leftover_bytes = 0;
+ status = NT_STATUS_ILLEGAL_CHARACTER;
+ }
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_uc_convert_unicode_stream_utf16_to_utf8(
+ __in_out nt_unicode_conversion_params_utf16_to_utf8 * params)
+{
+ int32_t status;
+ nt_utf16_callback_args args;
+ ntapi_uc_utf16_callback_fn * callback_fn[5];
+
+ callback_fn[0] = (ntapi_uc_utf16_callback_fn *)__utf16_to_utf8_handler_1byte_or_null_termination;
+ callback_fn[1] = (ntapi_uc_utf16_callback_fn *)__utf16_to_utf8_handler_1byte_or_null_termination;
+ callback_fn[2] = (ntapi_uc_utf16_callback_fn *)__utf16_to_utf8_handler_2bytes;
+ callback_fn[3] = (ntapi_uc_utf16_callback_fn *)__utf16_to_utf8_handler_3bytes;
+ callback_fn[4] = (ntapi_uc_utf16_callback_fn *)__utf16_to_utf8_handler_4bytes;
+
+ args.src = params->src;
+ args.dst = params->dst;
+ args.dst_cap = (void *)((uintptr_t)(params->dst) + (params->dst_size_in_bytes));
+ args.bytes_written = params->bytes_written;
+
+ status = __ntapi_uc_validate_unicode_stream_utf16(
+ params->src,
+ params->src_size_in_bytes,
+ &params->code_points,
+ &params->addr_failed,
+ callback_fn,
+ &args);
+
+ params->bytes_written = args.bytes_written;
+
+ if (status)
+ status = __update_stream_leftover_info_utf16(params);
+
+ /* the following bit shift will be optimized out on 32-bit architectures */
+ params->leftover_bytes <<= (8 * (sizeof(uintptr_t) - sizeof(uint32_t)));
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_uc_convert_unicode_stream_utf16_to_utf32(
+ __in_out nt_unicode_conversion_params_utf16_to_utf32 * params)
+{
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/unicode/ntapi_uc_unicode_conversion_from_utf8.c b/src/unicode/ntapi_uc_unicode_conversion_from_utf8.c
new file mode 100644
index 0000000..02976ea
--- /dev/null
+++ b/src/unicode/ntapi_uc_unicode_conversion_from_utf8.c
@@ -0,0 +1,288 @@
+/********************************************************/
+/* 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/nt_status.h>
+#include <ntapi/nt_unicode.h>
+#include "ntapi_impl.h"
+
+
+typedef struct ___two_bytes {
+ unsigned char low;
+ unsigned char high;
+} __two_bytes;
+
+
+typedef struct ___three_bytes {
+ unsigned char low;
+ unsigned char middle;
+ unsigned char high;
+} __three_bytes;
+
+
+static int32_t __fastcall __utf8_to_utf16_handler_1byte_or_null_termination(nt_utf8_callback_args * args)
+{
+ /***************************/
+ /* from: 0xxxxxxx */
+ /* to: 00000000 0xxxxxxx */
+ /***************************/
+
+ wchar16_t * dst;
+
+ if (args->dst >= args->dst_cap)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ dst = (wchar16_t *)args->dst;
+ *dst = *(args->src);
+
+ /* advance source and destination buffer */
+ args->src++;
+ args->dst = (void *)((uintptr_t)(args->dst) + sizeof(wchar16_t));
+
+ /* bytes_written */
+ args->bytes_written += sizeof(wchar16_t);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __utf8_to_utf16_handler_2bytes(nt_utf8_callback_args * args)
+{
+ /***************************/
+ /* from: 110yyyyy 10xxxxxx */
+ /* to: 00000yyy yyxxxxxx */
+ /***************************/
+
+ __two_bytes * src; /* big endian */
+ wchar16_t * dst;
+
+ if (args->dst >= args->dst_cap)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ src = (__two_bytes *)args->src;
+ dst = (wchar16_t *)args->dst;
+
+ /* yyyyy */
+ *dst = (src->low ^ 0xC0);
+ *dst <<= 6;
+
+ /* xxxxxx */
+ *dst |= (src->high ^ 0x80);
+
+ /* advance source and destination buffer */
+ args->src += 2;
+ args->dst = (void *)((uintptr_t)(args->dst) + sizeof(wchar16_t));
+
+ /* bytes_written */
+ args->bytes_written += sizeof(wchar16_t);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __utf8_to_utf16_handler_3bytes(nt_utf8_callback_args * args)
+{
+ /************************************/
+ /* from: 1110zzzz 10yyyyyy 10xxxxxx */
+ /* to: zzzzyyyy yyxxxxxx */
+ /************************************/
+
+ __three_bytes * src; /* big endian */
+ wchar16_t * dst;
+ wchar16_t yyyyy;
+
+ if (args->dst >= args->dst_cap)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ src = (__three_bytes *)args->src;
+ dst = (wchar16_t *)args->dst;
+
+ /* zzzz */
+ *dst = (src->low ^ 0xE0);
+ *dst <<= 12;
+
+ /* yyyyy */
+ yyyyy = (src->middle ^ 0x80);
+ yyyyy <<= 6;
+ *dst |= yyyyy;
+
+ /* xxxxxx */
+ *dst |= (src->high ^ 0x80);
+
+ /* advance source and destination buffer */
+ args->src += 3;
+ args->dst = (void *)((uintptr_t)(args->dst) + sizeof(wchar16_t));
+
+ /* bytes_written */
+ args->bytes_written += sizeof(wchar16_t);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __utf8_to_utf16_handler_4bytes(nt_utf8_callback_args * args)
+{
+ /*************************************************/
+ /* from: 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx */
+ /* to: 110110ww wwzzzzyy 110111yy yyxxxxxx */
+ /*************************************************/
+
+ __two_bytes * src_low; /* big endian */
+ __two_bytes * src_high; /* big endian */
+ wchar16_t * dst_lead;
+ wchar16_t * dst_trail;
+
+ wchar16_t u;
+ unsigned char ulow;
+ unsigned char uhigh;
+ unsigned char yyyy;
+
+ dst_lead = dst_trail = (wchar16_t *)args->dst;
+ dst_trail++;
+
+ if ((uintptr_t)dst_trail >= (uintptr_t)args->dst_cap)
+ return NT_STATUS_BUFFER_TOO_SMALL;
+
+ src_low = src_high = (__two_bytes *)args->src;
+ src_high++;
+
+ /* u */
+ ulow = src_low->low ^ 0xF0;
+ uhigh = src_low->high ^ 0x80;
+
+ ulow <<= 2;
+ uhigh >>= 4;
+
+ u = ulow | uhigh;
+
+ /* 110110ww wwzzzzyy */
+ *dst_lead = 0xD800;
+ *dst_lead |= ((u-1) << 6);
+ *dst_lead |= ((src_low->high ^ 0x80) << 2);
+ *dst_lead |= ((src_high->low ^ 0x80) >> 4);
+
+ /* 110111yy yyxxxxxx */
+ yyyy = (src_high->low << 4);
+ *dst_trail = yyyy;
+ *dst_trail <<= 2;
+ *dst_trail |= (src_high->high ^ 0x80);
+ *dst_trail |= 0xDC00;
+
+ /* advance source and destination buffer */
+ args->src += 4;
+ args->dst = (void *)((uintptr_t)(args->dst) + (2 * sizeof(wchar16_t)));
+
+ /* bytes_written */
+ args->bytes_written += 2 * sizeof(wchar16_t);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __update_stream_leftover_info_utf8(
+ __in_out nt_unicode_conversion_params_utf8_to_utf16 * params)
+{
+ int32_t status;
+ ptrdiff_t offset;
+ unsigned char * utf8;
+
+ offset = (uintptr_t)params->src + (uintptr_t)params->src_size_in_bytes - (uintptr_t)params->addr_failed;
+ utf8 = (unsigned char *)params->addr_failed;
+
+ /* default status */
+ status = NT_STATUS_ILLEGAL_CHARACTER;
+
+ if (offset == 1) {
+ if ((utf8[0] >= 0xC2) && (utf8[0] <= 0xF4)) {
+ /* one leftover byte */
+ params->leftover_count = 1;
+ params->leftover_bytes = utf8[0];
+ params->leftover_bytes <<= 24;
+ status = NT_STATUS_SUCCESS;
+ }
+ } else if (offset == 2) {
+ if /* ------- */ (((utf8[0] == 0xE0) && (utf8[1] >= 0xA0) && (utf8[1] <= 0xBF))
+ || ((utf8[0] >= 0xE1) && (utf8[0] <= 0xEC) && (utf8[1] >= 0x80) && (utf8[1] <= 0xBF))
+ || ((utf8[0] == 0xED) && (utf8[1] >= 0x80) && (utf8[1] <= 0x9F))
+ || ((utf8[0] >= 0xEE) && (utf8[0] <= 0xEF) && (utf8[1] >= 0x80) && (utf8[1] <= 0xBF))
+ || ((utf8[0] == 0xF0) && (utf8[1] >= 0x90) && (utf8[1] <= 0xBF))
+ || ((utf8[0] >= 0xF1) && (utf8[0] <= 0xF3) && (utf8[1] >= 0x80) && (utf8[1] <= 0xBF))
+ || ((utf8[0] == 0xF4) && (utf8[1] >= 0x80) && (utf8[1] <= 0x8F))) {
+ /* two leftover bytes */
+ params->leftover_count = 2;
+ params->leftover_bytes = utf8[0];
+ params->leftover_bytes <<= 8;
+ params->leftover_bytes += utf8[1];
+ params->leftover_bytes <<= 16;
+ status = NT_STATUS_SUCCESS;
+ }
+ } else if (offset == 3) {
+ if /* ------- */ (((utf8[0] == 0xF0) && (utf8[1] >= 0x90) && (utf8[1] <= 0xBF))
+ || ((utf8[0] >= 0xF1) && (utf8[0] <= 0xF3) && (utf8[1] >= 0x80) && (utf8[1] <= 0xBF))
+ || ((utf8[0] == 0xF4) && (utf8[1] >= 0x80) && (utf8[1] <= 0x8F))) {
+ /* three leftover bytes */
+ params->leftover_count = 3;
+ params->leftover_bytes = utf8[0];
+ params->leftover_bytes <<= 8;
+ params->leftover_bytes += utf8[1];
+ params->leftover_bytes <<= 8;
+ params->leftover_bytes += utf8[2];
+ params->leftover_bytes <<= 8;
+ status = NT_STATUS_SUCCESS;
+ }
+ }
+
+ if (status != NT_STATUS_SUCCESS) {
+ params->leftover_count = 0;
+ params->leftover_bytes = 0;
+ }
+
+ return status;
+}
+
+int32_t __stdcall __ntapi_uc_convert_unicode_stream_utf8_to_utf16(
+ __in_out nt_unicode_conversion_params_utf8_to_utf16 * params)
+{
+ int32_t status;
+ nt_utf8_callback_args args;
+ ntapi_uc_utf8_callback_fn * callback_fn[5];
+
+ callback_fn[0] = (ntapi_uc_utf8_callback_fn *)__utf8_to_utf16_handler_1byte_or_null_termination;
+ callback_fn[1] = (ntapi_uc_utf8_callback_fn *)__utf8_to_utf16_handler_1byte_or_null_termination;
+ callback_fn[2] = (ntapi_uc_utf8_callback_fn *)__utf8_to_utf16_handler_2bytes;
+ callback_fn[3] = (ntapi_uc_utf8_callback_fn *)__utf8_to_utf16_handler_3bytes;
+ callback_fn[4] = (ntapi_uc_utf8_callback_fn *)__utf8_to_utf16_handler_4bytes;
+
+ args.src = params->src;
+ args.dst = params->dst;
+ args.dst_cap = (void *)((uintptr_t)(params->dst) + (params->dst_size_in_bytes));
+ args.bytes_written = params->bytes_written;
+
+ status = __ntapi_uc_validate_unicode_stream_utf8(
+ params->src,
+ params->src_size_in_bytes,
+ &params->code_points,
+ &params->addr_failed,
+ callback_fn,
+ &args);
+
+ params->bytes_written = args.bytes_written;
+
+ if (status != NT_STATUS_SUCCESS)
+ status = __update_stream_leftover_info_utf8(params);
+
+ /* (optimized out on 32-bit architectures) */
+ params->leftover_bytes <<= (8 * (sizeof(uintptr_t) - sizeof(uint32_t)));
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_uc_convert_unicode_stream_utf8_to_utf32(
+ __in_out nt_unicode_conversion_params_utf8_to_utf32 * params)
+{
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/unicode/ntapi_uc_unicode_validation.c b/src/unicode/ntapi_uc_unicode_validation.c
new file mode 100644
index 0000000..4c6fcac
--- /dev/null
+++ b/src/unicode/ntapi_uc_unicode_validation.c
@@ -0,0 +1,329 @@
+/********************************************************/
+/* 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/nt_status.h>
+#include <ntapi/nt_unicode.h>
+
+/**
+ * unofficial bit distribution table for comprehension purposes only
+ *
+ * scalar nickname utf-16 utf-8[0] utf-8[1] utf-8[2] utf-8[3]
+ * ------ -------- -------- -------- -------- -------- --------
+ * 00000000 7x 00000000 0xxxxxxx
+ * 0xxxxxxx 0xxxxxxx
+ *
+ * 00000yyy 5y6x 00000yyy 110yyyyy 10xxxxxx
+ * yyxxxxxx yyxxxxxx
+ *
+ * zzzzyyyy 4z6y6x zzzzyyyy 1110zzzz 10yyyyyy 10xxxxxx
+ * yyxxxxxx yyxxxxxx
+ *
+ * 000uuuuu 5u4z6y6x 110110ww 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
+ * zzzzyyyy wwzzzzyy
+ * yyxxxxxx 110111yy
+ * yyxxxxxx (where wwww = uuuuu - 1)
+ *
+ *
+ * validation of utf-8
+ *
+ * from to utf-8[0] utf-8[1] utf-8[2] utf-8[3]
+ * ------ ------ -------- -------- -------- --------
+ * 0x0000 0x007F 00..7F
+ * 0x0080 0x07FF C2..DF 80..BF
+ * 0x0800 0x0FFF E0 A0..BF 80..BF
+ * 0x1000 0xCFFF E1..EC 80..BF 80..BF
+ * 0xD000 0xD7FF ED 80..9F 80..BF
+ * 0xE000 0xFFFF EE..EF 80..BF 80..BF
+ * 0x10000 0x3FFFF F0 90..BF 80..BF 80..BF
+ * 0x40000 0xFFFFF F1..F3 80..BF 80..BF 80..BF
+ * 0x100000 0x10FFFF F4 80..8F 80..BF 80..BF
+ *
+**/
+
+
+#define __AVAILABLE_CODE_POINTS 0x110000
+
+int __stdcall __ntapi_uc_get_code_point_byte_count_utf8(uint32_t code_point)
+{
+ /* try clearing 7x bits */
+ if ((code_point >> 7) == 0)
+ return 1;
+
+ /* try clearing 5y + 6x bits */
+ else if ((code_point >> 11) == 0)
+ return 2;
+
+ /* try clearing 4z +6y + 6x bits */
+ else if ((code_point >> 16) == 0)
+ return 3;
+
+ /* try clearing 5u + 4z + 6y + 6x bits */
+ else if ((code_point >> 21) == 0)
+ return 4;
+
+ /* __AVAILABLE_CODE_POINTS exceeded */
+ else
+ return 0;
+}
+
+
+int __stdcall __ntapi_uc_get_code_point_byte_count_utf16(uint32_t code_point)
+{
+ /* try clearing 4z +6y + 6x bits */
+ if ((code_point >> 16) == 0)
+ return 2;
+
+ /* try clearing 5u + 4z + 6y + 6x bits */
+ else if ((code_point >> 21) == 0)
+ return 4;
+
+ /* __AVAILABLE_CODE_POINTS exceeded */
+ else
+ return 0;
+}
+
+
+/**
+ * following is a straight-forward implementation
+ * of unicode conversion and validation (see also:
+ * Table 3-7 of the Unicode Standard, version 6.2).
+ *
+ * the use of callbacks allows the validation
+ * functions to be the basis of our utf-8 conversion
+ * functions on the one hand, and the posix path arg
+ * normalization routine on the other.
+**/
+
+static int32_t __fastcall __default_callback_fn_utf8(nt_utf8_callback_args * args)
+{
+ args->src += args->byte_count;
+ return NT_STATUS_SUCCESS;
+}
+
+int32_t __stdcall __ntapi_uc_validate_unicode_stream_utf8(
+ __in const unsigned char * ch,
+ __in size_t size_in_bytes __optional,
+ __out size_t * code_points __optional,
+ __out void ** addr_failed __optional,
+ __in ntapi_uc_utf8_callback_fn ** callback_fn __optional,
+ __in nt_utf8_callback_args * callback_args __optional)
+{
+ const unsigned char * utf8;
+ unsigned char * ch_boundary;
+ unsigned char byte_count;
+ size_t _code_points;
+
+ ntapi_uc_utf8_callback_fn * _callback_fn[5];
+ nt_utf8_callback_args _callback_args;
+
+ if (!callback_fn) {
+ _callback_fn[0] = __default_callback_fn_utf8;
+ _callback_fn[1] = __default_callback_fn_utf8;
+ _callback_fn[2] = __default_callback_fn_utf8;
+ _callback_fn[3] = __default_callback_fn_utf8;
+ _callback_fn[4] = __default_callback_fn_utf8;
+ callback_fn = (ntapi_uc_utf8_callback_fn **)&_callback_fn;
+ }
+
+ if (!callback_args) {
+ callback_args = &_callback_args;
+ callback_args->src = (unsigned char *)0;
+ }
+
+ if (callback_args->src)
+ ch = callback_args->src;
+ else
+ callback_args->src = ch;
+
+ if (size_in_bytes)
+ ch_boundary = (unsigned char *)((uintptr_t)ch + size_in_bytes);
+ else
+ ch_boundary = (unsigned char *)(~0);
+
+ if (!code_points)
+ code_points = &_code_points;
+
+ while ((ch < ch_boundary) && (*ch)) {
+ utf8 = ch;
+ byte_count = 0;
+
+ /* try one byte */
+ if (utf8[0] <= 0x7F)
+ byte_count = 1;
+
+ /* try two bytes */
+ else if ((++ch < ch_boundary)
+ && (utf8[0] >= 0xC2) && (utf8[0] <= 0xDF)
+ && (utf8[1] >= 0x80) && (utf8[1] <= 0xBF))
+ byte_count = 2;
+
+ /* try three bytes */
+ else if ((++ch < ch_boundary)
+ && (utf8[0] == 0xE0)
+ && (utf8[1] >= 0xA0) && (utf8[1] <= 0xBF)
+ && (utf8[2] >= 0x80) && (utf8[2] <= 0xBF))
+ byte_count = 3;
+
+ else if (
+ (utf8[0] >= 0xE1) && (utf8[0] <= 0xEC)
+ && (utf8[1] >= 0x80) && (utf8[1] <= 0xBF)
+ && (utf8[2] >= 0x80) && (utf8[2] <= 0xBF))
+ byte_count = 3;
+
+ else if (
+ (utf8[0] == 0xED)
+ && (utf8[1] >= 0x80) && (utf8[1] <= 0x9F)
+ && (utf8[2] >= 0x80) && (utf8[2] <= 0xBF))
+ byte_count = 3;
+
+ else if (
+ (utf8[0] >= 0xEE) && (utf8[0] <= 0xEF)
+ && (utf8[1] >= 0x80) && (utf8[1] <= 0xBF)
+ && (utf8[2] >= 0x80) && (utf8[2] <= 0xBF))
+ byte_count = 3;
+
+ /* try four bytes */
+ else if ((++ch < ch_boundary)
+ && (utf8[0] == 0xF0)
+ && (utf8[1] >= 0x90) && (utf8[1] <= 0xBF)
+ && (utf8[2] >= 0x80) && (utf8[2] <= 0xBF)
+ && (utf8[3] >= 0x80) && (utf8[3] <= 0xBF))
+ byte_count = 4;
+
+ else if (
+ (utf8[0] >= 0xF1) && (utf8[0] <= 0xF3)
+ && (utf8[1] >= 0x80) && (utf8[1] <= 0xBF)
+ && (utf8[2] >= 0x80) && (utf8[2] <= 0xBF)
+ && (utf8[3] >= 0x80) && (utf8[3] <= 0xBF))
+ byte_count = 4;
+
+ else if (
+ (utf8[0] == 0xF4)
+ && (utf8[1] >= 0x80) && (utf8[1] <= 0x8F)
+ && (utf8[2] >= 0x80) && (utf8[2] <= 0xBF)
+ && (utf8[3] >= 0x80) && (utf8[3] <= 0xBF))
+ byte_count = 4;
+
+ if (byte_count) {
+ (*code_points)++;
+ callback_args->byte_count = byte_count;
+ callback_fn[byte_count](callback_args);
+ } else {
+ if (addr_failed)
+ *addr_failed = (void *)utf8;
+ return NT_STATUS_ILLEGAL_CHARACTER;
+ }
+
+ /* advance, transcode if needed */
+ ch = callback_args->src;
+ }
+
+ if ((ch < ch_boundary) && (*ch == 0))
+ callback_fn[0](callback_args);
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+static int32_t __fastcall __default_callback_fn_utf16(nt_utf16_callback_args * args)
+{
+ if (args->byte_count == 4)
+ args->src += 2;
+ else
+ args->src++;
+
+ return NT_STATUS_SUCCESS;
+}
+
+
+int32_t __stdcall __ntapi_uc_validate_unicode_stream_utf16(
+ __in const wchar16_t * wch,
+ __in size_t size_in_bytes __optional,
+ __out size_t * code_points __optional,
+ __out void ** addr_failed __optional,
+ __in ntapi_uc_utf16_callback_fn ** callback_fn __optional,
+ __in nt_utf16_callback_args * callback_args __optional)
+{
+ const wchar16_t * wch_trail;
+ wchar16_t * wch_boundary;
+ unsigned char byte_count;
+ size_t _code_points;
+
+ ntapi_uc_utf16_callback_fn * _callback_fn[5];
+ nt_utf16_callback_args _callback_args;
+
+ if (!callback_fn) {
+ _callback_fn[0] = __default_callback_fn_utf16;
+ _callback_fn[1] = __default_callback_fn_utf16;
+ _callback_fn[2] = __default_callback_fn_utf16;
+ _callback_fn[3] = __default_callback_fn_utf16;
+ _callback_fn[4] = __default_callback_fn_utf16;
+ callback_fn = (ntapi_uc_utf16_callback_fn **)&_callback_fn;
+ }
+
+ if (!callback_args) {
+ callback_args = &_callback_args;
+ callback_args->src = (wchar16_t *)0;
+ }
+
+ if (callback_args->src)
+ wch = callback_args->src;
+ else
+ callback_args->src = wch;
+
+ if (size_in_bytes)
+ wch_boundary = (wchar16_t *)((uintptr_t)wch + size_in_bytes);
+ else
+ wch_boundary = (wchar16_t *)(~0);
+
+ if (!code_points)
+ code_points = &_code_points;
+
+ while ((wch < wch_boundary) && (*wch)) {
+ byte_count = 0;
+
+ /* try one byte */
+ if (*wch <= 0x7F)
+ byte_count = 1;
+
+ /* try two bytes */
+ else if (*wch <= 0x7FF)
+ byte_count = 2;
+
+ /* try three bytes */
+ else if ((*wch < 0xD800) || (*wch >= 0xE000))
+ byte_count = 3;
+
+ /* try four bytes */
+ else if ((*wch >= 0xD800) && (*wch < 0xDC00)) {
+ wch_trail = wch + 1;
+
+ if ((wch_trail < wch_boundary)
+ && (*wch_trail >= 0xDC00)
+ && (*wch_trail < 0xE000))
+ byte_count = 4;
+ }
+
+ if (byte_count) {
+ (*code_points)++;
+ callback_args->byte_count = byte_count;
+ callback_fn[byte_count](callback_args);
+ } else {
+ if (addr_failed)
+ *addr_failed = (void *)wch;
+ return NT_STATUS_ILLEGAL_CHARACTER;
+ }
+
+ /* advance, transcode as needed */
+ wch = callback_args->src;
+ }
+
+ if ((wch < wch_boundary) && (*wch == 0))
+ callback_fn[0](callback_args);
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/vfd/ntapi_vfd_helper.c b/src/vfd/ntapi_vfd_helper.c
new file mode 100644
index 0000000..054a388
--- /dev/null
+++ b/src/vfd/ntapi_vfd_helper.c
@@ -0,0 +1,34 @@
+/********************************************************/
+/* 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/nt_status.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_vfd.h>
+#include "ntapi_impl.h"
+
+void __stdcall __ntapi_vfd_dev_name_init(
+ __out nt_vfd_dev_name * devname,
+ __in const nt_guid * guid)
+{
+ uint32_t * prefix = (uint32_t *)devname->prefix;
+
+ /* compiler-independent */
+ prefix[0] = 0x44005C;
+ prefix[1] = 0x760065;
+ prefix[2] = 0x630069;
+ prefix[3] = 0x5C0065;
+
+ __ntapi->tt_guid_to_utf16_string(
+ guid,
+ &devname->guid);
+
+ devname->name.strlen = sizeof(devname->prefix) + sizeof(devname->guid);
+ devname->name.maxlen = 0;
+ devname->name.buffer = (uint16_t *)&devname->prefix;
+
+ return;
+}
diff --git a/src/vmount/ntapi_vms_cache.c b/src/vmount/ntapi_vms_cache.c
new file mode 100644
index 0000000..97fe32f
--- /dev/null
+++ b/src/vmount/ntapi_vms_cache.c
@@ -0,0 +1,209 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+typedef struct nt_vms_cache_interface {
+ nt_vms_system * vms_sys;
+ struct dalist_ex cache;
+ size_t alloc_size;
+ uintptr_t buffer[1];
+} nt_vms_cache_context;
+
+
+typedef struct _nt_vms_cache_record {
+ void * hfile;
+ uint32_t dev_name_hash;
+ nt_large_integer index_number;
+ intptr_t client_key;
+ intptr_t server_key;
+} nt_vms_cache_record;
+
+
+int32_t __stdcall __ntapi_vms_cache_free(
+ __in nt_vms_cache vms_cache)
+{
+ int32_t status;
+ void * region_addr;
+ size_t region_size;
+
+ /* validation */
+ if (!vms_cache)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* free memory */
+ region_addr = vms_cache;
+ region_size = vms_cache->alloc_size;
+
+ status = __ntapi->zw_free_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &region_addr,
+ &region_size,
+ NT_MEM_RELEASE);
+
+ return status;
+}
+
+/* vms optional cache functions */
+nt_vms_cache __stdcall __ntapi_vms_cache_alloc(
+ __in nt_vms_system * vms_sys,
+ __in uint32_t flags __reserved,
+ __in void * options __reserved,
+ __out int32_t * status __optional)
+{
+ int32_t _status;
+ void * buffer;
+ size_t buffer_size;
+ nt_vms_cache_context * vms_cache;
+
+ /* status */
+ if (!status) status = &_status;
+
+ /* validation */
+ if (!vms_sys) {
+ *status = NT_STATUS_INVALID_PARAMETER;
+ return (nt_vms_cache)0;
+ }
+
+ /* calculate size */
+ buffer_size = sizeof(nt_vms_cache_context);
+ buffer_size += vms_sys->vms_points_cap * (sizeof(nt_vms_cache_record) - sizeof(uintptr_t));
+
+ /* allocate buffer */
+ *status = __ntapi->zw_allocate_virtual_memory(
+ NT_CURRENT_PROCESS_HANDLE,
+ &buffer,
+ 0,
+ &buffer_size,
+ NT_MEM_COMMIT,
+ NT_PAGE_READWRITE);
+
+ if (*status) return (nt_vms_cache)0;
+
+ /* init vms cache */
+ vms_cache = (nt_vms_cache_context *)buffer;
+ vms_cache->vms_sys = vms_sys;
+ vms_cache->alloc_size = buffer_size;
+
+ /* init list */
+ *status = dalist_init_ex(
+ &vms_cache->cache,
+ sizeof(nt_vms_cache_record),
+ 0x1000,
+ __ntapi->zw_allocate_virtual_memory,
+ DALIST_MEMFN_NT_ALLOCATE_VIRTUAL_MEMORY);
+
+ if (*status != DALIST_OK) {
+ *status = NT_STATUS_UNSUCCESSFUL;
+ __ntapi_vms_cache_free(vms_cache);
+ return (nt_vms_cache)0;
+ }
+
+ /* set list buffer */
+ buffer_size -= (size_t)&(((nt_vms_cache_context *)0)->buffer);
+
+ *status = dalist_deposit_memory_block(
+ &vms_cache->cache,
+ &vms_cache->buffer,
+ buffer_size);
+
+ return vms_cache;
+}
+
+
+int32_t __stdcall __ntapi_vms_cache_record_append(
+ __in nt_vms_cache cache,
+ __in void * hfile,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number,
+ __in intptr_t client_key,
+ __in intptr_t server_key)
+{
+ int32_t status;
+ struct dalist_node_ex * node;
+ nt_vms_cache_record * cache_record;
+
+ status = dalist_get_node_by_key(
+ &cache->cache,
+ &node,
+ (uintptr_t)hfile,
+ DALIST_NODE_TYPE_EXISTING,
+ (uintptr_t *)0);
+
+ if (status != DALIST_OK)
+ status = NT_STATUS_INTERNAL_ERROR;
+ else if (node)
+ status = NT_STATUS_OBJECTID_EXISTS;
+ else {
+ status = dalist_get_free_node(&cache->cache,(void **)&node);
+
+ if (status == DALIST_OK) {
+ cache_record = (nt_vms_cache_record *)&node->dblock;
+
+ __ntapi->tt_aligned_block_memset(
+ node,
+ 0,
+ (uintptr_t)&((struct dalist_node_ex *)0)->dblock + sizeof(*cache_record));
+
+ node->key = (uintptr_t)hfile;
+
+ cache_record->hfile = hfile;
+ cache_record->dev_name_hash = dev_name_hash;
+ cache_record->index_number.quad = index_number.quad;
+ cache_record->client_key = client_key;
+ cache_record->server_key = server_key;
+
+ status = dalist_insert_node_by_key(
+ &cache->cache,
+ node);
+
+ if (status != DALIST_OK)
+ dalist_deposit_free_node(
+ &cache->cache,
+ node);
+ }
+ }
+
+ return status;
+}
+
+
+int32_t __stdcall __ntapi_vms_cache_record_remove(
+ __in nt_vms_cache cache,
+ __in void * hfile,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number)
+{
+ int32_t status;
+ struct dalist_node_ex * node;
+
+ status = dalist_get_node_by_key(
+ &cache->cache,
+ &node,
+ (uintptr_t)hfile,
+ DALIST_NODE_TYPE_EXISTING,
+ (uintptr_t *)0);
+
+ if (status != DALIST_OK)
+ status = NT_STATUS_INTERNAL_ERROR;
+ else if (node)
+ status = NT_STATUS_INVALID_PARAMETER;
+ else {
+ status = dalist_discard_node(
+ &cache->cache,
+ node);
+
+ if (status != DALIST_OK)
+ status = NT_STATUS_INTERNAL_ERROR;
+ }
+
+ return status;
+}
diff --git a/src/vmount/ntapi_vms_client_connect.c b/src/vmount/ntapi_vms_client_connect.c
new file mode 100644
index 0000000..364d4d1
--- /dev/null
+++ b/src/vmount/ntapi_vms_client_connect.c
@@ -0,0 +1,86 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_tty.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+static void __vms_port_name_from_server_info(
+ __out nt_port_name * vms_port_name,
+ __in nt_tty_vms_info * vmsinfo)
+{
+ nt_port_attr port_attr;
+
+ port_attr.type = NT_PORT_TYPE_VMOUNT;
+ port_attr.subtype = NT_PORT_SUBTYPE_DEFAULT;
+
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)&port_attr.keys,
+ (uintptr_t *)&vmsinfo->vms_keys,
+ sizeof(nt_port_keys));
+
+ __ntapi->tt_port_guid_from_type(
+ &port_attr.guid,
+ port_attr.type,
+ port_attr.subtype);
+
+ __ntapi->tt_port_name_from_attributes(
+ vms_port_name,
+ &port_attr);
+}
+
+
+int32_t __stdcall __ntapi_vms_client_connect(
+ __out void ** hvms,
+ __in nt_tty_vms_info * vmsinfo)
+{
+ int32_t status;
+ nt_port_name vms_port_name;
+
+ nt_unicode_string name;
+ nt_sqos sqos;
+ nt_oa oa;
+
+ /* vmount daemon port name */
+ __vms_port_name_from_server_info(
+ &vms_port_name,
+ vmsinfo);
+
+ /* port name init */
+ name.buffer = (wchar16_t *)&vms_port_name;
+ name.maxlen = 0;
+ name.strlen = (uint16_t)(size_t)(&((nt_port_name *)0)->null_termination);
+
+ /* init security structure */
+ sqos.length = sizeof(sqos);
+ sqos.impersonation_level = NT_SECURITY_IMPERSONATION;
+ sqos.context_tracking_mode = NT_SECURITY_TRACKING_DYNAMIC;
+ sqos.effective_only = 1;
+
+ /* init the port's object attributes */
+ oa.len = sizeof(oa);
+ oa.root_dir = (void *)0;
+ oa.obj_name = &name;
+ oa.obj_attr = 0;
+ oa.sec_desc = (nt_security_descriptor *)0;
+ oa.sec_qos = &sqos;
+
+ status = __ntapi->zw_connect_port(
+ hvms,
+ &name,
+ &sqos,
+ (nt_port_section_write *)0,
+ (nt_port_section_read *)0,
+ (uint32_t *)0,
+ (void *)0,
+ (uint32_t *)0);
+
+ return status;
+}
diff --git a/src/vmount/ntapi_vms_client_disconnect.c b/src/vmount/ntapi_vms_client_disconnect.c
new file mode 100644
index 0000000..b7d528c
--- /dev/null
+++ b/src/vmount/ntapi_vms_client_disconnect.c
@@ -0,0 +1,37 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+int32_t __stdcall __ntapi_vms_client_disconnect(
+ __in void * hvms)
+{
+ nt_vms_daemon_msg msg;
+
+ if (!hvms) return NT_STATUS_INVALID_HANDLE;
+
+ /* msg */
+ __ntapi->tt_aligned_block_memset(&msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.msginfo.opcode = NT_VMS_CLIENT_DISCONNECT;
+
+ /* zw_request_wait_reply_port */
+ __ntapi->zw_request_wait_reply_port(
+ hvms,
+ &msg,
+ &msg);
+
+ /* close client handle */
+ return __ntapi->zw_close(hvms);
+}
diff --git a/src/vmount/ntapi_vms_helper.c b/src/vmount/ntapi_vms_helper.c
new file mode 100644
index 0000000..4134112
--- /dev/null
+++ b/src/vmount/ntapi_vms_helper.c
@@ -0,0 +1,118 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+nt_vms_node * __stdcall __ntapi_vms_get_end_component_first_node(
+ __in nt_vms_system * pvms_sys,
+ __in uint32_t end_component_hash)
+{
+ nt_vms_node * node;
+
+ /* verify non-empty list and valid input */
+ if (!pvms_sys->dev_name_head_node || !end_component_hash)
+ return (nt_vms_node *)0;
+
+ /* find first node by end component hash */
+ node = (nt_vms_node *)((uintptr_t)pvms_sys + pvms_sys->end_component_head_node);
+
+ while (node->next && (node->end_component_hash < end_component_hash))
+ node = (nt_vms_node *)((uintptr_t)pvms_sys + node->next);
+
+ if (node->end_component_hash == end_component_hash)
+ return node;
+ else
+ return (nt_vms_node *)0;
+}
+
+
+static nt_vms_node * __stdcall __ntapi_vms_get_node(
+ __in nt_vms_system * pvms_sys,
+ __in uint32_t end_component_hash,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number)
+{
+ nt_vms_node * node;
+
+ /* verify non-empty list */
+ if (!pvms_sys->dev_name_head_node)
+ return (nt_vms_node *)0;
+
+ /* end_component_hash */
+ if (end_component_hash) {
+ node = (nt_vms_node *)((uintptr_t)pvms_sys + pvms_sys->end_component_head_node);
+
+ while (node->next && (node->end_component_hash < end_component_hash))
+ node = (nt_vms_node *)((uintptr_t)pvms_sys + node->next);
+
+ if (node->end_component_hash != end_component_hash)
+ return (nt_vms_node *)0;
+ } else
+ node = (nt_vms_node *)((uintptr_t)pvms_sys + pvms_sys->dev_name_head_node);
+
+ /* find device nodes */
+ while (node->next && (node->dev_name_hash < dev_name_hash))
+ node = (nt_vms_node *)((uintptr_t)pvms_sys + node->next);
+
+ if (node->dev_name_hash != dev_name_hash)
+ return (nt_vms_node *)0;
+
+ /* find mount-point nodes */
+ while (node->next && (node->index_number.quad < index_number.quad))
+ node = (nt_vms_node *)((uintptr_t)pvms_sys + node->next);
+
+ if (node->index_number.quad != index_number.quad)
+ return (nt_vms_node *)0;
+
+ return node;
+}
+
+
+nt_vms_node * __stdcall __ntapi_vms_get_node_by_dev_name(
+ __in nt_vms_system * pvms_sys,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number)
+{
+ return __ntapi_vms_get_node(
+ pvms_sys,
+ 0,
+ dev_name_hash,
+ index_number);
+}
+
+
+nt_vms_node * __stdcall __ntapi_vms_get_node_by_end_component(
+ __in nt_vms_system * pvms_sys,
+ __in uint32_t end_component_hash,
+ __in uint32_t dev_name_hash,
+ __in nt_large_integer index_number)
+{
+ return __ntapi_vms_get_node(
+ pvms_sys,
+ end_component_hash,
+ dev_name_hash,
+ index_number);
+}
+
+
+nt_vms_point * __stdcall __ntapi_vms_get_top_of_stack_mount_point(
+ __in nt_vms_system * pvms_sys,
+ __in nt_vms_node * node)
+{
+ nt_vms_point * point;
+
+ point = (nt_vms_point *)((uintptr_t)pvms_sys + node->stack);
+
+ while (point->next)
+ point = (nt_vms_point *)((uintptr_t)pvms_sys + point->next);
+
+ return point;
+}
diff --git a/src/vmount/ntapi_vms_point_attach.c b/src/vmount/ntapi_vms_point_attach.c
new file mode 100644
index 0000000..a4c5c7e
--- /dev/null
+++ b/src/vmount/ntapi_vms_point_attach.c
@@ -0,0 +1,52 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+static int32_t __stdcall __ntapi_vms_point_attach_detach(
+ __in void * hvms,
+ __in nt_vms_point_info * point_info,
+ __in int32_t vms_opcode)
+{
+ int32_t status;
+ nt_vms_daemon_msg msg;
+
+ /* msg */
+ __ntapi->tt_aligned_block_memset(&msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.msginfo.opcode = vms_opcode;
+
+ /* copy point to msg */
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)&(msg.data.pointinfo),
+ (uintptr_t *)point_info,
+ sizeof(*point_info));
+
+ /* zw_request_wait_reply_port */
+ status = __ntapi->zw_request_wait_reply_port(hvms,&msg,&msg);
+
+ /* return vms status */
+ return status ? status : msg.data.msginfo.status;
+}
+
+
+int32_t __stdcall __ntapi_vms_point_attach(
+ __in void * hvms,
+ __in nt_vms_point_info * point_info)
+{
+ return __ntapi_vms_point_attach_detach(
+ hvms,
+ point_info,
+ NT_VMS_POINT_ATTACH);
+}
diff --git a/src/vmount/ntapi_vms_ref_count.c b/src/vmount/ntapi_vms_ref_count.c
new file mode 100644
index 0000000..3be149f
--- /dev/null
+++ b/src/vmount/ntapi_vms_ref_count.c
@@ -0,0 +1,96 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+static int32_t __stdcall __ntapi_vms_ref_count_inc_dec(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info,
+ __in int32_t vms_opcode)
+{
+ int32_t status;
+ nt_vms_daemon_msg msg;
+
+ /* msg */
+ __ntapi->tt_aligned_block_memset(&msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.msginfo.opcode = vms_opcode;
+
+ /* copy ref count info to msg */
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)&(msg.data.refcntinfo),
+ (uintptr_t *)ref_cnt_info,
+ sizeof(*ref_cnt_info));
+
+ /* zw_request_wait_reply_port */
+ status = __ntapi->zw_request_wait_reply_port(
+ hvms,
+ &msg,
+ &msg);
+
+ if (status) return status;
+
+ /* return info */
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)ref_cnt_info,
+ (uintptr_t *)&(msg.data.refcntinfo),
+ sizeof(*ref_cnt_info));
+
+ /* return vms status */
+ return status ? status : msg.data.msginfo.status;
+}
+
+
+int32_t __stdcall __ntapi_vms_ref_count_inc(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info)
+{
+ return __ntapi_vms_ref_count_inc_dec(
+ hvms,
+ ref_cnt_info,
+ NT_VMS_REF_COUNT_INC);
+}
+
+
+int32_t __stdcall __ntapi_vms_ref_count_dec(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info)
+{
+ return __ntapi_vms_ref_count_inc_dec(
+ hvms,
+ ref_cnt_info,
+ NT_VMS_REF_COUNT_DEC);
+}
+
+
+int32_t __stdcall __ntapi_vms_point_detach(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info)
+{
+ return __ntapi_vms_ref_count_inc_dec(
+ hvms,
+ ref_cnt_info,
+ NT_VMS_POINT_DETACH);
+}
+
+
+int32_t __stdcall __ntapi_vms_point_get_handles(
+ __in void * hvms,
+ __in nt_vms_ref_count_info * ref_cnt_info)
+{
+ return __ntapi_vms_ref_count_inc_dec(
+ hvms,
+ ref_cnt_info,
+ NT_VMS_POINT_GET_HANDLES);
+}
diff --git a/src/vmount/ntapi_vms_table_query.c b/src/vmount/ntapi_vms_table_query.c
new file mode 100644
index 0000000..847a58f
--- /dev/null
+++ b/src/vmount/ntapi_vms_table_query.c
@@ -0,0 +1,45 @@
+/********************************************************/
+/* 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/nt_port.h>
+#include <ntapi/nt_vmount.h>
+#include <ntapi/ntapi.h>
+#include "ntapi_impl.h"
+
+
+int32_t __stdcall __ntapi_vms_table_query(
+ __in void * hvms,
+ __in nt_vms_daemon_info * vms_info)
+{
+ int32_t status;
+ nt_vms_daemon_msg msg;
+
+ /* msg */
+ __ntapi->tt_aligned_block_memset(&msg,0,sizeof(msg));
+
+ msg.header.msg_type = NT_LPC_NEW_MESSAGE;
+ msg.header.data_size = sizeof(msg.data);
+ msg.header.msg_size = sizeof(msg);
+ msg.data.msginfo.opcode = NT_VMS_TABLE_QUERY;
+
+ /* zw_request_wait_reply_port */
+ status = __ntapi->zw_request_wait_reply_port(
+ hvms,
+ &msg,
+ &msg);
+
+ if (status) return status;
+
+ /* return info */
+ __ntapi->tt_aligned_block_memcpy(
+ (uintptr_t *)vms_info,
+ (uintptr_t *)&(msg.data.vmsinfo),
+ sizeof(*vms_info));
+
+ /* return vms status */
+ return status ? status : msg.data.msginfo.status;
+}