/********************************************************************* * wcsftime (MSVCRT.@) */ MSVCRT_size_t CDECL MSVCRT_wcsftime( MSVCRT_wchar_t *str, MSVCRT_size_t max, const MSVCRT_wchar_t *format, const struct MSVCRT_tm *mstm ) { char *s, *fmt; MSVCRT_size_t len; TRACE("%p %ld %s %p\n", str, max, debugstr_w(format), mstm ); len = WideCharToMultiByte( CP_UNIXCP, 0, format, -1, NULL, 0, NULL, NULL ); if (!(fmt = MSVCRT_malloc( len ))) return 0; WideCharToMultiByte( CP_UNIXCP, 0, format, -1, fmt, len, NULL, NULL ); if ((s = MSVCRT_malloc( max*4 ))) { struct tm tm; msvcrt_tm_to_unix( &tm, mstm ); if (!strftime( s, max*4, fmt, &tm )) s[0] = 0; len = MultiByteToWideChar( CP_UNIXCP, 0, s, -1, str, max ); if (len) len--; MSVCRT_free( s ); } else len = 0; MSVCRT_free( fmt ); return len; }
/********************************************************************* * realloc (MSVCRT.@) */ void* CDECL DECLSPEC_HOTPATCH MSVCRT_realloc(void* ptr, MSVCRT_size_t size) { if (!ptr) return MSVCRT_malloc(size); if (size) return msvcrt_heap_realloc(0, ptr, size); MSVCRT_free(ptr); return NULL; }
/********************************************************************* * _kbhit (MSVCRT.@) */ int CDECL _kbhit(void) { int retval = 0; LOCK_CONSOLE; if (__MSVCRT_console_buffer != MSVCRT_EOF) retval = 1; else { /* FIXME: There has to be a faster way than this in Win32.. */ INPUT_RECORD *ir = NULL; DWORD count = 0, i; GetNumberOfConsoleInputEvents(MSVCRT_console_in, &count); if (count && (ir = MSVCRT_malloc(count * sizeof(INPUT_RECORD))) && PeekConsoleInputA(MSVCRT_console_in, ir, count, &count)) for(i = 0; i < count - 1; i++) { if (ir[i].EventType == KEY_EVENT && ir[i].Event.KeyEvent.bKeyDown && ir[i].Event.KeyEvent.uChar.AsciiChar) { retval = 1; break; } } MSVCRT_free(ir); } UNLOCK_CONSOLE; return retval; }
/********************************************************************* * _cprintf (MSVCRT.@) */ int CDECL _cprintf(const char* format, ...) { char buf[2048], *mem = buf; int written, resize = sizeof(buf), retval; __ms_va_list valist; __ms_va_start( valist, format ); /* There are two conventions for snprintf failing: * Return -1 if we truncated, or * Return the number of bytes that would have been written * The code below handles both cases */ while ((written = MSVCRT_vsnprintf( mem, resize, format, valist )) == -1 || written > resize) { resize = (written == -1 ? resize * 2 : written + 1); if (mem != buf) MSVCRT_free (mem); if (!(mem = MSVCRT_malloc(resize))) return MSVCRT_EOF; __ms_va_start( valist, format ); } __ms_va_end(valist); LOCK_CONSOLE; retval = _cputs( mem ); UNLOCK_CONSOLE; if (mem != buf) MSVCRT_free (mem); return retval; }
/********************************************************************* * realloc (MSVCRT.@) */ void* CDECL MSVCRT_realloc(void* ptr, MSVCRT_size_t size) { if (!ptr) return MSVCRT_malloc(size); if (size) return HeapReAlloc(GetProcessHeap(), 0, ptr, size); MSVCRT_free(ptr); return NULL; }
/* INTERNAL: Create a wide string from an ascii string */ MSVCRT_wchar_t *msvcrt_wstrdupa(const char *str) { const unsigned int len = strlen(str) + 1 ; MSVCRT_wchar_t *wstr = MSVCRT_malloc(len* sizeof (MSVCRT_wchar_t)); if (!wstr) return NULL; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,str,len,wstr,len); return wstr; }
/********************************************************************* * _wcserror (MSVCRT.@) */ MSVCRT_wchar_t* CDECL MSVCRT__wcserror(int err) { thread_data_t *data = msvcrt_get_thread_data(); if (!data->wcserror_buffer) if (!(data->wcserror_buffer = MSVCRT_malloc(256 * sizeof(MSVCRT_wchar_t)))) return NULL; MSVCRT__wcserror_s(data->wcserror_buffer, 256, err); return data->wcserror_buffer; }
/********************************************************************* * _mbsdup (MSVCRT.@) * _strdup (MSVCRT.@) */ char* CDECL MSVCRT__strdup(const char* str) { if(str) { char * ret = MSVCRT_malloc(strlen(str)+1); if (ret) strcpy( ret, str ); return ret; } else return 0; }
/********************************************************************* * _wcsdup (MSVCRT.@) */ MSVCRT_wchar_t* CDECL MSVCRT__wcsdup( const MSVCRT_wchar_t* str ) { MSVCRT_wchar_t* ret = NULL; if (str) { int size = (strlenW(str) + 1) * sizeof(MSVCRT_wchar_t); ret = MSVCRT_malloc( size ); if (ret) memcpy( ret, str, size ); } return ret; }
/********************************************************************* * strerror (MSVCRT.@) */ char* CDECL MSVCRT_strerror(int err) { thread_data_t *data = msvcrt_get_thread_data(); if (!data->strerror_buffer) if (!(data->strerror_buffer = MSVCRT_malloc(256))) return NULL; if (err < 0 || err > MSVCRT__sys_nerr) err = MSVCRT__sys_nerr; strcpy( data->strerror_buffer, MSVCRT__sys_errlist[err] ); return data->strerror_buffer; }
/********************************************************************** * __wcserror (MSVCRT.@) */ MSVCRT_wchar_t* CDECL MSVCRT___wcserror(const MSVCRT_wchar_t* str) { thread_data_t *data = msvcrt_get_thread_data(); int err; if (!data->wcserror_buffer) if (!(data->wcserror_buffer = MSVCRT_malloc(256 * sizeof(MSVCRT_wchar_t)))) return NULL; err = MSVCRT___wcserror_s(data->wcserror_buffer, 256, str); if (err) FIXME("bad wcserror call (%d)\n", err); return data->wcserror_buffer; }
/* INTERNAL: Convert wide va_list to a single 'delim'-separated wide string, with an * extra '\0' to terminate it. */ static MSVCRT_wchar_t *msvcrt_valisttos(const MSVCRT_wchar_t *arg0, va_list alist, MSVCRT_wchar_t delim) { va_list alist2; unsigned long len; const MSVCRT_wchar_t *arg; MSVCRT_wchar_t *p, *ret; #ifdef HAVE_VA_COPY va_copy(alist2,alist); #else # ifdef HAVE___VA_COPY __va_copy(alist2,alist); # else alist2 = alist; # endif #endif if (!arg0) { /* Return NULL for an empty environment list */ return NULL; } /* get length */ arg = arg0; len = 0; do { len += strlenW(arg) + 1; arg = va_arg(alist, MSVCRT_wchar_t*); } while (arg != NULL); ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t)); if (!ret) return NULL; /* fill string */ arg = arg0; p = ret; do { len = strlenW(arg); memcpy(p, arg, len * sizeof(MSVCRT_wchar_t)); p += len; *p++ = delim; arg = va_arg(alist2, MSVCRT_wchar_t*); } while (arg != NULL); if (delim && p > ret) p[-1] = 0; else *p = 0; return ret; }
static inline int pf_check_auto_grow(pf_output *out, unsigned delta) { if (pf_is_auto_grow(out) && out->used + delta > out->len) { out->len = max(out->len * 2, out->used + delta); if (out->unicode) { if (out->buf.W != out->grow.W) out->buf.W = MSVCRT_realloc(out->buf.W, out->len * sizeof(WCHAR)); else out->buf.W = MSVCRT_malloc(out->len * sizeof(WCHAR)); if (!out->buf.W) return -1; } else { if (out->buf.A != out->grow.A) out->buf.A = MSVCRT_realloc(out->buf.A, out->len * sizeof(char)); else out->buf.A = MSVCRT_malloc(out->len * sizeof(char)); if (!out->buf.A) return -1; } } return 0; }
/* Internal common ctor for exception */ static void EXCEPTION_ctor(exception *_this, const char** name) { _this->vtable = &MSVCRT_exception_vtable; if (*name) { unsigned int name_len = strlen(*name) + 1; _this->name = MSVCRT_malloc(name_len); memcpy(_this->name, *name, name_len); _this->do_free = TRUE; } else { _this->name = NULL; _this->do_free = FALSE; } }
/* INTERNAL: Convert ansi va_list to a single 'delim'-separated wide string, with an * extra '\0' to terminate it. */ static MSVCRT_wchar_t *msvcrt_valisttos_aw(const char *arg0, va_list alist, MSVCRT_wchar_t delim) { va_list alist2; unsigned long len; const char *arg; MSVCRT_wchar_t *p, *ret; #ifdef HAVE_VA_COPY va_copy(alist2,alist); #else # ifdef HAVE___VA_COPY __va_copy(alist2,alist); # else alist2 = alist; # endif #endif if (!arg0) { /* Return NULL for an empty environment list */ return NULL; } /* get length */ arg = arg0; len = 0; do { len += MultiByteToWideChar(CP_ACP, 0, arg, -1, NULL, 0); arg = va_arg(alist, char*); } while (arg != NULL); ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t)); if (!ret) return NULL; /* fill string */ arg = arg0; p = ret; do { p += MultiByteToWideChar(CP_ACP, 0, arg, strlen(arg), p, len - (p - ret)); *p++ = delim; arg = va_arg(alist2, char*); } while (arg != NULL); if (delim && p > ret) p[-1] = 0; else *p = 0; return ret; }
/********************************************************************** * _strerror (MSVCRT.@) */ char* CDECL _strerror(const char* str) { thread_data_t *data = msvcrt_get_thread_data(); int err; if (!data->strerror_buffer) if (!(data->strerror_buffer = MSVCRT_malloc(256))) return NULL; err = data->thread_errno; if (err < 0 || err > MSVCRT__sys_nerr) err = MSVCRT__sys_nerr; if (str && *str) sprintf( data->strerror_buffer, "%s: %s\n", str, MSVCRT__sys_errlist[err] ); else sprintf( data->strerror_buffer, "%s\n", MSVCRT__sys_errlist[err] ); return data->strerror_buffer; }
/********************************************************************* * _wasctime (MSVCRT.@) */ MSVCRT_wchar_t * CDECL MSVCRT__wasctime(const struct MSVCRT_tm *mstm) { thread_data_t *data = msvcrt_get_thread_data(); struct tm tm; char buffer[30]; msvcrt_tm_to_unix( &tm, mstm ); if (!data->wasctime_buffer) data->wasctime_buffer = MSVCRT_malloc( 30*sizeof(MSVCRT_wchar_t) ); /* ought to be enough */ #ifdef HAVE_ASCTIME_R asctime_r( &tm, buffer ); #else strcpy( buffer, asctime(&tm) ); #endif MultiByteToWideChar( CP_UNIXCP, 0, buffer, -1, data->wasctime_buffer, 30 ); return data->wasctime_buffer; }
/********************************************************************* * qsort_s (MSVCRT.@) * * Based on NTDLL_qsort in dlls/ntdll/misc.c */ void CDECL MSVCRT_qsort_s(void *base, MSVCRT_size_t nmemb, MSVCRT_size_t size, int (CDECL *compar)(void *, const void *, const void *), void *context) { void *secondarr; const size_t total_size = nmemb*size; if (!MSVCRT_CHECK_PMT(base != NULL || (base == NULL && nmemb == 0))) return; if (!MSVCRT_CHECK_PMT(size > 0)) return; if (!MSVCRT_CHECK_PMT(compar != NULL)) return; if (total_size / size != nmemb) return; if (nmemb < 2) return; secondarr = MSVCRT_malloc(total_size); if (!secondarr) return; MSVCRT_mergesort(base, secondarr, size, compar, 0, nmemb-1, context); MSVCRT_free(secondarr); }
/* INTERNAL: Convert wide argv list to a single 'delim'-separated wide string, with an * extra '\0' to terminate it. */ static MSVCRT_wchar_t* msvcrt_argvtos(const MSVCRT_wchar_t* const* arg, MSVCRT_wchar_t delim) { const MSVCRT_wchar_t* const* a; long size; MSVCRT_wchar_t* p; MSVCRT_wchar_t* ret; if (!arg) { /* Return NULL for an empty environment list */ return NULL; } /* get length */ a = arg; size = 0; while (*a) { size += strlenW(*a) + 1; a++; } ret = MSVCRT_malloc((size + 1) * sizeof(MSVCRT_wchar_t)); if (!ret) return NULL; /* fill string */ a = arg; p = ret; while (*a) { int len = strlenW(*a); memcpy(p,*a,len * sizeof(MSVCRT_wchar_t)); p += len; *p++ = delim; a++; } if (delim && p > ret) p[-1] = 0; else *p = 0; return ret; }
/********************************************************************* * _wgetcwd (MSVCRT.@) * * Unicode version of _getcwd. */ MSVCRT_wchar_t* CDECL MSVCRT__wgetcwd(MSVCRT_wchar_t * buf, int size) { MSVCRT_wchar_t dir[MAX_PATH]; int dir_len = GetCurrentDirectoryW(MAX_PATH,dir); if (dir_len < 1) return NULL; /* FIXME: Real return value untested */ if (!buf) { if (size <= dir_len) size = dir_len + 1; if (!(buf = MSVCRT_malloc( size * sizeof(WCHAR) ))) return NULL; } if (dir_len >= size) { *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; /* buf too small */ } strcpyW(buf,dir); return buf; }
/********************************************************************* * _getcwd (MSVCRT.@) * * Get the current working directory. * * PARAMS * buf [O] Destination for current working directory. * size [I] Size of buf in characters * * RETURNS * Success: If buf is NULL, returns an allocated string containing the path. * Otherwise populates buf with the path and returns it. * Failure: NULL. errno indicates the error. */ char* CDECL MSVCRT__getcwd(char * buf, int size) { char dir[MAX_PATH]; int dir_len = GetCurrentDirectoryA(MAX_PATH,dir); if (dir_len < 1) return NULL; /* FIXME: Real return value untested */ if (!buf) { if (size <= dir_len) size = dir_len + 1; if (!(buf = MSVCRT_malloc( size ))) return NULL; } else if (dir_len >= size) { *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; /* buf too small */ } strcpy(buf,dir); return buf; }
/********************************************************************* * _beginthread (MSVCRT.@) */ MSVCRT_uintptr_t CDECL _beginthread( MSVCRT__beginthread_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */ unsigned int stack_size, /* [in] Stack size for new thread or 0 */ void *arglist) /* [in] Argument list to be passed to new thread or NULL */ { _beginthread_trampoline_t* trampoline; TRACE("(%p, %d, %p)\n", start_address, stack_size, arglist); /* Allocate the trampoline here so that it is still valid when the thread * starts... typically after this function has returned. * _beginthread_trampoline is responsible for freeing the trampoline */ trampoline=MSVCRT_malloc(sizeof(*trampoline)); trampoline->start_address = start_address; trampoline->arglist = arglist; /* FIXME */ return (MSVCRT_uintptr_t)CreateThread(NULL, stack_size, _beginthread_trampoline, trampoline, 0, NULL); }
/********************************************************************* * _wperror (MSVCRT.@) */ void CDECL MSVCRT__wperror(const MSVCRT_wchar_t* str) { MSVCRT_size_t size; char *buffer = NULL; if (str && *str) { size = MSVCRT_wcstombs(NULL, str, 0); if (size == -1) return; size++; buffer = MSVCRT_malloc(size); if (!buffer) return; if (MSVCRT_wcstombs(buffer, str, size) == -1) { MSVCRT_free(buffer); return; } } MSVCRT_perror(buffer); MSVCRT_free(buffer); }
/********************************************************************* * _aligned_offset_malloc (MSVCRT.@) */ void * CDECL _aligned_offset_malloc(MSVCRT_size_t size, MSVCRT_size_t alignment, MSVCRT_size_t offset) { void *memblock, *temp, **saved; TRACE("(%lu, %lu, %lu)\n", size, alignment, offset); /* alignment must be a power of 2 */ if ((alignment & (alignment - 1)) != 0) { *MSVCRT__errno() = MSVCRT_EINVAL; return NULL; } /* offset must be less than size */ if (offset >= size) { *MSVCRT__errno() = MSVCRT_EINVAL; return NULL; } /* don't align to less than void pointer size */ if (alignment < sizeof(void *)) alignment = sizeof(void *); /* allocate enough space for void pointer and alignment */ temp = MSVCRT_malloc(size + alignment + sizeof(void *)); if (!temp) return NULL; /* adjust pointer for proper alignment and offset */ memblock = ALIGN_PTR(temp, alignment, offset); /* Save the real allocation address below returned address */ /* so it can be found later to free. */ saved = SAVED_PTR(memblock); *saved = temp; return memblock; }
/********************************************************************* * asctime (MSVCRT.@) */ char * CDECL MSVCRT_asctime(const struct MSVCRT_tm *mstm) { char bufferA[30]; WCHAR bufferW[30]; thread_data_t *data = msvcrt_get_thread_data(); struct tm tm; msvcrt_tm_to_unix( &tm, mstm ); if (!data->asctime_buffer) data->asctime_buffer = MSVCRT_malloc( 30 ); /* ought to be enough */ #ifdef HAVE_ASCTIME_R asctime_r( &tm, bufferA ); #else strcpy( bufferA, asctime(&tm) ); #endif MultiByteToWideChar( CP_UNIXCP, 0, bufferA, -1, bufferW, 30 ); WideCharToMultiByte( CP_ACP, 0, bufferW, -1, data->asctime_buffer, 30, NULL, NULL ); return data->asctime_buffer; }
/********************************************************************* * _wfullpath (MSVCRT.@) * * Unicode version of _fullpath. */ MSVCRT_wchar_t * CDECL MSVCRT__wfullpath(MSVCRT_wchar_t * absPath, const MSVCRT_wchar_t* relPath, MSVCRT_size_t size) { DWORD rc; WCHAR* buffer; WCHAR* lastpart; BOOL alloced = FALSE; if (!relPath || !*relPath) return MSVCRT__wgetcwd(absPath, size); if (absPath == NULL) { buffer = MSVCRT_malloc(MAX_PATH * sizeof(WCHAR)); size = MAX_PATH; alloced = TRUE; } else buffer = absPath; if (size < 4) { *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; } TRACE(":resolving relative path %s\n",debugstr_w(relPath)); rc = GetFullPathNameW(relPath,size,buffer,&lastpart); if (rc > 0 && rc <= size ) return buffer; else { if (alloced) MSVCRT_free(buffer); return NULL; } }
/* INTERNAL: Convert ansi argv list to a single 'delim'-separated wide string, with an * extra '\0' to terminate it. */ static MSVCRT_wchar_t *msvcrt_argvtos_aw(const char * const *arg, MSVCRT_wchar_t delim) { const char * const *a; unsigned long len; MSVCRT_wchar_t *p, *ret; if (!arg) { /* Return NULL for an empty environment list */ return NULL; } /* get length */ a = arg; len = 0; while (*a) { len += MultiByteToWideChar(CP_ACP, 0, *a, -1, NULL, 0); a++; } ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t)); if (!ret) return NULL; /* fill string */ a = arg; p = ret; while (*a) { p += MultiByteToWideChar(CP_ACP, 0, *a, strlen(*a), p, len - (p - ret)); *p++ = delim; a++; } if (delim && p > ret) p[-1] = 0; else *p = 0; return ret; }
/********************************************************************* * _fullpath (MSVCRT.@) * * Create an absolute path from a relative path. * * PARAMS * absPath [O] Destination for absolute path * relPath [I] Relative path to convert to absolute * size [I] Length of absPath in characters. * * RETURNS * Success: If absPath is NULL, returns an allocated string containing the path. * Otherwise populates absPath with the path and returns it. * Failure: NULL. errno indicates the error. */ char * CDECL MSVCRT__fullpath(char * absPath, const char* relPath, unsigned int size) { DWORD rc; char* lastpart; char* buffer; BOOL alloced = FALSE; if (!relPath || !*relPath) return MSVCRT__getcwd(absPath, size); if (absPath == NULL) { buffer = MSVCRT_malloc(MAX_PATH); size = MAX_PATH; alloced = TRUE; } else buffer = absPath; if (size < 4) { *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; } TRACE(":resolving relative path '%s'\n",relPath); rc = GetFullPathNameA(relPath,size,buffer,&lastpart); if (rc > 0 && rc <= size) return buffer; else { if (alloced) MSVCRT_free(buffer); return NULL; } }
/********************************************************************* * _beginthread (MSVCRT.@) */ MSVCRT_uintptr_t CDECL _beginthread( MSVCRT__beginthread_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */ unsigned int stack_size, /* [in] Stack size for new thread or 0 */ void *arglist) /* [in] Argument list to be passed to new thread or NULL */ { _beginthread_trampoline_t* trampoline; HANDLE thread; TRACE("(%p, %d, %p)\n", start_address, stack_size, arglist); trampoline = MSVCRT_malloc(sizeof(*trampoline)); if(!trampoline) { *MSVCRT__errno() = MSVCRT_EAGAIN; return -1; } thread = CreateThread(NULL, stack_size, _beginthread_trampoline, trampoline, CREATE_SUSPENDED, NULL); if(!thread) { MSVCRT_free(trampoline); *MSVCRT__errno() = MSVCRT_EAGAIN; return -1; } trampoline->thread = thread; trampoline->start_address = start_address; trampoline->arglist = arglist; if(ResumeThread(thread) == -1) { MSVCRT_free(trampoline); *MSVCRT__errno() = MSVCRT_EAGAIN; return -1; } return (MSVCRT_uintptr_t)thread; }
/********************************************************************* * _malloc_base (UCRTBASE.@) */ void* CDECL _malloc_base(MSVCRT_size_t size) { return MSVCRT_malloc(size); }