From: Anton Baskanov baskanov@gmail.com
--- dlls/dplayx/dplay.c | 47 +++++++++++++++++++++++++++++++++-- dlls/dplayx/dplay_global.h | 1 + dlls/dplayx/dplayx_messages.h | 4 +-- dlls/dplayx/name_server.c | 12 ++++++--- dlls/dplayx/name_server.h | 1 + dlls/dplayx/tests/dplayx.c | 13 +++++----- 6 files changed, 62 insertions(+), 16 deletions(-)
diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 1ffc006cd04..d74b1a25bfe 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -303,6 +303,25 @@ static DWORD DP_CopyString( char **dst, const void *src, BOOL dstAnsi, BOOL srcA return size; }
+static void *DP_DuplicateString( void *src, BOOL dstAnsi, BOOL srcAnsi ) +{ + DWORD size; + char *dst; + + if ( !src ) + return NULL; + + size = DP_CopyString( NULL, src, dstAnsi, srcAnsi, NULL, 0 ); + + dst = malloc( size ); + if ( !dst ) + return NULL; + + DP_CopyString( &dst, src, dstAnsi, srcAnsi, dst, 0 ); + + return dst; +} + /* *lplpReply will be non NULL iff there is something to reply */ HRESULT DP_HandleMessage( IDirectPlayImpl *This, const void *lpcMessageBody, DWORD dwMessageBodySize, const void *lpcMessageHeader, WORD wCommandId, WORD wVersion, @@ -2357,6 +2376,7 @@ static DWORD CALLBACK DP_EnumSessionsSendAsyncRequestThread( LPVOID lpContext ) /* Now resend the enum request */ hr = NS_SendSessionRequestBroadcast( &data->requestGuid, data->dwEnumSessionFlags, + data->password, data->lpSpData );
if( FAILED(hr) ) @@ -2371,6 +2391,7 @@ static DWORD CALLBACK DP_EnumSessionsSendAsyncRequestThread( LPVOID lpContext )
/* Clean up the thread data */ CloseHandle( hSuicideRequest ); + free( data->password ); free( lpContext );
/* FIXME: Need to have some notification to main app thread that this is @@ -2447,6 +2468,7 @@ static HRESULT WINAPI IDirectPlay4Impl_EnumSessions( IDirectPlay4 *iface, DPSESS { IDirectPlayImpl *This = impl_from_IDirectPlay4( iface ); EnumSessionAsyncCallbackData *data; + WCHAR *password = NULL; DWORD defaultTimeout; void *connection; DPCAPS caps; @@ -2511,6 +2533,10 @@ static HRESULT WINAPI IDirectPlay4Impl_EnumSessions( IDirectPlay4 *iface, DPSESS return DP_OK; }
+ password = DP_DuplicateString( sdesc->lpszPassword, FALSE, TRUE ); + if ( !password && sdesc->lpszPassword ) + return DPERR_OUTOFMEMORY; + for ( ;; ) { if ( !(flags & DPENUMSESSIONS_ASYNC) ) @@ -2523,10 +2549,13 @@ static HRESULT WINAPI IDirectPlay4Impl_EnumSessions( IDirectPlay4 *iface, DPSESS LeaveCriticalSection( &This->lock );
/* Send the broadcast for session enumeration */ - hr = NS_SendSessionRequestBroadcast( &sdesc->guidApplication, flags, + hr = NS_SendSessionRequestBroadcast( &sdesc->guidApplication, flags, password, &This->dp2->spData ); if ( FAILED( hr ) ) + { + free( password ); return hr; + } SleepEx( timeout ? timeout : defaultTimeout, FALSE ); }
@@ -2543,26 +2572,37 @@ static HRESULT WINAPI IDirectPlay4Impl_EnumSessions( IDirectPlay4 *iface, DPSESS }
if ( !(flags & DPENUMSESSIONS_ASYNC) ) + { + free( password ); return DP_OK; + }
/* Async enumeration */
if ( This->dp2->dwEnumSessionLock ) + { + free( password ); return DPERR_CONNECTING; + }
/* See if we've already created a thread to service this interface */ if ( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE ) + { + free( password ); return DP_OK; + }
This->dp2->dwEnumSessionLock++;
/* Send the first enum request inline since the user may cancel a dialog * if one is presented. Also, may also have a connecting return code. */ - hr = NS_SendSessionRequestBroadcast( &sdesc->guidApplication, flags, &This->dp2->spData ); + hr = NS_SendSessionRequestBroadcast( &sdesc->guidApplication, flags, password, + &This->dp2->spData ); if ( FAILED( hr ) ) { This->dp2->dwEnumSessionLock--; + free( password ); return hr; }
@@ -2572,6 +2612,7 @@ static HRESULT WINAPI IDirectPlay4Impl_EnumSessions( IDirectPlay4 *iface, DPSESS data->requestGuid = sdesc->guidApplication; data->dwEnumSessionFlags = flags; data->dwTimeout = timeout ? timeout : defaultTimeout; + data->password = password;
This->dp2->hKillEnumSessionThreadEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); if ( !DuplicateHandle( GetCurrentProcess(), This->dp2->hKillEnumSessionThreadEvent, @@ -2582,6 +2623,8 @@ static HRESULT WINAPI IDirectPlay4Impl_EnumSessions( IDirectPlay4 *iface, DPSESS TRACE( ": creating EnumSessionsRequest thread\n" ); This->dp2->hEnumSessionThread = CreateThread( NULL, 0, DP_EnumSessionsSendAsyncRequestThread, data, 0, &tid ); + if ( !This->dp2->hEnumSessionThread ) + free( password );
This->dp2->dwEnumSessionLock--;
diff --git a/dlls/dplayx/dplay_global.h b/dlls/dplayx/dplay_global.h index 7ee91ba0402..e81c57a4442 100644 --- a/dlls/dplayx/dplay_global.h +++ b/dlls/dplayx/dplay_global.h @@ -37,6 +37,7 @@ typedef struct tagEnumSessionAsyncCallbackData GUID requestGuid; DWORD dwEnumSessionFlags; DWORD dwTimeout; + WCHAR *password; HANDLE hSuicideRequest; } EnumSessionAsyncCallbackData;
diff --git a/dlls/dplayx/dplayx_messages.h b/dlls/dplayx/dplayx_messages.h index 8c09c8d3749..c8758d3ddb1 100644 --- a/dlls/dplayx/dplayx_messages.h +++ b/dlls/dplayx/dplayx_messages.h @@ -142,9 +142,7 @@ typedef struct tagDPMSG_ENUMSESSIONSREQUEST
GUID guidApplication;
- DWORD dwPasswordSize; /* A Guess. This is 0x00000000. */ - /* This might be the name server DPID which - is needed for the reply */ + DWORD passwordOffset;
DWORD dwFlags; /* dwFlags from EnumSessions */
diff --git a/dlls/dplayx/name_server.c b/dlls/dplayx/name_server.c index ddd4ad57e42..4fabf64d32a 100644 --- a/dlls/dplayx/name_server.c +++ b/dlls/dplayx/name_server.c @@ -195,18 +195,20 @@ void NS_SetLocalAddr( LPVOID lpNSInfo, LPCVOID lpHdr, DWORD dwHdrSize ) */ HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid, DWORD dwFlags, + WCHAR *password, const SPINITDATA *lpSpData )
{ DPSP_ENUMSESSIONSDATA data; LPDPMSG_ENUMSESSIONSREQUEST lpMsg; + DWORD passwordSize = 0;
TRACE( "enumerating for guid %s\n", debugstr_guid( lpcGuid ) );
- /* Get the SP to deal with sending the EnumSessions request */ - FIXME( ": not all data fields are correct\n" ); + if ( password ) + passwordSize = (wcslen( password ) + 1) * sizeof( WCHAR );
- data.dwMessageSize = lpSpData->dwSPHeaderSize + sizeof( *lpMsg ); /*FIXME!*/ + data.dwMessageSize = lpSpData->dwSPHeaderSize + sizeof( *lpMsg ) + passwordSize; data.lpMessage = calloc( 1, data.dwMessageSize ); data.lpISP = lpSpData->lpISP; data.bReturnStatus = (dwFlags & DPENUMSESSIONS_RETURNSTATUS) != 0; @@ -219,11 +221,13 @@ HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid, lpMsg->envelope.wCommandId = DPMSGCMD_ENUMSESSIONSREQUEST; lpMsg->envelope.wVersion = DPMSGVER_DP6;
- lpMsg->dwPasswordSize = 0; /* FIXME: If enumerating passwords..? */ + lpMsg->passwordOffset = password ? sizeof( DPMSG_ENUMSESSIONSREQUEST ) : 0; lpMsg->dwFlags = dwFlags;
lpMsg->guidApplication = *lpcGuid;
+ memcpy( lpMsg + 1, password, passwordSize ); + return (lpSpData->lpCB->EnumSessions)( &data ); }
diff --git a/dlls/dplayx/name_server.h b/dlls/dplayx/name_server.h index 30c5bc7e9ae..70612ecf00f 100644 --- a/dlls/dplayx/name_server.h +++ b/dlls/dplayx/name_server.h @@ -44,6 +44,7 @@ void NS_ReplyToEnumSessionsRequest( LPCVOID lpcMsg,
HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid, DWORD dwFlags, + WCHAR *password, const SPINITDATA *lpSpData );
diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index 229183a43f7..9e0e6fdec96 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -865,21 +865,20 @@ static unsigned short receiveEnumSessionsRequest_( int line, SOCKET sock, const expectedSize = sizeof( request.spHeader ) + sizeof( request.request ) + expectedPasswordSize;
wsResult = receiveMessage_( line, sock, &request, sizeof( request ) ); - todo_wine_if( expectedPassword ) ok_( __FILE__, line )( wsResult == expectedSize, "recv() returned %d.\n", - wsResult ); + ok_( __FILE__, line )( wsResult == expectedSize, "recv() returned %d.\n", wsResult ); if ( wsResult == SOCKET_ERROR ) return 0;
- port = checkSpHeader_( line, &request.spHeader, expectedSize, expectedPassword != NULL ); + port = checkSpHeader_( line, &request.spHeader, expectedSize, FALSE ); 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 ) { - todo_wine ok_( __FILE__, line )( request.request.passwordOffset == 32, "got password offset %lu.\n", - request.request.passwordOffset ); - todo_wine ok_( __FILE__, line )( !lstrcmpW( request.password, expectedPassword ), "got password %s.\n", - wine_dbgstr_w( request.password ) ); + ok_( __FILE__, line )( request.request.passwordOffset == 32, "got password offset %lu.\n", + request.request.passwordOffset ); + ok_( __FILE__, line )( !lstrcmpW( request.password, expectedPassword ), "got password %s.\n", + wine_dbgstr_w( request.password ) ); } else {