[PATCH] msvcirt: Implement ofstream class.

Gijs Vermeulen gijsvrm at gmail.com
Thu Sep 17 18:19:47 CDT 2020


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=31342
Signed-off-by: Gijs Vermeulen <gijsvrm at gmail.com>
---
I included the filebuf_open changes in ifstream and fstream because in the rest of the file
the check is done like this.

 dlls/msvcirt/msvcirt.c       | 205 ++++++++++++++++++-
 dlls/msvcirt/msvcirt.spec    |  72 +++----
 dlls/msvcirt/tests/msvcirt.c | 380 +++++++++++++++++++++++++++++++++++
 dlls/msvcrt20/msvcrt20.spec  |  72 +++----
 dlls/msvcrt40/msvcrt40.spec  |  72 +++----
 5 files changed, 691 insertions(+), 110 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 0b0a34940d..a8f162e7f7 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -186,6 +186,8 @@ extern const vtable_ptr MSVCP_ostream_vtable;
 extern const vtable_ptr MSVCP_ostream_withassign_vtable;
 /* ??_7ostrstream@@6B@ */
 extern const vtable_ptr MSVCP_ostrstream_vtable;
+/* ??_7ofstream@@6B@ */
+extern const vtable_ptr MSVCP_ofstream_vtable;
 /* ??_7istream@@6B@ */
 extern const vtable_ptr MSVCP_istream_vtable;
 /* ??_7istream_withassign@@6B@ */
@@ -260,6 +262,8 @@ __ASM_BLOCK_BEGIN(vtables)
             VTABLE_ADD_FUNC(ostream_vector_dtor));
     __ASM_VTABLE(ostrstream,
             VTABLE_ADD_FUNC(ostream_vector_dtor));
