/********************************************************************* * memmove_s (MSVCRT.@) */ int CDECL memmove_s(void *dest, size_t numberOfElements, const void *src, size_t count) { TRACE("(%p %lu %p %lu)\n", dest, numberOfElements, src, count); if(!count) return 0; if(!dest || !src) { if(dest) memset(dest, 0, numberOfElements); *_errno() = EINVAL; return EINVAL; } if(count > numberOfElements) { memset(dest, 0, numberOfElements); *_errno() = ERANGE; return ERANGE; } memmove(dest, src, count); 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; }
/* * @implemented */ double _y1(double num) { double retval; if (!_finite(num)) *_errno() = EDOM; retval = __ieee754_y1(num); if (_fpclass(retval) == _FPCLASS_NINF) { *_errno() = EDOM; retval = sqrt(-1); } return retval; }
/* * @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; }
/********************************************************************* * malloc (MSVCRT.@) */ void* CDECL malloc(size_t size) { void *ret = HeapAlloc(GetProcessHeap(),0,size); if (!ret) *_errno() = ENOMEM; return ret; }
/* * @implemented */ int CDECL _pclose(FILE* file) { HANDLE h; DWORD i; if (!MSVCRT_CHECK_PMT(file != NULL)) return -1; _mlock(_POPEN_LOCK); for(i=0; i<popen_handles_size; i++) { if (popen_handles[i].f == file) break; } if(i == popen_handles_size) { _munlock(_POPEN_LOCK); *_errno() = EBADF; return -1; } h = popen_handles[i].proc; popen_handles[i].f = NULL; _munlock(_POPEN_LOCK); fclose(file); if(WaitForSingleObject(h, INFINITE)==WAIT_FAILED || !GetExitCodeProcess(h, &i)) { _dosmaperr(GetLastError()); CloseHandle(h); return -1; } CloseHandle(h); return i; }
static int __copy_standard_singlethreading(const char *from, const char *to) { int ret, retry = 0; struct stat stbuf; char buf[BIG_BUF_LEN]; uint64_t left, offset, size; fileid_t fid, src; lichbd_ioctx_t fioctx, tioctx; ret = __stor_getattr(from, &src, &stbuf); if (ret) GOTO(err_ret, ret); ret = __stor_connect(from, &fioctx); if (ret) GOTO(err_ret, ret); ret = __stor_create(to, &fid); if (ret) GOTO(err_ret, ret); ret = __stor_connect(to, &tioctx); if (ret) GOTO(err_ret, ret); offset = 0; left = stbuf.st_size; while (left > 0) { size = left < BIG_BUF_LEN ? left : BIG_BUF_LEN; retry = 0; retry1: ret = lichbd_pread(&fioctx, buf, size, offset); if (ret < 0) { ret = -ret; if (ret == EAGAIN) { USLEEP_RETRY(err_ret, ret, retry1, retry, 100, (100 * 1000)); } else GOTO(err_ret, ret); } retry = 0; retry2: ret = lichbd_pwrite(&tioctx, buf, size, offset); if (ret) { ret = _errno(ret); if (ret == EAGAIN || ret == ENOSPC) { USLEEP_RETRY(err_ret, ret, retry2, retry, 100, (100 * 1000)); } else GOTO(err_ret, ret); } offset += size; left -= size; } return 0; err_ret: return ret; }
/* main */ int main(int argc, char * argv[]) { int ret = 0; (void) argc; ret += _errno(argv[0]); return (ret == 0) ? 0 : 2; }
void Extension::SaveReceivedBinaryToFile(int Position, int Size, char * Filename) { if (Position < 0) CreateError("Cannot save received binary; Position less than 0."); else if (Size <= 0) CreateError("Cannot save received binary; Size equal or less than 0."); else if (!Filename || Filename[0] == '\0') CreateError("Cannot save received binary; filename is invalid."); else if (ThreadData.ReceivedMsg.Size - Size <= 0) CreateError("Cannot save received binary; Message is too small."); else { FILE * File = NULL; if (fopen_s(&File, Filename, "wb") || !File) { char errorval[20]; SaveExtInfo &S = AddEvent(0); std::string Error = "Cannot save received binary to file, error "; if (_itoa_s(*_errno(), &errorval[0], 20, 10)) { Error += " with opening the file, and with converting error number."; } else { Error += "number ["; Error += &errorval[0]; Error += "] occured with opening the file."; } Error += "\r\nThe message has not been modified."; S.Error.Text = _strdup(Error.c_str()); return; } // Jump to end fseek(File, 0, SEEK_END); // Read current position as file size long long filesize = _ftelli64(File); // Go back to start fseek(File, 0, SEEK_SET); long l; if ((l = fwrite(ThreadData.ReceivedMsg.Content + Position, 1, Size, File)) != Size) { char sizeastext[20]; SaveExtInfo &S = AddEvent(0); std::string Error = "Couldn't save the received binary to file, "; if (_itoa_s(errno, &sizeastext[0], 20, 10)) { Error += " and error copying size."; } else { Error += &sizeastext[0]; Error += " bytes managed to be written."; } S.Error.Text = _strdup(Error.c_str()); } fclose(File); } }
int CDECL _strtime_s(char* time, size_t size) { if(time && size) time[0] = '\0'; if(!time) { *_errno() = EINVAL; return EINVAL; } if(size < 9) { *_errno() = ERANGE; return ERANGE; } _strtime(time); return 0; }
/* * @implemented */ int CDECL _strdate_s(char* date, size_t size) { if(date && size) date[0] = '\0'; if(!date) { *_errno() = EINVAL; return EINVAL; } if(size < 9) { *_errno() = ERANGE; return ERANGE; } _strdate(date); return 0; }
size_t CDECL _strxfrm_l( char *dest, const char *src, size_t len, _locale_t locale ) { MSVCRT_pthreadlocinfo locinfo; int ret; if(!MSVCRT_CHECK_PMT(src)) return INT_MAX; if(!MSVCRT_CHECK_PMT(dest || !len)) return INT_MAX; if(len > INT_MAX) { FIXME("len > INT_MAX not supported\n"); len = INT_MAX; } if(!locale) locinfo = get_locinfo(); else locinfo = ((MSVCRT__locale_t)locale)->locinfo; if(!locinfo->lc_handle[MSVCRT_LC_COLLATE]) { strncpy(dest, src, len); return strlen(src); } ret = LCMapStringA(locinfo->lc_handle[MSVCRT_LC_COLLATE], LCMAP_SORTKEY, src, -1, NULL, 0); if(!ret) { if(len) dest[0] = 0; *_errno() = EILSEQ; return INT_MAX; } if(!len) return ret-1; if(ret > len) { dest[0] = 0; *_errno() = ERANGE; return ret-1; } return LCMapStringA(locinfo->lc_handle[MSVCRT_LC_COLLATE], LCMAP_SORTKEY, src, -1, dest, len) - 1; }
void Extension::AppendReceivedBinaryToFile(int Position, int Size, char * Filename) { if (Position < 0) CreateError("Cannot append received binary; Position less than 0."); else if (Size <= 0) CreateError("Cannot append received binary; Size equal or less than 0."); else if (!Filename || Filename[0] == '\0') CreateError("Cannot append received binary; filename is invalid."); else if (ThreadData.ReceivedMsg.Size - Size <= 0) CreateError("Cannot append received binary; Message is too small."); else { // Open while denying write of other programs FILE * File = _fsopen(Filename, "ab", SH_DENYWR); if (!File) { char errorval[20]; SaveExtInfo &S = AddEvent(0); std::string Error = "Cannot append received binary to file, error "; if (_itoa_s(*_errno(), &errorval[0], 20, 10)) { Error += " with opening the file, and with converting error number."; } else { Error += "number ["; Error += &errorval[0]; Error += "] occured with opening the file."; } Error += "\r\nThe message has not been modified."; S.Error.Text = _strdup(Error.c_str()); return; } long l; if ((l = fwrite(ThreadData.ReceivedMsg.Content + Position, 1, Size, File)) != Size) { char sizeastext[20]; SaveExtInfo &S = AddEvent(0); std::string Error = "Couldn't append the received binary to file, "; if (_itoa_s(errno, &sizeastext[0], 20, 10)) { Error += " and error copying size."; } else { Error += &sizeastext[0]; Error += " bytes managed to be append."; } S.Error.Text = _strdup(Error.c_str()); } fclose(File); } }
/********************************************************************* * wctomb (MSVCRT.@) */ INT CDECL wctomb( char *dst, wchar_t ch ) { BOOL error; INT size; size = WideCharToMultiByte(get_locinfo()->lc_codepage, 0, &ch, 1, dst, dst ? 6 : 0, NULL, &error); if(!size || error) { *_errno() = EINVAL; return EOF; } return size; }
/********************************************************************* * _aligned_offset_malloc (MSVCRT.@) */ void * CDECL _aligned_offset_malloc(size_t size, size_t alignment, 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) { *_errno() = EINVAL; return NULL; } /* offset must be less than size */ if (offset >= size) { *_errno() = 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 = 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; }
__int16 ResourceManager::readShort() { int err; __int16 buf; int success; assertTrue(this->fileDescriptors[this->curHandleIdx] != -1, "F:\\h2xsrc\\Base\\RESMGR.CPP", 732); buf = 0; success = _read(this->fileDescriptors[this->curHandleIdx], &buf, sizeof(short)); if ( !success ) err = *_errno(); return buf; }
long CJFile::Open(const char* szFileName, BOOL bWrite) { if(NULL == szFileName || strlen(szFileName) <= 0) { return -1; } m_lockRW.Lock(); Close(); if(bWrite) { m_pFile = fopen(szFileName, "wb"); } else { int iRet = access(szFileName, 0); if(iRet != 0) { m_lErrCode = *_errno(); m_lockRW.Unlock(); return -2; } m_pFile = fopen(szFileName, "rb"); } if(NULL == m_pFile) { m_lErrCode = *_errno(); m_lockRW.Unlock(); return -3; } fseek(m_pFile, 0, SEEK_SET); m_lockRW.Unlock(); return 0; }
void ResourceManager::readFromCurrentFile( void * buf, DWORD ntoread) { int err1; int *err2; signed int nread; assertTrue(this->fileDescriptors[this->curHandleIdx] != -1, "F:\\h2xsrc\\Base\\RESMGR.CPP", 816); yieldToGlobalUpdater(); nread = _read(this->fileDescriptors[this->curHandleIdx], buf, ntoread); if ( nread != ntoread ) { err1 = *_errno(); err2 = _errno(); sprintf( globBuf, "File error - bytes read %d, bytes requested %d, errno %d, last file '%s'", nread, ntoread, *err2, this->resourceToLoad); debugLog(globBuf); } yieldToGlobalUpdater(); }
/********************************************************************* * rand_s (MSVCRT.@) */ int CDECL rand_s(unsigned int *pval) { BOOLEAN (WINAPI *pSystemFunction036)(PVOID, ULONG); // RtlGenRandom HINSTANCE hadvapi32 = LoadLibraryA("advapi32.dll"); pSystemFunction036 = (void*)GetProcAddress(hadvapi32, "SystemFunction036"); #if 1 if (!pval || (pSystemFunction036 && !pSystemFunction036(pval, sizeof(*pval)))) { _invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0); *_errno() = EINVAL; return EINVAL; } #endif if(hadvapi32) FreeLibrary(hadvapi32); return 0; }
static void * __copy_from_local_worker(void *_arg) { int ret, retry; arg_t *arg; char buf[BIG_BUF_LEN]; uint64_t left, offset, size; arg = _arg; offset = arg->offset; left = arg->size; while (left > 0) { size = left < BIG_BUF_LEN ? left : BIG_BUF_LEN; ret = pread(arg->ext.fd, buf, size, offset); if (ret < 0) { ret = errno; GOTO(err_ret, ret); } retry = 0; retry: ret = lichbd_pwrite(&arg->ext.tioctx, buf, size, offset); if (ret) { ret = _errno(ret); if (ret == EAGAIN || ret == ENOSPC) { USLEEP_RETRY(err_ret, ret, retry, retry, 100, (100 * 1000)); } else GOTO(err_ret, ret); } offset += size; left -= size; } arg->ret = 0; sem_post(&arg->sem); return NULL; err_ret: arg->ret = ret; sem_post(&arg->sem); return NULL; }
int LastSystemError() { #if defined(_win_) int ret = GetLastError(); if (ret) return ret; ret = WSAGetLastError(); if (ret) return ret; // when descriptors number are over maximum, errno set in this variable ret = *(_errno()); return ret; #else return errno; #endif }
long CJFile::Write(const void* pData, long lLen) { m_lockRW.Lock(); if(NULL == m_pFile) { m_lockRW.Unlock(); return -1; } DWORD dwTime = GetTickCount(); DWORD dwWrited = 0; int iErrTick = 0; while(dwWrited < (DWORD)lLen) { if(GetTickCount() - dwTime > (DWORD)m_lTimeOut) { break; } size_t uRet = fwrite((BYTE*)pData + dwWrited, 1, lLen - dwWrited, m_pFile); if(uRet > 0) { dwWrited += uRet; fflush(m_pFile); } else { iErrTick++; if(iErrTick > 3) { m_lErrCode = *_errno(); } } } m_lockRW.Unlock(); return dwWrited; }
long CJFile::Read(void* pBuf, long lSize) { m_lockRW.Lock(); if(NULL == m_pFile) { m_lockRW.Unlock(); return -1; } DWORD dwTime = GetTickCount(); DWORD dwReded = 0; DWORD iErrTick = 0; while(dwReded < (DWORD)lSize) { if(GetTickCount() - dwTime > (DWORD)m_lTimeOut) { break; } size_t uRet = fread((BYTE*)pBuf + dwReded, 1, lSize - dwReded, m_pFile); if(uRet > 0) { dwReded += uRet; } else { iErrTick++; if(iErrTick > 3) { m_lErrCode = *_errno(); } } } m_lockRW.Unlock(); return dwReded; }
void Extension::AddFileToBinary(char * Filename) { if (!Filename || Filename[0] == '\0') CreateError("Cannot add file to send binary; filename is invalid."); else { FILE * File = NULL; // Open and deny other programs write priviledges if (!(File = _fsopen(Filename, "wb", _SH_DENYWR))) { char errorval[20]; SaveExtInfo &S = AddEvent(0); std::string Error = "Cannot save binary to file, error "; if (_itoa_s(*_errno(), &errorval[0], 20, 10)) { Error += " with opening the file, and with converting error number."; } else { Error += "number ["; Error += &errorval[0]; Error += "] occured with opening the file."; } Error += "\r\nThe message has not been modified."; S.Error.Text = _strdup(Error.c_str()); return; } // Jump to end fseek(File, 0, SEEK_END); // Read current position as file size long filesize = ftell(File); // Go back to start fseek(File, 0, SEEK_SET); char * buffer = (char *)malloc(filesize); if (!buffer) CreateError("Couldn't reserve enough memory to add file into message."); else { size_t s; if ((s = fread_s(buffer, filesize, 1, filesize, File)) != filesize) { char sizeastext[20]; SaveExtInfo &S = AddEvent(0); std::string Error = "Couldn't write full buffer to file, "; if (_itoa_s(s, &sizeastext[0], 20, 10)) { Error += " and error copying size."; } else { Error += &sizeastext[0]; Error += " bytes managed to be written."; } S.Error.Text = _strdup(Error.c_str()); } AddToSend(buffer, s); free(buffer); } fclose(File); } }
int main(int argc, char **argv, char **envp) { uc_engine *uc; uc_err err; int ret; uc_hook hhc; uint32_t val; EmuStarterParam_t starter_params; #ifdef _WIN32 HANDLE th = (HANDLE)-1; #else pthread_t th; #endif // dynamically load shared library #ifdef DYNLOAD uc_dyn_load(NULL, 0); #endif // Initialize emulator in MIPS 32bit little endian mode printf("uc_open()\n"); err = uc_open(UC_ARCH_MIPS, UC_MODE_MIPS32, &uc); if (err) { printf("Failed on uc_open() with error returned: %u\n", err); return err; } // map in a page of mem printf("uc_mem_map()\n"); err = uc_mem_map(uc, addr, 0x1000, UC_PROT_ALL); if (err) { printf("Failed on uc_mem_map() with error returned: %u\n", err); return err; } // write machine code to be emulated to memory printf("uc_mem_write()\n"); err = uc_mem_write(uc, addr, loop_test_code, sizeof(loop_test_code)); if( err ) { printf("Failed on uc_mem_write() with error returned: %u\n", err); return err; } // hook all instructions by having @begin > @end printf("uc_hook_add()\n"); uc_hook_add(uc, &hhc, UC_HOOK_CODE, mips_codehook, NULL, 1, 0); if( err ) { printf("Failed on uc_hook_add(code) with error returned: %u\n", err); return err; } // start background thread printf("---- Thread Starting ----\n"); starter_params.uc = uc; starter_params.startAddr = addr; starter_params.endAddr = addr + sizeof(loop_test_code); #ifdef _WIN32 // create thread th = (HANDLE)_beginthreadex(NULL, 0, win32_emu_starter, &starter_params, CREATE_SUSPENDED, NULL); if(th == (HANDLE)-1) { printf("Failed on _beginthreadex() with error returned: %u\n", _errno()); return -1; } // start thread ret = ResumeThread(th); if( ret == -1 ) { printf("Failed on ResumeThread() with error returned: %u\n", _errno()); return -2; } // wait 3 seconds Sleep(3 * 1000); #else // add posix code to start the emu_starter() thread ret = pthread_create(&th, NULL, posix_emu_starter, &starter_params); if( ret ) { printf("Failed on pthread_create() with error returned: %u\n", err); return -2; } // wait 3 seconds sleep(3); #endif // Stop the thread after it has been let to run in the background for a while printf("---- Thread Stopping ----\n"); printf("uc_emu_stop()\n"); err = uc_emu_stop(uc); if( err ) { printf("Failed on uc_emu_stop() with error returned: %u\n", err); return err; } test_passed_ok = true; // done executing, print some reg values as a test uc_reg_read(uc, UC_MIPS_REG_PC, &val); printf("pc is %X\n", val); uc_reg_read(uc, UC_MIPS_REG_A0, &val); printf("a0 is %X\n", val); // free resources printf("uc_close()\n"); uc_close(uc); if( test_passed_ok ) printf("\n\nTEST PASSED!\n\n"); else printf("\n\nTEST FAILED!\n\n"); // dynamically free shared library #ifdef DYNLOAD uc_dyn_free(); #endif 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); }
/********************************************************************* * _heapadd (MSVCRT.@) */ int CDECL _heapadd(void* mem, size_t size) { TRACE("(%p,%ld) unsupported in Win32\n", mem,size); *_errno() = ENOSYS; return -1; }
/* * @unimplemented */ double _j1(double num) { if (!_finite(num)) *_errno() = EDOM; return __ieee754_j1(num); }
/********************************************************************* * _aligned_offset_realloc (MSVCRT.@) */ void * CDECL _aligned_offset_realloc(void *memblock, size_t size, size_t alignment, size_t offset) { void * temp, **saved; size_t old_padding, new_padding, old_size; TRACE("(%p, %lu, %lu, %lu)\n", memblock, size, alignment, offset); if (!memblock) return _aligned_offset_malloc(size, alignment, offset); /* alignment must be a power of 2 */ if ((alignment & (alignment - 1)) != 0) { *_errno() = EINVAL; return NULL; } /* offset must be less than size */ if (offset >= size) { *_errno() = EINVAL; return NULL; } if (size == 0) { _aligned_free(memblock); return NULL; } /* don't align to less than void pointer size */ if (alignment < sizeof(void *)) alignment = sizeof(void *); /* make sure alignment and offset didn't change */ saved = SAVED_PTR(memblock); if (memblock != ALIGN_PTR(*saved, alignment, offset)) { *_errno() = EINVAL; return NULL; } old_padding = (char *)memblock - (char *)*saved; /* Get previous size of block */ old_size = _msize(*saved); if (old_size == -1) { /* It seems this function was called with an invalid pointer. Bail out. */ return NULL; } /* Adjust old_size to get amount of actual data in old block. */ if (old_size < old_padding) { /* Shouldn't happen. Something's weird, so bail out. */ return NULL; } old_size -= old_padding; temp = realloc(*saved, 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); new_padding = (char *)memblock - (char *)temp; /* Memory layout of old block is as follows: +-------+---------------------+-+--------------------------+-----------+ | ... | "old_padding" bytes | | ... "old_size" bytes ... | ... | +-------+---------------------+-+--------------------------+-----------+ ^ ^ ^ | | | *saved saved memblock Memory layout of new block is as follows: +-------+-----------------------------+-+----------------------+-------+ | ... | "new_padding" bytes | | ... "size" bytes ... | ... | +-------+-----------------------------+-+----------------------+-------+ ^ ^ ^ | | | temp saved memblock However, in the new block, actual data is still written as follows (because it was copied by MSVCRT_realloc): +-------+---------------------+--------------------------------+-------+ | ... | "old_padding" bytes | ... "old_size" bytes ... | ... | +-------+---------------------+--------------------------------+-------+ ^ ^ ^ | | | temp saved memblock Therefore, min(old_size,size) bytes of actual data have to be moved from the offset they were at in the old block (temp + old_padding), to the offset they have to be in the new block (temp + new_padding == memblock). */ if (new_padding != old_padding) memmove((char *)memblock, (char *)temp + old_padding, (old_size < size) ? old_size : size); *saved = temp; return memblock; }
/* * @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; }