From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 57 ++++---------------------------------- dlls/dplayx/tests/dplayx.c | 36 +++++++++++------------- 2 files changed, 21 insertions(+), 72 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index f02226544ea..ecdb4d9a2df 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -1758,28 +1758,10 @@ static HRESULT DP_IF_CreatePlayer( IDirectPlayImpl *This, DPID *lpidPlayer, * to the name server if requesting a player id and to the SP when * informing it of the player creation */ - { - if( dwFlags & DPPLAYER_SERVERPLAYER ) - { - if( *lpidPlayer == DPID_SERVERPLAYER ) - { - /* Server player for the host interface */ - dwCreateFlags |= DPLAYI_PLAYER_APPSERVER; - } - else if( *lpidPlayer == DPID_NAME_SERVER ) - { - /* Name server - master of everything */ - dwCreateFlags |= (DPLAYI_PLAYER_NAMESRVR|DPLAYI_PLAYER_SYSPLAYER); - } - else - { - /* Server player for a non host interface */ - dwCreateFlags |= DPLAYI_PLAYER_SYSPLAYER; - } - } + if( dwFlags & DPPLAYER_SERVERPLAYER ) + dwCreateFlags |= DPLAYI_PLAYER_APPSERVER;
- dwCreateFlags |= DPLAYI_PLAYER_PLAYERLOCAL; - } + dwCreateFlags |= DPLAYI_PLAYER_PLAYERLOCAL;
/* Verify we know how to handle all the flags */ if( !( ( dwFlags & DPPLAYER_SERVERPLAYER ) || @@ -1792,7 +1774,7 @@ static HRESULT DP_IF_CreatePlayer( IDirectPlayImpl *This, DPID *lpidPlayer, }
/* If the name is not specified, we must provide one */ - if( *lpidPlayer == DPID_UNKNOWN ) + if( !(dwFlags & DPPLAYER_SERVERPLAYER) ) { /* If we are the session master, we dish out the group/player ids */ if( This->dp2->bHostInterface ) @@ -1815,6 +1797,7 @@ static HRESULT DP_IF_CreatePlayer( IDirectPlayImpl *This, DPID *lpidPlayer, /* FIXME: Would be nice to perhaps verify that we don't already have * this player. */ + *lpidPlayer = DPID_SERVERPLAYER; }
EnterCriticalSection( &This->lock ); @@ -1912,21 +1895,6 @@ static HRESULT WINAPI IDirectPlay4AImpl_CreatePlayer( IDirectPlay4A *iface, DPID DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags ) { IDirectPlayImpl *This = impl_from_IDirectPlay4A( iface ); - - if( lpidPlayer == NULL ) - { - return DPERR_INVALIDPARAMS; - } - - if( dwFlags & DPPLAYER_SERVERPLAYER ) - { - *lpidPlayer = DPID_SERVERPLAYER; - } - else - { - *lpidPlayer = DPID_UNKNOWN; - } - return DP_IF_CreatePlayer( This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags, TRUE ); } @@ -1935,21 +1903,6 @@ static HRESULT WINAPI IDirectPlay4Impl_CreatePlayer( IDirectPlay4 *iface, DPID * DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags ) { IDirectPlayImpl *This = impl_from_IDirectPlay4( iface ); - - if( lpidPlayer == NULL ) - { - return DPERR_INVALIDPARAMS; - } - - if( dwFlags & DPPLAYER_SERVERPLAYER ) - { - *lpidPlayer = DPID_SERVERPLAYER; - } - else - { - *lpidPlayer = DPID_UNKNOWN; - } - return DP_IF_CreatePlayer( This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags, FALSE ); } diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index d1ed9368511..c92de4cfcdc 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -4214,16 +4214,15 @@ static void checkCreatePlayerOrGroupMessages_( int line, IDirectPlay4 *dp, DWORD
#define check_CreatePlayer( dp, dpid, name, flags, expectedHr, expectedDpid, recvSock, requestExpected, \ expectedFlags, expectedShortName, expectedShortNameA, expectedLongName, expectedLongNameA, \ - expectedCurrentPlayers, hrTodo, dpidTodo, flagsTodo, nameTodo ) \ + expectedCurrentPlayers, flagsTodo, nameTodo ) \ check_CreatePlayer_( __LINE__, dp, dpid, name, flags, expectedHr, expectedDpid, recvSock, requestExpected, \ expectedFlags, expectedShortName, expectedShortNameA, expectedLongName, expectedLongNameA, \ - expectedCurrentPlayers, hrTodo, dpidTodo, flagsTodo, nameTodo ) + expectedCurrentPlayers, flagsTodo, nameTodo ) static void check_CreatePlayer_( int line, IDirectPlay4 *dp, DPID *dpid, DPNAME *name, DWORD flags, HRESULT expectedHr, DPID expectedDpid, SOCKET recvSock, BOOL requestExpected, DWORD expectedFlags, const WCHAR *expectedShortName, const char *expectedShortNameA, const WCHAR *expectedLongName, const char *expectedLongNameA, - DWORD expectedCurrentPlayers, BOOL hrTodo, BOOL dpidTodo, BOOL flagsTodo, - BOOL nameTodo ) + DWORD expectedCurrentPlayers, BOOL flagsTodo, BOOL nameTodo ) { BYTE playerData[] = { 1, 2, 3, 4, 5, 6, 7, 8, }; CreatePlayerParam *param; @@ -4250,9 +4249,9 @@ static void check_CreatePlayer_( int line, IDirectPlay4 *dp, DPID *dpid, DPNAME sendSuperEnumPlayersReply_( line, sendSock, 2349, 2399, &dpsd, L"" );
hr = createPlayerAsyncWait( param, 2000 ); - todo_wine_if( hrTodo ) ok_( __FILE__, line )( hr == expectedHr, "CreatePlayer() returned %#lx.\n", hr ); + ok_( __FILE__, line )( hr == expectedHr, "CreatePlayer() returned %#lx.\n", hr ); if ( dpid ) - todo_wine_if( dpidTodo ) ok_( __FILE__, line )( *dpid == expectedDpid, "got dpid %#lx.\n", *dpid ); + ok_( __FILE__, line )( *dpid == expectedDpid, "got dpid %#lx.\n", *dpid );
checkPlayerExists_( line, dp, expectedDpid, DPPLAYERTYPE_PLAYER, expectedShortNameA, expectedLongNameA, expectedFlags, playerData, sizeof( playerData ), flagsTodo ); @@ -4269,9 +4268,9 @@ static void check_CreatePlayer_( int line, IDirectPlay4 *dp, DPID *dpid, DPNAME else { hr = createPlayerAsyncWait( param, 2000 ); - todo_wine_if( hrTodo ) ok_( __FILE__, line )( hr == expectedHr, "CreatePlayer() returned %#lx.\n", hr ); + ok_( __FILE__, line )( hr == expectedHr, "CreatePlayer() returned %#lx.\n", hr ); if ( dpid ) - todo_wine_if( dpidTodo ) ok_( __FILE__, line )( *dpid == expectedDpid, "got dpid %#lx.\n", *dpid ); + ok_( __FILE__, line )( *dpid == expectedDpid, "got dpid %#lx.\n", *dpid ); }
if ( recvSock != INVALID_SOCKET ) @@ -4317,50 +4316,47 @@ static void test_CreatePlayer(void) /* Connection not initialized */ dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, NULL, 0, DPERR_UNINITIALIZED, 0xdeadbeef, INVALID_SOCKET, FALSE, 0, NULL, NULL, - NULL, NULL, 0, FALSE, TRUE, FALSE, FALSE ); + NULL, NULL, 0, FALSE, FALSE );
init_TCPIP_provider( dp, "127.0.0.1", 0 );
/* Session not open */ dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, NULL, 0, DPERR_INVALIDPARAMS, 0xdeadbeef, INVALID_SOCKET, FALSE, 0, NULL, NULL, - NULL, NULL, 0, FALSE, TRUE, FALSE, FALSE ); + NULL, NULL, 0, FALSE, FALSE );
/* Join to normal session */ joinSession( dp, &appGuidDpsd, &serverDpsd, &sendSock, &recvSock );
/* Player name */ dpid = 0xdeadbeef; - check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 2, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 1, FALSE, FALSE, - FALSE, FALSE ); + check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 2, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 1, FALSE, FALSE );
dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, &fullName, 0, DP_OK, 3, recvSock, TRUE, 0x8, L"short player name", - "short player name", L"long player name", "long player name", 2, FALSE, FALSE, FALSE, TRUE ); + "short player name", L"long player name", "long player name", 2, FALSE, TRUE );
name = fullName; name.dwSize = 1; dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, &name, 0, DP_OK, 4, recvSock, TRUE, 0x8, L"short player name", "short player name", - L"long player name", "long player name", 3, FALSE, FALSE, FALSE, TRUE ); + L"long player name", "long player name", 3, FALSE, TRUE );
dpid = 0xdeadbeef; - check_CreatePlayer( dp, &dpid, &nullName, 0, DP_OK, 5, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 4, FALSE, FALSE, - FALSE, FALSE ); + check_CreatePlayer( dp, &dpid, &nullName, 0, DP_OK, 5, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 4, FALSE, FALSE );
/* Null dpid */ dpid = 0xdeadbeef; check_CreatePlayer( dp, NULL, NULL, 0, DPERR_INVALIDPARAMS, 0, recvSock, FALSE, 0, NULL, NULL, NULL, NULL, 0, FALSE, - FALSE, FALSE, FALSE ); + FALSE );
/* Flags */ dpid = 0xdeadbeef; - check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 6, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 5, FALSE, FALSE, - FALSE, FALSE ); + check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 6, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 5, FALSE, FALSE );
dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, NULL, DPPLAYER_SPECTATOR, DP_OK, 7, recvSock, TRUE, 0x208, NULL, NULL, NULL, NULL, 6, - FALSE, FALSE, TRUE, FALSE ); + TRUE, FALSE );
closesocket( recvSock ); closesocket( sendSock );
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 43 +++++++++++++++++++++++++++++++------- dlls/dplayx/dplay_global.h | 3 +++ 2 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index ecdb4d9a2df..9f1153fed19 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -1153,6 +1153,16 @@ static lpGroupData DP_CreateGroup( IDirectPlayImpl *This, const DPID *lpid, cons /* FIXME: Should we validate the dwFlags? */ lpGData->dwFlags = dwFlags;
+ /* Initialize the SP data section */ + lpGData->lpSPPlayerData = DPSP_CreateSPPlayerData(); + if ( !lpGData->lpSPPlayerData ) + { + free( lpGData->nameA ); + free( lpGData->name ); + free( lpGData ); + return NULL; + } + TRACE( "Created group id 0x%08lx\n", *lpid );
return lpGData; @@ -1180,6 +1190,7 @@ static void DP_DeleteGroup( IDirectPlayImpl *This, DPID dpid ) }
/* Delete player */ + free( lpGList->lpGData->lpSPPlayerData ); free( lpGList->lpGData->nameA ); free( lpGList->lpGData->name ); free( lpGList->lpGData ); @@ -5971,42 +5982,58 @@ HRESULT dplay_create( REFIID riid, void **ppv )
HRESULT DP_GetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void **lplpData ) { + struct GroupData *group; lpPlayerList lpPlayer;
EnterCriticalSection( &lpDP->lock );
lpPlayer = DP_FindPlayer( lpDP, idPlayer ); - if( lpPlayer == NULL ) + if( lpPlayer ) { + *lplpData = lpPlayer->lpPData->lpSPPlayerData; LeaveCriticalSection( &lpDP->lock ); - return DPERR_INVALIDPLAYER; + return DP_OK; }
- *lplpData = lpPlayer->lpPData->lpSPPlayerData; + group = DP_FindAnyGroup( lpDP, idPlayer ); + if( group ) + { + *lplpData = group->lpSPPlayerData; + LeaveCriticalSection( &lpDP->lock ); + return DP_OK; + }
LeaveCriticalSection( &lpDP->lock );
- return DP_OK; + return DPERR_INVALIDPLAYER; }
HRESULT DP_SetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void *lpData ) { + struct GroupData *group; lpPlayerList lpPlayer;
EnterCriticalSection( &lpDP->lock );
lpPlayer = DP_FindPlayer( lpDP, idPlayer ); - if( lpPlayer == NULL ) + if( lpPlayer ) { + lpPlayer->lpPData->lpSPPlayerData = lpData; LeaveCriticalSection( &lpDP->lock ); - return DPERR_INVALIDPLAYER; + return DP_OK; }
- lpPlayer->lpPData->lpSPPlayerData = lpData; + group = DP_FindAnyGroup( lpDP, idPlayer ); + if( group ) + { + group->lpSPPlayerData = lpData; + LeaveCriticalSection( &lpDP->lock ); + return DP_OK; + }
LeaveCriticalSection( &lpDP->lock );
- return DP_OK; + return DPERR_INVALIDPLAYER; }
/*************************************************************************** diff --git a/dlls/dplayx/dplay_global.h b/dlls/dplayx/dplay_global.h index 360114320fd..74f20977c62 100644 --- a/dlls/dplayx/dplay_global.h +++ b/dlls/dplayx/dplay_global.h @@ -116,6 +116,9 @@ struct GroupData /* View of remote data */ LPVOID lpRemoteData; DWORD dwRemoteDataSize; + + /* SP data on a per player basis */ + LPVOID lpSPPlayerData; }; typedef struct GroupData GroupData; typedef struct GroupData* lpGroupData;
From: Anton Baskanov baskanov@gmail.com
--- dlls/dpwsockx/dpwsockx_dll.h | 10 ++- dlls/dpwsockx/dpwsockx_main.c | 118 +++++++++++++++++++++++++++++----- 2 files changed, 112 insertions(+), 16 deletions(-)
diff --git a/dlls/dpwsockx/dpwsockx_dll.h b/dlls/dpwsockx/dpwsockx_dll.h index 88eb26ae220..12191d4bcdb 100644 --- a/dlls/dpwsockx/dpwsockx_dll.h +++ b/dlls/dpwsockx/dpwsockx_dll.h @@ -25,6 +25,7 @@ #include "winnt.h" #include "wine/dplaysp.h" #include "wine/list.h" +#include "wine/rbtree.h"
#define DPWS_MAXQUEUESIZE 0 #define DPWS_HUNDREDBAUD 0 @@ -75,11 +76,17 @@ struct tagDPWS_IN_CONNECTION
typedef struct { + struct rb_entry entry; SOCKADDR_IN addr;
SOCKET tcpSock; } DPWS_OUT_CONNECTION;
+typedef struct +{ + DPWS_OUT_CONNECTION *connection; +} DPWS_PLAYER; + typedef struct tagDPWS_DATA { LPDIRECTPLAYSP lpISP; @@ -90,7 +97,8 @@ typedef struct tagDPWS_DATA struct list inConnections;
CRITICAL_SECTION sendCs; - DPWS_OUT_CONNECTION nameserverConnection; + DPWS_PLAYER nameserver; + struct rb_tree connections;
BOOL started; HANDLE thread; diff --git a/dlls/dpwsockx/dpwsockx_main.c b/dlls/dpwsockx/dpwsockx_main.c index 74a22751996..5551422253b 100644 --- a/dlls/dpwsockx/dpwsockx_main.c +++ b/dlls/dpwsockx/dpwsockx_main.c @@ -36,6 +36,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(dplay);
static void DPWS_MessageBodyReceiveCompleted( DPWS_IN_CONNECTION *connection );
+static int DPWS_CompareConnections( const void *key, const struct rb_entry *entry ) +{ + DPWS_OUT_CONNECTION *connection = RB_ENTRY_VALUE( entry, DPWS_OUT_CONNECTION, entry ); + SOCKADDR_IN *addr = (SOCKADDR_IN *)key; + + if ( addr->sin_port < connection->addr.sin_port ) + return -1; + if ( addr->sin_port > connection->addr.sin_port ) + return 1; + + if ( addr->sin_addr.s_addr < connection->addr.sin_addr.s_addr ) + return -1; + if ( addr->sin_addr.s_addr > connection->addr.sin_addr.s_addr ) + return 1; + + return 0; +} + static HRESULT DPWS_BindToFreePort( SOCKET sock, SOCKADDR_IN *addr, int startPort, int endPort ) { int port; @@ -319,6 +337,8 @@ static HRESULT DPWS_Start( DPWS_DATA *dpwsData )
list_init( &dpwsData->inConnections );
+ rb_init( &dpwsData->connections, DPWS_CompareConnections ); + dpwsData->stopEvent = WSACreateEvent(); if ( !dpwsData->stopEvent ) { @@ -348,6 +368,8 @@ static HRESULT DPWS_Start( DPWS_DATA *dpwsData )
static void DPWS_Stop( DPWS_DATA *dpwsData ) { + DPWS_OUT_CONNECTION *outConnection2; + DPWS_OUT_CONNECTION *outConnection; DPWS_IN_CONNECTION *inConnection2; DPWS_IN_CONNECTION *inConnection;
@@ -360,8 +382,14 @@ static void DPWS_Stop( DPWS_DATA *dpwsData ) WaitForSingleObject( dpwsData->thread, INFINITE ); CloseHandle( dpwsData->thread );
- if ( dpwsData->nameserverConnection.tcpSock != INVALID_SOCKET ) - closesocket( dpwsData->nameserverConnection.tcpSock ); + RB_FOR_EACH_ENTRY_DESTRUCTOR( outConnection, outConnection2, &dpwsData->connections, + DPWS_OUT_CONNECTION, entry ) + { + rb_remove( &dpwsData->connections, &outConnection->entry ); + if ( outConnection->tcpSock != INVALID_SOCKET ) + closesocket( outConnection->tcpSock ); + free( outConnection ); + }
LIST_FOR_EACH_ENTRY_SAFE( inConnection, inConnection2, &dpwsData->inConnections, DPWS_IN_CONNECTION, entry ) @@ -450,12 +478,39 @@ static HRESULT WINAPI DPWSCB_Send( LPDPSP_SENDDATA data ) return DPERR_UNSUPPORTED; }
+static HRESULT DPWS_GetConnection( DPWS_DATA *dpwsData, SOCKADDR_IN *addr, + DPWS_OUT_CONNECTION **connection ) +{ + struct rb_entry *entry; + + entry = rb_get( &dpwsData->connections, addr ); + if ( entry ) + { + *connection = RB_ENTRY_VALUE( entry, DPWS_OUT_CONNECTION, entry ); + return DP_OK; + } + + *connection = calloc( 1, sizeof( DPWS_OUT_CONNECTION ) ); + if ( !*connection ) + return DPERR_OUTOFMEMORY; + + (*connection)->addr = *addr; + (*connection)->tcpSock = INVALID_SOCKET; + + rb_put( &dpwsData->connections, &(*connection)->addr, &(*connection)->entry ); + + return DP_OK; +} + static HRESULT WINAPI DPWSCB_CreatePlayer( LPDPSP_CREATEPLAYERDATA data ) { + DPWS_PLAYER playerPlaceholder = { 0 }; DPWS_PLAYERDATA *playerData; DWORD playerDataSize; + DPWS_PLAYER *player; DPWS_DATA *dpwsData; DWORD dpwsDataSize; + DWORD playerSize; HRESULT hr;
TRACE( "(%ld,0x%08lx,%p,%p)\n", @@ -498,14 +553,35 @@ static HRESULT WINAPI DPWSCB_CreatePlayer( LPDPSP_CREATEPLAYERDATA data ) playerData->udpAddr.sin_family = AF_INET; }
+ hr = IDirectPlaySP_SetSPPlayerData( data->lpISP, data->idPlayer, (void *) &playerPlaceholder, + sizeof( playerPlaceholder ), DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer, + (void **) &player, &playerSize, DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + if ( data->dwFlags & DPLAYI_PLAYER_PLAYERLOCAL ) + return DP_OK; + + hr = DPWS_GetConnection( dpwsData, &playerData->tcpAddr, &player->connection ); + if ( FAILED( hr ) ) + { + free( player ); + return hr; + } + return DP_OK; }
static HRESULT WINAPI DPWSCB_DeletePlayer( LPDPSP_DELETEPLAYERDATA data ) { - FIXME( "(%ld,0x%08lx,%p) stub\n", + TRACE( "(%ld,0x%08lx,%p)\n", data->idPlayer, data->dwFlags, data->lpISP ); - return DPERR_UNSUPPORTED; + + return DP_OK; }
static HRESULT WINAPI DPWSCB_GetAddress( LPDPSP_GETADDRESSDATA data ) @@ -549,6 +625,7 @@ static HRESULT WINAPI DPWSCB_GetCaps( LPDPSP_GETCAPSDATA data ) static HRESULT WINAPI DPWSCB_Open( LPDPSP_OPENDATA data ) { DPSP_MSG_HEADER *header = (DPSP_MSG_HEADER *) data->lpSPMessageHeader; + SOCKADDR_IN nameserverAddr; DPWS_DATA *dpwsData; DWORD dpwsDataSize; HRESULT hr; @@ -571,11 +648,14 @@ static HRESULT WINAPI DPWSCB_Open( LPDPSP_OPENDATA data ) if ( FAILED (hr) ) return hr;
- dpwsData->nameserverConnection.addr.sin_family = AF_INET; - dpwsData->nameserverConnection.addr.sin_addr = header->SockAddr.sin_addr; - dpwsData->nameserverConnection.addr.sin_port = header->SockAddr.sin_port; + memset( &nameserverAddr, 0, sizeof( nameserverAddr ) ); + nameserverAddr.sin_family = AF_INET; + nameserverAddr.sin_addr = header->SockAddr.sin_addr; + nameserverAddr.sin_port = header->SockAddr.sin_port;
- dpwsData->nameserverConnection.tcpSock = INVALID_SOCKET; + hr = DPWS_GetConnection( dpwsData, &nameserverAddr, &dpwsData->nameserver.connection ); + if ( FAILED( hr ) ) + return hr;
return DP_OK; } @@ -627,6 +707,7 @@ static HRESULT WINAPI DPWSCB_SendEx( LPDPSP_SENDEXDATA data ) { DPWS_OUT_CONNECTION *connection; DPSP_MSG_HEADER header = { 0 }; + DPWS_PLAYER *player; DPWS_DATA *dpwsData; DWORD dpwsDataSize; DWORD transferred; @@ -638,12 +719,6 @@ static HRESULT WINAPI DPWSCB_SendEx( LPDPSP_SENDEXDATA data ) data->dwPriority, data->dwTimeout, data->lpDPContext, data->lpdwSPMsgID, data->bSystemMessage );
- if ( data->idPlayerTo ) - { - FIXME( "only sending to nameserver is currently implemented\n" ); - return DPERR_UNSUPPORTED; - } - if ( !( data->dwFlags & DPSEND_GUARANTEED ) ) { FIXME( "non-guaranteed delivery is not yet supported\n" ); @@ -668,7 +743,20 @@ static HRESULT WINAPI DPWSCB_SendEx( LPDPSP_SENDEXDATA data )
EnterCriticalSection( &dpwsData->sendCs );
- connection = &dpwsData->nameserverConnection; + if ( data->idPlayerTo ) + { + DWORD playerSize; + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayerTo, (void **) &player, + &playerSize, DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + } + else + { + player = &dpwsData->nameserver; + } + + connection = player->connection;
if ( connection->tcpSock == INVALID_SOCKET ) {
From: Anton Baskanov baskanov@gmail.com
--- dlls/dpwsockx/dpwsockx_dll.h | 11 + dlls/dpwsockx/dpwsockx_main.c | 366 ++++++++++++++++++++++++++++------ 2 files changed, 312 insertions(+), 65 deletions(-)
diff --git a/dlls/dpwsockx/dpwsockx_dll.h b/dlls/dpwsockx/dpwsockx_dll.h index 12191d4bcdb..8e83247460d 100644 --- a/dlls/dpwsockx/dpwsockx_dll.h +++ b/dlls/dpwsockx/dpwsockx_dll.h @@ -80,11 +80,21 @@ typedef struct SOCKADDR_IN addr;
SOCKET tcpSock; + WSAOVERLAPPED overlapped; } DPWS_OUT_CONNECTION;
typedef struct { + struct rb_entry entry; + ULONG ref; DPWS_OUT_CONNECTION *connection; +} DPWS_CONNECTION_REF; + +typedef struct +{ + struct rb_entry entry; + DPID id; + struct rb_tree connectionRefs; } DPWS_PLAYER;
typedef struct tagDPWS_DATA @@ -98,6 +108,7 @@ typedef struct tagDPWS_DATA
CRITICAL_SECTION sendCs; DPWS_PLAYER nameserver; + DPWS_CONNECTION_REF nameserverConnectionRef; struct rb_tree connections;
BOOL started; diff --git a/dlls/dpwsockx/dpwsockx_main.c b/dlls/dpwsockx/dpwsockx_main.c index 5551422253b..678706a79cd 100644 --- a/dlls/dpwsockx/dpwsockx_main.c +++ b/dlls/dpwsockx/dpwsockx_main.c @@ -54,6 +54,13 @@ static int DPWS_CompareConnections( const void *key, const struct rb_entry *entr return 0; }
+static int DPWS_CompareConnectionRefs( const void *key, const struct rb_entry *entry ) +{ + DPWS_CONNECTION_REF *connectionRef = RB_ENTRY_VALUE( entry, DPWS_CONNECTION_REF, entry ); + + return DPWS_CompareConnections( key, &connectionRef->connection->entry ); +} + static HRESULT DPWS_BindToFreePort( SOCKET sock, SOCKADDR_IN *addr, int startPort, int endPort ) { int port; @@ -478,6 +485,75 @@ static HRESULT WINAPI DPWSCB_Send( LPDPSP_SENDDATA data ) return DPERR_UNSUPPORTED; }
+static HRESULT WINAPI DPWSCB_AddPlayerToGroup( DPSP_ADDPLAYERTOGROUPDATA *data ) +{ + DPWS_CONNECTION_REF *playerConnectionRef; + DPWS_CONNECTION_REF *groupConnectionRef; + struct rb_entry *entry; + DPWS_PLAYER *player; + DPWS_PLAYER *group; + DWORD playerSize; + DWORD groupSize; + HRESULT hr; + + TRACE( "(%ld,%ld,%p)\n", data->idPlayer, data->idGroup, data->lpISP ); + + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer, (void **) &player, &playerSize, + DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroup, (void **) &group, &groupSize, + DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + RB_FOR_EACH_ENTRY( playerConnectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry ) + { + entry = rb_get( &group->connectionRefs, &playerConnectionRef->connection->addr ); + if ( entry ) + { + groupConnectionRef = RB_ENTRY_VALUE( entry, DPWS_CONNECTION_REF, entry ); + ++groupConnectionRef->ref; + continue; + } + groupConnectionRef = calloc( 1, sizeof( DPWS_CONNECTION_REF ) ); + if ( !groupConnectionRef ) + return DPERR_OUTOFMEMORY; + groupConnectionRef->ref = 1; + groupConnectionRef->connection = playerConnectionRef->connection; + rb_put( &group->connectionRefs, &groupConnectionRef->connection->addr, + &groupConnectionRef->entry ); + } + + return DP_OK; +} + +static HRESULT WINAPI DPWSCB_CreateGroup( DPSP_CREATEGROUPDATA *data ) +{ + DPWS_PLAYER groupPlaceholder = { 0 }; + DPWS_PLAYER *group; + DWORD groupSize; + HRESULT hr; + + TRACE( "(%ld,0x%08lx,%p,%p)\n", data->idGroup, data->dwFlags, data->lpSPMessageHeader, + data->lpISP ); + + hr = IDirectPlaySP_SetSPPlayerData( data->lpISP, data->idGroup, &groupPlaceholder, + sizeof( groupPlaceholder ), DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroup, (void **) &group, &groupSize, + DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + rb_init( &group->connectionRefs, DPWS_CompareConnectionRefs ); + + return DP_OK; +} + static HRESULT DPWS_GetConnection( DPWS_DATA *dpwsData, SOCKADDR_IN *addr, DPWS_OUT_CONNECTION **connection ) { @@ -504,6 +580,7 @@ static HRESULT DPWS_GetConnection( DPWS_DATA *dpwsData, SOCKADDR_IN *addr,
static HRESULT WINAPI DPWSCB_CreatePlayer( LPDPSP_CREATEPLAYERDATA data ) { + DPWS_CONNECTION_REF *tcpConnectionRef; DPWS_PLAYER playerPlaceholder = { 0 }; DPWS_PLAYERDATA *playerData; DWORD playerDataSize; @@ -563,24 +640,82 @@ static HRESULT WINAPI DPWSCB_CreatePlayer( LPDPSP_CREATEPLAYERDATA data ) if ( FAILED( hr ) ) return hr;
+ rb_init( &player->connectionRefs, DPWS_CompareConnectionRefs ); + if ( data->dwFlags & DPLAYI_PLAYER_PLAYERLOCAL ) return DP_OK;
- hr = DPWS_GetConnection( dpwsData, &playerData->tcpAddr, &player->connection ); + tcpConnectionRef = calloc( 1, sizeof( DPWS_CONNECTION_REF ) ); + if ( !tcpConnectionRef ) + { + free( player ); + return DPERR_OUTOFMEMORY; + } + + tcpConnectionRef->ref = 1; + + hr = DPWS_GetConnection( dpwsData, &playerData->tcpAddr, &tcpConnectionRef->connection ); if ( FAILED( hr ) ) { + free( tcpConnectionRef ); free( player ); return hr; }
+ rb_put( &player->connectionRefs, &tcpConnectionRef->connection->addr, + &tcpConnectionRef->entry ); + + return DP_OK; +} + +static HRESULT WINAPI DPWSCB_DeleteGroup( DPSP_DELETEGROUPDATA *data ) +{ + DPWS_CONNECTION_REF *connectionRef2; + DPWS_CONNECTION_REF *connectionRef; + DPWS_PLAYER *group; + DWORD groupSize; + HRESULT hr; + + TRACE( "(%ld,0x%08lx,%p)\n", data->idGroup, data->dwFlags, data->lpISP ); + + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroup, (void **) &group, &groupSize, + DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + RB_FOR_EACH_ENTRY_DESTRUCTOR( connectionRef, connectionRef2, &group->connectionRefs, + DPWS_CONNECTION_REF, entry ) + { + rb_remove( &group->connectionRefs, &connectionRef->entry ); + free( connectionRef ); + } + return DP_OK; }
static HRESULT WINAPI DPWSCB_DeletePlayer( LPDPSP_DELETEPLAYERDATA data ) { + DPWS_CONNECTION_REF *connectionRef2; + DPWS_CONNECTION_REF *connectionRef; + DPWS_PLAYER *player; + DWORD playerSize; + HRESULT hr; + TRACE( "(%ld,0x%08lx,%p)\n", data->idPlayer, data->dwFlags, data->lpISP );
+ hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer, (void **) &player, &playerSize, + DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + RB_FOR_EACH_ENTRY_DESTRUCTOR( connectionRef, connectionRef2, &player->connectionRefs, + DPWS_CONNECTION_REF, entry ) + { + rb_remove( &player->connectionRefs, &connectionRef->entry ); + free( connectionRef ); + } + return DP_OK; }
@@ -653,10 +788,56 @@ static HRESULT WINAPI DPWSCB_Open( LPDPSP_OPENDATA data ) nameserverAddr.sin_addr = header->SockAddr.sin_addr; nameserverAddr.sin_port = header->SockAddr.sin_port;
- hr = DPWS_GetConnection( dpwsData, &nameserverAddr, &dpwsData->nameserver.connection ); + rb_init( &dpwsData->nameserver.connectionRefs, DPWS_CompareConnectionRefs ); + + hr = DPWS_GetConnection( dpwsData, &nameserverAddr, + &dpwsData->nameserverConnectionRef.connection ); + if ( FAILED( hr ) ) + return hr; + + rb_put( &dpwsData->nameserver.connectionRefs, + &dpwsData->nameserverConnectionRef.connection->addr, + &dpwsData->nameserverConnectionRef.entry ); + + return DP_OK; +} + +static HRESULT WINAPI DPWSCB_RemovePlayerFromGroup( DPSP_REMOVEPLAYERFROMGROUPDATA *data ) +{ + DPWS_CONNECTION_REF *playerConnectionRef; + DPWS_CONNECTION_REF *groupConnectionRef; + struct rb_entry *entry; + DPWS_PLAYER *player; + DPWS_PLAYER *group; + DWORD playerSize; + DWORD groupSize; + HRESULT hr; + + TRACE( "(%ld,%ld,%p)\n", data->idPlayer, data->idGroup, data->lpISP ); + + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer, (void **) &player, &playerSize, + DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroup, (void **) &group, &groupSize, + DPSET_LOCAL ); if ( FAILED( hr ) ) return hr;
+ RB_FOR_EACH_ENTRY( playerConnectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry ) + { + entry = rb_get( &group->connectionRefs, &playerConnectionRef->connection->addr ); + if ( !entry ) + continue; + groupConnectionRef = RB_ENTRY_VALUE( entry, DPWS_CONNECTION_REF, entry ); + --groupConnectionRef->ref; + if ( groupConnectionRef->ref ) + continue; + rb_remove( &player->connectionRefs, &groupConnectionRef->entry ); + free( groupConnectionRef ); + } + return DP_OK; }
@@ -703,14 +884,99 @@ static HRESULT WINAPI DPWSCB_GetAddressChoices( LPDPSP_GETADDRESSCHOICESDATA dat return DPERR_UNSUPPORTED; }
-static HRESULT WINAPI DPWSCB_SendEx( LPDPSP_SENDEXDATA data ) +static HRESULT DPWS_SendImpl( DPWS_DATA *dpwsData, DPWS_PLAYER *player, SGBUFFER *buffers, + DWORD bufferCount, DWORD messageSize ) { - DPWS_OUT_CONNECTION *connection; + DPWS_CONNECTION_REF *connectionRef; DPSP_MSG_HEADER header = { 0 }; + HRESULT sendResult; + + header.mixed = DPSP_MSG_MAKE_MIXED( messageSize, DPSP_MSG_TOKEN_REMOTE ); + header.SockAddr.sin_family = AF_INET; + header.SockAddr.sin_port = dpwsData->tcpAddr.sin_port; + + buffers[ 0 ].pData = (unsigned char *) &header; + + EnterCriticalSection( &dpwsData->sendCs ); + + RB_FOR_EACH_ENTRY( connectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry ) + { + DPWS_OUT_CONNECTION *connection = connectionRef->connection; + + if ( connection->tcpSock != INVALID_SOCKET ) + continue; + + connection->tcpSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); + if ( connection->tcpSock == INVALID_SOCKET ) + { + ERR( "socket() failed\n" ); + LeaveCriticalSection( &dpwsData->sendCs ); + return DPERR_UNAVAILABLE; + } + + if ( SOCKET_ERROR == connect( connection->tcpSock, (SOCKADDR *) &connection->addr, + sizeof( connection->addr ) ) ) + { + ERR( "connect() failed\n" ); + closesocket( connection->tcpSock ); + connection->tcpSock = INVALID_SOCKET; + LeaveCriticalSection( &dpwsData->sendCs ); + return DPERR_UNAVAILABLE; + } + } + + RB_FOR_EACH_ENTRY( connectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry ) + { + DPWS_OUT_CONNECTION *connection = connectionRef->connection; + DWORD transferred; + + if ( SOCKET_ERROR == WSASend( connection->tcpSock, (WSABUF *) buffers, bufferCount, + &transferred, 0, &connection->overlapped, NULL ) ) + { + if ( WSAGetLastError() != WSA_IO_PENDING ) + { + ERR( "WSASend() failed\n" ); + LeaveCriticalSection( &dpwsData->sendCs ); + return DPERR_UNAVAILABLE; + } + } + } + + sendResult = DP_OK; + + RB_FOR_EACH_ENTRY( connectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry ) + { + DPWS_OUT_CONNECTION *connection = connectionRef->connection; + DWORD transferred; + + if ( !WSAGetOverlappedResult( connection->tcpSock, &connection->overlapped, &transferred, + TRUE, NULL ) ) + { + ERR( "WSAGetOverlappedResult() failed\n" ); + sendResult = DPERR_UNAVAILABLE; + continue; + } + + if ( transferred < messageSize ) + { + ERR( "lost connection\n" ); + closesocket( connection->tcpSock ); + connection->tcpSock = INVALID_SOCKET; + sendResult = DPERR_CONNECTIONLOST; + continue; + } + } + + LeaveCriticalSection( &dpwsData->sendCs ); + + return sendResult; +} + +static HRESULT WINAPI DPWSCB_SendEx( LPDPSP_SENDEXDATA data ) +{ DPWS_PLAYER *player; DPWS_DATA *dpwsData; DWORD dpwsDataSize; - DWORD transferred; HRESULT hr;
TRACE( "(%p,0x%08lx,%ld,%ld,%p,%ld,%ld,%ld,%ld,%p,%p,%u)\n", @@ -735,14 +1001,6 @@ static HRESULT WINAPI DPWSCB_SendEx( LPDPSP_SENDEXDATA data ) if ( FAILED( hr ) ) return hr;
- header.mixed = DPSP_MSG_MAKE_MIXED( data->dwMessageSize, DPSP_MSG_TOKEN_REMOTE ); - header.SockAddr.sin_family = AF_INET; - header.SockAddr.sin_port = dpwsData->tcpAddr.sin_port; - - data->lpSendBuffers[ 0 ].pData = (unsigned char *) &header; - - EnterCriticalSection( &dpwsData->sendCs ); - if ( data->idPlayerTo ) { DWORD playerSize; @@ -756,62 +1014,40 @@ static HRESULT WINAPI DPWSCB_SendEx( LPDPSP_SENDEXDATA data ) player = &dpwsData->nameserver; }
- connection = player->connection; - - if ( connection->tcpSock == INVALID_SOCKET ) - { - connection->tcpSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); - if ( connection->tcpSock == INVALID_SOCKET ) - { - ERR( "socket() failed\n" ); - LeaveCriticalSection( &dpwsData->sendCs ); - return DPERR_UNAVAILABLE; - } - - if ( SOCKET_ERROR == connect( connection->tcpSock, (SOCKADDR *) &connection->addr, - sizeof( connection->addr ) ) ) - { - ERR( "connect() failed\n" ); - closesocket( connection->tcpSock ); - connection->tcpSock = INVALID_SOCKET; - LeaveCriticalSection( &dpwsData->sendCs ); - return DPERR_UNAVAILABLE; - } - } - - if ( SOCKET_ERROR == WSASend( connection->tcpSock, (WSABUF *) data->lpSendBuffers, - data->cBuffers, &transferred, 0, NULL, NULL ) ) - { - if ( WSAGetLastError() != WSA_IO_PENDING ) - { - ERR( "WSASend() failed\n" ); - LeaveCriticalSection( &dpwsData->sendCs ); - return DPERR_UNAVAILABLE; - } - } - - if ( transferred < data->dwMessageSize ) - { - ERR( "lost connection\n" ); - closesocket( connection->tcpSock ); - connection->tcpSock = INVALID_SOCKET; - LeaveCriticalSection( &dpwsData->sendCs ); - return DPERR_CONNECTIONLOST; - } - - LeaveCriticalSection( &dpwsData->sendCs ); - - return DP_OK; + return DPWS_SendImpl( dpwsData, player, data->lpSendBuffers, data->cBuffers, + data->dwMessageSize ); }
static HRESULT WINAPI DPWSCB_SendToGroupEx( LPDPSP_SENDTOGROUPEXDATA data ) { - FIXME( "(%p,0x%08lx,%ld,%ld,%p,%ld,%ld,%ld,%ld,%p,%p) stub\n", + DPWS_DATA *dpwsData; + DPWS_PLAYER *group; + DWORD dpwsDataSize; + DWORD groupSize; + HRESULT hr; + + TRACE( "(%p,0x%08lx,%ld,%ld,%p,%ld,%ld,%ld,%ld,%p,%p)\n", data->lpISP, data->dwFlags, data->idGroupTo, data->idPlayerFrom, data->lpSendBuffers, data->cBuffers, data->dwMessageSize, data->dwPriority, data->dwTimeout, data->lpDPContext, data->lpdwSPMsgID ); - return DPERR_UNSUPPORTED; + + if ( data->dwFlags & DPSEND_ASYNC ) + { + FIXME("asynchronous send is not yet supported\n"); + return DPERR_UNSUPPORTED; + } + + hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroupTo, (void **) &group, &groupSize, + DPSET_LOCAL ); + if ( FAILED( hr ) ) + return hr; + + return DPWS_SendImpl( dpwsData, group, data->lpSendBuffers, data->cBuffers, data->dwMessageSize ); }
static HRESULT WINAPI DPWSCB_Cancel( LPDPSP_CANCELDATA data ) @@ -835,11 +1071,15 @@ static void setup_callbacks( LPDPSP_SPCALLBACKS lpCB ) lpCB->EnumSessions = DPWSCB_EnumSessions; lpCB->Reply = DPWSCB_Reply; lpCB->Send = DPWSCB_Send; + lpCB->AddPlayerToGroup = DPWSCB_AddPlayerToGroup; + lpCB->CreateGroup = DPWSCB_CreateGroup; lpCB->CreatePlayer = DPWSCB_CreatePlayer; + lpCB->DeleteGroup = DPWSCB_DeleteGroup; lpCB->DeletePlayer = DPWSCB_DeletePlayer; lpCB->GetAddress = DPWSCB_GetAddress; lpCB->GetCaps = DPWSCB_GetCaps; lpCB->Open = DPWSCB_Open; + lpCB->RemovePlayerFromGroup = DPWSCB_RemovePlayerFromGroup; lpCB->CloseEx = DPWSCB_CloseEx; lpCB->ShutdownEx = DPWSCB_ShutdownEx; lpCB->GetAddressChoices = DPWSCB_GetAddressChoices; @@ -848,11 +1088,7 @@ static void setup_callbacks( LPDPSP_SPCALLBACKS lpCB ) lpCB->Cancel = DPWSCB_Cancel; lpCB->GetMessageQueue = DPWSCB_GetMessageQueue;
- lpCB->AddPlayerToGroup = NULL; lpCB->Close = NULL; - lpCB->CreateGroup = NULL; - lpCB->DeleteGroup = NULL; - lpCB->RemovePlayerFromGroup = NULL; lpCB->SendToGroup = NULL; lpCB->Shutdown = NULL; }
From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 39 +++++----- dlls/dplayx/dplay_global.h | 2 +- dlls/dplayx/dplayx_messages.c | 90 +++++++++++++++++++++- dlls/dplayx/dplayx_messages.h | 8 ++ dlls/dplayx/tests/dplayx.c | 138 +++++++++++++++------------------- 5 files changed, 179 insertions(+), 98 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 9f1153fed19..4662bdb3192 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -424,7 +424,7 @@ HRESULT DP_HandleMessage( IDirectPlayImpl *This, void *messageBody, hr = DP_CreatePlayer( This, messageHeader, &msg->playerId, &playerInfo.name, playerInfo.playerData, playerInfo.playerDataLength, playerInfo.spData, playerInfo.spDataLength, playerInfo.flags & ~DPLAYI_PLAYER_PLAYERLOCAL, - NULL, FALSE ); + NULL, NULL, FALSE ); if ( FAILED( hr ) ) { LeaveCriticalSection( &This->lock ); @@ -1494,7 +1494,7 @@ static HRESULT DP_CreateSPPlayer( IDirectPlayImpl *This, DPID dpid, DWORD flags,
HRESULT DP_CreatePlayer( IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPNAME *lpName, void *data, DWORD dataSize, void *spData, DWORD spDataSize, DWORD dwFlags, HANDLE hEvent, - BOOL bAnsi ) + struct PlayerData **playerData, BOOL bAnsi ) { lpPlayerData lpPData; lpPlayerList lpPList; @@ -1597,6 +1597,9 @@ HRESULT DP_CreatePlayer( IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPN if( ~dwFlags & DPLAYI_PLAYER_SYSPLAYER ) This->dp2->lpSessionDesc->dwCurrentPlayers++;
+ if( playerData ) + *playerData = lpPData; + return DP_OK; }
@@ -1738,6 +1741,7 @@ static HRESULT DP_IF_CreatePlayer( IDirectPlayImpl *This, DPID *lpidPlayer, DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi ) { + struct PlayerData *player; HRESULT hr = DP_OK; DWORD dwCreateFlags = 0;
@@ -1816,27 +1820,20 @@ static HRESULT DP_IF_CreatePlayer( IDirectPlayImpl *This, DPID *lpidPlayer, /* We pass creation flags, so we can distinguish sysplayers and not count them in the current player total */ hr = DP_CreatePlayer( This, NULL, lpidPlayer, lpPlayerName, lpData, dwDataSize, NULL, 0, - dwCreateFlags, hEvent, bAnsi ); - - LeaveCriticalSection( &This->lock ); - + dwCreateFlags, hEvent, &player, bAnsi ); if( FAILED( hr ) ) + { + LeaveCriticalSection( &This->lock ); return hr; + }
#if 1 - if( !This->dp2->bHostInterface ) + hr = DP_MSG_SendCreatePlayer( This, DPID_ALLPLAYERS, *lpidPlayer, dwCreateFlags, player->name, + lpData, dwDataSize, This->dp2->systemPlayerId ); + if( FAILED( hr ) ) { - /* Let the name server know about the creation of this player */ - /* FIXME: Is this only to be done for the creation of a server player or - * is this used for regular players? If only for server players, move - * this call to DP_SecureOpen(...); - */ -#if 0 - TRACE( "Sending message to self to get my addr\n" ); - DP_MSG_ToSelf( This, *lpidPlayer ); /* This is a hack right now */ -#endif - - hr = DP_MSG_ForwardPlayerCreation( This, *lpidPlayer, NULL ); + LeaveCriticalSection( &This->lock ); + return hr; } #else /* Inform all other peers of the creation of a new player. If there are @@ -1867,6 +1864,8 @@ static HRESULT DP_IF_CreatePlayer( IDirectPlayImpl *This, DPID *lpidPlayer, } #endif
+ LeaveCriticalSection( &This->lock ); + return hr; }
@@ -3529,7 +3528,7 @@ static HRESULT DP_SecureOpen( IDirectPlayImpl *This, const DPSESSIONDESC2 *lpsd, * while bConnectionOpen is FALSE. */
hr = DP_CreatePlayer( This, NULL, &This->dp2->systemPlayerId, NULL, NULL, 0, NULL, 0, - createFlags, NULL, bAnsi ); + createFlags, NULL, NULL, bAnsi ); if( FAILED( hr ) ) { free( password ); @@ -3565,7 +3564,7 @@ static HRESULT DP_SecureOpen( IDirectPlayImpl *This, const DPSESSIONDESC2 *lpsd, This->dp2->systemPlayerId = DP_NextObjectId();
hr = DP_CreatePlayer( This, NULL, &This->dp2->systemPlayerId, NULL, NULL, 0, NULL, 0, - createFlags, NULL, bAnsi ); + createFlags, NULL, NULL, bAnsi ); if( FAILED( hr ) ) { DP_IF_DestroyGroup( This, NULL, DPID_SYSTEM_GROUP, TRUE ); diff --git a/dlls/dplayx/dplay_global.h b/dlls/dplayx/dplay_global.h index 74f20977c62..ebdb81f0a98 100644 --- a/dlls/dplayx/dplay_global.h +++ b/dlls/dplayx/dplay_global.h @@ -210,7 +210,7 @@ HRESULT DP_HandleMessage( IDirectPlayImpl *This, void *messageBody, DPSESSIONDESC2 *DP_DuplicateSessionDesc( const DPSESSIONDESC2 *src, BOOL dstAnsi, BOOL srcAnsi ); HRESULT DP_CreatePlayer( IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPNAME *lpName, void *data, DWORD dataSize, void *spData, DWORD spDataSize, DWORD dwFlags, - HANDLE hEvent, BOOL bAnsi ); + HANDLE hEvent, struct PlayerData **playerData, BOOL bAnsi );
/* DP SP external interfaces into DirectPlay */ extern HRESULT DP_GetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void **lplpData ); diff --git a/dlls/dplayx/dplayx_messages.c b/dlls/dplayx/dplayx_messages.c index 6f71f04440d..52aea44a17f 100644 --- a/dlls/dplayx/dplayx_messages.c +++ b/dlls/dplayx/dplayx_messages.c @@ -668,7 +668,7 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlayImpl *This, DPID dpidServer, WC hr = DP_CreatePlayer( This, msgHeader, &playerInfo.id, &playerInfo.name, playerInfo.playerData, playerInfo.playerDataLength, playerInfo.spData, playerInfo.spDataLength, playerInfo.flags & ~DPLAYI_PLAYER_PLAYERLOCAL, NULL, - FALSE ); + NULL, FALSE ); if( FAILED( hr ) ) { free( msgHeader ); @@ -707,6 +707,94 @@ HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlayImpl *This, DPID dpidServer, WC return hr; }
+HRESULT DP_MSG_SendCreatePlayer( IDirectPlayImpl *This, DPID toId, DPID id, DWORD flags, + DPNAME *name, void *playerData, DWORD playerDataSize, + DPID systemPlayerId ) +{ + DPSP_SENDTOGROUPEXDATA sendData; + DPLAYI_PACKEDPLAYER playerInfo; + SGBUFFER buffers[ 8 ] = { 0 }; + UCHAR reserved[ 6 ] = { 0 }; + DWORD shortNameLength = 0; + DWORD longNameLength = 0; + DPMSG_CREATESESSION msg; + DWORD spPlayerDataSize; + void *spPlayerData; + HRESULT hr; + + hr = IDirectPlaySP_GetSPPlayerData( This->dp2->spData.lpISP, id, &spPlayerData, &spPlayerDataSize, + DPSET_REMOTE ); + if( FAILED( hr ) ) + return hr; + + if ( name->lpszShortName ) + shortNameLength = ( lstrlenW( name->lpszShortName ) + 1 ) * sizeof( WCHAR ); + + if ( name->lpszLongName ) + longNameLength = ( lstrlenW( name->lpszLongName ) + 1 ) * sizeof( WCHAR ); + + msg.envelope.dwMagic = DPMSGMAGIC_DPLAYMSG; + msg.envelope.wCommandId = DPMSGCMD_CREATESESSION; + msg.envelope.wVersion = DPMSGVER_DP6; + msg.toId = 0; + msg.playerId = id; + msg.groupId = 0; + msg.createOffset = sizeof( DPMSG_CREATESESSION ); + msg.passwordOffset = 0; + + playerInfo.size = sizeof( DPLAYI_PACKEDPLAYER ) + shortNameLength + longNameLength + + spPlayerDataSize + playerDataSize; + playerInfo.flags = flags; + playerInfo.id = id; + playerInfo.shortNameLength = shortNameLength; + playerInfo.longNameLength = longNameLength; + playerInfo.spDataLength = spPlayerDataSize; + playerInfo.playerDataLength = playerDataSize; + playerInfo.playerCount = 0; + playerInfo.systemPlayerId = systemPlayerId; + playerInfo.fixedSize = sizeof( DPLAYI_PACKEDPLAYER ); + playerInfo.version = DPMSGVER_DP6; + playerInfo.parentId = 0; + + buffers[ 0 ].len = This->dp2->spData.dwSPHeaderSize; + buffers[ 0 ].pData = NULL; + buffers[ 1 ].len = sizeof( msg ); + buffers[ 1 ].pData = (UCHAR *)&msg; + buffers[ 2 ].len = sizeof( playerInfo ); + buffers[ 2 ].pData = (UCHAR *)&playerInfo; + buffers[ 3 ].len = shortNameLength; + buffers[ 3 ].pData = (UCHAR *)name->lpszShortName; + buffers[ 4 ].len = longNameLength; + buffers[ 4 ].pData = (UCHAR *)name->lpszLongName; + buffers[ 5 ].len = spPlayerDataSize; + buffers[ 5 ].pData = spPlayerData; + buffers[ 6 ].len = playerDataSize; + buffers[ 6 ].pData = playerData; + buffers[ 7 ].len = sizeof( reserved ); + buffers[ 7 ].pData = reserved; + + sendData.lpISP = This->dp2->spData.lpISP; + sendData.dwFlags = DPSEND_GUARANTEED; + sendData.idGroupTo = toId; + sendData.idPlayerFrom = This->dp2->systemPlayerId; + sendData.lpSendBuffers = buffers; + sendData.cBuffers = ARRAYSIZE( buffers ); + sendData.dwMessageSize = DP_MSG_ComputeMessageSize( sendData.lpSendBuffers, sendData.cBuffers ); + sendData.dwPriority = 0; + sendData.dwTimeout = 0; + sendData.lpDPContext = NULL; + sendData.lpdwSPMsgID = NULL; + + hr = (*This->dp2->spData.lpCB->SendToGroupEx)( &sendData ); + if( FAILED( hr ) ) + { + ERR( "SendToGroupEx failed: %s\n", DPLAYX_HresultToString( hr ) ); + return hr; + } + + return DP_OK; +} + HRESULT DP_MSG_SendAddForwardAck( IDirectPlayImpl *This, DPID id ) { SGBUFFER buffers[ 2 ] = { 0 }; diff --git a/dlls/dplayx/dplayx_messages.h b/dlls/dplayx/dplayx_messages.h index 1ce1fc5ba09..37f3ce0a1bd 100644 --- a/dlls/dplayx/dplayx_messages.h +++ b/dlls/dplayx/dplayx_messages.h @@ -53,6 +53,9 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlayImpl *This, DWORD dwFlags, HRESULT DP_MSG_ReadPackedPlayer( char *data, DWORD *offset, DWORD maxSize, DPPLAYERINFO *playerInfo ); HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlayImpl *This, DPID dpidServer, WCHAR *password ); +HRESULT DP_MSG_SendCreatePlayer( IDirectPlayImpl *This, DPID toId, DPID id, DWORD flags, + DPNAME *name, void *playerData, DWORD playerDataSize, + DPID systemPlayerId ); HRESULT DP_MSG_SendAddForwardAck( IDirectPlayImpl *This, DPID id );
void DP_MSG_ReplyReceived( IDirectPlayImpl *This, WORD wCommandId, @@ -193,6 +196,11 @@ typedef const DPMSG_ENUMSESSIONSREQUEST* LPCDPMSG_ENUMSESSIONSREQUEST; typedef struct tagDPMSG_CREATESESSION { DPMSG_SENDENVELOPE envelope; + DPID toId; + DPID playerId; + DPID groupId; + DWORD createOffset; + DWORD passwordOffset; } DPMSG_CREATESESSION, *LPDPMSG_CREATESESSION; typedef const DPMSG_CREATESESSION* LPCDPMSG_CREATESESSION;
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index c92de4cfcdc..27f4e2f4579 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -1114,11 +1114,10 @@ static void checkNoMoreMessages_( int line, SOCKET sock ) ok_( __FILE__, line )( !wsResult || wsResult == SOCKET_ERROR, "recv() returned %d.\n", wsResult ); }
-#define checkSpHeader( header, expectedSize, sizeTodo ) checkSpHeader_( __LINE__, header, expectedSize, sizeTodo ) -static unsigned short checkSpHeader_( int line, SpHeader *header, DWORD expectedSize, BOOL sizeTodo ) +#define checkSpHeader( header, expectedSize ) checkSpHeader_( __LINE__, header, expectedSize ) +static unsigned short checkSpHeader_( int line, SpHeader *header, DWORD expectedSize ) { - todo_wine_if( sizeTodo ) ok_( __FILE__, line )( header->mixed == 0xfab00000 + expectedSize, "got mixed %#lx.\n", - header->mixed ); + ok_( __FILE__, line )( header->mixed == 0xfab00000 + expectedSize, "got mixed %#lx.\n", header->mixed ); ok_( __FILE__, line )( header->addr.sin_family == AF_INET, "got family %d.\n", header->addr.sin_family ); ok_( __FILE__, line )( 2300 <= ntohs( header->addr.sin_port ) && ntohs( header->addr.sin_port ) < 2350, "got port %d.\n", ntohs( header->addr.sin_port ) ); @@ -1127,12 +1126,11 @@ static unsigned short checkSpHeader_( int line, SpHeader *header, DWORD expected return ntohs( header->addr.sin_port ); }
-#define checkMessageHeader( header, expectedCommand, commandTodo ) checkMessageHeader_( __LINE__, header, expectedCommand, commandTodo ) -static void checkMessageHeader_( int line, MessageHeader *header, WORD expectedCommand, BOOL commandTodo ) +#define checkMessageHeader( header, expectedCommand ) checkMessageHeader_( __LINE__, header, expectedCommand ) +static void checkMessageHeader_( int line, MessageHeader *header, WORD expectedCommand ) { ok_( __FILE__, line )( header->magic == 0x79616c70, "got magic %#lx.\n", header->magic ); - todo_wine_if( commandTodo ) ok_( __FILE__, line )( header->command == expectedCommand, "got command %d.\n", - header->command ); + ok_( __FILE__, line )( header->command == expectedCommand, "got command %d.\n", header->command ); }
#define checkSpData( spData ) checkSpData_( __LINE__, spData ) @@ -1151,34 +1149,30 @@ static void checkSpData_( int line, SpData *spData ) }
#define checkPackedPlayer( player, expectedFlags, expectedId, expectedShortNameLength, expectedLongNameLength, \ - expectedPlayerDataSize, expectedSystemPlayerId, flagsTodo, nameTodo, playerDataTodo, \ - systemPlayerIdTodo ) \ + expectedPlayerDataSize, expectedSystemPlayerId, flagsTodo ) \ checkPackedPlayer_( __LINE__, player, expectedFlags, expectedId, expectedShortNameLength, expectedLongNameLength, \ - expectedPlayerDataSize, expectedSystemPlayerId, flagsTodo, nameTodo, playerDataTodo, \ - systemPlayerIdTodo ) + expectedPlayerDataSize, expectedSystemPlayerId, flagsTodo ) static void checkPackedPlayer_( int line, PackedPlayer *player, DWORD expectedFlags, DPID expectedId, DWORD expectedShortNameLength, DWORD expectedLongNameLength, - DWORD expectedPlayerDataSize, DPID expectedSystemPlayerId, BOOL flagsTodo, - BOOL nameTodo, BOOL playerDataTodo, BOOL systemPlayerIdTodo ) + DWORD expectedPlayerDataSize, DPID expectedSystemPlayerId, BOOL flagsTodo ) { DWORD expectedSize = sizeof( PackedPlayer ) + expectedShortNameLength + expectedLongNameLength + sizeof( SpData ) + expectedPlayerDataSize;
- todo_wine_if( nameTodo || playerDataTodo ) ok_( __FILE__, line )( player->size == expectedSize, - "got player info size %lu.\n", player->size ); + ok_( __FILE__, line )( player->size == expectedSize, "got player info size %lu.\n", player->size ); todo_wine_if( flagsTodo ) ok_( __FILE__, line )( player->flags == expectedFlags, "got flags %#lx.\n", player->flags ); ok_( __FILE__, line )( player->id == expectedId, "got player info player id %#lx.\n", player->id ); - todo_wine_if( nameTodo ) ok_( __FILE__, line )( player->shortNameLength == expectedShortNameLength, - "got short name length %lu.\n", player->shortNameLength ); - todo_wine_if( nameTodo ) ok_( __FILE__, line )( player->longNameLength == expectedLongNameLength, - "got long name length %lu.\n", player->longNameLength ); + ok_( __FILE__, line )( player->shortNameLength == expectedShortNameLength, "got short name length %lu.\n", + player->shortNameLength ); + ok_( __FILE__, line )( player->longNameLength == expectedLongNameLength, "got long name length %lu.\n", + player->longNameLength ); ok_( __FILE__, line )( player->spDataSize == sizeof( SpData ), "got SP data size %lu.\n", player->spDataSize ); - todo_wine_if( playerDataTodo ) ok_( __FILE__, line )( player->playerDataSize == expectedPlayerDataSize, - "got player data size %lu.\n", player->playerDataSize ); + ok_( __FILE__, line )( player->playerDataSize == expectedPlayerDataSize, "got player data size %lu.\n", + player->playerDataSize ); ok_( __FILE__, line )( !player->playerCount, "got player count %lu.\n", player->playerCount ); - todo_wine_if( systemPlayerIdTodo ) ok_( __FILE__, line )( player->systemPlayerId == expectedSystemPlayerId, - "got system player id %#lx.\n", player->systemPlayerId ); + ok_( __FILE__, line )( player->systemPlayerId == expectedSystemPlayerId, "got system player id %#lx.\n", + player->systemPlayerId ); ok_( __FILE__, line )( player->fixedSize == sizeof( PackedPlayer ), "got fixed size %lu.\n", player->fixedSize ); ok_( __FILE__, line )( !player->parentId, "got parent id %#lx.\n", player->parentId ); } @@ -1207,8 +1201,8 @@ static unsigned short receiveEnumSessionsRequest_( int line, SOCKET sock, const if ( wsResult == SOCKET_ERROR ) return 0;
- port = checkSpHeader_( line, &request.spHeader, expectedSize, FALSE ); - checkMessageHeader_( line, &request.request.header, 2, FALSE ); + port = checkSpHeader_( line, &request.spHeader, expectedSize ); + checkMessageHeader_( line, &request.request.header, 2 ); ok_( __FILE__, line )( IsEqualGUID( &request.request.appGuid, expectedAppGuid ), "got app guid %s.\n", wine_dbgstr_guid( &request.request.appGuid ) ); if ( expectedPassword ) @@ -1289,8 +1283,8 @@ static unsigned short receiveRequestPlayerId_( int line, SOCKET sock, DWORD expe wsResult = receiveMessage_( line, sock, &request, sizeof( request ) ); ok_( __FILE__, line )( wsResult == sizeof( request ), "recv() returned %d.\n", wsResult );
- port = checkSpHeader_( line, &request.spHeader, sizeof( request ), FALSE ); - checkMessageHeader_( line, &request.request.header, 5, FALSE ); + port = checkSpHeader_( line, &request.spHeader, sizeof( request ) ); + checkMessageHeader_( line, &request.request.header, 5 ); todo_wine_if( flagsTodo ) ok_( __FILE__, line )( request.request.flags == expectedFlags, "got flags %#lx.\n", request.request.flags );
@@ -1358,8 +1352,8 @@ static unsigned short receiveAddForwardRequest_( int line, SOCKET sock, DPID exp if ( wsResult == SOCKET_ERROR ) return 0;
- port = checkSpHeader_( line, &request.spHeader, expectedSize, FALSE ); - checkMessageHeader_( line, &request.request.header, 19, FALSE ); + port = checkSpHeader_( line, &request.spHeader, expectedSize ); + checkMessageHeader_( line, &request.request.header, 19 ); ok_( __FILE__, line )( !request.request.toId, "got destination id %#lx.\n", request.request.toId ); ok_( __FILE__, line )( request.request.playerId == expectedPlayerId, "got player id %#lx.\n", request.request.playerId ); @@ -1368,8 +1362,7 @@ static unsigned short receiveAddForwardRequest_( int line, SOCKET sock, DPID exp request.request.createOffset ); ok_( __FILE__, line )( request.request.passwordOffset == 108, "got password offset %lu.\n", request.request.passwordOffset ); - checkPackedPlayer_( line, &request.request.playerInfo, 0x9, expectedPlayerId, 0, 0, 0, expectedPlayerId, FALSE, - FALSE, FALSE, FALSE ); + checkPackedPlayer_( line, &request.request.playerInfo, 0x9, expectedPlayerId, 0, 0, 0, expectedPlayerId, FALSE ); checkSpData_( line, &request.request.spData );
wsResult = receiveMessage_( line, sock, password, expectedPasswordSize ); @@ -1639,20 +1632,19 @@ static unsigned short receiveAddForwardAck_( int line, SOCKET sock, DPID expecte wsResult = receiveMessage_( line, sock, &request, sizeof( request ) ); ok_( __FILE__, line )( wsResult == sizeof( request ), "recv() returned %d.\n", wsResult );
- port = checkSpHeader_( line, &request.spHeader, sizeof( request ), FALSE ); - checkMessageHeader_( line, &request.request.header, 47, FALSE ); + port = checkSpHeader_( line, &request.spHeader, sizeof( request ) ); + checkMessageHeader_( line, &request.request.header, 47 );
return port; }
#define receiveCreatePlayer( sock, expectedPlayerId, expectedFlags, expectedShortName, expectedLongName, \ - expectedPlayerData, expectedPlayerDataSize, flagsTodo, nameTodo ) \ + expectedPlayerData, expectedPlayerDataSize, flagsTodo ) \ receiveCreatePlayer_( __LINE__, sock, expectedPlayerId, expectedFlags, expectedShortName, expectedLongName, \ - expectedPlayerData, expectedPlayerDataSize, flagsTodo, nameTodo ) + expectedPlayerData, expectedPlayerDataSize, flagsTodo ) static unsigned short receiveCreatePlayer_( int line, SOCKET sock, DPID expectedPlayerId, DWORD expectedFlags, const WCHAR *expectedShortName, const WCHAR *expectedLongName, - void *expectedPlayerData, DWORD expectedPlayerDataSize, BOOL flagsTodo, - BOOL nameTodo ) + void *expectedPlayerData, DWORD expectedPlayerDataSize, BOOL flagsTodo ) { struct { @@ -1679,60 +1671,59 @@ static unsigned short receiveCreatePlayer_( int line, SOCKET sock, DPID expected wsResult = receiveMessage_( line, sock, &request, sizeof( request ) ); ok_( __FILE__, line )( wsResult == sizeof( request ), "recv() returned %d.\n", wsResult );
- port = checkSpHeader_( line, &request.spHeader, expectedSize, TRUE ); - checkMessageHeader_( line, &request.request.header, 8, TRUE ); + port = checkSpHeader_( line, &request.spHeader, expectedSize ); + checkMessageHeader_( line, &request.request.header, 8 ); ok_( __FILE__, line )( !request.request.toId, "got destination id %#lx.\n", request.request.toId ); ok_( __FILE__, line )( request.request.playerId == expectedPlayerId, "got player id %#lx.\n", request.request.playerId ); ok_( __FILE__, line )( !request.request.groupId, "got group id %#lx.\n", request.request.groupId ); ok_( __FILE__, line )( request.request.createOffset == 28, "got create offset %lu.\n", request.request.createOffset ); - todo_wine ok_( __FILE__, line )( !request.request.passwordOffset, "got password offset %lu.\n", - request.request.passwordOffset ); + ok_( __FILE__, line )( !request.request.passwordOffset, "got password offset %lu.\n", + request.request.passwordOffset ); checkPackedPlayer_( line, &request.request.playerInfo, expectedFlags, expectedPlayerId, expectedShortNameSize, - expectedLongNameSize, expectedPlayerDataSize, 0x12345678, flagsTodo, nameTodo, TRUE, TRUE ); + expectedLongNameSize, expectedPlayerDataSize, 0x12345678, flagsTodo );
if ( expectedShortName ) { wsResult = receiveMessage_( line, sock, shortName, expectedShortNameSize );
ok_( __FILE__, line )( wsResult == expectedShortNameSize, "recv() returned %d.\n", wsResult ); - todo_wine_if( nameTodo ) ok_( __FILE__, line )( !lstrcmpW( shortName, expectedShortName ), - "got short name %s.\n", wine_dbgstr_w( shortName ) ); + ok_( __FILE__, line )( !lstrcmpW( shortName, expectedShortName ), "got short name %s.\n", + wine_dbgstr_w( shortName ) ); }
if ( expectedLongName ) { wsResult = receiveMessage_( line, sock, longName, expectedLongNameSize );
- todo_wine_if( nameTodo ) ok_( __FILE__, line )( wsResult == expectedLongNameSize, "recv() returned %d.\n", - wsResult ); - todo_wine_if( nameTodo ) ok_( __FILE__, line )( !lstrcmpW( longName, expectedLongName ), - "got long name %s.\n", wine_dbgstr_w( longName ) ); + ok_( __FILE__, line )( wsResult == expectedLongNameSize, "recv() returned %d.\n", wsResult ); + ok_( __FILE__, line )( !lstrcmpW( longName, expectedLongName ), "got long name %s.\n", + wine_dbgstr_w( longName ) ); }
wsResult = receiveMessage_( line, sock, &spData, sizeof( spData ) ); - todo_wine_if( nameTodo ) ok_( __FILE__, line )( wsResult == sizeof( spData ), "recv() returned %d.\n", wsResult ); - todo_wine_if( nameTodo ) checkSpData_( line, &spData ); + ok_( __FILE__, line )( wsResult == sizeof( spData ), "recv() returned %d.\n", wsResult ); + checkSpData_( line, &spData );
if ( expectedPlayerDataSize ) { wsResult = receiveMessage_( line, sock, playerData, expectedPlayerDataSize );
- todo_wine ok_( __FILE__, line )( wsResult == expectedPlayerDataSize, "recv() returned %d.\n", wsResult ); - todo_wine ok_( __FILE__, line )( !memcmp( playerData, expectedPlayerData, expectedPlayerDataSize ), - "player data didn't match.\n" ); + ok_( __FILE__, line )( wsResult == expectedPlayerDataSize, "recv() returned %d.\n", wsResult ); + ok_( __FILE__, line )( !memcmp( playerData, expectedPlayerData, expectedPlayerDataSize ), + "player data didn't match.\n" ); }
wsResult = receiveMessage_( line, sock, &reserved1, sizeof( reserved1 ) );
- todo_wine ok_( __FILE__, line )( wsResult == sizeof( reserved1 ), "recv() returned %d.\n", wsResult ); - todo_wine ok_( __FILE__, line )( !reserved1, "got reserved1 %d.\n", reserved1 ); + ok_( __FILE__, line )( wsResult == sizeof( reserved1 ), "recv() returned %d.\n", wsResult ); + ok_( __FILE__, line )( !reserved1, "got reserved1 %d.\n", reserved1 );
wsResult = receiveMessage_( line, sock, &reserved2, sizeof( reserved2 ) );
- todo_wine ok_( __FILE__, line )( wsResult == sizeof( reserved2 ), "recv() returned %d.\n", wsResult ); - todo_wine ok_( __FILE__, line )( !reserved2, "got reserved2 %lu.\n", reserved2 ); + ok_( __FILE__, line )( wsResult == sizeof( reserved2 ), "recv() returned %d.\n", wsResult ); + ok_( __FILE__, line )( !reserved2, "got reserved2 %lu.\n", reserved2 );
return port; } @@ -4214,15 +4205,15 @@ static void checkCreatePlayerOrGroupMessages_( int line, IDirectPlay4 *dp, DWORD
#define check_CreatePlayer( dp, dpid, name, flags, expectedHr, expectedDpid, recvSock, requestExpected, \ expectedFlags, expectedShortName, expectedShortNameA, expectedLongName, expectedLongNameA, \ - expectedCurrentPlayers, flagsTodo, nameTodo ) \ + expectedCurrentPlayers, flagsTodo ) \ check_CreatePlayer_( __LINE__, dp, dpid, name, flags, expectedHr, expectedDpid, recvSock, requestExpected, \ expectedFlags, expectedShortName, expectedShortNameA, expectedLongName, expectedLongNameA, \ - expectedCurrentPlayers, flagsTodo, nameTodo ) + expectedCurrentPlayers, flagsTodo ) static void check_CreatePlayer_( int line, IDirectPlay4 *dp, DPID *dpid, DPNAME *name, DWORD flags, HRESULT expectedHr, DPID expectedDpid, SOCKET recvSock, BOOL requestExpected, DWORD expectedFlags, const WCHAR *expectedShortName, const char *expectedShortNameA, const WCHAR *expectedLongName, const char *expectedLongNameA, - DWORD expectedCurrentPlayers, BOOL flagsTodo, BOOL nameTodo ) + DWORD expectedCurrentPlayers, BOOL flagsTodo ) { BYTE playerData[] = { 1, 2, 3, 4, 5, 6, 7, 8, }; CreatePlayerParam *param; @@ -4233,7 +4224,6 @@ static void check_CreatePlayer_( int line, IDirectPlay4 *dp, DPID *dpid, DPNAME
if ( requestExpected ) { - DPSESSIONDESC2 dpsd; unsigned short port;
port = receiveRequestPlayerId_( line, recvSock, expectedFlags, flagsTodo ); @@ -4242,11 +4232,7 @@ static void check_CreatePlayer_( int line, IDirectPlay4 *dp, DPID *dpid, DPNAME
sendRequestPlayerReply_( line, sendSock, 2349, expectedDpid, DP_OK ); receiveCreatePlayer_( line, recvSock, expectedDpid, expectedFlags, expectedShortName, expectedLongName, - playerData, sizeof( playerData ), TRUE, nameTodo ); - - /* Wine incorrectly expects SUPERENUMPLAYERSREPLY to be sent, so send it to prevent timeout */ - memset( &dpsd, 0, sizeof( dpsd ) ); - sendSuperEnumPlayersReply_( line, sendSock, 2349, 2399, &dpsd, L"" ); + playerData, sizeof( playerData ), flagsTodo );
hr = createPlayerAsyncWait( param, 2000 ); ok_( __FILE__, line )( hr == expectedHr, "CreatePlayer() returned %#lx.\n", hr ); @@ -4316,47 +4302,47 @@ static void test_CreatePlayer(void) /* Connection not initialized */ dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, NULL, 0, DPERR_UNINITIALIZED, 0xdeadbeef, INVALID_SOCKET, FALSE, 0, NULL, NULL, - NULL, NULL, 0, FALSE, FALSE ); + NULL, NULL, 0, FALSE );
init_TCPIP_provider( dp, "127.0.0.1", 0 );
/* Session not open */ dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, NULL, 0, DPERR_INVALIDPARAMS, 0xdeadbeef, INVALID_SOCKET, FALSE, 0, NULL, NULL, - NULL, NULL, 0, FALSE, FALSE ); + NULL, NULL, 0, FALSE );
/* Join to normal session */ joinSession( dp, &appGuidDpsd, &serverDpsd, &sendSock, &recvSock );
/* Player name */ dpid = 0xdeadbeef; - check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 2, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 1, FALSE, FALSE ); + check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 2, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 1, FALSE );
dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, &fullName, 0, DP_OK, 3, recvSock, TRUE, 0x8, L"short player name", - "short player name", L"long player name", "long player name", 2, FALSE, TRUE ); + "short player name", L"long player name", "long player name", 2, FALSE );
name = fullName; name.dwSize = 1; dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, &name, 0, DP_OK, 4, recvSock, TRUE, 0x8, L"short player name", "short player name", - L"long player name", "long player name", 3, FALSE, TRUE ); + L"long player name", "long player name", 3, FALSE );
dpid = 0xdeadbeef; - check_CreatePlayer( dp, &dpid, &nullName, 0, DP_OK, 5, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 4, FALSE, FALSE ); + check_CreatePlayer( dp, &dpid, &nullName, 0, DP_OK, 5, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 4, FALSE );
/* Null dpid */ dpid = 0xdeadbeef; - check_CreatePlayer( dp, NULL, NULL, 0, DPERR_INVALIDPARAMS, 0, recvSock, FALSE, 0, NULL, NULL, NULL, NULL, 0, FALSE, + check_CreatePlayer( dp, NULL, NULL, 0, DPERR_INVALIDPARAMS, 0, recvSock, FALSE, 0, NULL, NULL, NULL, NULL, 0, FALSE );
/* Flags */ dpid = 0xdeadbeef; - check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 6, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 5, FALSE, FALSE ); + check_CreatePlayer( dp, &dpid, NULL, 0, DP_OK, 6, recvSock, TRUE, 0x8, NULL, NULL, NULL, NULL, 5, FALSE );
dpid = 0xdeadbeef; check_CreatePlayer( dp, &dpid, NULL, DPPLAYER_SPECTATOR, DP_OK, 7, recvSock, TRUE, 0x208, NULL, NULL, NULL, NULL, 6, - TRUE, FALSE ); + TRUE );
closesocket( recvSock ); closesocket( sendSock );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149027
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/dplayx/dplay.c:1758 error: patch failed: dlls/dplayx/tests/dplayx.c:4214 error: patch failed: dlls/dplayx/tests/dplayx.c:1127 Task: Patch failed to apply
=== debian11 (build log) ===
error: patch failed: dlls/dplayx/dplay.c:1758 error: patch failed: dlls/dplayx/tests/dplayx.c:4214 error: patch failed: dlls/dplayx/tests/dplayx.c:1127 Task: Patch failed to apply
=== debian11b (build log) ===
error: patch failed: dlls/dplayx/dplay.c:1758 error: patch failed: dlls/dplayx/tests/dplayx.c:4214 error: patch failed: dlls/dplayx/tests/dplayx.c:1127 Task: Patch failed to apply
Alistair Leslie-Hughes (@alesliehughes) commented about dlls/dpwsockx/dpwsockx_main.c:
static void DPWS_MessageBodyReceiveCompleted( DPWS_IN_CONNECTION *connection );
+static int DPWS_CompareConnections( const void *key, const struct rb_entry *entry ) +{
- DPWS_OUT_CONNECTION *connection = RB_ENTRY_VALUE( entry, DPWS_OUT_CONNECTION, entry );
- SOCKADDR_IN *addr = (SOCKADDR_IN *)key;
- if ( addr->sin_port < connection->addr.sin_port )
return -1;
- if ( addr->sin_port > connection->addr.sin_port )
return 1;
- if ( addr->sin_addr.s_addr < connection->addr.sin_addr.s_addr )
return -1;
- if ( addr->sin_addr.s_addr > connection->addr.sin_addr.s_addr )
return 1;
This looks wrong. Isn't this just "if (addr->sin_port != connection->addr.sin_port)" ? Same for s_addr.
On Fri Oct 18 20:36:14 2024 +0000, Alistair Leslie-Hughes wrote:
This looks wrong. Isn't this just "if (addr->sin_port != connection->addr.sin_port)" ? Same for s_addr.
Could you please explain in more detail why you think it's wrong?
Note that our RB tree requires the comparison function to return a negative value when the first item is less than the second, a positive one when greater, and zero when the items are equal.
Or did you mean something like this: ```suggestion:-8+0 if ( connection_key->addr.sin_port != connection->key.addr.sin_port ) return connection_key->addr.sin_port < connection->key.addr.sin_port ? -1 : 1;
if ( connection_key->addr.sin_addr.s_addr != connection->key.addr.sin_addr.s_addr ) return connection_key->addr.sin_addr.s_addr < connection->key.addr.sin_addr.s_addr ? -1 : 1; ```
Sorry that was my mistake. I saw two return -1.
This merge request was approved by Alistair Leslie-Hughes.