+    __ASM_VTABLE(ofstream,
+            VTABLE_ADD_FUNC(ostream_vector_dtor));
     __ASM_VTABLE(istream,
             VTABLE_ADD_FUNC(istream_vector_dtor));
     __ASM_VTABLE(istream_withassign,
@@ -284,6 +288,7 @@ __ASM_BLOCK_END
 /* ??_8ostream@@7B@ */
 /* ??_8ostream_withassign@@7B@ */
 /* ??_8ostrstream@@7B@ */
+/* ??_8ofstream@@7B@ */
 const int ostream_vbtable[] = {0, VBTABLE_ENTRY(ostream, FIELD_OFFSET(ostream, vbtable), ios)};
 /* ??_8istream@@7B@ */
 /* ??_8istream_withassign@@7B@ */
@@ -309,6 +314,8 @@ DEFINE_RTTI_DATA2(ostream_withassign, sizeof(ostream),
     &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostream_withassign@@")
 DEFINE_RTTI_DATA2(ostrstream, sizeof(ostream),
     &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVostrstream@@")
+DEFINE_RTTI_DATA2(ofstream, sizeof(ostream),
+    &ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVofstream@@")
 DEFINE_RTTI_DATA1(istream, sizeof(istream), &ios_rtti_base_descriptor, ".?AVistream@@")
 DEFINE_RTTI_DATA2(istream_withassign, sizeof(istream),
     &istream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AVistream_withassign@@")
@@ -2404,6 +2411,8 @@ ostream* __thiscall ostream_copy_ctor(ostream *this, const ostream *copy, BOOL v
 /* ??1ostream_withassign@@UEAA at XZ */
 /* ??1ostrstream@@UAE at XZ */
 /* ??1ostrstream@@UEAA at XZ */
+/* ??1ofstream@@UAE at XZ */
+/* ??1ofstream@@UEAA at XZ */
 DEFINE_THISCALL_WRAPPER(ostream_dtor, 4)
 void __thiscall ostream_dtor(ios *base)
 {
@@ -2442,6 +2451,8 @@ ostream* __thiscall ostream_assign_sb(ostream *this, streambuf *sb)
 /* ??4ostream_withassign@@QEAAAEAVostream@@AEBV1@@Z */
 /* ??4ostrstream@@QAEAAV0 at ABV0@@Z */
 /* ??4ostrstream@@QEAAAEAV0 at AEBV0@@Z */
+/* ??4ofstream@@QAEAAV0 at ABV0@@Z */
+/* ??4ofstream@@QEAAAEAV0 at AEBV0@@Z */
 DEFINE_THISCALL_WRAPPER(ostream_assign, 8)
 ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
 {
@@ -2454,6 +2465,8 @@ ostream* __thiscall ostream_assign(ostream *this, const ostream *rhs)
 /* ??_Dostream_withassign@@QEAAXXZ */
 /* ??_Dostrstream@@QAEXXZ */
 /* ??_Dostrstream@@QEAAXXZ */
+/* ??_Dofstream@@QAEXXZ */
+/* ??_Dofstream@@QEAAXXZ */
 DEFINE_THISCALL_WRAPPER(ostream_vbase_dtor, 4)
 void __thiscall ostream_vbase_dtor(ostream *this)
 {
@@ -2468,6 +2481,7 @@ void __thiscall ostream_vbase_dtor(ostream *this)
 /* ??_Eostream@@UAEPAXI at Z */
 /* ??_Eostream_withassign@@UAEPAXI at Z */
 /* ??_Eostrstream@@UAEPAXI at Z */
+/* ??_Eofstream@@UAEPAXI at Z */
 DEFINE_THISCALL_WRAPPER(ostream_vector_dtor, 8)
 ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
 {
@@ -2493,6 +2507,7 @@ ostream* __thiscall ostream_vector_dtor(ios *base, unsigned int flags)
 /* ??_Gostream@@UAEPAXI at Z */
 /* ??_Gostream_withassign@@UAEPAXI at Z */
 /* ??_Gostrstream@@UAEPAXI at Z */
+/* ??_Gofstream@@UAEPAXI at Z */
 DEFINE_THISCALL_WRAPPER(ostream_scalar_dtor, 8)
 ostream* __thiscall ostream_scalar_dtor(ios *base, unsigned int flags)
 {
@@ -3086,6 +3101,191 @@ char* __thiscall ostrstream_str(ostream *this)
     return strstreambuf_str(ostrstream_rdbuf(this));
 }
 
+/* ??0ofstream@@QAE at ABV0@@Z */
+/* ??0ofstream@@QEAA at AEBV0@@Z */
+DEFINE_THISCALL_WRAPPER(ofstream_copy_ctor, 12)
+ostream* __thiscall ofstream_copy_ctor(ostream *this, const ostream *copy, BOOL virt_init)
+{
+    TRACE("(%p %p %d)\n", this, copy, virt_init);
+    ostream_withassign_copy_ctor(this, copy, virt_init);
+    ostream_get_ios(this)->vtable = &MSVCP_ofstream_vtable;
+    return this;
+}
+
+/* ??0ofstream@@QAE at HPADH@Z */
+/* ??0ofstream@@QEAA at HPEADH@Z */
+DEFINE_THISCALL_WRAPPER(ofstream_buffer_ctor, 20)
+ostream* __thiscall ofstream_buffer_ctor(ostream *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) {
+        FIXME("out of memory\n");
+        return NULL;
+    }
+
+    filebuf_fd_reserve_ctor(fb, fd, buffer, length);
+    ostream_sb_ctor(this, &fb->base, virt_init);
+
+    base = ostream_get_ios(this);
+    base->vtable = &MSVCP_ofstream_vtable;
+    base->delbuf = 1;
+
+    return this;
+}
+
+/* ??0ofstream@@QAE at H@Z */
+/* ??0ofstream@@QEAA at H@Z */
+DEFINE_THISCALL_WRAPPER(ofstream_fd_ctor, 12)
+ostream* __thiscall ofstream_fd_ctor(ostream *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) {
+        FIXME("out of memory\n");
+        return NULL;
+    }
+
+    filebuf_fd_ctor(fb, fd);
+    ostream_sb_ctor(this, &fb->base, virt_init);
+
+    base = ostream_get_ios(this);
+    base->vtable = &MSVCP_ofstream_vtable;
+    base->delbuf = 1;
+
+    return this;
+}
+
+/* ??0ofstream@@QAE at PBDHH@Z */
+/* ??0ofstream@@QEAA at PEBDHH@Z */
+DEFINE_THISCALL_WRAPPER(ofstream_open_ctor, 20)
+ostream* __thiscall ofstream_open_ctor(ostream *this, const char *name, int 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) {
+        FIXME("out of memory\n");
+        return NULL;
+    }
+
+    filebuf_ctor(fb);
+    ostream_sb_ctor(this, &fb->base, virt_init);
+
+    base = ostream_get_ios(this);
+    base->vtable = &MSVCP_ofstream_vtable;
+    base->delbuf = 1;
+
+    if (filebuf_open(fb, name, mode|OPENMODE_out, protection) == NULL)
+        base->state |= IOSTATE_failbit;
+    return this;
+}
+
+/* ??0ofstream@@QAE at XZ */
+/* ??0ofstream@@QEAA at XZ */
+DEFINE_THISCALL_WRAPPER(ofstream_ctor, 8)
+ostream* __thiscall ofstream_ctor(ostream *this, BOOL virt_init)
+{
+    return ofstream_fd_ctor(this, -1, virt_init);
+}
+
+/* ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ */
+/* ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ */
+DEFINE_THISCALL_WRAPPER(ofstream_rdbuf, 4)
+filebuf* __thiscall ofstream_rdbuf(const ostream *this)
+{
+    TRACE("(%p)\n", this);
+    return (filebuf*) ostream_get_ios(this)->sb;
+}
+
+/* ?fd at ofstream@@QBEHXZ */
+/* ?fd at ofstream@@QEBAHXZ */
+DEFINE_THISCALL_WRAPPER(ofstream_fd, 4)
+filedesc __thiscall ofstream_fd(ostream *this)
+{
+    TRACE("(%p)\n", this);
+    return filebuf_fd(ofstream_rdbuf(this));
+}
+
+/* ?attach at ofstream@@QAEXH at Z */
+/* ?attach at ofstream@@QEAAXH at Z */
+DEFINE_THISCALL_WRAPPER(ofstream_attach, 8)
+void __thiscall ofstream_attach(ostream *this, filedesc fd)
+{
+    ios *base = ostream_get_ios(this);
+    TRACE("(%p %d)\n", this, fd);
+    if (filebuf_attach(ofstream_rdbuf(this), fd) == NULL)
+        ios_clear(base, base->state | IOSTATE_failbit);
+}
+
+/* ?close at ofstream@@QAEXXZ */
+/* ?close at ofstream@@QEAAXXZ */
+DEFINE_THISCALL_WRAPPER(ofstream_close, 4)
+void __thiscall ofstream_close(ostream *this)
+{
+    ios *base = ostream_get_ios(this);
+    TRACE("(%p)\n", this);
+    if (filebuf_close(ofstream_rdbuf(this)) == NULL)
+        ios_clear(base, base->state | IOSTATE_failbit);
+    else
+        ios_clear(base, IOSTATE_goodbit);
+}
+
+/* ?is_open at ofstream@@QBEHXZ */
+/* ?is_open at ofstream@@QEBAHXZ */
+DEFINE_THISCALL_WRAPPER(ofstream_is_open, 4)
+int __thiscall ofstream_is_open(const ostream *this)
+{
+    TRACE("(%p)\n", this);
+    return filebuf_is_open(ofstream_rdbuf(this));
+}
+
+/* ?open at ofstream@@QAEXPBDHH at Z */
+/* ?open at ofstream@@QEAAXPEBDHH at Z */
+DEFINE_THISCALL_WRAPPER(ofstream_open, 16)
+void __thiscall ofstream_open(ostream *this, const char *name, ios_open_mode mode, int protection)
+{
+    ios *base = ostream_get_ios(this);
+    TRACE("(%p %s %d %d)\n", this, name, mode, protection);
+    if (filebuf_open(ofstream_rdbuf(this), name, mode|OPENMODE_out, protection) == NULL)
+        ios_clear(base, base->state | IOSTATE_failbit);
+}
+
+/* ?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z */
+/* ?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z */
+DEFINE_THISCALL_WRAPPER(ofstream_setbuf, 12)
+streambuf* __thiscall ofstream_setbuf(ostream *this, char *buffer, int length)
+{
+    ios *base = ostream_get_ios(this);
+    filebuf* fb = ofstream_rdbuf(this);
+
+    TRACE("(%p %p %d)\n", this, buffer, length);
+
+    if (filebuf_is_open(fb)) {
+        ios_clear(base, base->state | IOSTATE_failbit);
+        return NULL;
+    }
+
+    return filebuf_setbuf(fb, buffer, length);
+}
+
+/* ?setmode at ofstream@@QAEHH at Z */
+/* ?setmode at ofstream@@QEAAHH at Z */
+DEFINE_THISCALL_WRAPPER(ofstream_setmode, 8)
+int __thiscall ofstream_setmode(ostream *this, int mode)
+{
+    TRACE("(%p %d)\n", this, mode);
+    return filebuf_setmode(ofstream_rdbuf(this), mode);
+}
+
 static inline ios* istream_get_ios(const istream *this)
 {
     return (ios*)((char*)this + this->vbtable[1]);
@@ -4218,7 +4418,7 @@ istream* __thiscall ifstream_open_ctor(istream *this, const char *name, ios_open
     base->vtable = &MSVCP_ifstream_vtable;
     base->delbuf = 1;
 
-    if (!filebuf_open(fb, name, mode|OPENMODE_in, protection))
+    if (filebuf_open(fb, name, mode|OPENMODE_in, protection) == NULL)
         base->state |= IOSTATE_failbit;
     return this;
 }
@@ -4633,7 +4833,7 @@ iostream* __thiscall fstream_open_ctor(iostream *this, const char *name, ios_ope
     base = istream_get_ios(&this->base1);
     base->delbuf = 1;
 
-    if (!filebuf_open(fb, name, mode, protection))
+    if (filebuf_open(fb, name, mode, protection) == NULL)
         base->state |= IOSTATE_failbit;
     return this;
 }
@@ -4801,6 +5001,7 @@ static void init_io(void *base)
     init_ostream_rtti(base);
     init_ostream_withassign_rtti(base);
     init_ostrstream_rtti(base);
+    init_ofstream_rtti(base);
     init_istream_rtti(base);
     init_istream_withassign_rtti(base);
     init_istrstream_rtti(base);
diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec
index 0842b14314..804300f1a3 100644
--- a/dlls/msvcirt/msvcirt.spec
+++ b/dlls/msvcirt/msvcirt.spec
@@ -70,16 +70,16 @@
 @ cdecl -arch=win64 ??0logic_error@@QEAA at AEBQEBD@Z(ptr ptr) MSVCP_logic_error_ctor
 @ thiscall -arch=win32 ??0logic_error@@QAE at ABV0@@Z(ptr ptr) MSVCP_logic_error_copy_ctor
 @ cdecl -arch=win64 ??0logic_error@@QEAA at AEBV0@@Z(ptr ptr) MSVCP_logic_error_copy_ctor
-@ stub -arch=win32 ??0ofstream@@QAE at ABV0@@Z  # __thiscall ofstream::ofstream(class ofstream const &)
-@ stub -arch=win64 ??0ofstream@@QEAA at AEBV0@@Z
-@ stub -arch=win32 ??0ofstream@@QAE at H@Z  # __thiscall ofstream::ofstream(int)
-@ stub -arch=win64 ??0ofstream@@QEAA at H@Z
-@ stub -arch=win32 ??0ofstream@@QAE at HPADH@Z  # __thiscall ofstream::ofstream(int,char *,int)
-@ stub -arch=win64 ??0ofstream@@QEAA at HPEADH@Z
-@ stub -arch=win32 ??0ofstream@@QAE at PBDHH@Z  # __thiscall ofstream::ofstream(char const *,int,int)
-@ stub -arch=win64 ??0ofstream@@QEAA at PEBDHH@Z
-@ stub -arch=win32 ??0ofstream@@QAE at XZ  # __thiscall ofstream::ofstream(void)
-@ stub -arch=win64 ??0ofstream@@QEAA at XZ
+@ thiscall -arch=win32 ??0ofstream@@QAE at ABV0@@Z(ptr ptr long) ofstream_copy_ctor
+@ cdecl -arch=win64 ??0ofstream@@QEAA at AEBV0@@Z(ptr ptr long) ofstream_copy_ctor
+@ thiscall -arch=win32 ??0ofstream@@QAE at H@Z(ptr long long) ofstream_fd_ctor
+@ cdecl -arch=win64 ??0ofstream@@QEAA at H@Z(ptr long long) ofstream_fd_ctor
+@ thiscall -arch=win32 ??0ofstream@@QAE at HPADH@Z(ptr long ptr long long) ofstream_buffer_ctor
+@ cdecl -arch=win64 ??0ofstream@@QEAA at HPEADH@Z(ptr long ptr long long) ofstream_buffer_ctor
+@ thiscall -arch=win32 ??0ofstream@@QAE at PBDHH@Z(ptr str long long long) ofstream_open_ctor
+@ cdecl -arch=win64 ??0ofstream@@QEAA at PEBDHH@Z(ptr str long long long) ofstream_open_ctor
+@ thiscall -arch=win32 ??0ofstream@@QAE at XZ(ptr long) ofstream_ctor
+@ cdecl -arch=win64 ??0ofstream@@QEAA at XZ(ptr long) ofstream_ctor
 @ thiscall -arch=win32 ??0ostream@@IAE at ABV0@@Z(ptr ptr long) ostream_copy_ctor
 @ cdecl -arch=win64 ??0ostream@@IEAA at AEBV0@@Z(ptr ptr long) ostream_copy_ctor
 @ thiscall -arch=win32 ??0ostream@@IAE at XZ(ptr long) ostream_ctor
@@ -152,8 +152,8 @@
 @ cdecl -arch=win64 ??1istrstream@@UEAA at XZ(ptr) istream_dtor
 @ thiscall -arch=win32 ??1logic_error@@UAE at XZ(ptr) MSVCP_logic_error_dtor
 @ cdecl -arch=win64 ??1logic_error@@UEAA at XZ(ptr) MSVCP_logic_error_dtor
-@ stub -arch=win32 ??1ofstream@@UAE at XZ  # virtual __thiscall ofstream::~ofstream(void)
-@ stub -arch=win64 ??1ofstream@@UEAA at XZ
+@ thiscall -arch=win32 ??1ofstream@@UAE at XZ(ptr) ostream_dtor
+@ cdecl -arch=win64 ??1ofstream@@UEAA at XZ(ptr) ostream_dtor
 @ thiscall -arch=win32 ??1ostream@@UAE at XZ(ptr) ostream_dtor
 @ cdecl -arch=win64 ??1ostream@@UEAA at XZ(ptr) ostream_dtor
 @ thiscall -arch=win32 ??1ostream_withassign@@UAE at XZ(ptr) ostream_dtor
@@ -200,8 +200,8 @@
 @ cdecl -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) istream_assign
 @ thiscall -arch=win32 ??4logic_error@@QAEAAV0 at ABV0@@Z(ptr ptr) MSVCP_logic_error_assign
 @ cdecl -arch=win64 ??4logic_error@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) MSVCP_logic_error_assign
-@ stub -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z  # class ofstream & __thiscall ofstream::operator=(class ofstream const &)
-@ stub -arch=win64 ??4ofstream@@QEAAAEAV0 at AEBV0@@Z
+@ thiscall -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z(ptr ptr) ostream_assign
+@ cdecl -arch=win64 ??4ofstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) ostream_assign
 @ thiscall -arch=win32 ??4ostream@@IAEAAV0 at ABV0@@Z(ptr ptr) ostream_assign
 @ cdecl -arch=win64 ??4ostream@@IEAAAEAV0 at AEBV0@@Z(ptr ptr) ostream_assign
 @ thiscall -arch=win32 ??4ostream@@IAEAAV0 at PAVstreambuf@@@Z(ptr ptr) ostream_assign_sb
@@ -312,7 +312,7 @@
 @ extern ??_7istream_withassign@@6B@ MSVCP_istream_vtable
 @ extern ??_7istrstream@@6B@ MSVCP_istrstream_vtable
 @ extern ??_7logic_error@@6B@ MSVCP_logic_error_vtable
-# @ extern ??_7ofstream@@6B@  # const ofstream::`vftable'
+@ extern ??_7ofstream@@6B@ MSVCP_ofstream_vtable
 @ extern ??_7ostream@@6B@ MSVCP_ostream_vtable
 @ extern ??_7ostream_withassign@@6B@ MSVCP_ostream_withassign_vtable
 @ extern ??_7ostrstream@@6B@ MSVCP_ostrstream_vtable
@@ -329,7 +329,7 @@
 @ extern ??_8istream@@7B@ istream_vbtable
 @ extern ??_8istream_withassign@@7B@ istream_vbtable
 @ extern ??_8istrstream@@7B@ istream_vbtable
-# @ extern ??_8ofstream@@7B@  # const ofstream::`vbtable'
+@ extern ??_8ofstream@@7B@ ostream_vbtable
 @ extern ??_8ostream@@7B@ ostream_vbtable
 @ extern ??_8ostream_withassign@@7B@ ostream_vbtable
 @ extern ??_8ostrstream@@7B@ ostream_vbtable
@@ -349,8 +349,8 @@
 @ cdecl -arch=win64 ??_Distream_withassign@@QEAAXXZ(ptr) istream_vbase_dtor
 @ thiscall -arch=win32 ??_Distrstream@@QAEXXZ(ptr) istream_vbase_dtor
 @ cdecl -arch=win64 ??_Distrstream@@QEAAXXZ(ptr) istream_vbase_dtor
-@ stub -arch=win32 ??_Dofstream@@QAEXXZ  # void __thiscall ofstream::`vbase destructor'(void)
-@ stub -arch=win64 ??_Dofstream@@QEAAXXZ
+@ thiscall -arch=win32 ??_Dofstream@@QAEXXZ(ptr) ostream_vbase_dtor
+@ cdecl -arch=win64 ??_Dofstream@@QEAAXXZ(ptr) ostream_vbase_dtor
 @ thiscall -arch=win32 ??_Dostream@@QAEXXZ(ptr) ostream_vbase_dtor
 @ cdecl -arch=win64 ??_Dostream@@QEAAXXZ(ptr) ostream_vbase_dtor
 @ thiscall -arch=win32 ??_Dostream_withassign@@QAEXXZ(ptr) ostream_vbase_dtor
@@ -371,7 +371,7 @@
 @ thiscall -arch=win32 ??_Eistream_withassign@@UAEPAXI at Z(ptr long) istream_vector_dtor
 @ thiscall -arch=win32 ??_Eistrstream@@UAEPAXI at Z(ptr long) istream_vector_dtor
 @ thiscall -arch=win32 ??_Elogic_error@@UAEPAXI at Z(ptr long) MSVCP_logic_error_vector_dtor
-@ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z  # virtual void * __thiscall ofstream::`vector deleting destructor'(unsigned int)
+@ thiscall -arch=win32 ??_Eofstream@@UAEPAXI at Z(ptr long) ostream_vector_dtor
 @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) ostream_vector_dtor
 @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) ostream_vector_dtor
 @ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) ostream_vector_dtor
@@ -390,7 +390,7 @@
 @ thiscall -arch=win32 ??_Gistream_withassign@@UAEPAXI at Z(ptr long) istream_scalar_dtor
 @ thiscall -arch=win32 ??_Gistrstream@@UAEPAXI at Z(ptr long) istream_scalar_dtor
 @ thiscall -arch=win32 ??_Glogic_error@@UAEPAXI at Z(ptr long) MSVCP_logic_error_scalar_dtor
-@ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z  # virtual void * __thiscall ofstream::`scalar deleting destructor'(unsigned int)
+@ thiscall -arch=win32 ??_Gofstream@@UAEPAXI at Z(ptr long) ostream_scalar_dtor
 @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) ostream_scalar_dtor
 @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) ostream_scalar_dtor
 @ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) ostream_scalar_dtor
@@ -408,8 +408,8 @@
 @ stub -arch=win64 ?attach at fstream@@QEAAXH at Z
 @ thiscall -arch=win32 ?attach at ifstream@@QAEXH at Z(ptr long) ifstream_attach
 @ cdecl -arch=win64 ?attach at ifstream@@QEAAXH at Z(ptr long) ifstream_attach
