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 + +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 + +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 + +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 + +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 + +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 + +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 +#include + +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 + +/* 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 + +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 + +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 + +#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 +#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 + +#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 +#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 +#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 +#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 +#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 +#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 +#include + +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 +#include + +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 +#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 +#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 +#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 +#include +#include + +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 + +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 +#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 +#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 + +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 +#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 +#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 +#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 +#include +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#include +#include + +/* 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 +#include + +/* 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 + +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 +#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 +#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 +#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 + +/* 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 +#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 +#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 +#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 +#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 +#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 +#include +#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 +#include +#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 +#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 +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include "ntapi_impl.h" + +int32_t __stdcall __ntapi_tt_get_env_var_meta_utf16( + __in const uint32_t * crc32_table, + __in wchar16_t * env_var_name, + __in uint32_t env_var_name_hash __optional, + __in wchar16_t ** envp, + __out nt_env_var_meta_utf16 * env_var_meta) +{ + int idx; + uint32_t crc32; + unsigned char * byte_buffer; + wchar16_t * wch; + + #define EQUAL_SIGN 0x3D + + /* step 1: crc32 of the target env_var_name */ + if (env_var_name_hash) + crc32 = env_var_name_hash; + else { + crc32 = 0 ^ 0xFFFFFFFF; + + /* initialize byte_buffer */ + byte_buffer = (unsigned char *)env_var_name; + + /* iterate */ + while (*byte_buffer) { + /* two bytes at a time */ + crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF]; + byte_buffer++; + crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF]; + byte_buffer++; + } + crc32 = (crc32 ^ 0xFFFFFFFF); + } + + /* initialize the env_var_meta structure */ + env_var_meta->name_hash = crc32; + env_var_meta->name = (wchar16_t *)0; + env_var_meta->value = (wchar16_t *)0; + env_var_meta->value_hash = 0; + env_var_meta->envp_index = 0; + env_var_meta->flags = 0; + + /* step 2: look for the environment variable in envp[] */ + idx = 0; + while (envp[idx] && (!env_var_meta->value)) { + wch = envp[idx]; + + /* find the equal sign */ + while ((*wch) && (*wch != EQUAL_SIGN)) + wch++; + + if (*wch != EQUAL_SIGN) + return NT_STATUS_ILLEGAL_CHARACTER; + + /* hash the current environment variable */ + crc32 = 0 ^ 0xFFFFFFFF; + + /* initialize byte_buffer */ + byte_buffer = (unsigned char *)envp[idx]; + + /* iterate */ + while ((uintptr_t)(byte_buffer) < (uintptr_t)wch) { + /* two bytes at a time */ + crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF]; + byte_buffer++; + crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF]; + byte_buffer++; + } + + if (env_var_meta->name_hash == (crc32 ^ 0xFFFFFFFF)) { + /* found it, get ready to hash the value */ + wch++; + env_var_meta->name = envp[idx]; + env_var_meta->value = wch; + env_var_meta->envp_index = idx; + } else { + idx++; + } + } + + if (env_var_meta->value) { + /* hash the value: utf-16, null-terminated */ + crc32 = 0 ^ 0xFFFFFFFF; + + /* initialize byte_buffer */ + byte_buffer = (unsigned char *)env_var_meta->value; + + /* iterate */ + while (*byte_buffer) { + /* two bytes at a time */ + crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF]; + byte_buffer++; + crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *byte_buffer) & 0xFF]; + byte_buffer++; + } + + env_var_meta->value_hash = (crc32 ^ 0xFFFFFFFF); + } + + return NT_STATUS_SUCCESS; +} + 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 +#include +#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 +#include +#include +#include +#include +#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<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; iinfo.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 +#include +#include +#include +#include +#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)); (iptrs); 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; ninfo.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 +#include +#include +#include +#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, + ®ion_addr, + ®ion_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, + ®ion_addr, + ®ion_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 +#include +#include +#include +#include +#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( + ¶ms->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( + ¶ms->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 = ¶ms->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( + ¶ms->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 +#include +#include +#include +#include +#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 = ¶ms->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 = ¶ms->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( + ¶ms->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 +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#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 +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#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 +#include + +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 +#include +#include +#include +#include +#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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include + +#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 +#include +#include +#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 +#include +#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 + +#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 +#include +#include +#include +#include +#include +#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 + +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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include + +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 +#include +#include +#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 +#include +#include +#include +#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; ildr_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 +#include +#include +#include +#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 +#include +#include +#include +#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; itypett_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 + +#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 +#include +#include +#include +#include +#include +#include +#include +#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( + ¶ms->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, + ¶ms->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 +#include +#include +#include +#include +#include +#include +#include +#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( + ¶ms->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( + ¶ms->hprocess, + ¶ms->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, + ¶ms->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 +#include +#include +#include +#include +#include +#include +#include +#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 **)¶ms_block, + 0, + ¶ms_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, + ¶ms_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 **)¶ms_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 **)¶ms_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 +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#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_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 +#include +#include +#include +#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_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 +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#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 +#include + +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 + +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 + +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 +#include + +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 +#include +#include +#include +#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 +#include + +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 +#include +#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 + +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 + +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 +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#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 +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#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, + ¶ms->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, + ¶ms->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, + ¶ms->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 *)¶ms->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( + ¶ms->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( + ¶ms->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 +#include +#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 +#include +#include +#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 +#include +#include +#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 +#include +#include +#include +#include +#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 +#include +#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( + ¶ms,0,sizeof(params)); + + params.image_name = image_name; + params.rtblock = &rtblock; + + if ((status = __ntapi->tt_create_native_process(¶ms))) + return status; + + if ((status = __ntapi->zw_wait_for_single_object( + ssattr.srv_ready, + NT_SYNC_NON_ALERTABLE, + 0))) + return __tty_create_session_return(¶ms,status); + + /* connect to subsystem */ + if ((status = __ntapi->tty_connect( + hport, + &port_name->base_named_objects[0], + NT_SECURITY_IMPERSONATION))) + return __tty_create_session_return(¶ms,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(¶ms,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 +#include +#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 +#include +#include +#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 +#include +#include +#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 +#include +#include +#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 +#include +#include +#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 +#include +#include +#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, + ¶ms->code_points, + ¶ms->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 +#include +#include +#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, + ¶ms->code_points, + ¶ms->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 +#include +#include + +/** + * 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 +#include +#include +#include +#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 +#include +#include +#include +#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, + ®ion_addr, + ®ion_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 +#include +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#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 +#include +#include +#include +#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; +}