Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
September 2020
- 79 participants
- 771 discussions
Based on the semi-stubs by Gijs Vermeulen.
We need to check that calls to different methods translate correctly to
modifications done on the internal filebuf - not all methods call their
filebuf counterparts directly (see setbuf).
Tested with Power Tab Editor and GraphCalc - the crashes are gone and loading
saved files seems to work correctly.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22616
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=30014
Signed-off-by: Arkadiusz Hiler <ahiler(a)codeweavers.com>
---
dlls/msvcirt/msvcirt.c | 185 ++++++++++++++++++++++++++
dlls/msvcirt/msvcirt.spec | 72 +++++------
dlls/msvcirt/tests/msvcirt.c | 243 +++++++++++++++++++++++++++++++++++
dlls/msvcrt20/msvcrt20.spec | 72 +++++------
dlls/msvcrt40/msvcrt40.spec | 72 +++++------
5 files changed, 536 insertions(+), 108 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index f76eaf6d7ac..a54d86f7350 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -192,6 +192,8 @@ extern const vtable_ptr MSVCP_istream_vtable;
extern const vtable_ptr MSVCP_istream_withassign_vtable;
/* ??_7istrstream@@6B@ */
extern const vtable_ptr MSVCP_istrstream_vtable;
+/* ??_7ifstream@@6B@ */
+extern const vtable_ptr MSVCP_ifstream_vtable;
/* ??_7iostream@@6B@ */
extern const vtable_ptr MSVCP_iostream_vtable;
/* ??_7strstream@@6B@ */
@@ -262,6 +264,8 @@ __ASM_BLOCK_BEGIN(vtables)
VTABLE_ADD_FUNC(istream_vector_dtor));
__ASM_VTABLE(istrstream,
VTABLE_ADD_FUNC(istream_vector_dtor));
+ __ASM_VTABLE(ifstream,
+ VTABLE_ADD_FUNC(istream_vector_dtor));
__ASM_VTABLE(iostream,
VTABLE_ADD_FUNC(iostream_vector_dtor));
__ASM_VTABLE(strstream,
@@ -280,6 +284,7 @@ const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, v
/* ??_8istream@@7B@ */
/* ??_8istream_withassign@@7B@ */
/* ??_8istrstream@@7B@ */
+/* ??_8ifstream@@7B@ */
const int istream_vbtable[] = {0, VBTABLE_ENTRY(istream, FIELD_OFFSET(istream, vbtable), ios)};
/* ??_8iostream@@7Bistream@@@ */
/* ??_8stdiostream@@7Bistream@@@ */
@@ -305,6 +310,8 @@ DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream),
&istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@")
DEFINE_RTTI_DATA2(istrstream, sizeof(istream),
&istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistrstream@@")
+DEFINE_RTTI_DATA2(ifstream, sizeof(istream),
+ &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVifstream@@")
DEFINE_RTTI_DATA4(iostream, sizeof(iostream),
&istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
&ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@")
@@ -3113,6 +3120,8 @@ istream* __thiscall istream_copy_ctor(istream *this, const istream *copy, BOOL v
/* ??1istream_withassign@@UEAA(a)XZ */
/* ??1istrstream@@UAE(a)XZ */
/* ??1istrstream@@UEAA(a)XZ */
+/* ??1ifstream@@UAE(a)XZ */
+/* ??1ifstream@@UEAA(a)XZ */
DEFINE_THISCALL_WRAPPER(istream_dtor, 4)
void __thiscall istream_dtor(ios *base)
{
@@ -3152,6 +3161,8 @@ istream* __thiscall istream_assign_sb(istream *this, streambuf *sb)
/* ??4istream_withassign@@QEAAAEAVistream@@AEBV1@@Z */
/* ??4istrstream@@QAEAAV0(a)ABV0@@Z */
/* ??4istrstream@@QEAAAEAV0(a)AEBV0@@Z */
+/* ??4ifstream@@QAEAAV0(a)ABV0@@Z */
+/* ??4ifstream@@QEAAAEAV0(a)AEBV0@@Z */
DEFINE_THISCALL_WRAPPER(istream_assign, 8)
istream* __thiscall istream_assign(istream *this, const istream *rhs)
{
@@ -3164,6 +3175,8 @@ istream* __thiscall istream_assign(istream *this, const istream *rhs)
/* ??_Distream_withassign@@QEAAXXZ */
/* ??_Distrstream@@QAEXXZ */
/* ??_Distrstream@@QEAAXXZ */
+/* ??_Difstream@@QAEXXZ */
+/* ??_Difstream@@QEAAXXZ */
DEFINE_THISCALL_WRAPPER(istream_vbase_dtor, 4)
void __thiscall istream_vbase_dtor(istream *this)
{
@@ -3178,6 +3191,7 @@ void __thiscall istream_vbase_dtor(istream *this)
/* ??_Eistream@@UAEPAXI(a)Z */
/* ??_Eistream_withassign@@UAEPAXI(a)Z */
/* ??_Eistrstream@@UAEPAXI(a)Z */
+/* ??_Eifstream@@UAEPAXI(a)Z */
DEFINE_THISCALL_WRAPPER(istream_vector_dtor, 8)
istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
{
@@ -3203,6 +3217,7 @@ istream* __thiscall istream_vector_dtor(ios *base, unsigned int flags)
/* ??_Gistream@@UAEPAXI(a)Z */
/* ??_Gistream_withassign@@UAEPAXI(a)Z */
/* ??_Gistrstream@@UAEPAXI(a)Z */
+/* ??_Gifstream@@UAEPAXI(a)Z */
DEFINE_THISCALL_WRAPPER(istream_scalar_dtor, 8)
istream* __thiscall istream_scalar_dtor(ios *base, unsigned int flags)
{
@@ -4089,6 +4104,175 @@ char* __thiscall istrstream_str(istream *this)
return strstreambuf_str(istrstream_rdbuf(this));
}
+/* ??0ifstream@@QAE(a)ABV0@@Z */
+/* ??0ifstream@@QEAA(a)AEBV0@@Z */
+DEFINE_THISCALL_WRAPPER(ifstream_copy_ctor, 12)
+istream* __thiscall ifstream_copy_ctor(istream *this, const istream *copy, BOOL virt_init)
+{
+ TRACE("(%p %p %d)\n", this, copy, virt_init);
+
+ istream_withassign_copy_ctor(this, copy, virt_init);
+ istream_get_ios(this)->vtable = &MSVCP_ifstream_vtable;
+
+ return this;
+}
+
+/* ??0ifstream@@QAE(a)HPADH@Z */
+/* ??0ifstream@@QEAA(a)HPEADH@Z */
+DEFINE_THISCALL_WRAPPER(ifstream_buffer_ctor, 20)
+istream* __thiscall ifstream_buffer_ctor(istream *this, filedesc fd, char *buffer, int length, BOOL virt_init)
+{
+ ios *base;
+ filebuf *fb = MSVCRT_operator_new(sizeof(filebuf));
+
+ TRACE("(%p %d %p %d %d)\n", this, fd, buffer, length, virt_init);
+
+ if (fb)
+ {
+ filebuf_fd_reserve_ctor(fb, fd, buffer, length);
+ istream_sb_ctor(this, &fb->base, virt_init);
+ }
+ else
+ istream_ctor(this, virt_init);
+
+ base = istream_get_ios(this);
+ base->vtable = &MSVCP_ifstream_vtable;
+ base->delbuf = 1;
+
+ return this;
+}
+
+/* ??0ifstream@@QAE(a)H@Z */
+/* ??0ifstream@@QEAA(a)H@Z */
+DEFINE_THISCALL_WRAPPER(ifstream_fd_ctor, 12)
+istream* __thiscall ifstream_fd_ctor(istream *this, filedesc fd, BOOL virt_init)
+{
+ ios *base;
+ filebuf *fb = MSVCRT_operator_new(sizeof(filebuf));
+
+ TRACE("(%p %d %d)\n", this, fd, virt_init);
+
+ if (fb)
+ {
+ filebuf_fd_ctor(fb, fd);
+ istream_sb_ctor(this, &fb->base, virt_init);
+ }
+ else
+ istream_ctor(this, virt_init);
+
+ base = istream_get_ios(this);
+ base->vtable = &MSVCP_ifstream_vtable;
+ base->delbuf = 1;
+
+ return this;
+}
+
+/* ??0ifstream@@QAE(a)PBDHH@Z */
+/* ??0ifstream@@QEAA(a)PEBDHH@Z */
+DEFINE_THISCALL_WRAPPER(ifstream_open_ctor, 20)
+istream* __thiscall ifstream_open_ctor(istream *this, const char *name, ios_open_mode mode, int protection, BOOL virt_init)
+{
+ ios *base;
+ filebuf *fb = MSVCRT_operator_new(sizeof(filebuf));
+
+ TRACE("(%p %s %d %d %d)\n", this, name, mode, protection, virt_init);
+
+ if (fb)
+ {
+ filebuf_ctor(fb);
+ istream_sb_ctor(this, &fb->base, virt_init);
+ filebuf_open(fb, name, mode, protection);
+ }
+ else
+ istream_ctor(this, virt_init);
+
+ base = istream_get_ios(this);
+ base->vtable = &MSVCP_ifstream_vtable;
+ base->delbuf = 1;
+
+ return this;
+}
+
+/* ??0ifstream@@QAE(a)XZ */
+/* ??0ifstream@@QEAA(a)XZ */
+DEFINE_THISCALL_WRAPPER(ifstream_ctor, 8)
+istream* __thiscall ifstream_ctor(istream *this, BOOL virt_init)
+{
+ return ifstream_fd_ctor(this, -1, virt_init);
+}
+
+/* ?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ */
+/* ?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ */
+DEFINE_THISCALL_WRAPPER(ifstream_rdbuf, 4)
+filebuf* __thiscall ifstream_rdbuf(const istream *this)
+{
+ TRACE("(%p)\n", this);
+ return (filebuf*) istream_get_ios(this)->sb;
+}
+
+/* ?fd(a)ifstream@@QBEHXZ */
+/* ?fd(a)ifstream@@QEBAHXZ */
+DEFINE_THISCALL_WRAPPER(ifstream_fd, 4)
+filedesc __thiscall ifstream_fd(istream *this)
+{
+ TRACE("(%p)\n", this);
+ return filebuf_fd(ifstream_rdbuf(this));
+}
+
+/* ?attach(a)ifstream@@QAEXH(a)Z */
+/* ?attach(a)ifstream@@QEAAXH(a)Z */
+DEFINE_THISCALL_WRAPPER(ifstream_attach, 8)
+void __thiscall ifstream_attach(istream *this, filedesc fd)
+{
+ TRACE("(%p %d)\n", this, fd);
+ filebuf_attach(ifstream_rdbuf(this), fd);
+}
+
+/* ?close(a)ifstream@@QAEXXZ */
+/* ?close(a)ifstream@@QEAAXXZ */
+DEFINE_THISCALL_WRAPPER(ifstream_close, 4)
+void __thiscall ifstream_close(istream *this)
+{
+ TRACE("(%p)\n", this);
+ filebuf_close(ifstream_rdbuf(this));
+}
+
+/* ?is_open(a)ifstream@@QBEHXZ */
+/* ?is_open(a)ifstream@@QEBAHXZ */
+DEFINE_THISCALL_WRAPPER(ifstream_is_open, 4)
+int __thiscall ifstream_is_open(const istream *this)
+{
+ TRACE("(%p)\n", this);
+ return filebuf_is_open(ifstream_rdbuf(this));
+}
+
+/* ?open(a)ifstream@@QAEXPBDHH(a)Z */
+/* ?open(a)ifstream@@QEAAXPEBDHH(a)Z */
+DEFINE_THISCALL_WRAPPER(ifstream_open, 16)
+void __thiscall ifstream_open(istream *this, const char *name, ios_open_mode mode, int protection)
+{
+ TRACE("(%p %s %d %d)\n", this, name, mode, protection);
+ filebuf_open(ifstream_rdbuf(this), name, mode, protection);
+}
+
+/* ?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z */
+/* ?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z */
+DEFINE_THISCALL_WRAPPER(ifstream_setbuf, 12)
+streambuf* __thiscall ifstream_setbuf(istream *this, char *buffer, int length)
+{
+ TRACE("(%p %p %d)\n", this, buffer, length);
+ return NULL;
+}
+
+/* ?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z */
+/* ?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z */
+DEFINE_THISCALL_WRAPPER(ifstream_setmode, 8)
+int __thiscall ifstream_setmode(istream *this, int mode)
+{
+ TRACE("(%p %d)\n", this, mode);
+ return filebuf_setmode(ifstream_rdbuf(this), mode);
+}
+
static inline ios* iostream_to_ios(const iostream *this)
{
return (ios*)((char*)this + iostream_vbtable_istream[1]);
@@ -4522,6 +4706,7 @@ static void init_io(void *base)
init_istream_rtti(base);
init_istream_withassign_rtti(base);
init_istrstream_rtti(base);
+ init_ifstream_rtti(base);
init_iostream_rtti(base);
init_strstream_rtti(base);
init_stdiostream_rtti(base);
diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec
index f2e875695ef..c2b4b9d30eb 100644
--- a/dlls/msvcirt/msvcirt.spec
+++ b/dlls/msvcirt/msvcirt.spec
@@ -26,16 +26,16 @@
@ stub -arch=win64 ??0fstream@@QEAA(a)PEBDHH@Z
@ stub -arch=win32 ??0fstream@@QAE(a)XZ # __thiscall fstream::fstream(void)
@ stub -arch=win64 ??0fstream@@QEAA(a)XZ
-@ stub -arch=win32 ??0ifstream@@QAE(a)ABV0@@Z # __thiscall ifstream::ifstream(class ifstream const &)
-@ stub -arch=win64 ??0ifstream@@QEAA(a)AEBV0@@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)H@Z # __thiscall ifstream::ifstream(int)
-@ stub -arch=win64 ??0ifstream@@QEAA(a)H@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)HPADH@Z # __thiscall ifstream::ifstream(int,char *,int)
-@ stub -arch=win64 ??0ifstream@@QEAA(a)HPEADH@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)PBDHH@Z # __thiscall ifstream::ifstream(char const *,int,int)
-@ stub -arch=win64 ??0ifstream@@QEAA(a)PEBDHH@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)XZ # __thiscall ifstream::ifstream(void)
-@ stub -arch=win64 ??0ifstream@@QEAA(a)XZ
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)ABV0@@Z(ptr ptr long) ifstream_copy_ctor
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)AEBV0@@Z(ptr ptr long) ifstream_copy_ctor
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)H@Z(ptr long long) ifstream_fd_ctor
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)H@Z(ptr long long) ifstream_fd_ctor
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)HPADH@Z(ptr long ptr long long) ifstream_buffer_ctor
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)HPEADH@Z(ptr long ptr long long) ifstream_buffer_ctor
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)PBDHH@Z(ptr str long long long) ifstream_open_ctor
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)PEBDHH@Z(ptr str long long long) ifstream_open_ctor
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)XZ(ptr long) ifstream_ctor
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)XZ(ptr long) ifstream_ctor
@ thiscall -arch=win32 ??0ios@@IAE(a)ABV0@@Z(ptr ptr) ios_copy_ctor
@ cdecl -arch=win64 ??0ios@@IEAA(a)AEBV0@@Z(ptr ptr) ios_copy_ctor
@ thiscall -arch=win32 ??0ios@@IAE(a)XZ(ptr) ios_ctor
@@ -138,8 +138,8 @@
@ cdecl -arch=win64 ??1filebuf@@UEAA(a)XZ(ptr) filebuf_dtor
@ stub -arch=win32 ??1fstream@@UAE(a)XZ # virtual __thiscall fstream::~fstream(void)
@ stub -arch=win64 ??1fstream@@UEAA(a)XZ
-@ stub -arch=win32 ??1ifstream@@UAE(a)XZ # virtual __thiscall ifstream::~ifstream(void)
-@ stub -arch=win64 ??1ifstream@@UEAA(a)XZ
+@ thiscall -arch=win32 ??1ifstream@@UAE(a)XZ(ptr) istream_dtor
+@ cdecl -arch=win64 ??1ifstream@@UEAA(a)XZ(ptr) istream_dtor
@ thiscall -arch=win32 ??1ios@@UAE(a)XZ(ptr) ios_dtor
@ cdecl -arch=win64 ??1ios@@UEAA(a)XZ(ptr) ios_dtor
@ thiscall -arch=win32 ??1iostream@@UAE(a)XZ(ptr) iostream_dtor
@@ -178,8 +178,8 @@
@ cdecl -arch=win64 ??4filebuf@@QEAAAEAV0(a)AEBV0@@Z(ptr ptr) filebuf_assign
@ stub -arch=win32 ??4fstream@@QAEAAV0(a)AAV0@@Z # class fstream & __thiscall fstream::operator=(class fstream &)
@ stub -arch=win64 ??4fstream@@QEAAAEAV0(a)AEAV0@@Z
-@ stub -arch=win32 ??4ifstream@@QAEAAV0(a)ABV0@@Z # class ifstream & __thiscall ifstream::operator=(class ifstream const &)
-@ stub -arch=win64 ??4ifstream@@QEAAAEAV0(a)AEBV0@@Z
+@ thiscall -arch=win32 ??4ifstream@@QAEAAV0(a)ABV0@@Z(ptr ptr) istream_assign
+@ cdecl -arch=win64 ??4ifstream@@QEAAAEAV0(a)AEBV0@@Z(ptr ptr) istream_assign
@ thiscall -arch=win32 ??4ios@@IAEAAV0(a)ABV0@@Z(ptr ptr) ios_assign
@ cdecl -arch=win64 ??4ios@@IEAAAEAV0(a)AEBV0@@Z(ptr ptr) ios_assign
@ thiscall -arch=win32 ??4iostream@@IAEAAV0(a)AAV0@@Z(ptr ptr) iostream_assign
@@ -305,7 +305,7 @@
@ extern ??_7exception@@6B@ MSVCP_exception_vtable
@ extern ??_7filebuf@@6B@ MSVCP_filebuf_vtable
# @ extern ??_7fstream@@6B@ # const fstream::`vftable'
-# @ extern ??_7ifstream@@6B@ # const ifstream::`vftable'
+@ extern ??_7ifstream@@6B@ MSVCP_ifstream_vtable
@ extern ??_7ios@@6B@ MSVCP_ios_vtable
@ extern ??_7iostream@@6B@ MSVCP_iostream_vtable
@ extern ??_7istream@@6B@ MSVCP_istream_vtable
@@ -323,7 +323,7 @@
@ extern ??_7strstreambuf@@6B@ MSVCP_strstreambuf_vtable
# @ extern ??_8fstream@@7Bistream@@@ # const fstream::`vbtable'{for `istream'}
# @ extern ??_8fstream@@7Bostream@@@ # const fstream::`vbtable'{for `ostream'}
-# @ extern ??_8ifstream@@7B@ # const ifstream::`vbtable'
+@ extern ??_8ifstream@@7B@ istream_vbtable
@ extern ??_8iostream@@7Bistream@@@ iostream_vbtable_istream
@ extern ??_8iostream@@7Bostream@@@ iostream_vbtable_ostream
@ extern ??_8istream@@7B@ istream_vbtable
@@ -339,8 +339,8 @@
@ extern ??_8strstream@@7Bostream@@@ iostream_vbtable_ostream
@ stub -arch=win32 ??_Dfstream@@QAEXXZ # void __thiscall fstream::`vbase destructor'(void)
@ stub -arch=win64 ??_Dfstream@@QEAAXXZ
-@ stub -arch=win32 ??_Difstream@@QAEXXZ # void __thiscall ifstream::`vbase destructor'(void)
-@ stub -arch=win64 ??_Difstream@@QEAAXXZ
+@ thiscall -arch=win32 ??_Difstream@@QAEXXZ(ptr) istream_vbase_dtor
+@ cdecl -arch=win64 ??_Difstream@@QEAAXXZ(ptr) istream_vbase_dtor
@ thiscall -arch=win32 ??_Diostream@@QAEXXZ(ptr) iostream_vbase_dtor
@ cdecl -arch=win64 ??_Diostream@@QEAAXXZ(ptr) iostream_vbase_dtor
@ thiscall -arch=win32 ??_Distream@@QAEXXZ(ptr) istream_vbase_dtor
@@ -364,7 +364,7 @@
@ thiscall -arch=win32 ??_Eexception@@UAEPAXI(a)Z(ptr long) MSVCP_exception_vector_dtor
@ thiscall -arch=win32 ??_Efilebuf@@UAEPAXI(a)Z(ptr long) filebuf_vector_dtor
@ stub -arch=win32 ??_Efstream@@UAEPAXI(a)Z # virtual void * __thiscall fstream::`vector deleting destructor'(unsigned int)
-@ stub -arch=win32 ??_Eifstream@@UAEPAXI(a)Z # virtual void * __thiscall ifstream::`vector deleting destructor'(unsigned int)
+@ thiscall -arch=win32 ??_Eifstream@@UAEPAXI(a)Z(ptr long) istream_vector_dtor
@ thiscall -arch=win32 ??_Eios@@UAEPAXI(a)Z(ptr long) ios_vector_dtor
@ thiscall -arch=win32 ??_Eiostream@@UAEPAXI(a)Z(ptr long) iostream_vector_dtor
@ thiscall -arch=win32 ??_Eistream@@UAEPAXI(a)Z(ptr long) istream_vector_dtor
@@ -383,7 +383,7 @@
@ thiscall -arch=win32 ??_Gexception@@UAEPAXI(a)Z(ptr long) MSVCP_exception_scalar_dtor
@ thiscall -arch=win32 ??_Gfilebuf@@UAEPAXI(a)Z(ptr long) filebuf_scalar_dtor
@ stub -arch=win32 ??_Gfstream@@UAEPAXI(a)Z # virtual void * __thiscall fstream::`scalar deleting destructor'(unsigned int)
-@ stub -arch=win32 ??_Gifstream@@UAEPAXI(a)Z # virtual void * __thiscall ifstream::`scalar deleting destructor'(unsigned int)
+@ thiscall -arch=win32 ??_Gifstream@@UAEPAXI(a)Z(ptr long) istream_scalar_dtor
@ thiscall -arch=win32 ??_Gios@@UAEPAXI(a)Z(ptr long) ios_scalar_dtor
@ thiscall -arch=win32 ??_Giostream@@UAEPAXI(a)Z(ptr long) iostream_scalar_dtor
@ thiscall -arch=win32 ??_Gistream@@UAEPAXI(a)Z(ptr long) istream_scalar_dtor
@@ -406,8 +406,8 @@
@ cdecl -arch=win64 ?attach(a)filebuf@@QEAAPEAV1(a)H@Z(ptr long) filebuf_attach
@ stub -arch=win32 ?attach(a)fstream@@QAEXH(a)Z # void __thiscall fstream::attach(int)
@ stub -arch=win64 ?attach(a)fstream@@QEAAXH(a)Z
-@ stub -arch=win32 ?attach(a)ifstream@@QAEXH(a)Z # void __thiscall ifstream::attach(int)
-@ stub -arch=win64 ?attach(a)ifstream@@QEAAXH(a)Z
+@ thiscall -arch=win32 ?attach(a)ifstream@@QAEXH(a)Z(ptr long) ifstream_attach
+@ cdecl -arch=win64 ?attach(a)ifstream@@QEAAXH(a)Z(ptr long) ifstream_attach
@ stub -arch=win32 ?attach(a)ofstream@@QAEXH(a)Z # void __thiscall ofstream::attach(int)
@ stub -arch=win64 ?attach(a)ofstream@@QEAAXH(a)Z
@ thiscall -arch=win32 ?bad(a)ios@@QBEHXZ(ptr) ios_bad
@@ -428,8 +428,8 @@
@ cdecl -arch=win64 ?close(a)filebuf@@QEAAPEAV1(a)XZ(ptr) filebuf_close
@ stub -arch=win32 ?close(a)fstream@@QAEXXZ # void __thiscall fstream::close(void)
@ stub -arch=win64 ?close(a)fstream@@QEAAXXZ
-@ stub -arch=win32 ?close(a)ifstream@@QAEXXZ # void __thiscall ifstream::close(void)
-@ stub -arch=win64 ?close(a)ifstream@@QEAAXXZ
+@ thiscall -arch=win32 ?close(a)ifstream@@QAEXXZ(ptr) ifstream_close
+@ cdecl -arch=win64 ?close(a)ifstream@@QEAAXXZ(ptr) ifstream_close
@ stub -arch=win32 ?close(a)ofstream@@QAEXXZ # void __thiscall ofstream::close(void)
@ stub -arch=win64 ?close(a)ofstream@@QEAAXXZ
@ cdecl -arch=win32 ?clrlock(a)ios@@QAAXXZ(ptr) ios_clrlock
@@ -472,8 +472,8 @@
@ cdecl -arch=win64 ?fd(a)filebuf@@QEBAHXZ(ptr) filebuf_fd
@ stub -arch=win32 ?fd(a)fstream@@QBEHXZ # int __thiscall fstream::fd(void)const
@ stub -arch=win64 ?fd(a)fstream@@QEBAHXZ
-@ stub -arch=win32 ?fd(a)ifstream@@QBEHXZ # int __thiscall ifstream::fd(void)const
-@ stub -arch=win64 ?fd(a)ifstream@@QEBAHXZ
+@ thiscall -arch=win32 ?fd(a)ifstream@@QBEHXZ(ptr) ifstream_fd
+@ cdecl -arch=win64 ?fd(a)ifstream@@QEBAHXZ(ptr) ifstream_fd
@ stub -arch=win32 ?fd(a)ofstream@@QBEHXZ # int __thiscall ofstream::fd(void)const
@ stub -arch=win64 ?fd(a)ofstream@@QEBAHXZ
@ thiscall -arch=win32 ?fill(a)ios@@QAEDD(a)Z(ptr long) ios_fill_set
@@ -541,8 +541,8 @@
@ cdecl -arch=win64 ?is_open(a)filebuf@@QEBAHXZ(ptr) filebuf_is_open
@ stub -arch=win32 ?is_open(a)fstream@@QBEHXZ # int __thiscall fstream::is_open(void)const
@ stub -arch=win64 ?is_open(a)fstream@@QEBAHXZ
-@ stub -arch=win32 ?is_open(a)ifstream@@QBEHXZ # int __thiscall ifstream::is_open(void)const
-@ stub -arch=win64 ?is_open(a)ifstream@@QEBAHXZ
+@ thiscall -arch=win32 ?is_open(a)ifstream@@QBEHXZ(ptr) ifstream_is_open
+@ cdecl -arch=win64 ?is_open(a)ifstream@@QEBAHXZ(ptr) ifstream_is_open
@ stub -arch=win32 ?is_open(a)ofstream@@QBEHXZ # int __thiscall ofstream::is_open(void)const
@ stub -arch=win64 ?is_open(a)ofstream@@QEBAHXZ
@ thiscall -arch=win32 ?isfx(a)istream@@QAEXXZ(ptr) istream_isfx
@@ -566,8 +566,8 @@
@ cdecl -arch=win64 ?open(a)filebuf@@QEAAPEAV1(a)PEBDHH@Z(ptr str long long) filebuf_open
@ stub -arch=win32 ?open(a)fstream@@QAEXPBDHH(a)Z # void __thiscall fstream::open(char const *,int,int)
@ stub -arch=win64 ?open(a)fstream@@QEAAXPEBDHH(a)Z
-@ stub -arch=win32 ?open(a)ifstream@@QAEXPBDHH(a)Z # void __thiscall ifstream::open(char const *,int,int)
-@ stub -arch=win64 ?open(a)ifstream@@QEAAXPEBDHH(a)Z
+@ thiscall -arch=win32 ?open(a)ifstream@@QAEXPBDHH(a)Z(ptr str long long) ifstream_open
+@ cdecl -arch=win64 ?open(a)ifstream@@QEAAXPEBDHH(a)Z(ptr str long long) ifstream_open
@ stub -arch=win32 ?open(a)ofstream@@QAEXPBDHH(a)Z # void __thiscall ofstream::open(char const *,int,int)
@ stub -arch=win64 ?open(a)ofstream@@QEAAXPEBDHH(a)Z
@ extern ?openprot(a)filebuf@@2HB filebuf_openprot
@@ -615,8 +615,8 @@
@ cdecl -arch=win64 ?pword(a)ios@@QEBAAEAPEAXH(a)Z(ptr long) ios_pword
@ stub -arch=win32 ?rdbuf(a)fstream@@QBEPAVfilebuf@@XZ # class filebuf * __thiscall fstream::rdbuf(void)const
@ stub -arch=win64 ?rdbuf(a)fstream@@QEBAPEAVfilebuf@@XZ
-@ stub -arch=win32 ?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ # class filebuf * __thiscall ifstream::rdbuf(void)const
-@ stub -arch=win64 ?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ
+@ thiscall -arch=win32 ?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ(ptr) ifstream_rdbuf
+@ cdecl -arch=win64 ?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ(ptr) ifstream_rdbuf
@ thiscall -arch=win32 ?rdbuf(a)ios@@QBEPAVstreambuf@@XZ(ptr) ios_rdbuf
@ cdecl -arch=win64 ?rdbuf(a)ios@@QEBAPEAVstreambuf@@XZ(ptr) ios_rdbuf
@ thiscall -arch=win32 ?rdbuf(a)istrstream@@QBEPAVstrstreambuf@@XZ(ptr) istrstream_rdbuf
@@ -663,8 +663,8 @@
@ cdecl -arch=win64 ?setbuf(a)filebuf@@UEAAPEAVstreambuf@@PEADH(a)Z(ptr ptr long) filebuf_setbuf
@ stub -arch=win32 ?setbuf(a)fstream@@QAEPAVstreambuf@@PADH(a)Z # class streambuf * __thiscall fstream::setbuf(char *,int)
@ stub -arch=win64 ?setbuf(a)fstream@@QEAAPEAVstreambuf@@PEADH(a)Z
-@ stub -arch=win32 ?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z # class streambuf * __thiscall ifstream::setbuf(char *,int)
-@ stub -arch=win64 ?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z
+@ thiscall -arch=win32 ?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z(ptr ptr long) ifstream_setbuf
+@ cdecl -arch=win64 ?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z(ptr ptr long) ifstream_setbuf
@ stub -arch=win32 ?setbuf(a)ofstream@@QAEPAVstreambuf@@PADH(a)Z # class streambuf * __thiscall ofstream::setbuf(char *,int)
@ stub -arch=win64 ?setbuf(a)ofstream@@QEAAPEAVstreambuf@@PEADH(a)Z
@ thiscall -arch=win32 ?setbuf(a)streambuf@@UAEPAV1(a)PADH@Z(ptr ptr long) streambuf_setbuf
@@ -685,8 +685,8 @@
@ cdecl -arch=win64 ?setmode(a)filebuf@@QEAAHH(a)Z(ptr long) filebuf_setmode
@ stub -arch=win32 ?setmode(a)fstream@@QAEHH(a)Z # int __thiscall fstream::setmode(int)
@ stub -arch=win64 ?setmode(a)fstream@@QEAAHH(a)Z
-@ stub -arch=win32 ?setmode(a)ifstream@@QAEHH(a)Z # int __thiscall ifstream::setmode(int)
-@ stub -arch=win64 ?setmode(a)ifstream@@QEAAHH(a)Z
+@ thiscall -arch=win32 ?setmode(a)ifstream@@QAEHH(a)Z(ptr long) ifstream_setmode
+@ cdecl -arch=win64 ?setmode(a)ifstream@@QEAAHH(a)Z(ptr long) ifstream_setmode
@ stub -arch=win32 ?setmode(a)ofstream@@QAEHH(a)Z # int __thiscall ofstream::setmode(int)
@ stub -arch=win64 ?setmode(a)ofstream@@QEAAHH(a)Z
@ thiscall -arch=win32 ?setp(a)streambuf@@IAEXPAD0(a)Z(ptr ptr ptr) streambuf_setp
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 6440bc0dab7..06688a91c06 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
+#include <sys/stat.h>
#include "wine/test.h"
typedef void (*vtable_ptr)(void);
@@ -403,6 +404,23 @@ static void (*__thiscall p_iostream_vbase_dtor)(iostream*);
static iostream* (*__thiscall p_iostream_assign_sb)(iostream*, streambuf*);
static iostream* (*__thiscall p_iostream_assign)(iostream*, const iostream*);
+/* ifstream */
+static istream* (*__thiscall p_ifstream_copy_ctor)(istream*, const istream*, BOOL);
+static istream* (*__thiscall p_ifstream_buffer_ctor)(istream*, filedesc, char*, int, BOOL);
+static istream* (*__thiscall p_ifstream_fd_ctor)(istream*, filedesc fd, BOOL virt_init);
+static istream* (*__thiscall p_ifstream_open_ctor)(istream*, const char *name, ios_open_mode, int, BOOL);
+static istream* (*__thiscall p_ifstream_ctor)(istream*, BOOL);
+static void (*__thiscall p_ifstream_dtor)(ios*);
+static void (*__thiscall p_ifstream_vbase_dtor)(istream*);
+static void (*__thiscall p_ifstream_attach)(istream*, filedesc);
+static void (*__thiscall p_ifstream_close)(istream*);
+static filedesc (*__thiscall p_ifstream_fd)(istream*);
+static int (*__thiscall p_ifstream_is_open)(const istream*);
+static void (*__thiscall p_ifstream_open)(istream*, const char*, ios_open_mode, int);
+static filebuf* (*__thiscall p_ifstream_rdbuf)(const istream*);
+static streambuf* (*__thiscall p_ifstream_setbuf)(istream*, char*, int);
+static int (*__thiscall p_ifstream_setmode)(istream*, int);
+
/* strstream */
static iostream* (*__thiscall p_strstream_copy_ctor)(iostream*, const iostream*, BOOL);
static iostream* (*__thiscall p_strstream_buffer_ctor)(iostream*, char*, int, int, BOOL);
@@ -703,6 +721,22 @@ static BOOL init(void)
SET(p_iostream_assign_sb, "??4iostream@@IEAAAEAV0(a)PEAVstreambuf@@@Z");
SET(p_iostream_assign, "??4iostream@@IEAAAEAV0(a)AEAV0@@Z");
+ SET(p_ifstream_copy_ctor, "??0ifstream@@QEAA(a)AEBV0@@Z");
+ SET(p_ifstream_buffer_ctor, "??0ifstream@@QEAA(a)HPEADH@Z");
+ SET(p_ifstream_fd_ctor, "??0ifstream@@QEAA(a)H@Z");
+ SET(p_ifstream_open_ctor, "??0ifstream@@QEAA(a)PEBDHH@Z");
+ SET(p_ifstream_ctor, "??0ifstream@@QEAA(a)XZ");
+ SET(p_ifstream_dtor, "??1ifstream@@UEAA(a)XZ");
+ SET(p_ifstream_vbase_dtor, "??_Difstream@@QEAAXXZ");
+ SET(p_ifstream_attach, "?attach(a)ifstream@@QEAAXH(a)Z");
+ SET(p_ifstream_close, "?close(a)ifstream@@QEAAXXZ");
+ SET(p_ifstream_fd, "?fd(a)ifstream@@QEBAHXZ");
+ SET(p_ifstream_is_open, "?is_open(a)ifstream@@QEBAHXZ");
+ SET(p_ifstream_open, "?open(a)ifstream@@QEAAXPEBDHH(a)Z");
+ SET(p_ifstream_rdbuf, "?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ");
+ SET(p_ifstream_setbuf, "?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z");
+ SET(p_ifstream_setmode, "?setmode(a)ifstream@@QEAAHH(a)Z");
+
SET(p_strstream_copy_ctor, "??0strstream@@QEAA(a)AEBV0@@Z");
SET(p_strstream_buffer_ctor, "??0strstream@@QEAA(a)PEADHH@Z");
SET(p_strstream_ctor, "??0strstream@@QEAA(a)XZ");
@@ -917,6 +951,22 @@ static BOOL init(void)
SET(p_iostream_assign_sb, "??4iostream@@IAEAAV0(a)PAVstreambuf@@@Z");
SET(p_iostream_assign, "??4iostream@@IAEAAV0(a)AAV0@@Z");
+ SET(p_ifstream_copy_ctor, "??0ifstream@@QAE(a)ABV0@@Z");
+ SET(p_ifstream_fd_ctor, "??0ifstream@@QAE(a)H@Z");
+ SET(p_ifstream_buffer_ctor, "??0ifstream@@QAE(a)HPADH@Z");
+ SET(p_ifstream_open_ctor, "??0ifstream@@QAE(a)PBDHH@Z");
+ SET(p_ifstream_ctor, "??0ifstream@@QAE(a)XZ");
+ SET(p_istrstream_dtor, "??1ifstream@@UAE(a)XZ");
+ SET(p_istrstream_vbase_dtor, "??_Difstream@@QAEXXZ");
+ SET(p_ifstream_attach, "?attach(a)ifstream@@QAEXH(a)Z");
+ SET(p_ifstream_close, "?close(a)ifstream@@QAEXXZ");
+ SET(p_ifstream_fd, "?fd(a)ifstream@@QBEHXZ");
+ SET(p_ifstream_is_open, "?is_open(a)ifstream@@QBEHXZ");
+ SET(p_ifstream_open, "?open(a)ifstream@@QAEXPBDHH(a)Z");
+ SET(p_ifstream_rdbuf, "?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ");
+ SET(p_ifstream_setbuf, "?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z");
+ SET(p_ifstream_setmode, "?setmode(a)ifstream@@QAEHH(a)Z");
+
SET(p_strstream_copy_ctor, "??0strstream@@QAE(a)ABV0@@Z");
SET(p_strstream_buffer_ctor, "??0strstream@@QAE(a)PADHH@Z");
SET(p_strstream_ctor, "??0strstream@@QAE(a)XZ");
@@ -6720,6 +6770,198 @@ static void test_iostream(void)
ok(ios2.base_ios.do_lock == 0xcdcdcdcd, "expected %d got %d\n", 0xcdcdcdcd, ios2.base_ios.do_lock);
}
+static void test_ifstream(void)
+{
+ const char *filename = "ifstream_test";
+ istream ifs, ifs_copy, *pifs;
+ streambuf *psb;
+ filebuf *pfb;
+ char buffer[64];
+ char st[8];
+ int fd, ret, i;
+
+ memset(&ifs, 0xab, sizeof(istream));
+
+ /* constructors/destructors */
+ pifs = call_func2(p_ifstream_ctor, &ifs, TRUE);
+ pfb = (filebuf*) ifs.base_ios.sb;
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ ok(ifs.extract_delim == 0, "expected 0 got %d\n", ifs.extract_delim);
+ ok(ifs.count == 0, "expected 0 got %d\n", ifs.count);
+ ok(ifs.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ifs.base_ios.sb);
+ ok(ifs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ifs.base_ios.state);
+ ok(ifs.base_ios.delbuf == 1, "expected 1 got %d\n", ifs.base_ios.delbuf);
+ ok(ifs.base_ios.tie == NULL, "expected %p got %p\n", NULL, ifs.base_ios.tie);
+ ok(ifs.base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, ifs.base_ios.flags);
+ ok(ifs.base_ios.precision == 6, "expected 6 got %d\n", ifs.base_ios.precision);
+ ok(ifs.base_ios.fill == ' ', "expected 32 got %d\n", ifs.base_ios.fill);
+ ok(ifs.base_ios.width == 0, "expected 0 got %d\n", ifs.base_ios.width);
+ ok(ifs.base_ios.do_lock == -1, "expected -1 got %d\n", ifs.base_ios.do_lock);
+ ok(pfb->fd == -1, "wrong fd, expected -1 got %d\n", pfb->fd);
+ ok(pfb->close == 0, "wrong value, expected 0 got %d\n", pfb->close);
+ ok(pfb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pfb->base.allocated);
+ ok(pfb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pfb->base.unbuffered);
+ ok(pfb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pfb->base.base);
+ ok(pfb->base.ebuf == NULL, "wrong ebuf, expected %p got %p\n", NULL, pfb->base.ebuf);
+ ok(pfb->fd == -1, "wrong fd, expected 0 got %d\n", pfb->fd);
+ call_func1(p_ifstream_vbase_dtor, &ifs);
+
+ pifs = call_func3(p_ifstream_fd_ctor, &ifs, 42, TRUE);
+ pfb = (filebuf*) ifs.base_ios.sb;
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ ok(ifs.base_ios.delbuf == 1, "expected 1 got %d\n", ifs.base_ios.delbuf);
+ ok(pfb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pfb->base.allocated);
+ ok(pfb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pfb->base.unbuffered);
+ ok(pfb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pfb->base.base);
+ ok(pfb->base.ebuf == NULL, "wrong ebuf, expected %p got %p\n", NULL, pfb->base.ebuf);
+ ok(pfb->fd == 42, "wrong fd, expected 42 got %d\n", pfb->fd);
+ ok(pfb->close == 0, "wrong value, expected 0 got %d\n", pfb->close);
+
+ pifs = call_func3(p_ifstream_copy_ctor, &ifs_copy, &ifs, TRUE);
+ pfb = (filebuf*) ifs_copy.base_ios.sb;
+ ok(pifs == &ifs_copy, "wrong return, expected %p got %p\n", &ifs_copy, pifs);
+ ok(ifs_copy.base_ios.sb == ifs.base_ios.sb, "expected shared streambuf\n");
+
+ call_func1(p_ifstream_vbase_dtor, &ifs_copy);
+ call_func1(p_ifstream_dtor, &ifs.base_ios);
+
+ pifs = call_func5(p_ifstream_buffer_ctor, &ifs, 53, buffer, ARRAY_SIZE(buffer), TRUE);
+ pfb = (filebuf*) ifs.base_ios.sb;
+ ok(ifs.base_ios.delbuf == 1, "expected 1 got %d\n", ifs.base_ios.delbuf);
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ ok(pfb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pfb->base.allocated);
+ ok(pfb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pfb->base.unbuffered);
+ ok(pfb->base.base == buffer, "wrong buffer, expected %p got %p\n", buffer, pfb->base.base);
+ ok(pfb->base.ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), pfb->base.ebuf);
+ ok(pfb->fd == 53, "wrong fd, expected 53 got %d\n", pfb->fd);
+ ok(pfb->close == 0, "wrong value, expected 0 got %d\n", pfb->close);
+ call_func1(p_ifstream_dtor, &ifs.base_ios);
+
+ pifs = call_func5(p_ifstream_buffer_ctor, &ifs, 64, NULL, 0, TRUE);
+ pfb = (filebuf*) ifs.base_ios.sb;
+ ok(ifs.base_ios.delbuf == 1, "expected 1 got %d\n", ifs.base_ios.delbuf);
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ ok(pfb->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pfb->base.allocated);
+ ok(pfb->base.unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", pfb->base.unbuffered);
+ ok(pfb->base.base == NULL, "wrong buffer, expected %p got %p\n", NULL, pfb->base.base);
+ ok(pfb->base.ebuf == NULL, "wrong ebuf, expected %p got %p\n", NULL, pfb->base.ebuf);
+ ok(pfb->fd == 64, "wrong fd, expected 64 got %d\n", pfb->fd);
+ ok(pfb->close == 0, "wrong value, expected 0 got %d\n", pfb->close);
+ call_func1(p_ifstream_vbase_dtor, &ifs);
+
+ pifs = call_func5(p_ifstream_open_ctor, &ifs, filename, OPENMODE_in, filebuf_openprot, TRUE);
+ pfb = (filebuf*) ifs.base_ios.sb;
+ ok(ifs.base_ios.delbuf == 1, "expected 1 got %d\n", ifs.base_ios.delbuf);
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ ok(pfb->base.allocated == 1, "wrong allocate value, expected 1 got %d\n", pfb->base.allocated);
+ ok(pfb->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pfb->base.unbuffered);
+ ok(pfb->base.base != NULL, "wrong buffer, expected not %p got %p\n", NULL, pfb->base.base);
+ ok(pfb->base.ebuf != NULL, "wrong ebuf, expected not %p got %p\n", NULL, pfb->base.ebuf);
+ ok(pfb->fd != -1, "wrong fd, expected not -1 got %d\n", pfb->fd);
+ fd = pfb->fd;
+ ok(pfb->close == 1, "wrong value, expected 1 got %d\n", pfb->close);
+ call_func1(p_ifstream_vbase_dtor, &ifs);
+ ok(_close(fd) == -1, "expected ifstream to close opened file\n");
+
+ /* setbuf - seems to be a nop and always return NULL */
+ pifs = call_func5(p_ifstream_buffer_ctor, &ifs, 64, NULL, 0, TRUE);
+ ok(ifs.base_ios.sb->base == NULL, "wrong base value, expected NULL got %p\n", ifs.base_ios.sb->base);
+ ok(ifs.base_ios.sb->ebuf == NULL, "wrong ebuf value, expected NULL got %p\n", ifs.base_ios.sb->ebuf);
+ ok(ifs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", pfb->base.unbuffered);
+ ok(ifs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ifs.base_ios.sb->allocated);
+
+ psb = call_func3(p_ifstream_setbuf, &ifs, buffer, ARRAY_SIZE(buffer));
+ ok(psb == NULL, "wrong return, expected NULL got %p\n", pfb);
+ ok(ifs.base_ios.sb->base == NULL, "wrong base value, expected NULL got %p\n", ifs.base_ios.sb->base);
+ ok(ifs.base_ios.sb->ebuf == NULL, "wrong ebuf value, expected NULL got %p\n", ifs.base_ios.sb->ebuf);
+ ok(ifs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ifs.base_ios.sb->unbuffered);
+ ok(ifs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ifs.base_ios.sb->allocated);
+
+ psb = call_func3(p_ifstream_setbuf, &ifs, NULL, 0);
+ ok(psb == NULL, "wrong return, expected NULL got %p\n", pfb);
+ ok(ifs.base_ios.sb->base == NULL, "wrong base value, expected NULL got %p\n", ifs.base_ios.sb->base);
+ ok(ifs.base_ios.sb->ebuf == NULL, "wrong ebuf value, expected NULL got %p\n", ifs.base_ios.sb->ebuf);
+ ok(ifs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ifs.base_ios.sb->unbuffered);
+ ok(ifs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got \n", ifs.base_ios.sb->allocated);
+ call_func1(p_ifstream_vbase_dtor, &ifs);
+
+ pifs = call_func5(p_ifstream_open_ctor, &ifs, filename, OPENMODE_in, filebuf_openprot, TRUE);
+ psb = call_func3(p_ifstream_setbuf, &ifs, NULL, 0);
+ ok(psb == NULL, "wrong return, expected NULL got %p\n", pfb);
+ ok(ifs.base_ios.sb->base != NULL, "wrong base value, expected NULL got %p\n", ifs.base_ios.sb->base);
+ ok(ifs.base_ios.sb->ebuf != NULL, "wrong ebuf value, expected NULL got %p\n", ifs.base_ios.sb->ebuf);
+ ok(ifs.base_ios.sb->unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", ifs.base_ios.sb->unbuffered);
+ ok(ifs.base_ios.sb->allocated == 1, "wrong allocated value, expected 1 got %d\n", ifs.base_ios.sb->allocated);
+
+ psb = call_func3(p_ifstream_setbuf, &ifs, buffer, ARRAY_SIZE(buffer));
+ ok(psb == NULL, "wrong return, expected NULL got %p\n", pfb);
+ ok(ifs.base_ios.sb->base != NULL, "wrong base value, expected NULL got %p\n", ifs.base_ios.sb->base);
+ ok(ifs.base_ios.sb->base != buffer, "wrong base value, expected not %p got %p\n", buffer, ifs.base_ios.sb->base);
+ ok(ifs.base_ios.sb->unbuffered == 0, "wrong unbuffered value, expected 1 got %d\n", ifs.base_ios.sb->unbuffered);
+ ok(ifs.base_ios.sb->allocated == 1, "wrong allocated value, expected 0 got %d\n", ifs.base_ios.sb->allocated);
+ call_func1(p_ifstream_vbase_dtor, &ifs);
+
+ /* attach */
+ pifs = call_func2(p_ifstream_ctor, &ifs, TRUE);
+ pfb = (filebuf*) ifs.base_ios.sb;
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ call_func2(p_ifstream_attach, &ifs, 42);
+ fd = call_func1(p_ifstream_fd, &ifs);
+ ok(fd == 42, "wrong fd, expected 42 got %d\n", fd);
+ ok(pfb->close == 0, "wrong close value, expected 0 got %d\n", pfb->close);
+ call_func2(p_ifstream_attach, &ifs, 53);
+ ok(fd == 42, "wrong fd, expected 42 got %d\n", fd);
+ call_func1(p_ifstream_vbase_dtor, &ifs);
+
+ /* fd */
+ pifs = call_func5(p_ifstream_open_ctor, &ifs, filename, OPENMODE_in, filebuf_openprot, TRUE);
+ pfb = (filebuf*) ifs.base_ios.sb;
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ fd = call_func1(p_ifstream_fd, &ifs);
+ ok(fd == pfb->fd, "wrong fd, expected %d but got %d\n", pfb->fd, fd);
+
+ /* rdbuf */
+ pfb = (filebuf*) call_func1(p_ifstream_rdbuf, &ifs);
+ ok((streambuf*) pfb == ifs.base_ios.sb, "wrong return, expected %p got %p\n", ifs.base_ios.sb, pfb);
+
+ /* setmode */
+ ret = call_func2(p_ifstream_setmode, &ifs, filebuf_binary);
+ ok(ret == filebuf_text, "wrong return, expected %d got %d\n", filebuf_text, ret);
+ ret = call_func2(p_ifstream_setmode, &ifs, filebuf_binary);
+ ok(ret == filebuf_binary, "wrong return, expected %d got %d\n", filebuf_binary, ret);
+ ret = call_func2(p_ifstream_setmode, &ifs, filebuf_text);
+ ok(ret == filebuf_binary, "wrong return, expected %d got %d\n", filebuf_binary, ret);
+ ret = call_func2(p_ifstream_setmode, &ifs, 0x9000);
+ ok(ret == -1, "wrong return, expected -1 got %d\n", ret);
+
+ /* close && is_open */
+ ok(call_func1(p_ifstream_is_open, &ifs) == 1, "expected ifstream to be open\n");
+ call_func1(p_ifstream_close, &ifs);
+ ok(call_func1(p_ifstream_is_open, &ifs) == 0, "expected ifstream to not be open\n");
+ ok(_close(fd) == -1, "expected close to close the opened file\n");
+
+ /* integration with parent istream - reading */
+ fd = _open(filename, _O_TRUNC|_O_CREAT|_O_RDWR, _S_IWRITE);
+ ok(fd != -1, "_open failed\n");
+ ok(_write(fd, "test 12", 7) == 7, "_write failed\n");
+ ok(_close(fd) == 0, "_close failed\n");
+
+ call_func4(p_ifstream_open, &ifs, filename, OPENMODE_in, filebuf_openprot);
+ memset(st, 'A', sizeof(st));
+ st[7] = 0;
+ pifs = call_func2(p_istream_read_str, &ifs, st);
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ ok(!strcmp(st, "test"), "expected 'test' got '%s'\n", st);
+
+ i = 12345;
+ pifs = call_func2(p_istream_read_int, pifs, &i);
+ ok(pifs == &ifs, "wrong return, expected %p got %p\n", &ifs, pifs);
+ ok(i == 12, "expected 12 got %d\n", i);
+
+ call_func1(p_ifstream_vbase_dtor, &ifs);
+ ok(_unlink(filename) == 0, "Couldn't unlink file named '%s'\n", filename);
+}
+
static void test_strstream(void)
{
iostream ios1, ios2, *pios;
@@ -7538,6 +7780,7 @@ START_TEST(msvcirt)
test_istream_withassign();
test_istrstream();
test_iostream();
+ test_ifstream();
test_strstream();
test_stdiostream();
test_Iostream_init();
diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec
index f06a53cc601..2ce72c6b13c 100644
--- a/dlls/msvcrt20/msvcrt20.spec
+++ b/dlls/msvcrt20/msvcrt20.spec
@@ -20,16 +20,16 @@
@ stub -arch=win64 ??0fstream@@QEAA(a)PEBDHH@Z
@ stub -arch=win32 ??0fstream@@QAE(a)XZ
@ stub -arch=win64 ??0fstream@@QEAA(a)XZ
-@ stub -arch=win32 ??0ifstream@@QAE(a)ABV0@@Z
-@ stub -arch=win64 ??0ifstream@@QEAA(a)AEBV0@@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)H@Z
-@ stub -arch=win64 ??0ifstream@@QEAA(a)H@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)HPADH@Z
-@ stub -arch=win64 ??0ifstream@@QEAA(a)HPEADH@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)PBDHH@Z
-@ stub -arch=win64 ??0ifstream@@QEAA(a)PEBDHH@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)XZ
-@ stub -arch=win64 ??0ifstream@@QEAA(a)XZ
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)ABV0@@Z(ptr ptr long) msvcirt.??0ifstream@@QAE(a)ABV0@@Z
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)AEBV0@@Z(ptr ptr long) msvcirt.??0ifstream@@QEAA(a)AEBV0@@Z
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)H@Z(ptr long long) msvcirt.??0ifstream@@QAE(a)H@Z
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)H@Z(ptr long long) msvcirt.??0ifstream@@QEAA(a)H@Z
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)HPADH@Z(ptr long ptr long long) msvcirt.??0ifstream@@QAE(a)HPADH@Z
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)HPEADH@Z(ptr long ptr long long) msvcirt.??0ifstream@@QEAA(a)HPEADH@Z
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)PBDHH@Z(ptr str long long long) msvcirt.??0ifstream@@QAE(a)PBDHH@Z
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)PEBDHH@Z(ptr str long long long) msvcirt.??0ifstream@@QEAA(a)PEBDHH@Z
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)XZ(ptr long) msvcirt.??0ifstream@@QAE(a)XZ
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)XZ(ptr long) msvcirt.??0ifstream@@QEAA(a)XZ
@ thiscall -arch=win32 ??0ios@@IAE(a)ABV0@@Z(ptr ptr) msvcirt.??0ios@@IAE(a)ABV0@@Z
@ cdecl -arch=win64 ??0ios@@IEAA(a)AEBV0@@Z(ptr ptr) msvcirt.??0ios@@IEAA(a)AEBV0@@Z
@ thiscall -arch=win32 ??0ios@@IAE(a)XZ(ptr) msvcirt.??0ios@@IAE(a)XZ
@@ -124,8 +124,8 @@
@ cdecl -arch=win64 ??1filebuf@@UEAA(a)XZ(ptr) msvcirt.??1filebuf@@UEAA(a)XZ
@ stub -arch=win32 ??1fstream@@UAE(a)XZ
@ stub -arch=win64 ??1fstream@@UEAA(a)XZ
-@ stub -arch=win32 ??1ifstream@@UAE(a)XZ
-@ stub -arch=win64 ??1ifstream@@UEAA(a)XZ
+@ thiscall -arch=win32 ??1ifstream@@UAE(a)XZ(ptr) msvcirt.??1ifstream@@UAE(a)XZ
+@ cdecl -arch=win64 ??1ifstream@@UEAA(a)XZ(ptr) msvcirt.??1ifstream@@UEAA(a)XZ
@ thiscall -arch=win32 ??1ios@@UAE(a)XZ(ptr) msvcirt.??1ios@@UAE(a)XZ
@ cdecl -arch=win64 ??1ios@@UEAA(a)XZ(ptr) msvcirt.??1ios@@UEAA(a)XZ
@ thiscall -arch=win32 ??1iostream@@UAE(a)XZ(ptr) msvcirt.??1iostream@@UAE(a)XZ
@@ -164,8 +164,8 @@
@ cdecl -arch=win64 ??4filebuf@@QEAAAEAV0(a)AEBV0@@Z(ptr ptr) msvcirt.??4filebuf@@QEAAAEAV0(a)AEBV0@@Z
@ stub -arch=win32 ??4fstream@@QAEAAV0(a)AAV0@@Z
@ stub -arch=win64 ??4fstream@@QEAAAEAV0(a)AEAV0@@Z
-@ stub -arch=win32 ??4ifstream@@QAEAAV0(a)ABV0@@Z
-@ stub -arch=win64 ??4ifstream@@QEAAAEAV0(a)AEBV0@@Z
+@ thiscall -arch=win32 ??4ifstream@@QAEAAV0(a)ABV0@@Z(ptr ptr) msvcirt.??4ifstream@@QAEAAV0(a)ABV0@@Z
+@ cdecl -arch=win64 ??4ifstream@@QEAAAEAV0(a)AEBV0@@Z(ptr ptr) msvcirt.??4ifstream@@QEAAAEAV0(a)AEBV0@@Z
@ thiscall -arch=win32 ??4ios@@IAEAAV0(a)ABV0@@Z(ptr ptr) msvcirt.??4ios@@IAEAAV0(a)ABV0@@Z
@ cdecl -arch=win64 ??4ios@@IEAAAEAV0(a)AEBV0@@Z(ptr ptr) msvcirt.??4ios@@IEAAAEAV0(a)AEBV0@@Z
@ thiscall -arch=win32 ??4iostream@@IAEAAV0(a)AAV0@@Z(ptr ptr) msvcirt.??4iostream@@IAEAAV0(a)AAV0@@Z
@@ -288,7 +288,7 @@
@ cdecl -arch=win64 ??Bios@@QEBAPEAXXZ(ptr) msvcirt.??Bios@@QEBAPEAXXZ
@ extern ??_7filebuf@@6B@ msvcirt.??_7filebuf@@6B@
# @ extern ??_7fstream@@6B@
-# @ extern ??_7ifstream@@6B@
+@ extern ??_7ifstream@@6B@ msvcirt.??_7ifstream@@6B@
@ extern ??_7ios@@6B@ msvcirt.??_7ios@@6B@
@ extern ??_7iostream@@6B@ msvcirt.??_7iostream@@6B@
@ extern ??_7istream@@6B@ msvcirt.??_7istream@@6B@
@@ -305,7 +305,7 @@
@ extern ??_7strstreambuf@@6B@ msvcirt.??_7strstreambuf@@6B@
# @ extern ??_8fstream@@7Bistream@@@
# @ extern ??_8fstream@@7Bostream@@@
-# @ extern ??_8ifstream@@7B@
+@ extern ??_8ifstream@@7B@ msvcirt.??_8ifstream@@7B@
@ extern ??_8iostream@@7Bistream@@@ msvcirt.??_8iostream@@7Bistream@@@
@ extern ??_8iostream@@7Bostream@@@ msvcirt.??_8iostream@@7Bostream@@@
@ extern ??_8istream@@7B@ msvcirt.??_8istream@@7B@
@@ -321,8 +321,8 @@
@ extern ??_8strstream@@7Bostream@@@ msvcirt.??_8strstream@@7Bostream@@@
@ stub -arch=win32 ??_Dfstream@@QAEXXZ
@ stub -arch=win64 ??_Dfstream@@QEAAXXZ
-@ stub -arch=win32 ??_Difstream@@QAEXXZ
-@ stub -arch=win64 ??_Difstream@@QEAAXXZ
+@ thiscall -arch=win32 ??_Difstream@@QAEXXZ(ptr) msvcirt.??_Difstream@@QAEXXZ
+@ cdecl -arch=win64 ??_Difstream@@QEAAXXZ(ptr) msvcirt.??_Difstream@@QEAAXXZ
@ thiscall -arch=win32 ??_Diostream@@QAEXXZ(ptr) msvcirt.??_Diostream@@QAEXXZ
@ cdecl -arch=win64 ??_Diostream@@QEAAXXZ(ptr) msvcirt.??_Diostream@@QEAAXXZ
@ thiscall -arch=win32 ??_Distream@@QAEXXZ(ptr) msvcirt.??_Distream@@QAEXXZ
@@ -346,7 +346,7 @@
@ stub -arch=win32 ??_EIostream_init@@QAEPAXI(a)Z
@ thiscall -arch=win32 ??_Efilebuf@@UAEPAXI(a)Z(ptr long) msvcirt.??_Efilebuf@@UAEPAXI(a)Z
@ stub -arch=win32 ??_Efstream@@UAEPAXI(a)Z
-@ stub -arch=win32 ??_Eifstream@@UAEPAXI(a)Z
+@ thiscall -arch=win32 ??_Eifstream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Eifstream@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Eios@@UAEPAXI(a)Z(ptr long) msvcirt.??_Eios@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Eiostream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Eiostream@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Eistream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Eistream@@UAEPAXI(a)Z
@@ -364,7 +364,7 @@
@ stub -arch=win32 ??_GIostream_init@@QAEPAXI(a)Z
@ thiscall -arch=win32 ??_Gfilebuf@@UAEPAXI(a)Z(ptr long) msvcirt.??_Gfilebuf@@UAEPAXI(a)Z
@ stub -arch=win32 ??_Gfstream@@UAEPAXI(a)Z
-@ stub -arch=win32 ??_Gifstream@@UAEPAXI(a)Z
+@ thiscall -arch=win32 ??_Gifstream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Gifstream@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Gios@@UAEPAXI(a)Z(ptr long) msvcirt.??_Gios@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Giostream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Giostream@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Gistream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Gistream@@UAEPAXI(a)Z
@@ -394,8 +394,8 @@
@ cdecl -arch=win64 ?attach(a)filebuf@@QEAAPEAV1(a)H@Z(ptr long) msvcirt.?attach(a)filebuf@@QEAAPEAV1(a)H@Z
@ stub -arch=win32 ?attach(a)fstream@@QAEXH(a)Z
@ stub -arch=win64 ?attach(a)fstream@@QEAAXH(a)Z
-@ stub -arch=win32 ?attach(a)ifstream@@QAEXH(a)Z
-@ stub -arch=win64 ?attach(a)ifstream@@QEAAXH(a)Z
+@ thiscall -arch=win32 ?attach(a)ifstream@@QAEXH(a)Z(ptr long) msvcirt.?attach(a)ifstream@@QAEXH(a)Z
+@ cdecl -arch=win64 ?attach(a)ifstream@@QEAAXH(a)Z(ptr long) msvcirt.?attach(a)ifstream@@QEAAXH(a)Z
@ stub -arch=win32 ?attach(a)ofstream@@QAEXH(a)Z
@ stub -arch=win64 ?attach(a)ofstream@@QEAAXH(a)Z
@ thiscall -arch=win32 ?bad(a)ios@@QBEHXZ(ptr) msvcirt.?bad(a)ios@@QBEHXZ
@@ -416,8 +416,8 @@
@ cdecl -arch=win64 ?close(a)filebuf@@QEAAPEAV1(a)XZ(ptr) msvcirt.?close(a)filebuf@@QEAAPEAV1(a)XZ
@ stub -arch=win32 ?close(a)fstream@@QAEXXZ
@ stub -arch=win64 ?close(a)fstream@@QEAAXXZ
-@ stub -arch=win32 ?close(a)ifstream@@QAEXXZ
-@ stub -arch=win64 ?close(a)ifstream@@QEAAXXZ
+@ thiscall -arch=win32 ?close(a)ifstream@@QAEXXZ(ptr) msvcirt.?close(a)ifstream@@QAEXXZ
+@ cdecl -arch=win64 ?close(a)ifstream@@QEAAXXZ(ptr) msvcirt.?close(a)ifstream@@QEAAXXZ
@ stub -arch=win32 ?close(a)ofstream@@QAEXXZ
@ stub -arch=win64 ?close(a)ofstream@@QEAAXXZ
@ cdecl -arch=win32 ?clrlock(a)ios@@QAAXXZ(ptr) msvcirt.?clrlock(a)ios@@QAAXXZ
@@ -460,8 +460,8 @@
@ cdecl -arch=win64 ?fd(a)filebuf@@QEBAHXZ(ptr) msvcirt.?fd(a)filebuf@@QEBAHXZ
@ stub -arch=win32 ?fd(a)fstream@@QBEHXZ
@ stub -arch=win64 ?fd(a)fstream@@QEBAHXZ
-@ stub -arch=win32 ?fd(a)ifstream@@QBEHXZ
-@ stub -arch=win64 ?fd(a)ifstream@@QEBAHXZ
+@ thiscall -arch=win32 ?fd(a)ifstream@@QBEHXZ(ptr) msvcirt.?fd(a)ifstream@@QBEHXZ
+@ cdecl -arch=win64 ?fd(a)ifstream@@QEBAHXZ(ptr) msvcirt.?fd(a)ifstream@@QEBAHXZ
@ stub -arch=win32 ?fd(a)ofstream@@QBEHXZ
@ stub -arch=win64 ?fd(a)ofstream@@QEBAHXZ
@ thiscall -arch=win32 ?fill(a)ios@@QAEDD(a)Z(ptr long) msvcirt.?fill(a)ios@@QAEDD(a)Z
@@ -527,8 +527,8 @@
@ cdecl -arch=win64 ?is_open(a)filebuf@@QEBAHXZ(ptr) msvcirt.?is_open(a)filebuf@@QEBAHXZ
@ stub -arch=win32 ?is_open(a)fstream@@QBEHXZ
@ stub -arch=win64 ?is_open(a)fstream@@QEBAHXZ
-@ stub -arch=win32 ?is_open(a)ifstream@@QBEHXZ
-@ stub -arch=win64 ?is_open(a)ifstream@@QEBAHXZ
+@ thiscall -arch=win32 ?is_open(a)ifstream@@QBEHXZ(ptr) msvcirt.?is_open(a)ifstream@@QBEHXZ
+@ cdecl -arch=win64 ?is_open(a)ifstream@@QEBAHXZ(ptr) msvcirt.?is_open(a)ifstream@@QEBAHXZ
@ stub -arch=win32 ?is_open(a)ofstream@@QBEHXZ
@ stub -arch=win64 ?is_open(a)ofstream@@QEBAHXZ
@ thiscall -arch=win32 ?isfx(a)istream@@QAEXXZ(ptr) msvcirt.?isfx(a)istream@@QAEXXZ
@@ -552,8 +552,8 @@
@ cdecl -arch=win64 ?open(a)filebuf@@QEAAPEAV1(a)PEBDHH@Z(ptr str long long) msvcirt.?open(a)filebuf@@QEAAPEAV1(a)PEBDHH@Z
@ stub -arch=win32 ?open(a)fstream@@QAEXPBDHH(a)Z
@ stub -arch=win64 ?open(a)fstream@@QEAAXPEBDHH(a)Z
-@ stub -arch=win32 ?open(a)ifstream@@QAEXPBDHH(a)Z
-@ stub -arch=win64 ?open(a)ifstream@@QEAAXPEBDHH(a)Z
+@ thiscall -arch=win32 ?open(a)ifstream@@QAEXPBDHH(a)Z(ptr str long long) msvcirt.?open(a)ifstream@@QAEXPBDHH(a)Z
+@ cdecl -arch=win64 ?open(a)ifstream@@QEAAXPEBDHH(a)Z(ptr str long long) msvcirt.?open(a)ifstream@@QEAAXPEBDHH(a)Z
@ stub -arch=win32 ?open(a)ofstream@@QAEXPBDHH(a)Z
@ stub -arch=win64 ?open(a)ofstream@@QEAAXPEBDHH(a)Z
@ extern ?openprot(a)filebuf@@2HB msvcirt.?openprot(a)filebuf@@2HB
@@ -601,8 +601,8 @@
@ cdecl -arch=win64 ?pword(a)ios@@QEBAAEAPEAXH(a)Z(ptr long) msvcirt.?pword(a)ios@@QEBAAEAPEAXH(a)Z
@ stub -arch=win32 ?rdbuf(a)fstream@@QBEPAVfilebuf@@XZ
@ stub -arch=win64 ?rdbuf(a)fstream@@QEBAPEAVfilebuf@@XZ
-@ stub -arch=win32 ?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ
-@ stub -arch=win64 ?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ
+@ thiscall -arch=win32 ?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ(ptr) msvcirt.?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ
+@ cdecl -arch=win64 ?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ(ptr) msvcirt.?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ
@ thiscall -arch=win32 ?rdbuf(a)ios@@QBEPAVstreambuf@@XZ(ptr) msvcirt.?rdbuf(a)ios@@QBEPAVstreambuf@@XZ
@ cdecl -arch=win64 ?rdbuf(a)ios@@QEBAPEAVstreambuf@@XZ(ptr) msvcirt.?rdbuf(a)ios@@QEBAPEAVstreambuf@@XZ
@ thiscall -arch=win32 ?rdbuf(a)istrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf(a)istrstream@@QBEPAVstrstreambuf@@XZ
@@ -651,8 +651,8 @@
@ cdecl -arch=win64 ?setbuf(a)filebuf@@UEAAPEAVstreambuf@@PEADH(a)Z(ptr ptr long) msvcirt.?setbuf(a)filebuf@@UEAAPEAVstreambuf@@PEADH(a)Z
@ stub -arch=win32 ?setbuf(a)fstream@@QAEPAVstreambuf@@PADH(a)Z
@ stub -arch=win64 ?setbuf(a)fstream@@QEAAPEAVstreambuf@@PEADH(a)Z
-@ stub -arch=win32 ?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z
-@ stub -arch=win64 ?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z
+@ thiscall -arch=win32 ?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z(ptr ptr long) msvcirt.?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z
+@ cdecl -arch=win64 ?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z(ptr ptr long) msvcirt.?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z
@ stub -arch=win32 ?setbuf(a)ofstream@@QAEPAVstreambuf@@PADH(a)Z
@ stub -arch=win64 ?setbuf(a)ofstream@@QEAAPEAVstreambuf@@PEADH(a)Z
@ thiscall -arch=win32 ?setbuf(a)streambuf@@UAEPAV1(a)PADH@Z(ptr ptr long) msvcirt.?setbuf(a)streambuf@@UAEPAV1(a)PADH@Z
@@ -673,8 +673,8 @@
@ cdecl -arch=win64 ?setmode(a)filebuf@@QEAAHH(a)Z(ptr long) msvcirt.?setmode(a)filebuf@@QEAAHH(a)Z
@ stub -arch=win32 ?setmode(a)fstream@@QAEHH(a)Z
@ stub -arch=win64 ?setmode(a)fstream@@QEAAHH(a)Z
-@ stub -arch=win32 ?setmode(a)ifstream@@QAEHH(a)Z
-@ stub -arch=win64 ?setmode(a)ifstream@@QEAAHH(a)Z
+@ thiscall -arch=win32 ?setmode(a)ifstream@@QAEHH(a)Z(ptr long) msvcirt.?setmode(a)ifstream@@QAEHH(a)Z
+@ cdecl -arch=win64 ?setmode(a)ifstream@@QEAAHH(a)Z(ptr long) msvcirt.?setmode(a)ifstream@@QEAAHH(a)Z
@ stub -arch=win32 ?setmode(a)ofstream@@QAEHH(a)Z
@ stub -arch=win64 ?setmode(a)ofstream@@QEAAHH(a)Z
@ thiscall -arch=win32 ?setp(a)streambuf@@IAEXPAD0(a)Z(ptr ptr ptr) msvcirt.?setp(a)streambuf@@IAEXPAD0(a)Z
diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec
index f0d966acd7c..efa3e3251d6 100644
--- a/dlls/msvcrt40/msvcrt40.spec
+++ b/dlls/msvcrt40/msvcrt40.spec
@@ -38,16 +38,16 @@
@ stub -arch=win64 ??0fstream@@QEAA(a)PEBDHH@Z
@ stub -arch=win32 ??0fstream@@QAE(a)XZ
@ stub -arch=win64 ??0fstream@@QEAA(a)XZ
-@ stub -arch=win32 ??0ifstream@@QAE(a)ABV0@@Z
-@ stub -arch=win64 ??0ifstream@@QEAA(a)AEBV0@@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)H@Z
-@ stub -arch=win64 ??0ifstream@@QEAA(a)H@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)HPADH@Z
-@ stub -arch=win64 ??0ifstream@@QEAA(a)HPEADH@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)PBDHH@Z
-@ stub -arch=win64 ??0ifstream@@QEAA(a)PEBDHH@Z
-@ stub -arch=win32 ??0ifstream@@QAE(a)XZ
-@ stub -arch=win64 ??0ifstream@@QEAA(a)XZ
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)ABV0@@Z(ptr ptr long) msvcirt.??0ifstream@@QAE(a)ABV0@@Z
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)AEBV0@@Z(ptr ptr long) msvcirt.??0ifstream@@QEAA(a)AEBV0@@Z
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)H@Z(ptr long long) msvcirt.??0ifstream@@QAE(a)H@Z
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)H@Z(ptr long long) msvcirt.??0ifstream@@QEAA(a)H@Z
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)HPADH@Z(ptr long ptr long long) msvcirt.??0ifstream@@QAE(a)HPADH@Z
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)HPEADH@Z(ptr long ptr long long) msvcirt.??0ifstream@@QEAA(a)HPEADH@Z
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)PBDHH@Z(ptr str long long long) msvcirt.??0ifstream@@QAE(a)PBDHH@Z
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)PEBDHH@Z(ptr str long long long) msvcirt.??0ifstream@@QEAA(a)PEBDHH@Z
+@ thiscall -arch=win32 ??0ifstream@@QAE(a)XZ(ptr long) msvcirt.??0ifstream@@QAE(a)XZ
+@ cdecl -arch=win64 ??0ifstream@@QEAA(a)XZ(ptr long) msvcirt.??0ifstream@@QEAA(a)XZ
@ thiscall -arch=win32 ??0ios@@IAE(a)ABV0@@Z(ptr ptr) msvcirt.??0ios@@IAE(a)ABV0@@Z
@ cdecl -arch=win64 ??0ios@@IEAA(a)AEBV0@@Z(ptr ptr) msvcirt.??0ios@@IEAA(a)AEBV0@@Z
@ thiscall -arch=win32 ??0ios@@IAE(a)XZ(ptr) msvcirt.??0ios@@IAE(a)XZ
@@ -154,8 +154,8 @@
@ cdecl -arch=win64 ??1filebuf@@UEAA(a)XZ(ptr) msvcirt.??1filebuf@@UEAA(a)XZ
@ stub -arch=win32 ??1fstream@@UAE(a)XZ
@ stub -arch=win64 ??1fstream@@UEAA(a)XZ
-@ stub -arch=win32 ??1ifstream@@UAE(a)XZ
-@ stub -arch=win64 ??1ifstream@@UEAA(a)XZ
+@ thiscall -arch=win32 ??1ifstream@@UAE(a)XZ(ptr) msvcirt.??1ifstream@@UAE(a)XZ
+@ cdecl -arch=win64 ??1ifstream@@UEAA(a)XZ(ptr) msvcirt.??1ifstream@@UEAA(a)XZ
@ thiscall -arch=win32 ??1ios@@UAE(a)XZ(ptr) msvcirt.??1ios@@UAE(a)XZ
@ cdecl -arch=win64 ??1ios@@UEAA(a)XZ(ptr) msvcirt.??1ios@@UEAA(a)XZ
@ thiscall -arch=win32 ??1iostream@@UAE(a)XZ(ptr) msvcirt.??1iostream@@UAE(a)XZ
@@ -206,8 +206,8 @@
@ cdecl -arch=win64 ??4filebuf@@QEAAAEAV0(a)AEBV0@@Z(ptr ptr) msvcirt.??4filebuf@@QEAAAEAV0(a)AEBV0@@Z
@ stub -arch=win32 ??4fstream@@QAEAAV0(a)AAV0@@Z
@ stub -arch=win64 ??4fstream@@QEAAAEAV0(a)AEAV0@@Z
-@ stub -arch=win32 ??4ifstream@@QAEAAV0(a)ABV0@@Z
-@ stub -arch=win64 ??4ifstream@@QEAAAEAV0(a)AEBV0@@Z
+@ thiscall -arch=win32 ??4ifstream@@QAEAAV0(a)ABV0@@Z(ptr ptr) msvcirt.??4ifstream@@QAEAAV0(a)ABV0@@Z
+@ cdecl -arch=win64 ??4ifstream@@QEAAAEAV0(a)AEBV0@@Z(ptr ptr) msvcirt.??4ifstream@@QEAAAEAV0(a)AEBV0@@Z
@ thiscall -arch=win32 ??4ios@@IAEAAV0(a)ABV0@@Z(ptr ptr) msvcirt.??4ios@@IAEAAV0(a)ABV0@@Z
@ cdecl -arch=win64 ??4ios@@IEAAAEAV0(a)AEBV0@@Z(ptr ptr) msvcirt.??4ios@@IEAAAEAV0(a)AEBV0@@Z
@ thiscall -arch=win32 ??4iostream@@IAEAAV0(a)AAV0@@Z(ptr ptr) msvcirt.??4iostream@@IAEAAV0(a)AAV0@@Z
@@ -340,7 +340,7 @@
@ extern ??_7exception@@6B@ msvcrt.??_7exception@@6B@
@ extern ??_7filebuf@@6B@ msvcirt.??_7filebuf@@6B@
# @ extern ??_7fstream@@6B@
-# @ extern ??_7ifstream@@6B@
+@ extern ??_7ifstream@@6B@ msvcirt.??_7ifstream@@6B@
@ extern ??_7ios@@6B@ msvcirt.??_7ios@@6B@
@ extern ??_7iostream@@6B@ msvcirt.??_7iostream@@6B@
@ extern ??_7istream@@6B@ msvcirt.??_7istream@@6B@
@@ -358,7 +358,7 @@
@ extern ??_7strstreambuf@@6B@ msvcirt.??_7strstreambuf@@6B@
# @ extern ??_8fstream@@7Bistream@@@
# @ extern ??_8fstream@@7Bostream@@@
-# @ extern ??_8ifstream@@7B@
+@ extern ??_8ifstream@@7B@ msvcirt.??_8ifstream@@7B@
@ extern ??_8iostream@@7Bistream@@@ msvcirt.??_8iostream@@7Bistream@@@
@ extern ??_8iostream@@7Bostream@@@ msvcirt.??_8iostream@@7Bostream@@@
@ extern ??_8istream@@7B@ msvcirt.??_8istream@@7B@
@@ -374,8 +374,8 @@
@ extern ??_8strstream@@7Bostream@@@ msvcirt.??_8strstream@@7Bostream@@@
@ stub -arch=win32 ??_Dfstream@@QAEXXZ
@ stub -arch=win64 ??_Dfstream@@QEAAXXZ
-@ stub -arch=win32 ??_Difstream@@QAEXXZ
-@ stub -arch=win64 ??_Difstream@@QEAAXXZ
+@ thiscall -arch=win32 ??_Difstream@@QAEXXZ(ptr) msvcirt.??_Difstream@@QAEXXZ
+@ cdecl -arch=win64 ??_Difstream@@QEAAXXZ(ptr) msvcirt.??_Difstream@@QEAAXXZ
@ thiscall -arch=win32 ??_Diostream@@QAEXXZ(ptr) msvcirt.??_Diostream@@QAEXXZ
@ cdecl -arch=win64 ??_Diostream@@QEAAXXZ(ptr) msvcirt.??_Diostream@@QEAAXXZ
@ thiscall -arch=win32 ??_Distream@@QAEXXZ(ptr) msvcirt.??_Distream@@QAEXXZ
@@ -403,7 +403,7 @@
@ thiscall -arch=win32 ??_Eexception@@UAEPAXI(a)Z(ptr long) msvcrt.??_Eexception@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Efilebuf@@UAEPAXI(a)Z(ptr long) msvcirt.??_Efilebuf@@UAEPAXI(a)Z
@ stub -arch=win32 ??_Efstream@@UAEPAXI(a)Z
-@ stub -arch=win32 ??_Eifstream@@UAEPAXI(a)Z
+@ thiscall -arch=win32 ??_Eifstream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Eifstream@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Eios@@UAEPAXI(a)Z(ptr long) msvcirt.??_Eios@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Eiostream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Eiostream@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Eistream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Eistream@@UAEPAXI(a)Z
@@ -426,7 +426,7 @@
@ thiscall -arch=win32 ??_Gexception@@UAEPAXI(a)Z(ptr long) msvcrt.??_Gexception@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Gfilebuf@@UAEPAXI(a)Z(ptr long) msvcirt.??_Gfilebuf@@UAEPAXI(a)Z
@ stub -arch=win32 ??_Gfstream@@UAEPAXI(a)Z
-@ stub -arch=win32 ??_Gifstream@@UAEPAXI(a)Z
+@ thiscall -arch=win32 ??_Gifstream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Gifstream@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Gios@@UAEPAXI(a)Z(ptr long) msvcirt.??_Gios@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Giostream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Giostream@@UAEPAXI(a)Z
@ thiscall -arch=win32 ??_Gistream@@UAEPAXI(a)Z(ptr long) msvcirt.??_Gistream@@UAEPAXI(a)Z
@@ -457,8 +457,8 @@
@ cdecl -arch=win64 ?attach(a)filebuf@@QEAAPEAV1(a)H@Z(ptr long) msvcirt.?attach(a)filebuf@@QEAAPEAV1(a)H@Z
@ stub -arch=win32 ?attach(a)fstream@@QAEXH(a)Z
@ stub -arch=win64 ?attach(a)fstream@@QEAAXH(a)Z
-@ stub -arch=win32 ?attach(a)ifstream@@QAEXH(a)Z
-@ stub -arch=win64 ?attach(a)ifstream@@QEAAXH(a)Z
+@ thiscall -arch=win32 ?attach(a)ifstream@@QAEXH(a)Z(ptr long) msvcirt.?attach(a)ifstream@@QAEXH(a)Z
+@ cdecl -arch=win64 ?attach(a)ifstream@@QEAAXH(a)Z(ptr long) msvcirt.?attach(a)ifstream@@QEAAXH(a)Z
@ stub -arch=win32 ?attach(a)ofstream@@QAEXH(a)Z
@ stub -arch=win64 ?attach(a)ofstream@@QEAAXH(a)Z
@ thiscall -arch=win32 ?bad(a)ios@@QBEHXZ(ptr) msvcirt.?bad(a)ios@@QBEHXZ
@@ -481,8 +481,8 @@
@ cdecl -arch=win64 ?close(a)filebuf@@QEAAPEAV1(a)XZ(ptr) msvcirt.?close(a)filebuf@@QEAAPEAV1(a)XZ
@ stub -arch=win32 ?close(a)fstream@@QAEXXZ
@ stub -arch=win64 ?close(a)fstream@@QEAAXXZ
-@ stub -arch=win32 ?close(a)ifstream@@QAEXXZ
-@ stub -arch=win64 ?close(a)ifstream@@QEAAXXZ
+@ thiscall -arch=win32 ?close(a)ifstream@@QAEXXZ(ptr) msvcirt.?close(a)ifstream@@QAEXXZ
+@ cdecl -arch=win64 ?close(a)ifstream@@QEAAXXZ(ptr) msvcirt.?close(a)ifstream@@QEAAXXZ
@ stub -arch=win32 ?close(a)ofstream@@QAEXXZ
@ stub -arch=win64 ?close(a)ofstream@@QEAAXXZ
@ cdecl -arch=win32 ?clrlock(a)ios@@QAAXXZ(ptr) msvcirt.?clrlock(a)ios@@QAAXXZ
@@ -525,8 +525,8 @@
@ cdecl -arch=win64 ?fd(a)filebuf@@QEBAHXZ(ptr) msvcirt.?fd(a)filebuf@@QEBAHXZ
@ stub -arch=win32 ?fd(a)fstream@@QBEHXZ
@ stub -arch=win64 ?fd(a)fstream@@QEBAHXZ
-@ stub -arch=win32 ?fd(a)ifstream@@QBEHXZ
-@ stub -arch=win64 ?fd(a)ifstream@@QEBAHXZ
+@ thiscall -arch=win32 ?fd(a)ifstream@@QBEHXZ(ptr) msvcirt.?fd(a)ifstream@@QBEHXZ
+@ cdecl -arch=win64 ?fd(a)ifstream@@QEBAHXZ(ptr) msvcirt.?fd(a)ifstream@@QEBAHXZ
@ stub -arch=win32 ?fd(a)ofstream@@QBEHXZ
@ stub -arch=win64 ?fd(a)ofstream@@QEBAHXZ
@ thiscall -arch=win32 ?fill(a)ios@@QAEDD(a)Z(ptr long) msvcirt.?fill(a)ios@@QAEDD(a)Z
@@ -594,8 +594,8 @@
@ cdecl -arch=win64 ?is_open(a)filebuf@@QEBAHXZ(ptr) msvcirt.?is_open(a)filebuf@@QEBAHXZ
@ stub -arch=win32 ?is_open(a)fstream@@QBEHXZ
@ stub -arch=win64 ?is_open(a)fstream@@QEBAHXZ
-@ stub -arch=win32 ?is_open(a)ifstream@@QBEHXZ
-@ stub -arch=win64 ?is_open(a)ifstream@@QEBAHXZ
+@ thiscall -arch=win32 ?is_open(a)ifstream@@QBEHXZ(ptr) msvcirt.?is_open(a)ifstream@@QBEHXZ
+@ cdecl -arch=win64 ?is_open(a)ifstream@@QEBAHXZ(ptr) msvcirt.?is_open(a)ifstream@@QEBAHXZ
@ stub -arch=win32 ?is_open(a)ofstream@@QBEHXZ
@ stub -arch=win64 ?is_open(a)ofstream@@QEBAHXZ
@ thiscall -arch=win32 ?isfx(a)istream@@QAEXXZ(ptr) msvcirt.?isfx(a)istream@@QAEXXZ
@@ -621,8 +621,8 @@
@ cdecl -arch=win64 ?open(a)filebuf@@QEAAPEAV1(a)PEBDHH@Z(ptr str long long) msvcirt.?open(a)filebuf@@QEAAPEAV1(a)PEBDHH@Z
@ stub -arch=win32 ?open(a)fstream@@QAEXPBDHH(a)Z
@ stub -arch=win64 ?open(a)fstream@@QEAAXPEBDHH(a)Z
-@ stub -arch=win32 ?open(a)ifstream@@QAEXPBDHH(a)Z
-@ stub -arch=win64 ?open(a)ifstream@@QEAAXPEBDHH(a)Z
+@ thiscall -arch=win32 ?open(a)ifstream@@QAEXPBDHH(a)Z(ptr str long long) msvcirt.?open(a)ifstream@@QAEXPBDHH(a)Z
+@ cdecl -arch=win64 ?open(a)ifstream@@QEAAXPEBDHH(a)Z(ptr str long long) msvcirt.?open(a)ifstream@@QEAAXPEBDHH(a)Z
@ stub -arch=win32 ?open(a)ofstream@@QAEXPBDHH(a)Z
@ stub -arch=win64 ?open(a)ofstream@@QEAAXPEBDHH(a)Z
@ extern ?openprot(a)filebuf@@2HB msvcirt.?openprot(a)filebuf@@2HB
@@ -672,8 +672,8 @@
@ cdecl -arch=win64 ?raw_name(a)type_info@@QEBAPEBDXZ(ptr) msvcrt.?raw_name(a)type_info@@QEBAPEBDXZ
@ stub -arch=win32 ?rdbuf(a)fstream@@QBEPAVfilebuf@@XZ
@ stub -arch=win64 ?rdbuf(a)fstream@@QEBAPEAVfilebuf@@XZ
-@ stub -arch=win32 ?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ
-@ stub -arch=win64 ?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ
+@ thiscall -arch=win32 ?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ(ptr) msvcirt.?rdbuf(a)ifstream@@QBEPAVfilebuf@@XZ
+@ cdecl -arch=win64 ?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ(ptr) msvcirt.?rdbuf(a)ifstream@@QEBAPEAVfilebuf@@XZ
@ thiscall -arch=win32 ?rdbuf(a)ios@@QBEPAVstreambuf@@XZ(ptr) msvcirt.?rdbuf(a)ios@@QBEPAVstreambuf@@XZ
@ cdecl -arch=win64 ?rdbuf(a)ios@@QEBAPEAVstreambuf@@XZ(ptr) msvcirt.?rdbuf(a)ios@@QEBAPEAVstreambuf@@XZ
@ thiscall -arch=win32 ?rdbuf(a)istrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf(a)istrstream@@QBEPAVstrstreambuf@@XZ
@@ -723,8 +723,8 @@
@ cdecl -arch=win64 ?setbuf(a)filebuf@@UEAAPEAVstreambuf@@PEADH(a)Z(ptr ptr long) msvcirt.?setbuf(a)filebuf@@UEAAPEAVstreambuf@@PEADH(a)Z
@ stub -arch=win32 ?setbuf(a)fstream@@QAEPAVstreambuf@@PADH(a)Z
@ stub -arch=win64 ?setbuf(a)fstream@@QEAAPEAVstreambuf@@PEADH(a)Z
-@ stub -arch=win32 ?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z
-@ stub -arch=win64 ?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z
+@ thiscall -arch=win32 ?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z(ptr ptr long) msvcirt.?setbuf(a)ifstream@@QAEPAVstreambuf@@PADH(a)Z
+@ cdecl -arch=win64 ?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z(ptr ptr long) msvcirt.?setbuf(a)ifstream@@QEAAPEAVstreambuf@@PEADH(a)Z
@ stub -arch=win32 ?setbuf(a)ofstream@@QAEPAVstreambuf@@PADH(a)Z
@ stub -arch=win64 ?setbuf(a)ofstream@@QEAAPEAVstreambuf@@PEADH(a)Z
@ thiscall -arch=win32 ?setbuf(a)streambuf@@UAEPAV1(a)PADH@Z(ptr ptr long) msvcirt.?setbuf(a)streambuf@@UAEPAV1(a)PADH@Z
@@ -745,8 +745,8 @@
@ cdecl -arch=win64 ?setmode(a)filebuf@@QEAAHH(a)Z(ptr long) msvcirt.?setmode(a)filebuf@@QEAAHH(a)Z
@ stub -arch=win32 ?setmode(a)fstream@@QAEHH(a)Z
@ stub -arch=win64 ?setmode(a)fstream@@QEAAHH(a)Z
-@ stub -arch=win32 ?setmode(a)ifstream@@QAEHH(a)Z
-@ stub -arch=win64 ?setmode(a)ifstream@@QEAAHH(a)Z
+@ thiscall -arch=win32 ?setmode(a)ifstream@@QAEHH(a)Z(ptr long) msvcirt.?setmode(a)ifstream@@QAEHH(a)Z
+@ cdecl -arch=win64 ?setmode(a)ifstream@@QEAAHH(a)Z(ptr long) msvcirt.?setmode(a)ifstream@@QEAAHH(a)Z
@ stub -arch=win32 ?setmode(a)ofstream@@QAEHH(a)Z
@ stub -arch=win64 ?setmode(a)ofstream@@QEAAHH(a)Z
@ thiscall -arch=win32 ?setp(a)streambuf@@IAEXPAD0(a)Z(ptr ptr ptr) msvcirt.?setp(a)streambuf@@IAEXPAD0(a)Z
--
2.28.0
2
1
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
.../api-ms-win-core-xstate-l1-1-0.spec | 2 +-
.../api-ms-win-core-xstate-l2-1-0.spec | 2 +-
dlls/kernel32/kernel32.spec | 2 +-
dlls/kernelbase/kernelbase.spec | 2 +-
dlls/kernelbase/memory.c | 41 +++++++++-
dlls/ntdll/exception.c | 10 +++
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/tests/exception.c | 77 ++++++++++++++++++-
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 1 +
include/ddk/wdm.h | 1 +
include/winbase.h | 1 +
11 files changed, 131 insertions(+), 9 deletions(-)
diff --git a/dlls/api-ms-win-core-xstate-l1-1-0/api-ms-win-core-xstate-l1-1-0.spec b/dlls/api-ms-win-core-xstate-l1-1-0/api-ms-win-core-xstate-l1-1-0.spec
index b933eca226f..0a29d660112 100644
--- a/dlls/api-ms-win-core-xstate-l1-1-0/api-ms-win-core-xstate-l1-1-0.spec
+++ b/dlls/api-ms-win-core-xstate-l1-1-0/api-ms-win-core-xstate-l1-1-0.spec
@@ -5,4 +5,4 @@
@ stdcall RtlInitializeExtendedContext(ptr long ptr) ntdll.RtlInitializeExtendedContext
@ stdcall RtlLocateExtendedFeature(ptr long ptr) ntdll.RtlLocateExtendedFeature
@ stdcall RtlLocateLegacyContext(ptr ptr) ntdll.RtlLocateLegacyContext
-@ stub RtlSetExtendedFeaturesMask
+@ stdcall RtlSetExtendedFeaturesMask(ptr int64) ntdll.RtlSetExtendedFeaturesMask
diff --git a/dlls/api-ms-win-core-xstate-l2-1-0/api-ms-win-core-xstate-l2-1-0.spec b/dlls/api-ms-win-core-xstate-l2-1-0/api-ms-win-core-xstate-l2-1-0.spec
index 5ad2df2b405..74aafa4db1c 100644
--- a/dlls/api-ms-win-core-xstate-l2-1-0/api-ms-win-core-xstate-l2-1-0.spec
+++ b/dlls/api-ms-win-core-xstate-l2-1-0/api-ms-win-core-xstate-l2-1-0.spec
@@ -3,4 +3,4 @@
@ stub GetXStateFeaturesMask
@ stdcall -arch=i386,x86_64 InitializeContext(ptr long ptr ptr) kernel32.InitializeContext
@ stdcall -arch=i386,x86_64 LocateXStateFeature(ptr long ptr) kernel32.LocateXStateFeature
-@ stub SetXStateFeaturesMask
+@ stdcall -arch=i386,x86_64 SetXStateFeaturesMask(ptr int64) kernel32.SetXStateFeaturesMask
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index c22f3000bf0..4bcda92bf7f 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -895,7 +895,7 @@
@ stdcall -import GetWindowsDirectoryA(ptr long)
@ stdcall -import GetWindowsDirectoryW(ptr long)
@ stdcall -import GetWriteWatch(long ptr long ptr ptr ptr)
-# @ stub GetXStateFeaturesMask
+@ stdcall -import -arch=i386,x86_64 SetXStateFeaturesMask(ptr int64)
@ stdcall GlobalAddAtomA(str)
@ stdcall GlobalAddAtomW(wstr)
@ stdcall -import GlobalAlloc(long long)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index ef862c57a4f..d2832600091 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -1510,7 +1510,7 @@
@ stdcall SetUserGeoID(long)
@ stdcall SetWaitableTimer(long ptr long ptr ptr long)
@ stdcall SetWaitableTimerEx(long ptr long ptr ptr ptr long)
-# @ stub SetXStateFeaturesMask
+@ stdcall -arch=i386,x86_64 SetXStateFeaturesMask(ptr int64)
@ stdcall SetupComm(long long long)
# @ stub SharedLocalIsEnabled
@ stdcall SignalObjectAndWait(long long long long)
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c
index ea958e1e232..f99b908494b 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -1236,10 +1236,10 @@ BOOL WINAPI InitializeContext( void *buffer, DWORD context_flags, CONTEXT **cont
#endif
+#if defined(__x86_64__)
/***********************************************************************
* LocateXStateFeature (kernelbase.@)
*/
-#if defined(__x86_64__)
void * WINAPI LocateXStateFeature( CONTEXT *context, DWORD feature_id, DWORD *length )
{
if (!(context->ContextFlags & CONTEXT_AMD64))
@@ -1262,7 +1262,28 @@ void * WINAPI LocateXStateFeature( CONTEXT *context, DWORD feature_id, DWORD *le
return &context->u.FltSave;
}
+
+/***********************************************************************
+ * SetXStateFeaturesMask (kernelbase.@)
+ */
+BOOL WINAPI SetXStateFeaturesMask( CONTEXT *context, DWORD64 feature_mask )
+{
+ if (!(context->ContextFlags & CONTEXT_AMD64))
+ return FALSE;
+
+ if (feature_mask & 0x3)
+ context->ContextFlags |= CONTEXT_FLOATING_POINT;
+
+ if ((context->ContextFlags & CONTEXT_XSTATE) != CONTEXT_XSTATE)
+ return !(feature_mask & ~(DWORD64)3);
+
+ RtlSetExtendedFeaturesMask( (CONTEXT_EX *)(context + 1), feature_mask );
+ return TRUE;
+}
#elif defined(__i386__)
+/***********************************************************************
+ * LocateXStateFeature (kernelbase.@)
+ */
void * WINAPI LocateXStateFeature( CONTEXT *context, DWORD feature_id, DWORD *length )
{
if (!(context->ContextFlags & CONTEXT_X86))
@@ -1285,6 +1306,24 @@ void * WINAPI LocateXStateFeature( CONTEXT *context, DWORD feature_id, DWORD *le
return &context->ExtendedRegisters;
}
+
+/***********************************************************************
+ * SetXStateFeaturesMask (kernelbase.@)
+ */
+BOOL WINAPI SetXStateFeaturesMask( CONTEXT *context, DWORD64 feature_mask )
+{
+ if (!(context->ContextFlags & CONTEXT_X86))
+ return FALSE;
+
+ if (feature_mask & 0x3)
+ context->ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
+
+ if ((context->ContextFlags & CONTEXT_XSTATE) != CONTEXT_XSTATE)
+ return !(feature_mask & ~(DWORD64)3);
+
+ RtlSetExtendedFeaturesMask( (CONTEXT_EX *)(context + 1), feature_mask );
+ return TRUE;
+}
#endif
/***********************************************************************
diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index 0e7e3b959e4..6ca22d6660f 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -861,3 +861,13 @@ void * WINAPI RtlLocateLegacyContext( CONTEXT_EX *context_ex, ULONG *length )
return (BYTE *)context_ex + context_ex->Legacy.Offset;
}
+
+/**********************************************************************
+ * RtlSetExtendedFeaturesMask (NTDLL.@)
+ */
+void WINAPI RtlSetExtendedFeaturesMask( CONTEXT_EX *context_ex, ULONG64 feature_mask )
+{
+ XSTATE *xs = (XSTATE *)((BYTE *)context_ex + context_ex->XState.Offset);
+
+ xs->Mask = RtlGetEnabledExtendedFeatures( feature_mask ) & ~(ULONG64)3;
+}
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index cc75aad06d1..0e17d29ed1b 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -946,6 +946,7 @@
@ stdcall RtlSetCurrentTransaction(ptr)
@ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long)
@ stdcall RtlSetEnvironmentVariable(ptr ptr ptr)
+@ stdcall RtlSetExtendedFeaturesMask(ptr int64)
@ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long)
@ stdcall RtlSetHeapInformation(long long ptr long)
@ stub RtlSetInformationAcl
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 4b714e4739e..7b6c65f8572 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -53,6 +53,7 @@ static NTSTATUS (WINAPI *pRtlInitializeExtendedContext2)(void *context, ULONG c
ULONG64 compaction_mask);
static void * (WINAPI *pRtlLocateExtendedFeature)(CONTEXT_EX *context_ex, ULONG feature_id, ULONG *length);
static void * (WINAPI *pRtlLocateLegacyContext)(CONTEXT_EX *context_ex, ULONG *length);
+static void (WINAPI *pRtlSetExtendedFeaturesMask)(CONTEXT_EX *context_ex, ULONG64 feature_mask);
static NTSTATUS (WINAPI *pNtReadVirtualMemory)(HANDLE, const void*, void*, SIZE_T, SIZE_T*);
static NTSTATUS (WINAPI *pNtTerminateProcess)(HANDLE handle, LONG exit_code);
static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
@@ -67,6 +68,7 @@ static BOOL (WINAPI *pInitializeContext)(void *buffer, DWORD context_flags,
static BOOL (WINAPI *pInitializeContext2)(void *buffer, DWORD context_flags, CONTEXT **context,
DWORD *length, ULONG64 compaction_mask);
static void * (WINAPI *pLocateXStateFeature)(CONTEXT *context, DWORD feature_id, DWORD *length);
+static BOOL (WINAPI *pSetXStateFeaturesMask)(CONTEXT *context, DWORD64 feature_mask);
#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64
@@ -6224,15 +6226,15 @@ static void test_extended_context(void)
},
};
ULONG expected_length, expected_length_xstate, context_flags, expected_offset;
+ ULONG64 enabled_features, expected_compaction;
DECLSPEC_ALIGN(64) BYTE context_buffer2[2048];
DECLSPEC_ALIGN(64) BYTE context_buffer[2048];
unsigned int i, j, address_offset, test;
ULONG ret, ret2, length, length2, align;
- ULONG64 enabled_features;
CONTEXT_EX *context_ex;
+ ULONG flags, flags_fpx;
CONTEXT *context;
unsigned data[8];
- ULONG flags;
XSTATE *xs;
BOOL bret;
void *p;
@@ -6359,6 +6361,36 @@ static void test_extended_context(void)
"Got unexpected p %p, length %#x, flags %#x.\n", p, length2, flags);
length2 = expected_length;
+ if (0)
+ {
+ /* Crashes on Windows. */
+ pRtlSetExtendedFeaturesMask(context_ex, 0);
+ }
+ bret = pSetXStateFeaturesMask(context, 0);
+ ok(bret == !!(flags & CONTEXT_NATIVE), "Got unexpected bret %#x, flags %#x.\n", bret, flags);
+ context_flags = *(DWORD *)(context_buffer + context_arch[test].flags_offset);
+ ok(context_flags == flags, "Got unexpected ContextFlags %#x, flags %#x.\n", context_flags, flags);
+
+ flags_fpx = flags & 0x10000 ? flags | 0x20 : flags | 0x8;
+ bret = pSetXStateFeaturesMask(context, 1);
+ ok(bret == !!(flags & CONTEXT_NATIVE), "Got unexpected bret %#x, flags %#x.\n", bret, flags);
+ context_flags = *(DWORD *)(context_buffer + context_arch[test].flags_offset);
+ ok(context_flags == (bret ? flags_fpx : flags),
+ "Got unexpected ContextFlags %#x, flags %#x.\n", context_flags, flags);
+
+ bret = pSetXStateFeaturesMask(context, 2);
+ ok(bret == !!(flags & CONTEXT_NATIVE), "Got unexpected bret %#x, flags %#x.\n", bret, flags);
+ context_flags = *(DWORD *)(context_buffer + context_arch[test].flags_offset);
+ ok(context_flags == (bret ? flags_fpx : flags),
+ "Got unexpected ContextFlags %#x, flags %#x.\n", context_flags, flags);
+
+ bret = pSetXStateFeaturesMask(context, 4);
+ ok(!bret, "Got unexpected bret %#x.\n", bret);
+ context_flags = *(DWORD *)(context_buffer + context_arch[test].flags_offset);
+ ok(context_flags == (flags & CONTEXT_NATIVE ? flags_fpx : flags),
+ "Got unexpected ContextFlags %#x, flags %#x.\n", context_flags, flags);
+ *(DWORD *)(context_buffer + context_arch[test].flags_offset) = flags;
+
for (j = 0; j < context_arch[test].flags_offset; ++j)
{
if (context_buffer[j] != 0xcc)
@@ -6469,6 +6501,7 @@ static void test_extended_context(void)
}
flags = context_arch[test].flag | 0x40;
+ flags_fpx = flags & 0x10000 ? flags | 0x20 : flags | 0x8;
length = 0xdeadbeef;
ret = pRtlGetExtendedContextLength(flags, &length);
@@ -6629,11 +6662,40 @@ static void test_extended_context(void)
else
ok(!p && length2 == 0xdeadbeef, "Got unexpected p %p, length %#x, flags %#x.\n", p, length2, flags);
+ expected_compaction = compaction_enabled ? ((ULONG64)1 << 63) | enabled_features : 0;
ok(!xs->Mask, "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
- ok(xs->CompactionMask == (compaction_enabled ? ((ULONG64)1 << 63) | enabled_features : 0),
+ ok(xs->CompactionMask == expected_compaction,
"Got unexpected CompactionMask %s.\n", wine_dbgstr_longlong(xs->CompactionMask));
ok(!xs->Reserved[0], "Got unexpected Reserved[0] %s.\n", wine_dbgstr_longlong(xs->Reserved[0]));
+ xs->Mask = 0xdeadbeef;
+ xs->CompactionMask = 0xdeadbeef;
+ pRtlSetExtendedFeaturesMask(context_ex, 0);
+ ok(!xs->Mask, "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
+ ok(xs->CompactionMask == 0xdeadbeef, "Got unexpected CompactionMask %s.\n", wine_dbgstr_longlong(xs->CompactionMask));
+ context_flags = *(DWORD *)(context_buffer + context_arch[test].flags_offset);
+ ok(context_flags == flags, "Got unexpected ContextFlags %#x, flags %#x.\n", context->ContextFlags, flags);
+
+ xs->Mask = 0xdeadbeef;
+ xs->CompactionMask = 0;
+ pRtlSetExtendedFeaturesMask(context_ex, ~(ULONG64)0);
+ ok(xs->Mask == (enabled_features & ~(ULONG64)3), "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
+ ok(!xs->CompactionMask, "Got unexpected CompactionMask %s.\n",
+ wine_dbgstr_longlong(xs->CompactionMask));
+ context_flags = *(DWORD *)(context_buffer + context_arch[test].flags_offset);
+ ok(context_flags == flags, "Got unexpected ContextFlags %#x, flags %#x.\n", context->ContextFlags, flags);
+
+ xs->Mask = 0xdeadbeef;
+ xs->CompactionMask = 0xdeadbeef;
+ bret = pSetXStateFeaturesMask(context, 7);
+ ok(bret == !!(flags & CONTEXT_NATIVE), "Got unexpected bret %#x.\n", bret);
+ context_flags = *(DWORD *)(context_buffer + context_arch[test].flags_offset);
+ ok(context_flags == (bret ? flags_fpx : flags),
+ "Got unexpected ContextFlags %#x, flags %#x.\n", context_flags, flags);
+ ok(xs->Mask == bret ? 4 : 0xdeadbeef, "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
+ ok(xs->CompactionMask == bret ? expected_compaction : 0xdeadbeef, "Got unexpected CompactionMask %s.\n",
+ wine_dbgstr_longlong(xs->CompactionMask));
+
if (pRtlGetExtendedContextLength2)
{
memset(context_buffer, 0xcc, sizeof(context_buffer));
@@ -6690,11 +6752,16 @@ static void test_extended_context(void)
+ context_ex->XState.Offset + context_ex->XState.Length,
"Got unexpected Length %#x, flags %#x.\n", context_ex->All.Length, flags);
+ expected_compaction = compaction_enabled ? (ULONG64)1 << 63 : 0;
xs = (XSTATE *)((BYTE *)context_ex + context_ex->XState.Offset);
ok(!xs->Mask, "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
- ok(xs->CompactionMask == (compaction_enabled ? (ULONG64)1 << 63 : 0),
+ ok(xs->CompactionMask == expected_compaction,
"Got unexpected CompactionMask %s.\n", wine_dbgstr_longlong(xs->CompactionMask));
ok(!xs->Reserved[0], "Got unexpected Reserved[0] %s.\n", wine_dbgstr_longlong(xs->Reserved[0]));
+
+ pRtlSetExtendedFeaturesMask(context_ex, ~(ULONG64)0);
+ ok(xs->Mask == (enabled_features & ~(ULONG64)3), "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
+ ok(xs->CompactionMask == expected_compaction, "Got unexpected CompactionMask %s.\n", wine_dbgstr_longlong(xs->CompactionMask));
}
}
@@ -6790,6 +6857,7 @@ START_TEST(exception)
X(RtlInitializeExtendedContext2);
X(RtlLocateExtendedFeature);
X(RtlLocateLegacyContext);
+ X(RtlSetExtendedFeaturesMask);
#undef X
#define X(f) p##f = (void*)GetProcAddress(hkernel32, #f)
@@ -6799,6 +6867,7 @@ START_TEST(exception)
X(InitializeContext);
X(InitializeContext2);
X(LocateXStateFeature);
+ X(SetXStateFeaturesMask);
#undef X
if (pRtlAddVectoredExceptionHandler && pRtlRemoveVectoredExceptionHandler)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index a900796359c..ffd8f7dcd4c 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -1235,6 +1235,7 @@
@ stdcall RtlSetBits(ptr long long)
@ stdcall RtlSetControlSecurityDescriptor(ptr long long)
@ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long)
+@ stdcall RtlSetExtendedFeaturesMask(ptr int64)
@ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long)
@ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long)
@ stdcall RtlSetSaclSecurityDescriptor(ptr long ptr long)
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 2115627d3a6..3938645da94 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1845,6 +1845,7 @@ NTSTATUS WINAPI RtlGetExtendedContextLength2(ULONG,ULONG*,ULONG64);
void * WINAPI RtlLocateLegacyContext(CONTEXT_EX*,ULONG*);
void * WINAPI RtlLocateExtendedFeature(CONTEXT_EX*,ULONG,ULONG*);
void * WINAPI RtlLocateExtendedFeature2(CONTEXT_EX*,ULONG,XSTATE_CONFIGURATION*,ULONG*);
+void WINAPI RtlSetExtendedFeaturesMask(CONTEXT_EX*,ULONG64);
#endif
#ifdef __x86_64__
diff --git a/include/winbase.h b/include/winbase.h
index d5ed5db8d7b..f741f0a09dc 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2700,6 +2700,7 @@ WINBASEAPI BOOL WINAPI SetVolumeMountPointW(LPCWSTR,LPCWSTR);
WINBASEAPI BOOL WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,LPVOID,BOOL);
WINBASEAPI BOOL WINAPI SetWaitableTimerEx(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,LPVOID,REASON_CONTEXT*,ULONG);
WINBASEAPI BOOL WINAPI SetUmsThreadInformation(PUMS_CONTEXT,UMS_THREAD_INFO_CLASS,void *,ULONG);
+WINBASEAPI BOOL WINAPI SetXStateFeaturesMask(CONTEXT*, DWORD64);
WINBASEAPI BOOL WINAPI SetupComm(HANDLE,DWORD,DWORD);
WINBASEAPI DWORD WINAPI SignalObjectAndWait(HANDLE,HANDLE,DWORD,BOOL);
WINBASEAPI DWORD WINAPI SizeofResource(HMODULE,HRSRC);
--
2.26.2
2
8
01 Sep '20
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/kernel32/tests/console.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
2
1
01 Sep '20
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
programs/conhost/conhost.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
1
0
[PATCH 4/5] server: Support IOCTL_CONDRV_CTRL_EVENT on console server handles.
by Jacek Caban 01 Sep '20
by Jacek Caban 01 Sep '20
01 Sep '20
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
server/console.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)
1
0
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
include/wine/condrv.h | 8 ++++++++
server/console.c | 19 +++++++++++++++++++
server/trace.c | 1 +
3 files changed, 28 insertions(+)
1
0
I think I've addressed all the issues that were mentioned.
I've moved the test from iphlpapi to ndis.sys. I think I'm using the
LoadOrderGroup correctly and it doesn't create any extra processes.
I also removed the creation of the symlink with DefineDosDevice. It was
inspired by some code I reversed in a third party dll, which the patches
are trying to address.
v1: https://www.winehq.org/pipermail/wine-devel/2020-August/172383.html
Isabella Bosia (7):
iphlpapi: Unify conversions to interface guid.
iphlpapi: Make the interface guids more unique.
wine.inf: Create NDIS service.
ndis.sys: Create network card registry keys.
ndis.sys: Create network card devices.
ndis.sys: Implement IOCTL_NDIS_QUERY_GLOBAL_STATS on network cards.
ndis.sys/tests: Add tests for ndis ioctls.
configure.ac | 1 +
dlls/iphlpapi/iphlpapi_main.c | 12 ++-
dlls/ndis.sys/Makefile.in | 1 +
dlls/ndis.sys/main.c | 159 ++++++++++++++++++++++++++++++++
dlls/ndis.sys/tests/Makefile.in | 5 +
dlls/ndis.sys/tests/ndis.c | 146 +++++++++++++++++++++++++++++
loader/wine.inf.in | 14 +++
7 files changed, 336 insertions(+), 2 deletions(-)
create mode 100644 dlls/ndis.sys/tests/Makefile.in
create mode 100644 dlls/ndis.sys/tests/ndis.c
--
2.25.1
1
7
[PATCH] kernel32/tests: Change file name to avoid collision with other tests.
by Carlos Rivera 01 Sep '20
by Carlos Rivera 01 Sep '20
01 Sep '20
Entries in IniFileMapping are persisted in Windows until the next
reboot, even if removed from the registry. This made the
function test_registry_mapping to cause other tests
that accessed the actual winetest.ini file to fail if the
profile test was run more than once on Windows without rebooting.
Signed-off-by: Carlos Rivera <carlos(a)superkaos.org>
---
dlls/kernel32/tests/profile.c | 182 +++++++++++++++++-----------------
1 file changed, 91 insertions(+), 91 deletions(-)
diff --git a/dlls/kernel32/tests/profile.c b/dlls/kernel32/tests/profile.c
index 5f1f4f0fe7..f981558548 100644
--- a/dlls/kernel32/tests/profile.c
+++ b/dlls/kernel32/tests/profile.c
@@ -1203,7 +1203,7 @@ static void test_registry_mapping(void)
ok(ret, "got error %u\n", GetLastError());
ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE,
- "Software\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\winetest.ini",
+ "Software\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\winetest_map.ini",
0, NULL, 0, KEY_READ | KEY_WRITE | KEY_WOW64_64KEY, NULL, &mapping_key, NULL);
if (ret == ERROR_ACCESS_DENIED)
{
@@ -1214,16 +1214,16 @@ static void test_registry_mapping(void)
ret = RegSetValueExA(mapping_key, "section1", 0, REG_SZ, (BYTE *)"USR:winetest_map", sizeof("USR:winetest_map"));
ok(!ret, "got error %u\n", ret);
- ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest_map.ini");
todo_wine ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section1", "name1", "winetest.ini", "default");
+ check_profile_string("section1", "name1", "winetest_map.ini", "default");
- ret = WritePrivateProfileStringA("section1", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("section1", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section1", "name1", "winetest.ini", "value1");
- check_profile_string("section1", "name1", "C:/fake/path/winetest.ini", "value1");
+ check_profile_string("section1", "name1", "winetest_map.ini", "value1");
+ check_profile_string("section1", "name1", "C:/fake/path/winetest_map.ini", "value1");
ret = RegOpenKeyExA(HKEY_CURRENT_USER, "winetest_map", 0, KEY_READ | KEY_WRITE, &mapped_key);
ok(!ret, "got error %u\n", ret);
@@ -1232,12 +1232,12 @@ static void test_registry_mapping(void)
ret = RegSetValueExA(mapped_key, "name2", 0, REG_SZ, (BYTE *)"value2", sizeof("value2"));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section1", "name2", "winetest.ini", "value2");
+ check_profile_string("section1", "name2", "winetest_map.ini", "value2");
- ret = GetFileAttributesA("C:/windows/winetest.ini");
- ok(ret == INVALID_FILE_ATTRIBUTES, "winetest.ini should not exist.\n");
+ ret = GetFileAttributesA("C:/windows/winetest_map.ini");
+ ok(ret == INVALID_FILE_ATTRIBUTES, "winetest_map.ini should not exist.\n");
- ret = WritePrivateProfileStringA("section1", "name2", NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA("section1", "name2", NULL, "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
ret = RegQueryValueExA(mapped_key, "name2", 0, NULL, NULL, NULL);
ok(ret == ERROR_FILE_NOT_FOUND, "got error %u\n", ret);
@@ -1246,35 +1246,35 @@ static void test_registry_mapping(void)
ret = RegSetValueExA(mapped_key, "name3", 0, REG_DWORD, (BYTE *)&ivalue, sizeof(ivalue));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section1", "name3", "winetest.ini", "default");
+ check_profile_string("section1", "name3", "winetest_map.ini", "default");
- ret = GetPrivateProfileIntA("section1", "name3", 0, "winetest.ini");
+ ret = GetPrivateProfileIntA("section1", "name3", 0, "winetest_map.ini");
ok(ret == 0, "got %#x\n", ret);
ret = RegSetValueExA(mapped_key, "name3", 0, REG_BINARY, (BYTE *)"value3", sizeof("value3"));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section1", "name3", "winetest.ini", "default");
+ check_profile_string("section1", "name3", "winetest_map.ini", "default");
ret = RegSetValueExA(mapped_key, "name3", 0, REG_MULTI_SZ, (BYTE *)"one\0two\0", sizeof("one\0two\0"));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section1", "name3", "winetest.ini", "default");
+ check_profile_string("section1", "name3", "winetest_map.ini", "default");
ret = RegSetValueExA(mapped_key, "name3", 0, REG_EXPAND_SZ, (BYTE *)"x%SystemRoot%", sizeof("x%SystemRoot%"));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section1", "name3", "winetest.ini", "default");
+ check_profile_string("section1", "name3", "winetest_map.ini", "default");
/* Test WritePrivateProfileSection(). Unlike with .ini files, it doesn't
* remove existing entries. */
- ret = WritePrivateProfileStringA("section1", "name4", "value4", "winetest.ini");
+ ret = WritePrivateProfileStringA("section1", "name4", "value4", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileStringA("section1", "name5", "value5", "winetest.ini");
+ ret = WritePrivateProfileStringA("section1", "name5", "value5", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileSectionA("section1", "name4=four\0name6=six\0", "winetest.ini");
+ ret = WritePrivateProfileSectionA("section1", "name4=four\0name6=six\0", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section1", "name4", "winetest.ini", "four");
- check_profile_string("section1", "name5", "winetest.ini", "value5");
- check_profile_string("section1", "name6", "winetest.ini", "six");
+ check_profile_string("section1", "name4", "winetest_map.ini", "four");
+ check_profile_string("section1", "name5", "winetest_map.ini", "value5");
+ check_profile_string("section1", "name6", "winetest_map.ini", "six");
/* Test deleting the section. */
@@ -1284,17 +1284,17 @@ static void test_registry_mapping(void)
ok(!ret, "got error %u\n", ret);
RegCloseKey(mapped_key);
- ret = WritePrivateProfileStringA("section1", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("section1", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileStringA("section1", NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA("section1", NULL, NULL, "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section1", "name1", "winetest.ini", "default");
+ check_profile_string("section1", "name1", "winetest_map.ini", "default");
- ret = WritePrivateProfileStringA("section1", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("section1", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileSectionA("section1", NULL, "winetest.ini");
+ ret = WritePrivateProfileSectionA("section1", NULL, "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section1", "name1", "winetest.ini", "default");
+ check_profile_string("section1", "name1", "winetest_map.ini", "default");
ret = RegDeleteKeyA(HKEY_CURRENT_USER, "winetest_map\\subkey");
ok(!ret, "got error %u\n", ret);
@@ -1304,44 +1304,44 @@ static void test_registry_mapping(void)
/* Test GetPrivateProfileSectionNames(). */
memset(buffer, 0xcc, sizeof(buffer));
- ret = GetPrivateProfileSectionNamesA(buffer, 5, "winetest.ini");
+ ret = GetPrivateProfileSectionNamesA(buffer, 5, "winetest_map.ini");
ok(ret == 3, "got %u\n", ret);
ok(!memcmp(buffer, "sec\0", 5), "got %s\n", debugstr_an(buffer, ret));
memset(buffer, 0xcc, sizeof(buffer));
- ret = GetPrivateProfileSectionNamesA(buffer, sizeof(buffer), "winetest.ini");
+ ret = GetPrivateProfileSectionNamesA(buffer, sizeof(buffer), "winetest_map.ini");
ok(ret == 9, "got %u\n", ret);
ok(!memcmp(buffer, "section1\0", 10), "got %s\n", debugstr_an(buffer, ret));
- ret = WritePrivateProfileStringA("file_section", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("file_section", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
memset(buffer, 0xcc, sizeof(buffer));
- ret = GetPrivateProfileSectionNamesA(buffer, 5, "winetest.ini");
+ ret = GetPrivateProfileSectionNamesA(buffer, 5, "winetest_map.ini");
ok(ret == 3, "got %u\n", ret);
ok(!memcmp(buffer, "sec\0", 5), "got %s\n", debugstr_an(buffer, ret));
memset(buffer, 0xcc, sizeof(buffer));
- ret = GetPrivateProfileSectionNamesA(buffer, sizeof(buffer), "winetest.ini");
+ ret = GetPrivateProfileSectionNamesA(buffer, sizeof(buffer), "winetest_map.ini");
ok(ret == 22, "got %u\n", ret);
ok(!memcmp(buffer, "section1\0file_section\0", 23), "got %s\n", debugstr_an(buffer, ret));
- ret = DeleteFileA("C:/windows/winetest.ini");
+ ret = DeleteFileA("C:/windows/winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
/* Test the SYS: prefix. */
ret = RegSetValueExA(mapping_key, "section2", 0, REG_SZ, (BYTE *)"SYS:winetest_map", sizeof("SYS:winetest_map"));
ok(!ret, "got error %u\n", ret);
- ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest_map.ini");
todo_wine ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section2", "name1", "winetest.ini", "default");
+ check_profile_string("section2", "name1", "winetest_map.ini", "default");
- ret = WritePrivateProfileStringA("section2", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("section2", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section2", "name1", "winetest.ini", "value1");
+ check_profile_string("section2", "name1", "winetest_map.ini", "value1");
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\winetest_map", 0, KEY_READ | KEY_WRITE, &mapped_key);
ok(!ret, "got error %u\n", ret);
@@ -1350,10 +1350,10 @@ static void test_registry_mapping(void)
ret = RegSetValueExA(mapped_key, "name2", 0, REG_SZ, (BYTE *)"value2", sizeof("value2"));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section2", "name2", "winetest.ini", "value2");
+ check_profile_string("section2", "name2", "winetest_map.ini", "value2");
- ret = GetFileAttributesA("C:/windows/winetest.ini");
- ok(ret == INVALID_FILE_ATTRIBUTES, "winetest.ini should not exist.\n");
+ ret = GetFileAttributesA("C:/windows/winetest_map.ini");
+ ok(ret == INVALID_FILE_ATTRIBUTES, "winetest_map.ini should not exist.\n");
ret = RegDeleteKeyA(mapped_key, "");
ok(!ret, "got error %u\n", ret);
@@ -1361,24 +1361,24 @@ static void test_registry_mapping(void)
/* Try writing directly to the .ini file on disk instead. */
- ret = WritePrivateProfileStringA("section3", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("section3", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section3", "name1", "winetest.ini", "value1");
+ check_profile_string("section3", "name1", "winetest_map.ini", "value1");
ret = RegSetValueExA(mapping_key, "section3", 0, REG_SZ, (BYTE *)"USR:winetest_map", sizeof("USR:winetest_map"));
ok(!ret, "got error %u\n", ret);
- ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest_map.ini");
todo_wine ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section3", "name1", "winetest.ini", "default");
+ check_profile_string("section3", "name1", "winetest_map.ini", "default");
ret = RegOpenKeyExA(HKEY_CURRENT_USER, "winetest_section3", 0, KEY_READ | KEY_WRITE, &mapped_key);
ok(ret == ERROR_FILE_NOT_FOUND, "got error %u\n", ret);
- ret = WritePrivateProfileStringA("section3", "name1", "value2", "winetest.ini");
+ ret = WritePrivateProfileStringA("section3", "name1", "value2", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section3", "name1", "winetest.ini", "value2");
+ check_profile_string("section3", "name1", "winetest_map.ini", "value2");
ret = RegOpenKeyExA(HKEY_CURRENT_USER, "winetest_map", 0, KEY_READ | KEY_WRITE, &mapped_key);
ok(!ret, "got error %u\n", ret);
@@ -1389,30 +1389,30 @@ static void test_registry_mapping(void)
ret = RegDeleteValueA(mapping_key, "section3");
ok(!ret, "got error %u\n", ret);
- ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest_map.ini");
todo_wine ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section3", "name1", "winetest.ini", "value1");
+ check_profile_string("section3", "name1", "winetest_map.ini", "value1");
- ret = DeleteFileA("C:/windows/winetest.ini");
+ ret = DeleteFileA("C:/windows/winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
/* Test default keys. */
- ret = WritePrivateProfileStringA("section4", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("section4", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section4", "name1", "winetest.ini", "value1");
+ check_profile_string("section4", "name1", "winetest_map.ini", "value1");
- ret = DeleteFileA("C:/windows/winetest.ini");
+ ret = DeleteFileA("C:/windows/winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
ret = RegSetValueExA(mapping_key, NULL, 0, REG_SZ, (BYTE *)"SYS:winetest_default", sizeof("SYS:winetest_default"));
ok(!ret, "got error %u\n", ret);
- ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest_map.ini");
todo_wine ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileStringA("section4", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("section4", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\winetest_default\\section4", 0, KEY_READ, &mapped_key);
@@ -1427,10 +1427,10 @@ static void test_registry_mapping(void)
ok(!ret, "got error %u\n", ret);
RegCloseKey(mapped_key);
- check_profile_string("section5", "name2", "winetest.ini", "value2");
+ check_profile_string("section5", "name2", "winetest_map.ini", "value2");
- ret = GetFileAttributesA("C:/windows/winetest.ini");
- ok(ret == INVALID_FILE_ATTRIBUTES, "winetest.ini should not exist.\n");
+ ret = GetFileAttributesA("C:/windows/winetest_map.ini");
+ ok(ret == INVALID_FILE_ATTRIBUTES, "winetest_map.ini should not exist.\n");
ret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\winetest_default\\Section4");
ret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\winetest_default\\Section5");
@@ -1447,12 +1447,12 @@ static void test_registry_mapping(void)
ok(!ret, "got error %u\n", ret);
ret = RegSetValueExA(mapping_subkey, "name2", 0, REG_SZ, (BYTE *)"SYS:winetest_name2", sizeof("SYS:winetest_name2"));
ok(!ret, "got error %u\n", ret);
- ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest_map.ini");
todo_wine ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileStringA("section6", "name1", "value1", "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", "name1", "value1", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section6", "name1", "winetest.ini", "value1");
+ check_profile_string("section6", "name1", "winetest_map.ini", "value1");
ret = RegOpenKeyExA(HKEY_CURRENT_USER, "winetest_name1", 0, KEY_READ | KEY_WRITE, &mapped_key);
ok(!ret, "got error %u\n", ret);
@@ -1460,13 +1460,13 @@ static void test_registry_mapping(void)
ret = RegSetValueExA(mapped_key, "name1", 0, REG_SZ, (BYTE *)"one", sizeof("one"));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section6", "name1", "winetest.ini", "one");
+ check_profile_string("section6", "name1", "winetest_map.ini", "one");
ret = RegDeleteKeyA(mapped_key, "");
ok(!ret, "got error %u\n", ret);
RegCloseKey(mapped_key);
- ret = WritePrivateProfileStringA("section6", "name2", "value2", "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", "name2", "value2", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\winetest_name2", 0, KEY_READ | KEY_WRITE, &mapped_key);
@@ -1475,31 +1475,31 @@ static void test_registry_mapping(void)
ret = RegSetValueExA(mapped_key, "name2", 0, REG_SZ, (BYTE *)"two", sizeof("two"));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section6", "name2", "winetest.ini", "two");
+ check_profile_string("section6", "name2", "winetest_map.ini", "two");
ret = RegDeleteKeyA(mapped_key, "");
ok(!ret, "got error %u\n", ret);
RegCloseKey(mapped_key);
- ret = WritePrivateProfileStringA("section6", "name3", "value3", "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", "name3", "value3", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section6", "name3", "winetest.ini", "value3");
- ret = DeleteFileA("C:/windows/winetest.ini");
+ check_profile_string("section6", "name3", "winetest_map.ini", "value3");
+ ret = DeleteFileA("C:/windows/winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
/* Test name-specific mapping with Get/WritePrivateProfileSection(). */
- ret = WritePrivateProfileStringA("section6", "name2", "value2", "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", "name2", "value2", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileStringA("section6", "name3", "value3", "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", "name3", "value3", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileSectionA("section6", "name1=one\0name3=three\0", "winetest.ini");
+ ret = WritePrivateProfileSectionA("section6", "name1=one\0name3=three\0", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section6", "name1", "winetest.ini", "one");
- check_profile_string("section6", "name2", "winetest.ini", "value2");
- check_profile_string("section6", "name3", "winetest.ini", "value3");
+ check_profile_string("section6", "name1", "winetest_map.ini", "one");
+ check_profile_string("section6", "name2", "winetest_map.ini", "value2");
+ check_profile_string("section6", "name3", "winetest_map.ini", "value3");
ret = RegOpenKeyExA(HKEY_CURRENT_USER, "winetest_name1", 0, KEY_READ | KEY_WRITE, &mapped_key);
ok(!ret, "got error %u\n", ret);
@@ -1508,38 +1508,38 @@ static void test_registry_mapping(void)
RegCloseKey(mapped_key);
memset(buffer, 0xcc, sizeof(buffer));
- ret = GetPrivateProfileSectionA("section6", buffer, 5, "winetest.ini");
+ ret = GetPrivateProfileSectionA("section6", buffer, 5, "winetest_map.ini");
ok(ret == 3, "got %u\n", ret);
ok(!memcmp(buffer, "nam\0", 5), "got %s\n", debugstr_an(buffer, ret));
memset(buffer, 0xcc, sizeof(buffer));
- ret = GetPrivateProfileSectionA("section6", buffer, sizeof(buffer), "winetest.ini");
+ ret = GetPrivateProfileSectionA("section6", buffer, sizeof(buffer), "winetest_map.ini");
ok(ret == 26, "got %u\n", ret);
ok(!memcmp(buffer, "name2=value2\0name3=value3\0", 27), "got %s\n", debugstr_an(buffer, ret));
- ret = WritePrivateProfileStringA("section6", NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", NULL, NULL, "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section6", "name1", "winetest.ini", "default");
- check_profile_string("section6", "name2", "winetest.ini", "default");
- check_profile_string("section6", "name3", "winetest.ini", "default");
+ check_profile_string("section6", "name1", "winetest_map.ini", "default");
+ check_profile_string("section6", "name2", "winetest_map.ini", "default");
+ check_profile_string("section6", "name3", "winetest_map.ini", "default");
ret = RegDeleteKeyA(HKEY_CURRENT_USER, "winetest_name1");
ok(!ret, "got error %u\n", ret);
ret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\winetest_name2");
ok(!ret, "got error %u\n", ret);
- ret = DeleteFileA("C:/windows/winetest.ini");
+ ret = DeleteFileA("C:/windows/winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
/* Test name-specific mapping with a default value. */
ret = RegSetValueExA(mapping_subkey, NULL, 0, REG_SZ, (BYTE *)"USR:winetest_default", sizeof("USR:winetest_default"));
ok(!ret, "got error %u\n", ret);
- ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA(NULL, NULL, NULL, "winetest_map.ini");
todo_wine ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileStringA("section6", "name2", "value2", "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", "name2", "value2", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- ret = WritePrivateProfileStringA("section6", "name3", "value3", "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", "name3", "value3", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
ret = RegOpenKeyExA(HKEY_CURRENT_USER, "winetest_default", 0, KEY_READ | KEY_WRITE, &mapped_key);
@@ -1548,22 +1548,22 @@ static void test_registry_mapping(void)
ret = RegSetValueExA(mapped_key, "name3", 0, REG_SZ, (BYTE *)"three", sizeof("three"));
ok(!ret, "got error %u\n", ret);
- check_profile_string("section6", "name3", "winetest.ini", "three");
+ check_profile_string("section6", "name3", "winetest_map.ini", "three");
memset(buffer, 0xcc, sizeof(buffer));
- ret = GetPrivateProfileSectionA("section6", buffer, sizeof(buffer), "winetest.ini");
+ ret = GetPrivateProfileSectionA("section6", buffer, sizeof(buffer), "winetest_map.ini");
ok(ret == 25, "got %u\n", ret);
todo_wine ok(!memcmp(buffer, "name2=value2\0name3=three\0", 26), "got %s\n", debugstr_an(buffer, ret));
- ret = WritePrivateProfileSectionA("section6", "name2=duo\0name3=treis\0", "winetest.ini");
+ ret = WritePrivateProfileSectionA("section6", "name2=duo\0name3=treis\0", "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section6", "name2", "winetest.ini", "duo");
- check_profile_string("section6", "name3", "winetest.ini", "treis");
+ check_profile_string("section6", "name2", "winetest_map.ini", "duo");
+ check_profile_string("section6", "name3", "winetest_map.ini", "treis");
- ret = WritePrivateProfileStringA("section6", NULL, NULL, "winetest.ini");
+ ret = WritePrivateProfileStringA("section6", NULL, NULL, "winetest_map.ini");
ok(ret, "got error %u\n", GetLastError());
- check_profile_string("section6", "name2", "winetest.ini", "default");
- check_profile_string("section6", "name3", "winetest.ini", "default");
+ check_profile_string("section6", "name2", "winetest_map.ini", "default");
+ check_profile_string("section6", "name3", "winetest_map.ini", "default");
ret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "Software\\winetest_name2");
ok(!ret, "got error %u\n", ret);
@@ -1581,7 +1581,7 @@ static void test_registry_mapping(void)
ok(!ret, "got error %u\n", ret);
RegCloseKey(mapping_key);
- ret = DeleteFileA("C:/windows/winetest.ini");
+ ret = DeleteFileA("C:/windows/winetest_map.ini");
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %u\n", GetLastError());
ret = RevertToSelf();
--
2.28.0
2
1
[PATCH] wbemprox: Provide semi-stub implementation for client_security_QueryBlanket().
by Paul Gofman 01 Sep '20
by Paul Gofman 01 Sep '20
01 Sep '20
Horizon Zero Dawn fails to query system memory size if CoQueryProxyBlanket()
fails for wbem services.
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/wbemprox/services.c | 20 ++++++++++++++++++--
dlls/wbemprox/tests/query.c | 7 +++++++
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/dlls/wbemprox/services.c b/dlls/wbemprox/services.c
index 3a0963e1f6c..ab7146db2d8 100644
--- a/dlls/wbemprox/services.c
+++ b/dlls/wbemprox/services.c
@@ -88,8 +88,24 @@ static HRESULT WINAPI client_security_QueryBlanket(
void **pAuthInfo,
DWORD *pCapabilities )
{
- FIXME("\n");
- return WBEM_E_FAILED;
+ FIXME("semi-stub.\n");
+
+ if (pAuthnSvc)
+ *pAuthnSvc = RPC_C_AUTHN_NONE;
+ if (pAuthzSvc)
+ *pAuthzSvc = RPC_C_AUTHZ_NONE;
+ if (pServerPrincName)
+ *pServerPrincName = NULL;
+ if (pAuthnLevel)
+ *pAuthnLevel = RPC_C_AUTHN_LEVEL_NONE;
+ if (pImpLevel)
+ *pImpLevel = RPC_C_IMP_LEVEL_DEFAULT;
+ if (pAuthInfo)
+ *pAuthInfo = NULL;
+ if (pCapabilities)
+ *pCapabilities = 0;
+
+ return WBEM_NO_ERROR;
}
static HRESULT WINAPI client_security_SetBlanket(
diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c
index 17942cd89ae..74fdfaa9bc8 100644
--- a/dlls/wbemprox/tests/query.c
+++ b/dlls/wbemprox/tests/query.c
@@ -1713,6 +1713,7 @@ START_TEST(query)
BSTR path = SysAllocString( L"ROOT\\CIMV2" );
IWbemLocator *locator;
IWbemServices *services;
+ DWORD authn_svc;
HRESULT hr;
CoInitialize( NULL );
@@ -1728,6 +1729,12 @@ START_TEST(query)
hr = IWbemLocator_ConnectServer( locator, path, NULL, NULL, NULL, 0, NULL, NULL, &services );
ok( hr == S_OK, "failed to get IWbemServices interface %08x\n", hr );
+ hr = CoQueryProxyBlanket( (IUnknown *)services, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
+ ok( hr == S_OK, "failed to query proxy blanket %08x\n", hr );
+
+ hr = CoQueryProxyBlanket( (IUnknown *)services, &authn_svc, NULL, NULL, NULL, NULL, NULL, NULL );
+ ok( hr == S_OK, "failed to query proxy blanket %08x\n", hr );
+
hr = CoSetProxyBlanket( (IUnknown *)services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
ok( hr == S_OK, "failed to set proxy blanket %08x\n", hr );
--
2.26.2
2
1
[PATCH] user32: Always wait for the desktop process to be ready in load_desktop_driver().
by Zhiyi Zhang 01 Sep '20
by Zhiyi Zhang 01 Sep '20
01 Sep '20
Having a __wine_display_device_guid property in the desktop window only guarantees that the window
is created. Explorer.exe still has to finish setting up virtual desktop, display settings etc.
load_desktop_driver() needs to make sure that the desktop initialization is done before allowing
applications to call user32 driver functions. Otherwise, they might get incorrect data. This race
condition became apparent after aadae4d1ea173dfa30e09d6cc816bb174e35f90d, which adds ~100ms to the
initialization process.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49762
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/driver.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 6d916c7d65d..abd8a34cceb 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -59,17 +59,14 @@ static BOOL load_desktop_driver( HWND hwnd, HMODULE *module )
DWORD size;
WCHAR path[MAX_PATH];
WCHAR key[ARRAY_SIZE(key_pathW) + ARRAY_SIZE(displayW) + 40];
- UINT guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW ));
+ UINT guid_atom;
USER_CheckNotLock();
strcpy( driver_load_error, "The explorer process failed to start." ); /* default error */
+ SendMessageW( hwnd, WM_NULL, 0, 0 ); /* wait for the desktop process to be ready */
- if (!guid_atom)
- {
- SendMessageW( hwnd, WM_NULL, 0, 0 ); /* wait for the desktop process to be ready */
- guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW ));
- }
+ guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW ));
memcpy( key, key_pathW, sizeof(key_pathW) );
if (!GlobalGetAtomNameW( guid_atom, key + strlenW(key), 40 )) return 0;
strcatW( key, displayW );
--
2.25.1
2
1