Windows 10 inline functions of crt and strsafe

Started by TouEnMasm, December 07, 2015, 08:39:01 PM

Previous topic - Next topic

TouEnMasm

Here the vc++ project source code to create a lib with those inline functions (win 10 vc++ 2015)
Report are welcome
Fa is a musical note to play with CL

jj2007

A 300k C source for functions that most of us can hack together in ten minutes?
::)

TWell

WSDK strsafe.lib is 30kb, so that wrapper is a bit larger :P
StrSafe.lib functions:
_StringVPrintf_lWorkerA@24
_StringVPrintf_lWorkerW@24
??_C@_00CNPNBAHC@?$AA@
??_C@_11LOCGONAA@?$AA?$AA@
_StringCopyWorkerA@20
_StringCopyWorkerW@20
_StringExHandleFillBehindNullA@12
_StringExHandleFillBehindNullW@12
_StringExHandleOtherFlagsA@24
_StringExHandleOtherFlagsW@24
_StringExValidateDestA@16
_StringExValidateDestAndLengthA@20
_StringExValidateDestAndLengthW@20
_StringExValidateDestW@16
_StringExValidateSrcA@16
_StringExValidateSrcW@16
_StringLengthWorkerA@12
_StringLengthWorkerW@12
_StringVPrintfWorkerA@20
_StringVPrintfWorkerW@20
_StringValidateDestA@12
_StringValidateDestAndLengthA@16
_StringValidateDestAndLengthW@16
_StringValidateDestW@12

TouEnMasm

This lib is for WINDOWS 10 who put many functions INLINE
NO,you couldn't hack them in ten minutes .They are in c++ code in the include file,a bit too much hard for an asm compiler.
:biggrin:
The lib is 300k with CRT and STRSAFE functions (471 public symbols).

