- 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
|
||||
*
|
||||
* NOTES
|
||||
|
|
|
@ -160,6 +160,8 @@ static HRESULT WINAPI DP_IF_EnumSessions
|
|||
( IDirectPlay2Impl* This, LPDPSESSIONDESC2 lpsd, DWORD dwTimeout,
|
||||
LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
|
||||
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,
|
||||
LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName,
|
||||
DWORD dwFlags, LPVOID lpContext );
|
||||
|
@ -174,7 +176,7 @@ static void DP_CopySessionDesc( LPDPSESSIONDESC2 destSessionDesc,
|
|||
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->sendMsgs);
|
||||
DPQ_INIT(This->dp2->replysExpected);
|
||||
|
||||
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 );
|
||||
|
||||
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof( IDirectPlay2Impl ) );
|
||||
sizeof( *This ) );
|
||||
|
||||
if( *ppvObj == NULL )
|
||||
{
|
||||
return DPERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
CopyMemory( *ppvObj, iface, sizeof( IDirectPlay2Impl ) );
|
||||
CopyMemory( *ppvObj, This, sizeof( *This ) );
|
||||
(*(IDirectPlay2Impl**)ppvObj)->ulInterfaceRef = 0;
|
||||
|
||||
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 */
|
||||
HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||
DWORD dwMessageBodySize, LPCVOID lpMessageHeader,
|
||||
HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpcMessageBody,
|
||||
DWORD dwMessageBodySize, LPCVOID lpcMessageHeader,
|
||||
WORD wCommandId, WORD wVersion,
|
||||
LPVOID* lplpReply, LPDWORD lpdwMsgSize )
|
||||
{
|
||||
TRACE( "(%p)->(%p,0x%08lx,%p,%u,%u)\n",
|
||||
This, lpMessageBody, dwMessageBodySize, lpMessageHeader, wCommandId,
|
||||
This, lpcMessageBody, dwMessageBodySize, lpcMessageHeader, wCommandId,
|
||||
wVersion );
|
||||
|
||||
DebugBreak();
|
||||
|
||||
switch( wCommandId )
|
||||
{
|
||||
case DPMSGCMD_REQUESTNEWPLAYERID:
|
||||
{
|
||||
#if 0
|
||||
LPCDPMSG_REQUESTNEWPLAYERID lpcMsg =
|
||||
(LPCDPMSG_REQUESTNEWPLAYERID)lpMessageBody;
|
||||
#endif
|
||||
(LPCDPMSG_REQUESTNEWPLAYERID)lpcMessageBody;
|
||||
|
||||
LPDPMSG_NEWPLAYERIDREPLY lpReply;
|
||||
|
||||
*lpdwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpReply );
|
||||
|
@ -640,25 +640,8 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
|||
HEAP_ZERO_MEMORY,
|
||||
*lpdwMsgSize );
|
||||
|
||||
FIXME( "Ignoring dwFlags in request msg\n" );
|
||||
|
||||
#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
|
||||
FIXME( "Ignoring dwFlags 0x%08lx in request msg\n",
|
||||
lpcMsg->dwFlags );
|
||||
|
||||
/* Setup the reply */
|
||||
lpReply = (LPDPMSG_NEWPLAYERIDREPLY)( (BYTE*)(*lplpReply) +
|
||||
|
@ -676,29 +659,25 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
|||
break;
|
||||
}
|
||||
|
||||
case DPMSGCMD_GETNAMETABLEREPLY:
|
||||
case DPMSGCMD_NEWPLAYERIDREPLY:
|
||||
{
|
||||
|
||||
if( This->dp2->hMsgReceipt )
|
||||
{
|
||||
/* 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" );
|
||||
}
|
||||
DP_MSG_ReplyReceived( This, wCommandId, lpcMessageBody, dwMessageBodySize );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DPMSGCMD_FORWARDADDPLAYERNACK:
|
||||
{
|
||||
DP_MSG_ErrorReceived( This, wCommandId, lpcMessageBody, dwMessageBodySize );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FIXME( "Unknown wCommandId %u. Ignoring message\n", wCommandId );
|
||||
DebugBreak();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -873,6 +852,8 @@ lpGroupData DP_CreateGroup( IDirectPlay2AImpl* This, LPDPID lpid,
|
|||
/* FIXME: Should we validate the dwFlags? */
|
||||
lpGData->dwFlags = dwFlags;
|
||||
|
||||
TRACE( "Created group id 0x%08lx\n", *lpid );
|
||||
|
||||
return lpGData;
|
||||
}
|
||||
|
||||
|
@ -968,6 +949,7 @@ static HRESULT WINAPI DP_IF_CreateGroup
|
|||
if( DPID_SYSTEM_GROUP == *lpidGroup )
|
||||
{
|
||||
This->dp2->lpSysGroup = lpGData;
|
||||
TRACE( "Inserting system group\n" );
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1325,6 +1312,7 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
|||
HANDLE hr = DP_OK;
|
||||
lpPlayerData lpPData;
|
||||
lpPlayerList lpPList;
|
||||
DWORD dwCreateFlags = 0;
|
||||
|
||||
TRACE( "(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx,%u)\n",
|
||||
This, lpidPlayer, lpPlayerName, hEvent, lpData,
|
||||
|
@ -1340,6 +1328,35 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
|||
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 */
|
||||
if( !( ( dwFlags & DPPLAYER_SERVERPLAYER ) ||
|
||||
( dwFlags & DPPLAYER_SPECTATOR )
|
||||
|
@ -1360,7 +1377,7 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
|||
}
|
||||
else
|
||||
{
|
||||
hr = DP_MSG_SendRequestPlayerId( This, dwFlags, lpidPlayer );
|
||||
hr = DP_MSG_SendRequestPlayerId( This, dwCreateFlags, lpidPlayer );
|
||||
|
||||
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,
|
||||
hEvent, bAnsi );
|
||||
|
||||
|
@ -1406,28 +1424,15 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
|||
if( This->dp2->spData.lpCB->CreatePlayer )
|
||||
{
|
||||
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.dwFlags = dwCreateFlags;
|
||||
data.lpSPMessageHeader = lpMsgHdr;
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -1453,11 +1458,22 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
|||
|
||||
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) );
|
||||
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
|
||||
* no peers keep this quiet.
|
||||
* 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,
|
||||
sizeof( msg ), 0, 0, NULL, NULL, bAnsi );
|
||||
}
|
||||
#endif
|
||||
|
||||
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 */
|
||||
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 */
|
||||
SetEvent( This->dp2->hKillEnumSessionThreadEvent );
|
||||
|
@ -2094,7 +2112,12 @@ static HRESULT WINAPI DP_IF_EnumSessions
|
|||
DP_IF_GetCaps( This, &spCaps, 0 );
|
||||
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 )
|
||||
|
@ -2725,6 +2748,7 @@ static HRESULT WINAPI DP_SecureOpen
|
|||
hr = DP_IF_CreatePlayer( This, NULL, &dpidServerId, NULL, 0, NULL,
|
||||
0,
|
||||
DPPLAYER_SERVERPLAYER | DPPLAYER_LOCAL , bAnsi );
|
||||
|
||||
}
|
||||
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 */
|
||||
static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData )
|
||||
static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDpSp )
|
||||
{
|
||||
UINT i;
|
||||
LPCSTR spSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
|
||||
|
@ -3814,6 +3838,7 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData )
|
|||
FILETIME filetime;
|
||||
|
||||
(i == 0) ? (searchSubKey = spSubKey ) : (searchSubKey = lpSubKey );
|
||||
*lpbIsDpSp = (i == 0) ? TRUE : FALSE;
|
||||
|
||||
|
||||
/* Need to loop over the service providers in the registry */
|
||||
|
@ -3910,6 +3935,7 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData )
|
|||
continue;
|
||||
}
|
||||
|
||||
TRACE( "Loading %s\n", returnBuffer );
|
||||
return LoadLibraryA( returnBuffer );
|
||||
}
|
||||
}
|
||||
|
@ -3917,18 +3943,17 @@ static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData )
|
|||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
||||
( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
|
||||
static HRESULT WINAPI DP_IF_InitializeConnection
|
||||
( IDirectPlay3Impl* This, LPVOID lpConnection, DWORD dwFlags, BOOL bAnsi )
|
||||
{
|
||||
HMODULE hServiceProvider;
|
||||
HRESULT hr;
|
||||
LPDPSP_SPINIT SPInit;
|
||||
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)\n", This, lpConnection, dwFlags );
|
||||
TRACE("(%p)->(%p,0x%08lx,%u)\n", This, lpConnection, dwFlags, bAnsi );
|
||||
|
||||
if( dwFlags != 0 )
|
||||
{
|
||||
|
@ -3958,7 +3983,7 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
|||
This->dp2->spData.lpGuid = &guidSP;
|
||||
|
||||
/* Load the service provider */
|
||||
hServiceProvider = DP_LoadSP( &guidSP, &This->dp2->spData );
|
||||
hServiceProvider = DP_LoadSP( &guidSP, &This->dp2->spData, &bIsDpSp );
|
||||
|
||||
if( hServiceProvider == 0 )
|
||||
{
|
||||
|
@ -3966,22 +3991,35 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
|||
return DPERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/* Initialize the service provider by calling SPInit */
|
||||
SPInit = (LPDPSP_SPINIT)GetProcAddress( hServiceProvider, "SPInit" );
|
||||
if( bIsDpSp )
|
||||
{
|
||||
/* 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 )
|
||||
{
|
||||
ERR( "Service provider doesn't provide SPInit interface?\n" );
|
||||
ERR( "Service provider doesn't provide %s interface?\n",
|
||||
bIsDpSp ? "SPInit" : "DPLSPInit" );
|
||||
FreeLibrary( hServiceProvider );
|
||||
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 );
|
||||
|
||||
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 );
|
||||
return hr;
|
||||
}
|
||||
|
@ -3995,12 +4033,18 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
|
|||
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
|
||||
( LPDIRECTPLAY3 iface, LPVOID lpConnection, DWORD dwFlags )
|
||||
{
|
||||
ICOM_THIS(IDirectPlay3Impl,iface);
|
||||
FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
|
||||
return DP_OK;
|
||||
return DP_IF_InitializeConnection( This, lpConnection, dwFlags, FALSE );
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DirectPlay3AImpl_SecureOpen
|
||||
|
@ -4846,9 +4890,42 @@ static ICOM_VTABLE(IDirectPlay4) directPlay4AVT =
|
|||
};
|
||||
#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
|
||||
* 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 )
|
||||
|
@ -5027,7 +5104,7 @@ static BOOL CALLBACK cbDPCreateEnumConnections(
|
|||
|
||||
|
||||
/***************************************************************************
|
||||
* DirectPlayCreate (DPLAYX.1) (DPLAY.1)
|
||||
* DirectPlayCreate [DPLAYX.1][DPLAY.1]
|
||||
*
|
||||
*/
|
||||
HRESULT WINAPI DirectPlayCreate
|
||||
|
@ -5044,7 +5121,6 @@ HRESULT WINAPI DirectPlayCreate
|
|||
return CLASS_E_NOAGGREGATION;
|
||||
}
|
||||
|
||||
|
||||
/* 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 */
|
||||
if( DP_CreateInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) != DP_OK )
|
||||
|
|
|
@ -35,6 +35,21 @@ typedef struct tagEnumSessionAsyncCallbackData
|
|||
HANDLE hSuicideRequest;
|
||||
} 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
|
||||
{
|
||||
/* Individual player information */
|
||||
|
@ -53,6 +68,9 @@ struct PlayerData
|
|||
LPVOID lpRemoteData;
|
||||
DWORD dwRemoteDataSize;
|
||||
|
||||
/* SP data on a per player basis */
|
||||
LPVOID lpSPPlayerData;
|
||||
|
||||
DWORD dwFlags; /* Special remarks about the type of player */
|
||||
};
|
||||
typedef struct PlayerData* lpPlayerData;
|
||||
|
@ -137,10 +155,8 @@ typedef struct tagDirectPlay2Data
|
|||
|
||||
BOOL bConnectionInitialized;
|
||||
|
||||
|
||||
/* proof of concept for message reception */
|
||||
HANDLE hMsgReceipt;
|
||||
LPVOID lpMsgReceived;
|
||||
/* Expected messages queue */
|
||||
DPQ_HEAD( tagDP_MSG_REPLY_STRUCT_LIST ) replysExpected;
|
||||
} DirectPlay2Data;
|
||||
|
||||
typedef struct tagDirectPlay3Data
|
||||
|
@ -192,5 +208,11 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
|||
WORD wCommandId, WORD wVersion,
|
||||
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 */
|
||||
|
|
|
@ -26,7 +26,6 @@ static BOOL DPSP_DestroyIUnknown( LPVOID lpSP );
|
|||
static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp );
|
||||
static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP );
|
||||
|
||||
|
||||
/* Predefine the interface */
|
||||
typedef struct IDirectPlaySPImpl IDirectPlaySPImpl;
|
||||
|
||||
|
@ -46,8 +45,6 @@ typedef struct tagDirectPlaySPData
|
|||
|
||||
IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */
|
||||
|
||||
LPVOID lpPlayerData; /* FIXME: Need to figure out how this actually behaves */
|
||||
DWORD dwPlayerDataSize;
|
||||
} DirectPlaySPData;
|
||||
|
||||
#define DPSP_IMPL_FIELDS \
|
||||
|
@ -64,7 +61,15 @@ struct IDirectPlaySPImpl
|
|||
/* Forward declaration of virtual tables */
|
||||
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 */
|
||||
extern
|
||||
|
@ -165,6 +170,15 @@ static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* 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;
|
||||
}
|
||||
|
||||
|
@ -200,14 +214,14 @@ static HRESULT WINAPI DPSP_QueryInterface
|
|||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
||||
|
||||
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof( IDirectPlaySPImpl ) );
|
||||
sizeof( *This ) );
|
||||
|
||||
if( *ppvObj == NULL )
|
||||
{
|
||||
return DPERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
CopyMemory( *ppvObj, iface, sizeof( IDirectPlaySPImpl ) );
|
||||
CopyMemory( *ppvObj, This, sizeof( *This ) );
|
||||
(*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0;
|
||||
|
||||
if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
|
||||
|
@ -363,18 +377,50 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
|
|||
DWORD dwFlags
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
LPDP_SPPLAYERDATA lpPlayerData;
|
||||
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||
|
||||
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
||||
FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n",
|
||||
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
|
||||
TRACE( "(%p)->(0x%08lx,%p,%p,0x%08lx)\n",
|
||||
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? */
|
||||
if( dwFlags == DPSET_LOCAL )
|
||||
{
|
||||
if( lpPlayerData->lpPlayerLocalData )
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerLocalData );
|
||||
}
|
||||
|
||||
*lplpData = This->sp->lpPlayerData;
|
||||
*lpdwDataSize = This->sp->dwPlayerDataSize;
|
||||
*lplpData = lpPlayerData->lpPlayerLocalData;
|
||||
*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
|
||||
|
@ -391,7 +437,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
|||
|
||||
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",
|
||||
This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
|
||||
|
||||
|
@ -409,6 +455,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
|||
switch( lpMsg->wCommandId )
|
||||
{
|
||||
/* Name server needs to handle this request */
|
||||
/* FIXME: This should be done in direct play handler */
|
||||
case DPMSGCMD_ENUMSESSIONSREQUEST:
|
||||
{
|
||||
DPSP_REPLYDATA data;
|
||||
|
@ -430,6 +477,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
|||
}
|
||||
|
||||
/* Name server needs to handle this request */
|
||||
/* FIXME: This should be done in direct play handler */
|
||||
case DPMSGCMD_ENUMSESSIONSREPLY:
|
||||
{
|
||||
NS_SetRemoteComputerAsNameServer( lpMessageHeader,
|
||||
|
@ -438,14 +486,13 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
|||
This->sp->dplay->dp2->lpNameServerData );
|
||||
|
||||
/* No reply expected */
|
||||
hr = DP_OK;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DPMSGCMD_GETNAMETABLE:
|
||||
case DPMSGCMD_GETNAMETABLEREPLY:
|
||||
case DPMSGCMD_NEWPLAYERIDREPLY:
|
||||
case DPMSGCMD_REQUESTNEWPLAYERID:
|
||||
/* Pass everything else to Direct Play */
|
||||
default:
|
||||
{
|
||||
DPSP_REPLYDATA data;
|
||||
|
||||
|
@ -453,9 +500,9 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
|||
data.dwMessageSize = 0;
|
||||
|
||||
/* Pass this message to the dplay interface to handle */
|
||||
DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
|
||||
lpMessageHeader, wCommandId, wVersion,
|
||||
&data.lpMessage, &data.dwMessageSize );
|
||||
hr = DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
|
||||
lpMessageHeader, wCommandId, wVersion,
|
||||
&data.lpMessage, &data.dwMessageSize );
|
||||
|
||||
/* Do we want a reply? */
|
||||
if( data.lpMessage != NULL )
|
||||
|
@ -476,10 +523,6 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME( "Unknown Command of %u and size 0x%08lx\n",
|
||||
lpMsg->wCommandId, dwMessageBodySize );
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -736,22 +779,40 @@ static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
|
|||
DWORD dwFlags
|
||||
)
|
||||
{
|
||||
HRESULT hr;
|
||||
LPDP_SPPLAYERDATA lpPlayerEntry;
|
||||
LPVOID lpPlayerData;
|
||||
|
||||
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||
|
||||
/* FIXME: I'm not sure if this stuff should be associated with the DPlay
|
||||
* player lists. How else would this stuff get deleted?
|
||||
*/
|
||||
|
||||
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
||||
FIXME( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n",
|
||||
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
|
||||
TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n",
|
||||
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;
|
||||
CopyMemory( This->sp->lpPlayerData, lpData, dwDataSize );
|
||||
lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 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
|
||||
|
@ -777,15 +838,16 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
|
|||
DWORD dwFlags
|
||||
)
|
||||
{
|
||||
HRESULT hr = DP_OK;
|
||||
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",
|
||||
This, lplpData, lpdwDataSize, dwFlags );
|
||||
|
||||
#if 0
|
||||
/* This is what the documentation says... */
|
||||
if( dwFlags != 0 )
|
||||
if( dwFlags != DPSET_REMOTE )
|
||||
{
|
||||
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
|
||||
* thing?
|
||||
*/
|
||||
if( dwFlags != 0 )
|
||||
if( dwFlags != DPSET_REMOTE )
|
||||
{
|
||||
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
|
||||
}
|
||||
|
@ -807,14 +869,24 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
|
|||
{
|
||||
*lpdwDataSize = This->sp->dwSpRemoteDataSize;
|
||||
*lplpData = This->sp->lpSpRemoteData;
|
||||
|
||||
if( This->sp->lpSpRemoteData == NULL )
|
||||
{
|
||||
hr = DPERR_GENERIC;
|
||||
}
|
||||
}
|
||||
else if( dwFlags == DPSET_LOCAL )
|
||||
{
|
||||
*lpdwDataSize = This->sp->dwSpLocalDataSize;
|
||||
*lplpData = This->sp->lpSpLocalData;
|
||||
|
||||
if( This->sp->lpSpLocalData == NULL )
|
||||
{
|
||||
hr = DPERR_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
return DP_OK;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
|
||||
|
@ -828,13 +900,13 @@ static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
|
|||
|
||||
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",
|
||||
This, lpData, dwDataSize, dwFlags );
|
||||
|
||||
#if 0
|
||||
/* This is what the documentation says... */
|
||||
if( dwFlags != 0 )
|
||||
if( dwFlags != DPSET_REMOTE )
|
||||
{
|
||||
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
|
||||
* thing?
|
||||
*/
|
||||
if( dwFlags != 0 )
|
||||
if( dwFlags != DPSET_REMOTE )
|
||||
{
|
||||
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( dwFlags == DPSET_REMOTE )
|
||||
{
|
||||
lpSpData = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, dwDataSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
|
||||
}
|
||||
|
||||
lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
|
||||
CopyMemory( lpSpData, lpData, dwDataSize );
|
||||
|
||||
/* If we have data already allocated, free it and replace it */
|
||||
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 )
|
||||
{
|
||||
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->lpSpRemoteData = lpSpData;
|
||||
}
|
||||
|
@ -923,3 +983,15 @@ static struct ICOM_VTABLE(IDirectPlaySP) directPlaySPVT =
|
|||
IDirectPlaySPImpl_SetSPData,
|
||||
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;
|
||||
} MSGTHREADINFO, *LPMSGTHREADINFO;
|
||||
|
||||
|
||||
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
|
||||
* asynchronous message reception
|
||||
|
@ -139,6 +142,42 @@ end_of_thread:
|
|||
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,
|
||||
LPDPID lpdpidAllocatedId )
|
||||
|
@ -146,7 +185,6 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
|||
LPVOID lpMsg;
|
||||
LPDPMSG_REQUESTNEWPLAYERID lpMsgBody;
|
||||
DWORD dwMsgSize;
|
||||
DWORD dwWaitReturn;
|
||||
HRESULT hr = DP_OK;
|
||||
|
||||
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
|
||||
|
@ -156,18 +194,15 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
|||
lpMsgBody = (LPDPMSG_REQUESTNEWPLAYERID)( (BYTE*)lpMsg +
|
||||
This->dp2->spData.dwSPHeaderSize );
|
||||
|
||||
/* Compose dplay message envelope */
|
||||
lpMsgBody->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
|
||||
lpMsgBody->envelope.wCommandId = DPMSGCMD_REQUESTNEWPLAYERID;
|
||||
lpMsgBody->envelope.wVersion = DPMSGVER_DP6;
|
||||
|
||||
/* Compose the body of the message */
|
||||
lpMsgBody->dwFlags = dwFlags;
|
||||
|
||||
/* FIXME: Need to have a more advanced queuing system as this needs to
|
||||
* 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...
|
||||
*/
|
||||
/* Send the message */
|
||||
{
|
||||
DPSP_SENDDATA data;
|
||||
|
||||
|
@ -179,37 +214,20 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
|||
data.bSystemMessage = TRUE; /* Allow reply to be sent */
|
||||
data.lpISP = This->dp2->spData.lpISP;
|
||||
|
||||
/* Setup for receipt */
|
||||
This->dp2->hMsgReceipt = CreateEventA( NULL, FALSE, FALSE, NULL );
|
||||
TRACE( "Asking for player id w/ dwFlags 0x%08lx\n",
|
||||
lpMsgBody->dwFlags );
|
||||
|
||||
TRACE( "Sending request for player id\n" );
|
||||
|
||||
hr = (*This->dp2->spData.lpCB->Send)( &data );
|
||||
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
ERR( "Request for new playerID send failed: %s\n",
|
||||
DPLAYX_HresultToString( hr ) );
|
||||
return DPERR_NOCONNECTION;
|
||||
}
|
||||
DP_MSG_ExpectReply( This, &data, DPMSG_DEFAULT_WAIT_TIME, DPMSGCMD_NEWPLAYERIDREPLY,
|
||||
&lpMsg, &dwMsgSize );
|
||||
}
|
||||
|
||||
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 */
|
||||
if( !FAILED(hr) )
|
||||
{
|
||||
LPCDPMSG_NEWPLAYERIDREPLY lpcReply;
|
||||
|
||||
lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)This->dp2->lpMsgReceived;
|
||||
lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)lpMsg;
|
||||
|
||||
*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
|
||||
* 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, This->dp2->lpMsgReceived );
|
||||
This->dp2->lpMsgReceived = NULL;
|
||||
HeapFree( GetProcessHeap(), 0, lpMsg );
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/* 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 DP_MSG_ForwardPlayerCreation( IDirectPlay2AImpl* This, DPID dpidServer )
|
||||
{
|
||||
HRESULT hr;
|
||||
DPSP_SENDDATA data;
|
||||
LPVOID lpMsg;
|
||||
LPDPMSG_FORWARDADDPLAYER lpMsgBody;
|
||||
DWORD dwMsgSize;
|
||||
HRESULT hr = DP_OK;
|
||||
|
||||
data.dwFlags = DPSEND_OPENSTREAM;
|
||||
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;
|
||||
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
|
||||
|
||||
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) )
|
||||
{
|
||||
ERR( "Request for open stream send failed: %s\n",
|
||||
DPLAYX_HresultToString( hr ) );
|
||||
ERR( "Request for new playerID send failed: %s\n",
|
||||
DPLAYX_HresultToString( hr ) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FIXME: hack to give some time for channel to open */
|
||||
SleepEx( 1000 /* 1 sec */, FALSE );
|
||||
dwWaitReturn = WaitForSingleObject( hMsgReceipt, dwWaitTime );
|
||||
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,
|
||||
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. */
|
||||
#include "pshpack1.h"
|
||||
|
@ -18,12 +32,12 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
|||
/* Non provided messages for DPLAY - guess work which may be wrong :( */
|
||||
#define DPMSGCMD_ENUMSESSIONSREPLY 1
|
||||
#define DPMSGCMD_ENUMSESSIONSREQUEST 2
|
||||
|
||||
#define DPMSGCMD_GETNAMETABLEREPLY 3 /* Contains all existing players in session */
|
||||
|
||||
#define DPMSGCMD_REQUESTNEWPLAYERID 5
|
||||
|
||||
#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_SYSTEMMESSAGE 10
|
||||
#define DPMSGCMD_DELETEPLAYER 11
|
||||
|
@ -31,9 +45,9 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
|||
|
||||
#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
|
||||
* 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
|
||||
* the message.
|
||||
* Size is 8 bytes
|
||||
*/
|
||||
|
||||
/* Size is 8 bytes */
|
||||
typedef struct tagDPMSG_SENDENVELOPE
|
||||
{
|
||||
DWORD dwMagic;
|
||||
|
@ -56,6 +69,9 @@ typedef struct tagDPMSG_SENDENVELOPE
|
|||
} DPMSG_SENDENVELOPE, *LPDPMSG_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
|
||||
{
|
||||
DWORD dwPlayerFrom;
|
||||
|
@ -63,7 +79,7 @@ typedef struct tagDPMSG_SYSMSGENVELOPE
|
|||
} DPMSG_SYSMSGENVELOPE, *LPDPMSG_SYSMSGENVELOPE;
|
||||
typedef const DPMSG_SYSMSGENVELOPE* LPCDPMSG_SYSMSGENVELOPE;
|
||||
|
||||
|
||||
/* Reply sent in response to an enumsession request */
|
||||
typedef struct tagDPMSG_ENUMSESSIONSREPLY
|
||||
{
|
||||
DPMSG_SENDENVELOPE envelope;
|
||||
|
@ -93,13 +109,14 @@ typedef struct tagDPMSG_ENUMSESSIONSREPLY
|
|||
} DPMSG_ENUMSESSIONSREPLY, *LPDPMSG_ENUMSESSIONSREPLY;
|
||||
typedef const DPMSG_ENUMSESSIONSREPLY* LPCDPMSG_ENUMSESSIONSREPLY;
|
||||
|
||||
/* Msg sent to find out what sessions are available */
|
||||
typedef struct tagDPMSG_ENUMSESSIONSREQUEST
|
||||
{
|
||||
DPMSG_SENDENVELOPE envelope;
|
||||
|
||||
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
|
||||
is needed for the reply */
|
||||
|
||||
|
@ -131,24 +148,50 @@ typedef struct tagDPMSG_NEWPLAYERIDREPLY
|
|||
DPMSG_SENDENVELOPE envelope;
|
||||
|
||||
DPID dpidNewPlayerId;
|
||||
#if 1
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
BYTE unknown[36]; /* This appears to always be 0 - not sure though */
|
||||
#endif
|
||||
|
||||
} DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_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"
|
||||
|
||||
|
||||
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
|
||||
|
|
|
@ -343,15 +343,15 @@ static HRESULT WINAPI DPL_QueryInterface
|
|||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
||||
|
||||
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof( IDirectPlayLobbyWImpl ) );
|
||||
sizeof( *This ) );
|
||||
|
||||
if( *ppvObj == NULL )
|
||||
{
|
||||
return DPERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
CopyMemory( *ppvObj, iface, sizeof( IDirectPlayLobbyWImpl ) );
|
||||
(*(IDirectPlayLobbyWImpl**)ppvObj)->ulInterfaceRef = 0;
|
||||
CopyMemory( *ppvObj, This, sizeof( *This ) );
|
||||
(*(IDirectPlayLobbyAImpl**)ppvObj)->ulInterfaceRef = 0;
|
||||
|
||||
if( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue