I would like to submit the following AcceptEx conformance test to
wine-patches, but I don't have a windows box (and i haven't got qemu
setup(correctly) yet). Would someone run this and let me know how/if
it failes (or succeeds... it should succeed).

Thanks
- Scott
From 00a1b8b04f99cfae3b77f6362068dbeba78d581e Mon Sep 17 00:00:00 2001
From: Scott Lindeneau <[EMAIL PROTECTED]>
Date: Thu, 21 Aug 2008 02:14:49 +0900
Subject: [PATCH] AcceptEx Conformance Tests. - Simple

---
 dlls/ws2_32/tests/sock.c |  204 ++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 198 insertions(+), 6 deletions(-)

diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index e2d2162..310e32f 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -20,7 +20,7 @@
  */
 
 #include <stdarg.h>
-
+#include <stdio.h>
 #include <windef.h>
 #include <winbase.h>
 #include <winsock2.h>
@@ -31,7 +31,7 @@
 #include <winerror.h>
 
 #define MAX_CLIENTS 4      /* Max number of clients */
-#define NUM_TESTS   4      /* Number of tests performed */
+#define NUM_TESTS   5      /* Number of tests performed */
 #define FIRST_CHAR 'A'     /* First character in transferred pattern */
 #define BIND_SLEEP 10      /* seconds to wait between attempts to bind() */
 #define BIND_TRIES 6       /* Number of bind() attempts */
@@ -54,7 +54,6 @@
         ok ( cond tmp, msg, GetCurrentThreadId(), err); \
    } while (0);
 
-
 /**************** Structs and typedefs ***************/
 
 typedef struct thread_info
@@ -583,6 +582,181 @@ static VOID WINAPI select_server ( server_params *par )
     server_stop ();
 }
 
+/*
+ * overlapped_server: A (partially)non-blocking server built on acceptex.
+ */
+static VOID WINAPI overlapped_server ( server_params *par )
+{
+    test_params *gen = par->general;
+    server_memory *mem;
+       HANDLE hCompPort;
+       WSAEVENT peerSockets[MAX_CLIENTS];
+       WSAOVERLAPPED overLap[MAX_CLIENTS];
+       LPSOCKADDR addrAddr;
+       LPSOCKADDR addrPeer;
+       int outBuf[MAX_CLIENTS];
+       int event_i;
+       int size;
+    int n_expected = gen->n_chunks * gen->chunk_size, i,
+        id = GetCurrentThreadId(), n_connections = 0, n_sent, n_recvd,
+        n_set, delta, n_ready;
+    char *p;
+    fd_set fds_recv, fds_send, fds_openrecv, fds_opensend;
+
+    trace ( "overlapped_server (%x) starting\n", id );
+
+    set_so_opentype ( TRUE ); /* overlapped server */
+       par->sock_flags = WSA_FLAG_OVERLAPPED;
+    server_start ( par );
+    mem = TlsGetValue ( tls );
+
+       /*Create completion port*/
+       hCompPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 
(u_long)0, 0 );
+       ok( hCompPort != NULL, "CreateIoCompletionPort failed\n" );
+       /*Associate completion port with listening port*/
+       ok( CreateIoCompletionPort((HANDLE)mem->s, hCompPort, (u_long)0, 0) != 
NULL, "CreateIoCompletionPort failed\n" );
+               
+    wsa_ok ( set_blocking ( mem->s, FALSE ), 0 ==, "overlapped_server (%x): 
failed to set blocking mode: %d\n" );
+    wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "overlapped_server (%x): 
listen failed: %d\n" );
+
+       /*empty overlapped structures*/
+       memset( overLap,0,sizeof(WSAOVERLAPPED) * MAX_CLIENTS );
+       for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
+       {
+               /*Create accepting socket*/
+               mem->sock[i].s = WSASocketA ( AF_INET, gen->sock_type, 
gen->sock_prot,
+                          NULL, 0, par->sock_flags );
+               /*Create event to wait on*/
+               peerSockets[i] = WSACreateEvent();
+               overLap[i].hEvent = peerSockets[i];
+               /*Call AcceptEx*/
+               AcceptEx( mem->s, /*listen socket*/
+                                       mem->sock[i].s, /*accept socket*/
+                                       mem->sock[i].buf, /*socket buffer*/
+                                       0, /*don't recieve any data*/
+                                       sizeof(struct sockaddr_in) + 16, /*size 
of address*/
+                                       sizeof(struct sockaddr_in) + 16, /*size 
of address*/
+                                       (LPDWORD)(outBuf + i), /*Pointer to an 
int that returns the number of bytes recieved*/
+                                       (overLap + i) ); /*Overlapped data 
structure */ 
+               ok(WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned 
unexpected value\n");
+               /*Associeate accepting socket with completionport*/
+               ok( CreateIoCompletionPort((HANDLE)mem->sock[i].s, hCompPort, 
(u_long)0, 0) != NULL , "CreateIoCompletionPort failed\n" );
+       }
+
+    trace ( "overlapped_server (%x) ready\n", id );
+    SetEvent ( server_ready ); /* notify clients */
+
+    FD_ZERO ( &fds_openrecv );
+    FD_ZERO ( &fds_recv );
+    FD_ZERO ( &fds_send );
+    FD_ZERO ( &fds_opensend );
+
+    FD_SET ( mem->s, &fds_openrecv );
+       event_i = WSA_WAIT_TIMEOUT;
+    while(1)
+    {
+               int bytes;
+        fds_recv = fds_openrecv;
+        fds_send = fds_opensend;
+        n_set = 0;
+               n_ready = 0;
+               event_i = WSAWaitForMultipleEvents(min ( gen->n_clients, 
MAX_CLIENTS ), peerSockets, FALSE, 0, FALSE);
+
+        /* check for incoming requests */
+        if ( event_i != WSA_WAIT_TIMEOUT ) 
+               {
+            n_set += 1;
+                       WSAResetEvent(peerSockets[event_i]);
+                       
GetOverlappedResult((HANDLE)mem->sock[event_i].s,(overLap + event_i), &bytes, 
FALSE);
+            trace ( "overlapped_server (%x): accepting client connection\n", 
id );
+
+            /* accept a single connection */
+            wsa_ok ( mem->sock[event_i].s, INVALID_SOCKET !=, 
"overlapped_server (%x): accept() failed: %d\n" );
+                       addrAddr = (LPSOCKADDR)&(mem->sock[event_i].addr);
+                       addrPeer = (LPSOCKADDR)&(mem->sock[event_i].peer);
+                       GetAcceptExSockaddrs(mem->sock[event_i].buf, 
/*bufferwith data*/
+                                                               0, /*no data 
recieved*/
+                                                               sizeof(struct 
sockaddr_in) + 16,
+                                                               sizeof(struct 
sockaddr_in) + 16,
+                                                               &addrAddr, /* 
local addr */
+                                                               &size, /* size 
*/
+                                                               &addrPeer, /* 
connection peer */
+                                                               &size ); /*size 
*/
+                       mem->sock[event_i].addr = *(struct 
sockaddr_in*)addrAddr; /*I can't figure out how to do this */
+                       mem->sock[event_i].peer = *(struct 
sockaddr_in*)addrPeer; /*any other way then written */
+            ok ( mem->sock[event_i].peer.sin_addr.s_addr == inet_addr ( 
gen->inet_addr ),
+                "overlapped_server (%x): strange peer address\n", id );
+
+            /* add to list of open connections */
+            FD_SET ( mem->sock[event_i].s, &fds_openrecv );
+            FD_SET ( mem->sock[event_i].s, &fds_opensend );
+            n_connections++;
+                       
+        }
+
+        /* handle open requests */
+
+        for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
+        {
+            if ( FD_ISSET( mem->sock[i].s, &fds_recv ) ) {
+                n_set += 1;
+                if ( mem->sock[i].n_recvd < n_expected ) {
+                    /* Receive data & check it */
+                    n_recvd = recv ( mem->sock[i].s, mem->sock[i].buf + 
mem->sock[i].n_recvd, min ( n_expected - mem->sock[i].n_recvd, par->buflen ), 0 
);
+                    ok ( n_recvd != SOCKET_ERROR, "overlapped_server (%x): 
error in recv(): %d\n", id, WSAGetLastError() );
+                    mem->sock[i].n_recvd += n_recvd;
+
+                    if ( mem->sock[i].n_recvd == n_expected ) {
+                        p = test_buffer ( mem->sock[i].buf, gen->chunk_size, 
gen->n_chunks );
+                        ok ( p == NULL, "overlapped_server (%x): test pattern 
error: %d\n", id, p - mem->sock[i].buf );
+                        FD_CLR ( mem->sock[i].s, &fds_openrecv );
+                    }
+
+                    ok ( mem->sock[i].n_recvd <= n_expected, 
"overlapped_server (%x): received too many bytes: %d\n", id, 
mem->sock[i].n_recvd );
+                }
+            }
+
+            /* only echo back what we've received */
+            delta = mem->sock[i].n_recvd - mem->sock[i].n_sent;
+
+            if ( FD_ISSET ( mem->sock[i].s, &fds_send ) ) {
+                n_set += 1;
+
+                if ( ( delta > 0 ) && ( mem->sock[i].n_sent < n_expected ) ) {
+                    /* Echo data back */
+                    n_sent = send ( mem->sock[i].s, mem->sock[i].buf + 
mem->sock[i].n_sent, min ( delta, par->buflen ), 0 );
+                    ok ( n_sent != SOCKET_ERROR, "overlapped_server (%x): 
error in send(): %d\n", id, WSAGetLastError() );
+                    mem->sock[i].n_sent += n_sent;
+
+                    if ( mem->sock[i].n_sent == n_expected ) {
+                        FD_CLR ( mem->sock[i].s, &fds_opensend );
+                    }
+
+                    ok ( mem->sock[i].n_sent <= n_expected, "overlapped_server 
(%x): sent too many bytes: %d\n", id, mem->sock[i].n_sent );
+                }
+            }
+        }
+
+        /* check if all clients are done */
+        if ( ( fds_opensend.fd_count == 0 ) 
+            && ( fds_openrecv.fd_count == 1 ) /* initial socket that accepts 
clients */
+            && ( n_connections  == min ( gen->n_clients, MAX_CLIENTS ) ) ) {
+            break;
+        }
+    }
+
+    for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ )
+    {
+        /* cleanup */
+        read_zero_bytes ( mem->sock[i].s );
+        wsa_ok ( closesocket ( mem->sock[i].s ),  0 ==, "overlapped_server 
(%x): closesocket error: %d\n" );
+        mem->sock[i].s = INVALID_SOCKET;
+    }
+
+    trace ( "overlapped_server (%x) exiting\n", id );
+    server_stop ();
+}
+
 /**************** Clients ***************/
 
 /*
@@ -600,7 +774,6 @@ static VOID WINAPI simple_client ( client_params *par )
     /* wait here because we want to call set_so_opentype before creating a 
socket */
     WaitForSingleObject ( server_ready, INFINITE );
     trace ( "simple_client (%x): server ready\n", id );
-
     check_so_opentype ();
     set_so_opentype ( FALSE ); /* non-overlapped */
     client_start ( par );
@@ -612,7 +785,6 @@ static VOID WINAPI simple_client ( client_params *par )
     ok ( set_blocking ( mem->s, TRUE ) == 0,
          "simple_client (%x): failed to set blocking mode\n", id );
     trace ( "simple_client (%x) connected\n", id );
-
     /* send data to server */
     n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, 
par->buflen );
     ok ( n_sent == n_expected,
@@ -629,7 +801,6 @@ static VOID WINAPI simple_client ( client_params *par )
     /* check data */
     p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks );
     ok ( p == NULL, "simple_client (%x): test pattern error: %d\n", id, p - 
mem->recv_buf);
-
     /* cleanup */
     read_zero_bytes ( mem->s );
     trace ( "simple_client (%x) exiting\n", id );
@@ -1114,6 +1285,27 @@ static test_setup tests [NUM_TESTS] =
             0,
             128
         }
+    },
+        /* Test 4: simple client and overlapped server */
+    {
+        {
+            STD_STREAM_SOCKET,
+            2048,
+            16,
+            2
+        },
+        overlapped_server,
+        {
+            NULL,
+            0,
+            64
+        },
+        simple_client,
+        {
+            NULL,
+            0,
+            128
+        }
     }
 };
 
-- 
1.5.4.3



Reply via email to