[PATCH] msvcirt: Implement _mtlock() and _mtunlock().

Arkadiusz Hiler ahiler at codeweavers.com
Fri Sep 4 09:16:19 CDT 2020


Looks like they are just cdecl wrappers around stdcall EnterCriticalSection()
and LeaveCriticalSection().

The game TRON 2.0 was crashing on the stubs. Now it makes it a bit further.

Signed-off-by: Arkadiusz Hiler <ahiler at codeweavers.com>
---
 dlls/msvcirt/msvcirt.c       | 12 +++++++++
 dlls/msvcirt/msvcirt.spec    |  4 +--
 dlls/msvcirt/tests/msvcirt.c | 49 ++++++++++++++++++++++++++++++++++++
 dlls/msvcrt20/msvcrt20.spec  |  4 +--
 dlls/msvcrt40/msvcrt40.spec  |  4 +--
 5 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 7e1d9977b78..eaeca639db2 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -4674,6 +4674,18 @@ DEFINE_VTBL_WRAPPER(56);
 void* (__cdecl *MSVCRT_operator_new)(SIZE_T);
 void (__cdecl *MSVCRT_operator_delete)(void*);
 
+void __cdecl _mtlock(CRITICAL_SECTION *crit)
+{
+    TRACE("(%p)\n", crit);
+    EnterCriticalSection(crit);
+}
+
+void __cdecl _mtunlock(CRITICAL_SECTION *crit)
+{
+    TRACE("(%p)\n", crit);
+    LeaveCriticalSection(crit);
+}
+
 static void init_cxx_funcs(void)
 {
     HMODULE hmod = GetModuleHandleA("msvcrt.dll");
diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec
index 75ae312b486..77a8f9477ef 100644
--- a/dlls/msvcirt/msvcirt.spec
+++ b/dlls/msvcirt/msvcirt.spec
@@ -786,5 +786,5 @@
 @ thiscall -arch=win32 ?xsputn at streambuf@@UAEHPBDH at Z(ptr ptr long) streambuf_xsputn
 @ cdecl -arch=win64 ?xsputn at streambuf@@UEAAHPEBDH at Z(ptr ptr long) streambuf_xsputn
 @ stub __dummy_export
-@ stub _mtlock
-@ stub _mtunlock
+@ cdecl _mtlock(ptr)
+@ cdecl _mtunlock(ptr)
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 4f9f859a861..2b12922ed30 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -446,6 +446,10 @@ static const char* (*__thiscall p_exception_what)(exception*);
 static logic_error* (*__thiscall p_logic_error_ctor)(logic_error*, const char**);
 static void (*__thiscall p_logic_error_dtor)(logic_error*);
 
+/* locking */
+static void (*__cdecl p__mtlock)(CRITICAL_SECTION *);
+static void (*__cdecl p__mtunlock)(CRITICAL_SECTION *);
+
 /* Predefined streams */
 static istream *p_cin;
 static ostream *p_cout, *p_cerr, *p_clog;
@@ -1002,6 +1006,9 @@ static BOOL init(void)
     SET(p_cerr, "?cerr@@3Vostream_withassign@@A");
     SET(p_clog, "?clog@@3Vostream_withassign@@A");
 
+    SET(p__mtlock, "_mtlock");
+    SET(p__mtunlock, "_mtunlock");
+
     init_thiscall_thunk();
     return TRUE;
 }
@@ -7767,6 +7774,47 @@ static void test_exception(void)
     call_func1(p_logic_error_dtor, (void*) &le);
 }
 
+static DWORD WINAPI _try_enter_critical(void *crit)
+{
+    BOOL ret = TryEnterCriticalSection(crit);
+
+    if (ret)
+        LeaveCriticalSection(crit);
+
+    return ret;
+}
+
+static void test_mtlock_mtunlock(void)
+{
+    CRITICAL_SECTION crit;
+    HANDLE thread;
+    DWORD exit_code, ret;
+
+    InitializeCriticalSection(&crit);
+
+    p__mtlock(&crit);
+
+    thread = CreateThread(NULL, 0, _try_enter_critical, &crit, 0, NULL);
+    ok(thread != NULL, "failed to create a thread, error: %x\n", GetLastError());
+    ret = WaitForSingleObject(thread, 1000);
+    ok(ret == WAIT_OBJECT_0, "failed to wait for the thread, ret: %d, error: %x\n", ret, GetLastError());
+    ok(GetExitCodeThread(thread, &exit_code), "failed to get exit code of the thread\n");
+    ok(exit_code == FALSE, "the thread entered critical section\n");
+    ret = CloseHandle(thread);
+    ok(ret, "failed to close thread's handle, error: %x\n", GetLastError());
+
+    p__mtunlock(&crit);
+
+    thread = CreateThread(NULL, 0, _try_enter_critical, &crit, 0, NULL);
+    ok(thread != NULL, "failed to create a thread, error: %x\n", GetLastError());
+    ret = WaitForSingleObject(thread, 1000);
+    ok(ret == WAIT_OBJECT_0, "failed to wait for the thread, ret: %d, error: %x\n", ret, GetLastError());
+    ok(GetExitCodeThread(thread, &exit_code), "failed to get exit code of the thread\n");
+    ok(exit_code == TRUE, "the thread was not able to enter critical section\n");
+    ret = CloseHandle(thread);
+    ok(ret, "failed to close thread's handle, error: %x\n", GetLastError());
+}
+
 START_TEST(msvcirt)
 {
     if(!init())
@@ -7794,6 +7842,7 @@ START_TEST(msvcirt)
     test_Iostream_init();
     test_std_streams();
     test_exception();
+    test_mtlock_mtunlock();
 
     FreeLibrary(msvcrt);
     FreeLibrary(msvcirt);
diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec
index 96c6c681478..4728cd21aa2 100644
--- a/dlls/msvcrt20/msvcrt20.spec
+++ b/dlls/msvcrt20/msvcrt20.spec
@@ -1072,8 +1072,8 @@
 @ cdecl _mkdir(str) msvcrt._mkdir
 @ cdecl _mktemp(str) msvcrt._mktemp
 @ cdecl _msize(ptr) msvcrt._msize
-@ stub _mtlock
-@ stub _mtunlock
+@ cdecl _mtlock(ptr) msvcirt._mtlock
+@ cdecl _mtunlock(ptr) msvcirt._mtunlock
 @ cdecl _nextafter(double double) msvcrt._nextafter
 @ cdecl _onexit(ptr) msvcrt._onexit
 @ varargs _open(str long) msvcrt._open
diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec
index 6a2c9a7e52e..586de93b020 100644
--- a/dlls/msvcrt40/msvcrt40.spec
+++ b/dlls/msvcrt40/msvcrt40.spec
@@ -1163,8 +1163,8 @@
 @ cdecl _mkdir(str) msvcrt._mkdir
 @ cdecl _mktemp(str) msvcrt._mktemp
 @ cdecl _msize(ptr) msvcrt._msize
-@ stub _mtlock
-@ stub _mtunlock
+@ cdecl _mtlock(ptr) msvcirt._mtlock
+@ cdecl _mtunlock(ptr) msvcirt._mtunlock
 @ cdecl _nextafter(double double) msvcrt._nextafter
 @ cdecl _onexit(ptr) msvcrt._onexit
 @ varargs _open(str long) msvcrt._open
-- 
2.28.0




More information about the wine-devel mailing list