[4/5] msvcirt: Add implementation of streambuf locking (resend)

Iván Matellanes matellanesivan at gmail.com
Mon Jun 8 14:26:43 CDT 2015


---
 dlls/msvcirt/msvcirt.c       |  52 +++++++++++++++++++-
 dlls/msvcirt/msvcirt.spec    |  20 ++++----
 dlls/msvcirt/tests/msvcirt.c | 111 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/msvcrt20/msvcrt20.spec  |  20 ++++----
 dlls/msvcrt40/msvcrt40.spec  |  20 ++++----
 5 files changed, 189 insertions(+), 34 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index a6d3749..afb673d 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -45,7 +45,7 @@ typedef struct {
     char *eback;
     char *gptr;
     char *egptr;
-    int unknown2;
+    int do_lock;
     CRITICAL_SECTION lock;
 } streambuf;
 
@@ -99,7 +99,7 @@ streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int
     this->vtable = &MSVCP_streambuf_vtable;
     this->allocated = 0;
     this->unknown = -1;
-    this->unknown2 = -1;
+    this->do_lock = -1;
     this->base = NULL;
     streambuf_setbuf(this, buffer, length);
     streambuf_setg(this, NULL, NULL, NULL);
@@ -288,6 +288,35 @@ char* __thiscall streambuf_pptr(const streambuf *this)
     return this->pptr;
 }
 
+/* ?clrlock at streambuf@@QAEXXZ */
+/* ?clrlock at streambuf@@QEAAXXZ */
+DEFINE_THISCALL_WRAPPER(streambuf_clrlock, 4)
+void __thiscall streambuf_clrlock(streambuf *this)
+{
+    TRACE("(%p)\n", this);
+    if (this->do_lock <= 0)
+        this->do_lock++;
+}
+
+/* ?lock at streambuf@@QAEXXZ */
+/* ?lock at streambuf@@QEAAXXZ */
+DEFINE_THISCALL_WRAPPER(streambuf_lock, 4)
+void __thiscall streambuf_lock(streambuf *this)
+{
+    TRACE("(%p)\n", this);
+    if (this->do_lock < 0)
+        EnterCriticalSection(&this->lock);
+}
+
+/* ?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ */
+/* ?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ */
+DEFINE_THISCALL_WRAPPER(streambuf_lockptr, 4)
+CRITICAL_SECTION* __thiscall streambuf_lockptr(streambuf *this)
+{
+    TRACE("(%p)\n", this);
+    return &this->lock;
+}
+
 /* Unexported */
 DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8)
 int __thiscall streambuf_overflow(streambuf *this, int c)
@@ -366,6 +395,15 @@ void __thiscall streambuf_setg(streambuf *this, char *ek, char *gp, char *eg)
     this->egptr = eg;
 }
 
+/* ?setlock at streambuf@@QAEXXZ */
+/* ?setlock at streambuf@@QEAAXXZ */
+DEFINE_THISCALL_WRAPPER(streambuf_setlock, 4)
+void __thiscall streambuf_setlock(streambuf *this)
+{
+    TRACE("(%p)\n", this);
+    this->do_lock--;
+}
+
 /* ?setp at streambuf@@IAEXPAD0 at Z */
 /* ?setp at streambuf@@IEAAXPEAD0 at Z */
 DEFINE_THISCALL_WRAPPER(streambuf_setp, 12)
@@ -410,6 +448,16 @@ int __thiscall streambuf_underflow(streambuf *this)
     return EOF;
 }
 
+/* ?unlock at streambuf@@QAEXXZ */
+/* ?unlock at streambuf@@QEAAXXZ */
+DEFINE_THISCALL_WRAPPER(streambuf_unlock, 4)
+void __thiscall streambuf_unlock(streambuf *this)
+{
+    TRACE("(%p)\n", this);
+    if (this->do_lock < 0)
+        LeaveCriticalSection(&this->lock);
+}
+
 /* ?xsgetn at streambuf@@UAEHPADH at Z */
 /* ?xsgetn at streambuf@@UEAAHPEADH at Z */
 DEFINE_THISCALL_WRAPPER(streambuf_xsgetn, 12)
diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec
index 8a57404..d40ea47 100644
--- a/dlls/msvcirt/msvcirt.spec
+++ b/dlls/msvcirt/msvcirt.spec
@@ -434,8 +434,8 @@
 @ stub -arch=win64 ?close at ofstream@@QEAAXXZ
 @ stub -arch=win32 ?clrlock at ios@@QAAXXZ  # void __cdecl ios::clrlock(void)
 @ stub -arch=win64 ?clrlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?clrlock at streambuf@@QAEXXZ  # void __thiscall streambuf::clrlock(void)
-@ stub -arch=win64 ?clrlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?clrlock at streambuf@@QAEXXZ(ptr) streambuf_clrlock
+@ cdecl -arch=win64 ?clrlock at streambuf@@QEAAXXZ(ptr) streambuf_clrlock
 @ stub ?cout@@3Vostream_withassign@@A  # class ostream_withassign cout
 @ stub -arch=win32 ?dbp at streambuf@@QAEXXZ  # void __thiscall streambuf::dbp(void)
 @ stub -arch=win64 ?dbp at streambuf@@QEAAXXZ
@@ -551,15 +551,15 @@
 @ stub -arch=win64 ?iword at ios@@QEBAAEAJH at Z
 @ stub -arch=win32 ?lock at ios@@QAAXXZ  # void __cdecl ios::lock(void)
 @ stub -arch=win64 ?lock at ios@@QEAAXXZ
-@ stub -arch=win32 ?lock at streambuf@@QAEXXZ  # void __thiscall streambuf::lock(void)
-@ stub -arch=win64 ?lock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?lock at streambuf@@QAEXXZ(ptr) streambuf_lock
+@ cdecl -arch=win64 ?lock at streambuf@@QEAAXXZ(ptr) streambuf_lock
 @ stub -arch=win32 ?lockbuf at ios@@QAAXXZ  # void __cdecl ios::lockbuf(void)
 @ stub -arch=win64 ?lockbuf at ios@@QEAAXXZ
 @ stub ?lockc at ios@@KAXXZ  # static void __cdecl ios::lockc(void)
 @ stub -arch=win32 ?lockptr at ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ  # struct _CRT_CRITICAL_SECTION * __thiscall ios::lockptr(void)
 @ stub -arch=win64 ?lockptr at ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ
-@ stub -arch=win32 ?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ  # struct _CRT_CRITICAL_SECTION * __thiscall streambuf::lockptr(void)
-@ stub -arch=win64 ?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ
+@ thiscall -arch=win32 ?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ(ptr) streambuf_lockptr
+@ cdecl -arch=win64 ?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ(ptr) streambuf_lockptr
 @ stub -arch=win32 ?oct@@YAAAVios@@AAV1@@Z  # class ios & __cdecl oct(class ios &)
 @ stub -arch=win64 ?oct@@YAAEAVios@@AEAV1@@Z
 @ stub -arch=win32 ?open at filebuf@@QAEPAV1 at PBDHH@Z  # class filebuf * __thiscall filebuf::open(char const *,int,int)
@@ -679,8 +679,8 @@
 @ cdecl -arch=win64 ?setg at streambuf@@IEAAXPEAD00 at Z(ptr ptr ptr ptr) streambuf_setg
 @ stub -arch=win32 ?setlock at ios@@QAAXXZ  # void __cdecl ios::setlock(void)
 @ stub -arch=win64 ?setlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?setlock at streambuf@@QAEXXZ  # void __thiscall streambuf::setlock(void)
-@ stub -arch=win64 ?setlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?setlock at streambuf@@QAEXXZ(ptr) streambuf_setlock
+@ cdecl -arch=win64 ?setlock at streambuf@@QEAAXXZ(ptr) streambuf_setlock
 @ stub -arch=win32 ?setmode at filebuf@@QAEHH at Z  # int __thiscall filebuf::setmode(int)
 @ stub -arch=win64 ?setmode at filebuf@@QEAAHH at Z
 @ stub -arch=win32 ?setmode at fstream@@QAEHH at Z  # int __thiscall fstream::setmode(int)
