Sorry about not knowing how to cross compile before. Here is the
patch(gmail doesn't let me attach exe's... I will look into this).
Please try this. Tell me if I am doing something wrong (again).
-Scott
From 3a7d296ed2184fd22b70d96880afc86927801ab7 Mon Sep 17 00:00:00 2001
From: Scott Lindeneau <[EMAIL PROTECTED]>
Date: Thu, 21 Aug 2008 04:21:22 +0900
Subject: [PATCH] AcceptEx Conformance tests.
---
dlls/ws2_32/tests/sock.c | 238 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 232 insertions(+), 6 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index e2d2162..cf96a63 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,215 @@ 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;
+ LPFN_ACCEPTEX lpfnAcceptEx = NULL;
+ GUID GuidAcceptEx = WSAID_ACCEPTEX;
+ LPFN_GETACCEPTEXSOCKADDRS lpfnGetAcceptExSockaddrs = NULL;
+ GUID GuidGetAccpetExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
+ int dummy,dummy2;
+ 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" );
+
+ WSAIoctl(mem->s,
+ SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &GuidAcceptEx,
+ sizeof(GuidAcceptEx),
+ &lpfnAcceptEx,
+ sizeof(lpfnAcceptEx),
+ &dummy,
+ NULL,
+ NULL);
+ wsa_ok(lpfnAcceptEx, NULL !=, "overlapped_server (%x): WSAIoctl failed
loading AcceptEx: %d\n");
+ WSAIoctl(mem->s,
+ SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &GuidGetAccpetExSockaddrs,
+ sizeof(GuidGetAccpetExSockaddrs),
+ &lpfnGetAcceptExSockaddrs,
+ sizeof(lpfnGetAcceptExSockaddrs),
+ &dummy2,
+ NULL,
+ NULL);
+ wsa_ok(lpfnGetAcceptExSockaddrs, NULL !=, "overlapped_server (%x):
WSAIoctl failed loading GetAcceptExSockaddrs: %d\n");
+
+ if(lpfnGetAcceptExSockaddrs == NULL || lpfnAcceptEx == NULL){
+ trace ( "overlapped_server (%x) failing stop\n", id );
+ server_stop();
+ }
+
+
+ /*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*/
+
+ lpfnAcceptEx( 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);
+ lpfnGetAcceptExSockaddrs(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 +808,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 +819,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 +835,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 +1319,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