Esempio n. 1
0
/***
*errno_t _strerror_s(buffer, sizeInTChars, message) - get system error message
*
*Purpose:
*   builds an error message consisting of the users error message
*   (the message parameter), followed by ": ", followed by the system
*   error message (index through errno), followed by a newline.  If
*   message is NULL or a null string, returns a pointer to just
*   the system error message.
*
*Entry:
*   TCHAR * buffer - Destination buffer.
*   size_t sizeInTChars - Size of the destination buffer.
*   TCHAR * message - user's message to prefix system error message
*
*Exit:
*   The error code.
*
*Exceptions:
*   Input parameters are validated. Refer to the validation section of the function.
*
*******************************************************************************/

#define _MIN_MSG_LENGTH 5

#ifdef _UNICODE
errno_t __cdecl __wcserror_s(
#else  /* _UNICODE */
errno_t __cdecl _strerror_s(
#endif  /* _UNICODE */
    TCHAR* buffer,
    size_t sizeInTChars,
    const _TCHAR *message
    )
{
    errno_t e = 0;

    /* validation section */
    _VALIDATE_RETURN_ERRCODE(buffer != NULL, EINVAL);
    _VALIDATE_RETURN_ERRCODE(sizeInTChars > 0, EINVAL);
    buffer[0] = '\0';

    if (message &&
        *message &&
        _tcslen(message) < (sizeInTChars - 2 - _MIN_MSG_LENGTH))
    {
        _ERRCHECK(_tcscpy_s(buffer, sizeInTChars, message));
        _ERRCHECK(_tcscat_s(buffer, sizeInTChars, _T(": ")));
    }

    /* append the error message at the end of the buffer */
    return _tcserror_s(buffer + _tcslen(buffer), sizeInTChars - _tcslen(buffer), errno);
}
Esempio n. 2
0
errno_t __cdecl _tctime64_s (
        _TSCHAR * buffer,
        size_t sizeInChars,
        const __time64_t *timp
        )
{
        struct tm tmtemp;
        errno_t e;

        _VALIDATE_RETURN_ERRCODE(
            ( ( buffer != NULL ) && ( sizeInChars > 0 ) ),
            EINVAL
        )

        _RESET_STRING(buffer, sizeInChars);

        _VALIDATE_RETURN_ERRCODE( ( timp != NULL ), EINVAL )
        _VALIDATE_RETURN_ERRCODE_NOEXC( ( *timp >= 0 ), EINVAL )

        e = _localtime64_s(&tmtemp, timp);
        if ( e == 0 )
        {
            e = _tasctime_s(buffer, sizeInChars, &tmtemp);
        }
        return e;
}
Esempio n. 3
0
extern "C" errno_t __cdecl wmemcpy_s(
    wchar_t*       const destination,
    size_t         const size_in_elements,
    wchar_t const* const source,
    size_t         const count
    )
{
    if (count == 0)
        return 0;

    _VALIDATE_RETURN_ERRCODE(destination != nullptr, EINVAL);

    if (source == nullptr || size_in_elements < count)
    {
        // Zero the destination buffer:
        wmemset(destination, 0, size_in_elements);

        _VALIDATE_RETURN_ERRCODE(source != nullptr, EINVAL);
        _VALIDATE_RETURN_ERRCODE(size_in_elements >= count, ERANGE);
        
        // Useless, but prefast is confused:
        return EINVAL;
    }

#pragma warning(suppress:__WARNING_BANNED_API_USAGEL2 __WARNING_BUFFER_COPY_NO_KNOWN_SIZEEXPR) /* 28726 22104 */
    wmemcpy(destination, source, count);
    return 0;
}
Esempio n. 4
0
/***
*errno_t strerror_s(buffer, sizeInTChars, errnum) - Map error number to error message string.
*
*Purpose:
*       The strerror_s runtime takes an error number for input and
*       copies the corresponding error message string in the destination
*       buffer. If the buffer is too small, the message is truncated.
*
*Entry:
*       TCHAR * buffer - Destination buffer.
*       size_t sizeInTChars - Size of the destination buffer.
*       int errnum - Integer error number (corresponding to an errno value).
*
*Exit:
*       The error code.
*
*Exceptions:
*       Input parameters are validated. Refer to the validation section of the function.
*
*******************************************************************************/

#ifdef _UNICODE
errno_t __cdecl _wcserror_s(
#else  /* _UNICODE */
errno_t __cdecl strerror_s(
#endif  /* _UNICODE */
        TCHAR* buffer,
        size_t sizeInTChars,
        int errnum
        )
{
        errno_t e = 0;

        /* validation section */
        _VALIDATE_RETURN_ERRCODE(buffer != NULL, EINVAL);
        _VALIDATE_RETURN_ERRCODE(sizeInTChars > 0, EINVAL);

        /* we use mbstowcs_s or strncpy_s because we want to truncate the error string
         * if the destination is not big enough
         */
#ifdef _UNICODE
        e = _ERRCHECK_EINVAL_ERANGE(mbstowcs_s(NULL, buffer, sizeInTChars, _get_sys_err_msg(errnum), _TRUNCATE));
        /* ignore the truncate information */
        if (e == STRUNCATE)
        {
                e = 0;
        }
#else  /* _UNICODE */
        _ERRCHECK(strncpy_s(buffer, sizeInTChars, _get_sys_err_msg(errnum), sizeInTChars - 1));
#endif  /* _UNICODE */
    return e;
}
Esempio n. 5
0
extern "C" errno_t __cdecl wcsrtombs_s(
        size_t *pRetValue,
        char *dst,
        size_t sizeInBytes,
        const wchar_t **src,
        size_t n,
        mbstate_t *pmbst
        )
{
    size_t retsize;

    if (pRetValue != NULL)
    {
        *pRetValue = -1;
    }

    /* validation section */
    _VALIDATE_RETURN_ERRCODE((dst == NULL && sizeInBytes == 0) || (dst != NULL && sizeInBytes > 0), EINVAL);
    if (dst != NULL)
    {
        _RESET_STRING(dst, sizeInBytes);
    }
    _VALIDATE_RETURN_ERRCODE(src != NULL, EINVAL);

    /* Call a non-deprecated helper to do the work. */
    retsize = _wcsrtombs_helper(dst, src, (n > sizeInBytes ? sizeInBytes : n), pmbst);

    if (retsize == (size_t)-1)
    {
        if (dst != NULL)
        {
            _RESET_STRING(dst, sizeInBytes);
        }
        return errno;
    }

    /* count the null terminator */
    retsize++;

    if (dst != NULL)
    {
        /* return error if the string does not fit */
        if (retsize > sizeInBytes)
        {
            _RESET_STRING(dst, sizeInBytes);
            _VALIDATE_RETURN_ERRCODE(retsize <= sizeInBytes, ERANGE);
        }

        /* ensure the string is null terminated */
        dst[retsize - 1] = '\0';
    }

    if (pRetValue != NULL)
    {
        *pRetValue = retsize;
    }

    return 0;
}
Esempio n. 6
0
extern "C" errno_t __cdecl _wcstombs_s_l(
    size_t* pConvertedChars,
    char* dst,
    size_t sizeInBytes,
    const wchar_t* src,
    size_t n,
    _locale_t plocinfo
) {
    size_t retsize;
    errno_t retvalue = 0;
    /* validation section */
    _VALIDATE_RETURN_ERRCODE((dst != NULL && sizeInBytes > 0) || (dst == NULL && sizeInBytes == 0), EINVAL);

    if (dst != NULL) {
        _RESET_STRING(dst, sizeInBytes);
    }

    if (pConvertedChars != NULL) {
        *pConvertedChars = 0;
    }

    retsize = _wcstombs_l_helper(dst, src, (n > sizeInBytes ? sizeInBytes : n), plocinfo);

    if (retsize == (size_t) - 1) {
        if (dst != NULL) {
            _RESET_STRING(dst, sizeInBytes);
        }

        return errno;
    }

    /* count the null terminator */
    retsize++;

    if (dst != NULL) {
        /* return error if the string does not fit, unless n == _TRUNCATE */
        if (retsize > sizeInBytes) {
            if (n != _TRUNCATE) {
                _RESET_STRING(dst, sizeInBytes);
                _VALIDATE_RETURN_ERRCODE(sizeInBytes > retsize, ERANGE);
            }

            retsize = sizeInBytes;
            retvalue = STRUNCATE;
        }

        /* ensure the string is null terminated */
        dst[retsize - 1] = '\0';
    }

    if (pConvertedChars != NULL) {
        *pConvertedChars = retsize;
    }

    return retvalue;
}
Esempio n. 7
0
errno_t __cdecl _tfreopen_helper(
    FILE** pfile,
    const _TSCHAR* filename,
    const _TSCHAR* mode,
    FILE* str,
    int shflag
) {
    REG1 FILE* stream;
    _VALIDATE_RETURN_ERRCODE((pfile != NULL), EINVAL);
    *pfile = NULL;
    _VALIDATE_RETURN_ERRCODE((filename != NULL), EINVAL);
    _VALIDATE_RETURN_ERRCODE((mode != NULL), EINVAL);
    _VALIDATE_RETURN_ERRCODE((str != NULL), EINVAL);

    /* We deliberately don't hard-validate for emptry strings here. All other invalid
    path strings are treated as runtime errors by the inner code in _open and openfile.
    This is also the appropriate treatment here. Since fopen is the primary access point
    for file strings it might be subjected to direct user input and thus must be robust to
    that rather than aborting. The CRT and OS do not provide any other path validator (because
    WIN32 doesn't allow such things to exist in full generality).
    */
    if (*filename == _T('\0')) {
        errno = EINVAL;
        return errno;
    }

    /* Init stream pointer */
    stream = str;
    _lock_str(stream);

    __try {
        /* If the stream is in use, try to close it. Ignore possible
         * error (ANSI 4.9.5.4). */
        if (inuse(stream)) {
            _fclose_nolock(stream);
        }

        stream->_ptr = stream->_base = NULL;
        stream->_cnt = stream->_flag = 0;
#ifdef _UNICODE
        *pfile = _wopenfile(filename, mode, shflag, stream);
#else  /* _UNICODE */
        *pfile = _openfile(filename, mode, shflag, stream);
#endif  /* _UNICODE */
    } __finally {
        _unlock_str(stream);
    }

    if (*pfile) {
        return 0;
    }

    return errno;
}
Esempio n. 8
0
errno_t __cdecl rand_s
(
    unsigned int* _RandomValue
) {
    PGENRANDOM pfnRtlGenRandom = _decode_pointer(g_pfnRtlGenRandom);
    _VALIDATE_RETURN_ERRCODE(_RandomValue != NULL, EINVAL);
    *_RandomValue = 0; // Review : better value to initialize it to?

    if (pfnRtlGenRandom == NULL) {
        PGENRANDOM encoded;
        void* enull;
        // Advapi32.dll is unloaded when the App exits.
        HMODULE hAdvApi32 = LoadLibrary("ADVAPI32.DLL");

        if (!hAdvApi32) {
            _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), EINVAL);
        }

        pfnRtlGenRandom = (PGENRANDOM) GetProcAddress(hAdvApi32, _TO_STR(RtlGenRandom));

        if (pfnRtlGenRandom == NULL) {
            _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), _get_errno_from_oserr(GetLastError()));
        }

        encoded = (PGENRANDOM) _encode_pointer(pfnRtlGenRandom);
        enull = _encoded_null();