@@ -753,8 +753,8 @@
 @ stub -arch=win64 ?underflow at strstreambuf@@UEAAHXZ
 @ stub -arch=win32 ?unlock at ios@@QAAXXZ  # void __cdecl ios::unlock(void)
 @ stub -arch=win64 ?unlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?unlock at streambuf@@QAEXXZ  # void __thiscall streambuf::unlock(void)
-@ stub -arch=win64 ?unlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?unlock at streambuf@@QAEXXZ(ptr) streambuf_unlock
+@ cdecl -arch=win64 ?unlock at streambuf@@QEAAXXZ(ptr) streambuf_unlock
 @ stub -arch=win32 ?unlockbuf at ios@@QAAXXZ  # void __cdecl ios::unlockbuf(void)
 @ stub -arch=win64 ?unlockbuf at ios@@QEAAXXZ
 @ stub ?unlockc at ios@@KAXXZ  # static void __cdecl ios::unlockc(void)
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 51b75ee..3c2c5ce 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -37,7 +37,7 @@ typedef struct {
     char *eback;
     char *gptr;
     char *egptr;
-    int unknown2;
+    int do_lock;
     CRITICAL_SECTION lock;
 } streambuf;
 
@@ -53,9 +53,13 @@ static streambuf* (*__thiscall p_streambuf_reserve_ctor)(streambuf*, char*, int)
 static streambuf* (*__thiscall p_streambuf_ctor)(streambuf*);
 static void (*__thiscall p_streambuf_dtor)(streambuf*);
 static int (*__thiscall p_streambuf_allocate)(streambuf*);
+static void (*__thiscall p_streambuf_clrclock)(streambuf*);
 static int (*__thiscall p_streambuf_doallocate)(streambuf*);
+static void (*__thiscall p_streambuf_lock)(streambuf*);
 static void (*__thiscall p_streambuf_setb)(streambuf*, char*, char*, int);
+static void (*__thiscall p_streambuf_setlock)(streambuf*);
 static streambuf* (*__thiscall p_streambuf_setbuf)(streambuf*, char*, int);
+static void (*__thiscall p_streambuf_unlock)(streambuf*);
 
 /* Emulate a __thiscall */
 #ifdef __i386__
@@ -130,28 +134,65 @@ static BOOL init(void)
         SET(p_streambuf_ctor, "??0streambuf@@IEAA at XZ");
         SET(p_streambuf_dtor, "??1streambuf@@UEAA at XZ");
         SET(p_streambuf_allocate, "?allocate at streambuf@@IEAAHXZ");
+        SET(p_streambuf_clrclock, "?clrlock at streambuf@@QEAAXXZ");
         SET(p_streambuf_doallocate, "?doallocate at streambuf@@MEAAHXZ");
+        SET(p_streambuf_lock, "?lock at streambuf@@QEAAXXZ");
         SET(p_streambuf_setb, "?setb at streambuf@@IEAAXPEAD0H at Z");
         SET(p_streambuf_setbuf, "?setbuf at streambuf@@UEAAPEAV1 at PEADH@Z");
+        SET(p_streambuf_setlock, "?setlock at streambuf@@QEAAXXZ");
+        SET(p_streambuf_unlock, "?unlock at streambuf@@QEAAXXZ");
     } else {
         SET(p_streambuf_reserve_ctor, "??0streambuf@@IAE at PADH@Z");
         SET(p_streambuf_ctor, "??0streambuf@@IAE at XZ");
         SET(p_streambuf_dtor, "??1streambuf@@UAE at XZ");
         SET(p_streambuf_allocate, "?allocate at streambuf@@IAEHXZ");
+        SET(p_streambuf_clrclock, "?clrlock at streambuf@@QAEXXZ");
         SET(p_streambuf_doallocate, "?doallocate at streambuf@@MAEHXZ");
+        SET(p_streambuf_lock, "?lock at streambuf@@QAEXXZ");
         SET(p_streambuf_setb, "?setb at streambuf@@IAEXPAD0H at Z");
         SET(p_streambuf_setbuf, "?setbuf at streambuf@@UAEPAV1 at PADH@Z");
+        SET(p_streambuf_setlock, "?setlock at streambuf@@QAEXXZ");
+        SET(p_streambuf_unlock, "?unlock at streambuf@@QAEXXZ");
     }
 
     init_thiscall_thunk();
     return TRUE;
 }
 