Quote
    471 public symbols

     524A ?wmemchr@@YAPA_WPA_W_WI@Z
     A43E __strdec
     A43E __strinc
     A43E __strncat_s_l
     A43E __strncnt
     A43E __strncpy_s_l
     A43E __strnextc
     A43E __strninc
     A43E __strnset_s_l
     A43E __strset_s_l
     A43E __strspnp
     A43E __strtok_l
     A43E __strtok_s_l
     A43E __tccmp
     A43E __tccpy
     A43E __tccpy_l
     A43E __tclen
     DB86 ??$__vcrt_va_start_verify_argument_type@PBD@@YAXXZ
     DB86 ??$__vcrt_va_start_verify_argument_type@PB_W@@YAXXZ
     DB86 ??_C@_00CNPNBAHC@?$AA@
     DB86 ??_C@_11LOCGONAA@?$AA?$AA@
     DB86 ?_OptionsStorage@?1??__local_stdio_printf_options@@9@4_KA
     DB86 _StringCbCatA@12
     DB86 _StringCbCatExA@24
     DB86 _StringCbCatExW@24
     DB86 _StringCbCatNA@16
     DB86 _StringCbCatNExA@28
     DB86 _StringCbCatNExW@28
     DB86 _StringCbCatNW@16
     DB86 _StringCbCatW@12
     DB86 _StringCbCopyA@12
     DB86 _StringCbCopyExA@24
     DB86 _StringCbCopyExW@24
     DB86 _StringCbCopyNA@16
     DB86 _StringCbCopyNExA@28
     DB86 _StringCbCopyNExW@28
     DB86 _StringCbCopyNW@16
     DB86 _StringCbCopyW@12
     DB86 _StringCbGetsA@8
     DB86 _StringCbGetsExA@20
     DB86 _StringCbGetsExW@20
     DB86 _StringCbGetsW@8
     DB86 _StringCbLengthA@12
     DB86 _StringCbLengthW@12
     DB86 _StringCbPrintfA
     DB86 _StringCbPrintfExA
     DB86 _StringCbPrintfExW
     DB86 _StringCbPrintfW
     DB86 _StringCbVPrintfA@16
     DB86 _StringCbVPrintfExA@28
     DB86 _StringCbVPrintfExW@28
     DB86 _StringCbVPrintfW@16
     DB86 _StringCchCatA@12
     DB86 _StringCchCatExA@24
     DB86 _StringCchCatExW@24
     DB86 _StringCchCatNA@16
     DB86 _StringCchCatNExA@28
     DB86 _StringCchCatNExW@28
     DB86 _StringCchCatNW@16
     DB86 _StringCchCatW@12
     DB86 _StringCchCopyA@12
     DB86 _StringCchCopyExA@24
     DB86 _StringCchCopyExW@24
     DB86 _StringCchCopyNA@16
     DB86 _StringCchCopyNExA@28
     DB86 _StringCchCopyNExW@28
     DB86 _StringCchCopyNW@16
     DB86 _StringCchCopyW@12
     DB86 _StringCchGetsA@8
     DB86 _StringCchGetsExA@20
     DB86 _StringCchGetsExW@20
     DB86 _StringCchGetsW@8
     DB86 _StringCchLengthA@12
     DB86 _StringCchLengthW@12
     DB86 _StringCchPrintfA
     DB86 _StringCchPrintfExA
     DB86 _StringCchPrintfExW
     DB86 _StringCchPrintfW
     DB86 _StringCchVPrintfA@16
     DB86 _StringCchVPrintfExA@28
     DB86 _StringCchVPrintfExW@28
     DB86 _StringCchVPrintfW@16
     DB86 _StringGetsWorkerA@12
     DB86 _StringGetsWorkerW@12
     DB86 ___local_stdio_printf_options
    33974 ?strchr@@YAPADQADH@Z
    33974 ?strpbrk@@YAPADQADQBD@Z
    33974 ?strrchr@@YAPADQADH@Z
    33974 ?strstr@@YAPADQADQBD@Z
    34C60 ??$__vcrt_va_start_verify_argument_type@QAU__crt_locale_pointers@@@@YAXXZ
    34C60 ??$__vcrt_va_start_verify_argument_type@QBD@@YAXXZ
    34C60 ?_OptionsStorage@?1??__local_stdio_scanf_options@@9@4_KA
    34C60 ___local_stdio_scanf_options
    34C60 __fprintf_l
    34C60 __fprintf_p
    34C60 __fprintf_p_l
    34C60 __fprintf_s_l
    34C60 __fscanf_l
    34C60 __fscanf_s_l
    34C60 __printf_l
    34C60 __printf_p
    34C60 __printf_p_l
    34C60 __printf_s_l
    34C60 __scanf_l
    34C60 __scanf_s_l
    34C60 __scprintf
    34C60 __scprintf_l
    34C60 __scprintf_p
    34C60 __scprintf_p_l
    34C60 __snprintf
    34C60 __snprintf_c
    34C60 __snprintf_c_l
    34C60 __snprintf_l
    34C60 __snprintf_s
    34C60 __snprintf_s_l
    34C60 __snscanf
    34C60 __snscanf_l
    34C60 __snscanf_s
    34C60 __snscanf_s_l
    34C60 __sprintf_l
    34C60 __sprintf_p
    34C60 __sprintf_p_l
    34C60 __sprintf_s_l
    34C60 __sscanf_l
    34C60 __sscanf_s_l
    34C60 __vfprintf_l
    34C60 __vfprintf_p
    34C60 __vfprintf_p_l
    34C60 __vfprintf_s_l
    34C60 __vfscanf_l
    34C60 __vfscanf_s_l
    34C60 __vprintf_l
    34C60 __vprintf_p
    34C60 __vprintf_p_l
    34C60 __vprintf_s_l
    34C60 __vscanf_l
    34C60 __vscanf_s_l
    34C60 __vscprintf
    34C60 __vscprintf_l
    34C60 __vscprintf_p
    34C60 __vscprintf_p_l
    34C60 __vsnprintf
    34C60 __vsnprintf_c
    34C60 __vsnprintf_c_l
    34C60 __vsnprintf_l
    34C60 __vsnprintf_s
    34C60 __vsnprintf_s_l
    34C60 __vsprintf_l
    34C60 __vsprintf_p
    34C60 __vsprintf_p_l
    34C60 __vsprintf_s_l
    34C60 __vsscanf_l
    34C60 __vsscanf_s_l
    34C60 _fprintf
    34C60 _fprintf_s
    34C60 _fscanf
    34C60 _fscanf_s
    34C60 _printf
    34C60 _printf_s
    34C60 _scanf
    34C60 _scanf_s
    34C60 _snprintf
    34C60 _sprintf
    34C60 _sprintf_s
    34C60 _sscanf
    34C60 _sscanf_s
    34C60 _vfprintf
    34C60 _vfprintf_s
    34C60 _vfscanf
    34C60 _vfscanf_s
    34C60 _vprintf
    34C60 _vprintf_s
    34C60 _vscanf
    34C60 _vscanf_s
    34C60 _vsnprintf
    34C60 _vsnprintf_s
    34C60 _vsprintf
    34C60 _vsprintf_s
    34C60 _vsscanf
    34C60 _vsscanf_s
    4B27A ?_mbschr@@YAPAEQAEI@Z
    4B27A ?_mbschr_l@@YAPAEQAEIQAU__crt_locale_pointers@@@Z
    4B27A ?_mbspbrk@@YAPAEQAEQBE@Z
    4B27A ?_mbspbrk_l@@YAPAEQAEQBEQAU__crt_locale_pointers@@@Z
    4B27A ?_mbsrchr@@YAPAEQAEI@Z
    4B27A ?_mbsrchr_l@@YAPAEQAEIQAU__crt_locale_pointers@@@Z
    4B27A ?_mbsstr@@YAPAEQAEQBE@Z
    4B27A ?_mbsstr_l@@YAPAEQAEQBEQAU__crt_locale_pointers@@@Z
    4D0F6 ?_fpcomp@@YAHMM@Z
    4D0F6 ?_fpcomp@@YAHNN@Z
    4D0F6 ?_fpcomp@@YAHOO@Z
    4D0F6 ?fpclassify@@YAHM@Z
    4D0F6 ?fpclassify@@YAHN@Z
    4D0F6 ?fpclassify@@YAHO@Z
    4D0F6 ?signbit@@YA_NM@Z
    4D0F6 ?signbit@@YA_NN@Z
    4D0F6 ?signbit@@YA_NO@Z
    4D0F6 __chgsignl
    4D0F6 __copysignl
    4D0F6 __hypotl
    4D0F6 __xmm@7fffffffffffffff7fffffffffffffff
    4D0F6 _acosf
    4D0F6 _acosl
    4D0F6 _asinf
    4D0F6 _asinl
    4D0F6 _atan2f
    4D0F6 _atan2l
    4D0F6 _atanf
    4D0F6 _atanl
    4D0F6 _ceilf
    4D0F6 _ceill
    4D0F6 _cosf
    4D0F6 _coshf
    4D0F6 _coshl
    4D0F6 _cosl
    4D0F6 _expf
    4D0F6 _expl
    4D0F6 _fabsf
    4D0F6 _fabsl
    4D0F6 _floorf
    4D0F6 _floorl
    4D0F6 _fmodf
    4D0F6 _fmodl
    4D0F6 _frexpf
    4D0F6 _frexpl
    4D0F6 _hypotf
    4D0F6 _hypotl
    4D0F6 _ldexpf
    4D0F6 _ldexpl
    4D0F6 _log10f
    4D0F6 _log10l
    4D0F6 _logf
    4D0F6 _logl
    4D0F6 _modff
    4D0F6 _modfl
    4D0F6 _powf
    4D0F6 _powl
    4D0F6 _sinf
    4D0F6 _sinhf
    4D0F6 _sinhl
    4D0F6 _sinl
    4D0F6 _sqrtf
    4D0F6 _sqrtl
    4D0F6 _tanf
    4D0F6 _tanhf
    4D0F6 _tanhl
    4D0F6 _tanl
    5688C ?wcschr@@YAPA_WPA_W_W@Z
    5688C ?wcspbrk@@YAPA_WPA_WPB_W@Z
    5688C ?wcsrchr@@YAPA_WPA_W_W@Z
    5688C ?wcsstr@@YAPA_WPA_WPB_W@Z
    5688C ?wcstok@@YAPA_WPA_WPB_W@Z
    57CFA ??$__vcrt_va_start_verify_argument_type@PAU__crt_locale_pointers@@@@YAXXZ
    57CFA ??$__vcrt_va_start_verify_argument_type@QB_W@@YAXXZ
    57CFA ___swprintf_l
    57CFA ___vswprintf_l
    57CFA __fwprintf_l
    57CFA __fwprintf_p
    57CFA __fwprintf_p_l
    57CFA __fwprintf_s_l
    57CFA __fwscanf_l
    57CFA __fwscanf_s_l
    57CFA __scwprintf
    57CFA __scwprintf_l
    57CFA __scwprintf_p
    57CFA __scwprintf_p_l
    57CFA __snwprintf
    57CFA __snwprintf_l
    57CFA __snwprintf_s
    57CFA __snwprintf_s_l
    57CFA __snwscanf
    57CFA __snwscanf_l
    57CFA __snwscanf_s
    57CFA __snwscanf_s_l
    57CFA __swprintf
    57CFA __swprintf_c
    57CFA __swprintf_c_l
    57CFA __swprintf_l
    57CFA __swprintf_p
    57CFA __swprintf_p_l
    57CFA __swprintf_s_l
    57CFA __swscanf_l
    57CFA __swscanf_s_l
    57CFA __vfwprintf_l
    57CFA __vfwprintf_p
    57CFA __vfwprintf_p_l
    57CFA __vfwprintf_s_l
    57CFA __vfwscanf_l
    57CFA __vfwscanf_s_l
    57CFA __vscwprintf
    57CFA __vscwprintf_l
    57CFA __vscwprintf_p
    57CFA __vscwprintf_p_l
    57CFA __vsnwprintf
    57CFA __vsnwprintf_l
    57CFA __vsnwprintf_s
    57CFA __vsnwprintf_s_l
    57CFA __vsnwscanf_l
    57CFA __vsnwscanf_s_l
    57CFA __vswprintf
    57CFA __vswprintf_c
    57CFA __vswprintf_c_l
    57CFA __vswprintf_l
    57CFA __vswprintf_p
    57CFA __vswprintf_p_l
    57CFA __vswprintf_s_l
    57CFA __vswscanf_l
    57CFA __vswscanf_s_l
    57CFA __vwprintf_l
    57CFA __vwprintf_p
    57CFA __vwprintf_p_l
    57CFA __vwprintf_s_l
    57CFA __vwscanf_l
    57CFA __vwscanf_s_l
    57CFA __wprintf_l
    57CFA __wprintf_p
    57CFA __wprintf_p_l
    57CFA __wprintf_s_l
    57CFA __wscanf_l
    57CFA __wscanf_s_l
    57CFA _fwprintf
    57CFA _fwprintf_s
    57CFA _fwscanf
    57CFA _fwscanf_s
    57CFA _swprintf
    57CFA _swprintf_s
    57CFA _swscanf
    57CFA _swscanf_s
    57CFA _vfwprintf
    57CFA _vfwprintf_s
    57CFA _vfwscanf
    57CFA _vfwscanf_s
    57CFA _vswprintf
    57CFA _vswprintf_s
    57CFA _vswscanf
    57CFA _vswscanf_s
    57CFA _vwprintf
    57CFA _vwprintf_s
    57CFA _vwscanf
    57CFA _vwscanf_s
    57CFA _wprintf
    57CFA _wprintf_s
    57CFA _wscanf
    57CFA _wscanf_s
    6D4BA ?_wopen@@YAHPB_WHH@Z
    6D4BA ?_wsopen@@YAHPB_WHHH@Z
    6E306 __cwprintf
    6E306 __cwprintf_l
    6E306 __cwprintf_p
    6E306 __cwprintf_p_l
    6E306 __cwprintf_s
    6E306 __cwprintf_s_l
    6E306 __cwscanf
    6E306 __cwscanf_l
    6E306 __cwscanf_s
    6E306 __cwscanf_s_l
    6E306 __vcwprintf
    6E306 __vcwprintf_l
    6E306 __vcwprintf_p
    6E306 __vcwprintf_p_l
    6E306 __vcwprintf_s
    6E306 __vcwprintf_s_l
    6E306 __vcwscanf
    6E306 __vcwscanf_l
    6E306 __vcwscanf_s
    6E306 __vcwscanf_s_l
    730D4 ?memchr@@YAPAXPAXHI@Z
    73B12 _memcpy_s
    73B12 _memmove_s
    74F32 ?_open@@YAHQBDHH@Z
    74F32 ?_sopen@@YAHQBDHHH@Z
    75DD6 __cprintf
    75DD6 __cprintf_l
    75DD6 __cprintf_p
    75DD6 __cprintf_p_l
    75DD6 __cprintf_s
    75DD6 __cprintf_s_l
    75DD6 __cscanf
    75DD6 __cscanf_l
    75DD6 __cscanf_s
    75DD6 __cscanf_s_l
    75DD6 __vcprintf
    75DD6 __vcprintf_l
    75DD6 __vcprintf_p
    75DD6 __vcprintf_p_l
    75DD6 __vcprintf_s
    75DD6 __vcprintf_s_l
    75DD6 __vcscanf
    75DD6 __vcscanf_l
    75DD6 __vcscanf_s
    75DD6 __vcscanf_s_l
    75DD6 _cprintf
    75DD6 _cscanf
    7B148 ?abs@@YAMU_C_float_complex@@@Z
    7B148 ?abs@@YANU_C_double_complex@@@Z
    7B148 ?abs@@YAOU_C_ldouble_complex@@@Z
    7B148 ?acos@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?acos@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?acos@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?acosh@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?acosh@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?acosh@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?arg@@YAMU_C_float_complex@@@Z
    7B148 ?arg@@YANU_C_double_complex@@@Z
    7B148 ?arg@@YAOU_C_ldouble_complex@@@Z
    7B148 ?asin@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?asin@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?asin@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?asinh@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?asinh@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?asinh@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?atan@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?atan@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?atan@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?atanh@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?atanh@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?atanh@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?carg@@YAMU_C_float_complex@@@Z
    7B148 ?carg@@YAOU_C_ldouble_complex@@@Z
    7B148 ?cimag@@YAMU_C_float_complex@@@Z
    7B148 ?cimag@@YAOU_C_ldouble_complex@@@Z
    7B148 ?conj@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?conj@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?cos@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?cos@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?cos@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?cosh@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?cosh@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?cosh@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?cproj@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?cproj@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?creal@@YAMU_C_float_complex@@@Z
    7B148 ?creal@@YAOU_C_ldouble_complex@@@Z
    7B148 ?exp@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?exp@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?exp@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?imag@@YAMU_C_float_complex@@@Z
    7B148 ?imag@@YANU_C_double_complex@@@Z
    7B148 ?imag@@YAOU_C_ldouble_complex@@@Z
    7B148 ?log10@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?log10@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?log10@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?log@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?log@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?log@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?norm@@YAMU_C_float_complex@@@Z
    7B148 ?norm@@YAOU_C_ldouble_complex@@@Z
    7B148 ?pow@@YA?AU_C_double_complex@@U1@0@Z
    7B148 ?pow@@YA?AU_C_float_complex@@U1@0@Z
    7B148 ?pow@@YA?AU_C_ldouble_complex@@U1@0@Z
    7B148 ?proj@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?proj@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?proj@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?real@@YAMU_C_float_complex@@@Z
    7B148 ?real@@YANU_C_double_complex@@@Z
    7B148 ?real@@YAOU_C_ldouble_complex@@@Z
    7B148 ?sin@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?sin@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?sin@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?sinh@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?sinh@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?sinh@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?sqrt@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?sqrt@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?sqrt@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?tan@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?tan@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?tan@@YA?AU_C_ldouble_complex@@U1@@Z
    7B148 ?tanh@@YA?AU_C_double_complex@@U1@@Z
    7B148 ?tanh@@YA?AU_C_float_complex@@U1@@Z
    7B148 ?tanh@@YA?AU_C_ldouble_complex@@U1@@Z