-@ stub -arch=win32 ?attach at ofstream@@QAEXH at Z  # void __thiscall ofstream::attach(int)
-@ stub -arch=win64 ?attach at ofstream@@QEAAXH at Z
+@ thiscall -arch=win32 ?attach at ofstream@@QAEXH at Z(ptr long) ofstream_attach
+@ cdecl -arch=win64 ?attach at ofstream@@QEAAXH at Z(ptr long) ofstream_attach
 @ thiscall -arch=win32 ?bad at ios@@QBEHXZ(ptr) ios_bad
 @ cdecl -arch=win64 ?bad at ios@@QEBAHXZ(ptr) ios_bad
 @ thiscall -arch=win32 ?base at streambuf@@IBEPADXZ(ptr) streambuf_base
@@ -430,8 +430,8 @@
 @ stub -arch=win64 ?close at fstream@@QEAAXXZ
 @ thiscall -arch=win32 ?close at ifstream@@QAEXXZ(ptr) ifstream_close
 @ cdecl -arch=win64 ?close at ifstream@@QEAAXXZ(ptr) ifstream_close
-@ stub -arch=win32 ?close at ofstream@@QAEXXZ  # void __thiscall ofstream::close(void)
-@ stub -arch=win64 ?close at ofstream@@QEAAXXZ
+@ thiscall -arch=win32 ?close at ofstream@@QAEXXZ(ptr) ofstream_close
+@ cdecl -arch=win64 ?close at ofstream@@QEAAXXZ(ptr) ofstream_close
 @ cdecl -arch=win32 ?clrlock at ios@@QAAXXZ(ptr) ios_clrlock
 @ cdecl -arch=win64 ?clrlock at ios@@QEAAXXZ(ptr) ios_clrlock
 @ thiscall -arch=win32 ?clrlock at streambuf@@QAEXXZ(ptr) streambuf_clrlock
@@ -474,8 +474,8 @@
 @ stub -arch=win64 ?fd at fstream@@QEBAHXZ
 @ thiscall -arch=win32 ?fd at ifstream@@QBEHXZ(ptr) ifstream_fd
 @ cdecl -arch=win64 ?fd at ifstream@@QEBAHXZ(ptr) ifstream_fd
-@ stub -arch=win32 ?fd at ofstream@@QBEHXZ  # int __thiscall ofstream::fd(void)const 
-@ stub -arch=win64 ?fd at ofstream@@QEBAHXZ
+@ thiscall -arch=win32 ?fd at ofstream@@QBEHXZ(ptr) ofstream_fd
+@ cdecl -arch=win64 ?fd at ofstream@@QEBAHXZ(ptr) ofstream_fd
 @ thiscall -arch=win32 ?fill at ios@@QAEDD at Z(ptr long) ios_fill_set
 @ cdecl -arch=win64 ?fill at ios@@QEAADD at Z(ptr long) ios_fill_set
 @ thiscall -arch=win32 ?fill at ios@@QBEDXZ(ptr) ios_fill_get
@@ -543,8 +543,8 @@
 @ stub -arch=win64 ?is_open at fstream@@QEBAHXZ
 @ thiscall -arch=win32 ?is_open at ifstream@@QBEHXZ(ptr) ifstream_is_open
 @ cdecl -arch=win64 ?is_open at ifstream@@QEBAHXZ(ptr) ifstream_is_open
-@ stub -arch=win32 ?is_open at ofstream@@QBEHXZ  # int __thiscall ofstream::is_open(void)const 
-@ stub -arch=win64 ?is_open at ofstream@@QEBAHXZ
+@ thiscall -arch=win32 ?is_open at ofstream@@QBEHXZ(ptr) ofstream_is_open
+@ cdecl -arch=win64 ?is_open at ofstream@@QEBAHXZ(ptr) ofstream_is_open
 @ thiscall -arch=win32 ?isfx at istream@@QAEXXZ(ptr) istream_isfx
 @ cdecl -arch=win64 ?isfx at istream@@QEAAXXZ(ptr) istream_isfx
 @ thiscall -arch=win32 ?iword at ios@@QBEAAJH at Z(ptr long) ios_iword
@@ -568,8 +568,8 @@
 @ stub -arch=win64 ?open at fstream@@QEAAXPEBDHH at Z
 @ thiscall -arch=win32 ?open at ifstream@@QAEXPBDHH at Z(ptr str long long) ifstream_open
 @ cdecl -arch=win64 ?open at ifstream@@QEAAXPEBDHH at Z(ptr str long long) ifstream_open
-@ stub -arch=win32 ?open at ofstream@@QAEXPBDHH at Z  # void __thiscall ofstream::open(char const *,int,int)
-@ stub -arch=win64 ?open at ofstream@@QEAAXPEBDHH at Z
+@ thiscall -arch=win32 ?open at ofstream@@QAEXPBDHH at Z(ptr str long long) ofstream_open
+@ cdecl -arch=win64 ?open at ofstream@@QEAAXPEBDHH at Z(ptr str long long) ofstream_open
 @ extern ?openprot at filebuf@@2HB filebuf_openprot
 @ thiscall -arch=win32 ?opfx at ostream@@QAEHXZ(ptr) ostream_opfx
 @ cdecl -arch=win64 ?opfx at ostream@@QEAAHXZ(ptr) ostream_opfx
@@ -621,8 +621,8 @@
 @ cdecl -arch=win64 ?rdbuf at ios@@QEBAPEAVstreambuf@@XZ(ptr) ios_rdbuf
 @ thiscall -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ(ptr) istrstream_rdbuf
 @ cdecl -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) istrstream_rdbuf
-@ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ  # class filebuf * __thiscall ofstream::rdbuf(void)const 
-@ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ
+@ thiscall -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ(ptr) ofstream_rdbuf
+@ cdecl -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ(ptr) ofstream_rdbuf
 @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) ostrstream_rdbuf
 @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) ostrstream_rdbuf
 @ thiscall -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ(ptr) stdiostream_rdbuf
@@ -665,8 +665,8 @@
 @ stub -arch=win64 ?setbuf at fstream@@QEAAPEAVstreambuf@@PEADH at Z
 @ thiscall -arch=win32 ?setbuf at ifstream@@QAEPAVstreambuf@@PADH at Z(ptr ptr long) ifstream_setbuf
 @ cdecl -arch=win64 ?setbuf at ifstream@@QEAAPEAVstreambuf@@PEADH at Z(ptr ptr long) ifstream_setbuf
-@ stub -arch=win32 ?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z  # class streambuf * __thiscall ofstream::setbuf(char *,int)
-@ stub -arch=win64 ?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z
+@ thiscall -arch=win32 ?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z(ptr ptr long) ofstream_setbuf
+@ cdecl -arch=win64 ?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z(ptr ptr long) ofstream_setbuf
 @ thiscall -arch=win32 ?setbuf at streambuf@@UAEPAV1 at PADH@Z(ptr ptr long) streambuf_setbuf
 @ cdecl -arch=win64 ?setbuf at streambuf@@UEAAPEAV1 at PEADH@Z(ptr ptr long) streambuf_setbuf
 @ thiscall -arch=win32 ?setbuf at strstreambuf@@UAEPAVstreambuf@@PADH at Z(ptr ptr long) strstreambuf_setbuf
@@ -687,8 +687,8 @@
 @ stub -arch=win64 ?setmode at fstream@@QEAAHH at Z
 @ thiscall -arch=win32 ?setmode at ifstream@@QAEHH at Z(ptr long) ifstream_setmode
 @ cdecl -arch=win64 ?setmode at ifstream@@QEAAHH at Z(ptr long) ifstream_setmode
-@ stub -arch=win32 ?setmode at ofstream@@QAEHH at Z  # int __thiscall ofstream::setmode(int)
-@ stub -arch=win64 ?setmode at ofstream@@QEAAHH at Z
+@ thiscall -arch=win32 ?setmode at ofstream@@QAEHH at Z(ptr long) ofstream_setmode
+@ cdecl -arch=win64 ?setmode at ofstream@@QEAAHH at Z(ptr long) ofstream_setmode
 @ thiscall -arch=win32 ?setp at streambuf@@IAEXPAD0 at Z(ptr ptr ptr) streambuf_setp
 @ cdecl -arch=win64 ?setp at streambuf@@IEAAXPEAD0 at Z(ptr ptr ptr) streambuf_setp
 @ thiscall -arch=win32 ?setrwbuf at stdiobuf@@QAEHHH at Z(ptr long long) stdiobuf_setrwbuf
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 7bb8bdcf73..18cce105fd 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -339,6 +339,23 @@ static void (*__thiscall p_ostrstream_vbase_dtor)(ostream*);
 static ostream* (*__thiscall p_ostrstream_assign)(ostream*, const ostream*);
 static int (*__thiscall p_ostrstream_pcount)(const ostream*);
 
+/* ofstream */
+static ostream* (*__thiscall p_ofstream_copy_ctor)(ostream*, const ostream*, BOOL);
+static ostream* (*__thiscall p_ofstream_buffer_ctor)(ostream*, filedesc, char*, int, BOOL);
+static ostream* (*__thiscall p_ofstream_fd_ctor)(ostream*, filedesc fd, BOOL virt_init);
+static ostream* (*__thiscall p_ofstream_open_ctor)(ostream*, const char *name, ios_open_mode, int, BOOL);
+static ostream* (*__thiscall p_ofstream_ctor)(ostream*, BOOL);
+static void (*__thiscall p_ofstream_dtor)(ios*);
+static void (*__thiscall p_ofstream_vbase_dtor)(ostream*);
+static void (*__thiscall p_ofstream_attach)(ostream*, filedesc);
+static void (*__thiscall p_ofstream_close)(ostream*);
+static filedesc (*__thiscall p_ofstream_fd)(ostream*);
+static int (*__thiscall p_ofstream_is_open)(const ostream*);
+static void (*__thiscall p_ofstream_open)(ostream*, const char*, ios_open_mode, int);
+static filebuf* (*__thiscall p_ofstream_rdbuf)(const ostream*);
+static streambuf* (*__thiscall p_ofstream_setbuf)(ostream*, char*, int);
+static int (*__thiscall p_ofstream_setmode)(ostream*, int);
+
 /* istream */
 static istream* (*__thiscall p_istream_copy_ctor)(istream*, const istream*, BOOL);
 static istream* (*__thiscall p_istream_ctor)(istream*, BOOL);
@@ -670,6 +687,22 @@ static BOOL init(void)
         SET(p_ostrstream_assign, "??4ostrstream@@QEAAAEAV0 at AEBV0@@Z");
         SET(p_ostrstream_pcount, "?pcount at ostrstream@@QEBAHXZ");
 
+        SET(p_ofstream_copy_ctor, "??0ofstream@@QEAA at AEBV0@@Z");
+        SET(p_ofstream_buffer_ctor, "??0ofstream@@QEAA at HPEADH@Z");
+        SET(p_ofstream_fd_ctor, "??0ofstream@@QEAA at H@Z");
+        SET(p_ofstream_open_ctor, "??0ofstream@@QEAA at PEBDHH@Z");
+        SET(p_ofstream_ctor, "??0ofstream@@QEAA at XZ");
+        SET(p_ofstream_dtor, "??1ofstream@@UEAA at XZ");
+        SET(p_ofstream_vbase_dtor, "??_Dofstream@@QEAAXXZ");
+        SET(p_ofstream_attach, "?attach at ofstream@@QEAAXH at Z");
+        SET(p_ofstream_close, "?close at ofstream@@QEAAXXZ");
+        SET(p_ofstream_fd, "?fd at ofstream@@QEBAHXZ");
+        SET(p_ofstream_is_open, "?is_open at ofstream@@QEBAHXZ");
+        SET(p_ofstream_open, "?open at ofstream@@QEAAXPEBDHH at Z");
+        SET(p_ofstream_rdbuf, "?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ");
+        SET(p_ofstream_setbuf, "?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z");
+        SET(p_ofstream_setmode, "?setmode at ofstream@@QEAAHH at Z");
+
         SET(p_istream_copy_ctor, "??0istream@@IEAA at AEBV0@@Z");
         SET(p_istream_ctor, "??0istream@@IEAA at XZ");
         SET(p_istream_sb_ctor, "??0istream@@QEAA at PEAVstreambuf@@@Z");
