📄 dplaysp.c
字号:
ERR( "Command processing failed %s\n", DPLAYX_HresultToString(hr) );
}
/* Do we want a reply? */
if( data.lpMessage != NULL )
{
data.lpSPMessageHeader = lpMessageHeader;
data.idNameServer = 0;
data.lpISP = iface;
hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
if( FAILED(hr) )
{
ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr) );
}
}
return hr;
#if 0
HRESULT hr = DP_OK;
HANDLE hReceiveEvent = 0;
/* FIXME: Aquire some sort of interface lock */
/* FIXME: Need some sort of context for this callback. Need to determine
* how this is actually done with the SP
*/
/* FIXME: Who needs to delete the message when done? */
switch( lpMsg->dwType )
{
case DPSYS_CREATEPLAYERORGROUP:
{
LPDPMSG_CREATEPLAYERORGROUP msg = (LPDPMSG_CREATEPLAYERORGROUP)lpMsg;
if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
{
hr = DP_IF_CreatePlayer( This, lpMessageHeader, msg->dpId,
&msg->dpnName, 0, msg->lpData,
msg->dwDataSize, msg->dwFlags, ... );
}
else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
{
/* Group in group situation? */
if( msg->dpIdParent == DPID_NOPARENT_GROUP )
{
hr = DP_IF_CreateGroup( This, lpMessageHeader, msg->dpId,
&msg->dpnName, 0, msg->lpData,
msg->dwDataSize, msg->dwFlags, ... );
}
else /* Group in Group */
{
hr = DP_IF_CreateGroupInGroup( This, lpMessageHeader, msg->dpIdParent,
&msg->dpnName, 0, msg->lpData,
msg->dwDataSize, msg->dwFlags, ... );
}
}
else /* Hmmm? */
{
ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" );
return;
}
break;
}
case DPSYS_DESTROYPLAYERORGROUP:
{
LPDPMSG_DESTROYPLAYERORGROUP msg = (LPDPMSG_DESTROYPLAYERORGROUP)lpMsg;
if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
{
hr = DP_IF_DestroyPlayer( This, msg->dpId, ... );
}
else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
{
hr = DP_IF_DestroyGroup( This, msg->dpId, ... );
}
else /* Hmmm? */
{
ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" );
return;
}
break;
}
case DPSYS_ADDPLAYERTOGROUP:
{
LPDPMSG_ADDPLAYERTOGROUP msg = (LPDPMSG_ADDPLAYERTOGROUP)lpMsg;
hr = DP_IF_AddPlayerToGroup( This, msg->dpIdGroup, msg->dpIdPlayer, ... );
break;
}
case DPSYS_DELETEPLAYERFROMGROUP:
{
LPDPMSG_DELETEPLAYERFROMGROUP msg = (LPDPMSG_DELETEPLAYERFROMGROUP)lpMsg;
hr = DP_IF_DeletePlayerFromGroup( This, msg->dpIdGroup, msg->dpIdPlayer,
... );
break;
}
case DPSYS_SESSIONLOST:
{
LPDPMSG_SESSIONLOST msg = (LPDPMSG_SESSIONLOST)lpMsg;
FIXME( "DPSYS_SESSIONLOST not handled\n" );
break;
}
case DPSYS_HOST:
{
LPDPMSG_HOST msg = (LPDPMSG_HOST)lpMsg;
FIXME( "DPSYS_HOST not handled\n" );
break;
}
case DPSYS_SETPLAYERORGROUPDATA:
{
LPDPMSG_SETPLAYERORGROUPDATA msg = (LPDPMSG_SETPLAYERORGROUPDATA)lpMsg;
if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
{
hr = DP_IF_SetPlayerData( This, msg->dpId, msg->lpData, msg->dwDataSize, DPSET_REMOTE, ... );
}
else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
{
hr = DP_IF_SetGroupData( This, msg->dpId, msg->lpData, msg->dwDataSize,
DPSET_REMOTE, ... );
}
else /* Hmmm? */
{
ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
return;
}
break;
}
case DPSYS_SETPLAYERORGROUPNAME:
{
LPDPMSG_SETPLAYERORGROUPNAME msg = (LPDPMSG_SETPLAYERORGROUPNAME)lpMsg;
if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
{
hr = DP_IF_SetPlayerName( This, msg->dpId, msg->dpnName, ... );
}
else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
{
hr = DP_IF_SetGroupName( This, msg->dpId, msg->dpnName, ... );
}
else /* Hmmm? */
{
ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
return;
}
break;
}
case DPSYS_SETSESSIONDESC;
{
LPDPMSG_SETSESSIONDESC msg = (LPDPMSG_SETSESSIONDESC)lpMsg;
hr = DP_IF_SetSessionDesc( This, &msg->dpDesc );
break;
}
case DPSYS_ADDGROUPTOGROUP:
{
LPDPMSG_ADDGROUPTOGROUP msg = (LPDPMSG_ADDGROUPTOGROUP)lpMsg;
hr = DP_IF_AddGroupToGroup( This, msg->dpIdParentGroup, msg->dpIdGroup,
... );
break;
}
case DPSYS_DELETEGROUPFROMGROUP:
{
LPDPMSG_DELETEGROUPFROMGROUP msg = (LPDPMSG_DELETEGROUPFROMGROUP)lpMsg;
hr = DP_IF_DeleteGroupFromGroup( This, msg->dpIdParentGroup,
msg->dpIdGroup, ... );
break;
}
case DPSYS_SECUREMESSAGE:
{
LPDPMSG_SECUREMESSAGE msg = (LPDPMSG_SECUREMESSAGE)lpMsg;
FIXME( "DPSYS_SECUREMESSAGE not implemented\n" );
break;
}
case DPSYS_STARTSESSION:
{
LPDPMSG_STARTSESSION msg = (LPDPMSG_STARTSESSION)lpMsg;
FIXME( "DPSYS_STARTSESSION not implemented\n" );
break;
}
case DPSYS_CHAT:
{
LPDPMSG_CHAT msg = (LPDPMSG_CHAT)lpMsg;
FIXME( "DPSYS_CHAT not implemeneted\n" );
break;
}
case DPSYS_SETGROUPOWNER:
{
LPDPMSG_SETGROUPOWNER msg = (LPDPMSG_SETGROUPOWNER)lpMsg;
FIXME( "DPSYS_SETGROUPOWNER not implemented\n" );
break;
}
case DPSYS_SENDCOMPLETE:
{
LPDPMSG_SENDCOMPLETE msg = (LPDPMSG_SENDCOMPLETE)lpMsg;
FIXME( "DPSYS_SENDCOMPLETE not implemented\n" );
break;
}
default:
{
/* NOTE: This should be a user defined type. There is nothing that we
* need to do with it except queue it.
*/
TRACE( "Received user message type(?) 0x%08lx through SP.\n",
lpMsg->dwType );
break;
}
}
FIXME( "Queue message in the receive queue. Need some context data!\n" );
if( FAILED(hr) )
{
ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg->dwType );
}
/* If a receive event was registered for this player, invoke it */
if( hReceiveEvent )
{
SetEvent( hReceiveEvent );
}
#endif
}
static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
( LPDIRECTPLAYSP iface,
DPID idPlayer,
LPVOID lpData,
DWORD dwDataSize,
DWORD dwFlags
)
{
HRESULT hr;
LPDP_SPPLAYERDATA lpPlayerEntry;
LPVOID lpPlayerData;
IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n",
This, idPlayer, lpData, dwDataSize, dwFlags );
hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerEntry );
if( FAILED(hr) )
{
/* Player must not exist */
return DPERR_INVALIDPLAYER;
}
lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
CopyMemory( lpPlayerData, lpData, dwDataSize );
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
( LPDIRECTPLAYSP iface,
LPCDPCOMPOUNDADDRESSELEMENT lpElements,
DWORD dwElementCount,
LPVOID lpAddress,
LPDWORD lpdwAddressSize
)
{
IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
FIXME( "(%p)->(%p,0x%08lx,%p,%p): stub\n",
This, lpElements, dwElementCount, lpAddress, lpdwAddressSize );
return DP_OK;
}
static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
( LPDIRECTPLAYSP iface,
LPVOID* lplpData,
LPDWORD lpdwDataSize,
DWORD dwFlags
)
{
HRESULT hr = DP_OK;
IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
/* 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 != DPSET_REMOTE )
{
return DPERR_INVALIDPARAMS;
}
#else
/* ... but most service providers call this with 1 */
/* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
* thing?
*/
if( dwFlags != DPSET_REMOTE )
{
TRACE( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
}
#endif
/* FIXME: What to do in the case where this isn't initialized yet? */
/* Yes, we're supposed to return a pointer to the memory we have stored! */
if( dwFlags == DPSET_REMOTE )
{
*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 hr;
}
static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
( LPDIRECTPLAYSP iface,
LPVOID lpData,
DWORD dwDataSize,
DWORD dwFlags
)
{
LPVOID lpSpData;
IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
/* 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 != DPSET_REMOTE )
{
return DPERR_INVALIDPARAMS;
}
#else
/* ... but most service providers call this with 1 */
/* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
* thing?
*/
if( dwFlags != DPSET_REMOTE )
{
TRACE( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
}
#endif
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 )
{
HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
This->sp->dwSpRemoteDataSize = dwDataSize;
This->sp->lpSpRemoteData = lpSpData;
}
else if ( dwFlags == DPSET_LOCAL )
{
HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
This->sp->lpSpLocalData = lpSpData;
This->sp->dwSpLocalDataSize = dwDataSize;
}
return DP_OK;
}
static VOID WINAPI IDirectPlaySPImpl_SendComplete
( LPDIRECTPLAYSP iface,
LPVOID unknownA,
DWORD unknownB
)
{
IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface;
FIXME( "(%p)->(%p,0x%08lx): stub\n",
This, unknownA, unknownB );
}
static const IDirectPlaySPVtbl directPlaySPVT =
{
DPSP_QueryInterface,
DPSP_AddRef,
DPSP_Release,
IDirectPlaySPImpl_AddMRUEntry,
IDirectPlaySPImpl_CreateAddress,
IDirectPlaySPImpl_EnumAddress,
IDirectPlaySPImpl_EnumMRUEntries,
IDirectPlaySPImpl_GetPlayerFlags,
IDirectPlaySPImpl_GetSPPlayerData,
IDirectPlaySPImpl_HandleMessage,
IDirectPlaySPImpl_SetSPPlayerData,
IDirectPlaySPImpl_CreateCompoundAddress,
IDirectPlaySPImpl_GetSPData,
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 ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -