Hacks from CodeWeavers
authorVitaly Perov <vitperov@etersoft.ru>
Mon, 27 Sep 2010 11:16:52 +0000 (15:16 +0400)
committerVitaly Perov <vitperov@etersoft.ru>
Mon, 27 Sep 2010 11:16:52 +0000 (15:16 +0400)
Conflicts:

dlls/ws2_32/socket.c

dlls/kernel32/kernel_main.c
dlls/user32/win.c
dlls/ws2_32/socket.c

index 387a32fe14e26239ed9fbf74bd5b6fbc04296a77..491c0880ff73ce5f1140162bf1a5182c1e630b47 100644 (file)
@@ -109,6 +109,13 @@ static BOOL process_attach( HMODULE module )
     {
         /* Securom checks for this one when version is NT */
         set_entry_point( module, "FT_Thunk", 0 );
+#ifdef __i386__
+        /* Bit of a CodeWeavers Hack, winehq made it so that win2k mode
+         * no longer did this. We need it for native dcom95. So until our
+         * ole implementation works right we need the shared heap*/
+        /* create the shared heap for broken win95 native dlls */
+        HeapCreate( HEAP_SHARED, 0, 0 );
+#endif
     }
     else LoadLibraryA( "krnl386.exe16" );
 
index a5761c755295b5fabe8fe752864c082d7aa7c0e4..6c0d20a13a6218ecf03bdcac169a60af8799e1f9 100644 (file)
@@ -2507,6 +2507,33 @@ LONG WINAPI SetWindowLongW(
     INT offset, /* [in] offset, in bytes, of location to alter */
     LONG newval /* [in] new value of location */
 ) {
+    if (GetVersion()&0x80000000 && offset == GWLP_WNDPROC)
+    {
+         /* CodeWeavers Only Hack... Needed for the Delegates tab
+          * in Outlook XP running in win98 mode
+          */
+         char class[80];
+         GetClassNameA(hwnd, class, sizeof(class));
+         if (strcmp(class,"REListBox20W")==0)
+         {
+            char name[MAX_PATH], *p;
+
+            GetModuleFileNameA(GetModuleHandleA(NULL),name,MAX_PATH);
+            p = strrchr(name, '\\');
+
+            if (p)
+                p++;
+            else
+                p = name;
+
+            if (!strcasecmp(p,"OUTLOOK.EXE"))
+            {
+                ERR("Outlook in WIN98 calling supposedly unimplemented function, triggering bandaid for class %s\n",debugstr_a(class));
+                SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+                return 0;
+            }
+         }
+    }
     return WIN_SetWindowLong( hwnd, offset, sizeof(LONG), newval, TRUE );
 }
 
index c96bbfbf98658f75bfcd2c7734248c6324035568..6a2f161be475eb1f88ed3fecbd00429bf440710b 100644 (file)
@@ -331,6 +331,8 @@ int WSAIOCTL_GetInterfaceName(int intNumber, char *intName);
 
 static void WS_AddCompletion( SOCKET sock, ULONG_PTR CompletionValue, NTSTATUS CompletionStatus, ULONG Information );
 
+static DWORD dwBlockedThreadId;
+
 #define MAP_OPTION(opt) { WS_##opt, opt }
 
 static const int ws_sock_map[][2] =
@@ -1815,6 +1817,20 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr,
 
     do {
         /* try accepting first (if there is a deferred connection) */
+        if (is_blocking)
+        {
+            int fd = get_sock_fd( s, FILE_READ_DATA, NULL );
+            if (fd == -1) return INVALID_SOCKET;
+            /* block here */
+            dwBlockedThreadId = GetCurrentThreadId();
+            do_block(fd, POLLIN, -1);
+            dwBlockedThreadId = 0;
+            _sync_sock_state(s); /* let wineserver notice connection */
+            release_sock_fd( s, fd );
+            /* retrieve any error codes from it */
+            SetLastError(_get_sock_error(s, FD_ACCEPT_BIT));
+            /* FIXME: care about the error? */
+        }
         SERVER_START_REQ( accept_socket )
         {
             req->lhandle    = wine_server_obj_handle( SOCKET2HANDLE(s) );
@@ -2061,7 +2077,28 @@ int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen)
 int WINAPI WS_closesocket(SOCKET s)
 {
     TRACE("socket %04lx\n", s);
-    if (CloseHandle(SOCKET2HANDLE(s))) return 0;
+
+    if (CloseHandle(SOCKET2HANDLE(s)))
+    {
+        /* CODEWEAVERS HACK:
+         * This is used to emulate Windows behaviour in that when you close a
+         * handle that is being used in a blocking operation it returns with
+         * EINVAL. Without this hack Wine will just hang forever. This hack
+         * interrupts the poll system call in do_block with a signal which will
+         * result in another call to poll and if the handle has been closed it
+         * will return EINVAL exactly as Windows does.
+         * NOTE: this relies on the fact that Suspend/ResumeThread are
+         * implemented using UNIX signals */
+        if (dwBlockedThreadId)
+        {
+            HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, dwBlockedThreadId);
+            SuspendThread(hThread);
+            ResumeThread(hThread);
+            CloseHandle(hThread);
+        }
+        /* END CODEWEAVERS HACK */
+        return 0;
+    }
     return SOCKET_ERROR;
 }