@@ -905,6 +938,22 @@ static BOOL init(void)
         SET(p_ostrstream_assign, "??4ostrstream@@QAEAAV0 at ABV0@@Z");
         SET(p_ostrstream_pcount, "?pcount at ostrstream@@QBEHXZ");
 
+        SET(p_ofstream_copy_ctor, "??0ofstream@@QAE at ABV0@@Z");
+        SET(p_ofstream_fd_ctor, "??0ofstream@@QAE at H@Z");
+        SET(p_ofstream_buffer_ctor, "??0ofstream@@QAE at HPADH@Z");
+        SET(p_ofstream_open_ctor, "??0ofstream@@QAE at PBDHH@Z");
+        SET(p_ofstream_ctor, "??0ofstream@@QAE at XZ");
+        SET(p_ofstream_dtor, "??1ofstream@@UAE at XZ");
+        SET(p_ofstream_vbase_dtor, "??_Dofstream@@QAEXXZ");
+        SET(p_ofstream_attach, "?attach at ofstream@@QAEXH at Z");
+        SET(p_ofstream_close, "?close at ofstream@@QAEXXZ");
+        SET(p_ofstream_fd, "?fd at ofstream@@QBEHXZ");
+        SET(p_ofstream_is_open, "?is_open at ofstream@@QBEHXZ");
+        SET(p_ofstream_open, "?open at ofstream@@QAEXPBDHH at Z");
+        SET(p_ofstream_rdbuf, "?rdbuf at ofstream@@QBEPAVfilebuf@@XZ");
+        SET(p_ofstream_setbuf, "?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z");
+        SET(p_ofstream_setmode, "?setmode at ofstream@@QAEHH at Z");
+
         SET(p_istream_copy_ctor, "??0istream@@IAE at ABV0@@Z");
         SET(p_istream_ctor, "??0istream@@IAE at XZ");
         SET(p_istream_sb_ctor, "??0istream@@QAE at PAVstreambuf@@@Z");
@@ -4498,6 +4547,336 @@ static void test_ostrstream(void)
     call_func1(p_ostrstream_vbase_dtor, &os1);
 }
 
