diff --git a/project/common.mk b/project/common.mk index 7f60ce5..09f23bf 100644 --- a/project/common.mk +++ b/project/common.mk @@ -21,6 +21,7 @@ COMMON_SRCS = \ src/internal/ntapi.c \ src/internal/ntapi_debug.c \ src/internal/ntapi_entry_point.c \ + src/internal/ntapi_open.c \ src/ipc/ntapi_tt_create_pipe_v1.c \ src/ipc/ntapi_tt_create_pipe_v2.c \ src/ldr/ntapi_ldr_create_state_snapshot.c \ diff --git a/src/internal/ntapi_impl.h b/src/internal/ntapi_impl.h index 9376d24..7bc010a 100644 --- a/src/internal/ntapi_impl.h +++ b/src/internal/ntapi_impl.h @@ -114,6 +114,11 @@ extern ntapi_vtbl ___ntapi_shadow; ntapi_internals * __cdecl __ntapi_internals(void); +/* helper functions */ +int32_t __ntapi_tt_open_file_utf8(void ** hfile, void * hat, const char * arg, int fprivate, wchar16_t *, uint32_t); +int32_t __ntapi_tt_open_dir_utf8(void ** hfile, void * hat, const char * arg, int fprivate, wchar16_t *, uint32_t); + + /* debug */ #define __ntidx(x) (&(((ntapi_vtbl *)0)->x)) / sizeof(size_t) diff --git a/src/internal/ntapi_open.c b/src/internal/ntapi_open.c new file mode 100644 index 0000000..e95b228 --- /dev/null +++ b/src/internal/ntapi_open.c @@ -0,0 +1,95 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013--2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include "ntapi_impl.h" + +static int32_t __ntapi_tt_open_utf8( + void ** hfile, + void * hat, + const char * arg, + uint32_t options, + int fprivate, + wchar16_t * buffer, + uint32_t buflen) +{ + int32_t status; + nt_oa oa; + nt_iosb iosb; + nt_unicode_string path; + nt_unicode_conversion_params_utf8_to_utf16 params = {0,0,0,0,0,0,0,0,0}; + wchar16_t * wch; + size_t nbytes; + + /* utf-8 --> utf-16 */ + params.src = (const unsigned char *)arg; + params.src_size_in_bytes = __ntapi->tt_string_null_offset_multibyte(arg); + params.dst = buffer; + params.dst_size_in_bytes = buflen; + + if ((status = __ntapi->uc_convert_unicode_stream_utf8_to_utf16(¶ms))) + return status; + + /* convenience */ + for (wch=buffer, nbytes=params.bytes_written; nbytes; ) { + if (*wch == '/') + *wch = '\\'; + + nbytes -= sizeof(wchar16_t); + wch++; + } + + /* path */ + path.maxlen = 0; + path.strlen = (uint16_t)params.bytes_written; + path.buffer = buffer; + + /* oa */ + oa.len = sizeof(nt_oa); + oa.root_dir = (buffer[0]=='\\') ? 0 : hat; + oa.obj_name = &path; + oa.obj_attr = fprivate ? 0 : NT_OBJ_INHERIT; + oa.sec_desc = 0; + oa.sec_qos = 0; + + /* open */ + return __ntapi->zw_open_file( + hfile, + NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_DATA, + &oa,&iosb, + NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE, + options | NT_FILE_SYNCHRONOUS_IO_ALERT); +} + +int32_t __ntapi_tt_open_file_utf8( + void ** hfile, + void * hat, + const char * arg, + int fprivate, + wchar16_t * buffer, + uint32_t buflen) +{ + return __ntapi_tt_open_utf8( + hfile,hat,arg, + NT_FILE_NON_DIRECTORY_FILE, + fprivate,buffer,buflen); +} + +int32_t __ntapi_tt_open_dir_utf8( + void ** hfile, + void * hat, + const char * arg, + int fprivate, + wchar16_t * buffer, + uint32_t buflen) +{ + return __ntapi_tt_open_utf8( + hfile,hat,arg, + NT_FILE_DIRECTORY_FILE, + fprivate,buffer,buflen); +}