- More implementation

- Should be able to enumerate sessions anywhere with at least tcp/ip
This commit is contained in:
Peter Hunnisett 2000-08-29 23:55:06 +00:00 committed by Alexandre Julliard
parent 8611353053
commit 8adbdd7c7b
7 changed files with 557 additions and 342 deletions

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,8 @@ struct PlayerData
DPNAME name;
HANDLE hEvent;
ULONG uRef; /* What is the reference count on this data? */
/* View of local data */
LPVOID lpLocalData;
DWORD dwLocalDataSize;
@ -68,6 +70,8 @@ struct GroupData
/* Internal information */
DPID parent; /* If parent == 0 it's a top level group */
ULONG uRef; /* Reference count */
DPQ_HEAD(GroupList) groups; /* A group has [0..n] groups */
DPQ_HEAD(PlayerList) players; /* A group has [0..n] players */
@ -117,12 +121,7 @@ typedef struct tagDirectPlay2Data
BOOL bHostInterface; /* Did this interface create the session */
#if 0
DPQ_HEAD(PlayerList) players; /* All players w/ interface */
DPQ_HEAD(GroupList) groups; /* All main groups w/ interface */
#else
lpGroupData lpSysGroup; /* System group with _everything_ in it */
#endif
LPDPSESSIONDESC2 lpSessionDesc;
@ -137,6 +136,11 @@ typedef struct tagDirectPlay2Data
HMODULE hServiceProvider;
BOOL bConnectionInitialized;
/* proof of concept for message reception */
HANDLE hMsgReceipt;
LPVOID lpMsgReceived;
} DirectPlay2Data;
typedef struct tagDirectPlay3Data
@ -182,4 +186,11 @@ extern ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
extern ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
extern ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
DWORD dwMessageBodySize, LPCVOID lpMessageHeader,
WORD wCommandId, WORD wVersion,
LPVOID* lplpReply, LPDWORD lpdwMsgSize );
#endif /* __WINE_DPLAY_GLOBAL_INCLUDED */

View File

@ -384,6 +384,8 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
{
LPDPMSG_SENDENVELOPE lpMsg = (LPDPMSG_SENDENVELOPE)lpMessageBody;
HRESULT hr = DPERR_GENERIC;
WORD wCommandId;
WORD wVersion;
ICOM_THIS(IDirectPlaySPImpl,iface);
@ -391,16 +393,20 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n",
This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
wCommandId = lpMsg->wCommandId;
wVersion = lpMsg->wVersion;
TRACE( "Incomming message has envelope of 0x%08lx, %u, %u\n",
lpMsg->dwMagic, lpMsg->wCommandId, lpMsg->wVersion );
lpMsg->dwMagic, wCommandId, wVersion );
if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG )
{
FIXME( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic );
ERR( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic );
}
switch( lpMsg->wCommandId )
{
/* Name server needs to handle this request */
case DPMSGCMD_ENUMSESSIONSREQUEST:
{
DPSP_REPLYDATA data;
@ -421,6 +427,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
break;
}
/* Name server needs to handle this request */
case DPMSGCMD_ENUMSESSIONSREPLY:
{
NS_SetRemoteComputerAsNameServer( lpMessageHeader,
@ -432,8 +439,43 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
break;
}
case DPMSGCMD_NEWPLAYERIDREPLY:
case DPMSGCMD_REQUESTNEWPLAYERID:
{
DPSP_REPLYDATA data;
data.lpMessage = NULL;
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 );
/* Do we want a reply? */
if( data.lpMessage != NULL )
{
HRESULT hr;
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) );
}
}
break;
}
default:
FIXME( "Unknown Command of %u\n", lpMsg->wCommandId );
FIXME( "Unknown Command of %u and size 0x%08lx\n",
lpMsg->wCommandId, dwMessageBodySize );
}
#if 0
@ -443,10 +485,7 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
/* FIXME: Need some sort of context for this callback. Need to determine
* how this is actually done with the SP
*/
/* FIXME: Add in size checks for all messages to determine corrupt messages */ /* FIXME: Who needs to delete the message when done? */
/* FIXME: Does this get invoked as soon as the message arrives, or as soon
* as it's removed from the queue (or peeked in queue?)
*/
/* FIXME: Who needs to delete the message when done? */
switch( lpMsg->dwType )
{
case DPSYS_CREATEPLAYERORGROUP:

View File

@ -331,7 +331,7 @@ typedef HRESULT (WINAPI *LPDPSP_SPINIT)(LPSPINITDATA);
/* This variable is exported from the DLL at ordinal 6 to be accessed by the
* SP directly
*/
extern DWORD gdwDPlaySPRefCount;
extern __declspec(dllimport) DWORD gdwDPlaySPRefCount;
#endif

View File

@ -11,8 +11,11 @@
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "dplayx_messages.h"
#include "dplay_global.h"
#include "dplayx_global.h"
DEFAULT_DEBUG_CHANNEL(dplay)
@ -136,3 +139,103 @@ end_of_thread:
return 0;
}
HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
LPDPID lpdpidAllocatedId )
{
LPVOID lpMsg;
LPDPMSG_REQUESTNEWPLAYERID lpMsgBody;
DWORD dwMsgSize;
DWORD dwWaitReturn;
HRESULT hr = DP_OK;
FIXME( "semi stub\n" );
DebugBreak();
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
lpMsgBody = (LPDPMSG_REQUESTNEWPLAYERID)( (BYTE*)lpMsg +
This->dp2->spData.dwSPHeaderSize );
lpMsgBody->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
lpMsgBody->envelope.wCommandId = DPMSGCMD_REQUESTNEWPLAYERID;
lpMsgBody->envelope.wVersion = DPMSGVER_DP6;
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...
*/
{
DPSP_SENDDATA data;
data.dwFlags = DPSEND_GUARANTEED;
data.idPlayerTo = 0; /* Name server */
data.idPlayerFrom = 0; /* Sending from DP */
data.lpMessage = lpMsg;
data.dwMessageSize = dwMsgSize;
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 );
hr = (*This->dp2->spData.lpCB->Send)( &data );
if( FAILED(hr) )
{
ERR( "Request for new playerID send failed: %s\n",
DPLAYX_HresultToString( hr ) );
}
}
dwWaitReturn = WaitForSingleObject( This->dp2->hMsgReceipt, 30000 );
if( dwWaitReturn != WAIT_OBJECT_0 )
{
ERR( "Wait failed 0x%08lx\n", dwWaitReturn );
}
CloseHandle( This->dp2->hMsgReceipt );
This->dp2->hMsgReceipt = 0;
/* Need to examine the data and extract the new player id */
/* I just hope that dplay doesn't return the whole new player! */
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 hr;
DPSP_SENDDATA data;
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;
hr = (*This->dp2->spData.lpCB->Send)( &data );
if( FAILED(hr) )
{
ERR( "Request for open stream send failed: %s\n",
DPLAYX_HresultToString( hr ) );
}
/* FIXME: hack to give some time for channel to open */
SleepEx( 1000 /* 1 sec */, FALSE );
return hr;
}