+static void test_ofstream(void)
+{
+    const char *filename = "ofstream_test";
+    ostream ofs, ofs_copy, *pofs;
+    streambuf *psb;
+    filebuf *pfb;
+    char buffer[64];
+    char st[8];
+    int fd, ret;
+
+    memset(&ofs, 0xab, sizeof(ostream));
+
+    /* constructors/destructors */
+    pofs = call_func2(p_ofstream_ctor, &ofs, TRUE);
+    pfb = (filebuf*) ofs.base_ios.sb;
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    ok(ofs.unknown == 0, "expected 0 got %d\n", ofs.unknown);
+    ok(ofs.base_ios.sb != NULL, "expected not %p got %p\n", NULL, ofs.base_ios.sb);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ok(ofs.base_ios.delbuf == 1, "expected 1 got %d\n", ofs.base_ios.delbuf);
+    ok(ofs.base_ios.tie == NULL, "expected %p got %p\n", NULL, ofs.base_ios.tie);
+    ok(ofs.base_ios.flags == 0x0, "expected %x got %x\n", 0x0, ofs.base_ios.flags);
+    ok(ofs.base_ios.precision == 6, "expected 6 got %d\n", ofs.base_ios.precision);
+    ok(ofs.base_ios.fill == ' ', "expected 32 got %d\n", ofs.base_ios.fill);
+    ok(ofs.base_ios.width == 0, "expected 0 got %d\n", ofs.base_ios.width);
+    ok(ofs.base_ios.do_lock == -1, "expected -1 got %d\n", ofs.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_ofstream_vbase_dtor, &ofs);
+
+    pofs = call_func3(p_ofstream_fd_ctor, &ofs, 42, TRUE);
+    pfb = (filebuf*) ofs.base_ios.sb;
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ok(ofs.base_ios.delbuf == 1, "expected 1 got %d\n", ofs.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);
+
+    pofs = call_func3(p_ofstream_copy_ctor, &ofs_copy, &ofs, TRUE);
+    pfb = (filebuf*) ofs_copy.base_ios.sb;
+    ok(pofs == &ofs_copy, "wrong return, expected %p got %p\n", &ofs_copy, pofs);
+    ok(ofs_copy.base_ios.sb == ofs.base_ios.sb, "expected shared streambuf\n");
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ok(ofs_copy.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs_copy.base_ios.state);
+
+    call_func1(p_ofstream_vbase_dtor, &ofs_copy);
+    call_func1(p_ofstream_dtor, &ofs.base_ios);
+
+    pofs = call_func5(p_ofstream_buffer_ctor, &ofs, 53, buffer, ARRAY_SIZE(buffer), TRUE);
+    pfb = (filebuf*) ofs.base_ios.sb;
+    ok(ofs.base_ios.delbuf == 1, "expected 1 got %d\n", ofs.base_ios.delbuf);
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    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_ofstream_dtor, &ofs.base_ios);
+
+    pofs = call_func5(p_ofstream_buffer_ctor, &ofs, 64, NULL, 0, TRUE);
+    pfb = (filebuf*) ofs.base_ios.sb;
+    ok(ofs.base_ios.delbuf == 1, "expected 1 got %d\n", ofs.base_ios.delbuf);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    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_ofstream_vbase_dtor, &ofs);
+
+    pofs = call_func5(p_ofstream_open_ctor, &ofs, filename, OPENMODE_out, filebuf_openprot, TRUE);
+    pfb = (filebuf*) ofs.base_ios.sb;
+    ok(ofs.base_ios.delbuf == 1, "expected 1 got %d\n", ofs.base_ios.delbuf);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    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_ofstream_vbase_dtor, &ofs);
+    ok(_close(fd) == -1, "expected ofstream to close opened file\n");
+    ok(_unlink(filename) == 0, "Couldn't unlink file named '%s'\n", filename);
+
+    /* setbuf */
+    call_func5(p_ofstream_buffer_ctor, &ofs, -1, NULL, 0, TRUE);
+    ok(ofs.base_ios.sb->base == NULL, "wrong base value, expected NULL got %p\n", ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == NULL, "wrong ebuf value, expected NULL got %p\n", ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", pfb->base.unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+
+    psb = call_func3(p_ofstream_setbuf, &ofs, buffer, ARRAY_SIZE(buffer));
+    ok(psb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, psb);
+    ok(ofs.base_ios.sb->base == buffer, "wrong buffer, expected %p got %p\n", buffer, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    psb = call_func3(p_ofstream_setbuf, &ofs, NULL, 0);
+    ok(psb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, psb);
+    ok(ofs.base_ios.sb->base == buffer, "wrong buffer, expected %p got %p\n", buffer, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    call_func1(p_ofstream_vbase_dtor, &ofs);
+
+    call_func2(p_ofstream_ctor, &ofs, TRUE);
+    ok(ofs.base_ios.sb->base == NULL, "wrong base value, expected NULL got %p\n", ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == NULL, "wrong ebuf value, expected NULL got %p\n", ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    psb = call_func3(p_ofstream_setbuf, &ofs, buffer, ARRAY_SIZE(buffer));
+    ok(psb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, psb);
+    ok(ofs.base_ios.sb->base == buffer, "wrong buffer, expected %p got %p\n", buffer, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    psb = call_func3(p_ofstream_setbuf, &ofs, NULL, 0);
+    ok(psb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, psb);
+    ok(ofs.base_ios.sb->base == buffer, "wrong buffer, expected %p got %p\n", buffer, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    psb = call_func3(p_ofstream_setbuf, &ofs, buffer + 8, ARRAY_SIZE(buffer) - 8);
+    ok(psb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, psb);
+    ok(ofs.base_ios.sb->base == buffer + 8, "wrong buffer, expected %p got %p\n", buffer + 8, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    psb = call_func3(p_ofstream_setbuf, &ofs, buffer + 8, 0);
+    ok(psb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, psb);
+    ok(ofs.base_ios.sb->base == buffer + 8, "wrong buffer, expected %p got %p\n", buffer + 8, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    psb = call_func3(p_ofstream_setbuf, &ofs, buffer + 4, ARRAY_SIZE(buffer) - 4);
+    ok(psb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, psb);
+    ok(ofs.base_ios.sb->base == buffer + 4, "wrong buffer, expected %p got %p\n", buffer + 4, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    psb = call_func3(p_ofstream_setbuf, &ofs, NULL, 5);
+    ok(psb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, psb);
+    ok(ofs.base_ios.sb->base == buffer + 4, "wrong buffer, expected %p got %p\n", buffer + 4, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == buffer + ARRAY_SIZE(buffer), "wrong ebuf, expected %p got %p\n", buffer + ARRAY_SIZE(buffer), ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    call_func1(p_ofstream_vbase_dtor, &ofs);
+
+    /* setbuf - seems to be a nop and always return NULL in those other cases */
+    pofs = call_func5(p_ofstream_buffer_ctor, &ofs, 42, NULL, 0, TRUE);
+    ok(ofs.base_ios.sb->base == NULL, "wrong base value, expected NULL got %p\n", ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == NULL, "wrong ebuf value, expected NULL got %p\n", ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+
+    ofs.base_ios.state = IOSTATE_eofbit;
+    psb = call_func3(p_ofstream_setbuf, &ofs, buffer, ARRAY_SIZE(buffer));
+    ok(psb == NULL, "wrong return, expected NULL got %p\n", psb);
+    ok(ofs.base_ios.sb->base == NULL, "wrong base value, expected NULL got %p\n", ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == NULL, "wrong ebuf value, expected NULL got %p\n", ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == (IOSTATE_eofbit | IOSTATE_failbit), "attaching on already setup stream did not set failbit\n");
+
+    ofs.base_ios.state = IOSTATE_eofbit;
+    psb = call_func3(p_ofstream_setbuf, &ofs, NULL, 0);
+    ok(psb == NULL, "wrong return, expected NULL got %p\n", psb);
+    ok(ofs.base_ios.sb->base == NULL, "wrong base value, expected NULL got %p\n", ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf == NULL, "wrong ebuf value, expected NULL got %p\n", ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 1, "wrong unbuffered value, expected 1 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 0, "wrong allocated value, expected 0 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == (IOSTATE_eofbit | IOSTATE_failbit), "attaching on already setup stream did not set failbit\n");
+    call_func1(p_ofstream_vbase_dtor, &ofs);
+
+    pofs = call_func5(p_ofstream_open_ctor, &ofs, filename, OPENMODE_out, filebuf_openprot, TRUE);
+    ofs.base_ios.state = IOSTATE_eofbit;
+    psb = call_func3(p_ofstream_setbuf, &ofs, NULL, 0);
+    ok(psb == NULL, "wrong return, expected NULL got %p\n", psb);
+    ok(ofs.base_ios.sb->base != NULL, "wrong base value, expected NULL got %p\n", ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->ebuf != NULL, "wrong ebuf value, expected NULL got %p\n", ofs.base_ios.sb->ebuf);
+    ok(ofs.base_ios.sb->unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 1, "wrong allocated value, expected 1 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == (IOSTATE_eofbit | IOSTATE_failbit), "attaching on already setup stream did not set failbit\n");
+
+    ofs.base_ios.state = IOSTATE_eofbit;
+    psb = call_func3(p_ofstream_setbuf, &ofs, buffer, ARRAY_SIZE(buffer));
+    ok(psb == NULL, "wrong return, expected NULL got %p\n", psb);
+    ok(ofs.base_ios.sb->base != NULL, "wrong base value, expected NULL got %p\n", ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->base != buffer, "wrong base value, expected not %p got %p\n", buffer, ofs.base_ios.sb->base);
+    ok(ofs.base_ios.sb->unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", ofs.base_ios.sb->unbuffered);
+    ok(ofs.base_ios.sb->allocated == 1, "wrong allocated value, expected 1 got %d\n", ofs.base_ios.sb->allocated);
+    ok(ofs.base_ios.state == (IOSTATE_eofbit | IOSTATE_failbit), "attaching on already setup stream did not set failbit\n");
+    call_func1(p_ofstream_vbase_dtor, &ofs);
+    ok(_unlink(filename) == 0, "Couldn't unlink file named '%s'\n", filename);
+
+    /* attach */
+    pofs = call_func2(p_ofstream_ctor, &ofs, TRUE);
+    pfb = (filebuf*) ofs.base_ios.sb;
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    call_func2(p_ofstream_attach, &ofs, 42);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "attaching on vanilla stream set some state bits\n");
+    fd = (int) call_func1(p_ofstream_fd, &ofs);
+    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);
+    ofs.base_ios.state = IOSTATE_eofbit;
+    call_func2(p_ofstream_attach, &ofs, 53);
+    ok(ofs.base_ios.state == (IOSTATE_eofbit | IOSTATE_failbit), "attaching on already setup stream did not set failbit\n");
+    ok(fd == 42, "wrong fd, expected 42 got %d\n", fd);
+    call_func1(p_ofstream_vbase_dtor, &ofs);
+
+    /* fd */
+    pofs = call_func2(p_ofstream_ctor, &ofs, TRUE);
+    pfb = (filebuf*) ofs.base_ios.sb;
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    fd = (int) call_func1(p_ofstream_fd, &ofs);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ok(fd == -1, "wrong fd, expected -1 but got %d\n", fd);
+    call_func1(p_ofstream_vbase_dtor, &ofs);
+
+    pofs = call_func5(p_ofstream_open_ctor, &ofs, filename, OPENMODE_out, filebuf_openprot, TRUE);
+    pfb = (filebuf*) ofs.base_ios.sb;
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    fd = (int) call_func1(p_ofstream_fd, &ofs);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ok(fd == pfb->fd, "wrong fd, expected %d but got %d\n", pfb->fd, fd);
+
+    /* rdbuf */
+    pfb = (filebuf*) call_func1(p_ofstream_rdbuf, &ofs);
+    ok((streambuf*) pfb == ofs.base_ios.sb, "wrong return, expected %p got %p\n", ofs.base_ios.sb, pfb);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    /* setmode */
+    ret = (int) call_func2(p_ofstream_setmode, &ofs, filebuf_binary);
+    ok(ret == filebuf_text, "wrong return, expected %d got %d\n", filebuf_text, ret);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ret = (int) call_func2(p_ofstream_setmode, &ofs, filebuf_binary);
+    ok(ret == filebuf_binary, "wrong return, expected %d got %d\n", filebuf_binary, ret);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ret = (int) call_func2(p_ofstream_setmode, &ofs, filebuf_text);
+    ok(ret == filebuf_binary, "wrong return, expected %d got %d\n", filebuf_binary, ret);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+    ret = (int) call_func2(p_ofstream_setmode, &ofs, 0x9000);
+    ok(ret == -1, "wrong return, expected -1 got %d\n", ret);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, ofs.base_ios.state);
+
+    /* close && is_open */
+    ok((int) call_func1(p_ofstream_is_open, &ofs) == 1, "expected ofstream to be open\n");
+    ofs.base_ios.state = IOSTATE_eofbit | IOSTATE_failbit;
+    call_func1(p_ofstream_close, &ofs);
+    ok(ofs.base_ios.state == IOSTATE_goodbit, "close did not clear state = %d\n", ofs.base_ios.state);
+    ofs.base_ios.state = IOSTATE_eofbit;
+    call_func1(p_ofstream_close, &ofs);
+    ok(ofs.base_ios.state == (IOSTATE_eofbit | IOSTATE_failbit), "close on a closed stream did not set failbit\n");
+    ok((int) call_func1(p_ofstream_is_open, &ofs) == 0, "expected ofstream to not be open\n");
+    ok(_close(fd) == -1, "expected close to close the opened file\n");
+
+    /* open */
+    ofs.base_ios.state = IOSTATE_eofbit;
+    call_func4(p_ofstream_open, &ofs, filename, OPENMODE_out, filebuf_openprot);
+    fd = (int) call_func1(p_ofstream_fd, &ofs);
+    ok(fd != -1, "wrong fd, expected not -1 got %d\n", fd);
+    ok(ofs.base_ios.state == IOSTATE_eofbit, "open did not succeed\n");
+    call_func4(p_ofstream_open, &ofs, filename, OPENMODE_out, filebuf_openprot);
+    ok(ofs.base_ios.state == (IOSTATE_eofbit | IOSTATE_failbit), "second open did not set failbit\n");
+    call_func1(p_ofstream_close, &ofs);
+
+    /* integration with parent ostream - writing */
+    ofs.base_ios.state = IOSTATE_goodbit; /* open doesn't clear the state */
+    call_func4(p_ofstream_open, &ofs, filename, OPENMODE_in, filebuf_openprot); /* make sure that OPENMODE_out is implicit */
+    pofs = call_func3(p_ostream_write_char, &ofs, "testing", 7);
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    call_func1(p_ofstream_close, &ofs);
+
+    /* read what we wrote */
+    fd = _open(filename, _O_RDONLY, _S_IREAD);
+    ok(fd != -1, "_open failed\n");
+    ok(_read(fd, st, 7) == 7, "_read failed\n");
+    ok(_close(fd) == 0, "_close failed\n");
+    ok(!strcmp(st, "testing"), "expected 'testing' got '%s'\n", st);
+    call_func1(p_ofstream_vbase_dtor, &ofs);
+    ok(_unlink(filename) == 0, "Couldn't unlink file named '%s'\n", filename);
+
+    /* make sure that OPENMODE_out is implicit with open_ctor */
+    pofs = call_func5(p_ofstream_open_ctor, &ofs, filename, OPENMODE_in, filebuf_openprot, TRUE);
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    pofs = call_func3(p_ostream_write_char, &ofs, "testing", 7);
+    ok(pofs == &ofs, "wrong return, expected %p got %p\n", &ofs, pofs);
+    call_func1(p_ofstream_close, &ofs);
+
+    fd = _open(filename, _O_RDONLY, _S_IREAD);
+    ok(fd != -1, "_open failed\n");
+    ok(_read(fd, st, 7) == 7, "_read failed\n");
+    ok(_close(fd) == 0, "_close failed\n");
+    ok(!strcmp(st, "testing"), "expected 'testing' got '%s'\n", st);
+    call_func1(p_ofstream_vbase_dtor, &ofs);
+    ok(_unlink(filename) == 0, "Couldn't unlink file named '%s'\n", filename);
+}
+
 static void test_istream(void)
 {
     istream is1, is2, *pis;
@@ -8092,6 +8471,7 @@ START_TEST(msvcirt)
     test_ostream_print();
     test_ostream_withassign();
     test_ostrstream();
+    test_ofstream();
     test_istream();
     test_istream_getint();
     test_istream_getdouble();
diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec
index 33383c1d33..907d3ffed6 100644
--- a/dlls/msvcrt20/msvcrt20.spec
+++ b/dlls/msvcrt20/msvcrt20.spec
@@ -60,16 +60,16 @@
 @ cdecl -arch=win64 ??0istrstream@@QEAA at PEAD@Z(ptr ptr long) msvcirt.??0istrstream@@QEAA at PEAD@Z
 @ thiscall -arch=win32 ??0istrstream@@QAE at PADH@Z(ptr ptr long long) msvcirt.??0istrstream@@QAE at PADH@Z
 @ cdecl -arch=win64 ??0istrstream@@QEAA at PEADH@Z(ptr ptr long long) msvcirt.??0istrstream@@QEAA at PEADH@Z
-@ stub -arch=win32 ??0ofstream@@QAE at ABV0@@Z
-@ stub -arch=win64 ??0ofstream@@QEAA at AEBV0@@Z
-@ stub -arch=win32 ??0ofstream@@QAE at H@Z
-@ stub -arch=win64 ??0ofstream@@QEAA at H@Z
-@ stub -arch=win32 ??0ofstream@@QAE at HPADH@Z
-@ stub -arch=win64 ??0ofstream@@QEAA at HPEADH@Z
-@ stub -arch=win32 ??0ofstream@@QAE at PBDHH@Z
-@ stub -arch=win64 ??0ofstream@@QEAA at PEBDHH@Z
-@ stub -arch=win32 ??0ofstream@@QAE at XZ
-@ stub -arch=win64 ??0ofstream@@QEAA at XZ
+@ thiscall -arch=win32 ??0ofstream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0ofstream@@QAE at ABV0@@Z
+@ cdecl -arch=win64 ??0ofstream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0ofstream@@QEAA at AEBV0@@Z
+@ thiscall -arch=win32 ??0ofstream@@QAE at H@Z(ptr long long) msvcirt.??0ofstream@@QAE at H@Z
+@ cdecl -arch=win64 ??0ofstream@@QEAA at H@Z(ptr long long) msvcirt.??0ofstream@@QEAA at H@Z
+@ thiscall -arch=win32 ??0ofstream@@QAE at HPADH@Z(ptr long ptr long long) msvcirt.??0ofstream@@QAE at HPADH@Z
+@ cdecl -arch=win64 ??0ofstream@@QEAA at HPEADH@Z(ptr long ptr long long) msvcirt.??0ofstream@@QEAA at HPEADH@Z
+@ thiscall -arch=win32 ??0ofstream@@QAE at PBDHH@Z(ptr str long long long) msvcirt.??0ofstream@@QAE at PBDHH@Z
+@ cdecl -arch=win64 ??0ofstream@@QEAA at PEBDHH@Z(ptr str long long long) msvcirt.??0ofstream@@QEAA at PEBDHH@Z
+@ thiscall -arch=win32 ??0ofstream@@QAE at XZ(ptr long) msvcirt.??0ofstream@@QAE at XZ
+@ cdecl -arch=win64 ??0ofstream@@QEAA at XZ(ptr long) msvcirt.??0ofstream@@QEAA at XZ
 @ thiscall -arch=win32 ??0ostream@@IAE at ABV0@@Z(ptr ptr long) msvcirt.??0ostream@@IAE at ABV0@@Z
 @ cdecl -arch=win64 ??0ostream@@IEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0ostream@@IEAA at AEBV0@@Z
 @ thiscall -arch=win32 ??0ostream@@IAE at XZ(ptr long) msvcirt.??0ostream@@IAE at XZ
@@ -136,8 +136,8 @@
 @ cdecl -arch=win64 ??1istream_withassign@@UEAA at XZ(ptr) msvcirt.??1istream_withassign@@UEAA at XZ
 @ thiscall -arch=win32 ??1istrstream@@UAE at XZ(ptr) msvcirt.??1istrstream@@UAE at XZ
 @ cdecl -arch=win64 ??1istrstream@@UEAA at XZ(ptr) msvcirt.??1istrstream@@UEAA at XZ
-@ stub -arch=win32 ??1ofstream@@UAE at XZ
-@ stub -arch=win64 ??1ofstream@@UEAA at XZ
+@ thiscall -arch=win32 ??1ofstream@@UAE at XZ(ptr) msvcirt.??1ofstream@@UAE at XZ
+@ cdecl -arch=win64 ??1ofstream@@UEAA at XZ(ptr) msvcirt.??1ofstream@@UEAA at XZ
 @ thiscall -arch=win32 ??1ostream@@UAE at XZ(ptr) msvcirt.??1ostream@@UAE at XZ
 @ cdecl -arch=win64 ??1ostream@@UEAA at XZ(ptr) msvcirt.??1ostream@@UEAA at XZ
 @ thiscall -arch=win32 ??1ostream_withassign@@UAE at XZ(ptr) msvcirt.??1ostream_withassign@@UAE at XZ
@@ -184,8 +184,8 @@
 @ cdecl -arch=win64 ??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z(ptr ptr) msvcirt.??4istream_withassign@@QEAAAEAVistream@@PEAVstreambuf@@@Z
 @ thiscall -arch=win32 ??4istrstream@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4istrstream@@QAEAAV0 at ABV0@@Z
 @ cdecl -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4istrstream@@QEAAAEAV0 at AEBV0@@Z
-@ stub -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z
-@ stub -arch=win64 ??4ofstream@@QEAAAEAV0 at AEBV0@@Z
+@ thiscall -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4ofstream@@QAEAAV0 at ABV0@@Z
+@ cdecl -arch=win64 ??4ofstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4ofstream@@QEAAAEAV0 at AEBV0@@Z
 @ thiscall -arch=win32 ??4ostream@@IAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4ostream@@IAEAAV0 at ABV0@@Z
 @ cdecl -arch=win64 ??4ostream@@IEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4ostream@@IEAAAEAV0 at AEBV0@@Z
 @ thiscall -arch=win32 ??4ostream@@IAEAAV0 at PAVstreambuf@@@Z(ptr ptr) msvcirt.??4ostream@@IAEAAV0 at PAVstreambuf@@@Z
@@ -294,7 +294,7 @@
 @ extern ??_7istream@@6B@ msvcirt.??_7istream@@6B@
 @ extern ??_7istream_withassign@@6B@ msvcirt.??_7istream_withassign@@6B@
 @ extern ??_7istrstream@@6B@ msvcirt.??_7istrstream@@6B@
-# @ extern ??_7ofstream@@6B@
+@ extern ??_7ofstream@@6B@ msvcirt.??_7ofstream@@6B@
 @ extern ??_7ostream@@6B@ msvcirt.??_7ostream@@6B@
 @ extern ??_7ostream_withassign@@6B@ msvcirt.??_7ostream_withassign@@6B@
 @ extern ??_7ostrstream@@6B@ msvcirt.??_7ostrstream@@6B@
@@ -311,7 +311,7 @@
 @ extern ??_8istream@@7B@ msvcirt.??_8istream@@7B@
 @ extern ??_8istream_withassign@@7B@ msvcirt.??_8istream_withassign@@7B@
 @ extern ??_8istrstream@@7B@ msvcirt.??_8istrstream@@7B@
-# @ extern ??_8ofstream@@7B@
+@ extern ??_8ofstream@@7B@ msvcirt.??_8ofstream@@7B@
 @ extern ??_8ostream@@7B@ msvcirt.??_8ostream@@7B@
 @ extern ??_8ostream_withassign@@7B@ msvcirt.??_8ostream_withassign@@7B@
 @ extern ??_8ostrstream@@7B@ msvcirt.??_8ostrstream@@7B@
@@ -331,8 +331,8 @@
 @ cdecl -arch=win64 ??_Distream_withassign@@QEAAXXZ(ptr) msvcirt.??_Distream_withassign@@QEAAXXZ
 @ thiscall -arch=win32 ??_Distrstream@@QAEXXZ(ptr) msvcirt.??_Distrstream@@QAEXXZ
 @ cdecl -arch=win64 ??_Distrstream@@QEAAXXZ(ptr) msvcirt.??_Distrstream@@QEAAXXZ
-@ stub -arch=win32 ??_Dofstream@@QAEXXZ
-@ stub -arch=win64 ??_Dofstream@@QEAAXXZ
+@ thiscall -arch=win32 ??_Dofstream@@QAEXXZ(ptr) msvcirt.??_Dofstream@@QAEXXZ
+@ cdecl -arch=win64 ??_Dofstream@@QEAAXXZ(ptr) msvcirt.??_Dofstream@@QEAAXXZ
 @ thiscall -arch=win32 ??_Dostream@@QAEXXZ(ptr) msvcirt.??_Dostream@@QAEXXZ
 @ cdecl -arch=win64 ??_Dostream@@QEAAXXZ(ptr) msvcirt.??_Dostream@@QEAAXXZ
 @ thiscall -arch=win32 ??_Dostream_withassign@@QAEXXZ(ptr) msvcirt.??_Dostream_withassign@@QAEXXZ
@@ -352,7 +352,7 @@
 @ thiscall -arch=win32 ??_Eistream@@UAEPAXI at Z(ptr long) msvcirt.??_Eistream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eistream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eistream_withassign@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eistrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eistrstream@@UAEPAXI at Z
-@ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z
+@ thiscall -arch=win32 ??_Eofstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eofstream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream_withassign@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostrstream@@UAEPAXI at Z
@@ -370,7 +370,7 @@
 @ thiscall -arch=win32 ??_Gistream@@UAEPAXI at Z(ptr long) msvcirt.??_Gistream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gistream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gistream_withassign@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gistrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gistrstream@@UAEPAXI at Z
-@ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z
+@ thiscall -arch=win32 ??_Gofstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gofstream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream_withassign@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostrstream@@UAEPAXI at Z
@@ -396,8 +396,8 @@
 @ stub -arch=win64 ?attach at fstream@@QEAAXH at Z
 @ thiscall -arch=win32 ?attach at ifstream@@QAEXH at Z(ptr long) msvcirt.?attach at ifstream@@QAEXH at Z
 @ cdecl -arch=win64 ?attach at ifstream@@QEAAXH at Z(ptr long) msvcirt.?attach at ifstream@@QEAAXH at Z
-@ stub -arch=win32 ?attach at ofstream@@QAEXH at Z
-@ stub -arch=win64 ?attach at ofstream@@QEAAXH at Z
+@ thiscall -arch=win32 ?attach at ofstream@@QAEXH at Z(ptr long) msvcirt.?attach at ofstream@@QAEXH at Z
+@ cdecl -arch=win64 ?attach at ofstream@@QEAAXH at Z(ptr long) msvcirt.?attach at ofstream@@QEAAXH at Z
 @ thiscall -arch=win32 ?bad at ios@@QBEHXZ(ptr) msvcirt.?bad at ios@@QBEHXZ
 @ cdecl -arch=win64 ?bad at ios@@QEBAHXZ(ptr) msvcirt.?bad at ios@@QEBAHXZ
 @ thiscall -arch=win32 ?base at streambuf@@IBEPADXZ(ptr) msvcirt.?base at streambuf@@IBEPADXZ
@@ -418,8 +418,8 @@
 @ stub -arch=win64 ?close at fstream@@QEAAXXZ
 @ thiscall -arch=win32 ?close at ifstream@@QAEXXZ(ptr) msvcirt.?close at ifstream@@QAEXXZ
 @ cdecl -arch=win64 ?close at ifstream@@QEAAXXZ(ptr) msvcirt.?close at ifstream@@QEAAXXZ
-@ stub -arch=win32 ?close at ofstream@@QAEXXZ
-@ stub -arch=win64 ?close at ofstream@@QEAAXXZ
+@ thiscall -arch=win32 ?close at ofstream@@QAEXXZ(ptr) msvcirt.?close at ofstream@@QAEXXZ
+@ cdecl -arch=win64 ?close at ofstream@@QEAAXXZ(ptr) msvcirt.?close at ofstream@@QEAAXXZ
 @ cdecl -arch=win32 ?clrlock at ios@@QAAXXZ(ptr) msvcirt.?clrlock at ios@@QAAXXZ
 @ cdecl -arch=win64 ?clrlock at ios@@QEAAXXZ(ptr) msvcirt.?clrlock at ios@@QEAAXXZ
 @ thiscall -arch=win32 ?clrlock at streambuf@@QAEXXZ(ptr) msvcirt.?clrlock at streambuf@@QAEXXZ
@@ -462,8 +462,8 @@
 @ stub -arch=win64 ?fd at fstream@@QEBAHXZ
 @ thiscall -arch=win32 ?fd at ifstream@@QBEHXZ(ptr) msvcirt.?fd at ifstream@@QBEHXZ
 @ cdecl -arch=win64 ?fd at ifstream@@QEBAHXZ(ptr) msvcirt.?fd at ifstream@@QEBAHXZ
-@ stub -arch=win32 ?fd at ofstream@@QBEHXZ
-@ stub -arch=win64 ?fd at ofstream@@QEBAHXZ
+@ thiscall -arch=win32 ?fd at ofstream@@QBEHXZ(ptr) msvcirt.?fd at ofstream@@QBEHXZ
+@ cdecl -arch=win64 ?fd at ofstream@@QEBAHXZ(ptr) msvcirt.?fd at ofstream@@QEBAHXZ
 @ thiscall -arch=win32 ?fill at ios@@QAEDD at Z(ptr long) msvcirt.?fill at ios@@QAEDD at Z
 @ cdecl -arch=win64 ?fill at ios@@QEAADD at Z(ptr long) msvcirt.?fill at ios@@QEAADD at Z
 @ thiscall -arch=win32 ?fill at ios@@QBEDXZ(ptr) msvcirt.?fill at ios@@QBEDXZ
@@ -529,8 +529,8 @@
 @ stub -arch=win64 ?is_open at fstream@@QEBAHXZ
 @ thiscall -arch=win32 ?is_open at ifstream@@QBEHXZ(ptr) msvcirt.?is_open at ifstream@@QBEHXZ
 @ cdecl -arch=win64 ?is_open at ifstream@@QEBAHXZ(ptr) msvcirt.?is_open at ifstream@@QEBAHXZ
-@ stub -arch=win32 ?is_open at ofstream@@QBEHXZ
-@ stub -arch=win64 ?is_open at ofstream@@QEBAHXZ
+@ thiscall -arch=win32 ?is_open at ofstream@@QBEHXZ(ptr) msvcirt.?is_open at ofstream@@QBEHXZ
+@ cdecl -arch=win64 ?is_open at ofstream@@QEBAHXZ(ptr) msvcirt.?is_open at ofstream@@QEBAHXZ
 @ thiscall -arch=win32 ?isfx at istream@@QAEXXZ(ptr) msvcirt.?isfx at istream@@QAEXXZ
 @ cdecl -arch=win64 ?isfx at istream@@QEAAXXZ(ptr) msvcirt.?isfx at istream@@QEAAXXZ
 @ thiscall -arch=win32 ?iword at ios@@QBEAAJH at Z(ptr long) msvcirt.?iword at ios@@QBEAAJH at Z
@@ -554,8 +554,8 @@
 @ stub -arch=win64 ?open at fstream@@QEAAXPEBDHH at Z
 @ thiscall -arch=win32 ?open at ifstream@@QAEXPBDHH at Z(ptr str long long) msvcirt.?open at ifstream@@QAEXPBDHH at Z
 @ cdecl -arch=win64 ?open at ifstream@@QEAAXPEBDHH at Z(ptr str long long) msvcirt.?open at ifstream@@QEAAXPEBDHH at Z
-@ stub -arch=win32 ?open at ofstream@@QAEXPBDHH at Z
-@ stub -arch=win64 ?open at ofstream@@QEAAXPEBDHH at Z
+@ thiscall -arch=win32 ?open at ofstream@@QAEXPBDHH at Z(ptr str long long) msvcirt.?open at ofstream@@QAEXPBDHH at Z
+@ cdecl -arch=win64 ?open at ofstream@@QEAAXPEBDHH at Z(ptr str long long) msvcirt.?open at ofstream@@QEAAXPEBDHH at Z
 @ extern ?openprot at filebuf@@2HB msvcirt.?openprot at filebuf@@2HB
 @ thiscall -arch=win32 ?opfx at ostream@@QAEHXZ(ptr) msvcirt.?opfx at ostream@@QAEHXZ
 @ cdecl -arch=win64 ?opfx at ostream@@QEAAHXZ(ptr) msvcirt.?opfx at ostream@@QEAAHXZ
@@ -607,8 +607,8 @@
 @ cdecl -arch=win64 ?rdbuf at ios@@QEBAPEAVstreambuf@@XZ(ptr) msvcirt.?rdbuf at ios@@QEBAPEAVstreambuf@@XZ
 @ thiscall -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ
 @ cdecl -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ
-@ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ
-@ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ
+@ thiscall -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ(ptr) msvcirt.?rdbuf at ofstream@@QBEPAVfilebuf@@XZ
+@ cdecl -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ(ptr) msvcirt.?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ
 @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ
 @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ
 @ thiscall -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ(ptr) msvcirt.?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ
@@ -653,8 +653,8 @@
 @ stub -arch=win64 ?setbuf at fstream@@QEAAPEAVstreambuf@@PEADH at Z
 @ thiscall -arch=win32 ?setbuf at ifstream@@QAEPAVstreambuf@@PADH at Z(ptr ptr long) msvcirt.?setbuf at ifstream@@QAEPAVstreambuf@@PADH at Z
 @ cdecl -arch=win64 ?setbuf at ifstream@@QEAAPEAVstreambuf@@PEADH at Z(ptr ptr long) msvcirt.?setbuf at ifstream@@QEAAPEAVstreambuf@@PEADH at Z
-@ stub -arch=win32 ?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z
-@ stub -arch=win64 ?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z
+@ thiscall -arch=win32 ?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z(ptr ptr long) msvcirt.?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z
+@ cdecl -arch=win64 ?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z(ptr ptr long) msvcirt.?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z
 @ thiscall -arch=win32 ?setbuf at streambuf@@UAEPAV1 at PADH@Z(ptr ptr long) msvcirt.?setbuf at streambuf@@UAEPAV1 at PADH@Z
 @ cdecl -arch=win64 ?setbuf at streambuf@@UEAAPEAV1 at PEADH@Z(ptr ptr long) msvcirt.?setbuf at streambuf@@UEAAPEAV1 at PEADH@Z
 @ thiscall -arch=win32 ?setbuf at strstreambuf@@UAEPAVstreambuf@@PADH at Z(ptr ptr long) msvcirt.?setbuf at strstreambuf@@UAEPAVstreambuf@@PADH at Z
@@ -675,8 +675,8 @@
 @ stub -arch=win64 ?setmode at fstream@@QEAAHH at Z
 @ thiscall -arch=win32 ?setmode at ifstream@@QAEHH at Z(ptr long) msvcirt.?setmode at ifstream@@QAEHH at Z
 @ cdecl -arch=win64 ?setmode at ifstream@@QEAAHH at Z(ptr long) msvcirt.?setmode at ifstream@@QEAAHH at Z
-@ stub -arch=win32 ?setmode at ofstream@@QAEHH at Z
-@ stub -arch=win64 ?setmode at ofstream@@QEAAHH at Z
+@ thiscall -arch=win32 ?setmode at ofstream@@QAEHH at Z(ptr long) msvcirt.?setmode at ofstream@@QAEHH at Z
+@ cdecl -arch=win64 ?setmode at ofstream@@QEAAHH at Z(ptr long) msvcirt.?setmode at ofstream@@QEAAHH at Z
 @ thiscall -arch=win32 ?setp at streambuf@@IAEXPAD0 at Z(ptr ptr ptr) msvcirt.?setp at streambuf@@IAEXPAD0 at Z
 @ cdecl -arch=win64 ?setp at streambuf@@IEAAXPEAD0 at Z(ptr ptr ptr) msvcirt.?setp at streambuf@@IEAAXPEAD0 at Z
 @ thiscall -arch=win32 ?setrwbuf at stdiobuf@@QAEHHH at Z(ptr long long) msvcirt.?setrwbuf at stdiobuf@@QAEHHH at Z
diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec
index 9f09cfdc8b..9e25f4f2bc 100644
--- a/dlls/msvcrt40/msvcrt40.spec
+++ b/dlls/msvcrt40/msvcrt40.spec
@@ -82,16 +82,16 @@
 @ cdecl -arch=win64 ??0logic_error@@QEAA at AEBQEBD@Z(ptr ptr) msvcirt.??0logic_error@@QEAA at AEBQEBD@Z
 @ thiscall -arch=win32 ??0logic_error@@QAE at ABV0@@Z(ptr ptr) msvcirt.??0logic_error@@QAE at ABV0@@Z
 @ cdecl -arch=win64 ??0logic_error@@QEAA at AEBV0@@Z(ptr ptr) msvcirt.??0logic_error@@QEAA at AEBV0@@Z
-@ stub -arch=win32 ??0ofstream@@QAE at ABV0@@Z
-@ stub -arch=win64 ??0ofstream@@QEAA at AEBV0@@Z
-@ stub -arch=win32 ??0ofstream@@QAE at H@Z
-@ stub -arch=win64 ??0ofstream@@QEAA at H@Z
-@ stub -arch=win32 ??0ofstream@@QAE at HPADH@Z
-@ stub -arch=win64 ??0ofstream@@QEAA at HPEADH@Z
-@ stub -arch=win32 ??0ofstream@@QAE at PBDHH@Z
-@ stub -arch=win64 ??0ofstream@@QEAA at PEBDHH@Z
-@ stub -arch=win32 ??0ofstream@@QAE at XZ
-@ stub -arch=win64 ??0ofstream@@QEAA at XZ
+@ thiscall -arch=win32 ??0ofstream@@QAE at ABV0@@Z(ptr ptr long) msvcirt.??0ofstream@@QAE at ABV0@@Z
+@ cdecl -arch=win64 ??0ofstream@@QEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0ofstream@@QEAA at AEBV0@@Z
+@ thiscall -arch=win32 ??0ofstream@@QAE at H@Z(ptr long long) msvcirt.??0ofstream@@QAE at H@Z
+@ cdecl -arch=win64 ??0ofstream@@QEAA at H@Z(ptr long long) msvcirt.??0ofstream@@QEAA at H@Z
+@ thiscall -arch=win32 ??0ofstream@@QAE at HPADH@Z(ptr long ptr long long) msvcirt.??0ofstream@@QAE at HPADH@Z
+@ cdecl -arch=win64 ??0ofstream@@QEAA at HPEADH@Z(ptr long ptr long long) msvcirt.??0ofstream@@QEAA at HPEADH@Z
+@ thiscall -arch=win32 ??0ofstream@@QAE at PBDHH@Z(ptr str long long long) msvcirt.??0ofstream@@QAE at PBDHH@Z
+@ cdecl -arch=win64 ??0ofstream@@QEAA at PEBDHH@Z(ptr str long long long) msvcirt.??0ofstream@@QEAA at PEBDHH@Z
+@ thiscall -arch=win32 ??0ofstream@@QAE at XZ(ptr long) msvcirt.??0ofstream@@QAE at XZ
+@ cdecl -arch=win64 ??0ofstream@@QEAA at XZ(ptr long) msvcirt.??0ofstream@@QEAA at XZ
 @ thiscall -arch=win32 ??0ostream@@IAE at ABV0@@Z(ptr ptr long) msvcirt.??0ostream@@IAE at ABV0@@Z
 @ cdecl -arch=win64 ??0ostream@@IEAA at AEBV0@@Z(ptr ptr long) msvcirt.??0ostream@@IEAA at AEBV0@@Z
 @ thiscall -arch=win32 ??0ostream@@IAE at XZ(ptr long) msvcirt.??0ostream@@IAE at XZ
@@ -168,8 +168,8 @@
 @ cdecl -arch=win64 ??1istrstream@@UEAA at XZ(ptr) msvcirt.??1istrstream@@UEAA at XZ
 @ thiscall -arch=win32 ??1logic_error@@UAE at XZ(ptr) msvcirt.??1logic_error@@UAE at XZ
 @ cdecl -arch=win64 ??1logic_error@@UEAA at XZ(ptr) msvcirt.??1logic_error@@UEAA at XZ
-@ stub -arch=win32 ??1ofstream@@UAE at XZ
-@ stub -arch=win64 ??1ofstream@@UEAA at XZ
+@ thiscall -arch=win32 ??1ofstream@@UAE at XZ(ptr) msvcirt.??1ofstream@@UAE at XZ
+@ cdecl -arch=win64 ??1ofstream@@UEAA at XZ(ptr) msvcirt.??1ofstream@@UEAA at XZ
 @ thiscall -arch=win32 ??1ostream@@UAE at XZ(ptr) msvcirt.??1ostream@@UAE at XZ
 @ cdecl -arch=win64 ??1ostream@@UEAA at XZ(ptr) msvcirt.??1ostream@@UEAA at XZ
 @ thiscall -arch=win32 ??1ostream_withassign@@UAE at XZ(ptr) msvcirt.??1ostream_withassign@@UAE at XZ
@@ -228,8 +228,8 @@
 @ cdecl -arch=win64 ??4istrstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4istrstream@@QEAAAEAV0 at AEBV0@@Z
 @ thiscall -arch=win32 ??4logic_error@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4logic_error@@QAEAAV0 at ABV0@@Z
 @ cdecl -arch=win64 ??4logic_error@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4logic_error@@QEAAAEAV0 at AEBV0@@Z
-@ stub -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z
-@ stub -arch=win64 ??4ofstream@@QEAAAEAV0 at AEBV0@@Z
+@ thiscall -arch=win32 ??4ofstream@@QAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4ofstream@@QAEAAV0 at ABV0@@Z
+@ cdecl -arch=win64 ??4ofstream@@QEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4ofstream@@QEAAAEAV0 at AEBV0@@Z
 @ thiscall -arch=win32 ??4ostream@@IAEAAV0 at ABV0@@Z(ptr ptr) msvcirt.??4ostream@@IAEAAV0 at ABV0@@Z
 @ cdecl -arch=win64 ??4ostream@@IEAAAEAV0 at AEBV0@@Z(ptr ptr) msvcirt.??4ostream@@IEAAAEAV0 at AEBV0@@Z
 @ thiscall -arch=win32 ??4ostream@@IAEAAV0 at PAVstreambuf@@@Z(ptr ptr) msvcirt.??4ostream@@IAEAAV0 at PAVstreambuf@@@Z
@@ -347,7 +347,7 @@
 @ extern ??_7istream_withassign@@6B@ msvcirt.??_7istream_withassign@@6B@
 @ extern ??_7istrstream@@6B@ msvcirt.??_7istrstream@@6B@
 @ extern ??_7logic_error@@6B@ msvcirt.??_7logic_error@@6B@
-# @ extern ??_7ofstream@@6B@
+@ extern ??_7ofstream@@6B@ msvcirt.??_7ofstream@@6B@
 @ extern ??_7ostream@@6B@ msvcirt.??_7ostream@@6B@
 @ extern ??_7ostream_withassign@@6B@ msvcirt.??_7ostream_withassign@@6B@
 @ extern ??_7ostrstream@@6B@ msvcirt.??_7ostrstream@@6B@
@@ -364,7 +364,7 @@
 @ extern ??_8istream@@7B@ msvcirt.??_8istream@@7B@
 @ extern ??_8istream_withassign@@7B@ msvcirt.??_8istream_withassign@@7B@
 @ extern ??_8istrstream@@7B@ msvcirt.??_8istrstream@@7B@
-# @ extern ??_8ofstream@@7B@
+@ extern ??_8ofstream@@7B@ msvcirt.??_8ofstream@@7B@
 @ extern ??_8ostream@@7B@ msvcirt.??_8ostream@@7B@
 @ extern ??_8ostream_withassign@@7B@ msvcirt.??_8ostream_withassign@@7B@
 @ extern ??_8ostrstream@@7B@ msvcirt.??_8ostrstream@@7B@
@@ -384,8 +384,8 @@
 @ cdecl -arch=win64 ??_Distream_withassign@@QEAAXXZ(ptr) msvcirt.??_Distream_withassign@@QEAAXXZ
 @ thiscall -arch=win32 ??_Distrstream@@QAEXXZ(ptr) msvcirt.??_Distrstream@@QAEXXZ
 @ cdecl -arch=win64 ??_Distrstream@@QEAAXXZ(ptr) msvcirt.??_Distrstream@@QEAAXXZ
-@ stub -arch=win32 ??_Dofstream@@QAEXXZ
-@ stub -arch=win64 ??_Dofstream@@QEAAXXZ
+@ thiscall -arch=win32 ??_Dofstream@@QAEXXZ(ptr) msvcirt.??_Dofstream@@QAEXXZ
+@ cdecl -arch=win64 ??_Dofstream@@QEAAXXZ(ptr) msvcirt.??_Dofstream@@QEAAXXZ
 @ thiscall -arch=win32 ??_Dostream@@QAEXXZ(ptr) msvcirt.??_Dostream@@QAEXXZ
 @ cdecl -arch=win64 ??_Dostream@@QEAAXXZ(ptr) msvcirt.??_Dostream@@QEAAXXZ
 @ thiscall -arch=win32 ??_Dostream_withassign@@QAEXXZ(ptr) msvcirt.??_Dostream_withassign@@QAEXXZ
@@ -410,7 +410,7 @@
 @ thiscall -arch=win32 ??_Eistream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eistream_withassign@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eistrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eistrstream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Elogic_error@@UAEPAXI at Z(ptr long) msvcirt.??_Elogic_error@@UAEPAXI at Z
-@ stub -arch=win32 ??_Eofstream@@UAEPAXI at Z
+@ thiscall -arch=win32 ??_Eofstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eofstream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eostream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Eostream_withassign@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Eostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Eostrstream@@UAEPAXI at Z
@@ -433,7 +433,7 @@
 @ thiscall -arch=win32 ??_Gistream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gistream_withassign@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gistrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gistrstream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Glogic_error@@UAEPAXI at Z(ptr long) msvcirt.??_Glogic_error@@UAEPAXI at Z
-@ stub -arch=win32 ??_Gofstream@@UAEPAXI at Z
+@ thiscall -arch=win32 ??_Gofstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gofstream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gostream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gostream_withassign@@UAEPAXI at Z(ptr long) msvcirt.??_Gostream_withassign@@UAEPAXI at Z
 @ thiscall -arch=win32 ??_Gostrstream@@UAEPAXI at Z(ptr long) msvcirt.??_Gostrstream@@UAEPAXI at Z
@@ -459,8 +459,8 @@
 @ stub -arch=win64 ?attach at fstream@@QEAAXH at Z
 @ thiscall -arch=win32 ?attach at ifstream@@QAEXH at Z(ptr long) msvcirt.?attach at ifstream@@QAEXH at Z
 @ cdecl -arch=win64 ?attach at ifstream@@QEAAXH at Z(ptr long) msvcirt.?attach at ifstream@@QEAAXH at Z
-@ stub -arch=win32 ?attach at ofstream@@QAEXH at Z
-@ stub -arch=win64 ?attach at ofstream@@QEAAXH at Z
+@ thiscall -arch=win32 ?attach at ofstream@@QAEXH at Z(ptr long) msvcirt.?attach at ofstream@@QAEXH at Z
+@ cdecl -arch=win64 ?attach at ofstream@@QEAAXH at Z(ptr long) msvcirt.?attach at ofstream@@QEAAXH at Z
 @ thiscall -arch=win32 ?bad at ios@@QBEHXZ(ptr) msvcirt.?bad at ios@@QBEHXZ
 @ cdecl -arch=win64 ?bad at ios@@QEBAHXZ(ptr) msvcirt.?bad at ios@@QEBAHXZ
 @ thiscall -arch=win32 ?base at streambuf@@IBEPADXZ(ptr) msvcirt.?base at streambuf@@IBEPADXZ
@@ -483,8 +483,8 @@
 @ stub -arch=win64 ?close at fstream@@QEAAXXZ
 @ thiscall -arch=win32 ?close at ifstream@@QAEXXZ(ptr) msvcirt.?close at ifstream@@QAEXXZ
 @ cdecl -arch=win64 ?close at ifstream@@QEAAXXZ(ptr) msvcirt.?close at ifstream@@QEAAXXZ
-@ stub -arch=win32 ?close at ofstream@@QAEXXZ
-@ stub -arch=win64 ?close at ofstream@@QEAAXXZ
+@ thiscall -arch=win32 ?close at ofstream@@QAEXXZ(ptr) msvcirt.?close at ofstream@@QAEXXZ
+@ cdecl -arch=win64 ?close at ofstream@@QEAAXXZ(ptr) msvcirt.?close at ofstream@@QEAAXXZ
 @ cdecl -arch=win32 ?clrlock at ios@@QAAXXZ(ptr) msvcirt.?clrlock at ios@@QAAXXZ
 @ cdecl -arch=win64 ?clrlock at ios@@QEAAXXZ(ptr) msvcirt.?clrlock at ios@@QEAAXXZ
 @ thiscall -arch=win32 ?clrlock at streambuf@@QAEXXZ(ptr) msvcirt.?clrlock at streambuf@@QAEXXZ
@@ -527,8 +527,8 @@
 @ stub -arch=win64 ?fd at fstream@@QEBAHXZ
 @ thiscall -arch=win32 ?fd at ifstream@@QBEHXZ(ptr) msvcirt.?fd at ifstream@@QBEHXZ
 @ cdecl -arch=win64 ?fd at ifstream@@QEBAHXZ(ptr) msvcirt.?fd at ifstream@@QEBAHXZ
-@ stub -arch=win32 ?fd at ofstream@@QBEHXZ
-@ stub -arch=win64 ?fd at ofstream@@QEBAHXZ
+@ thiscall -arch=win32 ?fd at ofstream@@QBEHXZ(ptr) msvcirt.?fd at ofstream@@QBEHXZ
+@ cdecl -arch=win64 ?fd at ofstream@@QEBAHXZ(ptr) msvcirt.?fd at ofstream@@QEBAHXZ
 @ thiscall -arch=win32 ?fill at ios@@QAEDD at Z(ptr long) msvcirt.?fill at ios@@QAEDD at Z
 @ cdecl -arch=win64 ?fill at ios@@QEAADD at Z(ptr long) msvcirt.?fill at ios@@QEAADD at Z
 @ thiscall -arch=win32 ?fill at ios@@QBEDXZ(ptr) msvcirt.?fill at ios@@QBEDXZ
@@ -596,8 +596,8 @@
 @ stub -arch=win64 ?is_open at fstream@@QEBAHXZ
 @ thiscall -arch=win32 ?is_open at ifstream@@QBEHXZ(ptr) msvcirt.?is_open at ifstream@@QBEHXZ
 @ cdecl -arch=win64 ?is_open at ifstream@@QEBAHXZ(ptr) msvcirt.?is_open at ifstream@@QEBAHXZ
-@ stub -arch=win32 ?is_open at ofstream@@QBEHXZ
-@ stub -arch=win64 ?is_open at ofstream@@QEBAHXZ
+@ thiscall -arch=win32 ?is_open at ofstream@@QBEHXZ(ptr) msvcirt.?is_open at ofstream@@QBEHXZ
+@ cdecl -arch=win64 ?is_open at ofstream@@QEBAHXZ(ptr) msvcirt.?is_open at ofstream@@QEBAHXZ
 @ thiscall -arch=win32 ?isfx at istream@@QAEXXZ(ptr) msvcirt.?isfx at istream@@QAEXXZ
 @ cdecl -arch=win64 ?isfx at istream@@QEAAXXZ(ptr) msvcirt.?isfx at istream@@QEAAXXZ
 @ thiscall -arch=win32 ?iword at ios@@QBEAAJH at Z(ptr long) msvcirt.?iword at ios@@QBEAAJH at Z
@@ -623,8 +623,8 @@
 @ stub -arch=win64 ?open at fstream@@QEAAXPEBDHH at Z
 @ thiscall -arch=win32 ?open at ifstream@@QAEXPBDHH at Z(ptr str long long) msvcirt.?open at ifstream@@QAEXPBDHH at Z
 @ cdecl -arch=win64 ?open at ifstream@@QEAAXPEBDHH at Z(ptr str long long) msvcirt.?open at ifstream@@QEAAXPEBDHH at Z
-@ stub -arch=win32 ?open at ofstream@@QAEXPBDHH at Z
-@ stub -arch=win64 ?open at ofstream@@QEAAXPEBDHH at Z
+@ thiscall -arch=win32 ?open at ofstream@@QAEXPBDHH at Z(ptr str long long) msvcirt.?open at ofstream@@QAEXPBDHH at Z
+@ cdecl -arch=win64 ?open at ofstream@@QEAAXPEBDHH at Z(ptr str long long) msvcirt.?open at ofstream@@QEAAXPEBDHH at Z
 @ extern ?openprot at filebuf@@2HB msvcirt.?openprot at filebuf@@2HB
 @ thiscall -arch=win32 ?opfx at ostream@@QAEHXZ(ptr) msvcirt.?opfx at ostream@@QAEHXZ
 @ cdecl -arch=win64 ?opfx at ostream@@QEAAHXZ(ptr) msvcirt.?opfx at ostream@@QEAAHXZ
@@ -678,8 +678,8 @@
 @ cdecl -arch=win64 ?rdbuf at ios@@QEBAPEAVstreambuf@@XZ(ptr) msvcirt.?rdbuf at ios@@QEBAPEAVstreambuf@@XZ
 @ thiscall -arch=win32 ?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at istrstream@@QBEPAVstrstreambuf@@XZ
 @ cdecl -arch=win64 ?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at istrstream@@QEBAPEAVstrstreambuf@@XZ
-@ stub -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ
-@ stub -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ
+@ thiscall -arch=win32 ?rdbuf at ofstream@@QBEPAVfilebuf@@XZ(ptr) msvcirt.?rdbuf at ofstream@@QBEPAVfilebuf@@XZ
+@ cdecl -arch=win64 ?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ(ptr) msvcirt.?rdbuf at ofstream@@QEBAPEAVfilebuf@@XZ
 @ thiscall -arch=win32 ?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QBEPAVstrstreambuf@@XZ
 @ cdecl -arch=win64 ?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ(ptr) msvcirt.?rdbuf at ostrstream@@QEBAPEAVstrstreambuf@@XZ
 @ thiscall -arch=win32 ?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ(ptr) msvcirt.?rdbuf at stdiostream@@QBEPAVstdiobuf@@XZ
@@ -725,8 +725,8 @@
 @ stub -arch=win64 ?setbuf at fstream@@QEAAPEAVstreambuf@@PEADH at Z
 @ thiscall -arch=win32 ?setbuf at ifstream@@QAEPAVstreambuf@@PADH at Z(ptr ptr long) msvcirt.?setbuf at ifstream@@QAEPAVstreambuf@@PADH at Z
 @ cdecl -arch=win64 ?setbuf at ifstream@@QEAAPEAVstreambuf@@PEADH at Z(ptr ptr long) msvcirt.?setbuf at ifstream@@QEAAPEAVstreambuf@@PEADH at Z
-@ stub -arch=win32 ?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z
-@ stub -arch=win64 ?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z
+@ thiscall -arch=win32 ?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z(ptr ptr long) msvcirt.?setbuf at ofstream@@QAEPAVstreambuf@@PADH at Z
+@ cdecl -arch=win64 ?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z(ptr ptr long) msvcirt.?setbuf at ofstream@@QEAAPEAVstreambuf@@PEADH at Z
 @ thiscall -arch=win32 ?setbuf at streambuf@@UAEPAV1 at PADH@Z(ptr ptr long) msvcirt.?setbuf at streambuf@@UAEPAV1 at PADH@Z
 @ cdecl -arch=win64 ?setbuf at streambuf@@UEAAPEAV1 at PEADH@Z(ptr ptr long) msvcirt.?setbuf at streambuf@@UEAAPEAV1 at PEADH@Z
 @ thiscall -arch=win32 ?setbuf at strstreambuf@@UAEPAVstreambuf@@PADH at Z(ptr ptr long) msvcirt.?setbuf at strstreambuf@@UAEPAVstreambuf@@PADH at Z
@@ -747,8 +747,8 @@
 @ stub -arch=win64 ?setmode at fstream@@QEAAHH at Z
 @ thiscall -arch=win32 ?setmode at ifstream@@QAEHH at Z(ptr long) msvcirt.?setmode at ifstream@@QAEHH at Z
 @ cdecl -arch=win64 ?setmode at ifstream@@QEAAHH at Z(ptr long) msvcirt.?setmode at ifstream@@QEAAHH at Z
-@ stub -arch=win32 ?setmode at ofstream@@QAEHH at Z
-@ stub -arch=win64 ?setmode at ofstream@@QEAAHH at Z
+@ thiscall -arch=win32 ?setmode at ofstream@@QAEHH at Z(ptr long) msvcirt.?setmode at ofstream@@QAEHH at Z
+@ cdecl -arch=win64 ?setmode at ofstream@@QEAAHH at Z(ptr long) msvcirt.?setmode at ofstream@@QEAAHH at Z
 @ thiscall -arch=win32 ?setp at streambuf@@IAEXPAD0 at Z(ptr ptr ptr) msvcirt.?setp at streambuf@@IAEXPAD0 at Z
 @ cdecl -arch=win64 ?setp at streambuf@@IEAAXPEAD0 at Z(ptr ptr ptr) msvcirt.?setp at streambuf@@IEAAXPEAD0 at Z
 @ thiscall -arch=win32 ?setrwbuf at stdiobuf@@QAEHHH at Z(ptr long long) msvcirt.?setrwbuf at stdiobuf@@QAEHHH at Z
-- 
2.28.0




More information about the wine-devel mailing list