- More implementation
- Should be able to enumerate sessions anywhere with at least tcp/ip
This commit is contained in:
parent
8611353053
commit
8adbdd7c7b
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue