Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2002
- 132 participants
- 664 messages
Re: ALSA driver
by Gavriel State
Ove Kaaven wrote:
> On 19 Apr 2002, Marco Pietrobono wrote:
>
>
>> I'm starting to work on a native ALSA driver for wine. Since I
>>remember that Marcus was working (or was planning to work) an that one
>>too, I would like to know if there is already something to work on or to
>>contribute to, or if I need to start from scratch.
>
> You must be mistaken, Eric Pouech was working on the ALSA driver. This
> driver is also pretty much complete, just bugfixes remain. Unfortunately,
> it's currently in the cold slimy clutches (from the LGPL-Wine perspective)
> of TransGaming staff, who might not want to part with it without getting
> some of that glorious LGPL code in Wine relicensed in exchange...
Actually, we have no official claim over the ALSA driver - we offered to
sponsor Eric Poech's development, but he asked that we put it into another
sponsorship instead. I am going to try to get the details of our proposals
to trade / sponsor some code up next week. We have this DIB engine we've
been working on for a bit, for example....
It is true though that TransGaming's David Hammerton 'has his clutches' on
the code - he's been working on it with Eric in his spare time. That said,
I just checked and while his hands are kind of cold, they didn't appear
to be at all slimy. David said that he might try to check it into the ReWind
tree this weekend.
-Gav
--
Gavriel State, CEO
TransGaming Technologies Inc.
http://www.transgaming.com/
gav(a)transgaming.com
April 19, 2002
(no subject)
by Ann and Jason Edmeades
I've noticed a small bug when using wcmd, in the changing to a directory, eg
c:\windows and doing 'dir \' fails to show the root directory. Its annoyed
me to the point of investigating and the problem seems to lie further down
inside the DOSFS_DoGetFullPathName routine. A simple testpgm shows the
problem:
#include <windows.h>
void main() {
char A[] = "\\";
char B[1024];
int rc;
rc = GetFullPathName (A, sizeof(B), B, NULL);
printf("rc = %d, a=%s, b=%s\n", rc, A, B);
}
(Note: Testpgm run on w2k)
Unfortunately I also noticed how often this routine is called and how many
cases it appears to be trying to handle, so am slightly nervous about
touching it! I am going to do some more investigation but does anyone have
any thoughts in the meantime?
Thanks
Jason
jason @ the-edmeades.demon.co.uk
April 19, 2002
Re: [PATCH] Big winsock2 / overlapped patch
by Sylvain Petreolle
--- Martin Wilck <Martin.Wilck(a)fujitsu-siemens.com> a
écrit : >
> Hi,
>
> This stuff really approaches a usable state!
>
> I know the patch is much too big but I have no time
> now to split it into
> pieces before next week.
If the patch is too big, then gzip it and send it
as an attachment :)
___________________________________________________________
Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en français !
Yahoo! Mail : http://fr.mail.yahoo.com
April 19, 2002
Re: toolbar.c problem (ATTN: Duane)
by Dusan Vujosevic
----- Original Message -----
From: "Duane Clark" <dclark(a)akamail.com>
To: <wine-devel(a)winehq.com>
Sent: Friday, April 19, 2002 11:41 AM
Subject: Re: toolbar.c problem (ATTN: Duane)
> I think you misunderstood my explanation. Once the menu is stuck and the
> button released, I slide the mouse into the flying menu and back out
> again, without pressing any mouse buttons. When the cursor leaves the
> flying menu, it disappears, but without calling TOOLBAR_LButtonUp().
> This is the second behavior, which may not be related.
I am working with the latest build of SL and this doesn't happen. I guess
you have the demo and that it does have that problem in which case it is
irrelevant since it has been fixed.
> >>Unfortunately
> >>for me, my real work is once again interfering severely with the amount
> >>of time I have to spend on Wine :-(
> >
> >
> > I'd be all too happy to help. I will take off my own time to test & fix
> > this. I'll try give you something over the weekend (patch).
> >
> >
> >> But I will try to get in a couple
> >>of tests with ControlSpy with the TBSTYLE_DROPDOWN style, since it
> >>should not take much time, perhaps this weekend.
>
> A suggestion I made a couple weeks ago would make things easier, I would
> think. That would be to duplicate your flying menus within ControlSpy. I
> don't know how easy that would be to implement, but once implemented, it
> would likely make debugging much easier.
OK, that's what I'll do. I will implement it (not a big deal) and forward it
to you. Expect it this weekend some time..
Thanks,
Dusan
April 19, 2002
Re: ALSA driver
by Dimitrie O. Paun
On April 19, 2002 12:45 pm, Ove Kaaven wrote:
> it's currently in the cold slimy clutches (from the LGPL-Wine perspective)
as if it's not from the X11-Wine perspective...
--
Dimi.
April 19, 2002
Re: Using WineLib directly
by Marcus Meissner
On Thu, Apr 18, 2002 at 06:45:05AM -0700, Zavada, Ed wrote:
> I've seen this question asked before, but there was never a response to the newsgroup.
>
> We'd like to use WineLib to provide implementations of the Windows
> calls in our application's Linux build while we work on a full blown
> port. So far, all the documentation requires that we use winebuild and
> generate a .so that is loaded by the wine server. Is this truely the
> only way to do this?
The .so is loaded by the 'wine' binary, not the server.
But actually yes, most sublibraries require wineserver to be running
to be used.
> Is there no way to just use the various libraries independent of wine
> server? For instance, I'd like to be able to make a call to MessageBox()
> from a native linux binary, then later eliminate the need for it (since
> this will ultimately be a console app).
I do not think so.
Ciao, Marcus
April 19, 2002
Re: ALSA driver
by Ove Kaaven
On 19 Apr 2002, Marco Pietrobono wrote:
> I'm starting to work on a native ALSA driver for wine. Since I
> remember that Marcus was working (or was planning to work) an that one
> too, I would like to know if there is already something to work on or to
> contribute to, or if I need to start from scratch.
You must be mistaken, Eric Pouech was working on the ALSA driver. This
driver is also pretty much complete, just bugfixes remain. Unfortunately,
it's currently in the cold slimy clutches (from the LGPL-Wine perspective)
of TransGaming staff, who might not want to part with it without getting
some of that glorious LGPL code in Wine relicensed in exchange...
April 19, 2002
[PATCH] Big winsock2 / overlapped patch
by Martin Wilck
Hi,
This stuff really approaches a usable state!
I know the patch is much too big but I have no time now to split it into
pieces before next week.
However, I am so excited to see the close events coming at the right time
that I must post it here and encourage people to try it.
Patch summary:
- Implement overlapped IO on sockets and the necessary changes in
overlapped request handling.
- Fix socket behaviour after FD_CLOSE received, when socket has been taken
out of the server's main select loop.
- Fix some more aspects of FD_CLOSE.
- Fix WSAAccept() deferred accept.
- Implement WSAGetOverlappedResult and WSAConnect().
- Some improvements for error code handling in Winsock2.
Tested: so far with my test programs only, but they really tries to make
things hard for wine.
Patch against yesterday's (2002/04/18) CVS version of wine.
Have fun,
Martin
--
Martin Wilck Phone: +49 5251 8 15113
Fujitsu Siemens Computers Fax: +49 5251 8 20409
Heinz-Nixdorf-Ring 1 mailto:Martin.Wilck(a)Fujitsu-Siemens.com
D-33106 Paderborn http://www.fujitsu-siemens.com/primergy
diff -ruNX ignore TMP/wine/dlls/winsock/socket.c MW/wine/dlls/winsock/socket.c
--- TMP/wine/dlls/winsock/socket.c Thu Apr 18 16:26:02 2002
+++ MW/wine/dlls/winsock/socket.c Fri Apr 19 15:51:52 2002
@@ -104,6 +104,7 @@
#include "wine/winbase16.h"
#include "wingdi.h"
#include "winuser.h"
+#include "winerror.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "wsipx.h"
@@ -125,6 +126,53 @@
inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
ntohs(((struct sockaddr_in *)a)->sin_port))
+/****************************************************************
+ * Async IO declarations
+ ****************************************************************/
+#include "async.h"
+
+static DWORD ws2_async_get_status (const struct async_private *ovp);
+static DWORD ws2_async_get_count (const struct async_private *ovp);
+static void ws2_async_set_status (struct async_private *ovp, const DWORD status);
+static void CALLBACK ws2_async_call_completion (ULONG_PTR data);
+static void ws2_async_cleanup ( struct async_private *ovp );
+
+static struct async_ops ws2_async_ops =
+{
+ ws2_async_get_status,
+ ws2_async_set_status,
+ ws2_async_get_count,
+ ws2_async_call_completion,
+ ws2_async_cleanup
+};
+
+static struct async_ops ws2_nocomp_async_ops =
+{
+ ws2_async_get_status,
+ ws2_async_set_status,
+ ws2_async_get_count,
+ NULL, /* call_completion */
+ ws2_async_cleanup
+};
+
+typedef struct ws2_async
+{
+ async_private async;
+ LPWSAOVERLAPPED overlapped;
+ LPWSAOVERLAPPED user_overlapped;
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_func;
+ struct iovec *iovec;
+ int n_iovecs;
+ struct WS_sockaddr *addr;
+ union {
+ int val; /* for send operations */
+ int *ptr; /* for recv operations */
+ } addrlen;
+ DWORD flags;
+} ws2_async;
+
+/****************************************************************/
+
/* ----------------------------------- internal data */
/* ws_... struct conversion flags */
@@ -223,13 +271,39 @@
*/
static int opentype = 0;
+inline static DWORD NtStatusToWSAError ( const DWORD status )
+{
+ /* We only need to cover the status codes set by server async request handling */
+ DWORD wserr;
+ switch ( status )
+ {
+ case STATUS_SUCCESS: wserr = 0; break;
+ case STATUS_PENDING: wserr = WSA_IO_PENDING; break;
+ case STATUS_INVALID_HANDLE: wserr = WSAENOTSOCK; break; /* WSAEBADF ? */
+ case STATUS_INVALID_PARAMETER: wserr = WSAEINVAL; break;
+ case STATUS_PIPE_DISCONNECTED: wserr = WSAESHUTDOWN; break;
+ case STATUS_CANCELLED: wserr = WSA_OPERATION_ABORTED; break;
+ case STATUS_TIMEOUT: wserr = WSAETIMEDOUT; break;
+ case STATUS_NO_MEMORY: wserr = WSAEFAULT; break;
+ default:
+ if ( status >= WSABASEERR && status <= WSABASEERR+1004 )
+ /* It is not a NT status code but a winsock error */
+ wserr = status;
+ else
+ {
+ wserr = RtlNtStatusToDosError( status );
+ FIXME ( "Status code %08lx converted to DOS error code %lx\n", status, wserr );
+ }
+ }
+ return wserr;
+}
+
/* set last error code from NT status without mapping WSA errors */
inline static unsigned int set_error( unsigned int err )
{
if (err)
{
- /* do not map WSA errors */
- if ((err < WSABASEERR) || (err >= 0x10000000)) err = RtlNtStatusToDosError(err);
+ err = NtStatusToWSAError ( err );
SetLastError( err );
}
return err;
@@ -245,10 +319,17 @@
return fd;
}
-inline static int _get_sock_fd_type( SOCKET s, enum fd_type *type, int *flags )
+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, GENERIC_READ, &fd, type, flags ) )) return -1;
+ if (set_error( wine_server_handle_to_fd( s, access, &fd, type, flags ) )) return -1;
+ if ( ( (access & GENERIC_READ) && (*flags & FD_FLAG_RECV_SHUTDOWN ) ) ||
+ ( (access & GENERIC_WRITE) && (*flags & FD_FLAG_SEND_SHUTDOWN ) ) )
+ {
+ close (fd);
+ WSASetLastError ( WSAESHUTDOWN );
+ return -1;
+ }
return fd;
}
@@ -904,6 +985,399 @@
free((void*)uaddr);
}
+/**************************************************************************
+ * Functions for handling overlapped I/O
+ **************************************************************************/
+
+static DWORD ws2_async_get_status (const struct async_private *ovp)
+{
+ return ((ws2_async*) ovp)->overlapped->Internal;
+}
+
+static VOID ws2_async_set_status (struct async_private *ovp, const DWORD status)
+{
+ ((ws2_async*) ovp)->overlapped->Internal = status;
+}
+
+static DWORD ws2_async_get_count (const struct async_private *ovp)
+{
+ return ((ws2_async*) ovp)->overlapped->InternalHigh;
+}
+
+static void ws2_async_cleanup ( struct async_private *ap )
+{
+ struct ws2_async *as = (struct ws2_async*) ap;
+
+ TRACE ( "as: %p uovl %p ovl %p\n", as, as->user_overlapped, as->overlapped );
+ if ( !as->user_overlapped )
+ {
+ if ( as->overlapped->hEvent != INVALID_HANDLE_VALUE )
+ WSACloseEvent ( as->overlapped->hEvent );
+ HeapFree ( GetProcessHeap(), 0, as->overlapped );
+ }
+
+ if ( as->iovec )
+ HeapFree ( GetProcessHeap(), 0, as->iovec );
+
+ HeapFree ( GetProcessHeap(), 0, as );
+}
+
+static void CALLBACK ws2_async_call_completion (ULONG_PTR data)
+{
+ ws2_async* as = (ws2_async*) data;
+
+ TRACE ("data: %p\n", as);
+
+ as->completion_func ( NtStatusToWSAError (as->overlapped->Internal),
+ as->overlapped->InternalHigh,
+ as->user_overlapped,
+ as->flags );
+ ws2_async_cleanup ( &as->async );
+}
+
+/***********************************************************************
+ * WS2_make_async (INTERNAL)
+ */
+
+static void WS2_async_recv (async_private *as);
+static void WS2_async_send (async_private *as);
+
+inline static struct ws2_async*
+WS2_make_async (SOCKET s, int fd, int type, struct iovec *iovec, DWORD dwBufferCount,
+ LPDWORD lpFlags, struct WS_sockaddr *addr,
+ LPINT addrlen, LPWSAOVERLAPPED lpOverlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
+{
+ struct ws2_async *wsa = HeapAlloc ( GetProcessHeap(), 0, sizeof ( ws2_async ) );
+
+ TRACE ( "wsa %p\n", wsa );
+
+ if (!wsa)
+ return NULL;
+
+ wsa->async.ops = ( lpCompletionRoutine ? &ws2_async_ops : &ws2_nocomp_async_ops );
+ wsa->async.handle = (HANDLE) s;
+ wsa->async.fd = fd;
+ wsa->async.type = type;
+ switch (type)
+ {
+ case ASYNC_TYPE_READ:
+ wsa->flags = *lpFlags;
+ wsa->async.func = WS2_async_recv;
+ wsa->addrlen.ptr = addrlen;
+ break;
+ case ASYNC_TYPE_WRITE:
+ wsa->flags = 0;
+ wsa->async.func = WS2_async_send;
+ wsa->addrlen.val = *addrlen;
+ break;
+ default:
+ ERR ("Invalid async type: %d\n", type);
+ }
+ wsa->user_overlapped = lpOverlapped;
+ wsa->completion_func = lpCompletionRoutine;
+ wsa->iovec = iovec;
+ wsa->n_iovecs = dwBufferCount;
+ wsa->addr = addr;
+
+ if ( lpOverlapped )
+ {
+ wsa->overlapped = lpOverlapped;
+ wsa->async.event = ( lpCompletionRoutine ? INVALID_HANDLE_VALUE : lpOverlapped->hEvent );
+ }
+ else
+ {
+ wsa->overlapped = HeapAlloc ( GetProcessHeap(), 0,
+ sizeof (WSAOVERLAPPED) );
+ if ( !wsa->overlapped )
+ goto error;
+ wsa->async.event = wsa->overlapped->hEvent = INVALID_HANDLE_VALUE;
+ }
+
+ wsa->overlapped->InternalHigh = 0;
+ TRACE ( "wsa %p, ops %p, h %d, ev %d, 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 );
+
+ return wsa;
+
+error:
+ TRACE ("Error\n");
+ HeapFree ( GetProcessHeap(), 0, wsa );
+ return NULL;
+}
+
+/***********************************************************************
+ * WS2_recv (INTERNAL)
+ *
+ * Work horse for both synchronous and asynchronous recv() operations.
+ */
+static int WS2_recv ( int fd, struct iovec* iov, int count,
+ struct WS_sockaddr *lpFrom, LPINT lpFromlen,
+ LPDWORD lpFlags )
+{
+ struct msghdr hdr;
+ int n;
+ TRACE ( "fd %d, iovec %p, count %d addr %p, len %p, flags %lx\n",
+ fd, iov, count, lpFrom, lpFromlen, *lpFlags);
+
+ hdr.msg_name = NULL;
+
+ if ( lpFrom )
+ {
+#if DEBUG_SOCKADDR
+ dump_sockaddr (lpFrom);
+#endif
+
+ hdr.msg_namelen = *lpFromlen;
+ hdr.msg_name = ws_sockaddr_alloc ( lpFrom, lpFromlen, &hdr.msg_namelen );
+ if ( !hdr.msg_name )
+ {
+ WSASetLastError ( WSAEFAULT );
+ n = -1;
+ goto out;
+ }
+ }
+ else
+ hdr.msg_namelen = 0;
+
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = count;
+ hdr.msg_control = NULL;
+ hdr.msg_controllen = 0;
+ hdr.msg_flags = 0;
+
+ if ( (n = recvmsg (fd, &hdr, *lpFlags)) == -1 )
+ {
+ TRACE ( "recvmsg error %d\n", errno);
+ goto out;
+ }
+
+ if ( lpFrom &&
+ ws_sockaddr_u2ws ( hdr.msg_name, hdr.msg_namelen,
+ lpFrom, lpFromlen ) != 0 )
+ {
+ /* The from buffer was too small, but we read the data
+ * anyway. Is that really bad?
+ */
+ WSASetLastError ( WSAEFAULT );
+ WARN ( "Address buffer too small\n" );
+ }
+
+out:
+
+ ws_sockaddr_free ( hdr.msg_name, lpFrom );
+ TRACE ("-> %d\n", n);
+ return n;
+}
+
+/***********************************************************************
+ * WS2_async_recv (INTERNAL)
+ *
+ * Handler for overlapped recv() operations.
+ */
+static void WS2_async_recv ( async_private *as )
+{
+ ws2_async* wsa = (ws2_async*) as;
+ int result, err;
+
+ TRACE ( "async %p\n", wsa );
+
+ if ( wsa->overlapped->Internal != STATUS_PENDING )
+ {
+ TRACE ( "status: %ld\n", wsa->overlapped->Internal );
+ return;
+ }
+
+ result = WS2_recv ( wsa->async.fd, wsa->iovec, wsa->n_iovecs,
+ wsa->addr, wsa->addrlen.ptr, &wsa->flags );
+
+ if (result >= 0)
+ {
+ 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 );
+ return;
+ }
+
+ err = wsaErrno ();
+ if ( err == WSAEINTR || err == WSAEWOULDBLOCK ) /* errno: EINTR / EAGAIN */
+ {
+ wsa->overlapped->Internal = STATUS_PENDING;
+ _enable_event ( (SOCKET) wsa->async.handle, FD_READ, 0, 0 );
+ TRACE ( "still pending\n" );
+ }
+ else
+ {
+ wsa->overlapped->Internal = err;
+ TRACE ( "Error: %x\n", err );
+ }
+}
+
+/***********************************************************************
+ * WS2_send (INTERNAL)
+ *
+ * Work horse for both synchronous and asynchronous send() operations.
+ */
+static int WS2_send ( int fd, struct iovec* iov, int count,
+ const struct WS_sockaddr *to, INT tolen, DWORD dwFlags )
+{
+ struct msghdr hdr;
+ int n = -1;
+ TRACE ( "fd %d, iovec %p, count %d addr %p, len %d, flags %lx\n",
+ fd, iov, count, to, tolen, dwFlags);
+
+ hdr.msg_name = NULL;
+
+ if ( to )
+ {
+#if DEBUG_SOCKADDR
+ dump_sockaddr (to);
+#endif
+ hdr.msg_name = (struct sockaddr*) ws_sockaddr_ws2u ( to, tolen, &hdr.msg_namelen );
+ if ( !hdr.msg_name )
+ {
+ WSASetLastError ( WSAEFAULT );
+ goto out;
+ }
+ }
+ else
+ hdr.msg_namelen = 0;
+
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = count;
+ hdr.msg_control = NULL;
+ hdr.msg_controllen = 0;
+ hdr.msg_flags = 0;
+
+ n = sendmsg (fd, &hdr, dwFlags);
+
+out:
+ ws_sockaddr_free ( hdr.msg_name, to );
+ return n;
+}
+
+/***********************************************************************
+ * WS2_async_send (INTERNAL)
+ *
+ * Handler for overlapped send() operations.
+ */
+static void WS2_async_send ( async_private *as )
+{
+ ws2_async* wsa = (ws2_async*) as;
+ int result, err;
+
+ TRACE ( "async %p\n", wsa );
+
+ if ( wsa->overlapped->Internal != STATUS_PENDING )
+ {
+ TRACE ( "status: %ld\n", wsa->overlapped->Internal );
+ return;
+ }
+
+ result = WS2_send ( wsa->async.fd, wsa->iovec, wsa->n_iovecs,
+ wsa->addr, wsa->addrlen.val, wsa->flags );
+
+ if (result >= 0)
+ {
+ 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 );
+ return;
+ }
+
+ err = wsaErrno ();
+ if ( err == WSAEINTR )
+ {
+ wsa->overlapped->Internal = STATUS_PENDING;
+ _enable_event ( (SOCKET) wsa->async.handle, FD_WRITE, 0, 0 );
+ TRACE ( "still pending\n" );
+ }
+ else
+ {
+ /* We set the status to a winsock error code and check for that
+ later in NtStatusToWSAError () */
+ wsa->overlapped->Internal = err;
+ TRACE ( "Error: %x\n", err );
+ }
+}
+
+/***********************************************************************
+ * WS2_async_shutdown (INTERNAL)
+ *
+ * Handler for shutdown() operations on overlapped sockets.
+ */
+static void WS2_async_shutdown ( async_private *as )
+{
+ ws2_async* wsa = (ws2_async*) as;
+ int err = 1;
+
+ TRACE ( "async %p %d\n", wsa, wsa->async.type );
+ switch ( wsa->async.type )
+ {
+ case ASYNC_TYPE_READ:
+ err = shutdown ( wsa->async.fd, 0 );
+ break;
+ case ASYNC_TYPE_WRITE:
+ err = shutdown ( wsa->async.fd, 1 );
+ break;
+ default:
+ ERR ("invalid type: %d\n", wsa->async.type );
+ }
+
+ if ( err )
+ wsa->overlapped->Internal = wsaErrno ();
+ else
+ wsa->overlapped->Internal = STATUS_SUCCESS;
+}
+
+/***********************************************************************
+ * WS2_register_async_shutdown (INTERNAL)
+ *
+ * Helper function for WS_shutdown() on overlapped sockets.
+ */
+static int WS2_register_async_shutdown ( SOCKET s, int fd, int type )
+{
+ struct ws2_async *wsa;
+ int ret, err = WSAEFAULT;
+ DWORD dwflags = 0;
+ int len = 0;
+ LPWSAOVERLAPPED ovl = HeapAlloc (GetProcessHeap(), 0, sizeof ( WSAOVERLAPPED ));
+
+ TRACE ("s %d fd %d type %d\n", s, fd, type);
+ if (!ovl)
+ goto out;
+
+ ovl->hEvent = WSACreateEvent ();
+ if ( ovl->hEvent == WSA_INVALID_EVENT )
+ goto out_free;
+
+ wsa = WS2_make_async ( s, fd, type, NULL, 0,
+ &dwflags, NULL, &len, ovl, NULL );
+ if ( !wsa )
+ goto out_close;
+
+ /* Hack: this will cause ws2_async_cleanup() to free the overlapped structure */
+ wsa->user_overlapped = NULL;
+ wsa->async.func = WS2_async_shutdown;
+ if ( (ret = register_new_async ( &wsa->async )) )
+ {
+ err = NtStatusToWSAError ( ret );
+ ws2_async_cleanup ( &wsa->async );
+ goto out;
+ }
+ return 0;
+
+out_close:
+ WSACloseEvent ( ovl->hEvent );
+out_free:
+ HeapFree ( GetProcessHeap(), 0, ovl );
+out:
+ return err;
+}
+
/***********************************************************************
* accept (WS2_32.1)
*/
@@ -1139,6 +1613,19 @@
}
/***********************************************************************
+ * WSAConnect (WS2_32.30)
+ */
+int WINAPI WSAConnect ( SOCKET s, const struct WS_sockaddr* name, int namelen,
+ LPWSABUF lpCallerData, LPWSABUF lpCalleeData,
+ LPQOS lpSQOS, LPQOS lpGQOS )
+{
+ if ( lpCallerData || lpCalleeData || lpSQOS || lpGQOS )
+ FIXME ("unsupported parameters!\n");
+ return WS_connect ( s, name, namelen );
+}
+
+
+/***********************************************************************
* getpeername (WS2_32.5)
*/
int WINAPI WS_getpeername(SOCKET s, struct WS_sockaddr *name, int *namelen)
@@ -1982,25 +2469,29 @@
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
{
- int i, n, fd, err = WSAENOTSOCK, flags;
+ int i, n, fd, err = WSAENOTSOCK, flags, ret;
struct iovec* iovec;
- struct msghdr msghdr;
+ struct ws2_async *wsa;
enum fd_type type;
TRACE ("socket %04x, wsabuf %p, nbufs %ld, flags %ld, to %p, tolen %d, ovl %p, func %p\n",
s, lpBuffers, dwBufferCount, dwFlags,
to, tolen, lpOverlapped, lpCompletionRoutine);
- fd = _get_sock_fd_type( s, &type, &flags );
+ fd = _get_sock_fd_type( s, GENERIC_WRITE, &type, &flags );
+ TRACE ( "fd=%d, type=%d, flags=%x\n", fd, type, flags );
if ( fd == -1 )
+ {
+ err = WSAGetLastError ();
goto error;
+ }
iovec = WS_ALLOC ( dwBufferCount * sizeof (struct iovec) );
if ( !iovec )
{
- err = WSAENOBUFS;
+ err = WSAEFAULT;
goto err_close;
}
@@ -2010,30 +2501,42 @@
iovec[i].iov_len = lpBuffers[i].len;
}
- msghdr.msg_name = NULL;
-
- if (to)
+ if ( (lpOverlapped || lpCompletionRoutine) && flags & FD_FLAG_OVERLAPPED )
{
-#if DEBUG_SOCKADDR
- dump_sockaddr (to);
-#endif
- msghdr.msg_name = (void*) ws_sockaddr_ws2u (to, tolen, &msghdr.msg_namelen);
- if ( !msghdr.msg_name )
+ wsa = WS2_make_async ( s, fd, ASYNC_TYPE_WRITE, iovec, dwBufferCount,
+ &dwFlags, (struct WS_sockaddr*) to, &tolen,
+ lpOverlapped, lpCompletionRoutine );
+ if ( !wsa )
{
err = WSAEFAULT;
goto err_free;
}
- }
- else
- msghdr.msg_namelen = 0;
+
+ if ( ( ret = register_new_async ( &wsa->async )) )
+ {
+ err = NtStatusToWSAError ( ret );
+
+ if ( !lpOverlapped )
+ HeapFree ( GetProcessHeap(), 0, wsa->overlapped );
+ HeapFree ( GetProcessHeap(), 0, wsa );
+ goto err_free;
+ }
- msghdr.msg_iov = iovec;
- msghdr.msg_iovlen = dwBufferCount;
- msghdr.msg_control = NULL;
- msghdr.msg_controllen = 0;
- msghdr.msg_flags = 0;
+ /* Try immediate completion */
+ if ( lpOverlapped )
+ {
+ if ( WSAGetOverlappedResult ( (HANDLE) s, lpOverlapped,
+ lpNumberOfBytesSent, FALSE, &dwFlags) )
+ return 0;
+
+ if ( (err = WSAGetLastError ()) != WSA_IO_INCOMPLETE )
+ goto error;
- /* FIXME: Treat overlapped IO here */
+ }
+
+ WSASetLastError (WSA_IO_PENDING);
+ return SOCKET_ERROR;
+ }
if (_is_blocking(s))
{
@@ -2041,9 +2544,8 @@
do_block(fd, 2);
}
- /* FIXME: can we support MSG_PARTIAL ? How does it relate to sendmsg()'s msg_flags ? */
-
- if ((n = sendmsg (fd, &msghdr, dwFlags)) == -1)
+ n = WS2_send ( fd, iovec, dwBufferCount, to, tolen, dwFlags );
+ if ( n == -1 )
{
err = wsaErrno();
if ( err == WSAEWOULDBLOCK )
@@ -2051,24 +2553,22 @@
goto err_free;
}
+ TRACE(" -> %i bytes\n", n);
*lpNumberOfBytesSent = n;
- ws_sockaddr_free ( msghdr.msg_name, to );
- WS_FREE ( iovec );
+ HeapFree ( GetProcessHeap(), 0, iovec );
close ( fd );
-
return 0;
err_free:
- ws_sockaddr_free ( msghdr.msg_name, to );
- WS_FREE ( iovec );
+ HeapFree ( GetProcessHeap(), 0, iovec );
err_close:
close ( fd );
error:
WARN (" -> ERROR %d\n", err);
- SetLastError (err);
+ WSASetLastError (err);
return SOCKET_ERROR;
}
@@ -2195,55 +2695,88 @@
return (INT16)WS_setsockopt( s, (UINT16)level, optname, optval, optlen );
}
-
/***********************************************************************
* shutdown (WS2_32.22)
*/
int WINAPI WS_shutdown(SOCKET s, int how)
{
- int fd = _get_sock_fd(s);
+ int fd, fd0 = -1, fd1 = -1, flags, err = WSAENOTSOCK;
+ enum fd_type type;
+ unsigned int clear_flags = 0;
- TRACE("socket %04x, how %i\n", s, how );
- if (fd != -1)
+ fd = _get_sock_fd_type ( s, 0, &type, &flags );
+ TRACE("socket %04x, how %i %d %d \n", s, how, type, flags );
+
+ if (fd == -1)
+ return SOCKET_ERROR;
+
+ switch( how )
{
- switch( how )
- {
- case 0: /* drop receives */
- _enable_event(s, 0, 0, FD_READ);
-#ifdef SHUT_RD
- how = SHUT_RD;
-#endif
- break;
-
- case 1: /* drop sends */
- _enable_event(s, 0, 0, FD_WRITE);
-#ifdef SHUT_WR
- how = SHUT_WR;
-#endif
- break;
-
- case 2: /* drop all */
-#ifdef SHUT_RDWR
- how = SHUT_RDWR;
-#endif
- default:
- WSAAsyncSelect( s, 0, 0, 0 );
- break;
- }
+ case 0: /* drop receives */
+ clear_flags |= FD_READ;
+ break;
+ case 1: /* drop sends */
+ clear_flags |= FD_WRITE;
+ break;
+ case 2: /* drop all */
+ clear_flags |= FD_READ|FD_WRITE;
+ default:
+ clear_flags |= FD_WINE_CONNECTED|FD_WINE_LISTENING;
+ }
+
+ if ( flags & FD_FLAG_OVERLAPPED ) {
+
+ switch ( how )
+ {
+ case SD_RECEIVE:
+ fd0 = fd;
+ break;
+ case SD_SEND:
+ fd1 = fd;
+ break;
+ case SD_BOTH:
+ default:
+ fd0 = fd;
+ fd1 = _get_sock_fd ( s );
+ }
- if (shutdown(fd, how) == 0)
- {
- if( how > 1 )
- {
- _enable_event(s, 0, 0, FD_WINE_CONNECTED|FD_WINE_LISTENING);
- }
- close(fd);
- return 0;
- }
- SetLastError(wsaErrno());
- close(fd);
- }
- else SetLastError(WSAENOTSOCK);
+ if ( fd0 != -1 )
+ {
+ err = WS2_register_async_shutdown ( s, fd0, ASYNC_TYPE_READ );
+ if ( err )
+ {
+ close ( fd0 );
+ goto error;
+ }
+ }
+ if ( fd1 != -1 )
+ {
+ err = WS2_register_async_shutdown ( s, fd1, ASYNC_TYPE_WRITE );
+ if ( err )
+ {
+ close ( fd1 );
+ goto error;
+ }
+ }
+ }
+ else /* non-overlapped mode */
+ {
+ if ( shutdown( fd, how ) )
+ {
+ err = wsaErrno ();
+ close ( fd );
+ goto error;
+ }
+ close(fd);
+ }
+
+ _enable_event( s, 0, 0, clear_flags );
+ if ( how > 1) WSAAsyncSelect( s, 0, 0, 0 );
+ return 0;
+
+error:
+ _enable_event( s, 0, 0, clear_flags );
+ WSASetLastError ( err );
return SOCKET_ERROR;
}
@@ -2672,6 +3205,44 @@
return SOCKET_ERROR;
}
+/**********************************************************************
+ * WSAGetOverlappedResult (WS2_32.40)
+ */
+BOOL WINAPI WSAGetOverlappedResult ( SOCKET s, LPWSAOVERLAPPED lpOverlapped,
+ LPDWORD lpcbTransfer, BOOL fWait,
+ LPDWORD lpdwFlags )
+{
+ DWORD r;
+
+ TRACE ( "socket %d ovl %p trans %p, wait %d flags %p\n",
+ s, lpOverlapped, lpcbTransfer, fWait, lpdwFlags );
+
+ if ( !(lpOverlapped && lpOverlapped->hEvent) )
+ {
+ ERR ( "Invalid pointer\n" );
+ WSASetLastError (WSA_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ do {
+ r = WaitForSingleObjectEx (lpOverlapped->hEvent, fWait ? INFINITE : 0, TRUE);
+ } while (r == STATUS_USER_APC);
+
+ if ( lpcbTransfer )
+ *lpcbTransfer = lpOverlapped->InternalHigh;
+
+ if ( lpdwFlags )
+ *lpdwFlags = lpOverlapped->Offset;
+
+ if ( r == WAIT_OBJECT_0 )
+ return TRUE;
+
+ WSASetLastError ( lpOverlapped->Internal == STATUS_PENDING ?
+ WSA_IO_INCOMPLETE : NtStatusToWSAError ( lpOverlapped->Internal ) );
+ return FALSE;
+}
+
+
/***********************************************************************
* WSAAsyncSelect (WS2_32.101)
*/
@@ -3250,7 +3821,6 @@
}
}
-
/***********************************************************************
* WSARecv (WS2_32.67)
*/
@@ -3272,11 +3842,9 @@
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
{
- /* Uses recvmsg() in order to provide scatter-gather I/O */
-
+ int i, n, fd, err = WSAENOTSOCK, flags, ret;
struct iovec* iovec;
- struct msghdr msghdr;
- int fd, i, length, err = WSAENOTSOCK, flags;
+ struct ws2_async *wsa;
enum fd_type type;
TRACE("socket %04x, wsabuf %p, nbufs %ld, flags %ld, from %p, fromlen %ld, ovl %p, func %p\n",
@@ -3284,19 +3852,19 @@
(lpFromlen ? *lpFromlen : -1L),
lpOverlapped, lpCompletionRoutine);
- fd = _get_sock_fd_type( s, &type, &flags );
+ fd = _get_sock_fd_type( s, GENERIC_READ, &type, &flags );
+ TRACE ( "fd=%d, type=%d, flags=%x\n", fd, type, flags );
if (fd == -1)
{
- err = WSAENOTSOCK;
+ err = WSAGetLastError ();
goto error;
}
- /* FIXME: should this be HeapAlloc() or WS_ALLOC ? */
- iovec = WS_ALLOC ( dwBufferCount * sizeof (struct iovec) );
+ iovec = HeapAlloc ( GetProcessHeap(), 0, dwBufferCount * sizeof (struct iovec) );
if ( !iovec )
{
- err = WSAENOBUFS;
+ err = WSAEFAULT;
goto err_close;
}
@@ -3306,74 +3874,77 @@
iovec[i].iov_len = lpBuffers[i].len;
}
- msghdr.msg_name = NULL;
-
- if ( lpFrom )
+ if ( (lpOverlapped || lpCompletionRoutine) && flags & FD_FLAG_OVERLAPPED )
{
-#if DEBUG_SOCKADDR
- dump_sockaddr (lpFrom);
-#endif
+ wsa = WS2_make_async ( s, fd, ASYNC_TYPE_READ, iovec, dwBufferCount,
+ lpFlags, lpFrom, lpFromlen,
+ lpOverlapped, lpCompletionRoutine );
- msghdr.msg_namelen = *lpFromlen;
- msghdr.msg_name = ws_sockaddr_alloc (lpFrom, lpFromlen, &msghdr.msg_namelen);
- }
- else
- msghdr.msg_namelen = 0;
+ if ( !wsa )
+ {
+ err = WSAEFAULT;
+ goto err_free;
+ }
+
+ if ( ( ret = register_new_async ( &wsa->async )) )
+ {
+ err = NtStatusToWSAError ( ret );
+
+ if ( !lpOverlapped )
+ HeapFree ( GetProcessHeap(), 0, wsa->overlapped );
+ HeapFree ( GetProcessHeap(), 0, wsa );
+ goto err_free;
+ }
- msghdr.msg_iov = iovec;
- msghdr.msg_iovlen = dwBufferCount;
- msghdr.msg_control = NULL;
- msghdr.msg_controllen = 0;
- msghdr.msg_flags = 0;
+ /* Try immediate completion */
+ if ( lpOverlapped )
+ {
+ if ( WSAGetOverlappedResult ( (HANDLE) s, lpOverlapped,
+ lpNumberOfBytesRecvd, FALSE, lpFlags) )
+ return 0;
+
+ if ( (err = WSAGetLastError ()) != WSA_IO_INCOMPLETE )
+ {
+ TRACE ("err: %d\n", err);
+ goto err_free;
+ }
+ }
- /* FIXME: Treat overlapped IO here */
+ WSASetLastError ( WSA_IO_PENDING );
+ return SOCKET_ERROR;
+ }
- if (_is_blocking(s))
+ if ( _is_blocking(s) )
{
/* block here */
/* FIXME: OOB and exceptfds? */
do_block(fd, 1);
}
-
- /* FIXME: can we support MSG_PARTIAL ?
- How does it relate to recvmsg()'s msg_flags ? */
-
- if ((length = recvmsg (fd, &msghdr, *lpFlags)) == -1)
+
+ n = WS2_recv ( fd, iovec, dwBufferCount, lpFrom, lpFromlen, lpFlags );
+ if ( n == -1 )
{
err = wsaErrno();
goto err_free;
}
- TRACE(" -> %i bytes\n", length);
+ TRACE(" -> %i bytes\n", n);
+ *lpNumberOfBytesRecvd = n;
- if ( lpFrom && ws_sockaddr_u2ws (msghdr.msg_name, msghdr.msg_namelen, lpFrom, lpFromlen) != 0 )
- {
- /* The from buffer was too small, but we read the data
- * anyway. Is that really bad?
- */
- SetLastError ( WSAEFAULT );
- WARN ( " -> Address buffer too small\n" );
- }
-
- *lpNumberOfBytesRecvd = length;
-
- WS_FREE (iovec);
- ws_sockaddr_free ( msghdr.msg_name, lpFrom );
+ HeapFree (GetProcessHeap(), 0, iovec);
close(fd);
_enable_event(s, FD_READ, 0, 0);
-
return 0;
err_free:
- WS_FREE (iovec);
- ws_sockaddr_free ( msghdr.msg_name, lpFrom );
+ HeapFree (GetProcessHeap(), 0, iovec);
err_close:
close (fd);
error:
WARN(" -> ERROR %d\n", err);
- SetLastError ( err );
+ WSASetLastError ( err );
return SOCKET_ERROR;
}
@@ -3419,7 +3990,7 @@
SOCKET cs;
SOCKADDR src_addr, dst_addr;
- TRACE("Socket %ui, sockaddr %p, addrlen %p, fnCondition %p, dwCallbackD ata %ld\n",
+ TRACE("Socket %u, sockaddr %p, addrlen %p, fnCondition %p, dwCallbackData %ld\n",
s, addr, addrlen, lpfnCondition, dwCallbackData);
@@ -3450,7 +4021,17 @@
addr = memcpy(addr, &src_addr, (*addrlen > size) ? size : *addrlen );
return cs;
case CF_DEFER:
- SetLastError(WSATRY_AGAIN);
+ SERVER_START_REQ ( set_socket_deferred )
+ {
+ req->handle = s;
+ req->deferred = cs;
+ if ( !wine_server_call_err ( req ) )
+ {
+ SetLastError ( WSATRY_AGAIN );
+ CloseHandle ( cs );
+ }
+ }
+ SERVER_END_REQ;
return SOCKET_ERROR;
case CF_REJECT:
WS_closesocket(cs);
diff -ruNX ignore TMP/wine/dlls/winsock/ws2_32.spec MW/wine/dlls/winsock/ws2_32.spec
--- TMP/wine/dlls/winsock/ws2_32.spec Thu Apr 18 16:26:02 2002
+++ MW/wine/dlls/winsock/ws2_32.spec Thu Apr 18 16:26:48 2002
@@ -42,7 +42,7 @@
27 stub WSAAddressToStringA
28 stub WSAAddressToStringW
29 stdcall WSACloseEvent(long) WSACloseEvent
-30 stub WSAConnect
+30 stdcall WSAConnect(long ptr long ptr ptr ptr ptr) WSAConnect
31 stdcall WSACreateEvent () WSACreateEvent
32 stub WSADuplicateSocketA
33 stub WSADuplicateSocketW
@@ -52,7 +52,7 @@
37 stdcall WSAEnumProtocolsA(ptr ptr ptr) WSAEnumProtocolsA
38 stdcall WSAEnumProtocolsW(ptr ptr ptr) WSAEnumProtocolsW
39 stdcall WSAEventSelect(long long long) WSAEventSelect
-40 stub WSAGetOverlappedResult
+40 stdcall WSAGetOverlappedResult(long ptr ptr long ptr) WSAGetOverlappedResult
41 stub WSAGetQOSByName
42 stub WSAGetServiceClassInfoA
43 stub WSAGetServiceClassInfoW
diff -ruNX ignore TMP/wine/files/file.c MW/wine/files/file.c
--- TMP/wine/files/file.c Thu Apr 18 15:41:00 2002
+++ MW/wine/files/file.c Fri Apr 19 13:52:52 2002
@@ -306,6 +306,13 @@
ret = wine_server_handle_to_fd( handle, access, &fd, type, flags );
if (ret) SetLastError( RtlNtStatusToDosError(ret) );
+ if ( ( (access & GENERIC_READ) && (*flags & FD_FLAG_RECV_SHUTDOWN ) ) ||
+ ( (access & GENERIC_WRITE) && (*flags & FD_FLAG_SEND_SHUTDOWN ) ) )
+ {
+ close (fd);
+ SetLastError ( ERROR_PIPE_NOT_CONNECTED );
+ return -1;
+ }
return fd;
}
@@ -1411,7 +1418,7 @@
*lpTransferred = lpOverlapped->InternalHigh;
SetLastError ( lpOverlapped->Internal == STATUS_PENDING ?
- ERROR_IO_INCOMPLETE : lpOverlapped->Internal );
+ ERROR_IO_INCOMPLETE : RtlNtStatusToDosError ( lpOverlapped->Internal ) );
return (r==WAIT_OBJECT_0);
}
@@ -1511,9 +1518,13 @@
if ( fd < 0 )
{
WARN ( "Couldn't get FD\n" );
- SetLastError ( ERROR_INVALID_PARAMETER );
return FALSE;
}
+ if ( ! (flags & FD_FLAG_OVERLAPPED) ) {
+ WARN ( "fd is not overlapped\n" );
+ SetLastError ( ERROR_INVALID_PARAMETER );
+ goto error;
+ }
ovp = (async_fileio*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_fileio));
if(!ovp)
@@ -1730,6 +1741,11 @@
{
TRACE( "Couldn't get FD\n" );
return FALSE;
+ }
+ if ( ! (flags & FD_FLAG_OVERLAPPED) ) {
+ WARN ( "fd is not overlapped\n" );
+ SetLastError ( ERROR_INVALID_PARAMETER );
+ goto error;
}
ovp = (async_fileio*) HeapAlloc(GetProcessHeap(), 0, sizeof (async_fileio));
diff -ruNX ignore TMP/wine/include/wine/server_protocol.h MW/wine/include/wine/server_protocol.h
--- TMP/wine/include/wine/server_protocol.h Thu Apr 18 16:26:02 2002
+++ MW/wine/include/wine/server_protocol.h Fri Apr 19 13:51:02 2002
@@ -796,6 +796,8 @@
#define FD_FLAG_OVERLAPPED 0x01
#define FD_FLAG_TIMEOUT 0x02
+#define FD_FLAG_RECV_SHUTDOWN 0x04
+#define FD_FLAG_SEND_SHUTDOWN 0x08
struct set_file_pointer_request
@@ -1001,6 +1003,16 @@
struct reply_header __header;
};
+struct set_socket_deferred_request
+{
+ struct request_header __header;
+ handle_t handle;
+ handle_t deferred;
+};
+struct set_socket_deferred_reply
+{
+ struct reply_header __header;
+};
struct alloc_console_request
@@ -2758,6 +2770,7 @@
REQ_set_socket_event,
REQ_get_socket_event,
REQ_enable_socket_event,
+ REQ_set_socket_deferred,
REQ_alloc_console,
REQ_free_console,
REQ_get_console_renderer_events,
@@ -2919,6 +2932,7 @@
struct set_socket_event_request set_socket_event_request;
struct get_socket_event_request get_socket_event_request;
struct enable_socket_event_request enable_socket_event_request;
+ struct set_socket_deferred_request set_socket_deferred_request;
struct alloc_console_request alloc_console_request;
struct free_console_request free_console_request;
struct get_console_renderer_events_request get_console_renderer_events_request;
@@ -3078,6 +3092,7 @@
struct set_socket_event_reply set_socket_event_reply;
struct get_socket_event_reply get_socket_event_reply;
struct enable_socket_event_reply enable_socket_event_reply;
+ struct set_socket_deferred_reply set_socket_deferred_reply;
struct alloc_console_reply alloc_console_reply;
struct free_console_reply free_console_reply;
struct get_console_renderer_events_reply get_console_renderer_events_reply;
@@ -3183,6 +3198,6 @@
struct get_window_properties_reply get_window_properties_reply;
};
-#define SERVER_PROTOCOL_VERSION 78
+#define SERVER_PROTOCOL_VERSION 80
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff -ruNX ignore TMP/wine/include/winsock.h MW/wine/include/winsock.h
--- TMP/wine/include/winsock.h Thu Apr 18 15:41:05 2002
+++ MW/wine/include/winsock.h Thu Apr 18 16:26:48 2002
@@ -728,6 +728,7 @@
#define FD_CLOSE 0x00000020
/* internal per-socket flags */
+/* CAUTION: FD_FLAG_RECV_SHUTDOWN / FD_FLAG_SEND_SHUTDOWN (server/protocol.def) must fit into this mask */
#ifdef __WINE__
#define FD_WINE_LISTENING 0x10000000
#define FD_WINE_NONBLOCKING 0x20000000
diff -ruNX ignore TMP/wine/include/winsock2.h MW/wine/include/winsock2.h
--- TMP/wine/include/winsock2.h Thu Apr 18 15:41:09 2002
+++ MW/wine/include/winsock2.h Thu Apr 18 16:26:48 2002
@@ -221,8 +221,7 @@
#define WSAEVENT HANDLE
#define LPWSAEVENT LPHANDLE
-#define WSAOVERLAPPED OVERLAPPED
-typedef struct _OVERLAPPED* LPWSAOVERLAPPED;
+typedef OVERLAPPED WSAOVERLAPPED, *LPWSAOVERLAPPED;
#define WSA_IO_PENDING (ERROR_IO_PENDING)
#define WSA_IO_INCOMPLETE (ERROR_IO_INCOMPLETE)
diff -ruNX ignore TMP/wine/server/async.c MW/wine/server/async.c
--- TMP/wine/server/async.c Tue Apr 16 11:18:11 2002
+++ MW/wine/server/async.c Fri Apr 19 13:50:30 2002
@@ -150,42 +150,32 @@
DECL_HANDLER(register_async)
{
- struct object *obj;
+ struct object *obj = get_handle_obj( current->process, req->handle, 0, NULL);
- if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL)) )
- return;
-
- if(obj->ops->queue_async)
+ if ( !(obj) || !obj->ops->queue_async )
{
- struct async_queue *q = obj->ops->queue_async(obj, NULL, req->type, 0);
- struct async *async;
-
- async = find_async(q, current, req->overlapped);
- if(req->status==STATUS_PENDING)
- {
- if(!async)
- async = create_async(obj, current, req->overlapped);
-
- if(async)
- {
- async->status = req->status;
- if(!obj->ops->queue_async(obj, async, req->type, req->count))
- destroy_async(async);
- }
- }
- else
- {
- if(async)
- destroy_async(async);
- else
- set_error(STATUS_INVALID_PARAMETER);
- }
-
- set_select_events(obj,obj->ops->get_poll_events(obj));
- }
- else
set_error(STATUS_INVALID_HANDLE);
+ return;
+ }
+
+/*
+ * The queue_async method must do the following:
+ *
+ * 1. Get the async_queue for the request of given type.
+ * 2. Call find_async() to look for the specific client request in the queue (=> NULL if not found).
+ * 3. If status is STATUS_PENDING:
+ * a) If no async request found in step 2 (new request): call create_async() to initialize one.
+ * b) Set request's status to STATUS_PENDING.
+ * c) If the "queue" field of the async request is NULL: call async_insert() to put it into the queue.
+ * Otherwise:
+ * If the async request was found in step 2, destroy it by calling destroy_async().
+ * 4. Carry out any operations necessary to adjust the object's poll events
+ * Usually: set_elect_events (obj, obj->ops->get_poll_events()).
+ *
+ * See also the implementations in file.c, serial.c, and sock.c.
+*/
+ obj->ops->queue_async (obj, req->overlapped, req->status, req->type, req->count);
release_object(obj);
}
diff -ruNX ignore TMP/wine/server/file.c MW/wine/server/file.c
--- TMP/wine/server/file.c Tue Apr 2 16:51:50 2002
+++ MW/wine/server/file.c Thu Apr 18 19:11:13 2002
@@ -69,7 +69,7 @@
static int file_flush( struct object *obj );
static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void file_destroy( struct object *obj );
-static struct async_queue * file_queue_async(struct object *obj, struct async* async, int type, int count);
+static void file_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count);
static const struct object_ops file_ops =
{
@@ -358,9 +358,10 @@
return FD_TYPE_DEFAULT;
}
-static struct async_queue *file_queue_async(struct object *obj, struct async *async, int type, int count)
+static void file_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count)
{
struct file *file = (struct file *)obj;
+ struct async *async;
struct async_queue *q;
assert( obj->ops == &file_ops );
@@ -368,7 +369,7 @@
if ( !(file->flags & FILE_FLAG_OVERLAPPED) )
{
set_error ( STATUS_INVALID_HANDLE );
- return NULL;
+ return;
}
switch(type)
@@ -381,13 +382,26 @@
break;
default:
set_error( STATUS_INVALID_PARAMETER );
- return NULL;
+ return;
}
- if(async && !async->q)
- async_insert(q, async);
+ async = find_async ( q, current, ptr );
+
+ if ( status == STATUS_PENDING )
+ {
+ if ( !async )
+ async = create_async ( obj, current, ptr );
+ if ( !async )
+ return;
+
+ async->status = STATUS_PENDING;
+ if ( !async->q )
+ async_insert( q, async );
+ }
+ else if ( async ) destroy_async ( async );
+ else set_error ( STATUS_INVALID_PARAMETER );
- return q;
+ set_select_events ( obj, file_get_poll_events ( obj ));
}
static void file_destroy( struct object *obj )
diff -ruNX ignore TMP/wine/server/object.h MW/wine/server/object.h
--- TMP/wine/server/object.h Thu Apr 4 09:37:39 2002
+++ MW/wine/server/object.h Fri Apr 19 13:29:37 2002
@@ -63,8 +63,8 @@
int (*flush)(struct object *);
/* get file information */
int (*get_file_info)(struct object *,struct get_file_info_reply *, int *flags);
- /* queue an async operation */
- struct async_queue* (*queue_async)(struct object *, struct async *async, int type, int count);
+ /* queue an async operation - see register_async handler in async.c*/
+ void (*queue_async)(struct object *, void* ptr, unsigned int status, int type, int count);
/* destroy on refcount == 0 */
void (*destroy)(struct object *);
};
diff -ruNX ignore TMP/wine/server/protocol.def MW/wine/server/protocol.def
--- TMP/wine/server/protocol.def Thu Apr 18 16:26:02 2002
+++ MW/wine/server/protocol.def Fri Apr 19 10:49:29 2002
@@ -612,7 +612,9 @@
};
#define FD_FLAG_OVERLAPPED 0x01
#define FD_FLAG_TIMEOUT 0x02
-
+/* Socket flags: see server/sock.c */
+#define FD_FLAG_RECV_SHUTDOWN 0x04
+#define FD_FLAG_SEND_SHUTDOWN 0x08
/* Set a file current position */
@REQ(set_file_pointer)
@@ -746,6 +748,10 @@
unsigned int cstate; /* status bits to clear */
@END
+(a)REQ(set_socket_deferred)
+ handle_t handle; /* handle to the socket */
+ handle_t deferred; /* handle to the socket for which accept() is deferred */
+(a)END
/* Allocate a console (only used by a console renderer) */
@REQ(alloc_console)
diff -ruNX ignore TMP/wine/server/request.h MW/wine/server/request.h
--- TMP/wine/server/request.h Thu Apr 18 16:26:02 2002
+++ MW/wine/server/request.h Fri Apr 19 13:51:02 2002
@@ -152,6 +152,7 @@
DECL_HANDLER(set_socket_event);
DECL_HANDLER(get_socket_event);
DECL_HANDLER(enable_socket_event);
+DECL_HANDLER(set_socket_deferred);
DECL_HANDLER(alloc_console);
DECL_HANDLER(free_console);
DECL_HANDLER(get_console_renderer_events);
@@ -312,6 +313,7 @@
(req_handler)req_set_socket_event,
(req_handler)req_get_socket_event,
(req_handler)req_enable_socket_event,
+ (req_handler)req_set_socket_deferred,
(req_handler)req_alloc_console,
(req_handler)req_free_console,
(req_handler)req_get_console_renderer_events,
diff -ruNX ignore TMP/wine/server/serial.c MW/wine/server/serial.c
--- TMP/wine/server/serial.c Tue Apr 2 16:51:51 2002
+++ MW/wine/server/serial.c Fri Apr 19 13:36:47 2002
@@ -51,7 +51,7 @@
static int serial_get_fd( struct object *obj );
static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static int serial_get_poll_events( struct object *obj );
-static struct async_queue * serial_queue_async(struct object *obj, struct async* async, int type, int count);
+static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count);
static void destroy_serial(struct object *obj);
static void serial_poll_event( struct object *obj, int event );
@@ -250,24 +250,11 @@
set_select_events(obj,obj->ops->get_poll_events(obj));
}
-/*
- * This function is an abuse of overloading that deserves some explanation.
- *
- * It has three purposes:
- *
- * 1. get the queue for a type of async operation
- * 2. requeue an async operation
- * 3. queue a new async operation
- *
- * It is overloaded so that these three functions only take one function pointer
- * in the object operations list.
- *
- * In all cases, it returns the async queue.
- */
-static struct async_queue *serial_queue_async(struct object *obj, struct async *async, int type, int count)
+static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count)
{
struct serial *serial = (struct serial *)obj;
struct async_queue *q;
+ struct async *async;
int timeout;
assert(obj->ops == &serial_ops);
@@ -288,19 +275,29 @@
break;
default:
set_error(STATUS_INVALID_PARAMETER);
- return NULL;
+ return;
}
- if(async)
+ async = find_async ( q, current, ptr );
+
+ if ( status == STATUS_PENDING )
{
+ if ( !async )
+ async = create_async ( obj, current, ptr );
+ if ( !async )
+ return;
+
+ async->status = STATUS_PENDING;
if(!async->q)
{
- async_add_timeout(async,timeout);
- async_insert(q, async);
+ async_add_timeout ( async, timeout );
+ async_insert ( q, async );
+ }
}
-}
+ else if ( async ) destroy_async ( async );
+ else set_error ( STATUS_INVALID_PARAMETER );
- return q;
+ set_select_events ( obj, serial_get_poll_events ( obj ));
}
/* create a serial */
diff -ruNX ignore TMP/wine/server/sock.c MW/wine/server/sock.c
--- TMP/wine/server/sock.c Thu Apr 18 16:26:02 2002
+++ MW/wine/server/sock.c Fri Apr 19 16:25:54 2002
@@ -72,6 +72,7 @@
unsigned int message; /* message to send */
unsigned int wparam; /* message wparam (socket handle) */
int errors[FD_MAX_EVENTS]; /* event errors */
+ struct sock* deferred; /* socket that waits for a deferred accept */
struct async_queue read_q; /* Queue for asynchronous reads */
struct async_queue write_q; /* Queue for asynchronous writes */
};
@@ -85,6 +86,7 @@
static void sock_destroy( struct object *obj );
static int sock_get_error( int err );
static void sock_set_error(void);
+static void sock_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count);
static const struct object_ops sock_ops =
{
@@ -99,7 +101,7 @@
sock_get_fd, /* get_fd */
no_flush, /* flush */
sock_get_info, /* get_file_info */
- NULL, /* queue_async */
+ sock_queue_async, /* queue_async */
sock_destroy /* destroy */
};
@@ -123,7 +125,25 @@
};
-static void sock_reselect( struct sock *sock )
+/* After POLLHUP is received, the socket will no longer be in the main select loop.
+ This function is used to signal pending events nevertheless */
+static void sock_try_event ( struct sock *sock, int event )
+{
+ struct pollfd pfd;
+
+ pfd.fd = sock->obj.fd;
+ pfd.events = event;
+ pfd.revents = 0;
+ poll (&pfd, 1, 0);
+
+ if ( pfd.revents )
+ {
+ if ( debug_level ) fprintf ( stderr, "sock_try_event: %x\n", pfd.revents );
+ sock_poll_event ( &sock->obj, pfd.revents );
+ }
+}
+
+static int sock_reselect( struct sock *sock )
{
int ev = sock_get_poll_events( &sock->obj );
@@ -132,21 +152,41 @@
if (sock->obj.select == -1) {
/* previously unconnected socket, is this reselect supposed to connect it? */
- if (!(sock->state & ~FD_WINE_NONBLOCKING)) return;
+ if (!(sock->state & ~FD_WINE_NONBLOCKING)) return 0;
/* ok, it is, attach it to the wineserver's main poll loop */
add_select_user( &sock->obj );
}
/* update condition mask */
set_select_events( &sock->obj, ev );
+ return ev;
}
/* wake anybody waiting on the socket event or send the associated message */
-static void sock_wake_up( struct sock *sock )
+static void sock_wake_up( struct sock *sock, int pollev )
{
unsigned int events = sock->pmask & sock->mask;
int i;
+ int async_active = 0;
- if (!events) return;
+ if ( sock->flags & FD_FLAG_OVERLAPPED )
+ {
+ if( pollev & (POLLIN|POLLPRI) && IS_READY( sock->read_q ) )
+ {
+ if (debug_level) fprintf ( stderr, "activating read queue for socket %p\n", sock );
+ async_notify( sock->read_q.head, STATUS_ALERTED );
+ async_active = 1;
+ }
+ if( pollev & POLLOUT && IS_READY( sock->write_q ) )
+ {
+ if (debug_level) fprintf ( stderr, "activating write queue for socket %p\n", sock );
+ async_notify( sock->write_q.head, STATUS_ALERTED );
+ async_active = 1;
+ }
+ }
+
+ /* Do not signal events if there are still pending asynchronous IO requests */
+ /* We need this to delay FD_CLOSE events until all pending overlapped requests are processed */
+ if ( !events || async_active ) return;
if (sock->event)
{
@@ -182,6 +222,7 @@
static void sock_poll_event( struct object *obj, int event )
{
struct sock *sock = (struct sock *)obj;
+ int empty_recv = 0;
assert( sock->obj.ops == &sock_ops );
if (debug_level)
@@ -232,19 +273,37 @@
if (event & POLLIN)
{
char dummy;
+ int nr;
/* Linux 2.4 doesn't report POLLHUP if only one side of the socket
* has been closed, so we need to check for it explicitly here */
- if (!recv( sock->obj.fd, &dummy, 1, MSG_PEEK )) event = POLLHUP;
- else
+ nr = recv( sock->obj.fd, &dummy, 1, MSG_PEEK );
+
+ if ( nr > 0 )
{
/* incoming data */
sock->pmask |= FD_READ;
sock->hmask |= FD_READ;
sock->errors[FD_READ_BIT] = 0;
if (debug_level)
- fprintf(stderr, "socket %d is readable\n", sock->obj.fd );
+ fprintf( stderr, "socket %d is readable\n", sock->obj.fd );
}
+ else if ( nr == 0 )
+ empty_recv = 1;
+ else
+ {
+ /* EAGAIN can happen if an async recv() falls between the server's poll()
+ call and the invocation of this routine */
+ if ( errno == EAGAIN )
+ event &= ~POLLIN;
+ else
+ {
+ if ( debug_level )
+ fprintf ( stderr, "recv error on socket %d: %d\n", sock->obj.fd, errno );
+ event = POLLERR;
+ }
+ }
+
}
if (event & POLLOUT)
{
@@ -262,25 +321,37 @@
if (debug_level)
fprintf(stderr, "socket %d got OOB data\n", sock->obj.fd);
}
- if (((event & POLLERR) || ((event & (POLLIN|POLLHUP)) == POLLHUP))
- && (sock->state & (FD_READ|FD_WRITE))) {
+ if ( (sock->state & (FD_READ|FD_WRITE)) && (event & (POLLERR|POLLHUP)) )
+ {
/* socket closing */
sock->errors[FD_CLOSE_BIT] = sock_error( sock->obj.fd );
- sock->state &= ~(FD_WINE_CONNECTED|FD_READ|FD_WRITE);
+ sock->state &= ~(FD_WINE_CONNECTED|FD_WRITE);
sock->pmask |= FD_CLOSE;
if (debug_level)
fprintf(stderr, "socket %d aborted by error %d\n",
sock->obj.fd, sock->errors[FD_CLOSE_BIT]);
}
+ else if ( empty_recv && (sock->state & FD_READ) )
+ {
+ /* incoming stream closing - do not alter sock->state, reading is still allowed */
+ sock->errors[FD_CLOSE_BIT] = 0;
+ sock->pmask |= FD_CLOSE;
+ if (debug_level)
+ fprintf(stderr, "socket %d incoming stream closed\n", sock->obj.fd);
+ }
}
if (event & (POLLERR|POLLHUP))
+ {
+ if ( debug_level )
+ fprintf ( stderr, "HUP/ERR - removing socket %d from select loop\n", sock->obj.fd );
set_select_events( &sock->obj, -1 );
+ }
else
sock_reselect( sock );
/* wake up anyone waiting for whatever just happened */
- if (sock->pmask & sock->mask) sock_wake_up( sock );
+ if ( sock->pmask & sock->mask || sock->flags & FD_FLAG_OVERLAPPED ) sock_wake_up( sock, event );
/* if anyone is stupid enough to wait on the socket object itself,
* maybe we should wake them up too, just in case? */
@@ -319,8 +390,11 @@
/* listening, wait for readable */
return (sock->hmask & FD_ACCEPT) ? 0 : POLLIN;
- if (mask & FD_READ) ev |= POLLIN | POLLPRI;
- if (mask & FD_WRITE) ev |= POLLOUT;
+ if (mask & FD_READ || (sock->flags & WSA_FLAG_OVERLAPPED && IS_READY (sock->read_q)))
+ ev |= POLLIN | POLLPRI;
+ if (mask & FD_WRITE || (sock->flags & WSA_FLAG_OVERLAPPED && IS_READY (sock->write_q)))
+ ev |= POLLOUT;
+
return ev;
}
@@ -350,10 +424,70 @@
reply->serial = 0;
}
*flags = 0;
- if (sock->flags & WSA_FLAG_OVERLAPPED) *flags |= FD_FLAG_OVERLAPPED;
+ if ( !(sock->state & FD_READ ) ) *flags |= FD_FLAG_RECV_SHUTDOWN;
+ if ( !(sock->state & FD_WRITE ) ) *flags |= FD_FLAG_SEND_SHUTDOWN;
+ if ( sock->flags & WSA_FLAG_OVERLAPPED ) *flags |= FD_FLAG_OVERLAPPED;
return FD_TYPE_DEFAULT;
}
+static void sock_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count)
+{
+ struct sock *sock = (struct sock *)obj;
+ struct async_queue *q;
+ struct async *async;
+ int pollev;
+
+ assert( obj->ops == &sock_ops );
+
+ if ( !(sock->flags & WSA_FLAG_OVERLAPPED) )
+ {
+ set_error ( STATUS_INVALID_HANDLE );
+ return;
+ }
+
+ switch( type )
+ {
+ case ASYNC_TYPE_READ:
+ q = &sock->read_q;
+ break;
+ case ASYNC_TYPE_WRITE:
+ q = &sock->write_q;
+ break;
+ default:
+ set_error( STATUS_INVALID_PARAMETER );
+ return;
+ }
+
+ async = find_async ( q, current, ptr );
+
+ if ( status == STATUS_PENDING )
+ {
+ if ( ( !( sock->state & FD_READ ) && type == ASYNC_TYPE_READ ) ||
+ ( !( sock->state & FD_WRITE ) && type == ASYNC_TYPE_WRITE ) )
+ {
+ set_error ( STATUS_PIPE_DISCONNECTED );
+ if ( async ) destroy_async ( async );
+ }
+ else
+ {
+ if ( !async )
+ async = create_async ( obj, current, ptr );
+ if ( !async )
+ return;
+
+ async->status = STATUS_PENDING;
+ if ( !async->q )
+ async_insert ( q, async );
+ }
+ }
+ else if ( async ) destroy_async ( async );
+ else set_error ( STATUS_INVALID_PARAMETER );
+
+ pollev = sock_reselect ( sock );
+ if ( pollev ) sock_try_event ( sock, pollev );
+ else if ( sock->pmask & sock->mask ) sock_wake_up ( sock, 0 );
+}
+
static void sock_destroy( struct object *obj )
{
struct sock *sock = (struct sock *)obj;
@@ -361,6 +495,9 @@
/* FIXME: special socket shutdown stuff? */
+ if ( sock->deferred )
+ release_object ( sock->deferred );
+
if ( sock->flags & WSA_FLAG_OVERLAPPED )
{
destroy_async_queue ( &sock->read_q );
@@ -394,13 +531,14 @@
sock->window = 0;
sock->message = 0;
sock->wparam = 0;
- sock_reselect( sock );
- clear_error();
+ sock->deferred = NULL;
if (sock->flags & WSA_FLAG_OVERLAPPED)
{
init_async_queue (&sock->read_q);
init_async_queue (&sock->write_q);
}
+ sock_reselect( sock );
+ clear_error();
return &sock->obj;
}
@@ -417,44 +555,51 @@
GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops);
if (!sock)
return NULL;
- /* Try to accept(2). We can't be safe that this an already connected socket
- * or that accept() is allowed on it. In those cases we will get -1/errno
- * return.
- */
- slen = sizeof(saddr);
- acceptfd = accept(sock->obj.fd,&saddr,&slen);
- if (acceptfd==-1) {
- sock_set_error();
- release_object( sock );
- return NULL;
- }
- if (!(acceptsock = alloc_object( &sock_ops, -1 )))
- {
- release_object( sock );
- return NULL;
- }
- /* newly created socket gets the same properties of the listening socket */
- fcntl(acceptfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
- acceptsock->obj.fd = acceptfd;
- acceptsock->state = FD_WINE_CONNECTED|FD_READ|FD_WRITE;
- if (sock->state & FD_WINE_NONBLOCKING)
- acceptsock->state |= FD_WINE_NONBLOCKING;
- acceptsock->mask = sock->mask;
- acceptsock->hmask = 0;
- acceptsock->pmask = 0;
- acceptsock->event = NULL;
- acceptsock->window = sock->window;
- acceptsock->message = sock->message;
- acceptsock->wparam = 0;
- if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
- acceptsock->flags = sock->flags;
- if ( acceptsock->flags & WSA_FLAG_OVERLAPPED )
- {
- init_async_queue ( &acceptsock->read_q );
- init_async_queue ( &acceptsock->write_q );
- }
+ if ( sock->deferred ) {
+ acceptsock = sock->deferred;
+ sock->deferred = NULL;
+ } else {
+
+ /* Try to accept(2). We can't be safe that this an already connected socket
+ * or that accept() is allowed on it. In those cases we will get -1/errno
+ * return.
+ */
+ slen = sizeof(saddr);
+ acceptfd = accept(sock->obj.fd,&saddr,&slen);
+ if (acceptfd==-1) {
+ sock_set_error();
+ release_object( sock );
+ return NULL;
+ }
+ if (!(acceptsock = alloc_object( &sock_ops, -1 )))
+ {
+ release_object( sock );
+ return NULL;
+ }
+ /* newly created socket gets the same properties of the listening socket */
+ fcntl(acceptfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
+ acceptsock->obj.fd = acceptfd;
+ acceptsock->state = FD_WINE_CONNECTED|FD_READ|FD_WRITE;
+ if (sock->state & FD_WINE_NONBLOCKING)
+ acceptsock->state |= FD_WINE_NONBLOCKING;
+ acceptsock->mask = sock->mask;
+ acceptsock->hmask = 0;
+ acceptsock->pmask = 0;
+ acceptsock->event = NULL;
+ acceptsock->window = sock->window;
+ acceptsock->message = sock->message;
+ acceptsock->wparam = 0;
+ if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
+ acceptsock->flags = sock->flags;
+ acceptsock->deferred = 0;
+ if ( acceptsock->flags & WSA_FLAG_OVERLAPPED )
+ {
+ init_async_queue ( &acceptsock->read_q );
+ init_async_queue ( &acceptsock->write_q );
+ }
+ }
clear_error();
sock->pmask &= ~FD_ACCEPT;
sock->hmask &= ~FD_ACCEPT;
@@ -566,6 +711,7 @@
{
struct sock *sock;
struct event *old_event;
+ int pollev;
if (!(sock = (struct sock*)get_handle_obj( current->process, req->handle,
GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, &sock_ops)))
@@ -579,7 +725,11 @@
if (req->event) sock->event = get_event_obj( current->process, req->event, EVENT_MODIFY_STATE );
if (debug_level && sock->event) fprintf(stderr, "event ptr: %p\n", sock->event);
- sock_reselect( sock );
+
+ pollev = sock_reselect( sock );
+ if ( pollev ) sock_try_event ( sock, pollev );
+ else if ( sock->pmask & sock->mask ) sock_wake_up ( sock, 0 );
+
if (sock->mask)
sock->state |= FD_WINE_NONBLOCKING;
@@ -587,7 +737,7 @@
it is possible that FD_CONNECT or FD_ACCEPT network events has happened
before a WSAEventSelect() was done on it.
(when dealing with Asynchronous socket) */
- if (sock->pmask & sock->mask) sock_wake_up( sock );
+ if (sock->pmask & sock->mask) sock_wake_up( sock, pollev );
if (old_event) release_object( old_event ); /* we're through with it */
release_object( &sock->obj );
@@ -634,6 +784,7 @@
DECL_HANDLER(enable_socket_event)
{
struct sock *sock;
+ int pollev;
if (!(sock = (struct sock*)get_handle_obj( current->process, req->handle,
GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE, &sock_ops)))
@@ -643,6 +794,33 @@
sock->hmask &= ~req->mask;
sock->state |= req->sstate;
sock->state &= ~req->cstate;
- sock_reselect( sock );
+
+ pollev = sock_reselect( sock );
+ if ( pollev ) sock_try_event ( sock, pollev );
+ else if ( sock->pmask & sock->mask ) sock_wake_up ( sock, 0 );
+
release_object( &sock->obj );
+}
+
+DECL_HANDLER(set_socket_deferred)
+{
+ struct sock *sock, *acceptsock;
+
+ sock=(struct sock*)get_handle_obj( current->process,req->handle,
+ GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops );
+ if ( !sock )
+ {
+ set_error ( WSAENOTSOCK );
+ return;
+ }
+ acceptsock = (struct sock*)get_handle_obj( current->process,req->deferred,
+ GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops );
+ if ( !acceptsock )
+ {
+ release_object ( sock );
+ set_error ( WSAENOTSOCK );
+ return;
+ }
+ sock->deferred = acceptsock;
+ release_object ( sock );
}
diff -ruNX ignore TMP/wine/server/trace.c MW/wine/server/trace.c
--- TMP/wine/server/trace.c Thu Apr 18 16:26:02 2002
+++ MW/wine/server/trace.c Fri Apr 19 13:51:02 2002
@@ -943,6 +943,12 @@
fprintf( stderr, " cstate=%08x", req->cstate );
}
+static void dump_set_socket_deferred_request( const struct set_socket_deferred_request *req )
+{
+ fprintf( stderr, " handle=%d,", req->handle );
+ fprintf( stderr, " deferred=%d", req->deferred );
+}
+
static void dump_alloc_console_request( const struct alloc_console_request *req )
{
fprintf( stderr, " access=%08x,", req->access );
@@ -2215,6 +2221,7 @@
(dump_func)dump_set_socket_event_request,
(dump_func)dump_get_socket_event_request,
(dump_func)dump_enable_socket_event_request,
+ (dump_func)dump_set_socket_deferred_request,
(dump_func)dump_alloc_console_request,
(dump_func)dump_free_console_request,
(dump_func)dump_get_console_renderer_events_request,
@@ -2372,6 +2379,7 @@
(dump_func)0,
(dump_func)dump_get_socket_event_reply,
(dump_func)0,
+ (dump_func)0,
(dump_func)dump_alloc_console_reply,
(dump_func)0,
(dump_func)dump_get_console_renderer_events_reply,
@@ -2529,6 +2537,7 @@
"set_socket_event",
"get_socket_event",
"enable_socket_event",
+ "set_socket_deferred",
"alloc_console",
"free_console",
"get_console_renderer_events",
April 19, 2002
Re: small patch for ./tools/wineinstall
by Tony Lambregts
Speeddymon wrote:
>my first patch fixes that problem and quite a few
>others
>
Please resubmit your patch in proper diff format. I have made proper
diffs for you (attached) but I don't feel right about submitting someone
elses work. I have tested it on my machine and it works fine. I
appreciate the work you put into getting these two programs to work but,
there is no way that your "patch" will get into cvs unless it is in
proper diff format. As I said before I dont feel right about submitting
someone elses work.
Tony Lambregts
Index: wineconf
===================================================================
RCS file: /home/wine/wine/tools/wineconf,v
retrieving revision 1.12
diff -u -r1.12 wineconf
--- wineconf 10 Mar 2002 00:24:22 -0000 1.12
+++ wineconf 17 Apr 2002 23:00:51 -0000
@@ -93,13 +93,20 @@
my ($device, $mntpoint, $type, @rest) = split(' ', $_);
if ($device !~ m"^/dev/fd") {
- if ($type eq "msdos" || $type eq "vfat") {
+ if ($type eq "ntfs") {
+ push(@::FatDrives, [$device, $mntpoint, 'win95']);
+ }
+ elsif ($type eq "msdos" || $type eq "vfat") {
push(@::FatDrives, [$device, $mntpoint, $type]);
}
elsif ($type eq "iso9660" ||
- $mntpoint eq "/cdrom" ||
+ ($mntpoint eq "/cdrom" && ! $type eq 'supermount') ||
($device eq '/dev/cdrom' && $type eq 'auto') ) {
push(@::CdromDrives, [$device, $mntpoint, 'win95']);
+ }
+ elsif ( ($mntpoint eq '/mnt/cdrom' || $mntpoint eq '/cdrom')
+ && $type eq 'supermount') {
+ push(@::CdromDrives, [ '/dev/cdrom', $mntpoint, 'win95']);
}
}
}
Index: wineinstall
===================================================================
RCS file: /home/wine/wine/tools/wineinstall,v
retrieving revision 1.26
diff -u -r1.26 wineinstall
--- wineinstall 1 Apr 2002 20:56:51 -0000 1.26
+++ wineinstall 17 Apr 2002 23:06:39 -0000
@@ -74,6 +74,25 @@
# that require root access
# add text to tell the user we need to run stuff as root so they don't
# think we are trying to pull something funny
+# Apr 14 2002 - Dustin Navea
+# tools/wineconf: fix to find Win2k on ntfs partitions (still read-only
+# tho)
+# tools/wineconf: fix to find non-supermount cd-rom drives (when mounted
+# at /cdrom)
+# tools/wineconf: fix to find supermount cd-rom drives and give it proper
+# device name (long as there is only 1 cd-rom)
+# Fix sed command when finding real-windows registry so it actually
+# accesses a file (~/.wine/config) instead of null ($CONF?!)
+# Added search for clean-install (not upgrade) Win2k registry
+# (next day, after some sleep)
+# Fix sed string when finding real-windows registry to actually find
+# windows partition name in [Drive C] section
+# it should now always find the windows partition and real-windows
+# registry (if not, let me know)
+# Apr 16 2002 - Dustin Navea
+# for some reason everything compiles ok on my setup, but libntdll.dll.so
+# can't be found when I run wine...having $libdir/wine in my
+# ld.config.so and running ldconfig fixed it tho, so I added that.
#--- defaults (change these if you are a packager)
CONFARGS="--enable-opengl" # configure args, e.g. --prefix=/usr --sysconfdir=/etc
@@ -291,6 +310,14 @@
sucommand="echo $libdir>>/etc/ld.so.conf;ldconfig;$sucommand"
}
fi
+ if [ -f /etc/ld.so.conf ] && ! grep -qs "$libdir/wine" /etc.ld.so.conf
+ then {
+ echo
+ echo "$libdir/wine doesn't exist in your /etc/ld.so.conf, it will be"
+ echo " added when we perform the install..."
+ sucommand="echo $libdir/wine>>/etc/ld.so.conf;$sucommand"
+ }
+ fi
echo
@@ -578,12 +605,14 @@
# (not to be done if windows registry exists)
if [ "$DOREG" = 'auto' ]
then {
- CROOT=`sed -n '/^\[Drive C\]$/,/^\[.*\]$/ s/^Path=\(.*\)/\1/p' $CONF`
+ CROOT=`sed -n '/^\[Drive C\]$/,/^\[.*\]$/ s/^\"Path\" = \"\(.*\)\"/\1/p' $LCONF`
echo "Checking for real Windows registry..."
if [ -f "$CROOT/windows/system.dat" ]
then DOREG=no
elif [ -f "$CROOT/windows/system32/config/system" ]
then DOREG=no
+ elif [ -f "$CROOT/WINNT/system32/config/system" ]
+ then DOREG=no
else DOREG=yes
fi
if [ "$DOREG" = 'yes' ]
April 19, 2002
Re: ALSA driver
by David Hammerton
Hi,
Eric has written one which is almost complete, I am in the midst of debugging
it and finising it off.
Contact me directly if you like.
David
On 19 Apr 2002 17:57:07 +0200, Marco Pietrobono wrote:
| Hi,
|
| I'm starting to work on a native ALSA driver for wine. Since I
| remember that Marcus was working (or was planning to work) an that one
| too, I would like to know if there is already something to work on or to
| contribute to, or if I need to start from scratch.
|
| If there is nothing already written, I would like to discuss what kind
| of approach we should use with ALSA programming, since FWIK there should
| be two way to use it: we can use the ALSA devices directly, just like it
| has been done with OSS, or we can use the alsalib to avoid all direct
| references to the kernel devices and ioctl, but this solution will add a
| dependency on the alsalib library itself to wine. Of course, we could
| add a configure option/check to allow its use at compilation time,
| but...
|
| BTW, Alsalib is LGPL, so the license shouldn't be a problem.
|
| bye,
|
| /pietrobo
|
|
| --
| Stud. Marco Pietrobono | Murphy's Law: if something could
| v. del Calice, 39 - 00178 ROMA | go wrong, it does.
| Tel. +39.06.7186329 339.7410893 | Legge di Murphy: se qualcosa può
| http://www.pietrobo.com | andar male, lo farà.
| ------------------------------------------------------------------------
| Strange game.
| The only winning move
| is not to play.
| What about a nice play of chess ?
|
--
David Hammerton
programmer and support
TransGaming Technologies Inc.
http://www.transgaming.com
david(a)transgaming.com
April 19, 2002
FW: Please educate me
by Medland, Bill
Thanks for the responses guys, but..
> -----Original Message-----
> From: David Laight [mailto:david(a)l8s.co.uk]
> Sent: Friday, April 19, 2002 3:33 AM
> Cc: Wine devel (E-mail)
> Subject: Re: Please educate me
>
>
> On Fri, Apr 19, 2002 at 04:13:03AM +0200, Sylvain Petreolle wrote:
> > > noticed that
> > >
> > > for ac_dir in /sbin:/usr/sbin:$PATH
> > >
> > > was splitting as
> > > 1. /sbin:/usr/sbin:/usr/local/bin
> > > 2. /bin
> > > 3. /usr/bin
> > > etc.
> >
> > it's a normal behaviour, because for uses space as a
> > separator, not ':' ??
> >
> > >
> > > Now, I know I can force it to work by changing the
> > > for loop to
> > > for ac_dir in /sbin /usr/sbin $PATH
>
> If you have:
> more_path="/sbin:/usr/sbin:$PATH"
> you can do:
> save_ifs="$IFS"
> IFS=" :"
> for ac_dir in $more_path
> do
> IFS="$save_ifs"
> ...
> done
>
> So that the shell treats ':' as a separator when
> parsing the output of the substitution.
>
>
> David
>
> --
> David Laight: david(a)l8s.co.uk
>
So why does "for" use spaces as the separator between the /sbin, the
/usr/sbin and the $PATH but $IFS while expanding the $PATH (which is using
:)? (And how come configure used to work OK but doesn't now?)
(And, of course, it is configure.ac I will have to change so I don't get to
change how AC_PATH_PROG gets expanded, and using spaces to separate will go
against the documentation on autoconf)
Bill
April 19, 2002
ALSA driver
by Marco Pietrobono
Hi,
I'm starting to work on a native ALSA driver for wine. Since I
remember that Marcus was working (or was planning to work) an that one
too, I would like to know if there is already something to work on or to
contribute to, or if I need to start from scratch.
If there is nothing already written, I would like to discuss what kind
of approach we should use with ALSA programming, since FWIK there should
be two way to use it: we can use the ALSA devices directly, just like it
has been done with OSS, or we can use the alsalib to avoid all direct
references to the kernel devices and ioctl, but this solution will add a
dependency on the alsalib library itself to wine. Of course, we could
add a configure option/check to allow its use at compilation time,
but...
BTW, Alsalib is LGPL, so the license shouldn't be a problem.
bye,
/pietrobo
--
Stud. Marco Pietrobono | Murphy's Law: if something could
v. del Calice, 39 - 00178 ROMA | go wrong, it does.
Tel. +39.06.7186329 339.7410893 | Legge di Murphy: se qualcosa può
http://www.pietrobo.com | andar male, lo farà.
------------------------------------------------------------------------
Strange game.
The only winning move
is not to play.
What about a nice play of chess ?
April 19, 2002
Re: toolbar.c problem (ATTN: Duane)
by Duane Clark
Dusan Vujosevic wrote:
>>Under Wine, I can make the flying toolbar stick (even with my patch) by
>>holding the mouse button down and sliding it out of the main toolbar.
>>Once out of the toolbar, I can let up the mouse button without the
>>toolbar going away. Once stuck, if I simply slide the mouse across the
>>flying toolbar, it disappears. This does not happen under Windows.
>
> That is true. If release the left mouse button anywhere else except over the
> toolbars the flyout will stick. The reason is that TOOLBAR_LButtonUp()
> doesn't get executed in that case and the WM_COMMAND is not sent.
> (Everything works perfectly under any Windows as you have noticed because
> Win32 doesn't send the WM_COMMAND as I said before).
I think you misunderstood my explanation. Once the menu is stuck and the
button released, I slide the mouse into the flying menu and back out
again, without pressing any mouse buttons. When the cursor leaves the
flying menu, it disappears, but without calling TOOLBAR_LButtonUp().
This is the second behavior, which may not be related.
>>Unfortunately
>>for me, my real work is once again interfering severely with the amount
>>of time I have to spend on Wine :-(
>
>
> I'd be all too happy to help. I will take off my own time to test & fix
> this. I'll try give you something over the weekend (patch).
>
>
>> But I will try to get in a couple
>>of tests with ControlSpy with the TBSTYLE_DROPDOWN style, since it
>>should not take much time, perhaps this weekend.
A suggestion I made a couple weeks ago would make things easier, I would
think. That would be to duplicate your flying menus within ControlSpy. I
don't know how easy that would be to implement, but once implemented, it
would likely make debugging much easier.
April 19, 2002
Re: Re: CoGetClassObject and SHQueryValueEx A/W/AW fixxes
by Leo van den Berg
hi Juergen,
I chose SHGetRegPathW from shlwapi, because that seemed to be the best
matching function for getting the registry string. I did not call a *AW
function directly. I fixed the SHQueryValueExW to convert the incoming
strings to ascii, _because_ the SHQueryValueExAW function had a bug in
handling ExpandEnviromentStringsA (always failed) and was ascii-only (it
doesn't seem to handle unicode at all). That was also the part i was not
completely happy about. I must say i'm not to happy about including
shlwapi either, but i think it is better than reinventing the wheel.
What would you suggest i do? Move SHGetRegPath into a libwine and make a
dependency from shlwapi and compobj(ole32) to that library? reimplement
SHGetRegPathW and SHQueryValueExW in place in compobj.c ? Especially
with the lib seperation going on.. there will be more and more inter-dll
dependencys, must we avoid that at all cost?
regards,
leo
juergen.schmied(a)debitel.net wrote:
>Hmm, I think ole32 must not import shlwapi.dll...
>Instead after the RegQueryValue call it should do a ExpandEnvironmentStrings when returned lpType is REG_EXPAND_SZ.
>
>... and never ever call a *AW Function internally, it will behave differently (one time it takes ASCII one time UNICODE) depending on the OSVERSION ...
>
>Juergen
>
>On 12 Apr 2002 at 20:17, Leo van den berg wrote:
>
>>Cleaned up and fixxed Registry Path finding of Inprocess32 & LocalServer32,
>>registry entrys like '%SystemRoot%' don't break programs anymore now.
>>Found that SHQueryValueEx - family of functions were broken (and derived
>>functions as well ofcourse). Not 100% happy about the result, but it seems
>>to *work* now.
>>
>>any comments welcome ofcourse,
>> Leo van den Berg
>>
>
>
April 19, 2002
Re: [WINE with XIM] help - runtime error
by Ulrich Czekalla
Hi Leanne,
This error is usually caused by unresolved symbols in the libx11drv.so.
Look for compile warnings about implicitly defined symbols when building
the x11drv.
By the way, I'm also looking into XIM support. Unfortunately my code
isn't complete yet. How far along are you? Could you post or send me
your diff. Perhaps we could work together.
/Ulrich
>Dear all,
>
>I have patched the code I was given in wine-16042002.
>When I ran it, I got the following error..
>
>~~~~~~~~~~~~~~
>[leanne(a)leanne73 wine]$ wine /tmp/notepad.exe
>err:module:BUILTIN32_dlopen failed to load .so lib for builtin
>x11drv.dll: /usr/X11R6/lib/libX11.so: shared object not open
>Could not load graphics driver 'x11drv'
>err:win:GetDesktopWindow Wine init error: either you're trying to use
an
>invalid native USER.EXE config, or some graphics/GUI libraries or DLLs
>didn't initialize properly. Aborting.
>~~~~~~~~~~~~~~
>
>I would like to ask which module/file relates to this error so that I
>could fix it?
>If you want to see my code, please welcome. or I can post the .diff
>later on.
>
>
>Many thanks.
>
>Yours sincerely,
>Leanne
April 19, 2002
Re: toolbar.c problem (ATTN: Duane)
by Dusan Vujosevic
----- Original Message -----
From: "Duane Clark" <dclark(a)akamail.com>
To: "Dusan Vujosevic" <dusanv(a)cadlink.com>
Cc: <wine-devel(a)winehq.com>
Sent: Thursday, April 18, 2002 7:18 PM
Subject: Re: toolbar.c problem (ATTN: Duane)
> Dusan Vujosevic wrote:
> > Hello,
> >
> > ----- Original Message -----
> > From: "Duane Clark" <dclark(a)akamail.com>
> > ...
> >>It is not "the correct way", since I have tested it with control spy
> >>under WinNT and Wine. That is not to say that my patch is correct
> >>either, but it fixes two different applications I have and in my mind is
> >>closer to the correct way. There may well be some conditions under which
> >>the message should not be sent, but the previous way was not correct.
> >
> >
> > How about we test whether the button has TBSTYLE_DROPDOWN
> > style set and not send the message in that case???
>
> Okay by me. I certainly did not test for that case.
>
> >>And there is more going on in your app, because the flying toolbars also
> >>disappear when the mouse is simply slid over them, without clicking.
> >
> >
> > Wine or Windows? I don't follow this / can't reproduce it under either
one.
>
> Under Wine, I can make the flying toolbar stick (even with my patch) by
> holding the mouse button down and sliding it out of the main toolbar.
> Once out of the toolbar, I can let up the mouse button without the
> toolbar going away. Once stuck, if I simply slide the mouse across the
> flying toolbar, it disappears. This does not happen under Windows.
That is true. If release the left mouse button anywhere else except over the
toolbars the flyout will stick. The reason is that TOOLBAR_LButtonUp()
doesn't get executed in that case and the WM_COMMAND is not sent.
(Everything works perfectly under any Windows as you have noticed because
Win32 doesn't send the WM_COMMAND as I said before).
> Note that I have my window manager set for "focus follows mouse", which
> perhaps could possibly have some effect here. However, other programs I
> have tried with flying toolbars, including Word2000 and Acroread, do not
> have this problem (nor the mouseup problem), so it is not a simple
> generic problem.
I will spy on Acrobat 4 over the weekend (don't have Word ...). That
*probably* isn't a TBSTYLE_DROPDOWN button (just judging from its looks).
> >>This behavior is not there under Windows, and has nothing to do with the
> >>ButtonUp change I made. The two may not be related, but I cannot help
> >>thinking they are. Unfortunately, I was not able to get a spy program to
> >>work with your app in windows, so I have not been able to figure out
> >>what messages should really be sent, and when.
> >
> >
> > I use Spy++ on it... What was the problem?
>
> I tried APIS32, but it barfed on this particular program.
I will try that as well.
> Unfortunately
> for me, my real work is once again interfering severely with the amount
> of time I have to spend on Wine :-(
I'd be all too happy to help. I will take off my own time to test & fix
this. I'll try give you something over the weekend (patch).
> But I will try to get in a couple
> of tests with ControlSpy with the TBSTYLE_DROPDOWN style, since it
> should not take much time, perhaps this weekend.
Thanks,
Dusan
April 19, 2002
Re: ALSA driver
by Marcus Meissner
On Fri, Apr 19, 2002 at 05:57:07PM +0200, Marco Pietrobono wrote:
> Hi,
>
> I'm starting to work on a native ALSA driver for wine. Since I
> remember that Marcus was working (or was planning to work) an that one
> too, I would like to know if there is already something to work on or to
> contribute to, or if I need to start from scratch.
I was not planning to work on it as of this time.
Ciao, Marcus
April 19, 2002
bug in wineinstall script
by Martin
make[1]: Leaving directory `/home/src/wine/programs/wineconsole'
Wine build complete.
Performing 'make install' as root to install binaries, enter root password
Password:
/bin/bash: - : unrecognized option
Either you entered an incorrect password or we failed to run
'make install' correctly.
If you didn't enter an incorrect password then please report this
error to wine-devel(a)winehq.com.
Installation failed, aborting.
bash-2.05$ uname -a
Linux hexa 2.4.17 #7 SMP Wed Jan 23 15:19:41 CET 2002 i686 unknown
bash-2.05$ /bin/bash --version
GNU bash, version 2.05.0(1)-release (i386-slackware-linux-gnu)
Copyright 2000 Free Software Foundation, Inc.
bash-2.05$
April 19, 2002
Re: Please educate me
by David Laight
On Fri, Apr 19, 2002 at 04:13:03AM +0200, Sylvain Petreolle wrote:
> > noticed that
> >
> > for ac_dir in /sbin:/usr/sbin:$PATH
> >
> > was splitting as
> > 1. /sbin:/usr/sbin:/usr/local/bin
> > 2. /bin
> > 3. /usr/bin
> > etc.
>
> it's a normal behaviour, because for uses space as a
> separator, not ':' ??
>
> >
> > Now, I know I can force it to work by changing the
> > for loop to
> > for ac_dir in /sbin /usr/sbin $PATH
If you have:
more_path="/sbin:/usr/sbin:$PATH"
you can do:
save_ifs="$IFS"
IFS=" :"
for ac_dir in $more_path
do
IFS="$save_ifs"
...
done
So that the shell treats ':' as a separator when
parsing the output of the substitution.
David
--
David Laight: david(a)l8s.co.uk
April 19, 2002
Re: CoGetClassObject and SHQueryValueEx A/W/AW fixxes
by juergen.schmied@debitel.net
Hmm, I think ole32 must not import shlwapi.dll...
Instead after the RegQueryValue call it should do a ExpandEnvironmentStrings when returned lpType is REG_EXPAND_SZ.
... and never ever call a *AW Function internally, it will behave differently (one time it takes ASCII one time UNICODE) depending on the OSVERSION ...
Juergen
On 12 Apr 2002 at 20:17, Leo van den berg wrote:
> Cleaned up and fixxed Registry Path finding of Inprocess32 & LocalServer32,
> registry entrys like '%SystemRoot%' don't break programs anymore now.
> Found that SHQueryValueEx - family of functions were broken (and derived
> functions as well ofcourse). Not 100% happy about the result, but it seems
> to *work* now.
>
> any comments welcome ofcourse,
> Leo van den Berg
>
April 19, 2002
[WINE with XIM] help - runtime error
by leanne
Dear all,
I have patched the code I was given in wine-16042002.
When I ran it, I got the following error.
~~~~~~~~~~~~~~
[leanne(a)leanne73 wine]$ wine /tmp/notepad.exe
err:module:BUILTIN32_dlopen failed to load .so lib for builtin
x11drv.dll: /usr/X11R6/lib/libX11.so: shared object not open
Could not load graphics driver 'x11drv'
err:win:GetDesktopWindow Wine init error: either you're trying to use an
invalid native USER.EXE config, or some graphics/GUI libraries or DLLs
didn't initialize properly. Aborting.
~~~~~~~~~~~~~~
I would like to ask which module/file relates to this error so that I
could fix it?
If you want to see my code, please welcome. or I can post the .diff
later on.
Many thanks.
Yours sincerely,
Leanne
April 19, 2002
Re: Please educate me
by Sylvain Petreolle
> noticed that
>
> for ac_dir in /sbin:/usr/sbin:$PATH
>
> was splitting as
> 1. /sbin:/usr/sbin:/usr/local/bin
> 2. /bin
> 3. /usr/bin
> etc.
it's a normal behaviour, because for uses space as a
separator, not ':' ??
>
> Now, I know I can force it to work by changing the
> for loop to
> for ac_dir in /sbin /usr/sbin $PATH
___________________________________________________________
Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en français !
Yahoo! Mail : http://fr.mail.yahoo.com
April 19, 2002
Re: toolbar.c problem (ATTN: Duane)
by Duane Clark
Andreas Mohr wrote:
> On Thu, Apr 18, 2002 at 04:18:47PM -0700, Duane Clark wrote:
>
>>Dusan Vujosevic wrote:
>>
>>>I use Spy++ on it... What was the problem?
>>
>>I tried APIS32, but it barfed on this particular program. Unfortunately
>>for me, my real work is once again interfering severely with the amount
>>of time I have to spend on Wine :-( But I will try to get in a couple
>>of tests with ControlSpy with the TBSTYLE_DROPDOWN style, since it
>>should not take much time, perhaps this weekend.
>
> Did you *really* only enable logging when arriving at this part ??
> Or maybe you did not enable logging even though you should have
> at some critical part or another...
As I recall, the program would not even run. It was the first time I
tried APIS32, though, so it could easily be operator error. I did try
running another program under APIS32, and was able to get it that one to
work.
April 19, 2002
Re: toolbar.c problem (ATTN: Duane)
by Andreas Mohr
On Thu, Apr 18, 2002 at 04:18:47PM -0700, Duane Clark wrote:
> Dusan Vujosevic wrote:
> > I use Spy++ on it... What was the problem?
>
> I tried APIS32, but it barfed on this particular program. Unfortunately
> for me, my real work is once again interfering severely with the amount
> of time I have to spend on Wine :-( But I will try to get in a couple
> of tests with ControlSpy with the TBSTYLE_DROPDOWN style, since it
> should not take much time, perhaps this weekend.
Did you *really* only enable logging when arriving at this part ??
Or maybe you did not enable logging even though you should have
at some critical part or another...
--
Andreas Mohr Stauferstr. 6, D-71272 Renningen, Germany
Tel. +49 7159 800604 http://home.arcor.de/andi.mohr/
April 18, 2002
Is Wine server request serialization broken ?
by Laurent Pinchart
Hi everybody,
I ran into a pretty serious problem. I'm trying to run a program which
creates a child process. I noticed that the call to the server request
init_process_done returned erroneus information about the debugger state.
After some investigation, here's what I found.
I put a few fprintfs in the start_process(), wine_server_call() and
send_request() functions. I also tweaked the init_process_done request to
return an unsigned int equal to 0x12345678 in the reply structure just after
the debugger member.
Here's what a 'normal' call to start_process() looks like
calling wine_server_call req=0x405a6ec4
wine_server_call req=0x405a6ec4 request_header.req=6
wine_server_call checkpoint 1
send_request checkpoint 1
send_request checkpoint 2
wine_server_call checkpoint 2
wine_server_call req=0x405a6ec4
wine_server_call 00 00 00 00 00 00 00 00
wine_server_call 00 00 00 00 78 56 34 12
wine_server_call returned req=0x405a6ec4
wine_server_call returned 00 00 00 00 00 00 00 00
wine_server_call returned 00 00 00 00 78 56 34 12
There is one 'checkpoint' in wine_server_call just before the call to
send_request(), and one right after. There are 2 checkpoints in send_request,
the first one right before the call to writev() and the second one right
after.
The hex dump in the above trace is the content of the 16 first bytes of
reply. Please notice the '78 56 34 12' at the end, being the extra member
I added to the init_process_done_reply structure.
Here's now what the 'broken' call to start_process() looks like
calling wine_server_call req=0x40556ec4
wine_server_call req=0x40556ec4 request_header.req=6
wine_server_call checkpoint 1
send_request checkpoint 1
wine_server_call req=0x40555254 request_header.req=90
wine_server_call checkpoint 1
send_request checkpoint 1
send_request checkpoint 2
wine_server_call checkpoint 2
wine_server_call req=0x40555254
wine_server_call 00 00 00 00 00 00 00 00
wine_server_call 00 00 00 00 78 56 34 12
wine_server_call req=0x4055601c request_header.req=90
wine_server_call checkpoint 1
send_request checkpoint 1
send_request checkpoint 2
wine_server_call checkpoint 2
wine_server_call req=0x4055601c
wine_server_call 00 00 00 00 00 00 00 00
wine_server_call 20 00 00 00 00 00 00 00
wine_server_call req=0x40555f2c request_header.req=94
wine_server_call checkpoint 1
send_request checkpoint 1
send_request checkpoint 2
wine_server_call checkpoint 2
wine_server_call req=0x40555f2c
wine_server_call 00 00 00 00 00 00 00 00
wine_server_call 28 00 00 00 00 00 00 00
wine_server_call req=0x4055607c request_header.req=20
wine_server_call checkpoint 1
send_request checkpoint 1
wine_server_call checkpoint 2
wine_server_call req=0x4055607c
wine_server_call 34 00 00 c0 00 00 00 00
wine_server_call ff ff ff ff 00 00 00 00
send_request checkpoint 2
wine_server_call checkpoint 2
wine_server_call req=0x40556ec4
wine_server_call 00 00 00 00 00 00 00 00
wine_server_call ff ff ff ff 00 00 00 00
wine_server_call returned req=0x40556ec4
wine_server_call returned 00 00 00 00 00 00 00 00
wine_server_call returned ff ff ff ff 00 00 00 00
As you can see, the call to writev() seems to trigger something
registry-related (90 is open_key, 94 is get_key_value and 20 is
close_handle).
I have absolutely no idea about where those calls come from (Wine internal
registry calls or external calls). Remember that there are two processes
running, start_process() being called for the second one.
As you can see for the hex dump, the open_key request receives the answer of
the init_process_done request !
I'm completely clueless about that problem. If someone has any idea, or needs
more information, please send me a mail.
Laurent Pinchart
April 18, 2002