#ifdef _M_IX86

        if ((void*)(LONG_PTR)InterlockedExchange(
                    (LONG*)&g_pfnRtlGenRandom,
                    (LONG)(LONG_PTR)encoded)
                != enull)
#else  /* _M_IX86 */
        if (InterlockedExchangePointer(
                    (void**)&g_pfnRtlGenRandom,
                    (void*)encoded)
                != enull)
#endif  /* _M_IX86 */
        {
            /* A different thread has already loaded advapi32.dll. */
            FreeLibrary(hAdvApi32);
        }
    }

    if (!(*pfnRtlGenRandom)(_RandomValue, (ULONG)sizeof(unsigned int))) {
        errno = ENOMEM;
        return errno;
    }

    return 0;
}
Esempio n. 9
0
errno_t __cdecl _get_fmode(int* pMode) {
    _VALIDATE_RETURN_ERRCODE((pMode != NULL), EINVAL);
    _BEGIN_SECURE_CRT_DEPRECATION_DISABLE
    *pMode = _fmode;
    _END_SECURE_CRT_DEPRECATION_DISABLE
    return 0;
}
Esempio n. 10
0
errno_t __cdecl _set_fmode(int mode) {
    _VALIDATE_RETURN_ERRCODE(((mode == _O_TEXT) || (mode == _O_BINARY) || (mode == _O_WTEXT)), EINVAL);
    _BEGIN_SECURE_CRT_DEPRECATION_DISABLE
    InterlockedExchange(&_fmode, mode);
    _END_SECURE_CRT_DEPRECATION_DISABLE
    return 0;
}
Esempio n. 11
0
extern "C" errno_t __cdecl wcrtomb_s(
        size_t *pRetValue,
        char *dst,
        size_t sizeInBytes,
        wchar_t wchar,
        mbstate_t *pst
        )
{
    int retValue = -1;
    errno_t e;

    /* validation section */
    /* note that we do not force sizeInBytes > 0 in the dst != NULL case, because we do not need to add
     * null terminator, due that dst will receive a character and not a string
     */
    _VALIDATE_RETURN_ERRCODE((dst == NULL && sizeInBytes == 0) || (dst != NULL), EINVAL);

    if (dst == NULL)
    {
        char buf[MB_LEN_MAX];
        e = _wcrtomb_s_l(&retValue, buf, MB_LEN_MAX, wchar, pst, NULL);
    }
    else
    {
        e = _wcrtomb_s_l(&retValue, dst, sizeInBytes, wchar, pst, NULL);
    }

    if (pRetValue != NULL)
    {
        (*pRetValue) = (size_t)retValue;
    }
    return e;
}
Esempio n. 12
0
_CRTIMP errno_t __cdecl _ftime64_s (
        struct __timeb64 *tp
        )
{
        FT nt_time;
        __time64_t t;
        TIME_ZONE_INFORMATION tzinfo;
        DWORD tzstate;
        long timezone = 0;

        _VALIDATE_RETURN_ERRCODE( ( tp != NULL ), EINVAL )

        __tzset();

        _ERRCHECK(_get_timezone(&timezone));
        tp->timezone = (short)(timezone / 60);

        GetSystemTimeAsFileTime( &(nt_time.ft_struct) );

        /*
         * Obtain the current DST status. Note the status is cached and only
         * updated once per minute, if necessary.
         */
        if ( (t = (__time64_t)(nt_time.ft_scalar / 600000000i64))
             != elapsed_minutes_cache )
        {
            if ( (tzstate = GetTimeZoneInformation( &tzinfo )) != 0xFFFFFFFF )
            {
                /*
                 * Must be very careful in determining whether or not DST is
                 * really in effect.
                 */
                if ( (tzstate == TIME_ZONE_ID_DAYLIGHT) &&
                     (tzinfo.DaylightDate.wMonth != 0) &&
                     (tzinfo.DaylightBias != 0) )
                    dstflag_cache = DAYLIGHT_TIME;
                else
                    /*
                     * When in doubt, assume standard time
                     */
                    dstflag_cache = STANDARD_TIME;
            }
            else
                dstflag_cache = UNKNOWN_TIME;

            elapsed_minutes_cache = t;
        }

        tp->dstflag = (short)dstflag_cache;

        tp->millitm = (unsigned short)((nt_time.ft_scalar / 10000i64) %
                      1000i64);

        tp->time = (__time64_t)((nt_time.ft_scalar - EPOCH_BIAS) / 10000000i64);

        return 0;
}
Esempio n. 13
0
extern "C" errno_t __cdecl wmemmove_s(
    wchar_t*       const destination,
    size_t         const size_in_elements,
    wchar_t const* const source,
    size_t         const count
    )
{
    if (count == 0)
        return 0;

#pragma warning(suppress:__WARNING_HIGH_PRIORITY_OVERFLOW_POSTCONDITION)
    _VALIDATE_RETURN_ERRCODE(destination != nullptr, EINVAL);
    _VALIDATE_RETURN_ERRCODE(source != nullptr, EINVAL);
    _VALIDATE_RETURN_ERRCODE(size_in_elements >= count, ERANGE);

#pragma warning(suppress:__WARNING_BANNED_API_USAGEL2 __WARNING_BUFFER_COPY_NO_KNOWN_SIZEEXPR) /* 28726 22104 */
    wmemmove(destination, source, count);
    return 0;
}
Esempio n. 14
0
static errno_t __cdecl common_freopen(
    FILE**             const result,
    Character const*   const file_name,
    Character const*   const mode,
    __crt_stdio_stream const stream,
    int                const share_flag
    ) throw()
{
    typedef __acrt_stdio_char_traits<Character> stdio_traits;

    _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL);
    *result = nullptr;

    // C11 7.21.5.4/3:  "If filename is a null pointer, the freopen function
    // attempts to change the mode of the stream to that specified by mode, as
    // if the name of the file currently associated with the stream had been
    // used. It is implementation-defined which changes of mode are permitted
    // (if any), and under what circumstances."
    //
    // In our implementation, we do not currently support changing the mode
    // in this way.  In the future, we might consider use of ReOpenFile to
    // implement support for changing the mode.
    _VALIDATE_RETURN_ERRCODE_NOEXC(file_name != nullptr, EBADF);

    _VALIDATE_RETURN_ERRCODE(mode      != nullptr, EINVAL);
    _VALIDATE_RETURN_ERRCODE(stream.valid()      , EINVAL);

    // Just as in the common_fsopen function, we do not hard-validate empty
    // 'file_name' strings in this function:
    _VALIDATE_RETURN_ERRCODE_NOEXC(*file_name != 0, EINVAL);

    errno_t return_value = 0;

    _lock_file(stream.public_stream());
    __try
    {
        // If the stream is in use, try to close it, ignoring possible errors:
        if (stream.is_in_use())
            _fclose_nolock(stream.public_stream());

        stream->_ptr  = nullptr;
        stream->_base = nullptr;
        stream->_cnt  = 0;
        stream.unset_flags(-1);

        // We may have called fclose above, which will deallocate the stream.
        // We still hold the lock on the stream, though, so we can just reset
        // the allocated flag to retain ownership.
        stream.set_flags(_IOALLOCATED);

        *result = stdio_traits::open_file(file_name, mode, share_flag, stream.public_stream());
        if (*result == nullptr)
        {
            stream.unset_flags(_IOALLOCATED);
            return_value = errno;
        }
    }
    __finally
    {
        _unlock_file(stream.public_stream());
    }

    return return_value;
}
Esempio n. 15
0
extern "C" errno_t __cdecl _mbsupr_s_l(
        unsigned char *string,
        size_t sizeInBytes,
        _locale_t plocinfo
        )
{
        size_t stringlen;

        /* validation section */
        _VALIDATE_RETURN_ERRCODE((string != nullptr && sizeInBytes > 0) || (string == nullptr && sizeInBytes == 0), EINVAL);

        if (string == nullptr)
        {
            /* nothing to do */
            return 0;
        }

        stringlen = strnlen((char *)string, sizeInBytes);
        if (stringlen >= sizeInBytes)
        {
            _RESET_STRING(string, sizeInBytes);
            _RETURN_DEST_NOT_NULL_TERMINATED(string, sizeInBytes);
        }
        _FILL_STRING(string, sizeInBytes, stringlen + 1);

        unsigned char *cp, *dst;
        _LocaleUpdate _loc_update(plocinfo);

        for (cp = string, dst = string; *cp; ++cp)
        {
            if ( _ismbblead_l(*cp, _loc_update.GetLocaleT()) )
            {


                int retval;
                unsigned char ret[4];

                if ( (retval = __acrt_LCMapStringA(
                                _loc_update.GetLocaleT(),
                                _loc_update.GetLocaleT()->mbcinfo->mblocalename,
                                LCMAP_UPPERCASE,
                                (const char *)cp,
                                2,
                                (char *)ret,
                                2,
                                _loc_update.GetLocaleT()->mbcinfo->mbcodepage,
                                TRUE )) == 0 )
                {
                    errno = EILSEQ;
                    _RESET_STRING(string, sizeInBytes);
                    return errno;
                }

                *(dst++) = ret[0];
                ++cp;
                if (retval > 1)
                {
                    *(dst++) = ret[1];
                }


            }
            else
                /* single byte, macro version */
                *(dst++) = (unsigned char) _mbbtoupper_l(*cp, _loc_update.GetLocaleT());
        }
        /* null terminate the string */
        *dst = '\0';

        return 0;
}
Esempio n. 16
0
extern "C" int __cdecl _wctomb_s_l (
        int *pRetValue,
        char *dst,
        size_t sizeInBytes,
        wchar_t wchar,
        _locale_t plocinfo
        )
{
    if (dst == NULL && sizeInBytes > 0)
    {
        /* indicate do not have state-dependent encodings */
        if (pRetValue != NULL)
        {
            *pRetValue = 0;
        }
        return 0;
    }

    if (pRetValue != NULL)
    {
        *pRetValue = -1;
    }

    /* validation section */
    /* we need to cast sizeInBytes to int, so we make sure we are not going to truncate sizeInBytes */
    _VALIDATE_RETURN_ERRCODE(sizeInBytes <= INT_MAX, EINVAL);


    _LocaleUpdate _loc_update(plocinfo);

    if ( _loc_update.GetLocaleT()->locinfo->lc_handle[LC_CTYPE] == _CLOCALEHANDLE )
    {
        if ( wchar > 255 )  /* validate high byte */
        {
            if (dst != NULL && sizeInBytes > 0)
            {
                memset(dst, 0, sizeInBytes);
            }
            errno = EILSEQ;
            return errno;
        }

        if (dst != NULL)
        {
            _VALIDATE_RETURN_ERRCODE(sizeInBytes > 0, ERANGE);
            *dst = (char) wchar;
        }
        if (pRetValue != NULL)
        {
            *pRetValue = 1;
        }
        return 0;
    }
    else
    {
        int size;
        BOOL defused = 0;

        if ( ((size = WideCharToMultiByte( _loc_update.GetLocaleT()->locinfo->lc_codepage,
                                           0,
                                           &wchar,
                                           1,
                                           dst,
                                           (int)sizeInBytes,
                                           NULL,
                                           &defused) ) == 0) ||
             (defused) )
        {
            if (size == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                if (dst != NULL && sizeInBytes > 0)
                {
                    memset(dst, 0, sizeInBytes);
                }
                _VALIDATE_RETURN_ERRCODE(("Buffer too small", 0), ERANGE);
            }
            errno = EILSEQ;
            return errno;
        }

        if (pRetValue != NULL)
        {
            *pRetValue = size;
        }
        return 0;
    }

}
Esempio n. 17
0
errno_t __cdecl rand_s
(
    unsigned int *_RandomValue
)
{
    PGENRANDOM pfnRtlGenRandom = (PGENRANDOM) DecodePointer(g_pfnRtlGenRandom);
    _VALIDATE_RETURN_ERRCODE( _RandomValue != NULL, EINVAL );
    *_RandomValue = 0; // Review : better value to initialize it to?

    if ( pfnRtlGenRandom == NULL )
    {
        PGENRANDOM encoded;
        void* enull;
#ifdef _CORESYS
#define RAND_DLL L"cryptbase.dll"
#else  /* _CORESYS */
#define RAND_DLL L"ADVAPI32.DLL"
#endif  /* _CORESYS */
        // advapi32.dll/cryptbase.dll is unloaded when the App exits.
        HMODULE hRandDll = LoadLibraryExW(RAND_DLL, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
#ifndef _CORESYS
        if (!hRandDll && GetLastError() == ERROR_INVALID_PARAMETER)
        {
            // LOAD_LIBRARY_SEARCH_SYSTEM32 is not supported on this platfrom,
            // try one more time using default options
            hRandDll = LoadLibraryExW(RAND_DLL, NULL, 0);
        }
#endif  /* _CORESYS */
        if (!hRandDll)
        {
            _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), EINVAL);
        }

        pfnRtlGenRandom = ( PGENRANDOM ) GetProcAddress( hRandDll, _TO_STR( RtlGenRandom ) );
        if ( pfnRtlGenRandom == NULL )
        {
            _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), _get_errno_from_oserr(GetLastError()));
        }
        encoded = (PGENRANDOM) EncodePointer(pfnRtlGenRandom);
        enull = EncodePointer(NULL);