Fa is a musical note to play with CL

Adamanteus

By my experiance possible skip using all strsave functionality using SEH and a little more. Also _l functions of this lib have same prototypes as [n] functions, as strncpy and strcpy_l. So using them looks as bed style of programming.

dedndave

in assembly language, the "safe" functions aren't really needed
we can design the code so that no buffer overflow is possible   :t

jj2007

Quote from: Adamanteus on December 08, 2015, 05:39:46 AM
By my experiance possible skip using all strsave functionality using SEH

Your wording is a bit ambiguous, it could mean "don't use strsafe functions which rely on SEH" or "don't use strsafe functions, use SEH and unsafe functions instead". Both versions are dangerous. Relying on SEH is almost always a bad idea. For example, using a buffer overflow to write a new address into the stack will not trigger an exception.


Quote from: dedndave on December 08, 2015, 06:39:39 AM
in assembly language, the "safe" functions aren't really needed
we can design the code so that no buffer overflow is possible   :t

Indeed :t

Adamanteus

Quote from: jj2007 on December 08, 2015, 07:34:31 AM
Your wording is a bit ambiguous, it could mean "don't use strsafe functions which rely on SEH" or "don't use strsafe functions, use SEH and unsafe functions instead". Both versions are dangerous. Relying on SEH is almost always a bad idea. For example, using a buffer overflow to write a new address into the stack will not trigger an exception.
Relying on SEH - strsave functionality, of throws when NULL pointers - used by _s functions of this lib, and better on SEH, as no need to care of all other types of functions, even you own. So both versions is correct - no ambiguous, and overflow preserves _l functions, that have same prototypes as [n] functions, as was said before - better to use them.