+struct streambuf_lock_arg
+{
+    streambuf *sb;
+    HANDLE lock[4];
+    HANDLE test[4];
+};
+
+static DWORD WINAPI lock_streambuf(void *arg)
+{
+    struct streambuf_lock_arg *lock_arg = arg;
+    call_func1(p_streambuf_lock, lock_arg->sb);
+    SetEvent(lock_arg->lock[0]);
+    WaitForSingleObject(lock_arg->test[0], INFINITE);
+    call_func1(p_streambuf_lock, lock_arg->sb);
+    SetEvent(lock_arg->lock[1]);
+    WaitForSingleObject(lock_arg->test[1], INFINITE);
+    call_func1(p_streambuf_lock, lock_arg->sb);
+    SetEvent(lock_arg->lock[2]);
+    WaitForSingleObject(lock_arg->test[2], INFINITE);
+    call_func1(p_streambuf_unlock, lock_arg->sb);
+    SetEvent(lock_arg->lock[3]);
+    WaitForSingleObject(lock_arg->test[3], INFINITE);
+    call_func1(p_streambuf_unlock, lock_arg->sb);
+    return 0;
+}
+
 static void test_streambuf(void)
 {
     streambuf sb, sb2, *psb;
+    struct streambuf_lock_arg lock_arg;
+    HANDLE thread;
     char reserve[16];
-    int ret;
+    int ret, i;
+    BOOL locked;
 
     memset(&sb, 0xab, sizeof(streambuf));
     memset(&sb2, 0xab, sizeof(streambuf));
@@ -170,6 +211,64 @@ static void test_streambuf(void)
     ok(sb2.ebuf == reserve+16, "wrong ebuf pointer, expected %p got %p\n", reserve+16, sb2.ebuf);
     ok(sb.lock.LockCount == -1, "wrong critical section state, expected -1 got %d\n", sb.lock.LockCount);
 
+    /* setlock */
+    ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock);
+    call_func1(p_streambuf_setlock, &sb);
+    ok(sb.do_lock == -2, "expected do_lock value -2, got %d\n", sb.do_lock);
+    call_func1(p_streambuf_setlock, &sb);
+    ok(sb.do_lock == -3, "expected do_lock value -3, got %d\n", sb.do_lock);
+    sb.do_lock = 3;
+    call_func1(p_streambuf_setlock, &sb);
+    ok(sb.do_lock == 2, "expected do_lock value 2, got %d\n", sb.do_lock);
+
+    /* clrlock */
+    sb.do_lock = -2;
+    call_func1(p_streambuf_clrclock, &sb);
+    ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock);
+    call_func1(p_streambuf_clrclock, &sb);
+    ok(sb.do_lock == 0, "expected do_lock value 0, got %d\n", sb.do_lock);
+    call_func1(p_streambuf_clrclock, &sb);
+    ok(sb.do_lock == 1, "expected do_lock value 1, got %d\n", sb.do_lock);
+    call_func1(p_streambuf_clrclock, &sb);
+    ok(sb.do_lock == 1, "expected do_lock value 1, got %d\n", sb.do_lock);
+
+    /* lock/unlock */
+    lock_arg.sb = &sb;
+    for (i = 0; i < 4; i++) {
+        lock_arg.lock[i] = CreateEventW(NULL, FALSE, FALSE, NULL);
+        ok(lock_arg.lock[i] != NULL, "CreateEventW failed\n");
+        lock_arg.test[i] = CreateEventW(NULL, FALSE, FALSE, NULL);
+        ok(lock_arg.test[i] != NULL, "CreateEventW failed\n");
+    }
+
+    sb.do_lock = 0;
+    thread = CreateThread(NULL, 0, lock_streambuf, (void*)&lock_arg, 0, NULL);
+    ok(thread != NULL, "CreateThread failed\n");
+    WaitForSingleObject(lock_arg.lock[0], INFINITE);
+    locked = TryEnterCriticalSection(&sb.lock);
+    ok(locked != 0, "could not lock the streambuf\n");
+    LeaveCriticalSection(&sb.lock);
+
+    sb.do_lock = 1;
+    SetEvent(lock_arg.test[0]);
+    WaitForSingleObject(lock_arg.lock[1], INFINITE);
+    locked = TryEnterCriticalSection(&sb.lock);
+    ok(locked != 0, "could not lock the streambuf\n");
+    LeaveCriticalSection(&sb.lock);
+
+    sb.do_lock = -1;
+    SetEvent(lock_arg.test[1]);
+    WaitForSingleObject(lock_arg.lock[2], INFINITE);
+    locked = TryEnterCriticalSection(&sb.lock);
+    ok(locked == 0, "the streambuf was not locked before\n");
+
+    sb.do_lock = 0;
+    SetEvent(lock_arg.test[2]);
+    WaitForSingleObject(lock_arg.lock[3], INFINITE);
+    locked = TryEnterCriticalSection(&sb.lock);
+    ok(locked == 0, "the streambuf was not locked before\n");
+    sb.do_lock = -1;
+
     /* setb */
     call_func4(p_streambuf_setb, &sb, reserve, reserve+16, 0);
     ok(sb.base == reserve, "wrong base pointer, expected %p got %p\n", reserve, sb.base);
@@ -219,8 +318,16 @@ static void test_streambuf(void)
     ok(sb2.allocated == 1, "wrong allocate value, expected 1 got %d\n", sb2.allocated);
     ok(sb2.ebuf - sb2.base == 512 , "wrong reserve area size, expected 512 got %p-%p\n", sb2.ebuf, sb2.base);
 
+    SetEvent(lock_arg.test[3]);
+    WaitForSingleObject(thread, INFINITE);
+
     call_func1(p_streambuf_dtor, &sb);
     call_func1(p_streambuf_dtor, &sb2);
+    for (i = 0; i < 4; i++) {
+        CloseHandle(lock_arg.lock[i]);
+        CloseHandle(lock_arg.test[i]);
+    }
+    CloseHandle(thread);
 }
 
 START_TEST(msvcirt)
diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec
index 2c60964..aff7bdc 100644
--- a/dlls/msvcrt20/msvcrt20.spec
+++ b/dlls/msvcrt20/msvcrt20.spec
@@ -422,8 +422,8 @@
 @ stub -arch=win64 ?close at ofstream@@QEAAXXZ
 @ stub -arch=win32 ?clrlock at ios@@QAAXXZ
 @ stub -arch=win64 ?clrlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?clrlock at streambuf@@QAEXXZ
-@ stub -arch=win64 ?clrlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?clrlock at streambuf@@QAEXXZ(ptr) msvcirt.?clrlock at streambuf@@QAEXXZ
+@ cdecl -arch=win64 ?clrlock at streambuf@@QEAAXXZ(ptr) msvcirt.?clrlock at streambuf@@QEAAXXZ
 @ stub ?cout@@3Vostream_withassign@@A
 @ stub -arch=win32 ?dbp at streambuf@@QAEXXZ
 @ stub -arch=win64 ?dbp at streambuf@@QEAAXXZ
@@ -537,15 +537,15 @@
 @ stub -arch=win64 ?iword at ios@@QEBAAEAJH at Z
 @ stub -arch=win32 ?lock at ios@@QAAXXZ
 @ stub -arch=win64 ?lock at ios@@QEAAXXZ