#ifdef _M_IX86
        if ( (void*)(LONG_PTR)InterlockedExchange(
                ( LONG* )&g_pfnRtlGenRandom,
                ( LONG )( LONG_PTR )encoded)
            != enull )
#else  /* _M_IX86 */
        if ( InterlockedExchangePointer(
                ( void** )&g_pfnRtlGenRandom,
                ( void* )encoded)
            != enull )
#endif  /* _M_IX86 */
        {
            /* A different thread has already loaded advapi32.dll/cryptbase.dll. */
            FreeLibrary( hRandDll );
        }
    }

    if ( !(*pfnRtlGenRandom)( _RandomValue, ( ULONG )sizeof( unsigned int ) ) )
    {
        errno = ENOMEM;
        return errno;
    }
    return 0;
}
Esempio n. 18
0
static errno_t __cdecl common_configure_argv(_crt_argv_mode const mode) throw()
{
    typedef __crt_char_traits<Character> traits;

    _VALIDATE_RETURN_ERRCODE(
        mode == _crt_argv_expanded_arguments ||
        mode == _crt_argv_unexpanded_arguments, EINVAL);

    do_locale_initialization(Character());

    
    static Character program_name[MAX_PATH + 1];
    traits::get_module_file_name(nullptr, program_name, MAX_PATH);
    traits::set_program_name(&program_name[0]);

    // If there's no command line at all, then use the program name as the
    // command line to parse, so that argv[0] is initialized with the program
    // name.  (This won't happen when the program is run by cmd.exe, but it
    // could happen if the program is spawned via some other means.)
    Character* const raw_command_line = get_command_line(Character());
    Character* const command_line = raw_command_line == nullptr || raw_command_line[0] == '\0'
        ? program_name
        : raw_command_line;

    size_t argument_count  = 0;
    size_t character_count = 0;
    parse_command_line(
        command_line,
        static_cast<Character**>(nullptr),
        static_cast<Character*>(nullptr),
        &argument_count,
        &character_count);

    __crt_unique_heap_ptr<unsigned char> buffer(__acrt_allocate_buffer_for_argv(
        argument_count,
        character_count,
        sizeof(Character)));

    _VALIDATE_RETURN_ERRCODE_NOEXC(buffer, ENOMEM);

    Character** const first_argument = reinterpret_cast<Character**>(buffer.get());
    Character*  const first_string   = reinterpret_cast<Character*>(buffer.get() + argument_count * sizeof(Character*));

    parse_command_line(command_line, first_argument, first_string, &argument_count, &character_count);

    // If we are not expanding wildcards, then we are done...
    if (mode == _crt_argv_unexpanded_arguments)
    {
        __argc = static_cast<int>(argument_count - 1);
        get_argv(Character()) = reinterpret_cast<Character**>(buffer.detach());
        return 0;
    }

    // ... otherwise, we try to do the wildcard expansion:
    __crt_unique_heap_ptr<Character*> expanded_argv;
    errno_t const argv_expansion_status = expand_argv_wildcards(first_argument, expanded_argv.get_address_of());
    if (argv_expansion_status != 0)
        return argv_expansion_status;

    __argc = [&]()
    {
        size_t n = 0;
        for (auto it = expanded_argv.get(); *it; ++it, ++n) { }
        return static_cast<int>(n);
    }();

    get_argv(Character()) = expanded_argv.detach();
    return 0;
}
Esempio n. 19
0
static errno_t __cdecl _wcslwr_s_l_stat (
        wchar_t * wsrc,
        size_t sizeInWords,
        _locale_t plocinfo
        )
{

    wchar_t *p;             /* traverses string for C locale conversion */
    wchar_t *wdst;          /* wide version of string in alternate case */
    int dstsize;            /* size in wide chars of wdst string buffer (include null) */
    errno_t e = 0;
    size_t stringlen;

    /* validation section */
    _VALIDATE_RETURN_ERRCODE(wsrc != NULL, EINVAL);
    stringlen = wcsnlen(wsrc, sizeInWords);
    if (stringlen >= sizeInWords)
    {
        _RESET_STRING(wsrc, sizeInWords);
        _RETURN_DEST_NOT_NULL_TERMINATED(wsrc, sizeInWords);
    }
    _FILL_STRING(wsrc, sizeInWords, stringlen + 1);

    if ( plocinfo->locinfo->locale_name[LC_CTYPE] == NULL)
    {
        for ( p = wsrc ; *p ; p++ )
        {
            if ( (*p >= (wchar_t)L'A') && (*p <= (wchar_t)L'Z') )
            {
                *p -= L'A' - L'a';
            }
        }

        return 0;
    }   /* C locale */

    /* Inquire size of wdst string */
    if ( (dstsize = __crtLCMapStringW(
                    plocinfo->locinfo->locale_name[LC_CTYPE],
                    LCMAP_LOWERCASE,
                    wsrc,
                    -1,
                    NULL,
                    0
                    )) == 0 )
    {
        errno = EILSEQ;
        return errno;
    }

    if (sizeInWords < (size_t)dstsize)
    {
        _RESET_STRING(wsrc, sizeInWords);
        _RETURN_BUFFER_TOO_SMALL(wsrc, sizeInWords);
    }

    /* Allocate space for wdst */
    wdst = (wchar_t *)_calloca(dstsize, sizeof(wchar_t));
    if (wdst == NULL)
    {
        errno = ENOMEM;
        return errno;
    }

    /* Map wrc string to wide-character wdst string in alternate case */
    if (__crtLCMapStringW(
                plocinfo->locinfo->locale_name[LC_CTYPE],
                LCMAP_LOWERCASE,
                wsrc,
                -1,
                wdst,
                dstsize
                ) != 0)
    {
        /* Copy wdst string to user string */
        e = wcscpy_s(wsrc, sizeInWords, wdst);
    }
    else
    {
        e = errno = EILSEQ;
    }

    _freea(wdst);

    return e;
}
Esempio n. 20
0
errno_t __cdecl _fptostr(
    char* buf,
    size_t sizeInBytes,
    REG4 int digits,
    REG3 STRFLT pflt
) {
    REG1 char* pbuf = buf;
    REG2 char* mantissa = pflt->mantissa;
    /* validation section */
    _VALIDATE_RETURN_ERRCODE(buf != NULL, EINVAL);
    _VALIDATE_RETURN_ERRCODE(sizeInBytes > 0, EINVAL);
    buf[0] = '\0';
    /* the buffer will contains ndec decimal digits plus an optional
     * overflow digit for the rounding
     */
    _VALIDATE_RETURN_ERRCODE(sizeInBytes > (size_t)((digits > 0 ? digits : 0) + 1), ERANGE);
    _VALIDATE_RETURN_ERRCODE(pflt != NULL, EINVAL);
    /* initialize the first digit in the buffer to '0' (NOTE - NOT '\0')
     * and set the pointer to the second digit of the buffer.  The first
     * digit is used to handle overflow on rounding (e.g. 9.9999...
     * becomes 10.000...) which requires a carry into the first digit.
     */
    *pbuf++ = '0';

    /* Copy the digits of the value into the buffer (with 0 padding)
     * and insert the terminating null character.
     */

    while (digits > 0) {
        *pbuf++ = (*mantissa) ? *mantissa++ : (char)'0';
        digits--;
    }

    *pbuf = '\0';

    /* do any rounding which may be needed.  Note - if digits < 0 don't
     * do any rounding since in this case, the rounding occurs in  a digit
     * which will not be output beause of the precision requested
     */

    if (digits >= 0 && *mantissa >= '5') {
        pbuf--;

        while (*pbuf == '9') {
            *pbuf-- = '0';
        }

        *pbuf += 1;
    }

    if (*buf == '1') {
        /* the rounding caused overflow into the leading digit (e.g.
         * 9.999.. went to 10.000...), so increment the decpt position
         * by 1
         */
        pflt->decpt++;
    } else {
        /* move the entire string to the left one digit to remove the
         * unused overflow digit.
         */
        memmove(buf, buf + 1, strlen(buf + 1) + 1);
    }

    return 0;
}
Esempio n. 21
0
static errno_t __cdecl common_localtime_s(
    tm*             const ptm,
    TimeType const* const ptime
    ) throw()
{
    typedef __crt_time_time_t_traits<TimeType> time_traits;

    _VALIDATE_RETURN_ERRCODE(ptm != nullptr, EINVAL);
    memset(ptm, 0xff, sizeof(tm));

    _VALIDATE_RETURN_ERRCODE(ptime != nullptr, EINVAL);

    // Check for illegal time_t value:
    _VALIDATE_RETURN_ERRCODE_NOEXC(*ptime >= 0,                       EINVAL);
    _VALIDATE_RETURN_ERRCODE_NOEXC(*ptime <= time_traits::max_time_t, EINVAL);

    __tzset();

    int  daylight = 0;
    long dstbias  = 0;
    long timezone = 0;
    _ERRCHECK(_get_daylight(&daylight));
    _ERRCHECK(_get_dstbias (&dstbias ));
    _ERRCHECK(_get_timezone(&timezone));

    if (*ptime > 3 * _DAY_SEC && *ptime < time_traits::max_time_t - 3 * _DAY_SEC)
    {
        // The date does not fall within the first three or last three representable
        // days; therefore, there is no possibility of overflowing or underflowing
        // the time_t representation as we compensate for time zone and daylight
        // savings time.
        TimeType ltime = *ptime - timezone;

        errno_t status0 = time_traits::gmtime_s(ptm, &ltime);
        if (status0 != 0)
            return status0;

        // Check and adjust for daylight savings time:
        if (daylight && _isindst(ptm))
        {
            ltime -= dstbias;
            
            errno_t const status1 = time_traits::gmtime_s(ptm, &ltime);
            if (status1 != 0)
                return status1;

            ptm->tm_isdst = 1;
        }
    }
    else
    {
        // The date falls within the first three or last three representable days;
        // therefore, it is possible that the time_t representation would overflow
        // or underflow while compensating for time zone and daylight savings time.
        // Therefore, we make the time zone and daylight savings time adjustments
        // directly in the tm structure.
        errno_t const status0 = time_traits::gmtime_s(ptm, ptime);
        if (status0 != 0)
            return status0;

        TimeType ltime = static_cast<TimeType>(ptm->tm_sec);

        // First, adjust for the time zone:
        if (daylight && _isindst(ptm))
        {
            ltime -= (timezone + dstbias);
            ptm->tm_isdst = 1;
        }
        else
        {
            ltime -= timezone;
        }

        ptm->tm_sec = static_cast<int>(ltime % 60);
        if (ptm->tm_sec < 0)
        {
            ptm->tm_sec += 60;
            ltime -= 60;
        }

        ltime = static_cast<TimeType>(ptm->tm_min) + ltime / 60;
        ptm->tm_min = static_cast<int>(ltime % 60);
        if (ptm->tm_min < 0)
        {
            ptm->tm_min += 60;
            ltime -= 60;
        }

        ltime = static_cast<TimeType>(ptm->tm_hour) + ltime / 60;
        ptm->tm_hour = static_cast<int>(ltime % 24);
        if (ptm->tm_hour < 0)
        {
            ptm->tm_hour += 24;
            ltime -=24;
        }

        ltime /= 24;

        if (ltime > 0)
        {
            // There is no possibility of overflowing the tm_day and tm_yday
            // members because the date can be no later than January 19.
            ptm->tm_wday = (ptm->tm_wday + static_cast<int>(ltime)) % 7;
            ptm->tm_mday += static_cast<int>(ltime);
            ptm->tm_yday += static_cast<int>(ltime);
        }
        else if (ltime < 0)
        {
            // It is possible to underflow the tm_mday and tm_yday fields.  If
            // this happens, then the adjusted date must lie in December 1969:
            ptm->tm_wday = (ptm->tm_wday + 7 + static_cast<int>(ltime)) % 7;
            ptm->tm_mday += static_cast<int>(ltime);
            if (ptm->tm_mday <= 0)
            {
                ptm->tm_mday += 31;

                // Per assumption #4 above, the time zone can cause the date to
                // underflow the epoch by more than a day.
                ptm->tm_yday = ptm->tm_yday + static_cast<int>(ltime) + 365;
                ptm->tm_mon = 11;
                ptm->tm_year--;
            }
            else
            {
                ptm->tm_yday += static_cast<int>(ltime);
            }
        }
    }

    return 0;
}
Esempio n. 22
0
errno_t __cdecl _tasctime_s (
    _TSCHAR *buffer,
    size_t sizeInChars,
    const struct tm *tb
    )
{
    _TSCHAR *p = buffer;
    int day, mon;
    int i;

    _VALIDATE_RETURN_ERRCODE(
        ( buffer != NULL ) && ( sizeInChars > 0 ),
        EINVAL
    )

    _RESET_STRING(buffer, sizeInChars);

    _VALIDATE_RETURN_ERRCODE(
        ( sizeInChars >= _ASCBUFSIZE ),
        EINVAL
    )
    _VALIDATE_RETURN_ERRCODE(
        ( tb != NULL ),
        EINVAL
    )
    _VALIDATE_RETURN_ERRCODE(
        ( tb->tm_year >= 0 ),
        EINVAL
    )
    // month 0 based
    _VALIDATE_RETURN_ERRCODE(
        ( ( tb->tm_mon  >= 0 ) && ( tb->tm_mon  <= 11 ) ),
        EINVAL
    )
    // hour/min/sec 0 based
    _VALIDATE_RETURN_ERRCODE(
        ( ( tb->tm_hour >= 0 ) && ( tb->tm_hour <= 23 ) ),
        EINVAL
    )
    _VALIDATE_RETURN_ERRCODE(
        ( ( tb->tm_min  >= 0 ) && ( tb->tm_min  <= 59 ) ),
        EINVAL
    )
    _VALIDATE_RETURN_ERRCODE(
        ( ( tb->tm_sec  >= 0 ) && ( tb->tm_sec  <= 59 ) ),
        EINVAL
    )
    // day 1 based
    _VALIDATE_RETURN_ERRCODE(
        (
            ( tb->tm_mday >= 1 ) &&
            (
                // Day is in valid range for the month
                ( ( _days[ tb->tm_mon + 1 ] - _days[ tb->tm_mon ] ) >=
                        tb->tm_mday ) ||
                // Special case for Feb in a leap year
                (
                    ( IS_LEAP_YEAR( tb->tm_year + 1900 ) ) &&
                    ( tb->tm_mon == 1 ) &&
                    ( tb->tm_mday <= 29 )
                )
            )
        ),
        EINVAL
    )
    // week day 0 based
    _VALIDATE_RETURN_ERRCODE(
        ( ( tb->tm_wday >= 0 ) && ( tb->tm_wday <= 6 ) ),
        EINVAL
    )


    /* copy day and month names into the buffer */

    day = tb->tm_wday * 3;      /* index to correct day string */
    mon = tb->tm_mon * 3;       /* index to correct month string */
    for (i=0; i < 3; i++,p++) {
        *p = *(__dnames + day + i);
        *(p+4) = *(__mnames + mon + i);
    }

    *p = _T(' ');           /* blank between day and month */

    p += 4;

    *p++ = _T(' ');
    p = store_dt(p, tb->tm_mday);   /* day of the month (1-31) */
    *p++ = _T(' ');
    p = store_dt(p, tb->tm_hour);   /* hours (0-23) */
    *p++ = _T(':');
    p = store_dt(p, tb->tm_min);    /* minutes (0-59) */
    *p++ = _T(':');
    p = store_dt(p, tb->tm_sec);    /* seconds (0-59) */
    *p++ = _T(' ');
    p = store_dt(p, 19 + (tb->tm_year/100)); /* year (after 1900) */
    p = store_dt(p, tb->tm_year%100);
    *p++ = _T('\n');
    *p = _T('\0');


    return 0;
}
Esempio n. 23
0
extern "C" errno_t __cdecl _gcvt_s (
        char *buf,
        size_t sizeInChars,
        double value,
        int ndec
        )
{
        STRFLT string;
        int    magnitude;
        _CRT_DOUBLE *pdvalue = (_CRT_DOUBLE *)&value;

        char *str;
        char *stop;
        errno_t e;
    _locale_t plocinfo = NULL;
    _LocaleUpdate _loc_update(plocinfo);
        struct _strflt strfltstruct;    /* temporary buffers */
        char   resultstring[22 /* MAX_MAN_DIGITS+1 */];

        /* validation section */
        _VALIDATE_RETURN_ERRCODE(buf != NULL, EINVAL);
        _VALIDATE_RETURN_ERRCODE(sizeInChars > 0, EINVAL);
        _RESET_STRING(buf, sizeInChars);
        _VALIDATE_RETURN_ERRCODE((size_t)ndec < sizeInChars, ERANGE);
        /* _cftoe and _cftof (used below) are more strict in validating sizeInChars */

        /* get the magnitude of the number */

        string = _fltout2( *pdvalue, &strfltstruct, resultstring, _countof(resultstring) );

        magnitude = string->decpt - 1;

        /* output the result according to the Fortran G format as outlined in
           Fortran language specification */

        if ( magnitude < -1  ||  magnitude > ndec-1 )
                /* then  Ew.d  d = ndec */
                e = _cftoe( &value, buf, sizeInChars, ndec-1, 0);
        else
                /* Fw.d  where d = ndec-string->decpt */
                e = _cftof( &value, buf, sizeInChars, ndec-string->decpt );

        if (e == 0)
        {
                /* remove the trailing zeroes before the exponent; we don't need to check for sizeInChars */
                str = buf;
                while (*str && *str != *__LCONV(_loc_update.GetLocaleT()->locinfo)->decimal_point)
                        str++;

                if (*str++)
                {
                        while (*str && *str != 'e')
                                str++;

                        stop = str--;

                        while (*str == '0')
                                str--;

                        while (*++str = *stop++)
                                ;
                }
        }
        else
        {
                errno = e;
        }

        return e;
}