[Wine-patches] [eterhack] ws2_32: Prevent TeleTRADER 4.00 freezing (eterbug #3421).

Alexander Morozov amorozov на etersoft.ru
Вт Мар 15 19:49:42 MSK 2011


----------- следующая часть -----------
From 62eb1818f1d5ea8d545169fc7b2c000ca1472c90 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 5 Feb 2009 15:12:44 +0300
Subject: [eterhack] ws2_32: Prevent TeleTRADER 4.00 freezing (eterbug #3421).

---
 dlls/ws2_32/socket.c |   42 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 13b9139..d794064 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -147,7 +147,9 @@
 #include "af_irda.h"
 #include "winnt.h"
 #include "iphlpapi.h"
+#include "tlhelp32.h"
 #include "wine/server.h"
+#include "wine/library.h"
 #include "wine/debug.h"
 #include "wine/exception.h"
 #include "wine/unicode.h"
@@ -991,12 +993,48 @@ static inline int get_rcvsnd_timeo( int fd, int optname)
 #define GET_SNDTIMEO(fd) (-1)
 #endif
 
+static int check_eterbug3421(void)
+{
+    static const char bug3421_app_exe[] = "terminal.exe";
+    static const char bug3421_app[] = "terminal";
+    static const char delim[] = "/\\";
+
+    char *ptr, *prog_name = __wine_main_argv[0];
+    THREADENTRY32 te32 = {sizeof(te32)};
+    HANDLE snap;
+    DWORD first_id;
+    int ret = 0;
+
+    while ((ptr = strpbrk(prog_name, delim)))
+        prog_name = ++ptr;
+    if (strcasecmp(prog_name, bug3421_app_exe) &&
+        strcasecmp(prog_name, bug3421_app))
+        return 0;
+    snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+    if (snap == INVALID_HANDLE_VALUE)
+        return 0;
+    if (!Thread32First(snap, &te32))
+        goto end;
+    first_id = te32.th32ThreadID;
+    while (Thread32Next(snap, &te32))
+        if (te32.th32ThreadID < first_id)
+            first_id = te32.th32ThreadID;
+    if (GetCurrentThreadId() == first_id)
+        ret = 1;
+end:
+    CloseHandle(snap);
+    return ret;
+}
+
 /* utility: given an fd, will block until one of the events occurs */
 static inline int do_block( int fd, int events, int timeout )
 {
   struct pollfd pfd;
   int ret;
 
+  if (check_eterbug3421())
+      return -1;
+
   pfd.fd = fd;
   pfd.events = events;
 
@@ -4036,7 +4074,7 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
             pfd.fd = fd;
             pfd.events = POLLOUT;
 
-            if (!timeout || !poll( &pfd, 1, timeout ))
+            if (!timeout || check_eterbug3421() || !poll( &pfd, 1, timeout ))
             {
                 err = WSAETIMEDOUT;
                 goto error; /* msdn says a timeout in send is fatal */
@@ -5839,7 +5877,7 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
             pfd.events = POLLIN;
             if (*lpFlags & WS_MSG_OOB) pfd.events |= POLLPRI;
 
-            if (!timeout || !poll( &pfd, 1, timeout ))
+            if (!timeout || check_eterbug3421() || !poll( &pfd, 1, timeout ))
             {
                 err = WSAETIMEDOUT;
                 /* a timeout is not fatal */
-- 
1.7.4.1



Подробная информация о списке рассылки Wine-patches