diff --git a/README.md b/README.md index 19a193bf..1ca76028 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,10 @@ Wine. All those differences are also documented on the Included bugfixes and improvements ================================== -**Bugfixes and features included in the next upcoming release [2]:** +**Bugfixes and features included in the next upcoming release [3]:** * Anno 1602 installer depends on Windows 98 behavior of SHFileOperationW +* FEAR 1 installer expects basic_string_wchar_dtor to return NULL ([Wine Bug #37358](http://bugs.winehq.org/show_bug.cgi?id=37358)) * Wine ignores IDF_CHECKFIRST flag in SetupPromptForDisk ([Wine Bug #20465](http://bugs.winehq.org/show_bug.cgi?id=20465)) diff --git a/patches/Makefile b/patches/Makefile index 98fdc0ee..ebf22ac7 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -37,6 +37,7 @@ PATCHLIST := \ kernel32-GetVolumePathName.ok \ kernel32-Named_Pipe.ok \ libs-Unicode_Collation.ok \ + msvcp60-basic_string_wchar_dtor.ok \ ntdll-ATL_Thunk.ok \ ntdll-DOS_Attributes.ok \ ntdll-Dynamic_DST.ok \ @@ -499,6 +500,25 @@ libs-Unicode_Collation.ok: echo '+ { "libs-Unicode_Collation", "Dmitry Timoshkov", "Fix comparison of punctuation characters." },'; \ ) > libs-Unicode_Collation.ok +# Patchset msvcp60-basic_string_wchar_dtor +# | +# | Included patches: +# | * basic_string_wchar_dtor needs to return NULL. [by Michael Müller] +# | +# | This patchset fixes the following Wine bugs: +# | * [#37358] FEAR 1 installer expects basic_string_wchar_dtor to return NULL +# | +# | Modified files: +# | * dlls/msvcp60/msvcp.h, dlls/msvcp60/string.c, dlls/msvcp60/tests/string.c +# | +.INTERMEDIATE: msvcp60-basic_string_wchar_dtor.ok +msvcp60-basic_string_wchar_dtor.ok: + $(call APPLY_FILE,msvcp60-basic_string_wchar_dtor/0001-msvcp60-basic_string_wchar_dtor-needs-to-return-NULL.patch) + $(call APPLY_FILE,msvcp60-basic_string_wchar_dtor/0002-msvcp60-tests-Add-tests-to-check-that-basic_string_w.patch) + @( \ + echo '+ { "msvcp60-basic_string_wchar_dtor", "Michael Müller", "basic_string_wchar_dtor needs to return NULL." },'; \ + ) > msvcp60-basic_string_wchar_dtor.ok + # Patchset ntdll-ATL_Thunk # | # | Included patches: diff --git a/patches/msvcp60-basic_string_wchar_dtor/0001-msvcp60-basic_string_wchar_dtor-needs-to-return-NULL.patch b/patches/msvcp60-basic_string_wchar_dtor/0001-msvcp60-basic_string_wchar_dtor-needs-to-return-NULL.patch new file mode 100644 index 00000000..ecf9c453 --- /dev/null +++ b/patches/msvcp60-basic_string_wchar_dtor/0001-msvcp60-basic_string_wchar_dtor-needs-to-return-NULL.patch @@ -0,0 +1,43 @@ +From 9274fd3f783aceb822e5ba83797cd8b77eee1872 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 9 Oct 2014 05:08:36 +0200 +Subject: msvcp60: basic_string_wchar_dtor needs to return NULL. + +--- + dlls/msvcp60/msvcp.h | 2 +- + dlls/msvcp60/string.c | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/dlls/msvcp60/msvcp.h b/dlls/msvcp60/msvcp.h +index 0a8c57c..7a3017c 100644 +--- a/dlls/msvcp60/msvcp.h ++++ b/dlls/msvcp60/msvcp.h +@@ -64,7 +64,7 @@ typedef struct + basic_string_wchar* __thiscall basic_string_wchar_ctor(basic_string_wchar*); + basic_string_wchar* basic_string_wchar_ctor_cstr(basic_string_wchar*, const wchar_t*); + basic_string_wchar* basic_string_wchar_ctor_cstr_len(basic_string_wchar*, const wchar_t*, MSVCP_size_t); +-void __thiscall basic_string_wchar_dtor(basic_string_wchar*); ++void* __thiscall basic_string_wchar_dtor(basic_string_wchar*); + const wchar_t* __thiscall basic_string_wchar_c_str(const basic_string_wchar*); + void basic_string_wchar_clear(basic_string_wchar*); + basic_string_wchar* __thiscall basic_string_wchar_append_ch(basic_string_wchar*, wchar_t); +diff --git a/dlls/msvcp60/string.c b/dlls/msvcp60/string.c +index f1b2b8e..b1a6c42 100644 +--- a/dlls/msvcp60/string.c ++++ b/dlls/msvcp60/string.c +@@ -2264,10 +2264,11 @@ basic_string_wchar* __thiscall basic_string_wchar_copy_ctor( + /* ??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE@XZ */ + /* ??1?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QEAA@XZ */ + DEFINE_THISCALL_WRAPPER(basic_string_wchar_dtor, 4) +-void __thiscall basic_string_wchar_dtor(basic_string_wchar *this) ++void* __thiscall basic_string_wchar_dtor(basic_string_wchar *this) + { + TRACE("%p\n", this); + basic_string_wchar__Tidy(this, TRUE); ++ return NULL; + } + + /* ?compare@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBEHIIPBGI@Z */ +-- +1.9.1 + diff --git a/patches/msvcp60-basic_string_wchar_dtor/0002-msvcp60-tests-Add-tests-to-check-that-basic_string_w.patch b/patches/msvcp60-basic_string_wchar_dtor/0002-msvcp60-tests-Add-tests-to-check-that-basic_string_w.patch new file mode 100644 index 00000000..1a04b0b9 --- /dev/null +++ b/patches/msvcp60-basic_string_wchar_dtor/0002-msvcp60-tests-Add-tests-to-check-that-basic_string_w.patch @@ -0,0 +1,129 @@ +From ff60b7b765182e57c09609017964a5eebe1703e3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Thu, 9 Oct 2014 05:22:24 +0200 +Subject: msvcp60/tests: Add tests to check that basic_string_wchar_dtor + returns NULL. + +--- + dlls/msvcp60/tests/string.c | 72 ++++++++++++++++++++++++++++++--------------- + 1 file changed, 49 insertions(+), 23 deletions(-) + +diff --git a/dlls/msvcp60/tests/string.c b/dlls/msvcp60/tests/string.c +index 3ed1480..681d714 100644 +--- a/dlls/msvcp60/tests/string.c ++++ b/dlls/msvcp60/tests/string.c +@@ -92,32 +92,35 @@ static void (__thiscall *p_basic_string_wchar_swap)(basic_string_wchar*, basic_s + #include "pshpack1.h" + struct thiscall_thunk + { +- BYTE pop_eax; /* popl %eax (ret addr) */ +- BYTE pop_edx; /* popl %edx (func) */ +- BYTE pop_ecx; /* popl %ecx (this) */ +- BYTE push_eax; /* pushl %eax */ +- WORD jmp_edx; /* jmp *%edx */ ++ BYTE pop_ecx; /* popl %ecx (ret addr) */ ++ BYTE pop_edx; /* popl %edx (func) */ ++ BYTE pop_eax; /* popl %eax (eax value) */ ++ BYTE xchg_ecx_esp[3]; /* xchg %ecx, *%esp (this <-> ret addr) */ ++ WORD jmp_edx; /* jmp *%edx */ + }; + #include "poppack.h" + +-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_func3)( void *func, void *this, const void *a, const void *b ); +-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_func6)( void *func, void *this, const void *a, const void *b, +- const void *c, const void *d, const void *e ); ++static void * (WINAPI *call_thiscall_func1)( void *func, unsigned int eax, void *this); ++static void * (WINAPI *call_thiscall_func2)( void *func, unsigned int eax, void *this, const void *a ); ++static void * (WINAPI *call_thiscall_func3)( void *func, unsigned int eax, void *this, const void *a, ++ const void *b ); ++static void * (WINAPI *call_thiscall_func4)( void *func, unsigned int eax, void *this, const void *a, ++ const void *b, const void *c ); ++static void * (WINAPI *call_thiscall_func5)( void *func, unsigned int eax, void *this, const void *a, ++ const void *b, const void *c, const void *d ); ++static void * (WINAPI *call_thiscall_func6)( void *func, unsigned int eax, void *this, const void *a, ++ const void *b, const void *c, const void *d, const void *e ); + + static void init_thiscall_thunk(void) + { + struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk), + MEM_COMMIT, PAGE_EXECUTE_READWRITE ); +- thunk->pop_eax = 0x58; /* popl %eax */ +- thunk->pop_edx = 0x5a; /* popl %edx */ + thunk->pop_ecx = 0x59; /* popl %ecx */ +- thunk->push_eax = 0x50; /* pushl %eax */ ++ thunk->pop_edx = 0x5a; /* popl %edx */ ++ thunk->pop_eax = 0x58; /* popl %eax */ ++ thunk->xchg_ecx_esp[0] = 0x87; /* xchg %ecx, *%esp */ ++ thunk->xchg_ecx_esp[1] = 0x0c; ++ thunk->xchg_ecx_esp[2] = 0x24; + thunk->jmp_edx = 0xe2ff; /* jmp *%edx */ + call_thiscall_func1 = (void *)thunk; + call_thiscall_func2 = (void *)thunk; +@@ -127,15 +130,17 @@ static void init_thiscall_thunk(void) + call_thiscall_func6 = (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_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)a,(const void*)b) +-#define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)a,\ ++ ++#define call_func1(func,_this) call_thiscall_func1(func,0,_this) ++#define call_func2(func,_this,a) call_thiscall_func2(func,0,_this,(const void*)a) ++#define call_func3(func,_this,a,b) call_thiscall_func3(func,0,_this,(const void*)a,(const void*)b) ++#define call_func4(func,_this,a,b,c) call_thiscall_func4(func,0,_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,\ ++#define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,0,_this,(const void*)a,\ + (const void*)b,(const void*)c,(const void*)d) +-#define call_func6(func,_this,a,b,c,d,e) call_thiscall_func6(func,_this,(const void*)a,\ ++#define call_func6(func,_this,a,b,c,d,e) call_thiscall_func6(func,0,_this,(const void*)a,\ + (const void*)b,(const void*)c,(const void*)d,(const void*)e) ++#define call_func1_eax(func,eax,_this) call_thiscall_func1(func,eax,_this) + + #else + +@@ -687,6 +692,26 @@ static void test_basic_string_wchar_swap(void) { + call_func1(p_basic_string_wchar_dtor, &str2); + } + ++static void test_basic_string_dtor_eax(void) { ++#ifdef __i386__ ++ basic_string_wchar str1; ++ void *ret; ++ wchar_t wtmp1[32]; ++ ++ mbstowcs(wtmp1, "qwerty", 32); ++ ++ /* eax = 0x1337 */ ++ call_func3(p_basic_string_wchar_ctor_cstr_alloc, &str1, wtmp1, &fake_allocator); ++ ret = call_func1_eax(p_basic_string_wchar_dtor, 0x1337, &str1); ++ ok (ret == (void *)0x0, "Expected eax value 0x%x, got 0x%x\n", 0x0, (unsigned int)ret); ++ ++ /* eax = 0xdeadbeef */ ++ call_func3(p_basic_string_wchar_ctor_cstr_alloc, &str1, wtmp1, &fake_allocator); ++ ret = call_func1_eax(p_basic_string_wchar_dtor, 0xdeadbeef, &str1); ++ ok (ret == (void *)0x0, "Expected eax value 0x%x, got 0x%x\n", 0x0, (unsigned int)ret); ++#endif ++} ++ + START_TEST(string) + { + if(!init()) +@@ -702,6 +727,7 @@ START_TEST(string) + test_basic_string_char_replace(); + test_basic_string_wchar(); + test_basic_string_wchar_swap(); ++ test_basic_string_dtor_eax(); + + FreeLibrary(msvcp); + } +-- +1.9.1 + diff --git a/patches/msvcp60-basic_string_wchar_dtor/definition b/patches/msvcp60-basic_string_wchar_dtor/definition new file mode 100644 index 00000000..b7717ae3 --- /dev/null +++ b/patches/msvcp60-basic_string_wchar_dtor/definition @@ -0,0 +1,4 @@ +Author: Michael Müller +Subject: basic_string_wchar_dtor needs to return NULL. +Revision: 1 +Fixes: [37358] FEAR 1 installer expects basic_string_wchar_dtor to return NULL