From: Theodoros Chatzigiannakis <tchatzigiannakis@gmail.com> --- dlls/msvcp140/tests/msvcp140.c | 132 +++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c index bad48e4934e..21b783bc6a0 100644 --- a/dlls/msvcp140/tests/msvcp140.c +++ b/dlls/msvcp140/tests/msvcp140.c @@ -93,6 +93,7 @@ struct thiscall_thunk static void * (WINAPI *call_thiscall_func1)( void *func, void *this ); static void * (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a ); +static void * (WINAPI *call_thiscall_func4)( void *func, void *this, const void *a, const void *b, const void *c ); static void * (WINAPI *call_thiscall_func5)( void *func, void *this, const void *a, const void *b, const void *c, const void *d ); static void * (WINAPI *call_thiscall_func8)( void *func, void *this, const void *a, const void *b, @@ -109,12 +110,14 @@ static void init_thiscall_thunk(void) thunk->jmp_edx = 0xe2ff; /* jmp *%edx */ call_thiscall_func1 = (void *)thunk; call_thiscall_func2 = (void *)thunk; + call_thiscall_func4 = (void *)thunk; call_thiscall_func5 = (void *)thunk; call_thiscall_func8 = (void *)thunk; } #define call_func1(func,_this) call_thiscall_func1(func,_this) #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a)) +#define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)(a),(const void*)(b),(const void*)(c)) #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),(const void*)(b), \ (const void*)(c), (const void*)(d)) #define call_func8(func,_this,a,b,c,d,e,f,g) call_thiscall_func8(func,_this,(const void*)(a),(const void*)(b), \ @@ -125,6 +128,7 @@ static void init_thiscall_thunk(void) #define init_thiscall_thunk() #define call_func1(func,_this) func(_this) #define call_func2(func,_this,a) func(_this,a) +#define call_func4(func,_this,a,b,c) func(_this,a,b,c) #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d) #define call_func8(func,_this,a,b,c,d,e,f,g) func(_this,a,b,c,d,e,f,g) @@ -361,6 +365,75 @@ typedef struct static void (__cdecl *p___ExceptionPtrSwap)(exception_ptr *a, exception_ptr *b); +typedef SSIZE_T streamsize; + +typedef struct { void *mutex; } mutex; +typedef struct { struct _locale__Locimp *ptr; } locale; + +typedef struct { + const void *vtable; + MSVCP_size_t stdstr; + int state, except, fmtfl; + streamsize prec, wide; + void *arr, *calls; + locale *loc; +} ios_base; + +typedef struct { + ios_base base; + void *strbuf, *stream; + char fillch; +} basic_ios_char; + +typedef struct { const int *vbtable; } basic_ostream_char; + +typedef struct { + const int *vbtable; + streamsize count; +} basic_istream_char; + +typedef struct { + basic_istream_char base1; + basic_ostream_char base2; +} basic_iostream_char; + +typedef struct { + const void *vtable; + mutex lock; + char *rbuf, *wbuf, **prbuf, **pwbuf, *rpos, *wpos, **prpos, **pwpos; + int rsize, wsize, *prsize, *pwsize; + locale *loc; +} basic_streambuf_char; + +typedef struct { + basic_streambuf_char base; + char *seekhigh; + int state; + char allocator; +} basic_stringbuf_char; + +typedef struct { + basic_iostream_char base; + basic_stringbuf_char strbuf; + /* virtual inheritance */ + basic_ios_char basic_ios; +} basic_stringstream_char; + +#define BUF_SIZE_CHAR 16 +typedef struct { + void *allocator; + union { char buf[BUF_SIZE_CHAR]; char *ptr; } data; + size_t size, res; +} basic_string_char; + +static basic_string_char* (__thiscall *p_basic_string_char_ctor_cstr)(basic_string_char*, const char*); +static void (__thiscall *p_basic_string_char_dtor)(basic_string_char*); +static basic_stringstream_char* (__thiscall *p_basic_stringstream_char_ctor_str)(basic_stringstream_char*, + const basic_string_char*, int, MSVCP_bool); +static void (__thiscall *p_basic_stringstream_char_vbase_dtor)(basic_stringstream_char*); +static int (__thiscall *p_basic_istream_char_get)(basic_istream_char*); +static basic_istream_char* (__thiscall *p_basic_istream_char_assign)(basic_istream_char*, basic_istream_char*); + static HMODULE msvcp; #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y) #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0) @@ -401,6 +474,18 @@ static BOOL init(void) SET(p__Fiopen_wchar, "?_Fiopen@std@@YAPEAU_iobuf@@PEB_WHH@Z"); SET(p__Fiopen, "?_Fiopen@std@@YAPEAU_iobuf@@PEBDHH@Z"); + SET(p_basic_string_char_ctor_cstr, + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@PEBD@Z"); + SET(p_basic_string_char_dtor, + "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@XZ"); + SET(p_basic_stringstream_char_ctor_str, + "??0?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@H@Z"); + SET(p_basic_stringstream_char_vbase_dtor, + "??_D?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXXZ"); + SET(p_basic_istream_char_get, + "?get@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAHXZ"); + SET(p_basic_istream_char_assign, + "??4?$basic_istream@DU?$char_traits@D@std@@@std@@IEAAAEAV01@$$QEAV01@@Z"); SET(p_codecvt_char16_ctor, "??_F?$codecvt@_SDU_Mbstatet@@@std@@QEAAXXZ"); SET(p_codecvt_char16_ctor_refs, "??0?$codecvt@_SDU_Mbstatet@@@std@@QEAA@_K@Z"); SET(p_codecvt_char16_ctor_mode, "??0?$codecvt@_SDU_Mbstatet@@@std@@QEAA@AEBV_Locinfo@1@KW4_Codecvt_mode@1@_K@Z"); @@ -420,6 +505,18 @@ static BOOL init(void) SET(p__TaskEventLogger__LogTaskExecutionCompleted, "?_LogTaskExecutionCompleted@_TaskEventLogger@details@Concurrency@@QAAXXZ"); SET(p__TaskEventLogger__LogWorkItemCompleted, "?_LogWorkItemCompleted@_TaskEventLogger@details@Concurrency@@QAAXXZ"); SET(p__TaskEventLogger__LogWorkItemStarted, "?_LogWorkItemStarted@_TaskEventLogger@details@Concurrency@@QAAXXZ"); + SET(p_basic_string_char_ctor_cstr, + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAA@PBD@Z"); + SET(p_basic_string_char_dtor, + "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAA@XZ"); + SET(p_basic_stringstream_char_ctor_str, + "??0?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAA@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@H@Z"); + SET(p_basic_stringstream_char_vbase_dtor, + "??_D?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAAXXZ"); + SET(p_basic_istream_char_get, + "?get@?$basic_istream@DU?$char_traits@D@std@@@std@@QAAHXZ"); + SET(p_basic_istream_char_assign, + "??4?$basic_istream@DU?$char_traits@D@std@@@std@@IAAAAV01@$$QAV01@@Z"); SET(p_codecvt_char16_ctor, "??_F?$codecvt@_SDU_Mbstatet@@@std@@QAAXXZ"); SET(p_codecvt_char16_ctor_refs, "??0?$codecvt@_SDU_Mbstatet@@@std@@QAA@I@Z"); SET(p_codecvt_char16_ctor_mode, "??0?$codecvt@_SDU_Mbstatet@@@std@@QAA@ABV_Locinfo@1@KW4_Codecvt_mode@1@I@Z"); @@ -438,6 +535,18 @@ static BOOL init(void) SET(p__TaskEventLogger__LogTaskExecutionCompleted, "?_LogTaskExecutionCompleted@_TaskEventLogger@details@Concurrency@@QAEXXZ"); SET(p__TaskEventLogger__LogWorkItemCompleted, "?_LogWorkItemCompleted@_TaskEventLogger@details@Concurrency@@QAEXXZ"); SET(p__TaskEventLogger__LogWorkItemStarted, "?_LogWorkItemStarted@_TaskEventLogger@details@Concurrency@@QAEXXZ"); + SET(p_basic_string_char_ctor_cstr, + "??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z"); + SET(p_basic_string_char_dtor, + "??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ"); + SET(p_basic_stringstream_char_ctor_str, + "??0?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@1@H@Z"); + SET(p_basic_stringstream_char_vbase_dtor, + "??_D?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXXZ"); + SET(p_basic_istream_char_get, + "?get@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEHXZ"); + SET(p_basic_istream_char_assign, + "??4?$basic_istream@DU?$char_traits@D@std@@@std@@IAEAAV01@$$QAV01@@Z"); SET(p_codecvt_char16_ctor, "??_F?$codecvt@_SDU_Mbstatet@@@std@@QAEXXZ"); SET(p_codecvt_char16_ctor_refs, "??0?$codecvt@_SDU_Mbstatet@@@std@@QAE@I@Z"); SET(p_codecvt_char16_ctor_mode, "??0?$codecvt@_SDU_Mbstatet@@@std@@QAE@ABV_Locinfo@1@KW4_Codecvt_mode@1@I@Z"); @@ -2482,6 +2591,28 @@ static void test_exception_pointer(void) ok(ptr2.ref == (void *)2, "ptr2.ref = %p\n", ptr2.ref); } +static void test_istream_assign(void) +{ + basic_stringstream_char ss1, ss2; + basic_string_char str; + + call_func2(p_basic_string_char_ctor_cstr, &str, "hello"); + call_func4(p_basic_stringstream_char_ctor_str, &ss1, &str, OPENMODE_out|OPENMODE_in, TRUE); + call_func4(p_basic_stringstream_char_ctor_str, &ss2, &str, OPENMODE_out|OPENMODE_in, TRUE); + call_func1(p_basic_string_char_dtor, &str); + + call_func1(p_basic_istream_char_get, &ss1.base.base1); + ok(ss1.base.base1.count == 1, "expected count 1, got %d\n", (int)ss1.base.base1.count); + ok(ss2.base.base1.count == 0, "expected count 0, got %d\n", (int)ss2.base.base1.count); + + call_func2(p_basic_istream_char_assign, &ss1.base.base1, &ss2.base.base1); + ok(ss1.base.base1.count == 0, "expected count 0, got %d\n", (int)ss1.base.base1.count); + ok(ss2.base.base1.count == 1, "expected count 1, got %d\n", (int)ss2.base.base1.count); + + call_func1(p_basic_stringstream_char_vbase_dtor, &ss1); + call_func1(p_basic_stringstream_char_vbase_dtor, &ss2); +} + START_TEST(msvcp140) { if(!init()) return; @@ -2514,5 +2645,6 @@ START_TEST(msvcp140) test_codecvt_char16(); test_thread_library_reference(); test_exception_pointer(); + test_istream_assign(); FreeLibrary(msvcp); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10636