Commit c35d07fc authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

ucrtbase: Add _set_thread_local_invalid_parameter_handler implementation.

parent 025c5434
...@@ -433,6 +433,16 @@ void CDECL _seterrormode(int mode) ...@@ -433,6 +433,16 @@ void CDECL _seterrormode(int mode)
void __cdecl MSVCRT__invalid_parameter(const MSVCRT_wchar_t *expr, const MSVCRT_wchar_t *func, void __cdecl MSVCRT__invalid_parameter(const MSVCRT_wchar_t *expr, const MSVCRT_wchar_t *func,
const MSVCRT_wchar_t *file, unsigned int line, MSVCRT_uintptr_t arg) const MSVCRT_wchar_t *file, unsigned int line, MSVCRT_uintptr_t arg)
{ {
#if _MSVCR_VER >= 140
thread_data_t *data = msvcrt_get_thread_data();
if (data->invalid_parameter_handler)
{
data->invalid_parameter_handler( expr, func, file, line, arg );
return;
}
#endif
if (invalid_parameter_handler) invalid_parameter_handler( expr, func, file, line, arg ); if (invalid_parameter_handler) invalid_parameter_handler( expr, func, file, line, arg );
else else
{ {
...@@ -474,13 +484,14 @@ MSVCRT_invalid_parameter_handler CDECL _set_invalid_parameter_handler( ...@@ -474,13 +484,14 @@ MSVCRT_invalid_parameter_handler CDECL _set_invalid_parameter_handler(
return old; return old;
} }
#if _MSVCR_VER >= 140
/********************************************************************* /*********************************************************************
* _get_thread_local_invalid_parameter_handler (UCRTBASE.@) * _get_thread_local_invalid_parameter_handler (UCRTBASE.@)
*/ */
MSVCRT_invalid_parameter_handler CDECL _get_thread_local_invalid_parameter_handler(void) MSVCRT_invalid_parameter_handler CDECL _get_thread_local_invalid_parameter_handler(void)
{ {
FIXME(" stub\n"); TRACE("\n");
return NULL; return msvcrt_get_thread_data()->invalid_parameter_handler;
} }
/********************************************************************* /*********************************************************************
...@@ -489,6 +500,12 @@ MSVCRT_invalid_parameter_handler CDECL _get_thread_local_invalid_parameter_handl ...@@ -489,6 +500,12 @@ MSVCRT_invalid_parameter_handler CDECL _get_thread_local_invalid_parameter_handl
MSVCRT_invalid_parameter_handler CDECL _set_thread_local_invalid_parameter_handler( MSVCRT_invalid_parameter_handler CDECL _set_thread_local_invalid_parameter_handler(
MSVCRT_invalid_parameter_handler handler) MSVCRT_invalid_parameter_handler handler)
{ {
FIXME("(%p) stub\n", handler); thread_data_t *data = msvcrt_get_thread_data();
return NULL; MSVCRT_invalid_parameter_handler old = data->invalid_parameter_handler;
TRACE("(%p)\n", handler);
data->invalid_parameter_handler = handler;
return old;
} }
#endif
...@@ -266,6 +266,9 @@ struct __thread_data { ...@@ -266,6 +266,9 @@ struct __thread_data {
DWORD cached_cp; DWORD cached_cp;
char cached_locale[131]; char cached_locale[131];
void *unk10[100]; void *unk10[100];
#if _MSVCR_VER >= 140
MSVCRT_invalid_parameter_handler invalid_parameter_handler;
#endif
}; };
typedef struct __thread_data thread_data_t; typedef struct __thread_data thread_data_t;
......
...@@ -27,6 +27,33 @@ ...@@ -27,6 +27,33 @@
#include <winbase.h> #include <winbase.h>
#include "wine/test.h" #include "wine/test.h"
#define DEFINE_EXPECT(func) \
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
#define SET_EXPECT(func) \
expect_ ## func = TRUE
#define CHECK_EXPECT2(func) \
do { \
ok(expect_ ##func, "unexpected call " #func "\n"); \
called_ ## func = TRUE; \
}while(0)
#define CHECK_EXPECT(func) \
do { \
CHECK_EXPECT2(func); \
expect_ ## func = FALSE; \
}while(0)
#define CHECK_CALLED(func) \
do { \
ok(called_ ## func, "expected " #func "\n"); \
expect_ ## func = called_ ## func = FALSE; \
}while(0)
DEFINE_EXPECT(global_invalid_parameter_handler);
DEFINE_EXPECT(thread_invalid_parameter_handler);
typedef int (CDECL *MSVCRT__onexit_t)(void); typedef int (CDECL *MSVCRT__onexit_t)(void);
typedef struct MSVCRT__onexit_table_t typedef struct MSVCRT__onexit_table_t
...@@ -41,6 +68,11 @@ static int (CDECL *p_register_onexit_function)(MSVCRT__onexit_table_t *table, MS ...@@ -41,6 +68,11 @@ static int (CDECL *p_register_onexit_function)(MSVCRT__onexit_table_t *table, MS
static int (CDECL *p_execute_onexit_table)(MSVCRT__onexit_table_t *table); static int (CDECL *p_execute_onexit_table)(MSVCRT__onexit_table_t *table);
static int (CDECL *p___fpe_flt_rounds)(void); static int (CDECL *p___fpe_flt_rounds)(void);
static unsigned int (CDECL *p__controlfp)(unsigned int, unsigned int); static unsigned int (CDECL *p__controlfp)(unsigned int, unsigned int);
static _invalid_parameter_handler (CDECL *p__set_invalid_parameter_handler)(_invalid_parameter_handler);
static _invalid_parameter_handler (CDECL *p__get_invalid_parameter_handler)(void);
static _invalid_parameter_handler (CDECL *p__set_thread_local_invalid_parameter_handler)(_invalid_parameter_handler);
static _invalid_parameter_handler (CDECL *p__get_thread_local_invalid_parameter_handler)(void);
static int (CDECL *p__ltoa_s)(LONG, char*, size_t, int);
static void test__initialize_onexit_table(void) static void test__initialize_onexit_table(void)
{ {
...@@ -223,6 +255,63 @@ static void test___fpe_flt_rounds(void) ...@@ -223,6 +255,63 @@ static void test___fpe_flt_rounds(void)
ok(ret == 0, "__fpe_flt_rounds returned %d\n", ret); ok(ret == 0, "__fpe_flt_rounds returned %d\n", ret);
} }
static void __cdecl global_invalid_parameter_handler(
const wchar_t *expression, const wchar_t *function,
const wchar_t *file, unsigned line, uintptr_t arg)
{
CHECK_EXPECT(global_invalid_parameter_handler);
}
static void __cdecl thread_invalid_parameter_handler(
const wchar_t *expression, const wchar_t *function,
const wchar_t *file, unsigned line, uintptr_t arg)
{
CHECK_EXPECT(thread_invalid_parameter_handler);
}
static void test_invalid_parameter_handler(void)
{
_invalid_parameter_handler ret;
ret = p__get_invalid_parameter_handler();
ok(!ret, "ret != NULL\n");
ret = p__get_thread_local_invalid_parameter_handler();
ok(!ret, "ret != NULL\n");
ret = p__set_thread_local_invalid_parameter_handler(thread_invalid_parameter_handler);
ok(!ret, "ret != NULL\n");
ret = p__get_thread_local_invalid_parameter_handler();
ok(ret == thread_invalid_parameter_handler, "ret = %p\n", ret);
ret = p__get_invalid_parameter_handler();
ok(!ret, "ret != NULL\n");
ret = p__set_invalid_parameter_handler(global_invalid_parameter_handler);
ok(!ret, "ret != NULL\n");
ret = p__get_invalid_parameter_handler();
ok(ret == global_invalid_parameter_handler, "ret = %p\n", ret);
ret = p__get_thread_local_invalid_parameter_handler();
ok(ret == thread_invalid_parameter_handler, "ret = %p\n", ret);
SET_EXPECT(thread_invalid_parameter_handler);
p__ltoa_s(0, NULL, 0, 0);
CHECK_CALLED(thread_invalid_parameter_handler);
ret = p__set_thread_local_invalid_parameter_handler(NULL);
ok(ret == thread_invalid_parameter_handler, "ret = %p\n", ret);
SET_EXPECT(global_invalid_parameter_handler);
p__ltoa_s(0, NULL, 0, 0);
CHECK_CALLED(global_invalid_parameter_handler);
ret = p__set_invalid_parameter_handler(NULL);
ok(ret == global_invalid_parameter_handler, "ret = %p\n", ret);
}
static BOOL init(void) static BOOL init(void)
{ {
HMODULE module = LoadLibraryA("ucrtbase.dll"); HMODULE module = LoadLibraryA("ucrtbase.dll");
...@@ -237,6 +326,11 @@ static BOOL init(void) ...@@ -237,6 +326,11 @@ static BOOL init(void)
p_execute_onexit_table = (void*)GetProcAddress(module, "_execute_onexit_table"); p_execute_onexit_table = (void*)GetProcAddress(module, "_execute_onexit_table");
p___fpe_flt_rounds = (void*)GetProcAddress(module, "__fpe_flt_rounds"); p___fpe_flt_rounds = (void*)GetProcAddress(module, "__fpe_flt_rounds");
p__controlfp = (void*)GetProcAddress(module, "_controlfp"); p__controlfp = (void*)GetProcAddress(module, "_controlfp");
p__set_invalid_parameter_handler = (void*)GetProcAddress(module, "_set_invalid_parameter_handler");
p__get_invalid_parameter_handler = (void*)GetProcAddress(module, "_get_invalid_parameter_handler");
p__set_thread_local_invalid_parameter_handler = (void*)GetProcAddress(module, "_set_thread_local_invalid_parameter_handler");
p__get_thread_local_invalid_parameter_handler = (void*)GetProcAddress(module, "_get_thread_local_invalid_parameter_handler");
p__ltoa_s = (void*)GetProcAddress(module, "_ltoa_s");
return TRUE; return TRUE;
} }
...@@ -246,6 +340,7 @@ START_TEST(misc) ...@@ -246,6 +340,7 @@ START_TEST(misc)
if(!init()) if(!init())
return; return;
test_invalid_parameter_handler();
test__initialize_onexit_table(); test__initialize_onexit_table();
test__register_onexit_function(); test__register_onexit_function();
test__execute_onexit_table(); test__execute_onexit_table();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment