From 4438a8722287d389878a432ba9aa6ad27b47a944 Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Mon, 11 Apr 2016 14:19:00 -0700 Subject: [PATCH] ucrtbase: Add __std_exception_destroy/copy Signed-off-by: Daniel Lehman --- .../api-ms-win-crt-private-l1-1-0.spec | 4 +- dlls/msvcrt/except.c | 35 +++++++++ dlls/ucrtbase/tests/Makefile.in | 1 + dlls/ucrtbase/tests/cpp.c | 91 ++++++++++++++++++++++ dlls/ucrtbase/ucrtbase.spec | 4 +- dlls/vcruntime140/vcruntime140.spec | 4 +- 6 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 dlls/ucrtbase/tests/cpp.c diff --git a/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec b/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec index b7b0eec..c85a998 100644 --- a/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec +++ b/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec @@ -42,8 +42,8 @@ @ stub __intrinsic_setjmpex @ stub __processing_throw @ stub __report_gsfailure -@ stub __std_exception_copy -@ stub __std_exception_destroy +@ cdecl __std_exception_copy(ptr ptr) ucrtbase.__std_exception_copy +@ cdecl __std_exception_destroy(ptr) ucrtbase.__std_exception_destroy @ cdecl __std_type_info_compare(ptr ptr) ucrtbase.__std_type_info_compare @ stub __std_type_info_destroy_list @ stub __std_type_info_hash diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c index fc0e36e..7ca7b46 100644 --- a/dlls/msvcrt/except.c +++ b/dlls/msvcrt/except.c @@ -462,3 +462,38 @@ void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_us __DestructExceptionObject(data->exc_record); data->exc_record = frame_info->rec; } + +struct __std_exception_data { + char *what; + MSVCRT_bool dofree; +}; + +/********************************************************************* + * __std_exception_copy (MSVCRT.@) + */ +void CDECL MSVCRT___std_exception_copy(const struct __std_exception_data *src, + struct __std_exception_data *dst) +{ + TRACE("(%p %p)\n", src, dst); + + if(src->dofree) { + dst->what = MSVCRT__strdup(src->what); + dst->dofree = 1; + } else { + dst->what = src->what; + dst->dofree = 0; + } +} + +/********************************************************************* + * __std_exception_destroy (MSVCRT.@) + */ +void CDECL MSVCRT___std_exception_destroy(struct __std_exception_data *data) +{ + TRACE("(%p)\n", data); + + if(data->dofree) + MSVCRT_free(data->what); + data->what = NULL; + data->dofree = 0; +} diff --git a/dlls/ucrtbase/tests/Makefile.in b/dlls/ucrtbase/tests/Makefile.in index c4fa7c8..f84f328 100644 --- a/dlls/ucrtbase/tests/Makefile.in +++ b/dlls/ucrtbase/tests/Makefile.in @@ -2,5 +2,6 @@ TESTDLL = ucrtbase.dll APPMODE = -mno-cygwin C_SRCS = \ + cpp.c \ printf.c \ string.c diff --git a/dlls/ucrtbase/tests/cpp.c b/dlls/ucrtbase/tests/cpp.c new file mode 100644 index 0000000..33f9429 --- /dev/null +++ b/dlls/ucrtbase/tests/cpp.c @@ -0,0 +1,91 @@ +/* + * Copyright 2016 Daniel Lehman (Esri) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include + +#include +#include +#include "wine/test.h" + +typedef unsigned char MSVCRT_bool; + +typedef struct { + const char *what; + MSVCRT_bool dofree; +} __std_exception_data; + +static void (CDECL *p___std_exception_copy)(const __std_exception_data*, __std_exception_data*); +static void (CDECL *p___std_exception_destroy)(__std_exception_data*); + +static BOOL init(void) +{ + HMODULE module; + + module = LoadLibraryA("ucrtbase.dll"); + if (!module) + { + win_skip("ucrtbase.dll not installed\n"); + return FALSE; + } + + p___std_exception_copy = (void*)GetProcAddress(module, "__std_exception_copy"); + p___std_exception_destroy = (void*)GetProcAddress(module, "__std_exception_destroy"); + return TRUE; +} + +static void test___std_exception(void) +{ + __std_exception_data src; + __std_exception_data dst; + + if (0) /* crash on Windows */ + { + p___std_exception_copy(NULL, &src); + p___std_exception_copy(&dst, NULL); + + src.what = "invalid free"; + src.dofree = 1; + p___std_exception_destroy(&src); + p___std_exception_destroy(NULL); + } + + src.what = "what"; + src.dofree = 0; + p___std_exception_copy(&src, &dst); + ok(dst.what == src.what, "expected what to be same, got src %p dst %p\n", src.what, dst.what); + ok(!dst.dofree, "expected 0, got %d\n", dst.dofree); + + src.dofree = 0x42; + p___std_exception_copy(&src, &dst); + ok(dst.what != src.what, "expected what to be different, got src %p dst %p\n", src.what, dst.what); + ok(dst.dofree == 1, "expected 1, got %d\n", dst.dofree); + + p___std_exception_destroy(&dst); + ok(!dst.what, "expected NULL, got %p\n", dst.what); + ok(!dst.dofree, "expected 0, got %d\n", dst.dofree); +} + +START_TEST(cpp) +{ + if (!init()) return; + test___std_exception(); +} diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 0670f6e..664afe9 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -140,8 +140,8 @@ @ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ stub __report_gsfailure @ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr -@ stub __std_exception_copy -@ stub __std_exception_destroy +@ cdecl __std_exception_copy(ptr ptr) MSVCRT___std_exception_copy +@ cdecl __std_exception_destroy(ptr) MSVCRT___std_exception_destroy @ cdecl __std_type_info_compare(ptr ptr) MSVCRT_type_info_compare @ stub __std_type_info_destroy_list @ stub __std_type_info_hash diff --git a/dlls/vcruntime140/vcruntime140.spec b/dlls/vcruntime140/vcruntime140.spec index d8c33c4..ea8c93b 100644 --- a/dlls/vcruntime140/vcruntime140.spec +++ b/dlls/vcruntime140/vcruntime140.spec @@ -36,8 +36,8 @@ @ stub __intrinsic_setjmpex @ stub __processing_throw @ stub __report_gsfailure -@ stub __std_exception_copy -@ stub __std_exception_destroy +@ cdecl __std_exception_copy(ptr ptr) ucrtbase.__std_exception_copy +@ cdecl __std_exception_destroy(ptr) ucrtbase.__std_exception_destroy @ stub __std_terminate @ cdecl __std_type_info_compare(ptr ptr) ucrtbase.__std_type_info_compare @ stub __std_type_info_destroy_list -- 1.9.5