- Remove winmm hack in dplay code
- Fix up some missing holes in the code - More message implementation - Status documentation update
This commit is contained in:
parent
a387aa4868
commit
72526ba4f5
|
@ -380,7 +380,7 @@ crtdll/libcrtdll.so: libkernel32.so
|
||||||
ddraw/libddraw.so: libole32.so libuser32.so libx11drv.so libgdi32.so libkernel32.so
|
ddraw/libddraw.so: libole32.so libuser32.so libx11drv.so libgdi32.so libkernel32.so
|
||||||
dinput/libdinput.so: libuser32.so libkernel32.so
|
dinput/libdinput.so: libuser32.so libkernel32.so
|
||||||
dplay/libdplay.so: libdplayx.so
|
dplay/libdplay.so: libdplayx.so
|
||||||
dplayx/libdplayx.so: libole32.so libadvapi32.so libkernel32.so
|
dplayx/libdplayx.so: libwinmm.so libole32.so libadvapi32.so libkernel32.so
|
||||||
dsound/libdsound.so: libwinmm.so libkernel32.so
|
dsound/libdsound.so: libwinmm.so libkernel32.so
|
||||||
gdi/libgdi32.so: libkernel32.so
|
gdi/libgdi32.so: libkernel32.so
|
||||||
icmp/libicmp.so: libkernel32.so
|
icmp/libicmp.so: libkernel32.so
|
||||||
|
|
|
@ -4,7 +4,7 @@ SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = dplayx
|
MODULE = dplayx
|
||||||
SOVERSION = 1.0
|
SOVERSION = 1.0
|
||||||
IMPORTS = ole32 advapi32 kernel32
|
IMPORTS = winmm ole32 advapi32 kernel32
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
dpclassfactory.c \
|
dpclassfactory.c \
|
||||||
|
|
|
@ -622,6 +622,8 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||||
This, lpMessageBody, dwMessageBodySize, lpMessageHeader, wCommandId,
|
This, lpMessageBody, dwMessageBodySize, lpMessageHeader, wCommandId,
|
||||||
wVersion );
|
wVersion );
|
||||||
|
|
||||||
|
DebugBreak();
|
||||||
|
|
||||||
switch( wCommandId )
|
switch( wCommandId )
|
||||||
{
|
{
|
||||||
case DPMSGCMD_REQUESTNEWPLAYERID:
|
case DPMSGCMD_REQUESTNEWPLAYERID:
|
||||||
|
@ -638,7 +640,25 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
*lpdwMsgSize );
|
*lpdwMsgSize );
|
||||||
|
|
||||||
FIXME( "Ignoring dwFlags in msg\n" );
|
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
|
||||||
|
|
||||||
/* Setup the reply */
|
/* Setup the reply */
|
||||||
lpReply = (LPDPMSG_NEWPLAYERIDREPLY)( (BYTE*)(*lplpReply) +
|
lpReply = (LPDPMSG_NEWPLAYERIDREPLY)( (BYTE*)(*lplpReply) +
|
||||||
|
@ -648,10 +668,10 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||||
lpReply->envelope.wCommandId = DPMSGCMD_NEWPLAYERIDREPLY;
|
lpReply->envelope.wCommandId = DPMSGCMD_NEWPLAYERIDREPLY;
|
||||||
lpReply->envelope.wVersion = DPMSGVER_DP6;
|
lpReply->envelope.wVersion = DPMSGVER_DP6;
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* FIXME: Need to know the proper contents of the message! */
|
|
||||||
lpReply->dpidNewPlayerId = DP_NextObjectId();
|
lpReply->dpidNewPlayerId = DP_NextObjectId();
|
||||||
#endif
|
|
||||||
|
TRACE( "Allocating new playerid 0x%08lx from remote request\n",
|
||||||
|
lpReply->dpidNewPlayerId );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -659,8 +679,6 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||||
case DPMSGCMD_NEWPLAYERIDREPLY:
|
case DPMSGCMD_NEWPLAYERIDREPLY:
|
||||||
{
|
{
|
||||||
|
|
||||||
DebugBreak();
|
|
||||||
|
|
||||||
if( This->dp2->hMsgReceipt )
|
if( This->dp2->hMsgReceipt )
|
||||||
{
|
{
|
||||||
/* This is a hack only */
|
/* This is a hack only */
|
||||||
|
@ -672,7 +690,7 @@ HRESULT DP_HandleMessage( IDirectPlay2Impl* This, LPCVOID lpMessageBody,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR( "No receipt event set\n" );
|
ERR( "No receipt event set - only expecting in reply mode\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1304,6 +1322,7 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
DWORD dwFlags,
|
DWORD dwFlags,
|
||||||
BOOL bAnsi )
|
BOOL bAnsi )
|
||||||
{
|
{
|
||||||
|
HANDLE hr = DP_OK;
|
||||||
lpPlayerData lpPData;
|
lpPlayerData lpPData;
|
||||||
lpPlayerList lpPList;
|
lpPlayerList lpPList;
|
||||||
|
|
||||||
|
@ -1341,7 +1360,7 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HRESULT hr = DP_MSG_SendRequestPlayerId( This, dwFlags, lpidPlayer );
|
hr = DP_MSG_SendRequestPlayerId( This, dwFlags, lpidPlayer );
|
||||||
|
|
||||||
if( FAILED(hr) )
|
if( FAILED(hr) )
|
||||||
{
|
{
|
||||||
|
@ -1409,7 +1428,34 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
data.lpSPMessageHeader = lpMsgHdr;
|
data.lpSPMessageHeader = lpMsgHdr;
|
||||||
data.lpISP = This->dp2->spData.lpISP;
|
data.lpISP = This->dp2->spData.lpISP;
|
||||||
|
|
||||||
(*This->dp2->spData.lpCB->CreatePlayer)( &data );
|
hr = (*This->dp2->spData.lpCB->CreatePlayer)( &data );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( FAILED(hr) )
|
||||||
|
{
|
||||||
|
ERR( "Failed to create player with sp: %s\n", DPLAYX_HresultToString(hr) );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now let the SP know that this player is a member of the system group */
|
||||||
|
if( This->dp2->spData.lpCB->AddPlayerToGroup )
|
||||||
|
{
|
||||||
|
DPSP_ADDPLAYERTOGROUPDATA data;
|
||||||
|
|
||||||
|
data.idPlayer = *lpidPlayer;
|
||||||
|
data.idGroup = DPID_SYSTEM_GROUP;
|
||||||
|
data.lpISP = This->dp2->spData.lpISP;
|
||||||
|
|
||||||
|
TRACE( "Calling SP AddPlayerToGroup (sys group)\n" );
|
||||||
|
|
||||||
|
hr = (*This->dp2->spData.lpCB->AddPlayerToGroup)( &data );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( FAILED(hr) )
|
||||||
|
{
|
||||||
|
ERR( "Failed to add player to sys groupwith sp: %s\n",
|
||||||
|
DPLAYX_HresultToString(hr) );
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
||||||
|
@ -1435,11 +1481,11 @@ static HRESULT WINAPI DP_IF_CreatePlayer
|
||||||
/* FIXME: Correct to just use send effectively? */
|
/* FIXME: Correct to just use send effectively? */
|
||||||
/* FIXME: Should size include data w/ message or just message "header" */
|
/* FIXME: Should size include data w/ message or just message "header" */
|
||||||
/* FIXME: Check return code */
|
/* FIXME: Check return code */
|
||||||
DP_SendEx( This, DPID_SERVERPLAYER, DPID_ALLPLAYERS, 0, &msg, sizeof( msg ),
|
hr = DP_SendEx( This, DPID_SERVERPLAYER, DPID_ALLPLAYERS, 0, &msg,
|
||||||
0, 0, NULL, NULL, bAnsi );
|
sizeof( msg ), 0, 0, NULL, NULL, bAnsi );
|
||||||
}
|
}
|
||||||
|
|
||||||
return DP_OK;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
|
static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
|
||||||
|
@ -1936,6 +1982,9 @@ static void DP_InvokeEnumSessionCallbacks
|
||||||
|
|
||||||
FIXME( ": not checking for conditions\n" );
|
FIXME( ": not checking for conditions\n" );
|
||||||
|
|
||||||
|
/* Not sure if this should be pruning but it's convenient */
|
||||||
|
NS_PruneSessionCache( lpNSInfo );
|
||||||
|
|
||||||
NS_ResetSessionEnumeration( lpNSInfo );
|
NS_ResetSessionEnumeration( lpNSInfo );
|
||||||
|
|
||||||
/* Enumerate all sessions */
|
/* Enumerate all sessions */
|
||||||
|
@ -2663,7 +2712,7 @@ static HRESULT WINAPI DP_SecureOpen
|
||||||
|
|
||||||
if( dwFlags & DPOPEN_JOIN )
|
if( dwFlags & DPOPEN_JOIN )
|
||||||
{
|
{
|
||||||
DPID dpidServerId = DPID_SERVERPLAYER;
|
DPID dpidServerId = DPID_UNKNOWN;
|
||||||
|
|
||||||
/* Create the server player for this interface. This way we can receive
|
/* Create the server player for this interface. This way we can receive
|
||||||
* messages for this session.
|
* messages for this session.
|
||||||
|
@ -2685,6 +2734,12 @@ static HRESULT WINAPI DP_SecureOpen
|
||||||
0, DPPLAYER_SERVERPLAYER, bAnsi );
|
0, DPPLAYER_SERVERPLAYER, bAnsi );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( FAILED(hr) )
|
||||||
|
{
|
||||||
|
ERR( "Couldn't create name server/system player: %s\n",
|
||||||
|
DPLAYX_HresultToString(hr) );
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
/* FIXME: Need to add interface locking inside procedures */
|
/* FIXME: Need to add interface locking inside procedures */
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(dplay);
|
DEFAULT_DEBUG_CHANNEL(dplay)
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
static BOOL DPSP_CreateIUnknown( LPVOID lpSP );
|
static BOOL DPSP_CreateIUnknown( LPVOID lpSP );
|
||||||
|
@ -369,6 +369,8 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
|
||||||
FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n",
|
FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n",
|
||||||
This, idPlayer, lplpData, lpdwDataSize, dwFlags );
|
This, idPlayer, lplpData, lpdwDataSize, dwFlags );
|
||||||
|
|
||||||
|
/* What to do in the case where there is nothing set yet? */
|
||||||
|
|
||||||
*lplpData = This->sp->lpPlayerData;
|
*lplpData = This->sp->lpPlayerData;
|
||||||
*lpdwDataSize = This->sp->dwPlayerDataSize;
|
*lpdwDataSize = This->sp->dwPlayerDataSize;
|
||||||
|
|
||||||
|
@ -440,6 +442,8 @@ static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DPMSGCMD_GETNAMETABLE:
|
||||||
|
case DPMSGCMD_GETNAMETABLEREPLY:
|
||||||
case DPMSGCMD_NEWPLAYERIDREPLY:
|
case DPMSGCMD_NEWPLAYERIDREPLY:
|
||||||
case DPMSGCMD_REQUESTNEWPLAYERID:
|
case DPMSGCMD_REQUESTNEWPLAYERID:
|
||||||
{
|
{
|
||||||
|
@ -796,6 +800,8 @@ static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
|
||||||
}
|
}
|
||||||
#endif
|
#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! */
|
/* Yes, we're supposed to return a pointer to the memory we have stored! */
|
||||||
if( dwFlags == DPSET_REMOTE )
|
if( dwFlags == DPSET_REMOTE )
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,23 +55,27 @@ typedef BOOL (CALLBACK* LPENUMMRUCALLBACK)( LPCVOID lpData,
|
||||||
ICOM_DEFINE(IDirectPlaySP,IUnknown)
|
ICOM_DEFINE(IDirectPlaySP,IUnknown)
|
||||||
#undef ICOM_INTERFACE
|
#undef ICOM_INTERFACE
|
||||||
|
|
||||||
|
|
||||||
|
/* NOTE: The microsoft provided header file doesn't have these access
|
||||||
|
* functions
|
||||||
|
*/
|
||||||
/*** IUnknown methods ***/
|
/*** IUnknown methods ***/
|
||||||
#define IDirectPlaySP_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
|
#define IDirectPlaySP_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
|
||||||
#define IDirectPlaySP_AddRef(p) ICOM_CALL (AddRef,p)
|
#define IDirectPlaySP_AddRef(p) ICOM_CALL (AddRef,p)
|
||||||
#define IDirectPlaySP_Release(p) ICOM_CALL (Release,p)
|
#define IDirectPlaySP_Release(p) ICOM_CALL (Release,p)
|
||||||
/*** IDirectPlaySP methods ***/
|
/*** IDirectPlaySP methods ***/
|
||||||
#define IDirectPlaySP_AddMRUEntry ICOM_CALL5(AddMRUEntry,p,a,b,c,d,e)
|
#define IDirectPlaySP_AddMRUEntry(p,a,b,c,d,e) ICOM_CALL5(AddMRUEntry,p,a,b,c,d,e)
|
||||||
#define IDirectPlaySP_CreateAddress ICOM_CALL6(CreateAddress,p,a,b,c,d,e,f)
|
#define IDirectPlaySP_CreateAddress(p,a,b,c,d,e,f) ICOM_CALL6(CreateAddress,p,a,b,c,d,e,f)
|
||||||
#define IDirectPlaySP_EnumAddress ICOM_CALL4(EnumAddress,p,a,b,c,d)
|
#define IDirectPlaySP_EnumAddress(p,a,b,c,d) ICOM_CALL4(EnumAddress,p,a,b,c,d)
|
||||||
#define IDirectPlaySP_EnumMRUEntries ICOM_CALL4(EnumMRUEntries,p,a,b,c,d)
|
#define IDirectPlaySP_EnumMRUEntries(p,a,b,c,d) ICOM_CALL4(EnumMRUEntries,p,a,b,c,d)
|
||||||
#define IDirectPlaySP_GetPlayerFlags ICOM_CALL2(GetPlayerFlags,p,a,b)
|
#define IDirectPlaySP_GetPlayerFlags(p,a,b) ICOM_CALL2(GetPlayerFlags,p,a,b)
|
||||||
#define IDirectPlaySP_GetSPPlayerData ICOM_CALL4(GetSPPlayerData,p,a,b,c,d)
|
#define IDirectPlaySP_GetSPPlayerData(p,a,b,c,d) ICOM_CALL4(GetSPPlayerData,p,a,b,c,d)
|
||||||
#define IDirectPlaySP_HandleMessage ICOM_CALL3(HandleMessage,p,a,b,c)
|
#define IDirectPlaySP_HandleMessage(p,a,b,c) ICOM_CALL3(HandleMessage,p,a,b,c)
|
||||||
#define IDirectPlaySP_SetSPPlayerData ICOM_CALL4(SetSPPlayerData,p,a,b,c,d)
|
#define IDirectPlaySP_SetSPPlayerData(p,a,b,c,d) ICOM_CALL4(SetSPPlayerData,p,a,b,c,d)
|
||||||
#define IDirectPlaySP_CreateCompoundAddress ICOM_CALL4(CreateCompoundAddress,p,a,b,c,d)
|
#define IDirectPlaySP_CreateCompoundAddress(p,a,b,c,d) ICOM_CALL4(CreateCompoundAddress,p,a,b,c,d)
|
||||||
#define IDirectPlaySP_GetSPData ICOM_CALL3(GetSPData,p,a,b,c)
|
#define IDirectPlaySP_GetSPData(p,a,b,c) ICOM_CALL3(GetSPData,p,a,b,c)
|
||||||
#define IDirectPlaySP_SetSPData ICOM_CALL3(SetSPData,p,a,b,c)
|
#define IDirectPlaySP_SetSPData(p,a,b,c) ICOM_CALL3(SetSPData,p,a,b,c)
|
||||||
#define IDirectPlaySP_SendComplete ICOM_CALL2(SendComplete,p,a,b)
|
#define IDirectPlaySP_SendComplete(p,a,b) ICOM_CALL2(SendComplete,p,a,b)
|
||||||
|
|
||||||
/* SP Callback stuff */
|
/* SP Callback stuff */
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ name dplayx
|
||||||
type win32
|
type win32
|
||||||
init DPLAYX_LibMain
|
init DPLAYX_LibMain
|
||||||
|
|
||||||
|
import winmm.dll
|
||||||
import ole32.dll
|
import ole32.dll
|
||||||
import advapi32.dll
|
import advapi32.dll
|
||||||
import kernel32.dll
|
import kernel32.dll
|
||||||
|
@ -11,7 +12,7 @@ import kernel32.dll
|
||||||
3 stdcall DirectPlayEnumerateW(ptr ptr) DirectPlayEnumerateW
|
3 stdcall DirectPlayEnumerateW(ptr ptr) DirectPlayEnumerateW
|
||||||
4 stdcall DirectPlayLobbyCreateA(ptr ptr ptr ptr long) DirectPlayLobbyCreateA
|
4 stdcall DirectPlayLobbyCreateA(ptr ptr ptr ptr long) DirectPlayLobbyCreateA
|
||||||
5 stdcall DirectPlayLobbyCreateW(ptr ptr ptr ptr long) DirectPlayLobbyCreateW
|
5 stdcall DirectPlayLobbyCreateW(ptr ptr ptr ptr long) DirectPlayLobbyCreateW
|
||||||
6 stub gdwDPlaySPRefCount
|
6 extern gdwDPlaySPRefCount gdwDPlaySPRefCount
|
||||||
9 stdcall DirectPlayEnumerate(ptr ptr) DirectPlayEnumerateA
|
9 stdcall DirectPlayEnumerate(ptr ptr) DirectPlayEnumerateA
|
||||||
10 stdcall DllCanUnloadNow() DPLAYX_DllCanUnloadNow
|
10 stdcall DllCanUnloadNow() DPLAYX_DllCanUnloadNow
|
||||||
11 stdcall DllGetClassObject(ptr ptr ptr) DPLAYX_DllGetClassObject
|
11 stdcall DllGetClassObject(ptr ptr ptr) DPLAYX_DllGetClassObject
|
||||||
|
|
|
@ -149,10 +149,6 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
DWORD dwWaitReturn;
|
DWORD dwWaitReturn;
|
||||||
HRESULT hr = DP_OK;
|
HRESULT hr = DP_OK;
|
||||||
|
|
||||||
FIXME( "semi stub\n" );
|
|
||||||
|
|
||||||
DebugBreak();
|
|
||||||
|
|
||||||
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
|
dwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpMsgBody );
|
||||||
|
|
||||||
lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
|
lpMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwMsgSize );
|
||||||
|
@ -185,6 +181,8 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
|
|
||||||
/* Setup for receipt */
|
/* Setup for receipt */
|
||||||
This->dp2->hMsgReceipt = CreateEventA( NULL, FALSE, FALSE, NULL );
|
This->dp2->hMsgReceipt = CreateEventA( NULL, FALSE, FALSE, NULL );
|
||||||
|
|
||||||
|
TRACE( "Sending request for player id\n" );
|
||||||
|
|
||||||
hr = (*This->dp2->spData.lpCB->Send)( &data );
|
hr = (*This->dp2->spData.lpCB->Send)( &data );
|
||||||
|
|
||||||
|
@ -192,6 +190,7 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
{
|
{
|
||||||
ERR( "Request for new playerID send failed: %s\n",
|
ERR( "Request for new playerID send failed: %s\n",
|
||||||
DPLAYX_HresultToString( hr ) );
|
DPLAYX_HresultToString( hr ) );
|
||||||
|
return DPERR_NOCONNECTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,13 +198,36 @@ HRESULT DP_MSG_SendRequestPlayerId( IDirectPlay2AImpl* This, DWORD dwFlags,
|
||||||
if( dwWaitReturn != WAIT_OBJECT_0 )
|
if( dwWaitReturn != WAIT_OBJECT_0 )
|
||||||
{
|
{
|
||||||
ERR( "Wait failed 0x%08lx\n", dwWaitReturn );
|
ERR( "Wait failed 0x%08lx\n", dwWaitReturn );
|
||||||
|
hr = DPERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle( This->dp2->hMsgReceipt );
|
CloseHandle( This->dp2->hMsgReceipt );
|
||||||
This->dp2->hMsgReceipt = 0;
|
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 */
|
||||||
/* I just hope that dplay doesn't return the whole new player! */
|
if( !FAILED(hr) )
|
||||||
|
{
|
||||||
|
LPCDPMSG_NEWPLAYERIDREPLY lpcReply;
|
||||||
|
|
||||||
|
lpcReply = (LPCDPMSG_NEWPLAYERIDREPLY)This->dp2->lpMsgReceived;
|
||||||
|
|
||||||
|
*lpdpidAllocatedId = lpcReply->dpidNewPlayerId;
|
||||||
|
|
||||||
|
TRACE( "Received reply for id = 0x%08lx\n", lpcReply->dpidNewPlayerId );
|
||||||
|
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,6 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
#define DPMSGCMD_ENUMSESSIONSREPLY 1
|
#define DPMSGCMD_ENUMSESSIONSREPLY 1
|
||||||
#define DPMSGCMD_ENUMSESSIONSREQUEST 2
|
#define DPMSGCMD_ENUMSESSIONSREQUEST 2
|
||||||
|
|
||||||
#define DPMSGCMD_GETSETNAMETABLE 3 /* Request info from NS about
|
|
||||||
existing players/groups etc. Is
|
|
||||||
also used for reply */
|
|
||||||
|
|
||||||
#define DPMSGCMD_REQUESTNEWPLAYERID 5
|
#define DPMSGCMD_REQUESTNEWPLAYERID 5
|
||||||
|
|
||||||
|
@ -34,7 +31,9 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
|
|
||||||
#define DPMSGCMD_ENUMGROUPS 17
|
#define DPMSGCMD_ENUMGROUPS 17
|
||||||
|
|
||||||
#define DPMSGCMD_FORWARDCREATEPLAYER 19 /* This may be a get name table req */
|
#define DPMSGCMD_GETNAMETABLE 19
|
||||||
|
|
||||||
|
#define DPMSGCMD_GETNAMETABLEREPLY 29
|
||||||
|
|
||||||
/* 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.
|
||||||
|
@ -48,7 +47,7 @@ DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
* the message.
|
* the message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Size is 4 bytes */
|
/* Size is 8 bytes */
|
||||||
typedef struct tagDPMSG_SENDENVELOPE
|
typedef struct tagDPMSG_SENDENVELOPE
|
||||||
{
|
{
|
||||||
DWORD dwMagic;
|
DWORD dwMagic;
|
||||||
|
@ -126,15 +125,17 @@ typedef struct tagDPMSG_REQUESTNEWPLAYERID
|
||||||
} DPMSG_REQUESTNEWPLAYERID, *LPDPMSG_REQUESTNEWPLAYERID;
|
} DPMSG_REQUESTNEWPLAYERID, *LPDPMSG_REQUESTNEWPLAYERID;
|
||||||
typedef const DPMSG_REQUESTNEWPLAYERID* LPCDPMSG_REQUESTNEWPLAYERID;
|
typedef const DPMSG_REQUESTNEWPLAYERID* LPCDPMSG_REQUESTNEWPLAYERID;
|
||||||
|
|
||||||
/* 64 byte - ~18 header ~= 46 bytes msg */
|
/* 48 bytes msg */
|
||||||
typedef struct tagDPMSG_NEWPLAYERIDREPLY
|
typedef struct tagDPMSG_NEWPLAYERIDREPLY
|
||||||
{
|
{
|
||||||
DPMSG_SENDENVELOPE envelope;
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
|
||||||
#if 0
|
|
||||||
DPID dpidNewPlayerId;
|
DPID dpidNewPlayerId;
|
||||||
#else
|
#if 1
|
||||||
BYTE unknown[38];
|
/* 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
|
#endif
|
||||||
|
|
||||||
} DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_NEWPLAYERIDREPLY;
|
} DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_NEWPLAYERIDREPLY;
|
||||||
|
|
|
@ -77,7 +77,7 @@ do { \
|
||||||
*/
|
*/
|
||||||
#define DPQ_FIND_ENTRY( head, elm, field, fieldCompareOperator, fieldToCompare, rc )\
|
#define DPQ_FIND_ENTRY( head, elm, field, fieldCompareOperator, fieldToCompare, rc )\
|
||||||
do { \
|
do { \
|
||||||
(rc) = (head).lpQHFirst; /* NULL head? */ \
|
(rc) = DPQ_FIRST(head); /* NULL head? */ \
|
||||||
\
|
\
|
||||||
while( rc ) \
|
while( rc ) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -96,6 +96,39 @@ do { \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* head - pointer to DPQ_HEAD struct
|
||||||
|
* elm - how to find the next element
|
||||||
|
* field - to be concatenated to rc to compare with fieldToCompare
|
||||||
|
* fieldToCompare - The value that we're comparing against
|
||||||
|
* compare_cb - Callback to invoke to determine if comparision should continue.
|
||||||
|
* Callback must be defined with DPQ_DECL_COMPARECB.
|
||||||
|
* rc - Variable to put the return code. Same type as (head).lpQHFirst
|
||||||
|
*/
|
||||||
|
#define DPQ_FIND_ENTRY_CB( head, elm, field, compare_cb, fieldToCompare, rc )\
|
||||||
|
do { \
|
||||||
|
(rc) = DPQ_FIRST(head); /* NULL head? */ \
|
||||||
|
\
|
||||||
|
while( rc ) \
|
||||||
|
{ \
|
||||||
|
/* What we're searching for? */ \
|
||||||
|
if( compare_cb( &((rc)->field), &(fieldToCompare) ) ) \
|
||||||
|
{ \
|
||||||
|
break; /* no more */ \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* End of list check */ \
|
||||||
|
if( ( (rc) = (rc)->elm.lpQNext ) == (head).lpQHFirst ) \
|
||||||
|
{ \
|
||||||
|
rc = NULL; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* How to define the method to be passed to DPQ_DELETEQ */
|
||||||
|
#define DPQ_DECL_COMPARECB( name, type ) BOOL name( const type* elem1, const type* elem2 )
|
||||||
|
|
||||||
|
|
||||||
/* head - pointer to DPQ_HEAD struct
|
/* head - pointer to DPQ_HEAD struct
|
||||||
* elm - how to find the next element
|
* elm - how to find the next element
|
||||||
* field - to be concatenated to rc to compare with fieldToEqual
|
* field - to be concatenated to rc to compare with fieldToEqual
|
||||||
|
@ -115,19 +148,42 @@ do { \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* head - pointer to DPQ_HEAD struct
|
||||||
|
* elm - how to find the next element
|
||||||
|
* field - to be concatenated to rc to compare with fieldToCompare
|
||||||
|
* fieldToCompare - The value that we're comparing against
|
||||||
|
* compare_cb - Callback to invoke to determine if comparision should continue.
|
||||||
|
* Callback must be defined with DPQ_DECL_COMPARECB.
|
||||||
|
* rc - Variable to put the return code. Same type as (head).lpQHFirst
|
||||||
|
*/
|
||||||
|
#define DPQ_REMOVE_ENTRY_CB( head, elm, field, compare_cb, fieldToCompare, rc )\
|
||||||
|
do { \
|
||||||
|
DPQ_FIND_ENTRY_CB( head, elm, field, compare_cb, fieldToCompare, rc );\
|
||||||
|
\
|
||||||
|
/* Was the element found? */ \
|
||||||
|
if( rc ) \
|
||||||
|
{ \
|
||||||
|
DPQ_REMOVE( head, rc, elm ); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* Delete the entire queue
|
/* Delete the entire queue
|
||||||
* head - pointer to the head of the queue
|
* head - pointer to the head of the queue
|
||||||
* field - field to access the next elements of the queue
|
* field - field to access the next elements of the queue
|
||||||
* type - type of the pointer to the element element
|
* type - type of the pointer to the element element
|
||||||
* df - a delete function to be called. Declared with DPQ_DECL_DELETECB.
|
* df - a delete function to be called. Declared with DPQ_DECL_DELETECB.
|
||||||
*/
|
*/
|
||||||
#define DPQ_DELETEQ( head, field, type, df ) \
|
#define DPQ_DELETEQ( head, field, type, df ) \
|
||||||
while( !DPQ_IS_EMPTY(head) ) \
|
do \
|
||||||
{ \
|
{ \
|
||||||
type holder = (head).lpQHFirst; \
|
while( !DPQ_IS_EMPTY(head) ) \
|
||||||
DPQ_REMOVE( head, holder, field ); \
|
{ \
|
||||||
df( holder ); \
|
type holder = DPQ_FIRST(head); \
|
||||||
}
|
DPQ_REMOVE( head, holder, field ); \
|
||||||
|
df( holder ); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/* How to define the method to be passed to DPQ_DELETEQ */
|
/* How to define the method to be passed to DPQ_DELETEQ */
|
||||||
#define DPQ_DECL_DELETECB( name, type ) void name( type elem )
|
#define DPQ_DECL_DELETECB( name, type ) void name( type elem )
|
||||||
|
|
|
@ -1137,7 +1137,7 @@ BOOL DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId, HANDLE hDestProcess,
|
||||||
LPHANDLE lphRead )
|
LPHANDLE lphRead )
|
||||||
{
|
{
|
||||||
/* These are the handles for the created process */
|
/* These are the handles for the created process */
|
||||||
HANDLE hAppStart, hAppDeath, hAppRead;
|
HANDLE hAppStart, hAppDeath, hAppRead, hTemp;
|
||||||
SECURITY_ATTRIBUTES s_attrib;
|
SECURITY_ATTRIBUTES s_attrib;
|
||||||
|
|
||||||
s_attrib.nLength = sizeof( s_attrib );
|
s_attrib.nLength = sizeof( s_attrib );
|
||||||
|
@ -1145,9 +1145,14 @@ BOOL DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId, HANDLE hDestProcess,
|
||||||
s_attrib.bInheritHandle = TRUE;
|
s_attrib.bInheritHandle = TRUE;
|
||||||
|
|
||||||
/* FIXME: Is there a handle leak here? */
|
/* FIXME: Is there a handle leak here? */
|
||||||
*lphStart = CreateEventA( &s_attrib, TRUE, FALSE, NULL );
|
hTemp = CreateEventA( &s_attrib, TRUE, FALSE, NULL );
|
||||||
*lphDeath = CreateEventA( &s_attrib, TRUE, FALSE, NULL );
|
*lphStart = ConvertToGlobalHandle( hTemp );
|
||||||
*lphRead = CreateEventA( &s_attrib, TRUE, FALSE, NULL );
|
|
||||||
|
hTemp = CreateEventA( &s_attrib, TRUE, FALSE, NULL );
|
||||||
|
*lphDeath = ConvertToGlobalHandle( hTemp );
|
||||||
|
|
||||||
|
hTemp = CreateEventA( &s_attrib, TRUE, FALSE, NULL );
|
||||||
|
*lphRead = ConvertToGlobalHandle( hTemp );
|
||||||
|
|
||||||
if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart,
|
if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart,
|
||||||
hDestProcess, &hAppStart,
|
hDestProcess, &hAppStart,
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
#include "mmsystem.h"
|
||||||
|
|
||||||
#include "dplayx_global.h"
|
#include "dplayx_global.h"
|
||||||
#include "name_server.h"
|
#include "name_server.h"
|
||||||
|
@ -43,16 +44,25 @@ struct NSCache
|
||||||
};
|
};
|
||||||
typedef struct NSCache NSCache, *lpNSCache;
|
typedef struct NSCache NSCache, *lpNSCache;
|
||||||
|
|
||||||
|
/* Function prototypes */
|
||||||
|
DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData );
|
||||||
|
|
||||||
/* Name Server functions
|
/* Name Server functions
|
||||||
* ---------------------
|
* ---------------------
|
||||||
*/
|
*/
|
||||||
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd )
|
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd )
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
|
/* FIXME: Remove this method? */
|
||||||
DPLAYX_SetLocalSession( lpsd );
|
DPLAYX_SetLocalSession( lpsd );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPQ_DECL_COMPARECB( cbUglyPig, GUID )
|
||||||
|
{
|
||||||
|
return IsEqualGUID( elem1, elem2 );
|
||||||
|
}
|
||||||
|
|
||||||
/* Store the given NS remote address for future reference */
|
/* Store the given NS remote address for future reference */
|
||||||
void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
|
void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
|
||||||
DWORD dwHdrSize,
|
DWORD dwHdrSize,
|
||||||
|
@ -65,8 +75,21 @@ void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
|
||||||
TRACE( "%p, %p, %p\n", lpNSAddrHdr, lpMsg, lpNSInfo );
|
TRACE( "%p, %p, %p\n", lpNSAddrHdr, lpMsg, lpNSInfo );
|
||||||
|
|
||||||
/* FIXME: Should check to see if the reply is for an existing session. If
|
/* FIXME: Should check to see if the reply is for an existing session. If
|
||||||
* so we just update the contents and update the timestamp.
|
* so we remove the old and add the new so oldest is at front.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* See if we can find this session. If we can, remove it as it's a dup */
|
||||||
|
DPQ_REMOVE_ENTRY_CB( lpCache->first, next, data->guidInstance, cbUglyPig,
|
||||||
|
lpMsg->sd.guidInstance, lpCacheNode );
|
||||||
|
|
||||||
|
if( lpCacheNode != NULL )
|
||||||
|
{
|
||||||
|
TRACE( "Duplicate session entry for %s removed - updated version kept\n",
|
||||||
|
debugstr_guid( &lpCacheNode->data->guidInstance ) );
|
||||||
|
cbDeleteNSNodeFromHeap( lpCacheNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add this to the list */
|
||||||
lpCacheNode = (lpNSCacheData)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
lpCacheNode = (lpNSCacheData)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
sizeof( *lpCacheNode ) );
|
sizeof( *lpCacheNode ) );
|
||||||
|
|
||||||
|
@ -96,7 +119,7 @@ void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
(LPWSTR)(lpMsg+1) );
|
(LPWSTR)(lpMsg+1) );
|
||||||
|
|
||||||
lpCacheNode->dwTime = GetTickCount();
|
lpCacheNode->dwTime = timeGetTime();
|
||||||
|
|
||||||
DPQ_INSERT(lpCache->first, lpCacheNode, next );
|
DPQ_INSERT(lpCache->first, lpCacheNode, next );
|
||||||
|
|
||||||
|
@ -116,6 +139,10 @@ LPVOID NS_GetNSAddr( LPVOID lpNSInfo )
|
||||||
|
|
||||||
/* Ok. Cheat and don't search for the correct stuff just take the first.
|
/* Ok. Cheat and don't search for the correct stuff just take the first.
|
||||||
* FIXME: In the future how are we to know what is _THE_ enum we used?
|
* FIXME: In the future how are we to know what is _THE_ enum we used?
|
||||||
|
* This is going to have to go into dplay somehow. Perhaps it
|
||||||
|
* comes back with app server id for the join command! Oh...that
|
||||||
|
* must be it. That would make this method obsolete once that's
|
||||||
|
* in place.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return lpCache->first.lpQHFirst->lpNSAddrHdr;
|
return lpCache->first.lpQHFirst->lpNSAddrHdr;
|
||||||
|
@ -159,17 +186,17 @@ HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid,
|
||||||
return (lpSpData->lpCB->EnumSessions)( &data );
|
return (lpSpData->lpCB->EnumSessions)( &data );
|
||||||
}
|
}
|
||||||
|
|
||||||
DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData );
|
/* Delete a name server node which has been allocated on the heap */
|
||||||
DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData )
|
DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData )
|
||||||
{
|
{
|
||||||
|
/* NOTE: This proc doesn't deal with the walking pointer */
|
||||||
|
|
||||||
/* FIXME: Memory leak on data (contained ptrs) */
|
/* FIXME: Memory leak on data (contained ptrs) */
|
||||||
HeapFree( GetProcessHeap(), 0, elem->data );
|
HeapFree( GetProcessHeap(), 0, elem->data );
|
||||||
HeapFree( GetProcessHeap(), 0, elem->lpNSAddrHdr );
|
HeapFree( GetProcessHeap(), 0, elem->lpNSAddrHdr );
|
||||||
HeapFree( GetProcessHeap(), 0, elem );
|
HeapFree( GetProcessHeap(), 0, elem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Render all data in a session cache invalid */
|
/* Render all data in a session cache invalid */
|
||||||
void NS_InvalidateSessionCache( LPVOID lpNSInfo )
|
void NS_InvalidateSessionCache( LPVOID lpNSInfo )
|
||||||
{
|
{
|
||||||
|
@ -216,7 +243,6 @@ void NS_DeleteSessionCache( LPVOID lpNSInfo )
|
||||||
/* Reinitialize the present pointer for this cache */
|
/* Reinitialize the present pointer for this cache */
|
||||||
void NS_ResetSessionEnumeration( LPVOID lpNSInfo )
|
void NS_ResetSessionEnumeration( LPVOID lpNSInfo )
|
||||||
{
|
{
|
||||||
|
|
||||||
((lpNSCache)lpNSInfo)->present = ((lpNSCache)lpNSInfo)->first.lpQHFirst;
|
((lpNSCache)lpNSInfo)->present = ((lpNSCache)lpNSInfo)->first.lpQHFirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,33 +270,60 @@ LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo )
|
||||||
/* This method should check to see if there are any sessions which are
|
/* This method should check to see if there are any sessions which are
|
||||||
* older than the criteria. If so, just delete that information.
|
* older than the criteria. If so, just delete that information.
|
||||||
*/
|
*/
|
||||||
|
/* FIXME: This needs to be called by some periodic timer */
|
||||||
void NS_PruneSessionCache( LPVOID lpNSInfo )
|
void NS_PruneSessionCache( LPVOID lpNSInfo )
|
||||||
{
|
{
|
||||||
lpNSCache lpCache = lpNSInfo;
|
lpNSCache lpCache = lpNSInfo;
|
||||||
lpNSCacheData lpCacheEntry;
|
|
||||||
|
|
||||||
DWORD dwPresentTime = GetTickCount();
|
const DWORD dwPresentTime = timeGetTime();
|
||||||
#if defined( HACK_TIMEGETTIME )
|
const DWORD dwPrunePeriod = 60000; /* is 60 secs enough? */
|
||||||
DWORD dwPruneTime = dwPresentTime - 2; /* One iteration with safety */
|
const DWORD dwPruneTime = dwPresentTime - dwPrunePeriod;
|
||||||
#else
|
|
||||||
DWORD dwPruneTime = dwPresentTime - 10000 /* 10 secs? */;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FIXME( ": semi stub\n" );
|
/* This silly little algorithm is based on the fact we keep entries in
|
||||||
|
* the queue in a time based order. It also assumes that it is not possible
|
||||||
/* FIXME: This doesn't handle time roll over correctly */
|
* to wrap around over yourself (which is not unreasonable).
|
||||||
/* FIXME: Session memory leak on delete */
|
* The if statements verify if the first entry in the queue is less
|
||||||
do
|
* than dwPrunePeriod old depending on the "clock" roll over.
|
||||||
|
*/
|
||||||
|
for( ;; )
|
||||||
{
|
{
|
||||||
DPQ_FIND_ENTRY( lpCache->first, next, dwTime, <=, dwPruneTime, lpCacheEntry );
|
lpNSCacheData lpFirstData;
|
||||||
|
|
||||||
|
if( DPQ_IS_EMPTY(lpCache->first) )
|
||||||
|
{
|
||||||
|
/* Nothing to prune */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( dwPruneTime > dwPresentTime ) /* 0 <= dwPresentTime <= dwPrunePeriod */
|
||||||
|
{
|
||||||
|
if( ( DPQ_FIRST(lpCache->first)->dwTime <= dwPresentTime ) ||
|
||||||
|
( DPQ_FIRST(lpCache->first)->dwTime > dwPruneTime )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Less than dwPrunePeriod old - keep */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* dwPrunePeriod <= dwPresentTime <= max dword */
|
||||||
|
{
|
||||||
|
if( ( DPQ_FIRST(lpCache->first)->dwTime <= dwPresentTime ) &&
|
||||||
|
( DPQ_FIRST(lpCache->first)->dwTime > dwPruneTime )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* Less than dwPrunePeriod old - keep */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lpFirstData = DPQ_FIRST(lpCache->first);
|
||||||
|
DPQ_REMOVE( lpCache->first, DPQ_FIRST(lpCache->first), next );
|
||||||
|
cbDeleteNSNodeFromHeap( lpFirstData );
|
||||||
}
|
}
|
||||||
while( lpCacheEntry != NULL );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NAME SERVER Message stuff */
|
||||||
|
|
||||||
/* Message stuff */
|
|
||||||
void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
|
void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
|
||||||
LPDPSP_REPLYDATA lpReplyData,
|
LPDPSP_REPLYDATA lpReplyData,
|
||||||
IDirectPlay2Impl* lpDP )
|
IDirectPlay2Impl* lpDP )
|
||||||
|
@ -318,4 +371,3 @@ void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
|
||||||
lstrcpyW( (LPWSTR)(rmsg+1), string );
|
lstrcpyW( (LPWSTR)(rmsg+1), string );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,12 @@ dplayx_messages.h,
|
||||||
dplayx_messages.c: Messaging interface required for both DirectPlay and
|
dplayx_messages.c: Messaging interface required for both DirectPlay and
|
||||||
DirectPlayLobby.
|
DirectPlayLobby.
|
||||||
|
|
||||||
|
dplaysp.c,
|
||||||
|
dplaysp.h: COM interface between DPLAYX and the service provider dlls. dplaysp.h is
|
||||||
|
something that should be included into any service provider. Basically
|
||||||
|
the COM interface is partially documented but is generally lacking in the
|
||||||
|
finer points.
|
||||||
|
|
||||||
Presently the architectural relationship between this files is a little shakey, but
|
Presently the architectural relationship between this files is a little shakey, but
|
||||||
isn't so sufficiently bad that it needs fixing yet.
|
isn't so sufficiently bad that it needs fixing yet.
|
||||||
|
|
||||||
|
@ -56,7 +62,17 @@ However, now that address separation is a reality, all binary samples provided
|
||||||
in the sdk can be used. I have had success spawning processes and one
|
in the sdk can be used. I have had success spawning processes and one
|
||||||
directx7 example will allow creation of an app and allow another to join it.
|
directx7 example will allow creation of an app and allow another to join it.
|
||||||
Unfortunately, there isn't much for it to be able to do give the state of
|
Unfortunately, there isn't much for it to be able to do give the state of
|
||||||
inter lobby messaging.
|
inter directlobby or directplay messaging.
|
||||||
|
|
||||||
|
Messages which work:
|
||||||
|
|
||||||
|
For session enumeration: DPMSGCMD_ENUMSESSIONSREPLY & DPMSGCMD_ENUMSESSIONSREQUEST
|
||||||
|
have most fields understood, but not all. Everything _seems_
|
||||||
|
to work.
|
||||||
|
|
||||||
|
For playerid requesting: DPMSGCMD_REQUESTNEWPLAYERID & DPMSGCMD_NEWPLAYERIDREPLY
|
||||||
|
barely work. This needs to be completed for sessions to be
|
||||||
|
able to actually start.
|
||||||
|
|
||||||
A small issue will be the fact that DirectX 6.1(ie. DirectPlay4) introduces a layer of functionality
|
A small issue will be the fact that DirectX 6.1(ie. DirectPlay4) introduces a layer of functionality
|
||||||
inside the DP objects which provide guaranteed protocol delivery. This is
|
inside the DP objects which provide guaranteed protocol delivery. This is
|
||||||
|
@ -96,18 +112,21 @@ TODO:
|
||||||
share registry implementation (or at least simplify).
|
share registry implementation (or at least simplify).
|
||||||
- Add in appropriate RegCloseKey calls for all the opening we're doing...
|
- Add in appropriate RegCloseKey calls for all the opening we're doing...
|
||||||
- Fix all the buffer sizes for registry calls. They're off by one - but in a safe direction.
|
- Fix all the buffer sizes for registry calls. They're off by one - but in a safe direction.
|
||||||
- Find out how to call the service provider dlls - they don't have a published interface!
|
- (done) Find out how to call the service provider dlls - they don't have a published interface!
|
||||||
- Fix race condition on interface destruction
|
- Fix race condition on interface destruction
|
||||||
- Handles need to be correctly reference counted
|
- Handles need to be correctly reference counted
|
||||||
- Need to check if we need to deallocate any list objects when destroying
|
- Need to check if we need to deallocate any list objects when destroying
|
||||||
dplay interface
|
dplay interface
|
||||||
- RunApplication process spawning needs to have correct syncronization.
|
- RunApplication process spawning needs to have correct syncronization.
|
||||||
- Need to get inter lobby messages working.
|
- Need to get inter lobby messages working.
|
||||||
|
- Decypher dplay messages between applications and implement...
|
||||||
|
- Need to implement lobby session spawning.
|
||||||
|
|
||||||
ENHANCEMENTS:
|
ENHANCEMENTS:
|
||||||
- Improve footprint and realtime blocking by setting up a seperate data share
|
- Improve footprint and realtime blocking by setting up a seperate data share
|
||||||
between lobby application and client since there can be multiple apps per
|
between lobby application and client since there can be multiple apps per
|
||||||
client.
|
client. Also get rid of offset dependency by making data offset independent
|
||||||
|
somehow.
|
||||||
- Handle everything in UNICODE (as server does) and do conversions for ANSI
|
- Handle everything in UNICODE (as server does) and do conversions for ANSI
|
||||||
interfaces. Should cut down on dplayx code base and maintanability (marginally)
|
interfaces. Should cut down on dplayx code base and maintanability (marginally)
|
||||||
and could be used to improve efficiency of dialog with the server (it wouldn't
|
and could be used to improve efficiency of dialog with the server (it wouldn't
|
||||||
|
@ -124,34 +143,23 @@ Programs to make work:
|
||||||
|
|
||||||
Next API to implement on a per SDK program basis:
|
Next API to implement on a per SDK program basis:
|
||||||
override.exe
|
override.exe
|
||||||
- fixme:dplay:DirectPlayCreate Modem binding not supported yet
|
- (calls dpserial so basic problems with that remain)
|
||||||
- DirectPlay3AImpl_InitializeConnection
|
- after that ?
|
||||||
- DirectPlay2AImpl_Open
|
|
||||||
- ?
|
|
||||||
|
|
||||||
dplaunch.exe
|
dplaunch.exe
|
||||||
- Just needs final process startup messages to be exchanged correctly!
|
- I think that everything is basically working. The launched app may not
|
||||||
|
work on the other hand.
|
||||||
|
|
||||||
lserver.exe
|
lserver.exe
|
||||||
- IDirectPlayLobby2WImpl_Connect
|
- Missing messaging portion. Everything else works.
|
||||||
- fixme:dplay:DirectPlayCreate Modem binding not supported yet
|
|
||||||
- IDirectPlay3WImpl_CreatePlayer
|
|
||||||
- IDirectPlay3WImpl_CreateGroup
|
|
||||||
- IDirectPlay3WImpl_SetGroupData
|
|
||||||
- IDirectPlay3WImpl_Send
|
|
||||||
- ?
|
|
||||||
|
|
||||||
bellhop.exe
|
bellhop.exe
|
||||||
- DP_SendSessionRequestBroadcast (implement the name server stuff)
|
- Need to implement lobby server support.
|
||||||
- ?
|
- ?
|
||||||
|
|
||||||
dpslots.exe
|
dpslots.exe
|
||||||
- IDirectPlayLobby3AImpl_ConnectEx
|
- Works as host except for message stuff
|
||||||
- ?
|
- Missing correct handling of receipt of playerid
|
||||||
|
|
||||||
override.exe
|
|
||||||
- DirectPlayCreate Service provider binding not supported yet
|
|
||||||
- ?
|
|
||||||
|
|
||||||
Other TODO:
|
Other TODO:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue