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@codeweavers.com ---
v2: * use correct mangled symbols in the comment on top of setmode * set p_ifstream_dtor and p_ifstream_vbase_dtor in win32 path
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..df2d7dcffad 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@XZ */ /* ??1istrstream@@UAE@XZ */ /* ??1istrstream@@UEAA@XZ */ +/* ??1ifstream@@UAE@XZ */ +/* ??1ifstream@@UEAA@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@ABV0@@Z */ /* ??4istrstream@@QEAAAEAV0@AEBV0@@Z */ +/* ??4ifstream@@QAEAAV0@ABV0@@Z */ +/* ??4ifstream@@QEAAAEAV0@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@Z */ /* ??_Eistream_withassign@@UAEPAXI@Z */ /* ??_Eistrstream@@UAEPAXI@Z */ +/* ??_Eifstream@@UAEPAXI@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@Z */ /* ??_Gistream_withassign@@UAEPAXI@Z */ /* ??_Gistrstream@@UAEPAXI@Z */ +/* ??_Gifstream@@UAEPAXI@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@ABV0@@Z */ +/* ??0ifstream@@QEAA@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@HPADH@Z */ +/* ??0ifstream@@QEAA@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@H@Z */ +/* ??0ifstream@@QEAA@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@PBDHH@Z */ +/* ??0ifstream@@QEAA@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@XZ */ +/* ??0ifstream@@QEAA@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@ifstream@@QBEPAVfilebuf@@XZ */ +/* ?rdbuf@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@ifstream@@QBEHXZ */ +/* ?fd@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@ifstream@@QAEXH@Z */ +/* ?attach@ifstream@@QEAAXH@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@ifstream@@QAEXXZ */ +/* ?close@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@ifstream@@QBEHXZ */ +/* ?is_open@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@ifstream@@QAEXPBDHH@Z */ +/* ?open@ifstream@@QEAAXPEBDHH@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@ifstream@@QAEPAVstreambuf@@PADH@Z */ +/* ?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@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; +} + +/* ?setmode@ifstream@@QAEHH@Z */ +/* ?setmode@ifstream@@QEAAHH@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@PEBDHH@Z @ stub -arch=win32 ??0fstream@@QAE@XZ # __thiscall fstream::fstream(void) @ stub -arch=win64 ??0fstream@@QEAA@XZ -@ stub -arch=win32 ??0ifstream@@QAE@ABV0@@Z # __thiscall ifstream::ifstream(class ifstream const &) -@ stub -arch=win64 ??0ifstream@@QEAA@AEBV0@@Z -@ stub -arch=win32 ??0ifstream@@QAE@H@Z # __thiscall ifstream::ifstream(int) -@ stub -arch=win64 ??0ifstream@@QEAA@H@Z -@ stub -arch=win32 ??0ifstream@@QAE@HPADH@Z # __thiscall ifstream::ifstream(int,char *,int) -@ stub -arch=win64 ??0ifstream@@QEAA@HPEADH@Z -@ stub -arch=win32 ??0ifstream@@QAE@PBDHH@Z # __thiscall ifstream::ifstream(char const *,int,int) -@ stub -arch=win64 ??0ifstream@@QEAA@PEBDHH@Z -@ stub -arch=win32 ??0ifstream@@QAE@XZ # __thiscall ifstream::ifstream(void) -@ stub -arch=win64 ??0ifstream@@QEAA@XZ +@ thiscall -arch=win32 ??0ifstream@@QAE@ABV0@@Z(ptr ptr long) ifstream_copy_ctor +@ cdecl -arch=win64 ??0ifstream@@QEAA@AEBV0@@Z(ptr ptr long) ifstream_copy_ctor +@ thiscall -arch=win32 ??0ifstream@@QAE@H@Z(ptr long long) ifstream_fd_ctor +@ cdecl -arch=win64 ??0ifstream@@QEAA@H@Z(ptr long long) ifstream_fd_ctor +@ thiscall -arch=win32 ??0ifstream@@QAE@HPADH@Z(ptr long ptr long long) ifstream_buffer_ctor +@ cdecl -arch=win64 ??0ifstream@@QEAA@HPEADH@Z(ptr long ptr long long) ifstream_buffer_ctor +@ thiscall -arch=win32 ??0ifstream@@QAE@PBDHH@Z(ptr str long long long) ifstream_open_ctor +@ cdecl -arch=win64 ??0ifstream@@QEAA@PEBDHH@Z(ptr str long long long) ifstream_open_ctor +@ thiscall -arch=win32 ??0ifstream@@QAE@XZ(ptr long) ifstream_ctor +@ cdecl -arch=win64 ??0ifstream@@QEAA@XZ(ptr long) ifstream_ctor @ thiscall -arch=win32 ??0ios@@IAE@ABV0@@Z(ptr ptr) ios_copy_ctor @ cdecl -arch=win64 ??0ios@@IEAA@AEBV0@@Z(ptr ptr) ios_copy_ctor @ thiscall -arch=win32 ??0ios@@IAE@XZ(ptr) ios_ctor @@ -138,8 +138,8 @@ @ cdecl -arch=win64 ??1filebuf@@UEAA@XZ(ptr) filebuf_dtor @ stub -arch=win32 ??1fstream@@UAE@XZ # virtual __thiscall fstream::~fstream(void) @ stub -arch=win64 ??1fstream@@UEAA@XZ -@ stub -arch=win32 ??1ifstream@@UAE@XZ # virtual __thiscall ifstream::~ifstream(void) -@ stub -arch=win64 ??1ifstream@@UEAA@XZ +@ thiscall -arch=win32 ??1ifstream@@UAE@XZ(ptr) istream_dtor +@ cdecl -arch=win64 ??1ifstream@@UEAA@XZ(ptr) istream_dtor @ thiscall -arch=win32 ??1ios@@UAE@XZ(ptr) ios_dtor @ cdecl -arch=win64 ??1ios@@UEAA@XZ(ptr) ios_dtor @ thiscall -arch=win32 ??1iostream@@UAE@XZ(ptr) iostream_dtor @@ -178,8 +178,8 @@ @ cdecl -arch=win64 ??4filebuf@@QEAAAEAV0@AEBV0@@Z(ptr ptr) filebuf_assign @ stub -arch=win32 ??4fstream@@QAEAAV0@AAV0@@Z # class fstream & __thiscall fstream::operator=(class fstream &) @ stub -arch=win64 ??4fstream@@QEAAAEAV0@AEAV0@@Z -@ stub -arch=win32 ??4ifstream@@QAEAAV0@ABV0@@Z # class ifstream & __thiscall ifstream::operator=(class ifstream const &) -@ stub -arch=win64 ??4ifstream@@QEAAAEAV0@AEBV0@@Z +@ thiscall -arch=win32 ??4ifstream@@QAEAAV0@ABV0@@Z(ptr ptr) istream_assign +@ cdecl -arch=win64 ??4ifstream@@QEAAAEAV0@AEBV0@@Z(ptr ptr) istream_assign @ thiscall -arch=win32 ??4ios@@IAEAAV0@ABV0@@Z(ptr ptr) ios_assign @ cdecl -arch=win64 ??4ios@@IEAAAEAV0@AEBV0@@Z(ptr ptr) ios_assign @ thiscall -arch=win32 ??4iostream@@IAEAAV0@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@Z(ptr long) MSVCP_exception_vector_dtor @ thiscall -arch=win32 ??_Efilebuf@@UAEPAXI@Z(ptr long) filebuf_vector_dtor @ stub -arch=win32 ??_Efstream@@UAEPAXI@Z # virtual void * __thiscall fstream::`vector deleting destructor'(unsigned int) -@ stub -arch=win32 ??_Eifstream@@UAEPAXI@Z # virtual void * __thiscall ifstream::`vector deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Eifstream@@UAEPAXI@Z(ptr long) istream_vector_dtor @ thiscall -arch=win32 ??_Eios@@UAEPAXI@Z(ptr long) ios_vector_dtor @ thiscall -arch=win32 ??_Eiostream@@UAEPAXI@Z(ptr long) iostream_vector_dtor @ thiscall -arch=win32 ??_Eistream@@UAEPAXI@Z(ptr long) istream_vector_dtor @@ -383,7 +383,7 @@ @ thiscall -arch=win32 ??_Gexception@@UAEPAXI@Z(ptr long) MSVCP_exception_scalar_dtor @ thiscall -arch=win32 ??_Gfilebuf@@UAEPAXI@Z(ptr long) filebuf_scalar_dtor @ stub -arch=win32 ??_Gfstream@@UAEPAXI@Z # virtual void * __thiscall fstream::`scalar deleting destructor'(unsigned int) -@ stub -arch=win32 ??_Gifstream@@UAEPAXI@Z # virtual void * __thiscall ifstream::`scalar deleting destructor'(unsigned int) +@ thiscall -arch=win32 ??_Gifstream@@UAEPAXI@Z(ptr long) istream_scalar_dtor @ thiscall -arch=win32 ??_Gios@@UAEPAXI@Z(ptr long) ios_scalar_dtor @ thiscall -arch=win32 ??_Giostream@@UAEPAXI@Z(ptr long) iostream_scalar_dtor @ thiscall -arch=win32 ??_Gistream@@UAEPAXI@Z(ptr long) istream_scalar_dtor @@ -406,8 +406,8 @@ @ cdecl -arch=win64 ?attach@filebuf@@QEAAPEAV1@H@Z(ptr long) filebuf_attach @ stub -arch=win32 ?attach@fstream@@QAEXH@Z # void __thiscall fstream::attach(int) @ stub -arch=win64 ?attach@fstream@@QEAAXH@Z -@ stub -arch=win32 ?attach@ifstream@@QAEXH@Z # void __thiscall ifstream::attach(int) -@ stub -arch=win64 ?attach@ifstream@@QEAAXH@Z +@ thiscall -arch=win32 ?attach@ifstream@@QAEXH@Z(ptr long) ifstream_attach +@ cdecl -arch=win64 ?attach@ifstream@@QEAAXH@Z(ptr long) ifstream_attach @ stub -arch=win32 ?attach@ofstream@@QAEXH@Z # void __thiscall ofstream::attach(int) @ stub -arch=win64 ?attach@ofstream@@QEAAXH@Z @ thiscall -arch=win32 ?bad@ios@@QBEHXZ(ptr) ios_bad @@ -428,8 +428,8 @@ @ cdecl -arch=win64 ?close@filebuf@@QEAAPEAV1@XZ(ptr) filebuf_close @ stub -arch=win32 ?close@fstream@@QAEXXZ # void __thiscall fstream::close(void) @ stub -arch=win64 ?close@fstream@@QEAAXXZ -@ stub -arch=win32 ?close@ifstream@@QAEXXZ # void __thiscall ifstream::close(void) -@ stub -arch=win64 ?close@ifstream@@QEAAXXZ +@ thiscall -arch=win32 ?close@ifstream@@QAEXXZ(ptr) ifstream_close +@ cdecl -arch=win64 ?close@ifstream@@QEAAXXZ(ptr) ifstream_close @ stub -arch=win32 ?close@ofstream@@QAEXXZ # void __thiscall ofstream::close(void) @ stub -arch=win64 ?close@ofstream@@QEAAXXZ @ cdecl -arch=win32 ?clrlock@ios@@QAAXXZ(ptr) ios_clrlock @@ -472,8 +472,8 @@ @ cdecl -arch=win64 ?fd@filebuf@@QEBAHXZ(ptr) filebuf_fd @ stub -arch=win32 ?fd@fstream@@QBEHXZ # int __thiscall fstream::fd(void)const @ stub -arch=win64 ?fd@fstream@@QEBAHXZ -@ stub -arch=win32 ?fd@ifstream@@QBEHXZ # int __thiscall ifstream::fd(void)const -@ stub -arch=win64 ?fd@ifstream@@QEBAHXZ +@ thiscall -arch=win32 ?fd@ifstream@@QBEHXZ(ptr) ifstream_fd +@ cdecl -arch=win64 ?fd@ifstream@@QEBAHXZ(ptr) ifstream_fd @ stub -arch=win32 ?fd@ofstream@@QBEHXZ # int __thiscall ofstream::fd(void)const @ stub -arch=win64 ?fd@ofstream@@QEBAHXZ @ thiscall -arch=win32 ?fill@ios@@QAEDD@Z(ptr long) ios_fill_set @@ -541,8 +541,8 @@ @ cdecl -arch=win64 ?is_open@filebuf@@QEBAHXZ(ptr) filebuf_is_open @ stub -arch=win32 ?is_open@fstream@@QBEHXZ # int __thiscall fstream::is_open(void)const @ stub -arch=win64 ?is_open@fstream@@QEBAHXZ -@ stub -arch=win32 ?is_open@ifstream@@QBEHXZ # int __thiscall ifstream::is_open(void)const -@ stub -arch=win64 ?is_open@ifstream@@QEBAHXZ +@ thiscall -arch=win32 ?is_open@ifstream@@QBEHXZ(ptr) ifstream_is_open +@ cdecl -arch=win64 ?is_open@ifstream@@QEBAHXZ(ptr) ifstream_is_open @ stub -arch=win32 ?is_open@ofstream@@QBEHXZ # int __thiscall ofstream::is_open(void)const @ stub -arch=win64 ?is_open@ofstream@@QEBAHXZ @ thiscall -arch=win32 ?isfx@istream@@QAEXXZ(ptr) istream_isfx @@ -566,8 +566,8 @@ @ cdecl -arch=win64 ?open@filebuf@@QEAAPEAV1@PEBDHH@Z(ptr str long long) filebuf_open @ stub -arch=win32 ?open@fstream@@QAEXPBDHH@Z # void __thiscall fstream::open(char const *,int,int) @ stub -arch=win64 ?open@fstream@@QEAAXPEBDHH@Z -@ stub -arch=win32 ?open@ifstream@@QAEXPBDHH@Z # void __thiscall ifstream::open(char const *,int,int) -@ stub -arch=win64 ?open@ifstream@@QEAAXPEBDHH@Z +@ thiscall -arch=win32 ?open@ifstream@@QAEXPBDHH@Z(ptr str long long) ifstream_open +@ cdecl -arch=win64 ?open@ifstream@@QEAAXPEBDHH@Z(ptr str long long) ifstream_open @ stub -arch=win32 ?open@ofstream@@QAEXPBDHH@Z # void __thiscall ofstream::open(char const *,int,int) @ stub -arch=win64 ?open@ofstream@@QEAAXPEBDHH@Z @ extern ?openprot@filebuf@@2HB filebuf_openprot @@ -615,8 +615,8 @@ @ cdecl -arch=win64 ?pword@ios@@QEBAAEAPEAXH@Z(ptr long) ios_pword @ stub -arch=win32 ?rdbuf@fstream@@QBEPAVfilebuf@@XZ # class filebuf * __thiscall fstream::rdbuf(void)const @ stub -arch=win64 ?rdbuf@fstream@@QEBAPEAVfilebuf@@XZ -@ stub -arch=win32 ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ # class filebuf * __thiscall ifstream::rdbuf(void)const -@ stub -arch=win64 ?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ +@ thiscall -arch=win32 ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ(ptr) ifstream_rdbuf +@ cdecl -arch=win64 ?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ(ptr) ifstream_rdbuf @ thiscall -arch=win32 ?rdbuf@ios@@QBEPAVstreambuf@@XZ(ptr) ios_rdbuf @ cdecl -arch=win64 ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ(ptr) ios_rdbuf @ thiscall -arch=win32 ?rdbuf@istrstream@@QBEPAVstrstreambuf@@XZ(ptr) istrstream_rdbuf @@ -663,8 +663,8 @@ @ cdecl -arch=win64 ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z(ptr ptr long) filebuf_setbuf @ stub -arch=win32 ?setbuf@fstream@@QAEPAVstreambuf@@PADH@Z # class streambuf * __thiscall fstream::setbuf(char *,int) @ stub -arch=win64 ?setbuf@fstream@@QEAAPEAVstreambuf@@PEADH@Z -@ stub -arch=win32 ?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z # class streambuf * __thiscall ifstream::setbuf(char *,int) -@ stub -arch=win64 ?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z +@ thiscall -arch=win32 ?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z(ptr ptr long) ifstream_setbuf +@ cdecl -arch=win64 ?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z(ptr ptr long) ifstream_setbuf @ stub -arch=win32 ?setbuf@ofstream@@QAEPAVstreambuf@@PADH@Z # class streambuf * __thiscall ofstream::setbuf(char *,int) @ stub -arch=win64 ?setbuf@ofstream@@QEAAPEAVstreambuf@@PEADH@Z @ thiscall -arch=win32 ?setbuf@streambuf@@UAEPAV1@PADH@Z(ptr ptr long) streambuf_setbuf @@ -685,8 +685,8 @@ @ cdecl -arch=win64 ?setmode@filebuf@@QEAAHH@Z(ptr long) filebuf_setmode @ stub -arch=win32 ?setmode@fstream@@QAEHH@Z # int __thiscall fstream::setmode(int) @ stub -arch=win64 ?setmode@fstream@@QEAAHH@Z -@ stub -arch=win32 ?setmode@ifstream@@QAEHH@Z # int __thiscall ifstream::setmode(int) -@ stub -arch=win64 ?setmode@ifstream@@QEAAHH@Z +@ thiscall -arch=win32 ?setmode@ifstream@@QAEHH@Z(ptr long) ifstream_setmode +@ cdecl -arch=win64 ?setmode@ifstream@@QEAAHH@Z(ptr long) ifstream_setmode @ stub -arch=win32 ?setmode@ofstream@@QAEHH@Z # int __thiscall ofstream::setmode(int) @ stub -arch=win64 ?setmode@ofstream@@QEAAHH@Z @ thiscall -arch=win32 ?setp@streambuf@@IAEXPAD0@Z(ptr ptr ptr) streambuf_setp diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 6440bc0dab7..fa1f001d6cd 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@PEAVstreambuf@@@Z"); SET(p_iostream_assign, "??4iostream@@IEAAAEAV0@AEAV0@@Z");
+ SET(p_ifstream_copy_ctor, "??0ifstream@@QEAA@AEBV0@@Z"); + SET(p_ifstream_buffer_ctor, "??0ifstream@@QEAA@HPEADH@Z"); + SET(p_ifstream_fd_ctor, "??0ifstream@@QEAA@H@Z"); + SET(p_ifstream_open_ctor, "??0ifstream@@QEAA@PEBDHH@Z"); + SET(p_ifstream_ctor, "??0ifstream@@QEAA@XZ"); + SET(p_ifstream_dtor, "??1ifstream@@UEAA@XZ"); + SET(p_ifstream_vbase_dtor, "??_Difstream@@QEAAXXZ"); + SET(p_ifstream_attach, "?attach@ifstream@@QEAAXH@Z"); + SET(p_ifstream_close, "?close@ifstream@@QEAAXXZ"); + SET(p_ifstream_fd, "?fd@ifstream@@QEBAHXZ"); + SET(p_ifstream_is_open, "?is_open@ifstream@@QEBAHXZ"); + SET(p_ifstream_open, "?open@ifstream@@QEAAXPEBDHH@Z"); + SET(p_ifstream_rdbuf, "?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ"); + SET(p_ifstream_setbuf, "?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z"); + SET(p_ifstream_setmode, "?setmode@ifstream@@QEAAHH@Z"); + SET(p_strstream_copy_ctor, "??0strstream@@QEAA@AEBV0@@Z"); SET(p_strstream_buffer_ctor, "??0strstream@@QEAA@PEADHH@Z"); SET(p_strstream_ctor, "??0strstream@@QEAA@XZ"); @@ -917,6 +951,22 @@ static BOOL init(void) SET(p_iostream_assign_sb, "??4iostream@@IAEAAV0@PAVstreambuf@@@Z"); SET(p_iostream_assign, "??4iostream@@IAEAAV0@AAV0@@Z");
+ SET(p_ifstream_copy_ctor, "??0ifstream@@QAE@ABV0@@Z"); + SET(p_ifstream_fd_ctor, "??0ifstream@@QAE@H@Z"); + SET(p_ifstream_buffer_ctor, "??0ifstream@@QAE@HPADH@Z"); + SET(p_ifstream_open_ctor, "??0ifstream@@QAE@PBDHH@Z"); + SET(p_ifstream_ctor, "??0ifstream@@QAE@XZ"); + SET(p_ifstream_dtor, "??1ifstream@@UAE@XZ"); + SET(p_ifstream_vbase_dtor, "??_Difstream@@QAEXXZ"); + SET(p_ifstream_attach, "?attach@ifstream@@QAEXH@Z"); + SET(p_ifstream_close, "?close@ifstream@@QAEXXZ"); + SET(p_ifstream_fd, "?fd@ifstream@@QBEHXZ"); + SET(p_ifstream_is_open, "?is_open@ifstream@@QBEHXZ"); + SET(p_ifstream_open, "?open@ifstream@@QAEXPBDHH@Z"); + SET(p_ifstream_rdbuf, "?rdbuf@ifstream@@QBEPAVfilebuf@@XZ"); + SET(p_ifstream_setbuf, "?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z"); + SET(p_ifstream_setmode, "?setmode@ifstream@@QAEHH@Z"); + SET(p_strstream_copy_ctor, "??0strstream@@QAE@ABV0@@Z"); SET(p_strstream_buffer_ctor, "??0strstream@@QAE@PADHH@Z"); SET(p_strstream_ctor, "??0strstream@@QAE@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@PEBDHH@Z @ stub -arch=win32 ??0fstream@@QAE@XZ @ stub -arch=win64 ??0fstream@@QEAA@XZ -@ stub -arch=win32 ??0ifstream@@QAE@ABV0@@Z -@ stub -arch=win64 ??0ifstream@@QEAA@AEBV0@@Z -@ stub -arch=win32 ??0ifstream@@QAE@H@Z -@ stub -arch=win64 ??0ifstream@@QEAA@H@Z -@ stub -arch=win32 ??0ifstream@@QAE@HPADH@Z -@ stub -arch=win64 ??0ifstream@@QEAA@HPEADH@Z -@ stub -arch=win32 ??0ifstream@@QAE@PBDHH@Z -@ stub -arch=win64 ??0ifstream@@QEAA@PEBDHH@Z -@ stub -arch=win32 ??0ifstream@@QAE@XZ -@ stub -arch=win64 ??0ifstream@@QEAA@XZ +@ thiscall -arch=win32 ??0ifstream@@QAE@ABV0@@Z(ptr ptr long) msvcirt.??0ifstream@@QAE@ABV0@@Z +@ cdecl -arch=win64 ??0ifstream@@QEAA@AEBV0@@Z(ptr ptr long) msvcirt.??0ifstream@@QEAA@AEBV0@@Z +@ thiscall -arch=win32 ??0ifstream@@QAE@H@Z(ptr long long) msvcirt.??0ifstream@@QAE@H@Z +@ cdecl -arch=win64 ??0ifstream@@QEAA@H@Z(ptr long long) msvcirt.??0ifstream@@QEAA@H@Z +@ thiscall -arch=win32 ??0ifstream@@QAE@HPADH@Z(ptr long ptr long long) msvcirt.??0ifstream@@QAE@HPADH@Z +@ cdecl -arch=win64 ??0ifstream@@QEAA@HPEADH@Z(ptr long ptr long long) msvcirt.??0ifstream@@QEAA@HPEADH@Z +@ thiscall -arch=win32 ??0ifstream@@QAE@PBDHH@Z(ptr str long long long) msvcirt.??0ifstream@@QAE@PBDHH@Z +@ cdecl -arch=win64 ??0ifstream@@QEAA@PEBDHH@Z(ptr str long long long) msvcirt.??0ifstream@@QEAA@PEBDHH@Z +@ thiscall -arch=win32 ??0ifstream@@QAE@XZ(ptr long) msvcirt.??0ifstream@@QAE@XZ +@ cdecl -arch=win64 ??0ifstream@@QEAA@XZ(ptr long) msvcirt.??0ifstream@@QEAA@XZ @ thiscall -arch=win32 ??0ios@@IAE@ABV0@@Z(ptr ptr) msvcirt.??0ios@@IAE@ABV0@@Z @ cdecl -arch=win64 ??0ios@@IEAA@AEBV0@@Z(ptr ptr) msvcirt.??0ios@@IEAA@AEBV0@@Z @ thiscall -arch=win32 ??0ios@@IAE@XZ(ptr) msvcirt.??0ios@@IAE@XZ @@ -124,8 +124,8 @@ @ cdecl -arch=win64 ??1filebuf@@UEAA@XZ(ptr) msvcirt.??1filebuf@@UEAA@XZ @ stub -arch=win32 ??1fstream@@UAE@XZ @ stub -arch=win64 ??1fstream@@UEAA@XZ -@ stub -arch=win32 ??1ifstream@@UAE@XZ -@ stub -arch=win64 ??1ifstream@@UEAA@XZ +@ thiscall -arch=win32 ??1ifstream@@UAE@XZ(ptr) msvcirt.??1ifstream@@UAE@XZ +@ cdecl -arch=win64 ??1ifstream@@UEAA@XZ(ptr) msvcirt.??1ifstream@@UEAA@XZ @ thiscall -arch=win32 ??1ios@@UAE@XZ(ptr) msvcirt.??1ios@@UAE@XZ @ cdecl -arch=win64 ??1ios@@UEAA@XZ(ptr) msvcirt.??1ios@@UEAA@XZ @ thiscall -arch=win32 ??1iostream@@UAE@XZ(ptr) msvcirt.??1iostream@@UAE@XZ @@ -164,8 +164,8 @@ @ cdecl -arch=win64 ??4filebuf@@QEAAAEAV0@AEBV0@@Z(ptr ptr) msvcirt.??4filebuf@@QEAAAEAV0@AEBV0@@Z @ stub -arch=win32 ??4fstream@@QAEAAV0@AAV0@@Z @ stub -arch=win64 ??4fstream@@QEAAAEAV0@AEAV0@@Z -@ stub -arch=win32 ??4ifstream@@QAEAAV0@ABV0@@Z -@ stub -arch=win64 ??4ifstream@@QEAAAEAV0@AEBV0@@Z +@ thiscall -arch=win32 ??4ifstream@@QAEAAV0@ABV0@@Z(ptr ptr) msvcirt.??4ifstream@@QAEAAV0@ABV0@@Z +@ cdecl -arch=win64 ??4ifstream@@QEAAAEAV0@AEBV0@@Z(ptr ptr) msvcirt.??4ifstream@@QEAAAEAV0@AEBV0@@Z @ thiscall -arch=win32 ??4ios@@IAEAAV0@ABV0@@Z(ptr ptr) msvcirt.??4ios@@IAEAAV0@ABV0@@Z @ cdecl -arch=win64 ??4ios@@IEAAAEAV0@AEBV0@@Z(ptr ptr) msvcirt.??4ios@@IEAAAEAV0@AEBV0@@Z @ thiscall -arch=win32 ??4iostream@@IAEAAV0@AAV0@@Z(ptr ptr) msvcirt.??4iostream@@IAEAAV0@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@Z @ thiscall -arch=win32 ??_Efilebuf@@UAEPAXI@Z(ptr long) msvcirt.??_Efilebuf@@UAEPAXI@Z @ stub -arch=win32 ??_Efstream@@UAEPAXI@Z -@ stub -arch=win32 ??_Eifstream@@UAEPAXI@Z +@ thiscall -arch=win32 ??_Eifstream@@UAEPAXI@Z(ptr long) msvcirt.??_Eifstream@@UAEPAXI@Z @ thiscall -arch=win32 ??_Eios@@UAEPAXI@Z(ptr long) msvcirt.??_Eios@@UAEPAXI@Z @ thiscall -arch=win32 ??_Eiostream@@UAEPAXI@Z(ptr long) msvcirt.??_Eiostream@@UAEPAXI@Z @ thiscall -arch=win32 ??_Eistream@@UAEPAXI@Z(ptr long) msvcirt.??_Eistream@@UAEPAXI@Z @@ -364,7 +364,7 @@ @ stub -arch=win32 ??_GIostream_init@@QAEPAXI@Z @ thiscall -arch=win32 ??_Gfilebuf@@UAEPAXI@Z(ptr long) msvcirt.??_Gfilebuf@@UAEPAXI@Z @ stub -arch=win32 ??_Gfstream@@UAEPAXI@Z -@ stub -arch=win32 ??_Gifstream@@UAEPAXI@Z +@ thiscall -arch=win32 ??_Gifstream@@UAEPAXI@Z(ptr long) msvcirt.??_Gifstream@@UAEPAXI@Z @ thiscall -arch=win32 ??_Gios@@UAEPAXI@Z(ptr long) msvcirt.??_Gios@@UAEPAXI@Z @ thiscall -arch=win32 ??_Giostream@@UAEPAXI@Z(ptr long) msvcirt.??_Giostream@@UAEPAXI@Z @ thiscall -arch=win32 ??_Gistream@@UAEPAXI@Z(ptr long) msvcirt.??_Gistream@@UAEPAXI@Z @@ -394,8 +394,8 @@ @ cdecl -arch=win64 ?attach@filebuf@@QEAAPEAV1@H@Z(ptr long) msvcirt.?attach@filebuf@@QEAAPEAV1@H@Z @ stub -arch=win32 ?attach@fstream@@QAEXH@Z @ stub -arch=win64 ?attach@fstream@@QEAAXH@Z -@ stub -arch=win32 ?attach@ifstream@@QAEXH@Z -@ stub -arch=win64 ?attach@ifstream@@QEAAXH@Z +@ thiscall -arch=win32 ?attach@ifstream@@QAEXH@Z(ptr long) msvcirt.?attach@ifstream@@QAEXH@Z +@ cdecl -arch=win64 ?attach@ifstream@@QEAAXH@Z(ptr long) msvcirt.?attach@ifstream@@QEAAXH@Z @ stub -arch=win32 ?attach@ofstream@@QAEXH@Z @ stub -arch=win64 ?attach@ofstream@@QEAAXH@Z @ thiscall -arch=win32 ?bad@ios@@QBEHXZ(ptr) msvcirt.?bad@ios@@QBEHXZ @@ -416,8 +416,8 @@ @ cdecl -arch=win64 ?close@filebuf@@QEAAPEAV1@XZ(ptr) msvcirt.?close@filebuf@@QEAAPEAV1@XZ @ stub -arch=win32 ?close@fstream@@QAEXXZ @ stub -arch=win64 ?close@fstream@@QEAAXXZ -@ stub -arch=win32 ?close@ifstream@@QAEXXZ -@ stub -arch=win64 ?close@ifstream@@QEAAXXZ +@ thiscall -arch=win32 ?close@ifstream@@QAEXXZ(ptr) msvcirt.?close@ifstream@@QAEXXZ +@ cdecl -arch=win64 ?close@ifstream@@QEAAXXZ(ptr) msvcirt.?close@ifstream@@QEAAXXZ @ stub -arch=win32 ?close@ofstream@@QAEXXZ @ stub -arch=win64 ?close@ofstream@@QEAAXXZ @ cdecl -arch=win32 ?clrlock@ios@@QAAXXZ(ptr) msvcirt.?clrlock@ios@@QAAXXZ @@ -460,8 +460,8 @@ @ cdecl -arch=win64 ?fd@filebuf@@QEBAHXZ(ptr) msvcirt.?fd@filebuf@@QEBAHXZ @ stub -arch=win32 ?fd@fstream@@QBEHXZ @ stub -arch=win64 ?fd@fstream@@QEBAHXZ -@ stub -arch=win32 ?fd@ifstream@@QBEHXZ -@ stub -arch=win64 ?fd@ifstream@@QEBAHXZ +@ thiscall -arch=win32 ?fd@ifstream@@QBEHXZ(ptr) msvcirt.?fd@ifstream@@QBEHXZ +@ cdecl -arch=win64 ?fd@ifstream@@QEBAHXZ(ptr) msvcirt.?fd@ifstream@@QEBAHXZ @ stub -arch=win32 ?fd@ofstream@@QBEHXZ @ stub -arch=win64 ?fd@ofstream@@QEBAHXZ @ thiscall -arch=win32 ?fill@ios@@QAEDD@Z(ptr long) msvcirt.?fill@ios@@QAEDD@Z @@ -527,8 +527,8 @@ @ cdecl -arch=win64 ?is_open@filebuf@@QEBAHXZ(ptr) msvcirt.?is_open@filebuf@@QEBAHXZ @ stub -arch=win32 ?is_open@fstream@@QBEHXZ @ stub -arch=win64 ?is_open@fstream@@QEBAHXZ -@ stub -arch=win32 ?is_open@ifstream@@QBEHXZ -@ stub -arch=win64 ?is_open@ifstream@@QEBAHXZ +@ thiscall -arch=win32 ?is_open@ifstream@@QBEHXZ(ptr) msvcirt.?is_open@ifstream@@QBEHXZ +@ cdecl -arch=win64 ?is_open@ifstream@@QEBAHXZ(ptr) msvcirt.?is_open@ifstream@@QEBAHXZ @ stub -arch=win32 ?is_open@ofstream@@QBEHXZ @ stub -arch=win64 ?is_open@ofstream@@QEBAHXZ @ thiscall -arch=win32 ?isfx@istream@@QAEXXZ(ptr) msvcirt.?isfx@istream@@QAEXXZ @@ -552,8 +552,8 @@ @ cdecl -arch=win64 ?open@filebuf@@QEAAPEAV1@PEBDHH@Z(ptr str long long) msvcirt.?open@filebuf@@QEAAPEAV1@PEBDHH@Z @ stub -arch=win32 ?open@fstream@@QAEXPBDHH@Z @ stub -arch=win64 ?open@fstream@@QEAAXPEBDHH@Z -@ stub -arch=win32 ?open@ifstream@@QAEXPBDHH@Z -@ stub -arch=win64 ?open@ifstream@@QEAAXPEBDHH@Z +@ thiscall -arch=win32 ?open@ifstream@@QAEXPBDHH@Z(ptr str long long) msvcirt.?open@ifstream@@QAEXPBDHH@Z +@ cdecl -arch=win64 ?open@ifstream@@QEAAXPEBDHH@Z(ptr str long long) msvcirt.?open@ifstream@@QEAAXPEBDHH@Z @ stub -arch=win32 ?open@ofstream@@QAEXPBDHH@Z @ stub -arch=win64 ?open@ofstream@@QEAAXPEBDHH@Z @ extern ?openprot@filebuf@@2HB msvcirt.?openprot@filebuf@@2HB @@ -601,8 +601,8 @@ @ cdecl -arch=win64 ?pword@ios@@QEBAAEAPEAXH@Z(ptr long) msvcirt.?pword@ios@@QEBAAEAPEAXH@Z @ stub -arch=win32 ?rdbuf@fstream@@QBEPAVfilebuf@@XZ @ stub -arch=win64 ?rdbuf@fstream@@QEBAPEAVfilebuf@@XZ -@ stub -arch=win32 ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ -@ stub -arch=win64 ?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ +@ thiscall -arch=win32 ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ(ptr) msvcirt.?rdbuf@ifstream@@QBEPAVfilebuf@@XZ +@ cdecl -arch=win64 ?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ(ptr) msvcirt.?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf@ios@@QBEPAVstreambuf@@XZ(ptr) msvcirt.?rdbuf@ios@@QBEPAVstreambuf@@XZ @ cdecl -arch=win64 ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ(ptr) msvcirt.?rdbuf@ios@@QEBAPEAVstreambuf@@XZ @ thiscall -arch=win32 ?rdbuf@istrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf@istrstream@@QBEPAVstrstreambuf@@XZ @@ -651,8 +651,8 @@ @ cdecl -arch=win64 ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z(ptr ptr long) msvcirt.?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z @ stub -arch=win32 ?setbuf@fstream@@QAEPAVstreambuf@@PADH@Z @ stub -arch=win64 ?setbuf@fstream@@QEAAPEAVstreambuf@@PEADH@Z -@ stub -arch=win32 ?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z -@ stub -arch=win64 ?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z +@ thiscall -arch=win32 ?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z(ptr ptr long) msvcirt.?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z +@ cdecl -arch=win64 ?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z(ptr ptr long) msvcirt.?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z @ stub -arch=win32 ?setbuf@ofstream@@QAEPAVstreambuf@@PADH@Z @ stub -arch=win64 ?setbuf@ofstream@@QEAAPEAVstreambuf@@PEADH@Z @ thiscall -arch=win32 ?setbuf@streambuf@@UAEPAV1@PADH@Z(ptr ptr long) msvcirt.?setbuf@streambuf@@UAEPAV1@PADH@Z @@ -673,8 +673,8 @@ @ cdecl -arch=win64 ?setmode@filebuf@@QEAAHH@Z(ptr long) msvcirt.?setmode@filebuf@@QEAAHH@Z @ stub -arch=win32 ?setmode@fstream@@QAEHH@Z @ stub -arch=win64 ?setmode@fstream@@QEAAHH@Z -@ stub -arch=win32 ?setmode@ifstream@@QAEHH@Z -@ stub -arch=win64 ?setmode@ifstream@@QEAAHH@Z +@ thiscall -arch=win32 ?setmode@ifstream@@QAEHH@Z(ptr long) msvcirt.?setmode@ifstream@@QAEHH@Z +@ cdecl -arch=win64 ?setmode@ifstream@@QEAAHH@Z(ptr long) msvcirt.?setmode@ifstream@@QEAAHH@Z @ stub -arch=win32 ?setmode@ofstream@@QAEHH@Z @ stub -arch=win64 ?setmode@ofstream@@QEAAHH@Z @ thiscall -arch=win32 ?setp@streambuf@@IAEXPAD0@Z(ptr ptr ptr) msvcirt.?setp@streambuf@@IAEXPAD0@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@PEBDHH@Z @ stub -arch=win32 ??0fstream@@QAE@XZ @ stub -arch=win64 ??0fstream@@QEAA@XZ -@ stub -arch=win32 ??0ifstream@@QAE@ABV0@@Z -@ stub -arch=win64 ??0ifstream@@QEAA@AEBV0@@Z -@ stub -arch=win32 ??0ifstream@@QAE@H@Z -@ stub -arch=win64 ??0ifstream@@QEAA@H@Z -@ stub -arch=win32 ??0ifstream@@QAE@HPADH@Z -@ stub -arch=win64 ??0ifstream@@QEAA@HPEADH@Z -@ stub -arch=win32 ??0ifstream@@QAE@PBDHH@Z -@ stub -arch=win64 ??0ifstream@@QEAA@PEBDHH@Z -@ stub -arch=win32 ??0ifstream@@QAE@XZ -@ stub -arch=win64 ??0ifstream@@QEAA@XZ +@ thiscall -arch=win32 ??0ifstream@@QAE@ABV0@@Z(ptr ptr long) msvcirt.??0ifstream@@QAE@ABV0@@Z +@ cdecl -arch=win64 ??0ifstream@@QEAA@AEBV0@@Z(ptr ptr long) msvcirt.??0ifstream@@QEAA@AEBV0@@Z +@ thiscall -arch=win32 ??0ifstream@@QAE@H@Z(ptr long long) msvcirt.??0ifstream@@QAE@H@Z +@ cdecl -arch=win64 ??0ifstream@@QEAA@H@Z(ptr long long) msvcirt.??0ifstream@@QEAA@H@Z +@ thiscall -arch=win32 ??0ifstream@@QAE@HPADH@Z(ptr long ptr long long) msvcirt.??0ifstream@@QAE@HPADH@Z +@ cdecl -arch=win64 ??0ifstream@@QEAA@HPEADH@Z(ptr long ptr long long) msvcirt.??0ifstream@@QEAA@HPEADH@Z +@ thiscall -arch=win32 ??0ifstream@@QAE@PBDHH@Z(ptr str long long long) msvcirt.??0ifstream@@QAE@PBDHH@Z +@ cdecl -arch=win64 ??0ifstream@@QEAA@PEBDHH@Z(ptr str long long long) msvcirt.??0ifstream@@QEAA@PEBDHH@Z +@ thiscall -arch=win32 ??0ifstream@@QAE@XZ(ptr long) msvcirt.??0ifstream@@QAE@XZ +@ cdecl -arch=win64 ??0ifstream@@QEAA@XZ(ptr long) msvcirt.??0ifstream@@QEAA@XZ @ thiscall -arch=win32 ??0ios@@IAE@ABV0@@Z(ptr ptr) msvcirt.??0ios@@IAE@ABV0@@Z @ cdecl -arch=win64 ??0ios@@IEAA@AEBV0@@Z(ptr ptr) msvcirt.??0ios@@IEAA@AEBV0@@Z @ thiscall -arch=win32 ??0ios@@IAE@XZ(ptr) msvcirt.??0ios@@IAE@XZ @@ -154,8 +154,8 @@ @ cdecl -arch=win64 ??1filebuf@@UEAA@XZ(ptr) msvcirt.??1filebuf@@UEAA@XZ @ stub -arch=win32 ??1fstream@@UAE@XZ @ stub -arch=win64 ??1fstream@@UEAA@XZ -@ stub -arch=win32 ??1ifstream@@UAE@XZ -@ stub -arch=win64 ??1ifstream@@UEAA@XZ +@ thiscall -arch=win32 ??1ifstream@@UAE@XZ(ptr) msvcirt.??1ifstream@@UAE@XZ +@ cdecl -arch=win64 ??1ifstream@@UEAA@XZ(ptr) msvcirt.??1ifstream@@UEAA@XZ @ thiscall -arch=win32 ??1ios@@UAE@XZ(ptr) msvcirt.??1ios@@UAE@XZ @ cdecl -arch=win64 ??1ios@@UEAA@XZ(ptr) msvcirt.??1ios@@UEAA@XZ @ thiscall -arch=win32 ??1iostream@@UAE@XZ(ptr) msvcirt.??1iostream@@UAE@XZ @@ -206,8 +206,8 @@ @ cdecl -arch=win64 ??4filebuf@@QEAAAEAV0@AEBV0@@Z(ptr ptr) msvcirt.??4filebuf@@QEAAAEAV0@AEBV0@@Z @ stub -arch=win32 ??4fstream@@QAEAAV0@AAV0@@Z @ stub -arch=win64 ??4fstream@@QEAAAEAV0@AEAV0@@Z -@ stub -arch=win32 ??4ifstream@@QAEAAV0@ABV0@@Z -@ stub -arch=win64 ??4ifstream@@QEAAAEAV0@AEBV0@@Z +@ thiscall -arch=win32 ??4ifstream@@QAEAAV0@ABV0@@Z(ptr ptr) msvcirt.??4ifstream@@QAEAAV0@ABV0@@Z +@ cdecl -arch=win64 ??4ifstream@@QEAAAEAV0@AEBV0@@Z(ptr ptr) msvcirt.??4ifstream@@QEAAAEAV0@AEBV0@@Z @ thiscall -arch=win32 ??4ios@@IAEAAV0@ABV0@@Z(ptr ptr) msvcirt.??4ios@@IAEAAV0@ABV0@@Z @ cdecl -arch=win64 ??4ios@@IEAAAEAV0@AEBV0@@Z(ptr ptr) msvcirt.??4ios@@IEAAAEAV0@AEBV0@@Z @ thiscall -arch=win32 ??4iostream@@IAEAAV0@AAV0@@Z(ptr ptr) msvcirt.??4iostream@@IAEAAV0@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@Z(ptr long) msvcrt.??_Eexception@@UAEPAXI@Z @ thiscall -arch=win32 ??_Efilebuf@@UAEPAXI@Z(ptr long) msvcirt.??_Efilebuf@@UAEPAXI@Z @ stub -arch=win32 ??_Efstream@@UAEPAXI@Z -@ stub -arch=win32 ??_Eifstream@@UAEPAXI@Z +@ thiscall -arch=win32 ??_Eifstream@@UAEPAXI@Z(ptr long) msvcirt.??_Eifstream@@UAEPAXI@Z @ thiscall -arch=win32 ??_Eios@@UAEPAXI@Z(ptr long) msvcirt.??_Eios@@UAEPAXI@Z @ thiscall -arch=win32 ??_Eiostream@@UAEPAXI@Z(ptr long) msvcirt.??_Eiostream@@UAEPAXI@Z @ thiscall -arch=win32 ??_Eistream@@UAEPAXI@Z(ptr long) msvcirt.??_Eistream@@UAEPAXI@Z @@ -426,7 +426,7 @@ @ thiscall -arch=win32 ??_Gexception@@UAEPAXI@Z(ptr long) msvcrt.??_Gexception@@UAEPAXI@Z @ thiscall -arch=win32 ??_Gfilebuf@@UAEPAXI@Z(ptr long) msvcirt.??_Gfilebuf@@UAEPAXI@Z @ stub -arch=win32 ??_Gfstream@@UAEPAXI@Z -@ stub -arch=win32 ??_Gifstream@@UAEPAXI@Z +@ thiscall -arch=win32 ??_Gifstream@@UAEPAXI@Z(ptr long) msvcirt.??_Gifstream@@UAEPAXI@Z @ thiscall -arch=win32 ??_Gios@@UAEPAXI@Z(ptr long) msvcirt.??_Gios@@UAEPAXI@Z @ thiscall -arch=win32 ??_Giostream@@UAEPAXI@Z(ptr long) msvcirt.??_Giostream@@UAEPAXI@Z @ thiscall -arch=win32 ??_Gistream@@UAEPAXI@Z(ptr long) msvcirt.??_Gistream@@UAEPAXI@Z @@ -457,8 +457,8 @@ @ cdecl -arch=win64 ?attach@filebuf@@QEAAPEAV1@H@Z(ptr long) msvcirt.?attach@filebuf@@QEAAPEAV1@H@Z @ stub -arch=win32 ?attach@fstream@@QAEXH@Z @ stub -arch=win64 ?attach@fstream@@QEAAXH@Z -@ stub -arch=win32 ?attach@ifstream@@QAEXH@Z -@ stub -arch=win64 ?attach@ifstream@@QEAAXH@Z +@ thiscall -arch=win32 ?attach@ifstream@@QAEXH@Z(ptr long) msvcirt.?attach@ifstream@@QAEXH@Z +@ cdecl -arch=win64 ?attach@ifstream@@QEAAXH@Z(ptr long) msvcirt.?attach@ifstream@@QEAAXH@Z @ stub -arch=win32 ?attach@ofstream@@QAEXH@Z @ stub -arch=win64 ?attach@ofstream@@QEAAXH@Z @ thiscall -arch=win32 ?bad@ios@@QBEHXZ(ptr) msvcirt.?bad@ios@@QBEHXZ @@ -481,8 +481,8 @@ @ cdecl -arch=win64 ?close@filebuf@@QEAAPEAV1@XZ(ptr) msvcirt.?close@filebuf@@QEAAPEAV1@XZ @ stub -arch=win32 ?close@fstream@@QAEXXZ @ stub -arch=win64 ?close@fstream@@QEAAXXZ -@ stub -arch=win32 ?close@ifstream@@QAEXXZ -@ stub -arch=win64 ?close@ifstream@@QEAAXXZ +@ thiscall -arch=win32 ?close@ifstream@@QAEXXZ(ptr) msvcirt.?close@ifstream@@QAEXXZ +@ cdecl -arch=win64 ?close@ifstream@@QEAAXXZ(ptr) msvcirt.?close@ifstream@@QEAAXXZ @ stub -arch=win32 ?close@ofstream@@QAEXXZ @ stub -arch=win64 ?close@ofstream@@QEAAXXZ @ cdecl -arch=win32 ?clrlock@ios@@QAAXXZ(ptr) msvcirt.?clrlock@ios@@QAAXXZ @@ -525,8 +525,8 @@ @ cdecl -arch=win64 ?fd@filebuf@@QEBAHXZ(ptr) msvcirt.?fd@filebuf@@QEBAHXZ @ stub -arch=win32 ?fd@fstream@@QBEHXZ @ stub -arch=win64 ?fd@fstream@@QEBAHXZ -@ stub -arch=win32 ?fd@ifstream@@QBEHXZ -@ stub -arch=win64 ?fd@ifstream@@QEBAHXZ +@ thiscall -arch=win32 ?fd@ifstream@@QBEHXZ(ptr) msvcirt.?fd@ifstream@@QBEHXZ +@ cdecl -arch=win64 ?fd@ifstream@@QEBAHXZ(ptr) msvcirt.?fd@ifstream@@QEBAHXZ @ stub -arch=win32 ?fd@ofstream@@QBEHXZ @ stub -arch=win64 ?fd@ofstream@@QEBAHXZ @ thiscall -arch=win32 ?fill@ios@@QAEDD@Z(ptr long) msvcirt.?fill@ios@@QAEDD@Z @@ -594,8 +594,8 @@ @ cdecl -arch=win64 ?is_open@filebuf@@QEBAHXZ(ptr) msvcirt.?is_open@filebuf@@QEBAHXZ @ stub -arch=win32 ?is_open@fstream@@QBEHXZ @ stub -arch=win64 ?is_open@fstream@@QEBAHXZ -@ stub -arch=win32 ?is_open@ifstream@@QBEHXZ -@ stub -arch=win64 ?is_open@ifstream@@QEBAHXZ +@ thiscall -arch=win32 ?is_open@ifstream@@QBEHXZ(ptr) msvcirt.?is_open@ifstream@@QBEHXZ +@ cdecl -arch=win64 ?is_open@ifstream@@QEBAHXZ(ptr) msvcirt.?is_open@ifstream@@QEBAHXZ @ stub -arch=win32 ?is_open@ofstream@@QBEHXZ @ stub -arch=win64 ?is_open@ofstream@@QEBAHXZ @ thiscall -arch=win32 ?isfx@istream@@QAEXXZ(ptr) msvcirt.?isfx@istream@@QAEXXZ @@ -621,8 +621,8 @@ @ cdecl -arch=win64 ?open@filebuf@@QEAAPEAV1@PEBDHH@Z(ptr str long long) msvcirt.?open@filebuf@@QEAAPEAV1@PEBDHH@Z @ stub -arch=win32 ?open@fstream@@QAEXPBDHH@Z @ stub -arch=win64 ?open@fstream@@QEAAXPEBDHH@Z -@ stub -arch=win32 ?open@ifstream@@QAEXPBDHH@Z -@ stub -arch=win64 ?open@ifstream@@QEAAXPEBDHH@Z +@ thiscall -arch=win32 ?open@ifstream@@QAEXPBDHH@Z(ptr str long long) msvcirt.?open@ifstream@@QAEXPBDHH@Z +@ cdecl -arch=win64 ?open@ifstream@@QEAAXPEBDHH@Z(ptr str long long) msvcirt.?open@ifstream@@QEAAXPEBDHH@Z @ stub -arch=win32 ?open@ofstream@@QAEXPBDHH@Z @ stub -arch=win64 ?open@ofstream@@QEAAXPEBDHH@Z @ extern ?openprot@filebuf@@2HB msvcirt.?openprot@filebuf@@2HB @@ -672,8 +672,8 @@ @ cdecl -arch=win64 ?raw_name@type_info@@QEBAPEBDXZ(ptr) msvcrt.?raw_name@type_info@@QEBAPEBDXZ @ stub -arch=win32 ?rdbuf@fstream@@QBEPAVfilebuf@@XZ @ stub -arch=win64 ?rdbuf@fstream@@QEBAPEAVfilebuf@@XZ -@ stub -arch=win32 ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ -@ stub -arch=win64 ?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ +@ thiscall -arch=win32 ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ(ptr) msvcirt.?rdbuf@ifstream@@QBEPAVfilebuf@@XZ +@ cdecl -arch=win64 ?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ(ptr) msvcirt.?rdbuf@ifstream@@QEBAPEAVfilebuf@@XZ @ thiscall -arch=win32 ?rdbuf@ios@@QBEPAVstreambuf@@XZ(ptr) msvcirt.?rdbuf@ios@@QBEPAVstreambuf@@XZ @ cdecl -arch=win64 ?rdbuf@ios@@QEBAPEAVstreambuf@@XZ(ptr) msvcirt.?rdbuf@ios@@QEBAPEAVstreambuf@@XZ @ thiscall -arch=win32 ?rdbuf@istrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf@istrstream@@QBEPAVstrstreambuf@@XZ @@ -723,8 +723,8 @@ @ cdecl -arch=win64 ?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z(ptr ptr long) msvcirt.?setbuf@filebuf@@UEAAPEAVstreambuf@@PEADH@Z @ stub -arch=win32 ?setbuf@fstream@@QAEPAVstreambuf@@PADH@Z @ stub -arch=win64 ?setbuf@fstream@@QEAAPEAVstreambuf@@PEADH@Z -@ stub -arch=win32 ?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z -@ stub -arch=win64 ?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z +@ thiscall -arch=win32 ?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z(ptr ptr long) msvcirt.?setbuf@ifstream@@QAEPAVstreambuf@@PADH@Z +@ cdecl -arch=win64 ?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z(ptr ptr long) msvcirt.?setbuf@ifstream@@QEAAPEAVstreambuf@@PEADH@Z @ stub -arch=win32 ?setbuf@ofstream@@QAEPAVstreambuf@@PADH@Z @ stub -arch=win64 ?setbuf@ofstream@@QEAAPEAVstreambuf@@PEADH@Z @ thiscall -arch=win32 ?setbuf@streambuf@@UAEPAV1@PADH@Z(ptr ptr long) msvcirt.?setbuf@streambuf@@UAEPAV1@PADH@Z @@ -745,8 +745,8 @@ @ cdecl -arch=win64 ?setmode@filebuf@@QEAAHH@Z(ptr long) msvcirt.?setmode@filebuf@@QEAAHH@Z @ stub -arch=win32 ?setmode@fstream@@QAEHH@Z @ stub -arch=win64 ?setmode@fstream@@QEAAHH@Z -@ stub -arch=win32 ?setmode@ifstream@@QAEHH@Z -@ stub -arch=win64 ?setmode@ifstream@@QEAAHH@Z +@ thiscall -arch=win32 ?setmode@ifstream@@QAEHH@Z(ptr long) msvcirt.?setmode@ifstream@@QAEHH@Z +@ cdecl -arch=win64 ?setmode@ifstream@@QEAAHH@Z(ptr long) msvcirt.?setmode@ifstream@@QEAAHH@Z @ stub -arch=win32 ?setmode@ofstream@@QAEHH@Z @ stub -arch=win64 ?setmode@ofstream@@QEAAHH@Z @ thiscall -arch=win32 ?setp@streambuf@@IAEXPAD0@Z(ptr ptr ptr) msvcirt.?setp@streambuf@@IAEXPAD0@Z
Hi Arek,
The patch is quite long so I might have missed something.
+/* ??0ifstream@@QAE@HPADH@Z */ +/* ??0ifstream@@QEAA@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);
The allocation failure handling looks quite strange. It's probably better to remove it so the application crashes instead of misbehaving.
+/* ??0ifstream@@QAE@PBDHH@Z */ +/* ??0ifstream@@QEAA@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);
We should probably add OPENMODE_in as in e.g. msvcp90/ios.c:basic_ifstream_char_open. The same applies to all functions with mode argument.
+/* ?attach@ifstream@@QAEXH@Z */ +/* ?attach@ifstream@@QEAAXH@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);
+}
You should probably set failbit if filebuf_attach fails. The same applies to other functions on failure.
+/* ?close@ifstream@@QAEXXZ */ +/* ?close@ifstream@@QEAAXXZ */ +DEFINE_THISCALL_WRAPPER(ifstream_close, 4) +void __thiscall ifstream_close(istream *this) +{
- TRACE("(%p)\n", this);
- filebuf_close(ifstream_rdbuf(this));
+}
You should probably set failbit if filebuf_close fails. Also you should probably clear errors on successful close.
- 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");
Isn't the fd closed by ifstream_vbase_dtor -> filebuf_dtor -> filebuf_close?
- /* setbuf - seems to be a nop and always return NULL */
- pifs = call_func5(p_ifstream_buffer_ctor, &ifs, 64, NULL, 0, TRUE);
Passing arbitrary value as fd doesn't look right. How about changing 64 to -1? It will also show some problems with setbuf implementation.
- psb = call_func3(p_ifstream_setbuf, &ifs, buffer, ARRAY_SIZE(buffer));
- ok(psb == NULL, "wrong return, expected NULL got %p\n", pfb);
Typo: pfb -> psb.
There are also some compilation warnings when compiling tests (i386).
Thanks, Piotr
Op di 1 sep. 2020 om 17:54 schreef Piotr Caban piotr@codeweavers.com:
+/* ??0ifstream@@QAE@HPADH@Z */ +/* ??0ifstream@@QEAA@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);
The allocation failure handling looks quite strange. It's probably better to remove it so the application crashes instead of misbehaving.
It's been a while, but if I remember correctly, I did it this way because stdiostream and strstream and probably others do the same.
On Tue, Sep 01, 2020 at 05:54:45PM +0200, Piotr Caban wrote:
Hi Arek,
The patch is quite long so I might have missed something.
Hey,
Thanks for the review! I was wondering if I should split it a bit - ctros and dtors firts, and then each other method + correspnsidng tests in separate patches.
Not sure if this would really make a difference though.
+/* ??0ifstream@@QAE@HPADH@Z */ +/* ??0ifstream@@QEAA@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);
The allocation failure handling looks quite strange. It's probably better to remove it so the application crashes instead of misbehaving.
I was wondering the same, but as Gijs have said other constructors seem to leave the object in that half initialized state (see ostrstream*_ctor, istrstream_buffer_ctor), so I went with it.
Should it instead set badbit or should it return NULL? Should we change all of the streams here?
+/* ??0ifstream@@QAE@PBDHH@Z */ +/* ??0ifstream@@QEAA@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);
We should probably add OPENMODE_in as in e.g. msvcp90/ios.c:basic_ifstream_char_open. The same applies to all functions with mode argument.
This makes a lot of sense for an input stream. Same for ifstream_open. I've also added a few tests.
+/* ?attach@ifstream@@QAEXH@Z */ +/* ?attach@ifstream@@QEAAXH@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);
+}
You should probably set failbit if filebuf_attach fails. The same applies to other functions on failure.
+/* ?close@ifstream@@QAEXXZ */ +/* ?close@ifstream@@QEAAXXZ */ +DEFINE_THISCALL_WRAPPER(ifstream_close, 4) +void __thiscall ifstream_close(istream *this) +{
- TRACE("(%p)\n", this);
- filebuf_close(ifstream_rdbuf(this));
+}
You should probably set failbit if filebuf_close fails. Also you should probably clear errors on successful close.
failbit handling added, with accompanying tests
- 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");
Isn't the fd closed by ifstream_vbase_dtor -> filebuf_dtor -> filebuf_close?
It is. Here I am just making sure that everything works as expected on the higher level. Is using _close() to make sure that fd is closed wrong?
- /* setbuf - seems to be a nop and always return NULL */
- pifs = call_func5(p_ifstream_buffer_ctor, &ifs, 64, NULL, 0, TRUE);
Passing arbitrary value as fd doesn't look right. How about changing 64 to -1? It will also show some problems with setbuf implementation.
-1 have a special meaning, and I find ok() on the internal value with an arbitrary number a bit better when it come to testing. We do the same in filebuf tests and it works on Windows too.
Thanks for pointing out that setbuf behaves differently when we have no fd opened and no buffer.
Having done some experimentation it looks like filebuf has slightly different semantics than streambuf when it comes to setting unbuffered value in setbuf(). Wine's implemention doesn't follow that.
This was throwing me off while trying to make this work.
I'll leave setbuf() out for now, and spin another series fixing filebuf implementation first.
- psb = call_func3(p_ifstream_setbuf, &ifs, buffer, ARRAY_SIZE(buffer));
- ok(psb == NULL, "wrong return, expected NULL got %p\n", pfb);
Typo: pfb -> psb.
There are also some compilation warnings when compiling tests (i386).
fix'd :-)
On 9/2/20 5:01 PM, Arkadiusz Hiler wrote:
Thanks for the review! I was wondering if I should split it a bit - ctros and dtors firts, and then each other method + correspnsidng tests in separate patches.
Not sure if this would really make a difference though.
It's easier to review smaller patches. I think it's OK to send it in one patch since you already have it written that way.
+/* ??0ifstream@@QAE@HPADH@Z */ +/* ??0ifstream@@QEAA@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);
The allocation failure handling looks quite strange. It's probably better to remove it so the application crashes instead of misbehaving.
I was wondering the same, but as Gijs have said other constructors seem to leave the object in that half initialized state (see ostrstream*_ctor, istrstream_buffer_ctor), so I went with it.
Should it instead set badbit or should it return NULL? Should we change all of the streams here?
I don't know how native handles out of memory error in this case. Newer versions are throwing bad_alloc exception but it was not available in msvcirt. I don't like the possibility of debugging the application only to find out that the ifstream object is broken due to out of memory condition. I would prefer something like: fb = MSVCRT_operator_new(sizeof(filebuf)); if (!fb) { FIXME("out of memory\n"); return NULL; } filebuf_fd_reserve_ctor(fb, fd, buffer, length); or even fb = MSVCRT_operator_new(sizeof(filebuf)); filebuf_fd_reserve_ctor(fb, fd, buffer, length);
It is. Here I am just making sure that everything works as expected on the higher level. Is using _close() to make sure that fd is closed wrong?
It's ok. I misread the code, sorry.
-1 have a special meaning, and I find ok() on the internal value with an arbitrary number a bit better when it come to testing. We do the same in filebuf tests and it works on Windows too.
It's generally nicer to pass valid file descriptor but it's not necessarily wrong. The risk is that the function will work differently due to fd validation. Anyway, since it's in tests, I don't really mind.