dpwsockx: Start listening for incoming TCP connections in EnumSessions().

This commit is contained in:
Anton Baskanov 2024-01-29 14:52:48 +07:00 committed by Alexandre Julliard
parent 568462f795
commit 28fdca5ea5
Notes: Alexandre Julliard 2024-09-11 23:40:30 +02:00
Approved-by: Alistair Leslie-Hughes (@alesliehughes)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6468
3 changed files with 123 additions and 11 deletions

View file

@ -1964,7 +1964,7 @@ static void check_EnumSessions_async_( int line, DPSESSIONDESC2 *dpsd, IDirectPl
checkNoMoreMessages_( line, enumSock );
hr = enumSessionsAsyncWait( param, 2000 );
todo_wine ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr );
ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr );
todo_wine ok_( __FILE__, line )( callbackData.actualCount == callbackData.expectedCount, "got session count %d.\n",
callbackData.actualCount );
@ -1985,7 +1985,7 @@ static void check_EnumSessions_async_( int line, DPSESSIONDESC2 *dpsd, IDirectPl
receiveEnumSessionsRequest_( line, enumSock, &appGuid, NULL, DPENUMSESSIONS_ASYNC );
hr = enumSessionsAsyncWait( param, 2000 );
todo_wine ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr );
ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr );
todo_wine ok_( __FILE__, line )( callbackData.actualCount == callbackData.expectedCount, "got session count %d.\n",
callbackData.actualCount );
@ -2020,7 +2020,7 @@ static void check_EnumSessions_async_( int line, DPSESSIONDESC2 *dpsd, IDirectPl
/* Retrieve results */
param = enumSessionsAsync( dp, dpsd, 100, checkSessionListCallback, &callbackData, DPENUMSESSIONS_ASYNC );
hr = enumSessionsAsyncWait( param, 2000 );
todo_wine ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr );
ok_( __FILE__, line )( hr == DP_OK, "got hr %#lx.\n", hr );
todo_wine ok_( __FILE__, line )( callbackData.actualCount == callbackData.expectedCount, "got session count %d.\n",
callbackData.actualCount );
@ -2068,15 +2068,15 @@ static void test_EnumSessions(void)
check_EnumSessions( dp, &dpsd, 0, DPERR_INVALIDPARAMS, 0, FALSE, FALSE, NULL, 0, FALSE );
/* No sessions */
check_EnumSessions( dp, &appGuidDpsd, 0, DP_OK, 0, TRUE, TRUE, NULL, 0, TRUE );
check_EnumSessions( dp, &appGuidDpsd, 0, DP_OK, 0, TRUE, TRUE, NULL, 0, FALSE );
/* Invalid params */
check_EnumSessions( dp, &appGuidDpsd, -1, DPERR_INVALIDPARAMS, 0, FALSE, FALSE, NULL, 0, TRUE );
check_EnumSessions( dp, NULL, 0, DPERR_INVALIDPARAMS, 0, FALSE, FALSE, NULL, 0, FALSE );
/* All sessions are enumerated regardless of flags */
check_EnumSessions( dp, &appGuidDpsd, 0, DP_OK, 2, TRUE, TRUE, NULL, 2, TRUE );
check_EnumSessions( dp, &appGuidDpsd, DPENUMSESSIONS_AVAILABLE, DP_OK, 2, TRUE, TRUE, NULL, 2, TRUE );
check_EnumSessions( dp, &appGuidDpsd, 0, DP_OK, 2, TRUE, TRUE, NULL, 2, FALSE );
check_EnumSessions( dp, &appGuidDpsd, DPENUMSESSIONS_AVAILABLE, DP_OK, 2, TRUE, TRUE, NULL, 2, FALSE );
/* Async enumeration */
check_EnumSessions_async( &appGuidDpsd, dp );
@ -2084,7 +2084,7 @@ static void test_EnumSessions(void)
/* Enumeration with password */
dpsd = appGuidDpsd;
dpsd.lpszPasswordA = (char *) "password";
check_EnumSessions( dp, &dpsd, 0, DP_OK, 2, TRUE, TRUE, L"password", 2, TRUE );
check_EnumSessions( dp, &dpsd, 0, DP_OK, 2, TRUE, TRUE, L"password", 2, FALSE );
IDirectPlayX_Release( dp );
}

