Hi Michael, all,
here is a patch to make winsock compile without warnings without -DWINE_NO_STRICT. Comments are welcome.
Martin
PS Michael, will you send this stuff to wine-patches?
Index: Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/winsock/Makefile.in,v retrieving revision 1.18 diff -u -r1.18 Makefile.in --- Makefile.in 18 Oct 2002 23:46:28 -0000 1.18 +++ Makefile.in 28 Oct 2002 15:02:23 -0000 @@ -1,4 +1,4 @@ -EXTRADEFS = -DUSE_WS_PREFIX -DWINE_NO_STRICT +EXTRADEFS = -DUSE_WS_PREFIX TOPSRCDIR = @top_srcdir@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ Index: async.c =================================================================== RCS file: /home/wine/wine/dlls/winsock/async.c,v retrieving revision 1.27 diff -u -r1.27 async.c --- async.c 17 Oct 2002 16:43:43 -0000 1.27 +++ async.c 28 Oct 2002 15:02:24 -0000 @@ -136,6 +136,10 @@ #define AQ_GETSERV 2 #define AQ_GETMASK 3
+/* The handles used are pseudo-handles that can be simply casted. */ +/* 16-bit values are used internally (to be sure handle comparison works right in 16-bit apps). */ +#define WSA_H32(h16) ((HANDLE)(ULONG_PTR)(h16)) + /* ----------------------------------- helper functions - */
static int list_size(char** l, int item_size) @@ -335,7 +339,7 @@ return size; }
-static HANDLE __ws_async_handle = 0xdead; +static HANDLE16 __ws_async_handle = 0xdead;
/* Generic async query struct. we use symbolic names for the different queries * for readability. @@ -486,7 +490,7 @@ } break; } - PostMessageA(HWND_32(aq->hWnd),aq->uMsg,aq->async_handle,size|(fail<<16)); + PostMessageA(HWND_32(aq->hWnd),aq->uMsg,(WPARAM) aq->async_handle,size|(fail<<16)); HeapFree(GetProcessHeap(),0,arg); return 0; } @@ -547,7 +551,8 @@ aq->ptr1 = ptr1; aq->int2 = int2; aq->ptr2 = ptr2; - aq->async_handle = ++__ws_async_handle; + /* avoid async_handle = 0 */ + aq->async_handle = (++__ws_async_handle ? __ws_async_handle : ++__ws_async_handle); aq->flags = flags; aq->sbuf = (SEGPTR)sbuf; aq->sbuflen = sbuflen; @@ -579,10 +584,10 @@ HANDLE WINAPI WSAAsyncGetHostByAddr(HWND hWnd, UINT uMsg, LPCSTR addr, INT len, INT type, LPSTR sbuf, INT buflen) { - TRACE("hwnd %04x, msg %04x, addr %08x[%i]\n", + TRACE("hwnd %p, msg %04x, addr %08x[%i]\n", hWnd, uMsg, (unsigned)addr , len ); - return __WSAsyncDBQuery(hWnd,uMsg,len,addr,type,NULL,sbuf,buflen, - AQ_NUMBER|AQ_COPYPTR1|AQ_WIN32|AQ_GETHOST); + return WSA_H32( __WSAsyncDBQuery(hWnd,uMsg,len,addr,type,NULL,sbuf,buflen, + AQ_NUMBER|AQ_COPYPTR1|AQ_WIN32|AQ_GETHOST)); }
/*********************************************************************** @@ -604,10 +609,10 @@ HANDLE WINAPI WSAAsyncGetHostByName(HWND hWnd, UINT uMsg, LPCSTR name, LPSTR sbuf, INT buflen) { - TRACE("hwnd %04x, msg %08x, host %s, buffer %i\n", + TRACE("hwnd %p, msg %08x, host %s, buffer %i\n", hWnd, uMsg, (name)?name:"<null>", (int)buflen ); - return __WSAsyncDBQuery(hWnd,uMsg,0,name,0,NULL,sbuf,buflen, - AQ_NAME|AQ_DUPLOWPTR1|AQ_WIN32|AQ_GETHOST); + return WSA_H32( __WSAsyncDBQuery(hWnd,uMsg,0,name,0,NULL,sbuf,buflen, + AQ_NAME|AQ_DUPLOWPTR1|AQ_WIN32|AQ_GETHOST)); }
/*********************************************************************** @@ -629,10 +634,10 @@ HANDLE WINAPI WSAAsyncGetProtoByName(HWND hWnd, UINT uMsg, LPCSTR name, LPSTR sbuf, INT buflen) { - TRACE("hwnd %04x, msg %08x, protocol %s\n", + TRACE("hwnd %p, msg %08x, protocol %s\n", hWnd, uMsg, (name)?name:"<null>" ); - return __WSAsyncDBQuery(hWnd,uMsg,0,name,0,NULL,sbuf,buflen, - AQ_NAME|AQ_DUPLOWPTR1|AQ_WIN32|AQ_GETPROTO); + return WSA_H32( __WSAsyncDBQuery(hWnd,uMsg,0,name,0,NULL,sbuf,buflen, + AQ_NAME|AQ_DUPLOWPTR1|AQ_WIN32|AQ_GETPROTO)); }
@@ -654,9 +659,9 @@ HANDLE WINAPI WSAAsyncGetProtoByNumber(HWND hWnd, UINT uMsg, INT number, LPSTR sbuf, INT buflen) { - TRACE("hwnd %04x, msg %04x, num %i\n", hWnd, uMsg, number ); - return __WSAsyncDBQuery(hWnd,uMsg,number,NULL,0,NULL,sbuf,buflen, - AQ_GETPROTO|AQ_NUMBER|AQ_WIN32); + TRACE("hwnd %p, msg %04x, num %i\n", hWnd, uMsg, number ); + return WSA_H32( __WSAsyncDBQuery(hWnd,uMsg,number,NULL,0,NULL,sbuf,buflen, + AQ_GETPROTO|AQ_NUMBER|AQ_WIN32)); }
/*********************************************************************** @@ -678,10 +683,10 @@ HANDLE WINAPI WSAAsyncGetServByName(HWND hWnd, UINT uMsg, LPCSTR name, LPCSTR proto, LPSTR sbuf, INT buflen) { - TRACE("hwnd %04x, msg %04x, name %s, proto %s\n", + TRACE("hwnd %p, msg %04x, name %s, proto %s\n", hWnd, uMsg, (name)?name:"<null>", (proto)?proto:"<null>"); - return __WSAsyncDBQuery(hWnd,uMsg,0,name,0,proto,sbuf,buflen, - AQ_GETSERV|AQ_NAME|AQ_DUPLOWPTR1|AQ_DUPLOWPTR2|AQ_WIN32); + return WSA_H32( __WSAsyncDBQuery(hWnd,uMsg,0,name,0,proto,sbuf,buflen, + AQ_GETSERV|AQ_NAME|AQ_DUPLOWPTR1|AQ_DUPLOWPTR2|AQ_WIN32)); }
/*********************************************************************** @@ -703,10 +708,10 @@ HANDLE WINAPI WSAAsyncGetServByPort(HWND hWnd, UINT uMsg, INT port, LPCSTR proto, LPSTR sbuf, INT buflen) { - TRACE("hwnd %04x, msg %04x, port %i, proto %s\n", + TRACE("hwnd %p, msg %04x, port %i, proto %s\n", hWnd, uMsg, port, (proto)?proto:"<null>" ); - return __WSAsyncDBQuery(hWnd,uMsg,port,NULL,0,proto,sbuf,buflen, - AQ_GETSERV|AQ_NUMBER|AQ_DUPLOWPTR2|AQ_WIN32); + return WSA_H32( __WSAsyncDBQuery(hWnd,uMsg,port,NULL,0,proto,sbuf,buflen, + AQ_GETSERV|AQ_NUMBER|AQ_DUPLOWPTR2|AQ_WIN32)); }
/*********************************************************************** @@ -714,7 +719,7 @@ */ INT WINAPI WSACancelAsyncRequest(HANDLE hAsyncTaskHandle) { - FIXME("(%08x),stub\n", hAsyncTaskHandle); + FIXME("(%p),stub\n", hAsyncTaskHandle); return 0; }
@@ -723,7 +728,7 @@ */ INT16 WINAPI WSACancelAsyncRequest16(HANDLE16 hAsyncTaskHandle) { - return (HANDLE16)WSACancelAsyncRequest((HANDLE)hAsyncTaskHandle); + return (INT16)WSACancelAsyncRequest(WSA_H32 (hAsyncTaskHandle)); }
/*********************************************************************** Index: socket.c =================================================================== RCS file: /home/wine/wine/dlls/winsock/socket.c,v retrieving revision 1.109 diff -u -r1.109 socket.c --- socket.c 17 Oct 2002 16:43:43 -0000 1.109 +++ socket.c 28 Oct 2002 15:02:24 -0000 @@ -26,6 +26,7 @@ #include "config.h" #include "wine/port.h"
+#include <assert.h> #include <stdio.h> #include <string.h> #include <sys/types.h> @@ -131,6 +132,18 @@ inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \ ntohs(((struct sockaddr_in *)a)->sin_port))
+/* HANDLE<->SOCKET conversion (SOCKET is u_int). */ +#define SOCKET2HANDLE(s) ((HANDLE)(ULONG_PTR)(s)) +#define HANDLE2SOCKET(h) ((SOCKET)(ULONG_PTR)(h)) +#define HANDLE2SOCKET_S(h) __handle2socket(h) + +inline static SOCKET __handle2socket (HANDLE h) +/* Sanity check (necessary if sizeof (HANDLE) > sizeof (SOCKET)) */ +{ + assert ( SOCKET2HANDLE ( HANDLE2SOCKET (h) ) == h ); + return HANDLE2SOCKET(h); +} + /**************************************************************** * Async IO declarations ****************************************************************/ @@ -314,14 +327,15 @@ { int fd;
- if (set_error( wine_server_handle_to_fd( s, GENERIC_READ, &fd, NULL, NULL ) )) return -1; + if (set_error( wine_server_handle_to_fd( SOCKET2HANDLE(s), GENERIC_READ, &fd, NULL, NULL ) )) + return -1; return fd; }
inline static int _get_sock_fd_type( SOCKET s, DWORD access, enum fd_type *type, int *flags ) { int fd; - if (set_error( wine_server_handle_to_fd( s, access, &fd, type, flags ) )) return -1; + if (set_error( wine_server_handle_to_fd( SOCKET2HANDLE(s), access, &fd, type, flags ) )) return -1; if ( ( (access & GENERIC_READ) && (*flags & FD_FLAG_RECV_SHUTDOWN ) ) || ( (access & GENERIC_WRITE) && (*flags & FD_FLAG_SEND_SHUTDOWN ) ) ) { @@ -332,8 +346,8 @@ return fd; }
-static void _enable_event(SOCKET s, unsigned int event, - unsigned int sstate, unsigned int cstate) +static void _enable_event( HANDLE s, unsigned int event, + unsigned int sstate, unsigned int cstate ) { SERVER_START_REQ( enable_socket_event ) { @@ -351,7 +365,7 @@ int ret; SERVER_START_REQ( get_socket_event ) { - req->handle = s; + req->handle = SOCKET2HANDLE(s); req->service = FALSE; req->c_event = 0; wine_server_call( req ); @@ -366,7 +380,7 @@ unsigned int ret; SERVER_START_REQ( get_socket_event ) { - req->handle = s; + req->handle = SOCKET2HANDLE(s); req->service = FALSE; req->c_event = 0; wine_server_call( req ); @@ -389,7 +403,7 @@
SERVER_START_REQ( get_socket_event ) { - req->handle = s; + req->handle = SOCKET2HANDLE(s); req->service = FALSE; req->c_event = 0; wine_server_set_reply( req, events, sizeof(events) ); @@ -427,7 +441,7 @@ */ BOOL WINAPI WS_LibMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad) { - TRACE("0x%x 0x%lx %p\n", hInstDLL, fdwReason, fImpLoad); + TRACE("%p 0x%lx %p\n", hInstDLL, fdwReason, fImpLoad); switch (fdwReason) { case DLL_PROCESS_ATTACH: opentype_tls_index = TlsAlloc(); @@ -1089,7 +1103,7 @@ }
wsa->overlapped->InternalHigh = 0; - TRACE ( "wsa %p, ops %p, h %d, ev %d, fd %d, func %p, ov %p, uov %p, cfunc %p\n", + TRACE ( "wsa %p, ops %p, h %p, ev %p, fd %d, func %p, ov %p, uov %p, cfunc %p\n", wsa, wsa->async.ops, wsa->async.handle, wsa->async.event, wsa->async.fd, wsa->async.func, wsa->overlapped, wsa->user_overlapped, wsa->completion_func );
@@ -1196,7 +1210,7 @@ wsa->overlapped->Internal = STATUS_SUCCESS; wsa->overlapped->InternalHigh = result; TRACE ( "received %d bytes\n", result ); - _enable_event ( (SOCKET) wsa->async.handle, FD_READ, 0, 0 ); + _enable_event ( wsa->async.handle, FD_READ, 0, 0 ); return; }
@@ -1204,7 +1218,7 @@ if ( err == WSAEINTR || err == WSAEWOULDBLOCK ) /* errno: EINTR / EAGAIN */ { wsa->overlapped->Internal = STATUS_PENDING; - _enable_event ( (SOCKET) wsa->async.handle, FD_READ, 0, 0 ); + _enable_event ( wsa->async.handle, FD_READ, 0, 0 ); TRACE ( "still pending\n" ); } else @@ -1288,7 +1302,7 @@ wsa->overlapped->Internal = STATUS_SUCCESS; wsa->overlapped->InternalHigh = result; TRACE ( "sent %d bytes\n", result ); - _enable_event ( (SOCKET) wsa->async.handle, FD_WRITE, 0, 0 ); + _enable_event ( wsa->async.handle, FD_WRITE, 0, 0 ); return; }
@@ -1296,7 +1310,7 @@ if ( err == WSAEINTR ) { wsa->overlapped->Internal = STATUS_PENDING; - _enable_event ( (SOCKET) wsa->async.handle, FD_WRITE, 0, 0 ); + _enable_event ( wsa->async.handle, FD_WRITE, 0, 0 ); TRACE ( "still pending\n" ); } else @@ -1373,7 +1387,7 @@ goto out; } /* Try immediate completion */ - if ( WSAGetOverlappedResult ( (HANDLE) s, ovl, NULL, FALSE, NULL ) ) + if ( WSAGetOverlappedResult ( s, ovl, NULL, FALSE, NULL ) ) return 0; if ( (err = WSAGetLastError ()) == WSA_IO_INCOMPLETE ) return 0; @@ -1411,11 +1425,11 @@ close(fd); SERVER_START_REQ( accept_socket ) { - req->lhandle = s; + req->lhandle = SOCKET2HANDLE(s); req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; req->inherit = TRUE; set_error( wine_server_call( req ) ); - as = (SOCKET)reply->handle; + as = HANDLE2SOCKET_S( reply->handle ); } SERVER_END_REQ; if (as) @@ -1524,7 +1538,7 @@ int WINAPI WS_closesocket(SOCKET s) { TRACE("socket %08x\n", s); - if (CloseHandle(s)) return 0; + if (CloseHandle(SOCKET2HANDLE(s))) return 0; return SOCKET_ERROR; }
@@ -1571,7 +1585,7 @@ if (errno == EINPROGRESS) { /* tell wineserver that a connection is in progress */ - _enable_event(s, FD_CONNECT|FD_READ|FD_WRITE, + _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE, FD_CONNECT|FD_READ|FD_WRITE, FD_WINE_CONNECTED|FD_WINE_LISTENING); if (_is_blocking(s)) @@ -1608,7 +1622,7 @@
connect_success: close(fd); - _enable_event(s, FD_CONNECT|FD_READ|FD_WRITE, + _enable_event(SOCKET2HANDLE(s), FD_CONNECT|FD_READ|FD_WRITE, FD_WINE_CONNECTED|FD_READ|FD_WRITE, FD_CONNECT|FD_WINE_LISTENING); return 0; @@ -2236,9 +2250,9 @@ } close(fd); if (*argp) - _enable_event(s, 0, FD_WINE_NONBLOCKING, 0); + _enable_event(SOCKET2HANDLE(s), 0, FD_WINE_NONBLOCKING, 0); else - _enable_event(s, 0, 0, FD_WINE_NONBLOCKING); + _enable_event(SOCKET2HANDLE(s), 0, 0, FD_WINE_NONBLOCKING); return 0;
case WS_SIOCATMARK: @@ -2295,7 +2309,7 @@ if (listen(fd, backlog) == 0) { close(fd); - _enable_event(s, FD_ACCEPT, + _enable_event(SOCKET2HANDLE(s), FD_ACCEPT, FD_WINE_LISTENING, FD_CONNECT|FD_WINE_CONNECTED); return 0; @@ -2562,7 +2576,7 @@ /* Try immediate completion */ if ( lpOverlapped && !NtResetEvent( lpOverlapped->hEvent, NULL ) ) { - if ( WSAGetOverlappedResult ( (HANDLE) s, lpOverlapped, + if ( WSAGetOverlappedResult ( s, lpOverlapped, lpNumberOfBytesSent, FALSE, &dwFlags) ) return 0;
@@ -2585,7 +2599,7 @@ { err = wsaErrno(); if ( err == WSAEWOULDBLOCK ) - _enable_event (s, FD_WRITE, 0, 0); + _enable_event (SOCKET2HANDLE(s), FD_WRITE, 0, 0); goto err_free; }
@@ -2849,12 +2863,12 @@ close(fd); }
- _enable_event( s, 0, 0, clear_flags ); + _enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags ); if ( how > 1) WSAAsyncSelect( s, 0, 0, 0 ); return 0;
error: - _enable_event( s, 0, 0, clear_flags ); + _enable_event( SOCKET2HANDLE(s), 0, 0, clear_flags ); WSASetLastError ( err ); return SOCKET_ERROR; } @@ -3247,11 +3261,11 @@ { int ret;
- TRACE("%08x, hEvent %08x, lpEvent %08x\n", s, hEvent, (unsigned)lpEvent ); + TRACE("%08x, hEvent %p, lpEvent %08x\n", s, hEvent, (unsigned)lpEvent );
SERVER_START_REQ( get_socket_event ) { - req->handle = s; + req->handle = SOCKET2HANDLE(s); req->service = TRUE; req->c_event = hEvent; wine_server_set_reply( req, lpEvent->iErrorCode, sizeof(lpEvent->iErrorCode) ); @@ -3270,11 +3284,11 @@ { int ret;
- TRACE("%08x, hEvent %08x, event %08x\n", s, hEvent, (unsigned)lEvent ); + TRACE("%08x, hEvent %p, event %08x\n", s, hEvent, (unsigned)lEvent );
SERVER_START_REQ( set_socket_event ) { - req->handle = s; + req->handle = SOCKET2HANDLE(s); req->mask = lEvent; req->event = hEvent; req->window = 0; @@ -3319,7 +3333,7 @@ if ( r == WAIT_OBJECT_0 ) NtSetEvent ( lpOverlapped->hEvent, NULL ); } - + if ( lpcbTransfer ) *lpcbTransfer = lpOverlapped->InternalHigh;
@@ -3348,11 +3362,11 @@ { int ret;
- TRACE("%x, hWnd %x, uMsg %08x, event %08lx\n", s, hWnd, uMsg, lEvent ); + TRACE("%x, hWnd %p, uMsg %08x, event %08lx\n", s, hWnd, uMsg, lEvent );
SERVER_START_REQ( set_socket_event ) { - req->handle = s; + req->handle = SOCKET2HANDLE(s); req->mask = lEvent; req->event = 0; req->window = hWnd; @@ -3404,7 +3418,7 @@ */ BOOL WINAPI WSACloseEvent(WSAEVENT event) { - TRACE ("event=0x%x\n", event); + TRACE ("event=%p\n", event);
return CloseHandle(event); } @@ -3491,7 +3505,7 @@ req->flags = dwFlags; req->inherit = TRUE; set_error( wine_server_call( req ) ); - ret = (SOCKET)reply->handle; + ret = HANDLE2SOCKET_S( reply->handle ); } SERVER_END_REQ; if (ret) @@ -4005,7 +4019,7 @@ /* Try immediate completion */ if ( lpOverlapped && !NtResetEvent( lpOverlapped->hEvent, NULL ) ) { - if ( WSAGetOverlappedResult ( (HANDLE) s, lpOverlapped, + if ( WSAGetOverlappedResult ( s, lpOverlapped, lpNumberOfBytesRecvd, FALSE, lpFlags) ) return 0;
@@ -4036,7 +4050,7 @@
HeapFree (GetProcessHeap(), 0, iovec); close(fd); - _enable_event(s, FD_READ, 0, 0); + _enable_event(SOCKET2HANDLE(s), FD_READ, 0, 0);
return 0;
@@ -4127,12 +4141,12 @@ case CF_DEFER: SERVER_START_REQ ( set_socket_deferred ) { - req->handle = s; - req->deferred = cs; + req->handle = SOCKET2HANDLE (s); + req->deferred = SOCKET2HANDLE (cs); if ( !wine_server_call_err ( req ) ) { SetLastError ( WSATRY_AGAIN ); - CloseHandle ( cs ); + WS_closesocket ( cs ); } } SERVER_END_REQ; @@ -4184,7 +4198,7 @@ * the target use the global duplicate, or we could copy a reference to us to the structure * and let the target duplicate it from us, but let's do it as simple as possible */ hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId); - DuplicateHandle(GetCurrentProcess(), s, + DuplicateHandle(GetCurrentProcess(), SOCKET2HANDLE(s), hProcess, (LPHANDLE)&lpProtocolInfo->dwCatalogEntryId, 0, FALSE, DUPLICATE_SAME_ACCESS); CloseHandle(hProcess);
Hello Martin,
On Mon, Oct 28, 2002 at 04:07:46PM +0100, Martin Wilck wrote:
here is a patch to make winsock compile without warnings without -DWINE_NO_STRICT. Comments are welcome.
Well, i looked at the patch and it seems resonable. You are the winsock expert and if you feel confortable with it please submit it to wine-patches (Alexandre will complain if he dosn't like it ;). One request: i'm not sure if the compiler will optimize away the assert from __handle2socket on machines where sizeof(HANDLE) == sizeof(SOCKET). But if not could you please add something like if (sizeof(HANDLE) > sizeof(SOCKET)) { assert(.... } On i386 the size are equal and the assert not needed.
bye michael
Michael Stefaniuc mstefani@redhat.de writes:
Well, i looked at the patch and it seems resonable. You are the winsock expert and if you feel confortable with it please submit it to wine-patches (Alexandre will complain if he dosn't like it ;). One request: i'm not sure if the compiler will optimize away the assert from __handle2socket on machines where sizeof(HANDLE) == sizeof(SOCKET). But if not could you please add something like if (sizeof(HANDLE) > sizeof(SOCKET)) { assert(.... } On i386 the size are equal and the assert not needed.
The assert is useless anyway. Even if the types have different sizes you'll need to allocate a billion handles to trigger it. It's much better to use a simple cast (without ULONG_PTR) so the compiler will warn if the pointer and integer are different sizes.
Michael Stefaniuc wrote:
i'm not sure if the compiler will optimize away the assert from __handle2socket on machines where sizeof(HANDLE) = sizeof(SOCKET).
gcc does optimize this away if the function is declared inline, checked that. The assert is used only when new sockets are allocated (i.e. only in socket() and accept() calls), it is certainly not performance-critical.
Alexandre Julliard wrote:
The assert is useless anyway. Even if the types have different sizes you'll need to allocate a billion handles to trigger it.
If _you_ say that - I didn't feel bold enough to argue that way :-)
It's much better to use a simple cast (without ULONG_PTR) so the compiler will warn if the pointer and integer are different sizes.
If you really want a compiler warning rather than a runtime error, OK.
Perhaps someone could check if SOCKET is really a 32bit type on 64bit Windows.
Martin