static bool __cdecl compute_size(LARGE_INTEGER const& integer, long& size) throw() { size = 0; _VALIDATE_RETURN_NOEXC(integer.HighPart == 0 && integer.LowPart <= LONG_MAX, EOVERFLOW, false); size = static_cast<long>(integer.LowPart); return true; }
static bool __cdecl compute_size(LARGE_INTEGER const& integer, __int64& size) throw() { size = 0; _VALIDATE_RETURN_NOEXC(integer.HighPart <= LONG_MAX, EOVERFLOW, false); size = static_cast<__int64>( static_cast<unsigned __int64>(integer.HighPart) * 0x100000000i64 + static_cast<unsigned __int64>(integer.LowPart)); return true; }
_TSCHAR * __cdecl _tctime64 ( const __time64_t *timp ) { struct tm tmtemp; errno_t e; _VALIDATE_RETURN( ( timp != NULL ), EINVAL, NULL ) _VALIDATE_RETURN_NOEXC( ( *timp >= 0 ), EINVAL, NULL ) e = _localtime64_s(&tmtemp, timp); if ( e == 0 ) { _BEGIN_SECURE_CRT_DEPRECATION_DISABLE return _tasctime(&tmtemp); _END_SECURE_CRT_DEPRECATION_DISABLE }
void * __cdecl _recalloc_base(void * memblock, size_t count, size_t size) { void * retp = NULL; size_t size_orig = 0, old_size = 0; /* ensure that (size * count) does not overflow */ if (count > 0) { _VALIDATE_RETURN_NOEXC((_HEAP_MAXREQ / count) >= size, ENOMEM, NULL); } size_orig = size * count; if (memblock != NULL) old_size = _msize(memblock); retp = _realloc_base(memblock, size_orig); if (retp != NULL && old_size < size_orig) { memset ((char*)retp + old_size, 0, size_orig - old_size); } return retp; }
extern "C" void* __cdecl _aligned_offset_recalloc_base( void* block, size_t count, size_t size, size_t align, size_t offset ) { size_t user_size = 0; /* wanted size, passed to aligned realoc */ size_t start_fill = 0; /* location where aligned recalloc starts to fill with 0 */ /* filling must start from the end of the previous user block */ void * retptr = nullptr; /* result of aligned recalloc*/ /* ensure that (size * num) does not overflow */ if (count > 0) { _VALIDATE_RETURN_NOEXC((_HEAP_MAXREQ / count) >= size, ENOMEM, nullptr); } user_size = size * count; if (block != nullptr) { start_fill = _aligned_msize(block, align, offset); } retptr = _aligned_offset_realloc_base(block, user_size, align, offset); if (retptr != nullptr) { if (start_fill < user_size) { memset ((char*)retptr + start_fill, 0, user_size - start_fill); } } return retptr; }
// This function implements the logic of realloc(). It is called directly by // the realloc() and _recalloc() functions in the Release CRT and is called by // the debug heap in the Debug CRT. extern "C" _CRTRESTRICT void* __cdecl _realloc_base( void* const block, size_t const size ) { // If the block is a nullptr, just call malloc: if (block == nullptr) return _malloc_base(size); // If the new size is 0, just call free and return nullptr: if (size == 0) { _free_base(block); return nullptr; } // Ensure that the requested size is not too large: _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr); for (;;) { void* const new_block = HeapReAlloc(__acrt_heap, 0, block, size); if (new_block) return new_block; // Otherwise, see if we need to call the new handler, and if so call it. // If the new handler fails, just return nullptr: if (_query_new_mode() == 0 || !_callnewh(size)) { errno = ENOMEM; return nullptr; } // The new handler was successful; try to allocate again... } }
extern "C" void* __cdecl _aligned_offset_realloc_base( void* block, size_t size, size_t align, size_t offset ) { uintptr_t ptr, retptr, gap, stptr, diff; uintptr_t movsz, reqsz; int bFree = 0; /* special cases */ if (block == nullptr) { return _aligned_offset_malloc_base(size, align, offset); } if (size == 0) { _aligned_free_base(block); return nullptr; } /* validation section */ _VALIDATE_RETURN(IS_2_POW_N(align), EINVAL, nullptr); _VALIDATE_RETURN(offset == 0 || offset < size, EINVAL, nullptr); stptr = (uintptr_t)block; /* ptr points to the pointer to starting of the memory block */ stptr = (stptr & ~(PTR_SZ -1)) - PTR_SZ; /* ptr is the pointer to the start of memory block*/ stptr = *((uintptr_t *)stptr); align = (align > PTR_SZ ? align : PTR_SZ) -1; /* gap = number of bytes needed to round up offset to align with PTR_SZ*/ gap = (0 -offset)&(PTR_SZ -1); diff = (uintptr_t)block - stptr; /* Mov size is min of the size of data available and sizw requested. */ #pragma warning(push) #pragma warning(disable: 22018) // Silence prefast about overflow/underflow movsz = _msize((void *)stptr) - ((uintptr_t)block - stptr); #pragma warning(pop) movsz = movsz > size ? size : movsz; reqsz = PTR_SZ + gap + align + size; _VALIDATE_RETURN_NOEXC(size <= reqsz, ENOMEM, nullptr); /* First check if we can expand(reducing or expanding using expand) data * safely, ie no data is lost. eg, reducing alignment and keeping size * same might result in loss of data at the tail of data block while * expanding. * * If no, use malloc to allocate the new data and move data. * * If yes, expand and then check if we need to move the data. */ if ((stptr +align +PTR_SZ +gap)<(uintptr_t)block) { if ((ptr = (uintptr_t)malloc(reqsz)) == (uintptr_t) nullptr) return nullptr; bFree = 1; } else { /* we need to save errno, which can be modified by _expand */ errno_t save_errno = errno; if ((ptr = (uintptr_t)_expand((void *)stptr, reqsz)) == (uintptr_t)nullptr) { errno = save_errno; if ((ptr = (uintptr_t)malloc(reqsz)) == (uintptr_t) nullptr) return nullptr; bFree = 1; } else stptr = ptr; } if ( ptr == ((uintptr_t)block - diff) && !( ((size_t)block + gap +offset) & ~(align) )) { return block; } retptr =((ptr +PTR_SZ +gap +align +offset)&~align)- offset; memmove((void *)retptr, (void *)(stptr + diff), movsz); if ( bFree) free ((void *)stptr); ((uintptr_t *)(retptr - gap))[-1] = ptr; return (void *)retptr; }