View file

@ -37,7 +37,12 @@
typedef struct tagDPWS_DATA
{
LPDIRECTPLAYSP lpISP;
LPDIRECTPLAYSP lpISP;
SOCKET tcpSock;
SOCKADDR_IN tcpAddr;
BOOL started;
} DPWS_DATA, *LPDPWS_DATA;
#include "pshpack1.h"

View file

@ -30,12 +30,98 @@
WINE_DEFAULT_DEBUG_CHANNEL(dplay);
#define DPWS_START_TCP_PORT 2300
#define DPWS_END_TCP_PORT 2350
static HRESULT DPWS_BindToFreePort( SOCKET sock, SOCKADDR_IN *addr, int startPort, int endPort )
{
int port;
memset( addr, 0, sizeof( *addr ) );
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = htonl( INADDR_ANY );
for ( port = startPort; port < endPort; ++port )
{
addr->sin_port = htons( port );
if ( SOCKET_ERROR != bind( sock, (SOCKADDR *) addr, sizeof( *addr ) ) )
return DP_OK;
if ( WSAGetLastError() == WSAEADDRINUSE )
continue;
ERR( "bind() failed\n" );
return DPERR_UNAVAILABLE;
}
ERR( "no free ports\n" );
return DPERR_UNAVAILABLE;
}
static HRESULT DPWS_Start( DPWS_DATA *dpwsData )
{
HRESULT hr;
if ( dpwsData->started )
return S_OK;
dpwsData->tcpSock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( dpwsData->tcpSock == INVALID_SOCKET )
{
ERR( "socket() failed\n" );
return DPERR_UNAVAILABLE;
}
hr = DPWS_BindToFreePort( dpwsData->tcpSock, &dpwsData->tcpAddr, DPWS_START_TCP_PORT,
DPWS_END_TCP_PORT );
if ( FAILED( hr ) )
{
closesocket( dpwsData->tcpSock );
return hr;
}
if ( SOCKET_ERROR == listen( dpwsData->tcpSock, SOMAXCONN ) )
{
ERR( "listen() failed\n" );
closesocket( dpwsData->tcpSock );
return DPERR_UNAVAILABLE;
}
dpwsData->started = TRUE;
return S_OK;
}
static void DPWS_Stop( DPWS_DATA *dpwsData )
{
if ( !dpwsData->started )
return;
dpwsData->started = FALSE;
closesocket( dpwsData->tcpSock );
}
static HRESULT WINAPI DPWSCB_EnumSessions( LPDPSP_ENUMSESSIONSDATA data )
{
DPWS_DATA *dpwsData;
DWORD dpwsDataSize;
HRESULT hr;
FIXME( "(%p,%ld,%p,%u) stub\n",
data->lpMessage, data->dwMessageSize,
data->lpISP, data->bReturnStatus );
return DPERR_UNSUPPORTED;
hr = IDirectPlaySP_GetSPData( data->lpISP, (void **)&dpwsData, &dpwsDataSize, DPSET_LOCAL );
if ( FAILED( hr ) )
return hr;
hr = DPWS_Start( dpwsData );
if ( FAILED (hr) )
return hr;
return S_OK;
}
static HRESULT WINAPI DPWSCB_Reply( LPDPSP_REPLYDATA data )
@ -118,14 +204,35 @@ static HRESULT WINAPI DPWSCB_Open( LPDPSP_OPENDATA data )
static HRESULT WINAPI DPWSCB_CloseEx( LPDPSP_CLOSEDATA data )
{
FIXME( "(%p) stub\n", data->lpISP );
return DPERR_UNSUPPORTED;
DPWS_DATA *dpwsData;
DWORD dpwsDataSize;
HRESULT hr;
TRACE( "(%p)\n", data->lpISP );
hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL );
if ( FAILED( hr ) )
return hr;
DPWS_Stop( dpwsData );
return DP_OK;
}
static HRESULT WINAPI DPWSCB_ShutdownEx( LPDPSP_SHUTDOWNDATA data )
{
DPWS_DATA *dpwsData;
DWORD dpwsDataSize;
HRESULT hr;
TRACE( "(%p)\n", data->lpISP );
hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL );
if ( FAILED( hr ) )
return hr;
DPWS_Stop( dpwsData );
WSACleanup();
return DP_OK;