View File

@ -6,6 +6,8 @@
#include "dplay.h"
#include "rpc.h" /* For GUID */
#include "dplay_global.h"
DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
HANDLE hDeath, HANDLE hConnRead );
@ -27,11 +29,13 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
#define DPMSGCMD_CREATESESSION 8
#define DPMSGCMD_CREATENEWPLAYER 9
#define DPMSGCMD_SYSTEMMESSAGE 10
#define DPMSGCMD_DELETEPLAYER 11
#define DPMSGCMD_DELETEGROUP 12
#define DPMSGCMD_ENUMGROUPS 17
#define DPMSGCMD_FORWARDCREATEPLAYER 19 /* This may be a get name table req */
/* This is what DP 6 defines it as. Don't know what it means. All messages
* defined below are DPMSGVER_DP6.
*/
@ -112,12 +116,12 @@ typedef struct tagDPMSG_CREATESESSION
} DPMSG_CREATESESSION, *LPDPMSG_CREATESESSION;
typedef const DPMSG_CREATESESSION* LPCDPMSG_CREATESESSION;
/* 28 bytes - ~18 header ~= 10 bytes msg */
/* 12 bytes msg */
typedef struct tagDPMSG_REQUESTNEWPLAYERID
{
DPMSG_SENDENVELOPE envelope;
DWORD dwFlags; /* dwFlags used for CreatePlayer */
} DPMSG_REQUESTNEWPLAYERID, *LPDPMSG_REQUESTNEWPLAYERID;
typedef const DPMSG_REQUESTNEWPLAYERID* LPCDPMSG_REQUESTNEWPLAYERID;
@ -127,10 +131,23 @@ typedef struct tagDPMSG_NEWPLAYERIDREPLY
{
DPMSG_SENDENVELOPE envelope;
#if 0
DPID dpidNewPlayerId;
#else
BYTE unknown[38];
#endif
} DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_NEWPLAYERIDREPLY;
typedef const DPMSG_NEWPLAYERIDREPLY* LPCDPMSG_NEWPLAYERIDREPLY;
#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

View File

@ -303,7 +303,8 @@ void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
lpReplyData->lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
lpReplyData->dwMessageSize );
rmsg = (LPDPMSG_ENUMSESSIONSREPLY)lpReplyData->lpMessage;
rmsg = (LPDPMSG_ENUMSESSIONSREPLY)( (BYTE*)lpReplyData->lpMessage +
lpDP->dp2->spData.dwSPHeaderSize);
rmsg->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
rmsg->envelope.wCommandId = DPMSGCMD_ENUMSESSIONSREPLY;
@ -323,7 +324,7 @@ void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
string = lpDP->dp2->lpSessionDesc->sess.lpszSessionName;
}
lstrcpyW( (LPWSTR)rmsg+1, string );
lstrcpyW( (LPWSTR)(rmsg+1), string );
}