diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 7294d89568e..66b56b0eba8 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -470,7 +470,7 @@ @ stub _get_errno @ stub _get_fmode @ stub _get_heap_handle -@ stub _get_invalid_parameter_handler +@ cdecl _get_invalid_parameter_handler() msvcr90._get_invalid_parameter_handler @ cdecl _get_osfhandle(long) msvcrt._get_osfhandle @ stub _get_osplatform @ stub _get_osver @@ -533,7 +533,7 @@ @ stub _inp @ stub _inpd @ stub _inpw -@ stub _invalid_parameter +@ extern _invalid_parameter msvcrt._invalid_parameter @ stub _invalid_parameter_noinfo @ stub _invoke_watson @ extern _iob msvcrt._iob @@ -873,7 +873,7 @@ @ stub _set_errno @ cdecl _set_error_mode(long) msvcrt._set_error_mode @ stub _set_fmode -@ stub _set_invalid_parameter_handler +@ cdecl _set_invalid_parameter_handler(ptr) msvcr90._set_invalid_parameter_handler @ stub _set_malloc_crt_max_wait @ stub _set_output_format @ stub _set_printf_count_output diff --git a/dlls/msvcr90/msvcr90.c b/dlls/msvcr90/msvcr90.c index 1bada8b1d84..4fa65b5e544 100644 --- a/dlls/msvcr90/msvcr90.c +++ b/dlls/msvcr90/msvcr90.c @@ -27,6 +27,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcr90); typedef int (CDECL *_INITTERM_E_FN)(void); +typedef void (__cdecl *_invalid_parameter_handler)(const wchar_t*, const wchar_t*, const wchar_t*, unsigned, unsigned*); /********************************************************************* * DllMain (MSVCR90.@) @@ -76,6 +77,30 @@ void * CDECL _encoded_null(void) return MSVCR90_encode_pointer(NULL); } +/********************************************************************* + * _get_invalid_parameter_handler (MSVCR90.@) + */ +_invalid_parameter_handler CDECL _get_invalid_parameter_handler(void) +{ + TRACE("\n"); + return *((_invalid_parameter_handler*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_invalid_parameter")); +} + +/********************************************************************* + * _set_invalid_parameter_handler (MSVCR90.@) + */ +_invalid_parameter_handler CDECL _set_invalid_parameter_handler(_invalid_parameter_handler handler) +{ + _invalid_parameter_handler *ptr = (_invalid_parameter_handler*)GetProcAddress( + GetModuleHandleA("msvcrt.dll"), "_invalid_parameter"); + _invalid_parameter_handler old = *ptr; + + TRACE("(%p)\n", handler); + + *ptr = handler; + return old; +} + /********************************************************************* * _initterm_e (MSVCR90.@) * diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 9feaa477eb5..0255b96adf2 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -462,7 +462,7 @@ @ stub _get_errno @ stub _get_fmode @ stub _get_heap_handle -@ stub _get_invalid_parameter_handler +@ cdecl _get_invalid_parameter_handler() @ cdecl _get_osfhandle(long) msvcrt._get_osfhandle @ stub _get_output_format @ stub _get_pgmptr @@ -521,7 +521,7 @@ @ stub _inp @ stub _inpd @ stub _inpw -@ stub _invalid_parameter +@ extern _invalid_parameter msvcrt._invalid_parameter @ stub _invalid_parameter_noinfo @ stub _invoke_watson @ extern _iob msvcrt._iob @@ -859,7 +859,7 @@ @ stub _set_errno @ cdecl _set_error_mode(long) msvcrt._set_error_mode @ stub _set_fmode -@ stub _set_invalid_parameter_handler +@ cdecl _set_invalid_parameter_handler(ptr) @ stub _set_malloc_crt_max_wait @ stub _set_output_format @ stub _set_printf_count_output diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index f332622baf3..03d75eef9cb 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -25,6 +25,7 @@ #include #include "wine/test.h" +static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler); typedef int (__cdecl *_INITTERM_E_FN)(void); static int (__cdecl *p_initterm_e)(_INITTERM_E_FN *table, _INITTERM_E_FN *end); static void* (__cdecl *p_encode_pointer)(void *); @@ -35,6 +36,17 @@ int cb_called[4]; /* ########## */ +void __cdecl test_invalid_parameter_handler(const wchar_t *expression, + const wchar_t *function, const wchar_t *file, + unsigned line, unsigned *res) +{ + ok(expression == NULL, "expression is not NULL\n"); + ok(function == NULL, "function is not NULL\n"); + ok(file == NULL, "file is not NULL\n"); + ok(line == 0, "line = %u\n", line); + ok(res == NULL, "res = %p\n", res); +} + static int initterm_cb0(void) { cb_called[0]++; @@ -169,6 +181,11 @@ START_TEST(msvcr90) return; } + p_set_invalid_parameter_handler = (void *) GetProcAddress(hcrt, "_set_invalid_parameter_handler"); + if(p_set_invalid_parameter_handler) + ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL, + "Invalid parameter handler was already set\n"); + p_initterm_e = (void *) GetProcAddress(hcrt, "_initterm_e"); p_encode_pointer = (void *) GetProcAddress(hcrt, "_encode_pointer"); p_decode_pointer = (void *) GetProcAddress(hcrt, "_decode_pointer"); diff --git a/dlls/msvcrt/errno.c b/dlls/msvcrt/errno.c index 413ab391fc0..c4c861885e9 100644 --- a/dlls/msvcrt/errno.c +++ b/dlls/msvcrt/errno.c @@ -117,6 +117,7 @@ char *MSVCRT__sys_errlist[] = }; unsigned int MSVCRT__sys_nerr = sizeof(MSVCRT__sys_errlist)/sizeof(MSVCRT__sys_errlist[0]) - 1; +MSVCRT_invalid_parameter_handler MSVCRT_invalid_parameter = NULL; /* INTERNAL: Set the crt and dos errno's from the OS error given. */ void msvcrt_set_errno(int err) diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 1de0c7ba216..1000f3ddb2d 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -75,6 +75,7 @@ typedef void (*__cdecl MSVCRT__se_translator_function)(unsigned int code, struct typedef void (*__cdecl MSVCRT__beginthread_start_routine_t)(void *); typedef unsigned int (__stdcall *MSVCRT__beginthreadex_start_routine_t)(void *); typedef int (*__cdecl MSVCRT__onexit_t)(void); +typedef void (__cdecl *MSVCRT_invalid_parameter_handler)(const wchar_t*, const wchar_t*, const wchar_t*, unsigned, unsigned*); typedef struct {long double x;} MSVCRT__LDOUBLE; @@ -124,6 +125,7 @@ extern LCID MSVCRT_current_lc_all_lcid; extern WORD MSVCRT__ctype [257]; extern WORD MSVCRT_current_ctype[257]; extern WORD* MSVCRT__pctype; +extern MSVCRT_invalid_parameter_handler MSVCRT_invalid_parameter; void msvcrt_set_errno(int); diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 988d48e0509..bee7ba1947d 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -479,7 +479,7 @@ @ stub _inp #(long) -i386 @ stub _inpd #(long) -i386 @ stub _inpw #(long) -i386 -# stub _invalid_parameter +@ extern _invalid_parameter MSVCRT_invalid_parameter @ extern _iob MSVCRT__iob # stub _isalnum_l # stub _isalpha_l diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 6fd64d9ee7a..e19c54381af 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -53,6 +53,7 @@ static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsig static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc); static int (__cdecl *p_wcsupr_s)(wchar_t *str, size_t size); static size_t (__cdecl *p_strnlen)(const char *, size_t); +static _invalid_parameter_handler *p_invalid_parameter; static int *p__mb_cur_max; static unsigned char *p_mbctype; @@ -61,6 +62,17 @@ static unsigned char *p_mbctype; HMODULE hMsvcrt; +void __cdecl test_invalid_parameter_handler(const wchar_t *expression, + const wchar_t *function, const wchar_t *file, + unsigned line, unsigned *res) +{ + ok(expression == NULL, "expression is not NULL\n"); + ok(function == NULL, "function is not NULL\n"); + ok(file == NULL, "file is not NULL\n"); + ok(line == 0, "line = %u\n", line); + ok(res == NULL, "res = %p\n", res); +} + static void test_swab( void ) { char original[] = "BADCFEHGJILKNMPORQTSVUXWZY@#"; char expected1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@#"; @@ -946,6 +958,9 @@ START_TEST(string) SET(pmemcmp,"memcmp"); SET(p_mbctype,"_mbctype"); SET(p__mb_cur_max,"__mb_cur_max"); + p_invalid_parameter = (void *)GetProcAddress( hMsvcrt,"_invalid_parameter"); + if(p_invalid_parameter) + *p_invalid_parameter = test_invalid_parameter_handler; pstrcpy_s = (void *)GetProcAddress( hMsvcrt,"strcpy_s" ); pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" ); p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" ); diff --git a/include/msvcrt/stdlib.h b/include/msvcrt/stdlib.h index 2531f73b5f6..617bd1c5b68 100644 --- a/include/msvcrt/stdlib.h +++ b/include/msvcrt/stdlib.h @@ -261,4 +261,8 @@ static inline ldiv_t __wine_msvcrt_ldiv(__msvcrt_long num, __msvcrt_long denom) #include +typedef void (__cdecl *_invalid_parameter_handler)(const wchar_t*, const wchar_t*, const wchar_t*, unsigned, unsigned*); +_invalid_parameter_handler __cdecl _set_invalid_parameter_handler(_invalid_parameter_handler); +_invalid_parameter_handler __cdecl _get_invalid_parameter_handler(void); + #endif /* __WINE_STDLIB_H */