-@ stub -arch=win32 ?lock at streambuf@@QAEXXZ
-@ stub -arch=win64 ?lock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?lock at streambuf@@QAEXXZ(ptr) msvcirt.?lock at streambuf@@QAEXXZ
+@ cdecl -arch=win64 ?lock at streambuf@@QEAAXXZ(ptr) msvcirt.?lock at streambuf@@QEAAXXZ
 @ stub -arch=win32 ?lockbuf at ios@@QAAXXZ
 @ stub -arch=win64 ?lockbuf at ios@@QEAAXXZ
 @ stub ?lockc at ios@@KAXXZ
 @ stub -arch=win32 ?lockptr at ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ
 @ stub -arch=win64 ?lockptr at ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ
-@ stub -arch=win32 ?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ
-@ stub -arch=win64 ?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ
+@ thiscall -arch=win32 ?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ(ptr) msvcirt.?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ
+@ cdecl -arch=win64 ?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ(ptr) msvcirt.?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ
 @ stub -arch=win32 ?oct@@YAAAVios@@AAV1@@Z
 @ stub -arch=win64 ?oct@@YAAEAVios@@AEAV1@@Z
 @ stub -arch=win32 ?open at filebuf@@QAEPAV1 at PBDHH@Z
@@ -667,8 +667,8 @@
 @ cdecl -arch=win64 ?setg at streambuf@@IEAAXPEAD00 at Z(ptr ptr ptr ptr) msvcirt.?setg at streambuf@@IEAAXPEAD00 at Z
 @ stub -arch=win32 ?setlock at ios@@QAAXXZ
 @ stub -arch=win64 ?setlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?setlock at streambuf@@QAEXXZ
-@ stub -arch=win64 ?setlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?setlock at streambuf@@QAEXXZ(ptr) msvcirt.?setlock at streambuf@@QAEXXZ
+@ cdecl -arch=win64 ?setlock at streambuf@@QEAAXXZ(ptr) msvcirt.?setlock at streambuf@@QEAAXXZ
 @ stub -arch=win32 ?setmode at filebuf@@QAEHH at Z
 @ stub -arch=win64 ?setmode at filebuf@@QEAAHH at Z
 @ stub -arch=win32 ?setmode at fstream@@QAEHH at Z
@@ -743,8 +743,8 @@
 @ cdecl ?unexpected@@YAXXZ() msvcrt.?unexpected@@YAXXZ
 @ stub -arch=win32 ?unlock at ios@@QAAXXZ
 @ stub -arch=win64 ?unlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?unlock at streambuf@@QAEXXZ
-@ stub -arch=win64 ?unlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?unlock at streambuf@@QAEXXZ(ptr) msvcirt.?unlock at streambuf@@QAEXXZ
+@ cdecl -arch=win64 ?unlock at streambuf@@QEAAXXZ(ptr) msvcirt.?unlock at streambuf@@QEAAXXZ
 @ stub -arch=win32 ?unlockbuf at ios@@QAAXXZ
 @ stub -arch=win64 ?unlockbuf at ios@@QEAAXXZ
 @ stub ?unlockc at ios@@KAXXZ
diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec
index a029b1b..4574502 100644
--- a/dlls/msvcrt40/msvcrt40.spec
+++ b/dlls/msvcrt40/msvcrt40.spec
@@ -487,8 +487,8 @@
 @ stub -arch=win64 ?close at ofstream@@QEAAXXZ
 @ stub -arch=win32 ?clrlock at ios@@QAAXXZ
 @ stub -arch=win64 ?clrlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?clrlock at streambuf@@QAEXXZ
-@ stub -arch=win64 ?clrlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?clrlock at streambuf@@QAEXXZ(ptr) msvcirt.?clrlock at streambuf@@QAEXXZ
+@ cdecl -arch=win64 ?clrlock at streambuf@@QEAAXXZ(ptr) msvcirt.?clrlock at streambuf@@QEAAXXZ
 @ stub ?cout@@3Vostream_withassign@@A
 @ stub -arch=win32 ?dbp at streambuf@@QAEXXZ
 @ stub -arch=win64 ?dbp at streambuf@@QEAAXXZ
