diff --git a/include/ntapi/nt_argv.h b/include/ntapi/nt_argv.h index eae5996..531c6c0 100644 --- a/include/ntapi/nt_argv.h +++ b/include/ntapi/nt_argv.h @@ -30,9 +30,7 @@ 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; @@ -48,9 +46,7 @@ typedef struct _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; @@ -60,9 +56,7 @@ 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; @@ -140,27 +134,11 @@ typedef int32_t __stdcall ntapi_tt_get_argv_envp_utf16( 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, diff --git a/include/ntapi/ntapi.h b/include/ntapi/ntapi.h index a413e4e..8af844f 100644 --- a/include/ntapi/ntapi.h +++ b/include/ntapi/ntapi.h @@ -482,8 +482,6 @@ typedef struct _ntapi_vtbl { 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; diff --git a/project/common.mk b/project/common.mk index 8dd2dfc..7f60ce5 100644 --- a/project/common.mk +++ b/project/common.mk @@ -3,7 +3,6 @@ COMMON_SRCS = \ src/argv/ntapi_tt_array_utf16.c \ src/argv/ntapi_tt_array_utf8.c \ src/argv/ntapi_tt_env_vars.c \ - src/argv/ntapi_tt_get_option.c \ src/blitter/ntapi_blt_alloc.c \ src/blitter/ntapi_blt_block.c \ src/blitter/ntapi_blt_free.c \ diff --git a/src/argv/ntapi_tt_env_vars.c b/src/argv/ntapi_tt_env_vars.c index 4fe590c..5642101 100644 --- a/src/argv/ntapi_tt_env_vars.c +++ b/src/argv/ntapi_tt_env_vars.c @@ -9,104 +9,41 @@ #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 + #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; + /* init */ + env_var_meta->name = 0; + env_var_meta->value = 0; + env_var_meta->envp_index = 0; + env_var_meta->flags = 0; - /* 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)) { + /* lookup */ + for (idx=0; envp[idx] && !env_var_meta->value; idx++) { wch = envp[idx]; - /* find the equal sign */ - while ((*wch) && (*wch != 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 */ + if (!(__ntapi->tt_strncmp_utf16( + envp[idx], + env_var_name, + wch - envp[idx]))) { wch++; - env_var_meta->name = envp[idx]; - env_var_meta->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 deleted file mode 100644 index 6cb3993..0000000 --- a/src/argv/ntapi_tt_get_option.c +++ /dev/null @@ -1,450 +0,0 @@ -/********************************************************/ -/* ntapi: Native API core library */ -/* Copyright (C) 2013--2016 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 __inline__ __fastcall int __is_bmp_code_point(uint16_t code_point) -{ - return ((code_point < 0xD800) || (code_point >= 0xE000)); -} - - -static __inline__ __fastcall int __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/internal/ntapi.c b/src/internal/ntapi.c index b77cdd5..390931f 100644 --- a/src/internal/ntapi.c +++ b/src/internal/ntapi.c @@ -250,8 +250,6 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl) __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; diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h index 9ded75a..6dbb87d 100644 --- a/src/internal/ntapi_fnapi.h +++ b/src/internal/ntapi_fnapi.h @@ -137,8 +137,6 @@ 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; diff --git a/src/process/ntapi_tt_get_runtime_data.c b/src/process/ntapi_tt_get_runtime_data.c index 4513570..e5a7d55 100644 --- a/src/process/ntapi_tt_get_runtime_data.c +++ b/src/process/ntapi_tt_get_runtime_data.c @@ -23,11 +23,11 @@ static wchar16_t runtime_arg[20] = { int32_t __stdcall __ntapi_tt_get_runtime_data( __out nt_runtime_data ** rtdata, - __in wchar16_t ** argv) + __in wchar16_t ** wargv) { int32_t status; nt_process_parameters * process_params; - nt_cmd_option_meta_utf16 cmd_opt_meta; + wchar16_t * addrarg; nt_runtime_data buffer; nt_runtime_data * prtdata; ntapi_internals * __internals; @@ -41,22 +41,24 @@ int32_t __stdcall __ntapi_tt_get_runtime_data( return NT_STATUS_SUCCESS; } - if (!(argv = argv ? argv : __internals->ntapi_img_sec_bss->argv_envp_array)) + if (!(wargv = wargv ? wargv : __internals->ntapi_img_sec_bss->argv_envp_array)) return NT_STATUS_INVALID_PARAMETER_2; + if (!wargv[1] || !wargv[2]) + return NT_STATUS_MORE_PROCESSING_REQUIRED; + /* integral process? */ - if ((status = __ntapi->tt_get_short_option_meta_utf16( - __ntapi->tt_crc32_table(), - 'r', - argv, - &cmd_opt_meta))) - return status; + if ((wargv[1][0] == '-') && (wargv[1][1] == 'r') && (wargv[1][2] == 0)) + addrarg = wargv[2]; + else + return NT_STATUS_INVALID_PARAMETER; - else if (argv[3]) + if (!addrarg || wargv[3]) status = NT_STATUS_INVALID_PARAMETER_MIX; + /* obtain pointer to data block */ if ((status = __ntapi->tt_hex_utf16_to_uintptr( - cmd_opt_meta.value, + addrarg, (uintptr_t *)&prtdata))) return status;