- Add proper message reply mechanism and sp player data storage
- More implementation and fixes
This commit is contained in:
parent
23a5b79f56
commit
10a04e7485
|
@ -77,7 +77,7 @@ static IClassFactoryImpl DP_and_DPL_CF = {&DP_and_DPL_Vtbl, 1 };
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* DPLAYX_DllGetClassObject [DPLAYX.?]
|
* DPLAYX_DllGetClassObject [DPLAYX.11]
|
||||||
* Retrieves DP or DPL class object from a DLL object
|
* Retrieves DP or DPL class object from a DLL object
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
|
|
|
@ -160,6 +160,8 @@ static HRESULT WINAPI DP_IF_EnumSessions
|
||||||
( IDirectPlay2Impl* This, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout,
|
( IDirectPlay2Impl* This, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout,
|
||||||
LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
|
LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
|
||||||
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
|
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
|
||||||
|
static HRESULT WINAPI DP_IF_InitializeConnection
|
||||||
|
( IDirectPlay3Impl* This, LPVOID lpConnection, DWORD dwFlags, BOOL bAnsi );
|
||||||
static BOOL CALLBACK cbDPCreateEnumConnections( LPCGUID lpguidSP,
|
static BOOL CALLBACK cbDPCreateEnumConnections( LPCGUID lpguidSP,
|
||||||
LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName,
|
LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName,
|
||||||
DWORD dwFlags, LPVOID lpContext );
|
DWORD dwFlags, LPVOID lpContext );
|
||||||
|
@ -174,7 +176,7 @@ static void DP_CopySessionDesc( LPDPSESSIONDESC2 destSessionDesc,
|
||||||
LPCDPSESSIONDESC2 srcSessDesc, BOOL bAnsi );
|
LPCDPSESSIONDESC2 srcSessDesc, BOOL bAnsi );
|
||||||
|
|
||||||
|
|
||||||
static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData );
|
static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDpSp );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -241,6 +243,7 @@ static BOOL DP_CreateDirectPlay2( LPVOID lpDP )
|
||||||
|
|
||||||
DPQ_INIT(This->dp2->receiveMsgs);
|
DPQ_INIT(This->dp2->receiveMsgs);
|
||||||
DPQ_INIT(This->dp2->sendMsgs);
|
DPQ_INIT(This->dp2->sendMsgs);
|
||||||
|
DPQ_INIT(This->dp2->replysExpected);
|
||||||
|
|
||||||
if( !NS_InitializeSessionCache( &This->dp2->lpNameServerData ) )
|
if( !NS_InitializeSessionCache( &This->dp2->lpNameServerData ) )
|
||||||
{
|
{
|
||||||
|
@ -504,14 +507,14 @@ static HRESULT WINAPI DP_QueryInterface
|
||||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
||||||
|
|
||||||
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
sizeof( IDirectPlay2Impl ) );
|
sizeof( *This ) );
|
||||||
|
|
||||||
if( *ppvObj == NULL )
|
if( *ppvObj == NULL )
|
||||||
{
|
{
|
||||||
return DPERR_OUTOFMEMORY;
|
return DPERR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMemory( *ppvObj, iface, sizeof( IDirectPlay2Impl ) );
|
CopyMemory( *ppvObj, This, sizeof( *This ) );
|
||||||
(*(IDirectPlay2Impl**)ppvObj)->ulInterfaceRef = 0;
|
(*(IDirectPlay2Impl**)ppvObj)->ulInterfaceRef = 0;
|
||||||
|
|
||||||
if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
|
if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
|
||||||
|
@ -613,25 +616,22 @@ static inline DPID DP_NextObjectId(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *lplpReply will be non NULL iff there is something to reply */
|
/* *lplpReply will be non NULL iff there is something to reply */
|
||||||
HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpcMessageBody,
|
||||||
DWORD dwMessageBodySize, LPCVOID lpMessageHeader,
|
DWORD dwMessageBodySize, LPCVOID lpcMessageHeader,
|
||||||
WORD wCommandId, WORD wVersion,
|
WORD wCommandId, WORD wVersion,
|
||||||
LPVOID* lplpReply, LPDWORD lpdwMsgSize )
|
LPVOID* lplpReply, LPDWORD lpdwMsgSize )
|
||||||
{
|
{
|
||||||
TRACE( "(%p)->(%p,0x%08lx,%p,%u,%u)\n",
|
TRACE( "(%p)->(%p,0x%08lx,%p,%u,%u)\n",
|
||||||
This, lpMessageBody, dwMessageBodySize, lpMessageHeader, wCommandId,
|
This, lpcMessageBody, dwMessageBodySize, lpcMessageHeader, wCommandId,
|
||||||
wVersion );
|
wVersion );
|
||||||
|
|
||||||
DebugBreak();
|
|
||||||
|
|
||||||
switch( wCommandId )
|
switch( wCommandId )
|
||||||
{
|
{
|
||||||
case DPMSGCMD_REQUESTNEWPLAYERID:
|
case DPMSGCMD_REQUESTNEWPLAYERID:
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
LPCDPMSG_REQUESTNEWPLAYERID lpcMsg =
|
LPCDPMSG_REQUESTNEWPLAYERID lpcMsg =
|
||||||
(LPCDPMSG_REQUESTNEWPLAYERID)lpMessageBody;
|
(LPCDPMSG_REQUESTNEWPLAYERID)lpcMessageBody;
|
||||||
#endif
|
|
||||||
LPDPMSG_NEWPLAYERIDREPLY lpReply;
|
LPDPMSG_NEWPLAYERIDREPLY lpReply;
|
||||||
|
|
||||||
*lpdwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpReply );
|
*lpdwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpReply );
|
||||||
|
@ -640,25 +640,8 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
*lpdwMsgSize );
|
*lpdwMsgSize );
|
||||||
|
|
||||||
FIXME( "Ignoring dwFlags in request msg\n" );
|
FIXME( "Ignoring dwFlags 0x%08lx in request msg\n",
|
||||||
|
lpcMsg->dwFlags );
|
||||||
#if 0
|
|
||||||
/* This is just a test. See how large the SPData is and send it */
|
|
||||||
{
|
|
||||||
LPVOID lpData;
|
|
||||||
DWORD dwDataSize;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
hr = IDirectPlaySP_GetSPData( This->dp2->spData.lpISP, &lpData,
|
|
||||||
&dwDataSize, DPSET_REMOTE );
|
|
||||||
|
|
||||||
if( FAILED(hr) )
|
|
||||||
{
|
|
||||||
ERR( "Unable to get remote SPData %s\n", DPLAYX_HresultToString(hr) );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Setup the reply */
|
/* Setup the reply */
|
||||||
lpReply = (LPDPMSG_NEWPLAYERIDREPLY)( (BYTE*)(*lplpReply) +
|
lpReply = (LPDPMSG_NEWPLAYERIDREPLY)( (BYTE*)(*lplpReply) +
|
||||||
|
@ -676,29 +659,25 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DPMSGCMD_GETNAMETABLEREPLY:
|
||||||
case DPMSGCMD_NEWPLAYERIDREPLY:
|
case DPMSGCMD_NEWPLAYERIDREPLY:
|
||||||
{
|
{
|
||||||
|
|
||||||
if( This->dp2->hMsgReceipt )
|
DP_MSG_ReplyReceived( This, wCommandId, lpcMessageBody, dwMessageBodySize );
|
||||||
{
|
|
||||||
/* This is a hack only */
|
|
||||||
This->dp2->lpMsgReceived = HeapAlloc( GetProcessHeap(),
|
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
dwMessageBodySize );
|
|
||||||
CopyMemory( This->dp2->lpMsgReceived, lpMessageBody, dwMessageBodySize );
|
|
||||||
SetEvent( This->dp2->hMsgReceipt );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERR( "No receipt event set - only expecting in reply mode\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DPMSGCMD_FORWARDADDPLAYERNACK:
|
||||||
|
{
|
||||||
|
DP_MSG_ErrorReceived( This, wCommandId, lpcMessageBody, dwMessageBodySize );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
FIXME( "Unknown wCommandId %u. Ignoring message\n", wCommandId );
|
FIXME( "Unknown wCommandId %u. Ignoring message\n", wCommandId );
|
||||||
|
DebugBreak();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -873,6 +852,8 @@ lpGroupData DP_CreateGroup( IDirectPlay2AImpl* This, LPDPID lpid,
|
||||||
/* FIXME: Should we validate the dwFlags? */
|
/* FIXME: Should we validate the dwFlags? */
|
||||||
lpGData->dwFlags = dwFlags;
|
lpGData->dwFlags = dwFlags;
|
||||||
|
|
||||||
|
TRACE( "Created group id 0x%08lx\n", *lpid );
|
||||||
|
|
||||||
return lpGData;
|
return lpGData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,6 +949,7 @@ static HRESULT WINAPI DP_IF_CreateGroup
|
||||||
if( DPID_SYSTEM_GROUP == *lpidGroup )
|
if( DPID_SYSTEM_GROUP == *lpidGroup )
|
||||||
{
|
{
|
||||||
This->dp2->lpSysGroup = lpGData;
|
This->dp2->lpSysGroup = lpGData;
|
||||||
|
TRACE( "Inserting system group\n" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1149,6 +1131,11 @@ lpPlayerData DP_CreatePlayer( IDirectPlay2Impl* This, LPDPID lpid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the SP data section */
|
||||||
|
lpPData->lpSPPlayerData = DPSP_CreateSPPlayerData();
|
||||||
|
|
||||||
|
TRACE( "Created player id 0x%08lx\n", *lpid );
|
||||||
|
|
||||||
return lpPData;
|
return lpPData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1325,6 +1312,7 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
HANDLE hr = DP_OK;
|
HANDLE hr = DP_OK;
|
||||||
lpPlayerData lpPData;
|
lpPlayerData lpPData;
|
||||||
lpPlayerList lpPList;
|
lpPlayerList lpPList;
|
||||||
|
DWORD dwCreateFlags = 0;
|
||||||
|
|
||||||
TRACE( "(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx,%u)\n",
|
TRACE( "(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx,%u)\n",
|
||||||
This, lpidPlayer, lpPlayerName, hEvent, lpData,
|
This, lpidPlayer, lpPlayerName, hEvent, lpData,
|
||||||
|
@ -1340,6 +1328,35 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
return DPERR_INVALIDPARAMS;
|
return DPERR_INVALIDPARAMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Determine the creation flags for the player. These will be passed
|
||||||
|
* 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( lpMsgHdr == NULL )
|
||||||
|
dwCreateFlags |= DPLAYI_PLAYER_PLAYERLOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Verify we know how to handle all the flags */
|
/* Verify we know how to handle all the flags */
|
||||||
if( !( ( dwFlags & DPPLAYER_SERVERPLAYER ) ||
|
if( !( ( dwFlags & DPPLAYER_SERVERPLAYER ) ||
|
||||||
( dwFlags & DPPLAYER_SPECTATOR )
|
( dwFlags & DPPLAYER_SPECTATOR )
|
||||||
|
@ -1360,7 +1377,7 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hr = DP_MSG_SendRequestPlayerId( This, dwFlags, lpidPlayer );
|
hr = DP_MSG_SendRequestPlayerId( This, dwCreateFlags, lpidPlayer );
|
||||||
|
|
||||||
if( FAILED(hr) )
|
if( FAILED(hr) )
|
||||||
{
|
{
|
||||||
|
@ -1376,6 +1393,7 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: Should we be storing these dwFlags or the creation ones? */
|
||||||
lpPData = DP_CreatePlayer( This, lpidPlayer, lpPlayerName, dwFlags,
|
lpPData = DP_CreatePlayer( This, lpidPlayer, lpPlayerName, dwFlags,
|
||||||
hEvent, bAnsi );
|
hEvent, bAnsi );
|
||||||
|
|
||||||
|
@ -1406,28 +1424,15 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
if( This->dp2->spData.lpCB->CreatePlayer )
|
if( This->dp2->spData.lpCB->CreatePlayer )
|
||||||
{
|
{
|
||||||
DPSP_CREATEPLAYERDATA data;
|
DPSP_CREATEPLAYERDATA data;
|
||||||
DWORD dwCreateFlags = 0;
|
|
||||||
|
|
||||||
TRACE( "Calling SP CreatePlayer\n" );
|
|
||||||
|
|
||||||
if( ( dwFlags & DPPLAYER_SERVERPLAYER ) &&
|
|
||||||
( *lpidPlayer == DPID_SERVERPLAYER )
|
|
||||||
)
|
|
||||||
dwCreateFlags |= DPLAYI_PLAYER_APPSERVER;
|
|
||||||
|
|
||||||
if( ( dwFlags & DPPLAYER_SERVERPLAYER ) &&
|
|
||||||
( *lpidPlayer == DPID_NAME_SERVER )
|
|
||||||
)
|
|
||||||
dwCreateFlags |= (DPLAYI_PLAYER_NAMESRVR|DPLAYI_PLAYER_SYSPLAYER);
|
|
||||||
|
|
||||||
if( lpMsgHdr == NULL )
|
|
||||||
dwCreateFlags |= DPLAYI_PLAYER_PLAYERLOCAL;
|
|
||||||
|
|
||||||
data.idPlayer = *lpidPlayer;
|
data.idPlayer = *lpidPlayer;
|
||||||
data.dwFlags = dwCreateFlags;
|
data.dwFlags = dwCreateFlags;
|
||||||
data.lpSPMessageHeader = lpMsgHdr;
|
data.lpSPMessageHeader = lpMsgHdr;
|
||||||
data.lpISP = This->dp2->spData.lpISP;
|
data.lpISP = This->dp2->spData.lpISP;
|
||||||
|
|
||||||
|
TRACE( "Calling SP CreatePlayer 0x%08lx: dwFlags: 0x%08lx lpMsgHdr: %p\n",
|
||||||
|
*lpidPlayer, data.dwFlags, data.lpSPMessageHeader );
|
||||||
|
|
||||||
hr = (*This->dp2->spData.lpCB->CreatePlayer)( &data );
|
hr = (*This->dp2->spData.lpCB->CreatePlayer)( &data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1453,11 +1458,22 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
|
|
||||||
if( FAILED(hr) )
|
if( FAILED(hr) )
|
||||||
{
|
{
|
||||||
ERR( "Failed to add player to sys groupwith sp: %s\n",
|
ERR( "Failed to add player to sys group with sp: %s\n",
|
||||||
DPLAYX_HresultToString(hr) );
|
DPLAYX_HresultToString(hr) );
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if( This->dp2->bHostInterface == FALSE )
|
||||||
|
{
|
||||||
|
/* 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(...);
|
||||||
|
*/
|
||||||
|
hr = DP_MSG_ForwardPlayerCreation( This, *lpidPlayer);
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* Inform all other peers of the creation of a new player. If there are
|
/* Inform all other peers of the creation of a new player. If there are
|
||||||
* no peers keep this quiet.
|
* no peers keep this quiet.
|
||||||
* Also, if this was a remote event, no need to rebroadcast it.
|
* Also, if this was a remote event, no need to rebroadcast it.
|
||||||
|
@ -1484,6 +1500,7 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
hr = DP_SendEx( This, DPID_SERVERPLAYER, DPID_ALLPLAYERS, 0, &msg,
|
hr = DP_SendEx( This, DPID_SERVERPLAYER, DPID_ALLPLAYERS, 0, &msg,
|
||||||
sizeof( msg ), 0, 0, NULL, NULL, bAnsi );
|
sizeof( msg ), 0, 0, NULL, NULL, bAnsi );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -2055,7 +2072,8 @@ static void DP_KillEnumSessionThread( IDirectPlay2Impl* This )
|
||||||
/* Does a thread exist? If so we were doing an async enum session */
|
/* Does a thread exist? If so we were doing an async enum session */
|
||||||
if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
|
if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
|
||||||
{
|
{
|
||||||
TRACE( "Killing EnumSession thread\n" );
|
TRACE( "Killing EnumSession thread %u\n",
|
||||||
|
This->dp2->hEnumSessionThread );
|
||||||
|
|
||||||
/* Request that the thread kill itself nicely */
|
/* Request that the thread kill itself nicely */
|
||||||
SetEvent( This->dp2->hKillEnumSessionThreadEvent );
|
SetEvent( This->dp2->hKillEnumSessionThreadEvent );
|
||||||
|
@ -2094,7 +2112,12 @@ static HRESULT WINAPI DP_IF_EnumSessions
|
||||||
DP_IF_GetCaps( This, &spCaps, 0 );
|
DP_IF_GetCaps( This, &spCaps, 0 );
|
||||||
dwTimeout = spCaps.dwTimeout;
|
dwTimeout = spCaps.dwTimeout;
|
||||||
|
|
||||||
/* FIXME: If it's still 0, we need to provide the IP default */
|
/* The service provider doesn't provide one either! */
|
||||||
|
if( dwTimeout == 0 )
|
||||||
|
{
|
||||||
|
/* Provide the TCP/IP default */
|
||||||
|
dwTimeout = DPMSG_WAIT_5_SECS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( dwFlags & DPENUMSESSIONS_STOPASYNC )
|
if( dwFlags & DPENUMSESSIONS_STOPASYNC )
|
||||||
|
@ -2725,6 +2748,7 @@ static HRESULT WINAPI DP_SecureOpen
|
||||||
hr = DP_IF_CreatePlayer( This, NULL, &dpidServerId, NULL, 0, NULL,
|
hr = DP_IF_CreatePlayer( This, NULL, &dpidServerId, NULL, 0, NULL,
|
||||||
0,
|
0,
|
||||||
DPPLAYER_SERVERPLAYER | DPPLAYER_LOCAL , bAnsi );
|
DPPLAYER_SERVERPLAYER | DPPLAYER_LOCAL , bAnsi );
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( dwFlags & DPOPEN_CREATE )
|
else if( dwFlags & DPOPEN_CREATE )
|
||||||
{
|
{
|
||||||
|
@ -3792,7 +3816,7 @@ BOOL CALLBACK DP_GetSpLpGuidFromCompoundAddress(
|
||||||
|
|
||||||
|
|
||||||
/* Find and perform a LoadLibrary on the requested SP or LP GUID */
|
/* Find and perform a LoadLibrary on the requested SP or LP GUID */
|
||||||
static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData )
|
static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDpSp )
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
LPCSTR spSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
|
LPCSTR spSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
|
||||||
|
@ -3814,6 +3838,7 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData )
|
||||||
FILETIME filetime;
|
FILETIME filetime;
|
||||||
|
|
||||||
(i == 0) ? (searchSubKey = spSubKey ) : (searchSubKey = lpSubKey );
|
(i == 0) ? (searchSubKey = spSubKey ) : (searchSubKey = lpSubKey );
|
||||||
|
*lpbIsDpSp = (i == 0) ? TRUE : FALSE;
|
||||||
|
|
||||||
|
|
||||||
/* Need to loop over the service providers in the registry */
|
/* Need to loop over the service providers in the registry */
|
||||||
|
@ -3910,6 +3935,7 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE( "Loading %s\n", returnBuffer );
|
||||||
return LoadLibraryA( returnBuffer );
|
return LoadLibraryA( returnBuffer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3917,18 +3943,17 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
static HRESULT WINAPI DP_IF_InitializeConnection
|
||||||
( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
|
( IDirectPlay3Impl* This, LPVOID lpConnection, DWORD dwFlags, BOOL bAnsi )
|
||||||
{
|
{
|
||||||
HMODULE hServiceProvider;
|
HMODULE hServiceProvider;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPDPSP_SPINIT SPInit;
|
LPDPSP_SPINIT SPInit;
|
||||||
GUID guidSP;
|
GUID guidSP;
|
||||||
DWORD dwAddrSize = 80; /* FIXME: Need to calculate it correctly */
|
const DWORD dwAddrSize = 80; /* FIXME: Need to calculate it correctly */
|
||||||
|
BOOL bIsDpSp; /* TRUE if Direct Play SP, FALSE if Direct Play Lobby SP */
|
||||||
|
|
||||||
ICOM_THIS(IDirectPlay3Impl,iface);
|
TRACE("(%p)->(%p,0x%08lx,%u)\n", This, lpConnection, dwFlags, bAnsi );
|
||||||
|
|
||||||
TRACE("(%p)->(%p,0x%08lx)\n", This, lpConnection, dwFlags );
|
|
||||||
|
|
||||||
if( dwFlags != 0 )
|
if( dwFlags != 0 )
|
||||||
{
|
{
|
||||||
|
@ -3958,7 +3983,7 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
||||||
This->dp2->spData.lpGuid = &guidSP;
|
This->dp2->spData.lpGuid = &guidSP;
|
||||||
|
|
||||||
/* Load the service provider */
|
/* Load the service provider */
|
||||||
hServiceProvider = DP_LoadSP( &guidSP, &This->dp2->spData );
|
hServiceProvider = DP_LoadSP( &guidSP, &This->dp2->spData, &bIsDpSp );
|
||||||
|
|
||||||
if( hServiceProvider == 0 )
|
if( hServiceProvider == 0 )
|
||||||
{
|
{
|
||||||
|
@ -3966,22 +3991,35 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
||||||
return DPERR_UNAVAILABLE;
|
return DPERR_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the service provider by calling SPInit */
|
if( bIsDpSp )
|
||||||
SPInit = (LPDPSP_SPINIT)GetProcAddress( hServiceProvider, "SPInit" );
|
{
|
||||||
|
/* Initialize the service provider by calling SPInit */
|
||||||
|
SPInit = (LPDPSP_SPINIT)GetProcAddress( hServiceProvider, "SPInit" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Initialize the service provider by calling SPInit */
|
||||||
|
SPInit = (LPDPSP_SPINIT)GetProcAddress( hServiceProvider, "DPLSPInit" );
|
||||||
|
}
|
||||||
|
|
||||||
if( SPInit == NULL )
|
if( SPInit == NULL )
|
||||||
{
|
{
|
||||||
ERR( "Service provider doesn't provide SPInit interface?\n" );
|
ERR( "Service provider doesn't provide %s interface?\n",
|
||||||
|
bIsDpSp ? "SPInit" : "DPLSPInit" );
|
||||||
FreeLibrary( hServiceProvider );
|
FreeLibrary( hServiceProvider );
|
||||||
return DPERR_UNAVAILABLE;
|
return DPERR_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE( "Calling SPInit\n" );
|
TRACE( "Calling %s (SP entry point)\n", bIsDpSp ? "SPInit" : "DPLSPInit" );
|
||||||
|
|
||||||
|
/* FIXME: Need to break this out into a seperate routine for DP SP and
|
||||||
|
* DPL SP as they actually use different stuff...
|
||||||
|
*/
|
||||||
hr = (*SPInit)( &This->dp2->spData );
|
hr = (*SPInit)( &This->dp2->spData );
|
||||||
|
|
||||||
if( FAILED(hr) )
|
if( FAILED(hr) )
|
||||||
{
|
{
|
||||||
ERR( "SP Initialization failed: %s\n", DPLAYX_HresultToString(hr) );
|
ERR( "DP/DPL SP Initialization failed: %s\n", DPLAYX_HresultToString(hr) );
|
||||||
FreeLibrary( hServiceProvider );
|
FreeLibrary( hServiceProvider );
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -3995,12 +4033,18 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
||||||
return DP_OK;
|
return DP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
||||||
|
( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlay3Impl,iface);
|
||||||
|
return DP_IF_InitializeConnection( This, lpConnection, dwFlags, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
|
static HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
|
||||||
( LPDIRECTPLAY3 iface, LPVOID lpConnection, DWORD dwFlags )
|
( LPDIRECTPLAY3 iface, LPVOID lpConnection, DWORD dwFlags )
|
||||||
{
|
{
|
||||||
ICOM_THIS(IDirectPlay3Impl,iface);
|
ICOM_THIS(IDirectPlay3Impl,iface);
|
||||||
FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
|
return DP_IF_InitializeConnection( This, lpConnection, dwFlags, FALSE );
|
||||||
return DP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI DirectPlay3AImpl_SecureOpen
|
static HRESULT WINAPI DirectPlay3AImpl_SecureOpen
|
||||||
|
@ -4846,9 +4890,42 @@ static ICOM_VTABLE(IDirectPlay4) directPlay4AVT =
|
||||||
};
|
};
|
||||||
#undef XCAST
|
#undef XCAST
|
||||||
|
|
||||||
|
extern
|
||||||
|
HRESULT DP_GetSPPlayerData( IDirectPlay2Impl* lpDP,
|
||||||
|
DPID idPlayer,
|
||||||
|
LPVOID* lplpData )
|
||||||
|
{
|
||||||
|
lpPlayerList lpPlayer = DP_FindPlayer( lpDP, idPlayer );
|
||||||
|
|
||||||
|
if( lpPlayer == NULL )
|
||||||
|
{
|
||||||
|
return DPERR_INVALIDPLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lplpData = lpPlayer->lpPData->lpSPPlayerData;
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern
|
||||||
|
HRESULT DP_SetSPPlayerData( IDirectPlay2Impl* lpDP,
|
||||||
|
DPID idPlayer,
|
||||||
|
LPVOID lpData )
|
||||||
|
{
|
||||||
|
lpPlayerList lpPlayer = DP_FindPlayer( lpDP, idPlayer );
|
||||||
|
|
||||||
|
if( lpPlayer == NULL )
|
||||||
|
{
|
||||||
|
return DPERR_INVALIDPLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
lpPlayer->lpPData->lpSPPlayerData = lpData;
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* DirectPlayEnumerateA (DPLAYX.2)
|
* DirectPlayEnumerateA [DPLAYX.2][DPLAYX.9][DPLAY.2]
|
||||||
*
|
*
|
||||||
* The pointer to the structure lpContext will be filled with the
|
* The pointer to the structure lpContext will be filled with the
|
||||||
* appropriate data for each service offered by the OS. These services are
|
* appropriate data for each service offered by the OS. These services are
|
||||||
|
@ -4980,7 +5057,7 @@ HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* DirectPlayEnumerateW (DPLAYX.3)
|
* DirectPlayEnumerateW [DPLAYX.3]
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
|
HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
|
||||||
|
@ -5027,7 +5104,7 @@ static BOOL CALLBACK cbDPCreateEnumConnections(
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* DirectPlayCreate (DPLAYX.1) (DPLAY.1)
|
* DirectPlayCreate [DPLAYX.1][DPLAY.1]
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI DirectPlayCreate
|
HRESULT WINAPI DirectPlayCreate
|
||||||
|
@ -5044,7 +5121,6 @@ HRESULT WINAPI DirectPlayCreate
|
||||||
return CLASS_E_NOAGGREGATION;
|
return CLASS_E_NOAGGREGATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create an IDirectPlay object. We don't support that so we'll cheat and
|
/* Create an IDirectPlay object. We don't support that so we'll cheat and
|
||||||
give them an IDirectPlay2A object and hope that doesn't cause problems */
|
give them an IDirectPlay2A object and hope that doesn't cause problems */
|
||||||
if( DP_CreateInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) != DP_OK )
|
if( DP_CreateInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) != DP_OK )
|
||||||
|
|
|
@ -35,6 +35,21 @@ typedef struct tagEnumSessionAsyncCallbackData
|
||||||
HANDLE hSuicideRequest;
|
HANDLE hSuicideRequest;
|
||||||
} EnumSessionAsyncCallbackData;
|
} EnumSessionAsyncCallbackData;
|
||||||
|
|
||||||
|
typedef struct tagDP_MSG_REPLY_STRUCT
|
||||||
|
{
|
||||||
|
HANDLE hReceipt;
|
||||||
|
WORD wExpectedReply;
|
||||||
|
LPVOID lpReplyMsg;
|
||||||
|
DWORD dwMsgBodySize;
|
||||||
|
/* FIXME: Is the message header required as well? */
|
||||||
|
} DP_MSG_REPLY_STRUCT, *LPDP_MSG_REPLY_STRUCT;
|
||||||
|
|
||||||
|
typedef struct tagDP_MSG_REPLY_STRUCT_LIST
|
||||||
|
{
|
||||||
|
DPQ_ENTRY(tagDP_MSG_REPLY_STRUCT_LIST) replysExpected;
|
||||||
|
DP_MSG_REPLY_STRUCT replyExpected;
|
||||||
|
} DP_MSG_REPLY_STRUCT_LIST, *LPDP_MSG_REPLY_STRUCT_LIST;
|
||||||
|
|
||||||
struct PlayerData
|
struct PlayerData
|
||||||
{
|
{
|
||||||
/* Individual player information */
|
/* Individual player information */
|
||||||
|
@ -53,6 +68,9 @@ struct PlayerData
|
||||||
LPVOID lpRemoteData;
|
LPVOID lpRemoteData;
|
||||||
DWORD dwRemoteDataSize;
|
DWORD dwRemoteDataSize;
|
||||||
|
|
||||||
|
/* SP data on a per player basis */
|
||||||
|
LPVOID lpSPPlayerData;
|
||||||
|
|
||||||
DWORD dwFlags; /* Special remarks about the type of player */
|
DWORD dwFlags; /* Special remarks about the type of player */
|
||||||
};
|
};
|
||||||
typedef struct PlayerData* lpPlayerData;
|
typedef struct PlayerData* lpPlayerData;
|
||||||
|
@ -137,10 +155,8 @@ typedef struct tagDirectPlay2Data
|
||||||
|
|
||||||
BOOL bConnectionInitialized;
|
BOOL bConnectionInitialized;
|
||||||
|
|
||||||
|
/* Expected messages queue */
|
||||||
/* proof of concept for message reception */
|
DPQ_HEAD( tagDP_MSG_REPLY_STRUCT_LIST ) replysExpected;
|
||||||
HANDLE hMsgReceipt;
|
|
||||||
LPVOID lpMsgReceived;
|
|
||||||
} DirectPlay2Data;
|
} DirectPlay2Data;
|
||||||
|
|
||||||
typedef struct tagDirectPlay3Data
|
typedef struct tagDirectPlay3Data
|
||||||
|
@ -192,5 +208,11 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||||
WORD wCommandId, WORD wVersion,
|
WORD wCommandId, WORD wVersion,
|
||||||
LPVOID* lplpReply, LPDWORD lpdwMsgSize );
|
LPVOID* lplpReply, LPDWORD lpdwMsgSize );
|
||||||
|
|
||||||
|
/* DP SP external interfaces into DirectPlay */
|
||||||
|
extern HRESULT DP_GetSPPlayerData( IDirectPlay2Impl* lpDP, DPID idPlayer, LPVOID* lplpData );
|
||||||
|
extern HRESULT DP_SetSPPlayerData( IDirectPlay2Impl* lpDP, DPID idPlayer, LPVOID lpData );
|
||||||
|
|
||||||
|
/* DP external interfaces to call into DPSP interface */
|
||||||
|
extern LPVOID DPSP_CreateSPPlayerData(void);
|
||||||
|
|
||||||
#endif /* __WINE_DPLAY_GLOBAL_INCLUDED */
|
#endif /* __WINE_DPLAY_GLOBAL_INCLUDED */
|
||||||
|
|
|
@ -26,7 +26,6 @@ static BOOL DPSP_DestroyIUnknown( LPVOID lpSP );
|
||||||
static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp );
|
static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp );
|
||||||
static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP );
|
static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP );
|
||||||
|
|
||||||
|
|
||||||
/* Predefine the interface */
|
/* Predefine the interface */
|
||||||
typedef struct IDirectPlaySPImpl IDirectPlaySPImpl;
|
typedef struct IDirectPlaySPImpl IDirectPlaySPImpl;
|
||||||
|
|
||||||
|
@ -46,8 +45,6 @@ typedef struct tagDirectPlaySPData
|
||||||
|
|
||||||
IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */
|
IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */
|
||||||
|
|
||||||
LPVOID lpPlayerData; /* FIXME: Need to figure out how this actually behaves */
|
|
||||||
DWORD dwPlayerDataSize;
|
|
||||||
} DirectPlaySPData;
|
} DirectPlaySPData;
|
||||||
|
|
||||||
#define DPSP_IMPL_FIELDS \
|
#define DPSP_IMPL_FIELDS \
|
||||||
|
@ -64,7 +61,15 @@ struct IDirectPlaySPImpl
|
||||||
/* Forward declaration of virtual tables */
|
/* Forward declaration of virtual tables */
|
||||||
static ICOM_VTABLE(IDirectPlaySP) directPlaySPVT;
|
static ICOM_VTABLE(IDirectPlaySP) directPlaySPVT;
|
||||||
|
|
||||||
|
/* This structure is passed to the DP object for safe keeping */
|
||||||
|
typedef struct tagDP_SPPLAYERDATA
|
||||||
|
{
|
||||||
|
LPVOID lpPlayerLocalData;
|
||||||
|
DWORD dwPlayerLocalDataSize;
|
||||||
|
|
||||||
|
LPVOID lpPlayerRemoteData;
|
||||||
|
DWORD dwPlayerRemoteDataSize;
|
||||||
|
} DP_SPPLAYERDATA, *LPDP_SPPLAYERDATA;
|
||||||
|
|
||||||
/* Create the SP interface */
|
/* Create the SP interface */
|
||||||
extern
|
extern
|
||||||
|
@ -165,6 +170,15 @@ static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp )
|
||||||
*/
|
*/
|
||||||
/* IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp ); */
|
/* IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp ); */
|
||||||
|
|
||||||
|
/* FIXME: This is a kludge to get around a problem where a queryinterface
|
||||||
|
* is used to get a new interface and then is closed. We will then
|
||||||
|
* reference garbage. However, with this we will never deallocate
|
||||||
|
* the interface we store. The correct fix is to require all
|
||||||
|
* DP internal interfaces to use the This->dp2 interface which
|
||||||
|
* should be changed to This->dp
|
||||||
|
*/
|
||||||
|
IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp );
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,14 +214,14 @@ static HRESULT WINAPI DPSP_QueryInterface
|
||||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
||||||
|
|
||||||
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
sizeof( IDirectPlaySPImpl ) );
|
sizeof( *This ) );
|
||||||
|
|
||||||
if( *ppvObj == NULL )
|
if( *ppvObj == NULL )
|
||||||
{
|
{
|
||||||
return DPERR_OUTOFMEMORY;
|
return DPERR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMemory( *ppvObj, iface, sizeof( IDirectPlaySPImpl ) );
|
CopyMemory( *ppvObj, This, sizeof( *This ) );
|
||||||
(*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0;
|
(*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0;
|
||||||
|
|
||||||
if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
|
if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
|
||||||
|
@ -363,18 +377,50 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
|
||||||
DWORD dwFlags
|
DWORD dwFlags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
LPDP_SPPLAYERDATA lpPlayerData;
|
||||||
ICOM_THIS(IDirectPlaySPImpl,iface);
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
|
||||||
FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n",
|
TRACE( "(%p)->(0x%08lx,%p,%p,0x%08lx)\n",
|
||||||
This, idPlayer, lplpData, lpdwDataSize, dwFlags );
|
This, idPlayer, lplpData, lpdwDataSize, dwFlags );
|
||||||
|
|
||||||
|
hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerData );
|
||||||
|
|
||||||
|
if( FAILED(hr) )
|
||||||
|
{
|
||||||
|
TRACE( "Couldn't get player data: %s\n", DPLAYX_HresultToString(hr) );
|
||||||
|
return DPERR_INVALIDPLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
/* What to do in the case where there is nothing set yet? */
|
/* What to do in the case where there is nothing set yet? */
|
||||||
|
if( dwFlags == DPSET_LOCAL )
|
||||||
|
{
|
||||||
|
if( lpPlayerData->lpPlayerLocalData )
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerLocalData );
|
||||||
|
}
|
||||||
|
|
||||||
*lplpData = This->sp->lpPlayerData;
|
*lplpData = lpPlayerData->lpPlayerLocalData;
|
||||||
*lpdwDataSize = This->sp->dwPlayerDataSize;
|
*lpdwDataSize = lpPlayerData->dwPlayerLocalDataSize;
|
||||||
|
}
|
||||||
|
else if( dwFlags == DPSET_REMOTE )
|
||||||
|
{
|
||||||
|
if( lpPlayerData->lpPlayerRemoteData )
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerRemoteData );
|
||||||
|
}
|
||||||
|
|
||||||
return DP_OK;
|
*lplpData = lpPlayerData->lpPlayerRemoteData;
|
||||||
|
*lpdwDataSize = lpPlayerData->dwPlayerRemoteDataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *lplpData == NULL )
|
||||||
|
{
|
||||||
|
hr = DPERR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
|
@ -391,7 +437,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
|
|
||||||
ICOM_THIS(IDirectPlaySPImpl,iface);
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
|
||||||
FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n",
|
FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n",
|
||||||
This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
|
This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
|
||||||
|
|
||||||
|
@ -409,6 +455,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
switch( lpMsg->wCommandId )
|
switch( lpMsg->wCommandId )
|
||||||
{
|
{
|
||||||
/* Name server needs to handle this request */
|
/* Name server needs to handle this request */
|
||||||
|
/* FIXME: This should be done in direct play handler */
|
||||||
case DPMSGCMD_ENUMSESSIONSREQUEST:
|
case DPMSGCMD_ENUMSESSIONSREQUEST:
|
||||||
{
|
{
|
||||||
DPSP_REPLYDATA data;
|
DPSP_REPLYDATA data;
|
||||||
|
@ -430,6 +477,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Name server needs to handle this request */
|
/* Name server needs to handle this request */
|
||||||
|
/* FIXME: This should be done in direct play handler */
|
||||||
case DPMSGCMD_ENUMSESSIONSREPLY:
|
case DPMSGCMD_ENUMSESSIONSREPLY:
|
||||||
{
|
{
|
||||||
NS_SetRemoteComputerAsNameServer( lpMessageHeader,
|
NS_SetRemoteComputerAsNameServer( lpMessageHeader,
|
||||||
|
@ -438,14 +486,13 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
This->sp->dplay->dp2->lpNameServerData );
|
This->sp->dplay->dp2->lpNameServerData );
|
||||||
|
|
||||||
/* No reply expected */
|
/* No reply expected */
|
||||||
|
hr = DP_OK;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DPMSGCMD_GETNAMETABLE:
|
/* Pass everything else to Direct Play */
|
||||||
case DPMSGCMD_GETNAMETABLEREPLY:
|
default:
|
||||||
case DPMSGCMD_NEWPLAYERIDREPLY:
|
|
||||||
case DPMSGCMD_REQUESTNEWPLAYERID:
|
|
||||||
{
|
{
|
||||||
DPSP_REPLYDATA data;
|
DPSP_REPLYDATA data;
|
||||||
|
|
||||||
|
@ -453,9 +500,9 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
data.dwMessageSize = 0;
|
data.dwMessageSize = 0;
|
||||||
|
|
||||||
/* Pass this message to the dplay interface to handle */
|
/* Pass this message to the dplay interface to handle */
|
||||||
DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
|
hr = DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
|
||||||
lpMessageHeader, wCommandId, wVersion,
|
lpMessageHeader, wCommandId, wVersion,
|
||||||
&data.lpMessage, &data.dwMessageSize );
|
&data.lpMessage, &data.dwMessageSize );
|
||||||
|
|
||||||
/* Do we want a reply? */
|
/* Do we want a reply? */
|
||||||
if( data.lpMessage != NULL )
|
if( data.lpMessage != NULL )
|
||||||
|
@ -476,10 +523,6 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
FIXME( "Unknown Command of %u and size 0x%08lx\n",
|
|
||||||
lpMsg->wCommandId, dwMessageBodySize );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -736,22 +779,40 @@ static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
|
||||||
DWORD dwFlags
|
DWORD dwFlags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
LPDP_SPPLAYERDATA lpPlayerEntry;
|
||||||
|
LPVOID lpPlayerData;
|
||||||
|
|
||||||
ICOM_THIS(IDirectPlaySPImpl,iface);
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
/* FIXME: I'm not sure if this stuff should be associated with the DPlay
|
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
|
||||||
* player lists. How else would this stuff get deleted?
|
TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n",
|
||||||
*/
|
|
||||||
|
|
||||||
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
|
||||||
FIXME( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n",
|
|
||||||
This, idPlayer, lpData, dwDataSize, dwFlags );
|
This, idPlayer, lpData, dwDataSize, dwFlags );
|
||||||
|
|
||||||
This->sp->lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
|
hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerEntry );
|
||||||
|
if( FAILED(hr) )
|
||||||
|
{
|
||||||
|
/* Player must not exist */
|
||||||
|
return DPERR_INVALIDPLAYER;
|
||||||
|
}
|
||||||
|
|
||||||
This->sp->dwPlayerDataSize = dwDataSize;
|
lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
|
||||||
CopyMemory( This->sp->lpPlayerData, lpData, dwDataSize );
|
CopyMemory( lpPlayerData, lpData, dwDataSize );
|
||||||
|
|
||||||
return DP_OK;
|
if( dwFlags == DPSET_LOCAL )
|
||||||
|
{
|
||||||
|
lpPlayerEntry->lpPlayerLocalData = lpPlayerData;
|
||||||
|
lpPlayerEntry->dwPlayerLocalDataSize = dwDataSize;
|
||||||
|
}
|
||||||
|
else if( dwFlags == DPSET_REMOTE )
|
||||||
|
{
|
||||||
|
lpPlayerEntry->lpPlayerRemoteData = lpPlayerData;
|
||||||
|
lpPlayerEntry->dwPlayerRemoteDataSize = dwDataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = DP_SetSPPlayerData( This->sp->dplay, idPlayer, lpPlayerEntry );
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
|
static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
|
||||||
|
@ -777,15 +838,16 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
|
||||||
DWORD dwFlags
|
DWORD dwFlags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
HRESULT hr = DP_OK;
|
||||||
ICOM_THIS(IDirectPlaySPImpl,iface);
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
|
||||||
TRACE( "(%p)->(%p,%p,0x%08lx)\n",
|
TRACE( "(%p)->(%p,%p,0x%08lx)\n",
|
||||||
This, lplpData, lpdwDataSize, dwFlags );
|
This, lplpData, lpdwDataSize, dwFlags );
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* This is what the documentation says... */
|
/* This is what the documentation says... */
|
||||||
if( dwFlags != 0 )
|
if( dwFlags != DPSET_REMOTE )
|
||||||
{
|
{
|
||||||
return DPERR_INVALIDPARAMS;
|
return DPERR_INVALIDPARAMS;
|
||||||
}
|
}
|
||||||
|
@ -794,7 +856,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
|
||||||
/* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
|
/* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
|
||||||
* thing?
|
* thing?
|
||||||
*/
|
*/
|
||||||
if( dwFlags != 0 )
|
if( dwFlags != DPSET_REMOTE )
|
||||||
{
|
{
|
||||||
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
|
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
|
||||||
}
|
}
|
||||||
|
@ -807,14 +869,24 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
|
||||||
{
|
{
|
||||||
*lpdwDataSize = This->sp->dwSpRemoteDataSize;
|
*lpdwDataSize = This->sp->dwSpRemoteDataSize;
|
||||||
*lplpData = This->sp->lpSpRemoteData;
|
*lplpData = This->sp->lpSpRemoteData;
|
||||||
|
|
||||||
|
if( This->sp->lpSpRemoteData == NULL )
|
||||||
|
{
|
||||||
|
hr = DPERR_GENERIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( dwFlags == DPSET_LOCAL )
|
else if( dwFlags == DPSET_LOCAL )
|
||||||
{
|
{
|
||||||
*lpdwDataSize = This->sp->dwSpLocalDataSize;
|
*lpdwDataSize = This->sp->dwSpLocalDataSize;
|
||||||
*lplpData = This->sp->lpSpLocalData;
|
*lplpData = This->sp->lpSpLocalData;
|
||||||
|
|
||||||
|
if( This->sp->lpSpLocalData == NULL )
|
||||||
|
{
|
||||||
|
hr = DPERR_GENERIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DP_OK;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
|
static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
|
||||||
|
@ -828,13 +900,13 @@ static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
|
||||||
|
|
||||||
ICOM_THIS(IDirectPlaySPImpl,iface);
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
|
||||||
TRACE( "(%p)->(%p,0x%08lx,0x%08lx)\n",
|
TRACE( "(%p)->(%p,0x%08lx,0x%08lx)\n",
|
||||||
This, lpData, dwDataSize, dwFlags );
|
This, lpData, dwDataSize, dwFlags );
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* This is what the documentation says... */
|
/* This is what the documentation says... */
|
||||||
if( dwFlags != 0 )
|
if( dwFlags != DPSET_REMOTE )
|
||||||
{
|
{
|
||||||
return DPERR_INVALIDPARAMS;
|
return DPERR_INVALIDPARAMS;
|
||||||
}
|
}
|
||||||
|
@ -843,35 +915,23 @@ static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
|
||||||
/* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
|
/* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
|
||||||
* thing?
|
* thing?
|
||||||
*/
|
*/
|
||||||
if( dwFlags != 0 )
|
if( dwFlags != DPSET_REMOTE )
|
||||||
{
|
{
|
||||||
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
|
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( dwFlags == DPSET_REMOTE )
|
lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
|
||||||
{
|
|
||||||
lpSpData = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, dwDataSize );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
|
|
||||||
}
|
|
||||||
|
|
||||||
CopyMemory( lpSpData, lpData, dwDataSize );
|
CopyMemory( lpSpData, lpData, dwDataSize );
|
||||||
|
|
||||||
/* If we have data already allocated, free it and replace it */
|
/* If we have data already allocated, free it and replace it */
|
||||||
if( dwFlags == DPSET_REMOTE )
|
if( dwFlags == DPSET_REMOTE )
|
||||||
{
|
{
|
||||||
/* FIXME: This doesn't strictly make sense as there is no means to share
|
|
||||||
* this shared data. Must be misinterpreting something...
|
|
||||||
*/
|
|
||||||
if( This->sp->lpSpRemoteData )
|
if( This->sp->lpSpRemoteData )
|
||||||
{
|
{
|
||||||
DPLAYX_PrivHeapFree( This->sp->lpSpRemoteData );
|
HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: dwDataSize is also stored in the heap structure */
|
|
||||||
This->sp->dwSpRemoteDataSize = dwDataSize;
|
This->sp->dwSpRemoteDataSize = dwDataSize;
|
||||||
This->sp->lpSpRemoteData = lpSpData;
|
This->sp->lpSpRemoteData = lpSpData;
|
||||||
}
|
}
|
||||||
|
@ -923,3 +983,15 @@ static struct ICOM_VTABLE(IDirectPlaySP) directPlaySPVT =
|
||||||
IDirectPlaySPImpl_SetSPData,
|
IDirectPlaySPImpl_SetSPData,
|
||||||
IDirectPlaySPImpl_SendComplete
|
IDirectPlaySPImpl_SendComplete
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* DP external interfaces to call into DPSP interface */
|
||||||
|
|
||||||
|
/* Allocate the structure */
|
||||||
|
extern LPVOID DPSP_CreateSPPlayerData(void)
|
||||||
|
{
|
||||||
|
TRACE( "Creating SPPlayer data struct\n" );
|
||||||
|
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
sizeof( DP_SPPLAYERDATA ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,11 @@ typedef struct tagMSGTHREADINFO
|
||||||
HANDLE hNotifyEvent;
|
HANDLE hNotifyEvent;
|
||||||
} MSGTHREADINFO, *LPMSGTHREADINFO;
|
} MSGTHREADINFO, *LPMSGTHREADINFO;
|
||||||
|
|
||||||
|
|
||||||
static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext );
|
static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext );
|
||||||
|
static LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA data,
|
||||||
|
DWORD dwWaitTime, WORD wReplyCommandId,
|
||||||
|
LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize );
|
||||||
|
|
||||||
|
|
||||||
/* Create the message reception thread to allow the application to receive
|
/* Create the message reception thread to allow the application to receive
|
||||||
* asynchronous message reception
|
* asynchronous message reception
|
||||||
|
@ -139,6 +142,42 @@ end_of_thread:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DP messageing stuff */
|
||||||
|
static HANDLE DP_MSG_BuildAndLinkReplyStruct( IDirectPlay2Impl* This,
|
||||||
|
LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList,
|
||||||
|
WORD wReplyCommandId );
|
||||||
|
static LPVOID DP_MSG_CleanReplyStruct( LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList,
|
||||||
|
LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize );
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
HANDLE DP_MSG_BuildAndLinkReplyStruct( IDirectPlay2Impl* This,
|
||||||
|
LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList, WORD wReplyCommandId )
|
||||||
|
{
|
||||||
|
lpReplyStructList->replyExpected.hReceipt = CreateEventA( NULL, FALSE, FALSE, NULL );
|
||||||
|
lpReplyStructList->replyExpected.wExpectedReply = wReplyCommandId;
|
||||||
|
lpReplyStructList->replyExpected.lpReplyMsg = NULL;
|
||||||
|
lpReplyStructList->replyExpected.dwMsgBodySize = 0;
|
||||||
|
|
||||||
|
/* Insert into the message queue while locked */
|
||||||
|
EnterCriticalSection( &This->unk->DP_lock );
|
||||||
|
DPQ_INSERT( This->dp2->replysExpected, lpReplyStructList, replysExpected );
|
||||||
|
LeaveCriticalSection( &This->unk->DP_lock );
|
||||||
|
|
||||||
|
return lpReplyStructList->replyExpected.hReceipt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
LPVOID DP_MSG_CleanReplyStruct( LPDP_MSG_REPLY_STRUCT_LIST lpReplyStructList,
|
||||||
|
LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize )
|
||||||
|
{
|
||||||
|
CloseHandle( lpReplyStructList->replyExpected.hReceipt );
|
||||||
|
|
||||||
|
*lplpReplyMsg = lpReplyStructList->replyExpected.lpReplyMsg;
|
||||||
|
*lpdwMsgBodySize = lpReplyStructList->replyExpected.dwMsgBodySize;
|
||||||
|
|
||||||
|
return lpReplyStructList->replyExpected.lpReplyMsg;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
LPDPID lpdpidAllocatedId )
|
LPDPID lpdpidAllocatedId )
|
||||||
|
@ -146,7 +185,6 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
LPVOID lpMsg;
|
LPVOID lpMsg;
|
||||||
LPDPMSG_REQUESTNEWPLAYERID lpMsgBody;
|
LPDPMSG_REQUESTNEWPLAYERID lpMsgBody;
|
||||||
DWORD dwMsgSize;
|
DWORD dwMsgSize;
|
||||||
DWORD dwWaitReturn;
|
|
||||||
HRESULT hr = DP_OK;
|
HRESULT hr = DP_OK;
|
||||||
|
|
||||||
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
|
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
|
||||||
|
@ -156,19 +194,16 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
lpMsgBody = (LPDPMSG_REQUESTNEWPLAYERID)( (BYTE*)lpMsg +
|
lpMsgBody = (LPDPMSG_REQUESTNEWPLAYERID)( (BYTE*)lpMsg +
|
||||||
This->dp2->spData.dwSPHeaderSize );
|
This->dp2->spData.dwSPHeaderSize );
|
||||||
|
|
||||||
|
/* Compose dplay message envelope */
|
||||||
lpMsgBody->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
|
lpMsgBody->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
|
||||||
lpMsgBody->envelope.wCommandId = DPMSGCMD_REQUESTNEWPLAYERID;
|
lpMsgBody->envelope.wCommandId = DPMSGCMD_REQUESTNEWPLAYERID;
|
||||||
lpMsgBody->envelope.wVersion = DPMSGVER_DP6;
|
lpMsgBody->envelope.wVersion = DPMSGVER_DP6;
|
||||||
|
|
||||||
|
/* Compose the body of the message */
|
||||||
lpMsgBody->dwFlags = dwFlags;
|
lpMsgBody->dwFlags = dwFlags;
|
||||||
|
|
||||||
/* FIXME: Need to have a more advanced queuing system as this needs to
|
/* Send the message */
|
||||||
* block on send until we get response. Otherwise we need to be
|
{
|
||||||
* able to ensure we can pick out the exact response. Of course,
|
|
||||||
* with something as non critical as this, would it matter? The
|
|
||||||
* id has been effectively reserved for this session...
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
DPSP_SENDDATA data;
|
DPSP_SENDDATA data;
|
||||||
|
|
||||||
data.dwFlags = DPSEND_GUARANTEED;
|
data.dwFlags = DPSEND_GUARANTEED;
|
||||||
|
@ -179,37 +214,20 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
data.bSystemMessage = TRUE; /* Allow reply to be sent */
|
data.bSystemMessage = TRUE; /* Allow reply to be sent */
|
||||||
data.lpISP = This->dp2->spData.lpISP;
|
data.lpISP = This->dp2->spData.lpISP;
|
||||||
|
|
||||||
/* Setup for receipt */
|
TRACE( "Asking for player id w/ dwFlags 0x%08lx\n",
|
||||||
This->dp2->hMsgReceipt = CreateEventA( NULL, FALSE, FALSE, NULL );
|
lpMsgBody->dwFlags );
|
||||||
|
|
||||||
TRACE( "Sending request for player id\n" );
|
|
||||||
|
|
||||||
hr = (*This->dp2->spData.lpCB->Send)( &data );
|
|
||||||
|
|
||||||
if( FAILED(hr) )
|
DP_MSG_ExpectReply( This, &data, DPMSG_DEFAULT_WAIT_TIME, DPMSGCMD_NEWPLAYERIDREPLY,
|
||||||
{
|
&lpMsg, &dwMsgSize );
|
||||||
ERR( "Request for new playerID send failed: %s\n",
|
|
||||||
DPLAYX_HresultToString( hr ) );
|
|
||||||
return DPERR_NOCONNECTION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dwWaitReturn = WaitForSingleObject( This->dp2->hMsgReceipt, 30000 );
|
|
||||||
if( dwWaitReturn != WAIT_OBJECT_0 )
|
|
||||||
{
|
|
||||||
ERR( "Wait failed 0x%08lx\n", dwWaitReturn );
|
|
||||||
hr = DPERR_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle( This->dp2->hMsgReceipt );
|
|
||||||
This->dp2->hMsgReceipt = 0;
|
|
||||||
|
|
||||||
/* Need to examine the data and extract the new player id */
|
/* Need to examine the data and extract the new player id */
|
||||||
if( !FAILED(hr) )
|
if( !FAILED(hr) )
|
||||||
{
|
{
|
||||||
LPCDPMSG_NEWPLAYERIDREPLY lpcReply;
|
LPCDPMSG_NEWPLAYERIDREPLY lpcReply;
|
||||||
|
|
||||||
lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)This->dp2->lpMsgReceived;
|
lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)lpMsg;
|
||||||
|
|
||||||
*lpdpidAllocatedId = lpcReply->dpidNewPlayerId;
|
*lpdpidAllocatedId = lpcReply->dpidNewPlayerId;
|
||||||
|
|
||||||
|
@ -217,47 +235,217 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
|
|
||||||
/* FIXME: I think that the rest of the message has something to do
|
/* FIXME: I think that the rest of the message has something to do
|
||||||
* with remote data for the player that perhaps I need to setup.
|
* with remote data for the player that perhaps I need to setup.
|
||||||
|
* However, with the information that is passed, all that it could
|
||||||
|
* be used for is a standardized intialization value, which I'm
|
||||||
|
* guessing we can do without. Unless the message content is the same
|
||||||
|
* for several different messages?
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
/* Set the passed service provider data */
|
|
||||||
IDirectPlaySP_SetSPData( This->dp2->spData.lpISP, data,
|
|
||||||
msgsize, DPSET_REMOTE );
|
|
||||||
|
|
||||||
#endif
|
HeapFree( GetProcessHeap(), 0, lpMsg );
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, This->dp2->lpMsgReceived );
|
|
||||||
This->dp2->lpMsgReceived = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer )
|
||||||
/* This function seems to cause a trap in the SP. It would seem unnecessary */
|
|
||||||
/* FIXME: Remove this method if not required */
|
|
||||||
HRESULT DP_MSG_OpenStream( IDirectPlay2AImpl* This )
|
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
LPVOID lpMsg;
|
||||||
DPSP_SENDDATA data;
|
LPDPMSG_FORWARDADDPLAYER lpMsgBody;
|
||||||
|
DWORD dwMsgSize;
|
||||||
|
HRESULT hr = DP_OK;
|
||||||
|
|
||||||
data.dwFlags = DPSEND_OPENSTREAM;
|
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
|
||||||
data.idPlayerTo = 0; /* Name server */
|
|
||||||
data.idPlayerFrom = 0; /* From DP itself */
|
|
||||||
data.lpMessage = NULL;
|
|
||||||
data.dwMessageSize = This->dp2->spData.dwSPHeaderSize;
|
|
||||||
data.bSystemMessage = FALSE; /* FIXME? */
|
|
||||||
data.lpISP = This->dp2->spData.lpISP;
|
|
||||||
|
|
||||||
hr = (*This->dp2->spData.lpCB->Send)( &data );
|
lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
|
||||||
|
|
||||||
|
lpMsgBody = (LPDPMSG_FORWARDADDPLAYER)( (BYTE*)lpMsg +
|
||||||
|
This->dp2->spData.dwSPHeaderSize );
|
||||||
|
|
||||||
|
/* Compose dplay message envelope */
|
||||||
|
lpMsgBody->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
|
||||||
|
lpMsgBody->envelope.wCommandId = DPMSGCMD_FORWARDADDPLAYER;
|
||||||
|
lpMsgBody->envelope.wVersion = DPMSGVER_DP6;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
LPBYTE lpPData;
|
||||||
|
DWORD dwDataSize;
|
||||||
|
|
||||||
|
/* SP Player remote data needs to be propagated at some point - is this the point? */
|
||||||
|
IDirectPlaySP_GetSPPlayerData( This->dp2->spData.lpISP, dpidServer, (LPVOID*)&lpPData, &dwDataSize, DPSET_REMOTE );
|
||||||
|
|
||||||
|
ERR( "Player Data size is 0x%08lx\n"
|
||||||
|
"[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n"
|
||||||
|
"[%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x]\n",
|
||||||
|
|
||||||
|
dwDataSize,
|
||||||
|
lpPData[0], lpPData[1], lpPData[2], lpPData[3], lpPData[4],
|
||||||
|
lpPData[5], lpPData[6], lpPData[7], lpPData[8], lpPData[9],
|
||||||
|
lpPData[10], lpPData[11], lpPData[12], lpPData[13], lpPData[14],
|
||||||
|
lpPData[15], lpPData[16], lpPData[17], lpPData[18], lpPData[19],
|
||||||
|
lpPData[20], lpPData[21], lpPData[22], lpPData[23], lpPData[24],
|
||||||
|
lpPData[25], lpPData[26], lpPData[27], lpPData[28], lpPData[29],
|
||||||
|
lpPData[30], lpPData[31]
|
||||||
|
);
|
||||||
|
DebugBreak();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Compose body of message */
|
||||||
|
lpMsgBody->dpidAppServer = dpidServer;
|
||||||
|
lpMsgBody->unknown2[0] = 0x0;
|
||||||
|
lpMsgBody->unknown2[1] = 0x1c;
|
||||||
|
lpMsgBody->unknown2[2] = 0x6c;
|
||||||
|
lpMsgBody->unknown2[3] = 0x50;
|
||||||
|
lpMsgBody->unknown2[4] = 0x9;
|
||||||
|
|
||||||
|
lpMsgBody->dpidAppServer2 = dpidServer;
|
||||||
|
lpMsgBody->unknown3[0] = 0x0;
|
||||||
|
lpMsgBody->unknown3[0] = 0x0;
|
||||||
|
lpMsgBody->unknown3[0] = 0x20;
|
||||||
|
lpMsgBody->unknown3[0] = 0x0;
|
||||||
|
lpMsgBody->unknown3[0] = 0x0;
|
||||||
|
|
||||||
|
lpMsgBody->dpidAppServer3 = dpidServer;
|
||||||
|
lpMsgBody->unknown4[0] = 0x30;
|
||||||
|
lpMsgBody->unknown4[1] = 0xb;
|
||||||
|
lpMsgBody->unknown4[2] = 0x0;
|
||||||
|
lpMsgBody->unknown4[3] = 0x1e090002;
|
||||||
|
lpMsgBody->unknown4[4] = 0x0;
|
||||||
|
lpMsgBody->unknown4[5] = 0x0;
|
||||||
|
lpMsgBody->unknown4[6] = 0x0;
|
||||||
|
lpMsgBody->unknown4[7] = 0x32090002;
|
||||||
|
lpMsgBody->unknown4[8] = 0x0;
|
||||||
|
lpMsgBody->unknown4[9] = 0x0;
|
||||||
|
lpMsgBody->unknown4[10] = 0x0;
|
||||||
|
lpMsgBody->unknown4[11] = 0x0;
|
||||||
|
lpMsgBody->unknown4[12] = 0x0;
|
||||||
|
|
||||||
|
lpMsgBody->unknown5[0] = 0x0;
|
||||||
|
lpMsgBody->unknown5[1] = 0x0;
|
||||||
|
|
||||||
|
/* Send the message */
|
||||||
|
{
|
||||||
|
DPSP_SENDDATA data;
|
||||||
|
|
||||||
|
data.dwFlags = DPSEND_GUARANTEED;
|
||||||
|
data.idPlayerTo = 0; /* Name server */
|
||||||
|
data.idPlayerFrom = dpidServer; /* Sending from session server */
|
||||||
|
data.lpMessage = lpMsg;
|
||||||
|
data.dwMessageSize = dwMsgSize;
|
||||||
|
data.bSystemMessage = TRUE; /* Allow reply to be sent */
|
||||||
|
data.lpISP = This->dp2->spData.lpISP;
|
||||||
|
|
||||||
|
lpMsg = DP_MSG_ExpectReply( This, &data,
|
||||||
|
DPMSG_WAIT_60_SECS,
|
||||||
|
DPMSGCMD_GETNAMETABLEREPLY,
|
||||||
|
&lpMsg, &dwMsgSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to examine the data and extract the new player id */
|
||||||
|
if( lpMsg != NULL )
|
||||||
|
{
|
||||||
|
FIXME( "Name Table reply received: stub\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Queue up a structure indicating that we want a reply of type wReplyCommandId. DPlay does
|
||||||
|
* not seem to offer any way of uniquely differentiating between replies of the same type
|
||||||
|
* relative to the request sent. There is an implicit assumption that there will be no
|
||||||
|
* ordering issues on sends and receives from the opposite machine. No wonder MS is not
|
||||||
|
* a networking company.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
LPVOID DP_MSG_ExpectReply( IDirectPlay2AImpl* This, LPDPSP_SENDDATA lpData,
|
||||||
|
DWORD dwWaitTime, WORD wReplyCommandId,
|
||||||
|
LPVOID* lplpReplyMsg, LPDWORD lpdwMsgBodySize )
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
HANDLE hMsgReceipt;
|
||||||
|
DP_MSG_REPLY_STRUCT_LIST replyStructList;
|
||||||
|
DWORD dwWaitReturn;
|
||||||
|
|
||||||
|
/* Setup for receipt */
|
||||||
|
hMsgReceipt = DP_MSG_BuildAndLinkReplyStruct( This, &replyStructList,
|
||||||
|
wReplyCommandId );
|
||||||
|
|
||||||
|
TRACE( "Sending msg and expecting cmd %u in reply within %lu ticks\n",
|
||||||
|
wReplyCommandId, dwWaitTime );
|
||||||
|
hr = (*This->dp2->spData.lpCB->Send)( lpData );
|
||||||
|
|
||||||
if( FAILED(hr) )
|
if( FAILED(hr) )
|
||||||
{
|
{
|
||||||
ERR( "Request for open stream send failed: %s\n",
|
ERR( "Request for new playerID send failed: %s\n",
|
||||||
DPLAYX_HresultToString( hr ) );
|
DPLAYX_HresultToString( hr ) );
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: hack to give some time for channel to open */
|
dwWaitReturn = WaitForSingleObject( hMsgReceipt, dwWaitTime );
|
||||||
SleepEx( 1000 /* 1 sec */, FALSE );
|
if( dwWaitReturn != WAIT_OBJECT_0 )
|
||||||
|
{
|
||||||
|
ERR( "Wait failed 0x%08lx\n", dwWaitReturn );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
/* Clean Up */
|
||||||
|
return DP_MSG_CleanReplyStruct( &replyStructList, lplpReplyMsg, lpdwMsgBodySize );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine if there is a matching request for this incomming message and then copy
|
||||||
|
* all important data. It is quite silly to have to copy the message, but the documents
|
||||||
|
* indicate that a copy is taken. Silly really.
|
||||||
|
*/
|
||||||
|
void DP_MSG_ReplyReceived( IDirectPlay2AImpl* This, WORD wCommandId,
|
||||||
|
LPCVOID lpcMsgBody, DWORD dwMsgBodySize )
|
||||||
|
{
|
||||||
|
LPDP_MSG_REPLY_STRUCT_LIST lpReplyList;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if( wCommandId == DPMSGCMD_FORWARDADDPLAYER )
|
||||||
|
{
|
||||||
|
DebugBreak();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Find, and immediately remove (to avoid double triggering), the appropriate entry. Call locked to
|
||||||
|
* avoid problems.
|
||||||
|
*/
|
||||||
|
EnterCriticalSection( &This->unk->DP_lock );
|
||||||
|
DPQ_REMOVE_ENTRY( This->dp2->replysExpected, replysExpected, replyExpected.wExpectedReply,\
|
||||||
|
==, wCommandId, lpReplyList );
|
||||||
|
LeaveCriticalSection( &This->unk->DP_lock );
|
||||||
|
|
||||||
|
if( lpReplyList != NULL )
|
||||||
|
{
|
||||||
|
lpReplyList->replyExpected.dwMsgBodySize = dwMsgBodySize;
|
||||||
|
lpReplyList->replyExpected.lpReplyMsg = HeapAlloc( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
dwMsgBodySize );
|
||||||
|
CopyMemory( lpReplyList->replyExpected.lpReplyMsg,
|
||||||
|
lpcMsgBody, dwMsgBodySize );
|
||||||
|
|
||||||
|
/* Signal the thread which sent the message that it has a reply */
|
||||||
|
SetEvent( lpReplyList->replyExpected.hReceipt );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERR( "No receipt event set - only expecting in reply mode\n" );
|
||||||
|
DebugBreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DP_MSG_ErrorReceived( IDirectPlay2AImpl* This, WORD wCommandId,
|
||||||
|
LPCVOID lpMsgBody, DWORD dwMsgBodySize )
|
||||||
|
{
|
||||||
|
LPCDPMSG_FORWARDADDPLAYERNACK lpcErrorMsg;
|
||||||
|
|
||||||
|
lpcErrorMsg = (LPCDPMSG_FORWARDADDPLAYERNACK)lpMsgBody;
|
||||||
|
|
||||||
|
ERR( "Received error message %u. Error is %s\n",
|
||||||
|
wCommandId, DPLAYX_HresultToString( lpcErrorMsg->errorCode) );
|
||||||
|
DebugBreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,20 @@
|
||||||
DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
HANDLE hDeath, HANDLE hConnRead );
|
HANDLE hDeath, HANDLE hConnRead );
|
||||||
|
|
||||||
|
HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
|
LPDPID lpdipidAllocatedId );
|
||||||
|
HRESULT DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer );
|
||||||
|
|
||||||
|
void DP_MSG_ReplyReceived( IDirectPlay2AImpl* This, WORD wCommandId,
|
||||||
|
LPCVOID lpMsgBody, DWORD dwMsgBodySize );
|
||||||
|
void DP_MSG_ErrorReceived( IDirectPlay2AImpl* This, WORD wCommandId,
|
||||||
|
LPCVOID lpMsgBody, DWORD dwMsgBodySize );
|
||||||
|
|
||||||
|
/* Timings -> 1000 ticks/sec */
|
||||||
|
#define DPMSG_WAIT_5_SECS 5000
|
||||||
|
#define DPMSG_WAIT_30_SECS 30000
|
||||||
|
#define DPMSG_WAIT_60_SECS 60000
|
||||||
|
#define DPMSG_DEFAULT_WAIT_TIME DPMSG_WAIT_30_SECS
|
||||||
|
|
||||||
/* Message types etc. */
|
/* Message types etc. */
|
||||||
#include "pshpack1.h"
|
#include "pshpack1.h"
|
||||||
|
@ -18,12 +32,12 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
/* Non provided messages for DPLAY - guess work which may be wrong :( */
|
/* Non provided messages for DPLAY - guess work which may be wrong :( */
|
||||||
#define DPMSGCMD_ENUMSESSIONSREPLY 1
|
#define DPMSGCMD_ENUMSESSIONSREPLY 1
|
||||||
#define DPMSGCMD_ENUMSESSIONSREQUEST 2
|
#define DPMSGCMD_ENUMSESSIONSREQUEST 2
|
||||||
|
#define DPMSGCMD_GETNAMETABLEREPLY 3 /* Contains all existing players in session */
|
||||||
|
|
||||||
#define DPMSGCMD_REQUESTNEWPLAYERID 5
|
#define DPMSGCMD_REQUESTNEWPLAYERID 5
|
||||||
|
|
||||||
#define DPMSGCMD_NEWPLAYERIDREPLY 7
|
#define DPMSGCMD_NEWPLAYERIDREPLY 7
|
||||||
#define DPMSGCMD_CREATESESSION 8
|
#define DPMSGCMD_CREATESESSION 8 /* Might be a create nameserver or new player msg */
|
||||||
#define DPMSGCMD_CREATENEWPLAYER 9
|
#define DPMSGCMD_CREATENEWPLAYER 9
|
||||||
#define DPMSGCMD_SYSTEMMESSAGE 10
|
#define DPMSGCMD_SYSTEMMESSAGE 10
|
||||||
#define DPMSGCMD_DELETEPLAYER 11
|
#define DPMSGCMD_DELETEPLAYER 11
|
||||||
|
@ -31,9 +45,9 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
|
|
||||||
#define DPMSGCMD_ENUMGROUPS 17
|
#define DPMSGCMD_ENUMGROUPS 17
|
||||||
|
|
||||||
#define DPMSGCMD_GETNAMETABLE 19
|
#define DPMSGCMD_FORWARDADDPLAYER 19
|
||||||
|
|
||||||
#define DPMSGCMD_GETNAMETABLEREPLY 29
|
#define DPMSGCMD_FORWARDADDPLAYERNACK 36
|
||||||
|
|
||||||
/* This is what DP 6 defines it as. Don't know what it means. All messages
|
/* This is what DP 6 defines it as. Don't know what it means. All messages
|
||||||
* defined below are DPMSGVER_DP6.
|
* defined below are DPMSGVER_DP6.
|
||||||
|
@ -45,9 +59,8 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
|
|
||||||
/* All messages sent from the system are sent with this at the beginning of
|
/* All messages sent from the system are sent with this at the beginning of
|
||||||
* the message.
|
* the message.
|
||||||
|
* Size is 8 bytes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Size is 8 bytes */
|
|
||||||
typedef struct tagDPMSG_SENDENVELOPE
|
typedef struct tagDPMSG_SENDENVELOPE
|
||||||
{
|
{
|
||||||
DWORD dwMagic;
|
DWORD dwMagic;
|
||||||
|
@ -56,6 +69,9 @@ typedef struct tagDPMSG_SENDENVELOPE
|
||||||
} DPMSG_SENDENVELOPE, *LPDPMSG_SENDENVELOPE;
|
} DPMSG_SENDENVELOPE, *LPDPMSG_SENDENVELOPE;
|
||||||
typedef const DPMSG_SENDENVELOPE* LPCDPMSG_SENDENVELOPE;
|
typedef const DPMSG_SENDENVELOPE* LPCDPMSG_SENDENVELOPE;
|
||||||
|
|
||||||
|
/* System messages exchanged between players seems to have this
|
||||||
|
* payload envelope on top of the basic envelope
|
||||||
|
*/
|
||||||
typedef struct tagDPMSG_SYSMSGENVELOPE
|
typedef struct tagDPMSG_SYSMSGENVELOPE
|
||||||
{
|
{
|
||||||
DWORD dwPlayerFrom;
|
DWORD dwPlayerFrom;
|
||||||
|
@ -63,7 +79,7 @@ typedef struct tagDPMSG_SYSMSGENVELOPE
|
||||||
} DPMSG_SYSMSGENVELOPE, *LPDPMSG_SYSMSGENVELOPE;
|
} DPMSG_SYSMSGENVELOPE, *LPDPMSG_SYSMSGENVELOPE;
|
||||||
typedef const DPMSG_SYSMSGENVELOPE* LPCDPMSG_SYSMSGENVELOPE;
|
typedef const DPMSG_SYSMSGENVELOPE* LPCDPMSG_SYSMSGENVELOPE;
|
||||||
|
|
||||||
|
/* Reply sent in response to an enumsession request */
|
||||||
typedef struct tagDPMSG_ENUMSESSIONSREPLY
|
typedef struct tagDPMSG_ENUMSESSIONSREPLY
|
||||||
{
|
{
|
||||||
DPMSG_SENDENVELOPE envelope;
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
@ -93,13 +109,14 @@ typedef struct tagDPMSG_ENUMSESSIONSREPLY
|
||||||
} DPMSG_ENUMSESSIONSREPLY, *LPDPMSG_ENUMSESSIONSREPLY;
|
} DPMSG_ENUMSESSIONSREPLY, *LPDPMSG_ENUMSESSIONSREPLY;
|
||||||
typedef const DPMSG_ENUMSESSIONSREPLY* LPCDPMSG_ENUMSESSIONSREPLY;
|
typedef const DPMSG_ENUMSESSIONSREPLY* LPCDPMSG_ENUMSESSIONSREPLY;
|
||||||
|
|
||||||
|
/* Msg sent to find out what sessions are available */
|
||||||
typedef struct tagDPMSG_ENUMSESSIONSREQUEST
|
typedef struct tagDPMSG_ENUMSESSIONSREQUEST
|
||||||
{
|
{
|
||||||
DPMSG_SENDENVELOPE envelope;
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
|
||||||
GUID guidApplication;
|
GUID guidApplication;
|
||||||
|
|
||||||
DWORD dwPasswordSize; /* A Guess. This is normally 0x00000000. */
|
DWORD dwPasswordSize; /* A Guess. This is 0x00000000. */
|
||||||
/* This might be the name server DPID which
|
/* This might be the name server DPID which
|
||||||
is needed for the reply */
|
is needed for the reply */
|
||||||
|
|
||||||
|
@ -131,24 +148,50 @@ typedef struct tagDPMSG_NEWPLAYERIDREPLY
|
||||||
DPMSG_SENDENVELOPE envelope;
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
|
||||||
DPID dpidNewPlayerId;
|
DPID dpidNewPlayerId;
|
||||||
#if 1
|
|
||||||
/* Assume that this is data that is tacked on to the end of the message
|
/* Assume that this is data that is tacked on to the end of the message
|
||||||
* that comes from the SP remote data stored that needs to be propagated.
|
* that comes from the SP remote data stored that needs to be propagated.
|
||||||
*/
|
*/
|
||||||
BYTE unknown[36]; /* This appears to always be 0 - not sure though */
|
BYTE unknown[36]; /* This appears to always be 0 - not sure though */
|
||||||
#endif
|
|
||||||
|
|
||||||
} DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_NEWPLAYERIDREPLY;
|
} DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_NEWPLAYERIDREPLY;
|
||||||
typedef const DPMSG_NEWPLAYERIDREPLY* LPCDPMSG_NEWPLAYERIDREPLY;
|
typedef const DPMSG_NEWPLAYERIDREPLY* LPCDPMSG_NEWPLAYERIDREPLY;
|
||||||
|
|
||||||
|
typedef struct tagDPMSG_FORWARDADDPLAYER
|
||||||
|
{
|
||||||
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
|
||||||
|
DWORD unknown; /* 0 */
|
||||||
|
|
||||||
|
DPID dpidAppServer; /* Remote application server id */
|
||||||
|
DWORD unknown2[5]; /* ??? */
|
||||||
|
#define FORWARDADDPLAYER_UNKNOWN2_INIT { 0x0, 0x1c, 0x6c, 0x50, 0x9 }
|
||||||
|
|
||||||
|
DPID dpidAppServer2; /* Remote application server id again !? */
|
||||||
|
DWORD unknown3[5]; /* ??? */
|
||||||
|
#define FORWARDADDPLAYER_UNKNOWN3_INIT { 0x0, 0x0, 0x20, 0x0, 0x0 }
|
||||||
|
|
||||||
|
DPID dpidAppServer3; /* Remote application server id again !? */
|
||||||
|
|
||||||
|
DWORD unknown4[12]; /* ??? - Is this a clump of 5 and then 8? */
|
||||||
|
/* NOTE: 1 byte infront of the two 0x??090002 entries changes! */
|
||||||
|
#define FORWARDADDPLAYER_UNKNOWN4_INIT { 0x30, 0xb, 0x0, 0x1e090002, 0x0, 0x0, 0x0, 0x32090002, 0x0, 0x0, 0x0, 0x0 }
|
||||||
|
|
||||||
|
BYTE unknown5[2]; /* 2 bytes at the end. This may be a part of something! */
|
||||||
|
#define FORWARDADDPLAYER_UNKNOWN5_INIT { 0x0 }
|
||||||
|
|
||||||
|
} DPMSG_FORWARDADDPLAYER, *LPDPMSG_FORWARDADDPLAYER;
|
||||||
|
typedef const DPMSG_FORWARDADDPLAYER* LPCDPMSG_FORWARDADDPLAYER;
|
||||||
|
|
||||||
|
/* This is an error message that can be received. Not sure if this is
|
||||||
|
* specifically for a forward add player or for all errors
|
||||||
|
*/
|
||||||
|
typedef struct tagDPMSG_FORWARDADDPLAYERNACK
|
||||||
|
{
|
||||||
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
HRESULT errorCode;
|
||||||
|
} DPMSG_FORWARDADDPLAYERNACK, *LPDPMSG_FORWARDADDPLAYERNACK;
|
||||||
|
typedef const DPMSG_FORWARDADDPLAYERNACK* LPCDPMSG_FORWARDADDPLAYERNACK;
|
||||||
|
|
||||||
#include "poppack.h"
|
#include "poppack.h"
|
||||||
|
|
||||||
|
|
||||||
HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
|
||||||
LPDPID lpdipidAllocatedId );
|
|
||||||
|
|
||||||
/* FIXME: I don't think that this is a needed method */
|
|
||||||
HRESULT DP_MSG_OpenStream( IDirectPlay2AImpl* This );
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -343,15 +343,15 @@ static HRESULT WINAPI DPL_QueryInterface
|
||||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
||||||
|
|
||||||
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
sizeof( IDirectPlayLobbyWImpl ) );
|
sizeof( *This ) );
|
||||||
|
|
||||||
if( *ppvObj == NULL )
|
if( *ppvObj == NULL )
|
||||||
{
|
{
|
||||||
return DPERR_OUTOFMEMORY;
|
return DPERR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMemory( *ppvObj, iface, sizeof( IDirectPlayLobbyWImpl ) );
|
CopyMemory( *ppvObj, This, sizeof( *This ) );
|
||||||
(*(IDirectPlayLobbyWImpl**)ppvObj)->ulInterfaceRef = 0;
|
(*(IDirectPlayLobbyAImpl**)ppvObj)->ulInterfaceRef = 0;
|
||||||
|
|
||||||
if( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
|
if( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue