errno_t _gmtime64_s( struct tm* ptm, const __time64_t* ptime) { __time64_t time; if (!ptm) { MSVCRT_INVALID_PMT("ptm == NULL", ERROR_BAD_COMMAND); return ERROR_BAD_COMMAND; } if (!ptime) { MSVCRT_INVALID_PMT("ptime == NULL", ERROR_BAD_COMMAND); return ERROR_BAD_COMMAND; } time = *ptime; _gmtime_worker(ptm, time, 0); return ERROR_SUCCESS; }
/********************************************************************* * wcsncat_s (MSVCRT.@) * */ INT CDECL wcsncat_s(wchar_t *dst, size_t elem, const wchar_t *src, size_t count) { size_t srclen; wchar_t dststart; INT ret = 0; if (!MSVCRT_CHECK_PMT(dst != NULL) || !MSVCRT_CHECK_PMT(elem > 0)) { #ifndef _LIBCNT_ _set_errno(EINVAL); #endif return EINVAL; } if (!MSVCRT_CHECK_PMT(src != NULL || count == 0)) return EINVAL; if (count == 0) return 0; for (dststart = 0; dststart < elem; dststart++) { if (dst[dststart] == '\0') break; } if (dststart == elem) { MSVCRT_INVALID_PMT("dst[elem] is not NULL terminated\n", EINVAL); return EINVAL; } if (count == _TRUNCATE) { srclen = strlenW(src); if (srclen >= (elem - dststart)) { srclen = elem - dststart - 1; ret = STRUNCATE; } } else srclen = min(strlenW(src), count); if (srclen < (elem - dststart)) { memcpy(&dst[dststart], src, srclen*sizeof(wchar_t)); dst[dststart+srclen] = '\0'; return ret; } MSVCRT_INVALID_PMT("dst[elem] is too small", ERANGE); dst[0] = '\0'; return ERANGE; }
/********************************************************************** * __wcserror_s (MSVCRT.@) */ int CDECL MSVCRT___wcserror_s(MSVCRT_wchar_t* buffer, MSVCRT_size_t nc, const MSVCRT_wchar_t* str) { int err; static const WCHAR colonW[] = {':', ' ', '\0'}; static const WCHAR nlW[] = {'\n', '\0'}; size_t len; err = *MSVCRT__errno(); if (err < 0 || err > MSVCRT__sys_nerr) err = MSVCRT__sys_nerr; len = MultiByteToWideChar(CP_ACP, 0, MSVCRT__sys_errlist[err], -1, NULL, 0) + 1 /* \n */; if (str && *str) len += lstrlenW(str) + 2 /* ': ' */; if (len > nc) { MSVCRT_INVALID_PMT("buffer[nc] is too small", MSVCRT_ERANGE); return MSVCRT_ERANGE; } if (str && *str) { lstrcpyW(buffer, str); lstrcatW(buffer, colonW); } else buffer[0] = '\0'; len = lstrlenW(buffer); MultiByteToWideChar(CP_ACP, 0, MSVCRT__sys_errlist[err], -1, buffer + len, 256 - len); lstrcatW(buffer, nlW); return 0; }
/* * @implemented */ int _ui64tow_s( unsigned __int64 value, wchar_t *str, size_t size, int radix ) { wchar_t buffer[65], *pos; int digit; if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) || !MSVCRT_CHECK_PMT(radix>=2) || !MSVCRT_CHECK_PMT(radix<=36)) { #ifndef _LIBCNT_ *_errno() = EINVAL; #endif return EINVAL; } pos = &buffer[64]; *pos = '\0'; do { digit = value % radix; value = value / radix; if (digit < 10) *--pos = '0' + digit; else *--pos = 'a' + digit - 10; } while (value != 0); if((size_t)(buffer-pos+65) > size) { MSVCRT_INVALID_PMT("str[size] is too small", EINVAL); return EINVAL; } memcpy(str, pos, buffer-pos+65); return 0; }
/********************************************************************* * strncpy_s (MSVCRT.@) */ int CDECL strncpy_s(char *dest, size_t numberOfElements, const char *src, size_t count) { size_t i, end; TRACE("(%s %lu %s %lu)\n", dest, numberOfElements, src, count); if(!count) return 0; if (!MSVCRT_CHECK_PMT(dest != NULL) || !MSVCRT_CHECK_PMT(src != NULL) || !MSVCRT_CHECK_PMT(numberOfElements != 0)) { *_errno() = EINVAL; return EINVAL; } if(count!=_TRUNCATE && count<numberOfElements) end = count; else end = numberOfElements-1; for(i=0; i<end && src[i]; i++) dest[i] = src[i]; if(!src[i] || end==count || count==_TRUNCATE) { dest[i] = '\0'; return 0; } MSVCRT_INVALID_PMT("dest[numberOfElements] is too small"); dest[0] = '\0'; *_errno() = EINVAL; return EINVAL; }
/********************************************************************* * strncpy_s (MSVCRT.@) */ int CDECL MSVCRT_strncpy_s(char *dest, MSVCRT_size_t numberOfElements, const char *src, MSVCRT_size_t count) { MSVCRT_size_t i, end; TRACE("(%p %lu %s %lu)\n", dest, numberOfElements, debugstr_a(src), count); if(!count) { if(dest && numberOfElements) *dest = 0; return 0; } if (!MSVCRT_CHECK_PMT(dest != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(src != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(numberOfElements != 0)) return MSVCRT_EINVAL; if(count!=MSVCRT__TRUNCATE && count<numberOfElements) end = count; else end = numberOfElements-1; for(i=0; i<end && src[i]; i++) dest[i] = src[i]; if(!src[i] || end==count || count==MSVCRT__TRUNCATE) { dest[i] = '\0'; return 0; } MSVCRT_INVALID_PMT("dest[numberOfElements] is too small", MSVCRT_EINVAL); dest[0] = '\0'; return MSVCRT_EINVAL; }
/********************************************************************* * MSVCRT_wcsrtombs_s_l (INTERNAL) */ static int MSVCRT_wcsrtombs_s_l(MSVCRT_size_t *ret, char *mbstr, MSVCRT_size_t size, const MSVCRT_wchar_t **wcstr, MSVCRT_size_t count, MSVCRT__locale_t locale) { MSVCRT_size_t conv; if(!mbstr && !size && wcstr) { conv = MSVCRT_wcsrtombs_l(NULL, wcstr, 0, locale); if(ret) *ret = conv+1; return 0; } if (!MSVCRT_CHECK_PMT(wcstr != NULL) || !MSVCRT_CHECK_PMT(*wcstr != NULL) || !MSVCRT_CHECK_PMT(mbstr != NULL)) { if(mbstr && size) mbstr[0] = '\0'; *MSVCRT__errno() = MSVCRT_EINVAL; return MSVCRT_EINVAL; } if(count==MSVCRT__TRUNCATE || size<count) conv = size; else conv = count; conv = MSVCRT_wcsrtombs_l(mbstr, wcstr, conv, locale); if(conv<size) mbstr[conv++] = '\0'; else if(conv==size && (count==MSVCRT__TRUNCATE || mbstr[conv-1]=='\0')) mbstr[conv-1] = '\0'; else { MSVCRT_INVALID_PMT("mbstr[size] is too small"); if(size) mbstr[0] = '\0'; *MSVCRT__errno() = MSVCRT_ERANGE; return MSVCRT_ERANGE; } if(ret) *ret = conv; return 0; }
/********************************************************************* * _wsearchenv_s (MSVCRT.@) */ int CDECL MSVCRT__wsearchenv_s(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t* env, MSVCRT_wchar_t *buf, MSVCRT_size_t count) { MSVCRT_wchar_t* envVal, *penv; MSVCRT_wchar_t curPath[MAX_PATH]; if (!MSVCRT_CHECK_PMT(file != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(buf != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(count > 0)) return MSVCRT_EINVAL; *buf = '\0'; /* Try CWD first */ if (GetFileAttributesW( file ) != INVALID_FILE_ATTRIBUTES) { if (GetFullPathNameW( file, count, buf, NULL )) return 0; msvcrt_set_errno(GetLastError()); return 0; } /* Search given environment variable */ envVal = MSVCRT__wgetenv(env); if (!envVal) { *MSVCRT__errno() = MSVCRT_ENOENT; return MSVCRT_ENOENT; } penv = envVal; TRACE(":searching for %s in paths %s\n", debugstr_w(file), debugstr_w(envVal)); do { MSVCRT_wchar_t *end = penv; while(*end && *end != ';') end++; /* Find end of next path */ if (penv == end || !*penv) { *MSVCRT__errno() = MSVCRT_ENOENT; return MSVCRT_ENOENT; } memcpy(curPath, penv, (end - penv) * sizeof(MSVCRT_wchar_t)); if (curPath[end - penv] != '/' && curPath[end - penv] != '\\') { curPath[end - penv] = '\\'; curPath[end - penv + 1] = '\0'; } else curPath[end - penv] = '\0'; strcatW(curPath, file); TRACE("Checking for file %s\n", debugstr_w(curPath)); if (GetFileAttributesW( curPath ) != INVALID_FILE_ATTRIBUTES) { if (strlenW(curPath) + 1 > count) { MSVCRT_INVALID_PMT("buf[count] is too small", MSVCRT_ERANGE); return MSVCRT_ERANGE; } strcpyW(buf, curPath); return 0; } penv = *end ? end + 1 : end; } while(1); }
/* * @implemented */ int _i64tow_s(__int64 value, wchar_t *str, size_t size, int radix) { unsigned __int64 val; unsigned int digit; int is_negative; wchar_t buffer[65], *pos; size_t len; if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) || !MSVCRT_CHECK_PMT(radix >= 2) || !MSVCRT_CHECK_PMT(radix <= 36)) { if (str && size) str[0] = '\0'; #ifndef _LIBCNT_ *_errno() = EINVAL; #endif return EINVAL; } if (value < 0 && radix == 10) { is_negative = 1; val = -value; } else { is_negative = 0; val = value; } pos = buffer + 64; *pos = '\0'; do { digit = val % radix; val /= radix; if (digit < 10) *--pos = '0' + digit; else *--pos = 'a' + digit - 10; } while (val != 0); if (is_negative) *--pos = '-'; len = buffer + 65 - pos; if (len > size) { size_t i; wchar_t *p = str; /* Copy the temporary buffer backwards up to the available number of * characters. Don't copy the negative sign if present. */ if (is_negative) { p++; size--; } for (pos = buffer + 63, i = 0; i < size; i++) *p++ = *pos--; MSVCRT_INVALID_PMT("str[size] is too small", ERANGE); str[0] = '\0'; return ERANGE; } memcpy(str, pos, len * sizeof(wchar_t)); return 0; }
/********************************************************************* * _searchenv_s (MSVCRT.@) */ int _tsearchenv_s(const _TCHAR* file, const _TCHAR* env, _TCHAR *buf, size_t count) { _TCHAR *envVal, *penv; _TCHAR curPath[MAX_PATH]; if (!MSVCRT_CHECK_PMT(file != NULL) || !MSVCRT_CHECK_PMT(buf != NULL) || !MSVCRT_CHECK_PMT(count > 0)) { *_errno() = EINVAL; return EINVAL; } *buf = '\0'; /* Try CWD first */ if (GetFileAttributes( file ) != INVALID_FILE_ATTRIBUTES) { GetFullPathName( file, MAX_PATH, buf, NULL ); _dosmaperr(GetLastError()); return 0; } /* Search given environment variable */ envVal = _tgetenv(env); if (!envVal) { _set_errno(ENOENT); return ENOENT; } penv = envVal; do { _TCHAR *end = penv; while(*end && *end != ';') end++; /* Find end of next path */ if (penv == end || !*penv) { _set_errno(ENOENT); return ENOENT; } memcpy(curPath, penv, (end - penv) * sizeof(_TCHAR)); if (curPath[end - penv] != '/' && curPath[end - penv] != '\\') { curPath[end - penv] = '\\'; curPath[end - penv + 1] = '\0'; } else curPath[end - penv] = '\0'; _tcscat(curPath, file); if (GetFileAttributes( curPath ) != INVALID_FILE_ATTRIBUTES) { if (_tcslen(curPath) + 1 > count) { MSVCRT_INVALID_PMT("buf[count] is too small", ERANGE); return ERANGE; } _tcscpy(buf, curPath); return 0; } penv = *end ? end + 1 : end; } while(1); }