diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index e64a6925ae7..6bb322c6f88 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -20,7 +20,7 @@ #include "msvcrt.h" #include "msvcrt/eh.h" -#include "msvcrt/malloc.h" +#include "msvcrt/stdlib.h" #include "wine/debug.h" @@ -177,18 +177,16 @@ const char * MSVCRT_what_exception(exception * _this) } -static terminate_function func_terminate=NULL; -static unexpected_function func_unexpected=NULL; - /****************************************************************** * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) */ terminate_function MSVCRT_set_terminate(terminate_function func) { - terminate_function previous=func_terminate; - TRACE("(%p) returning %p\n",func,previous); - func_terminate=func; - return previous; + MSVCRT_thread_data *data = msvcrt_get_thread_data(); + terminate_function previous = data->terminate_handler; + TRACE("(%p) returning %p\n",func,previous); + data->terminate_handler = func; + return previous; } /****************************************************************** @@ -196,26 +194,43 @@ terminate_function MSVCRT_set_terminate(terminate_function func) */ unexpected_function MSVCRT_set_unexpected(unexpected_function func) { - unexpected_function previous=func_unexpected; - TRACE("(%p) returning %p\n",func,previous); - func_unexpected=func; - return previous; + MSVCRT_thread_data *data = msvcrt_get_thread_data(); + unexpected_function previous = data->unexpected_handler; + TRACE("(%p) returning %p\n",func,previous); + data->unexpected_handler = func; + return previous; +} + +/****************************************************************** + * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@) + */ +_se_translator_function MSVCRT__set_se_translator(_se_translator_function func) +{ + MSVCRT_thread_data *data = msvcrt_get_thread_data(); + _se_translator_function previous = data->se_translator; + TRACE("(%p) returning %p\n",func,previous); + data->se_translator = func; + return previous; } /****************************************************************** * ?terminate@@YAXXZ (MSVCRT.@) */ -void MSVCRT_terminate() +void MSVCRT_terminate(void) { - (*func_terminate)(); + MSVCRT_thread_data *data = msvcrt_get_thread_data(); + if (data->terminate_handler) data->terminate_handler(); + MSVCRT_abort(); } /****************************************************************** * ?unexpected@@YAXXZ (MSVCRT.@) */ -void MSVCRT_unexpected() +void MSVCRT_unexpected(void) { - (*func_unexpected)(); + MSVCRT_thread_data *data = msvcrt_get_thread_data(); + if (data->unexpected_handler) data->unexpected_handler(); + MSVCRT_terminate(); } @@ -523,4 +538,3 @@ void msvcrt_init_vtables(void) type_info_vtable[0] = MSVCRT_type_info_dtor; } - diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index c43bd52ed57..623d3b612c4 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -118,7 +118,7 @@ int _chdrive(int newdrive) { MSVCRT__set_errno(GetLastError()); if (newdrive <= 0) - SET_THREAD_VAR(errno,MSVCRT_EACCES); + *MSVCRT__errno() = MSVCRT_EACCES; return -1; } return 0; @@ -185,7 +185,7 @@ int _findnext(long hand, struct _finddata_t * ft) if (!FindNextFileA(hand, &find_data)) { - SET_THREAD_VAR(errno,MSVCRT_ENOENT); + *MSVCRT__errno() = MSVCRT_ENOENT; return -1; } @@ -202,7 +202,7 @@ int _wfindnext(long hand, struct _wfinddata_t * ft) if (!FindNextFileW(hand, &find_data)) { - SET_THREAD_VAR(errno,MSVCRT_ENOENT); + *MSVCRT__errno() = MSVCRT_ENOENT; return -1; } @@ -229,7 +229,7 @@ char* _getcwd(char * buf, int size) } if (dir_len >= size) { - SET_THREAD_VAR(errno,MSVCRT_ERANGE); + *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; /* buf too small */ } strcpy(buf,dir); @@ -255,7 +255,7 @@ WCHAR* _wgetcwd(WCHAR * buf, int size) } if (dir_len >= size) { - SET_THREAD_VAR(errno,MSVCRT_ERANGE); + *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; /* buf too small */ } strcpyW(buf,dir); @@ -293,14 +293,14 @@ char* _getdcwd(int drive, char * buf, int size) drivespec[0] += drive - 1; if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE) { - SET_THREAD_VAR(errno,MSVCRT_EACCES); + *MSVCRT__errno() = MSVCRT_EACCES; return NULL; } dir_len = GetFullPathNameA(drivespec,MAX_PATH,dir,&dummy); if (dir_len >= size || dir_len < 1) { - SET_THREAD_VAR(errno,MSVCRT_ERANGE); + *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; /* buf too small */ } @@ -333,14 +333,14 @@ WCHAR* _wgetdcwd(int drive, WCHAR * buf, int size) drivespec[0] += drive - 1; if (GetDriveTypeW(drivespec) < DRIVE_REMOVABLE) { - SET_THREAD_VAR(errno,MSVCRT_EACCES); + *MSVCRT__errno() = MSVCRT_EACCES; return NULL; } dir_len = GetFullPathNameW(drivespec,MAX_PATH,dir,&dummy); if (dir_len >= size || dir_len < 1) { - SET_THREAD_VAR(errno,MSVCRT_ERANGE); + *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; /* buf too small */ } @@ -629,7 +629,7 @@ char *_fullpath(char * absPath, const char* relPath, unsigned int size) if (size < 4) { - SET_THREAD_VAR(errno,MSVCRT_ERANGE); + *MSVCRT__errno() = MSVCRT_ERANGE; return NULL; } @@ -818,4 +818,3 @@ void _searchenv(const char* file, const char* env, char *buf) penv = *end ? end + 1 : end; } while(1); } - diff --git a/dlls/msvcrt/errno.c b/dlls/msvcrt/errno.c index d5601afa013..efc65f1ee7c 100644 --- a/dlls/msvcrt/errno.c +++ b/dlls/msvcrt/errno.c @@ -37,8 +37,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); /* INTERNAL: Set the crt and dos errno's from the OS error given. */ void MSVCRT__set_errno(int err) { - int *errno = GET_THREAD_VAR_PTR(errno); - unsigned long *doserrno = GET_THREAD_VAR_PTR(doserrno); + int *errno = MSVCRT__errno(); + unsigned long *doserrno = __doserrno(); *doserrno = err; @@ -99,7 +99,7 @@ void MSVCRT__set_errno(int err) */ int* MSVCRT__errno(void) { - return GET_THREAD_VAR_PTR(errno); + return &msvcrt_get_thread_data()->errno; } /********************************************************************* @@ -107,7 +107,7 @@ int* MSVCRT__errno(void) */ unsigned long* __doserrno(void) { - return GET_THREAD_VAR_PTR(doserrno); + return &msvcrt_get_thread_data()->doserrno; } /********************************************************************* @@ -124,7 +124,7 @@ char* MSVCRT_strerror(int err) char* _strerror(const char* err) { static char strerrbuff[256]; /* FIXME: Per thread, nprintf */ - sprintf(strerrbuff,"%s: %s\n",err,MSVCRT_strerror(GET_THREAD_VAR(errno))); + sprintf(strerrbuff,"%s: %s\n",err,MSVCRT_strerror(msvcrt_get_thread_data()->errno)); return strerrbuff; } @@ -133,5 +133,5 @@ char* _strerror(const char* err) */ void MSVCRT_perror(const char* str) { - _cprintf("%s: %s\n",str,MSVCRT_strerror(GET_THREAD_VAR(errno))); + _cprintf("%s: %s\n",str,MSVCRT_strerror(msvcrt_get_thread_data()->errno)); } diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 775f925c9e6..9b9ae265a3c 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -102,8 +102,8 @@ static HANDLE msvcrt_fdtoh(int fd) MSVCRT_handles[fd] == INVALID_HANDLE_VALUE) { WARN(":fd (%d) - no handle!\n",fd); - SET_THREAD_VAR(doserrno,0); - SET_THREAD_VAR(errno,MSVCRT_EBADF); + *__doserrno() = 0; + *MSVCRT__errno() = MSVCRT_EBADF; return INVALID_HANDLE_VALUE; } return MSVCRT_handles[fd]; @@ -160,8 +160,8 @@ static MSVCRT_FILE* msvcrt_alloc_fp(int fd) MSVCRT_handles[fd] == INVALID_HANDLE_VALUE) { WARN(":invalid fd %d\n",fd); - SET_THREAD_VAR(doserrno,0); - SET_THREAD_VAR(errno,MSVCRT_EBADF); + *__doserrno() = 0; + *MSVCRT__errno() = MSVCRT_EBADF; return NULL; } if (!MSVCRT_files[fd]) @@ -490,7 +490,7 @@ LONG _lseek(int fd, LONG offset, int whence) if (whence < 0 || whence > 2) { - SET_THREAD_VAR(errno,MSVCRT_EINVAL); + *MSVCRT__errno() = MSVCRT_EINVAL; return -1; } @@ -538,7 +538,7 @@ int _locking(int fd, int mode, LONG nbytes) if (mode < 0 || mode > 4) { - SET_THREAD_VAR(errno,MSVCRT_EINVAL); + *MSVCRT__errno() = MSVCRT_EINVAL; return -1; } @@ -553,7 +553,7 @@ int _locking(int fd, int mode, LONG nbytes) if ((cur_locn = SetFilePointer(hand, 0L, NULL, SEEK_CUR)) == 0xffffffff) { FIXME ("Seek failed\n"); - SET_THREAD_VAR(errno,MSVCRT_EINVAL); /* FIXME */ + *MSVCRT__errno() = MSVCRT_EINVAL; /* FIXME */ return -1; } if (mode == _LK_LOCK || mode == _LK_RLCK) diff --git a/dlls/msvcrt/heap.c b/dlls/msvcrt/heap.c index 2a5cbbf7171..3bc63fa7d11 100644 --- a/dlls/msvcrt/heap.c +++ b/dlls/msvcrt/heap.c @@ -25,6 +25,7 @@ #include "ms_errno.h" #include "msvcrt/malloc.h" +#include "msvcrt/stdlib.h" #include "mtdll.h" #include "wine/debug.h" @@ -230,7 +231,7 @@ int _heapset(unsigned int value) int _heapadd(void* mem, MSVCRT_size_t size) { TRACE("(%p,%d) unsupported in Win32\n", mem,size); - SET_THREAD_VAR(errno,MSVCRT_ENOSYS); + *MSVCRT__errno() = MSVCRT_ENOSYS; return -1; } diff --git a/dlls/msvcrt/main.c b/dlls/msvcrt/main.c index 06313237804..080579ae8ea 100644 --- a/dlls/msvcrt/main.c +++ b/dlls/msvcrt/main.c @@ -60,18 +60,8 @@ BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) msvcrt_init_args(); MSVCRT_setlocale(0, "C"); TRACE("finished process init\n"); - /* FALL THROUGH for Initial TLS allocation!! */ + break; case DLL_THREAD_ATTACH: - TRACE("starting thread init\n"); - /* Create TLS */ - tls = (MSVCRT_thread_data*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(MSVCRT_thread_data)); - if (!tls || !TlsSetValue(MSVCRT_tls_index, tls)) - { - ERR("TLS init failed! error = %ld\n", GetLastError()); - return FALSE; - } - TRACE("finished thread init\n"); break; case DLL_PROCESS_DETACH: msvcrt_free_mt_locks(); @@ -85,13 +75,7 @@ BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) case DLL_THREAD_DETACH: /* Free TLS */ tls = TlsGetValue(MSVCRT_tls_index); - - if (!tls) - { - ERR("TLS free failed! error = %ld\n", GetLastError()); - return FALSE; - } - HeapFree(GetProcessHeap(), 0, tls); + if (tls) HeapFree(GetProcessHeap(), 0, tls); TRACE("finished thread free\n"); break; } diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 68c1bd0f4eb..eeaea5f04db 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -129,7 +129,7 @@ static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL; double _CIacos(void) { FPU_DOUBLE(x); - if (x < -1.0 || x > 1.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (x < -1.0 || x > 1.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return acos(x); } @@ -139,7 +139,7 @@ double _CIacos(void) double _CIasin(void) { FPU_DOUBLE(x); - if (x < -1.0 || x > 1.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (x < -1.0 || x > 1.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return asin(x); } @@ -149,7 +149,7 @@ double _CIasin(void) double _CIatan(void) { FPU_DOUBLE(x); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return atan(x); } @@ -159,7 +159,7 @@ double _CIatan(void) double _CIatan2(void) { FPU_DOUBLES(x,y); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return atan2(x,y); } @@ -169,7 +169,7 @@ double _CIatan2(void) double _CIcos(void) { FPU_DOUBLE(x); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return cos(x); } @@ -179,7 +179,7 @@ double _CIcos(void) double _CIcosh(void) { FPU_DOUBLE(x); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return cosh(x); } @@ -189,7 +189,7 @@ double _CIcosh(void) double _CIexp(void) { FPU_DOUBLE(x); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return exp(x); } @@ -199,7 +199,7 @@ double _CIexp(void) double _CIfmod(void) { FPU_DOUBLES(x,y); - if (!finite(x) || !finite(y)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x) || !finite(y)) *MSVCRT__errno() = MSVCRT_EDOM; return fmod(x,y); } @@ -209,8 +209,8 @@ double _CIfmod(void) double _CIlog(void) { FPU_DOUBLE(x); - if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); - if (x == 0.0) SET_THREAD_VAR(errno,MSVCRT_ERANGE); + if (x < 0.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; + if (x == 0.0) *MSVCRT__errno() = MSVCRT_ERANGE; return log(x); } @@ -220,8 +220,8 @@ double _CIlog(void) double _CIlog10(void) { FPU_DOUBLE(x); - if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); - if (x == 0.0) SET_THREAD_VAR(errno,MSVCRT_ERANGE); + if (x < 0.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; + if (x == 0.0) *MSVCRT__errno() = MSVCRT_ERANGE; return log10(x); } @@ -234,7 +234,7 @@ double _CIpow(void) FPU_DOUBLES(x,y); /* FIXME: If x < 0 and y is not integral, set EDOM */ z = pow(x,y); - if (!finite(z)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(z)) *MSVCRT__errno() = MSVCRT_EDOM; return z; } @@ -244,7 +244,7 @@ double _CIpow(void) double _CIsin(void) { FPU_DOUBLE(x); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return sin(x); } @@ -254,7 +254,7 @@ double _CIsin(void) double _CIsinh(void) { FPU_DOUBLE(x); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return sinh(x); } @@ -264,7 +264,7 @@ double _CIsinh(void) double _CIsqrt(void) { FPU_DOUBLE(x); - if (x < 0.0 || !finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (x < 0.0 || !finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return sqrt(x); } @@ -274,7 +274,7 @@ double _CIsqrt(void) double _CItan(void) { FPU_DOUBLE(x); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return tan(x); } @@ -284,7 +284,7 @@ double _CItan(void) double _CItanh(void) { FPU_DOUBLE(x); - if (!finite(x)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(x)) *MSVCRT__errno() = MSVCRT_EDOM; return tanh(x); } @@ -363,7 +363,7 @@ unsigned int _rotl(unsigned int num, int shift) */ double _logb(double num) { - if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM; return logb(num); } @@ -401,7 +401,7 @@ double _scalb(double num, long power) { /* Note - Can't forward directly as libc expects y as double */ double dblpower = (double)power; - if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM; return scalb(num, dblpower); } @@ -474,7 +474,7 @@ double MSVCRT_ldexp(double num, long exp) double z = ldexp(num,exp); if (!finite(z)) - SET_THREAD_VAR(errno,MSVCRT_ERANGE); + *MSVCRT__errno() = MSVCRT_ERANGE; else if (z == 0 && signbit(z)) z = 0.0; /* Convert -0 -> +0 */ return z; @@ -628,11 +628,11 @@ INT _isnan(double num) double _y0(double num) { double retval; - if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM; retval = y0(num); if (_fpclass(retval) == _FPCLASS_NINF) { - SET_THREAD_VAR(errno,MSVCRT_EDOM); + *MSVCRT__errno() = MSVCRT_EDOM; retval = sqrt(-1); } return retval; @@ -644,11 +644,11 @@ double _y0(double num) double _y1(double num) { double retval; - if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM; retval = y1(num); if (_fpclass(retval) == _FPCLASS_NINF) { - SET_THREAD_VAR(errno,MSVCRT_EDOM); + *MSVCRT__errno() = MSVCRT_EDOM; retval = sqrt(-1); } return retval; @@ -660,11 +660,11 @@ double _y1(double num) double _yn(int order, double num) { double retval; - if (!finite(num)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(num)) *MSVCRT__errno() = MSVCRT_EDOM; retval = yn(order,num); if (_fpclass(retval) == _FPCLASS_NINF) { - SET_THREAD_VAR(errno,MSVCRT_EDOM); + *MSVCRT__errno() = MSVCRT_EDOM; retval = sqrt(-1); } return retval; @@ -676,7 +676,7 @@ double _yn(int order, double num) double _nextafter(double num, double next) { double retval; - if (!finite(num) || !finite(next)) SET_THREAD_VAR(errno,MSVCRT_EDOM); + if (!finite(num) || !finite(next)) *MSVCRT__errno() = MSVCRT_EDOM; retval = nextafter(num,next); return retval; } @@ -995,5 +995,3 @@ void _safe_fprem1(void) { TRACE("(): stub\n"); } - - diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 7cf80f55ccd..60dadb0c047 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -28,23 +28,21 @@ #include "winerror.h" #include "winnls.h" +#include "msvcrt/eh.h" + /* TLS data */ extern DWORD MSVCRT_tls_index; typedef struct __MSVCRT_thread_data { - int errno; - unsigned long doserrno; + int errno; + unsigned long doserrno; + terminate_function terminate_handler; + unexpected_function unexpected_handler; + _se_translator_function se_translator; } MSVCRT_thread_data; -#define GET_THREAD_DATA(x) \ - x = TlsGetValue(MSVCRT_tls_index) -#define GET_THREAD_VAR(x) \ - ((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x -#define GET_THREAD_VAR_PTR(x) \ - (&((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x) -#define SET_THREAD_VAR(x,y) \ - ((MSVCRT_thread_data*)TlsGetValue(MSVCRT_tls_index))->x = y +extern MSVCRT_thread_data *msvcrt_get_thread_data(void); extern int MSVCRT_current_lc_all_cp; @@ -53,6 +51,8 @@ void MSVCRT__set_errno(int); char* msvcrt_strndup(const char*,unsigned int); LPWSTR msvcrt_wstrndup(LPCWSTR, unsigned int); +void MSVCRT__amsg_exit(int errnum); + /* FIXME: This should be declared in new.h but it's not an extern "C" so * it would not be much use anyway. Even for Winelib applications. */ diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index d0fadafa987..d539216436c 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -42,7 +42,7 @@ init MSVCRT_Init @ cdecl ?_query_new_mode@@YAHXZ() MSVCRT__query_new_mode @ cdecl ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z(ptr) MSVCRT__set_new_handler @ cdecl ?_set_new_mode@@YAHH@Z(long) MSVCRT__set_new_mode -@ stub ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z +@ cdecl ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) MSVCRT__set_se_translator @ stub ?before@type_info@@QBEHABV1@@Z #(ptr ptr) stdcall @ stdcall ?name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_name @ stdcall ?raw_name@type_info@@QBEPBDXZ(ptr) MSVCRT_type_info_raw_name diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c index 55857505c41..74796349e8f 100644 --- a/dlls/msvcrt/process.c +++ b/dlls/msvcrt/process.c @@ -53,7 +53,7 @@ static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env) if ((unsigned)flags > _P_DETACH) { - SET_THREAD_VAR(errno,MSVCRT_EINVAL); + *MSVCRT__errno() = MSVCRT_EINVAL; return -1; } @@ -203,8 +203,8 @@ int _cwait(int *status, int pid, int action) if (doserrno == ERROR_INVALID_HANDLE) { - SET_THREAD_VAR(errno, MSVCRT_ECHILD); - SET_THREAD_VAR(doserrno,doserrno); + *MSVCRT__errno() = MSVCRT_ECHILD; + *__doserrno() = doserrno; } else MSVCRT__set_errno(doserrno); @@ -456,4 +456,3 @@ int _unloaddll(int dll) return err; } } - diff --git a/dlls/msvcrt/thread.c b/dlls/msvcrt/thread.c index b4f52c22b24..6a7f81fa081 100644 --- a/dlls/msvcrt/thread.c +++ b/dlls/msvcrt/thread.c @@ -33,6 +33,27 @@ typedef struct { void *arglist; } _beginthread_trampoline_t; +/********************************************************************* + * msvcrt_get_thread_data + * + * Return the thread local storage structure. + */ +MSVCRT_thread_data *msvcrt_get_thread_data(void) +{ + MSVCRT_thread_data *ptr; + DWORD err = GetLastError(); /* need to preserve last error */ + + if (!(ptr = TlsGetValue( MSVCRT_tls_index ))) + { + if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) + MSVCRT__amsg_exit(16); + if (!TlsSetValue( MSVCRT_tls_index, ptr )) MSVCRT__amsg_exit(16); + } + SetLastError( err ); + return ptr; +} + + /********************************************************************* * _beginthread_trampoline */ @@ -114,4 +135,3 @@ void _endthreadex( /* FIXME */ ExitThread(retval); } - diff --git a/include/msvcrt/eh.h b/include/msvcrt/eh.h index 001517298eb..39103a560c1 100644 --- a/include/msvcrt/eh.h +++ b/include/msvcrt/eh.h @@ -31,15 +31,18 @@ #define MSVCRT(x) x #endif +struct _EXCEPTION_POINTERS; typedef void (*terminate_handler)(); typedef void (*terminate_function)(); typedef void (*unexpected_handler)(); typedef void (*unexpected_function)(); - +typedef void (*_se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info); terminate_function MSVCRT(set_terminate)(terminate_function func); unexpected_function MSVCRT(set_unexpected)(unexpected_function func); +_se_translator_function MSVCRT(_set_se_translator)(_se_translator_function func); + void MSVCRT(terminate)(); void MSVCRT(unexpected)();