@@ -604,15 +604,15 @@
 @ stub -arch=win64 ?iword at ios@@QEBAAEAJH at Z
 @ stub -arch=win32 ?lock at ios@@QAAXXZ
 @ stub -arch=win64 ?lock at ios@@QEAAXXZ
-@ stub -arch=win32 ?lock at streambuf@@QAEXXZ
-@ stub -arch=win64 ?lock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?lock at streambuf@@QAEXXZ(ptr) msvcirt.?lock at streambuf@@QAEXXZ
+@ cdecl -arch=win64 ?lock at streambuf@@QEAAXXZ(ptr) msvcirt.?lock at streambuf@@QEAAXXZ
 @ stub -arch=win32 ?lockbuf at ios@@QAAXXZ
 @ stub -arch=win64 ?lockbuf at ios@@QEAAXXZ
 @ stub ?lockc at ios@@KAXXZ
 @ stub -arch=win32 ?lockptr at ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ
 @ stub -arch=win64 ?lockptr at ios@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ
-@ stub -arch=win32 ?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ
-@ stub -arch=win64 ?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ
+@ thiscall -arch=win32 ?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ(ptr) msvcirt.?lockptr at streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ
+@ cdecl -arch=win64 ?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ(ptr) msvcirt.?lockptr at streambuf@@IEAAPEAU_CRT_CRITICAL_SECTION@@XZ
 @ thiscall -arch=win32 ?name at type_info@@QBEPBDXZ(ptr) msvcrt.?name at type_info@@QBEPBDXZ
 @ cdecl -arch=win64 ?name at type_info@@QEBAPEBDXZ(ptr) msvcrt.?name at type_info@@QEBAPEBDXZ
 @ stub -arch=win32 ?oct@@YAAAVios@@AAV1@@Z
@@ -739,8 +739,8 @@
 @ cdecl -arch=win64 ?setg at streambuf@@IEAAXPEAD00 at Z(ptr ptr ptr ptr) msvcirt.?setg at streambuf@@IEAAXPEAD00 at Z
 @ stub -arch=win32 ?setlock at ios@@QAAXXZ
 @ stub -arch=win64 ?setlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?setlock at streambuf@@QAEXXZ
-@ stub -arch=win64 ?setlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?setlock at streambuf@@QAEXXZ(ptr) msvcirt.?setlock at streambuf@@QAEXXZ
+@ cdecl -arch=win64 ?setlock at streambuf@@QEAAXXZ(ptr) msvcirt.?setlock at streambuf@@QEAAXXZ
 @ stub -arch=win32 ?setmode at filebuf@@QAEHH at Z
 @ stub -arch=win64 ?setmode at filebuf@@QEAAHH at Z
 @ stub -arch=win32 ?setmode at fstream@@QAEHH at Z
@@ -815,8 +815,8 @@
 @ cdecl ?unexpected@@YAXXZ() msvcrt.?unexpected@@YAXXZ
 @ stub -arch=win32 ?unlock at ios@@QAAXXZ
 @ stub -arch=win64 ?unlock at ios@@QEAAXXZ
-@ stub -arch=win32 ?unlock at streambuf@@QAEXXZ
-@ stub -arch=win64 ?unlock at streambuf@@QEAAXXZ
+@ thiscall -arch=win32 ?unlock at streambuf@@QAEXXZ(ptr) msvcirt.?unlock at streambuf@@QAEXXZ
+@ cdecl -arch=win64 ?unlock at streambuf@@QEAAXXZ(ptr) msvcirt.?unlock at streambuf@@QEAAXXZ
 @ stub -arch=win32 ?unlockbuf at ios@@QAAXXZ
 @ stub -arch=win64 ?unlockbuf at ios@@QEAAXXZ
 @ stub ?unlockc at ios@@KAXXZ
-- 
2.1.4




More information about the wine-patches mailing list