Commit 4da59ea6 authored by Peter Hunnisett's avatar Peter Hunnisett Committed by Alexandre Julliard

- Make ref counting a little more efficient

- Correct suspended process resumption - Don't use sys/queue.h anymore - Properly initialize the global semaphore across processes - Create a mapped file for shared data structures - Change some trace messages - Allocate dynamic shared data from the mapped file - Rework setting and retrieving lobby settings from shared memory - Add infrastructure for syncronization after app launch - Small documentation update - Include some stuff missing from header - Start on dp and dpl message infrastructure - Unicode versions of player/group commands added - Combined Connect/ConnectEx and Open/SecureOpen - More implementation
parent 961053fd
......@@ -6,11 +6,13 @@ MODULE = dplayx
SOVERSION = 1.0
IMPORTS = ole32
C_SRCS = dplay.c \
dplobby.c \
C_SRCS = \
dpclassfactory.c \
dplayx_main.c \
dplay.c \
dplayx_global.c \
dplayx_main.c \
dplayx_messages.c \
dplobby.c \
name_server.c
@MAKE_DLL_RULES@
......
......@@ -20,13 +20,14 @@
#include "name_server.h"
#include "dplayx_queue.h"
DEFAULT_DEBUG_CHANNEL(dplay)
/* FIXME: This stuff shouldn't really be here. It indicates a poor architectural coupling */
#include "dplobby.h"
extern HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
DEFAULT_DEBUG_CHANNEL(dplay)
/*****************************************************************************
* Predeclare the interface implementation structures
......@@ -79,7 +80,7 @@ typedef struct PlayerData* lpPlayerData;
struct PlayerList
{
TAILQ_ENTRY(PlayerList) players;
DPQ_ENTRY(PlayerList) players;
lpPlayerData lpPData;
};
......@@ -90,8 +91,8 @@ struct GroupData
/* Internal information */
struct GroupData* parent; /* If parent == NULL it's a top level group */
TAILQ_HEAD(,GroupList) groups; /* A group has [0..n] groups */
TAILQ_HEAD(,PlayerList) players; /* A group has [0..n] players */
DPQ_HEAD(GroupList) groups; /* A group has [0..n] groups */
DPQ_HEAD(PlayerList) players; /* A group has [0..n] players */
DPID idGroupOwner; /* ID of player who owns the group */
......@@ -105,7 +106,7 @@ typedef struct GroupData* lpGroupData;
struct GroupList
{
TAILQ_ENTRY(GroupList) groups;
DPQ_ENTRY(GroupList) groups;
lpGroupData lpGData;
};
......@@ -124,8 +125,8 @@ typedef struct tagDirectPlay2Data
BOOL bHostInterface; /* Did this interface create the session */
TAILQ_HEAD( ,PlayerList) players; /* All players w/ interface */
TAILQ_HEAD( ,GroupList) groups; /* All main groups w/ interface */
DPQ_HEAD(PlayerList) players; /* All players w/ interface */
DPQ_HEAD(GroupList) groups; /* All main groups w/ interface */
} DirectPlay2Data;
typedef struct tagDirectPlay3Data
......@@ -173,7 +174,7 @@ static ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
/* Local function prototypes */
static lpPlayerList DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid );
static lpPlayerData DP_CreatePlayer( IDirectPlay2* iface, LPDPID lpid,
static lpPlayerData DP_CreatePlayer( IDirectPlay2Impl* iface, LPDPID lpid,
LPDPNAME lpName, HANDLE hEvent,
BOOL bAnsi );
static BOOL DP_CopyDPNAMEStruct( LPDPNAME lpDst, LPDPNAME lpSrc, BOOL bAnsi );
......@@ -197,6 +198,67 @@ static BOOL cbRemoveGroupOrPlayer( DPID dpId, DWORD dwPlayerType,
LPVOID lpContext );
static void DP_DeleteGroup( IDirectPlay2Impl* This, DPID dpid );
/* Helper methods for player/group interfaces */
static HRESULT WINAPI DP_IF_DeletePlayerFromGroup
( IDirectPlay2Impl* This, DPID idGroup, DPID idPlayer, BOOL bAnsi );
static HRESULT WINAPI DP_IF_CreatePlayer
( IDirectPlay2Impl* This, LPDPID lpidPlayer, LPDPNAME lpPlayerName,
HANDLE hEvent, LPVOID lpData, DWORD dwDataSize,
DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_DestroyGroup
( IDirectPlay2Impl* This, DPID idGroup, BOOL bAnsi );
static HRESULT WINAPI DP_IF_DestroyPlayer
( IDirectPlay2Impl* This, DPID idPlayer, BOOL bAnsi );
static HRESULT WINAPI DP_IF_EnumGroupPlayers
( IDirectPlay2Impl* This, DPID idGroup, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_EnumGroups
( IDirectPlay2Impl* This, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_EnumPlayers
( IDirectPlay2Impl* This, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_GetGroupData
( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_GetGroupName
( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
LPDWORD lpdwDataSize, BOOL bAnsi );
static HRESULT WINAPI DP_IF_GetPlayerData
( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_GetPlayerName
( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
LPDWORD lpdwDataSize, BOOL bAnsi );
static HRESULT WINAPI DP_IF_SetGroupName
( IDirectPlay2Impl* This, DPID idGroup, LPDPNAME lpGroupName,
DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_SetPlayerData
( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_SetPlayerName
( IDirectPlay2Impl* This, DPID idPlayer, LPDPNAME lpPlayerName,
DWORD dwFlags, BOOL bAnsi );
static HRESULT WINAPI DP_IF_AddGroupToGroup
( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup );
static HRESULT WINAPI DP_IF_CreateGroupInGroup
( IDirectPlay3Impl* This, DPID idParentGroup, LPDPID lpidGroup,
LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
DWORD dwFlags );
static HRESULT WINAPI DP_IF_DeleteGroupFromGroup
( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup );
static HRESULT WINAPI DP_SecureOpen
( IDirectPlay2Impl* This, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials );
static DWORD kludgePlayerGroupId = 1000;
......@@ -252,8 +314,8 @@ BOOL DP_CreateDirectPlay2( LPVOID lpDP )
This->dp2->bHostInterface = FALSE;
TAILQ_INIT(&This->dp2->players);
TAILQ_INIT(&This->dp2->groups);
DPQ_INIT(This->dp2->players);
DPQ_INIT(This->dp2->groups);
if( !NS_InitializeSessionCache( &This->dp2->lpNameServerData ) )
{
......@@ -646,11 +708,7 @@ static ULONG WINAPI DirectPlay2AImpl_AddRef
ULONG refCount;
ICOM_THIS(IDirectPlay3Impl,iface);
EnterCriticalSection( &This->unk->DP_lock );
{
refCount = ++(This->unk->ref);
}
LeaveCriticalSection( &This->unk->DP_lock );
refCount = InterlockedIncrement( &This->unk->ref );
TRACE("ref count incremented to %lu for %p\n", refCount, This );
......@@ -664,11 +722,7 @@ static ULONG WINAPI DirectPlay2AImpl_Release
ICOM_THIS(IDirectPlay3Impl,iface);
EnterCriticalSection( &This->unk->DP_lock );
{
refCount = --(This->unk->ref);
}
LeaveCriticalSection( &This->unk->DP_lock );
refCount = InterlockedDecrement( &This->unk->ref );
TRACE("ref count decremented to %lu for %p\n", refCount, This );
......@@ -720,7 +774,7 @@ static HRESULT WINAPI DirectPlay2AImpl_AddPlayerToGroup
lpNewPList->lpPData = lpPList->lpPData;
/* Add the player to the list of players for this group */
TAILQ_INSERT_TAIL(&lpGList->lpGData->players,lpNewPList,players);
DPQ_INSERT(lpGList->lpGData->players,lpNewPList,players);
/* Send a ADDPLAYERTOGROUP message */
FIXME( "Not sending message\n" );
......@@ -782,7 +836,7 @@ lpGroupData DP_CreateGroup( IDirectPlay2AImpl* This, LPDPID lpid,
return NULL;
}
TAILQ_INSERT_TAIL(&This->dp2->groups,lpGroup,groups);
DPQ_INSERT(This->dp2->groups,lpGroup,groups);
if( *lpid == DPID_UNKNOWN )
{
......@@ -810,7 +864,7 @@ DP_DeleteGroup( IDirectPlay2Impl* This, DPID dpid )
TRACE( "(%p)->(0x%08lx)\n", This, dpid );
TAILQ_REMOVE_ENTRY( &This->dp2->groups, groups, lpGData->dpid, dpid, lpGList );
DPQ_REMOVE_ENTRY( This->dp2->groups, groups, lpGData->dpid, dpid, lpGList );
if( lpGList == NULL )
{
......@@ -827,7 +881,6 @@ DP_DeleteGroup( IDirectPlay2Impl* This, DPID dpid )
}
/* This function only finds top level groups */
static lpGroupList DP_FindTopGroup( IDirectPlay2AImpl* This, DPID dpid )
{
......@@ -858,7 +911,7 @@ static lpGroupList DP_FindAnyGroup( IDirectPlay2AImpl* This, DPID dpid )
TRACE( "(%p)->(0x%08lx)\n", This, dpid );
TAILQ_FIND_ENTRY( &This->dp2->groups, groups, lpGData->dpid, dpid, lpGroups );
DPQ_FIND_ENTRY( This->dp2->groups, groups, lpGData->dpid, dpid, lpGroups );
return lpGroups;
}
......@@ -928,10 +981,9 @@ static HRESULT WINAPI DirectPlay2WImpl_CreateGroup
* If *lpid == DPID_UNKNOWN then assign the next available player
*/
static
lpPlayerData DP_CreatePlayer( IDirectPlay2* iface, LPDPID lpid,
lpPlayerData DP_CreatePlayer( IDirectPlay2Impl* This, LPDPID lpid,
LPDPNAME lpName, HANDLE hEvent, BOOL bAnsi )
{
ICOM_THIS(IDirectPlay2Impl,iface);
lpPlayerList lpPlayer;
TRACE( "(%p)->(%p,%p,%u)\n", This, lpid, lpName, bAnsi );
......@@ -956,7 +1008,7 @@ lpPlayerData DP_CreatePlayer( IDirectPlay2* iface, LPDPID lpid,
}
/* Insert the player list into the master list of players */
TAILQ_INSERT_TAIL(&This->dp2->players,lpPlayer,players);
DPQ_INSERT( This->dp2->players, lpPlayer, players );
if( *lpid == DPID_UNKNOWN )
{
......@@ -992,7 +1044,7 @@ DP_DeletePlayer( IDirectPlay2Impl* This, DPID dpid )
TRACE( "(%p)->(0x%08lx)\n", This, dpid );
TAILQ_REMOVE_ENTRY( &This->dp2->players, players, lpPData->dpid, dpid, lpPlayers );
DPQ_REMOVE_ENTRY( This->dp2->players, players, lpPData->dpid, dpid, lpPlayers );
if( lpPlayers == NULL )
{
......@@ -1015,7 +1067,7 @@ static lpPlayerList DP_FindPlayer( IDirectPlay2AImpl* This, DPID dpid )
TRACE( "(%p)->(0x%08lx)\n", This, dpid );
TAILQ_FIND_ENTRY( &This->dp2->players, players, lpPData->dpid, dpid, lpPlayers );
DPQ_FIND_ENTRY( This->dp2->players, players, lpPData->dpid, dpid, lpPlayers );
return lpPlayers;
}
......@@ -1105,19 +1157,21 @@ DP_SetPlayerData( lpPlayerData lpPData, LPVOID lpData, DWORD dwDataSize )
}
static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
( LPDIRECTPLAY2A iface,
static HRESULT WINAPI DP_IF_CreatePlayer
( IDirectPlay2Impl* This,
LPDPID lpidPlayer,
LPDPNAME lpPlayerName,
HANDLE hEvent,
LPVOID lpData,
DWORD dwDataSize,
DWORD dwFlags )
DWORD dwFlags,
BOOL bAnsi )
{
lpPlayerData lpPData;
ICOM_THIS(IDirectPlay2Impl,iface);
TRACE("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx)\n", This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags );
TRACE( "(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx,%u)\n",
This, lpidPlayer, lpPlayerName, hEvent, lpData,
dwDataSize, dwFlags, bAnsi );
if( dwFlags == 0 )
{
......@@ -1144,6 +1198,7 @@ static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
( DP_FindPlayer( This, DPID_SERVERPLAYER ) )
)
{
TRACE( "Denying SERVERPLAYER creation\n" );
return DPERR_CANTCREATEPLAYER;
}
......@@ -1154,8 +1209,8 @@ static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
*lpidPlayer = DPID_UNKNOWN;
}
lpPData = DP_CreatePlayer( iface, lpidPlayer,
lpPlayerName, hEvent, TRUE /*Ansi*/ );
lpPData = DP_CreatePlayer( This, lpidPlayer,
lpPlayerName, hEvent, bAnsi );
if( lpPData == NULL )
{
......@@ -1174,23 +1229,29 @@ static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_CreatePlayer
( LPDIRECTPLAY2A iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_CreatePlayer( This, lpidPlayer, lpPlayerName, hEvent,
lpData, dwDataSize, dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_CreatePlayer
( LPDIRECTPLAY2 iface, LPDPID lpidPlayer, LPDPNAME lpPlayerName, HANDLE hEvent, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(%p,%p,%d,%p,0x%08lx,0x%08lx): stub\n", This, lpidPlayer, lpPlayerName, hEvent, lpData, dwDataSize, dwFlags );
return DP_OK;
return DP_IF_CreatePlayer( This, lpidPlayer, lpPlayerName, hEvent,
lpData, dwDataSize, dwFlags, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_DeletePlayerFromGroup
( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
static HRESULT WINAPI DP_IF_DeletePlayerFromGroup
( IDirectPlay2Impl* This, DPID idGroup, DPID idPlayer, BOOL bAnsi )
{
lpGroupList lpGList;
lpPlayerList lpPList;
ICOM_THIS(IDirectPlay2Impl,iface);
TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, idGroup, idPlayer );
TRACE("(%p)->(0x%08lx,0x%08lx,%u)\n", This, idGroup, idPlayer, bAnsi );
/* Find the group */
if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
......@@ -1205,7 +1266,7 @@ static HRESULT WINAPI DirectPlay2AImpl_DeletePlayerFromGroup
}
/* Remove the player shortcut from the group */
TAILQ_REMOVE_ENTRY( &lpGList->lpGData->players, players, lpPData->dpid, idPlayer, lpPList );
DPQ_REMOVE_ENTRY( lpGList->lpGData->players, players, lpPData->dpid, idPlayer, lpPList );
if( lpPList == NULL )
{
......@@ -1221,17 +1282,24 @@ static HRESULT WINAPI DirectPlay2AImpl_DeletePlayerFromGroup
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_DeletePlayerFromGroup
( LPDIRECTPLAY2A iface, DPID idGroup, DPID idPlayer )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_DeletePlayerFromGroup( This, idGroup, idPlayer, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_DeletePlayerFromGroup
( LPDIRECTPLAY2 iface, DPID idGroup, DPID idPlayer )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idGroup, idPlayer );
return DP_OK;
return DP_IF_DeletePlayerFromGroup( This, idGroup, idPlayer, FALSE );
}
typedef struct _DPRGOPContext
{
LPDIRECTPLAY3 iface;
BOOL bAnsi;
DPID idGroup;
} DPRGOPContext, *lpDPRGOPContext;
......@@ -1273,14 +1341,13 @@ cbRemoveGroupOrPlayer(
return TRUE; /* Continue enumeration */
}
static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
( LPDIRECTPLAY2A iface, DPID idGroup )
static HRESULT WINAPI DP_IF_DestroyGroup
( IDirectPlay2Impl* This, DPID idGroup, BOOL bAnsi )
{
lpGroupList lpGList;
DPRGOPContext context;
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx): semi stub\n", This, idGroup );
FIXME("(%p)->(0x%08lx,%u): semi stub\n", This, idGroup, bAnsi );
/* Find the group */
if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
......@@ -1291,7 +1358,8 @@ static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
/* Yes we're performing a dangerous cast, but it will not be used
unless it's actually a dp3 interface because we will have no
nested groups to delete and we're performing a check below */
context.iface = (LPDIRECTPLAY3A)iface;
context.iface = (LPDIRECTPLAY3)This;
context.bAnsi = bAnsi;
context.idGroup = idGroup;
/* We should only concern ourselves with a group having groups if this is
......@@ -1299,12 +1367,12 @@ static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
if( This->dp3 )
{
/* Remove all links to groups that this group has since this is dp3 */
IDirectPlayX_EnumGroupsInGroup( (LPDIRECTPLAY3A)iface, idGroup, NULL,
IDirectPlayX_EnumGroupsInGroup( (LPDIRECTPLAY3A)This, idGroup, NULL,
cbRemoveGroupOrPlayer, (LPVOID)&context, 0 );
/* FIXME: Is it allowed to delete a sub group with a parent? Must be */
if( lpGList->lpGData->parent )
{
IDirectPlayX_DeleteGroupFromGroup( (LPDIRECTPLAY3A)iface,
IDirectPlayX_DeleteGroupFromGroup( (LPDIRECTPLAY3A)This,
lpGList->lpGData->parent->dpid,
idGroup );
}
......@@ -1312,7 +1380,7 @@ static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
}
/* Remove all players that this group has */
IDirectPlayX_EnumGroupPlayers( iface, idGroup, NULL,
IDirectPlayX_EnumGroupPlayers( (LPDIRECTPLAY3A)This, idGroup, NULL,
cbRemoveGroupOrPlayer, (LPVOID)&context, 0 );
/* Now delete this group data and list */
......@@ -1323,12 +1391,18 @@ static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_DestroyGroup
( LPDIRECTPLAY2A iface, DPID idGroup )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_DestroyGroup( This, idGroup, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_DestroyGroup
( LPDIRECTPLAY2 iface, DPID idGroup )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx): stub\n", This, idGroup );
return DP_OK;
return DP_IF_DestroyGroup( This, idGroup, FALSE );
}
typedef struct _DPFAGContext
......@@ -1337,13 +1411,12 @@ typedef struct _DPFAGContext
DPID idPlayer;
} DPFAGContext, *lpDPFAGContext;
static HRESULT WINAPI DirectPlay2AImpl_DestroyPlayer
( LPDIRECTPLAY2A iface, DPID idPlayer )
static HRESULT WINAPI DP_IF_DestroyPlayer
( IDirectPlay2Impl* This, DPID idPlayer, BOOL bAnsi )
{
DPFAGContext cbContext;
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx): semi stub\n", This, idPlayer );
FIXME("(%p)->(0x%08lx,%u): semi stub\n", This, idPlayer, bAnsi );
if( DP_FindPlayer( This, idPlayer ) )
{
......@@ -1352,12 +1425,12 @@ static HRESULT WINAPI DirectPlay2AImpl_DestroyPlayer
/* FIXME: If the player is remote, we must be the host to delete this */
cbContext.iface = iface;
cbContext.iface = (LPDIRECTPLAY2)This;
cbContext.idPlayer = idPlayer;
/* Find each group and call DeletePlayerFromGroup if the player is a
member of the group */
IDirectPlayX_EnumGroups( iface, NULL, cbDeletePlayerFromAllGroups,
IDirectPlayX_EnumGroups( (LPDIRECTPLAY2)This, NULL, cbDeletePlayerFromAllGroups,
(LPVOID)&cbContext, DPENUMGROUPS_ALL);
/* Now delete player and player list */
......@@ -1396,43 +1469,66 @@ cbDeletePlayerFromAllGroups(
return TRUE;
}
static HRESULT WINAPI DirectPlay2AImpl_DestroyPlayer
( LPDIRECTPLAY2A iface, DPID idPlayer )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_DestroyPlayer( This, idPlayer, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_DestroyPlayer
( LPDIRECTPLAY2 iface, DPID idPlayer )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx): stub\n", This, idPlayer );
return DP_IF_DestroyPlayer( This, idPlayer, FALSE );
}
static HRESULT WINAPI DP_IF_EnumGroupPlayers
( IDirectPlay2Impl* This, DPID idGroup, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi )
{
FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,%u): stub\n",
This, idGroup, lpguidInstance, lpEnumPlayersCallback2,
lpContext, dwFlags, bAnsi );
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_EnumGroupPlayers
( LPDIRECTPLAY2A iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
( LPDIRECTPLAY2A iface, DPID idGroup, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
return DP_OK;
return DP_IF_EnumGroupPlayers( This, idGroup, lpguidInstance,
lpEnumPlayersCallback2, lpContext,
dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_EnumGroupPlayers
( LPDIRECTPLAY2 iface, DPID idGroup, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
( LPDIRECTPLAY2 iface, DPID idGroup, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx): stub\n", This, idGroup, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
return DP_OK;
return DP_IF_EnumGroupPlayers( This, idGroup, lpguidInstance,
lpEnumPlayersCallback2, lpContext,
dwFlags, FALSE );
}
/* NOTE: This only enumerates top level groups (created with CreateGroup) */
static HRESULT WINAPI DirectPlay2AImpl_EnumGroups
( LPDIRECTPLAY2A iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
static HRESULT WINAPI DP_IF_EnumGroups
( IDirectPlay2Impl* This, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi )
{
lpGroupList lpGList;
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(%p,%p,%p,0x%08lx): semi stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
FIXME("(%p)->(%p,%p,%p,0x%08lx,%u): semi stub\n",
This, lpguidInstance, lpEnumPlayersCallback2,
lpContext, dwFlags, bAnsi );
lpGList = This->dp2->groups.tqh_first;
lpGList = This->dp2->groups.lpQHFirst;
while( lpGList )
{
......@@ -1451,7 +1547,7 @@ static HRESULT WINAPI DirectPlay2AImpl_EnumGroups
break; /* User requested break */
}
if( ( lpGList = lpGList->groups.tqe_next ) == This->dp2->groups.tqh_first )
if( ( lpGList = lpGList->groups.lpQNext ) == This->dp2->groups.lpQHFirst )
{
break;
}
......@@ -1460,31 +1556,57 @@ static HRESULT WINAPI DirectPlay2AImpl_EnumGroups
return DP_OK;
}
static HRESULT WINAPI DirectPlay2WImpl_EnumGroups
( LPDIRECTPLAY2 iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
static HRESULT WINAPI DirectPlay2AImpl_EnumGroups
( LPDIRECTPLAY2A iface, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
return DP_OK;
return DP_IF_EnumGroups( This, lpguidInstance, lpEnumPlayersCallback2,
lpContext, dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2AImpl_EnumPlayers
( LPDIRECTPLAY2A iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
static HRESULT WINAPI DirectPlay2WImpl_EnumGroups
( LPDIRECTPLAY2 iface, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_EnumGroups( This, lpguidInstance, lpEnumPlayersCallback2,
lpContext, dwFlags, FALSE );
}
static HRESULT WINAPI DP_IF_EnumPlayers
( IDirectPlay2Impl* This, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags, BOOL bAnsi )
{
FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
FIXME("(%p)->(%p,%p,%p,0x%08lx,%u): stub\n",
This, lpguidInstance, lpEnumPlayersCallback2,
lpContext, dwFlags, bAnsi );
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_EnumPlayers
( LPDIRECTPLAY2A iface, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_EnumPlayers( This, lpguidInstance, lpEnumPlayersCallback2,
lpContext, dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_EnumPlayers
( LPDIRECTPLAY2 iface, LPGUID lpguidInstance, LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2, LPVOID lpContext, DWORD dwFlags )
( LPDIRECTPLAY2 iface, LPGUID lpguidInstance,
LPDPENUMPLAYERSCALLBACK2 lpEnumPlayersCallback2,
LPVOID lpContext, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n",
This, lpguidInstance, lpEnumPlayersCallback2, lpContext, dwFlags );
return DP_OK;
return DP_IF_EnumPlayers( This, lpguidInstance, lpEnumPlayersCallback2,
lpContext, dwFlags, FALSE );
}
/* This function should call the registered callback function that the user
......@@ -1654,14 +1776,14 @@ static HRESULT WINAPI DirectPlay2WImpl_GetCaps
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_GetGroupData
( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
static HRESULT WINAPI DP_IF_GetGroupData
( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi )
{
lpGroupList lpGList;
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): dwFlags ignored\n", This, idGroup, lpData, lpdwDataSize, dwFlags );
FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx,%u): dwFlags ignored\n",
This, idGroup, lpData, lpdwDataSize, dwFlags, bAnsi );
if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
{
......@@ -1682,24 +1804,34 @@ static HRESULT WINAPI DirectPlay2AImpl_GetGroupData
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_GetGroupData
( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData,
LPDWORD lpdwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_GetGroupData( This, idGroup, lpData, lpdwDataSize,
dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_GetGroupData
( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData,
LPDWORD lpdwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idGroup, lpData, lpdwDataSize, dwFlags );
return DP_OK;
return DP_IF_GetGroupData( This, idGroup, lpData, lpdwDataSize,
dwFlags, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_GetGroupName
( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
static HRESULT WINAPI DP_IF_GetGroupName
( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
LPDWORD lpdwDataSize, BOOL bAnsi )
{
lpGroupList lpGList;
LPDPNAME lpName = (LPDPNAME)lpData;
DWORD dwRequiredDataSize;
ICOM_THIS(IDirectPlay2Impl,iface);
TRACE("(%p)->(0x%08lx,%p,%p)\n", This, idGroup, lpData, lpdwDataSize );
FIXME("(%p)->(0x%08lx,%p,%p,%u) ANSI ignored\n",
This, idGroup, lpData, lpdwDataSize, bAnsi );
if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
{
......@@ -1752,12 +1884,20 @@ static HRESULT WINAPI DirectPlay2AImpl_GetGroupName
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_GetGroupName
( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_GetGroupName( This, idGroup, lpData, lpdwDataSize, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_GetGroupName
( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, LPDWORD lpdwDataSize )
( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idGroup, lpData, lpdwDataSize );
return DP_OK;
return DP_IF_GetGroupName( This, idGroup, lpData, lpdwDataSize, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_GetMessageCount
......@@ -1808,14 +1948,14 @@ static HRESULT WINAPI DirectPlay2WImpl_GetPlayerCaps
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_GetPlayerData
( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
static HRESULT WINAPI DP_IF_GetPlayerData
( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
LPDWORD lpdwDataSize, DWORD dwFlags, BOOL bAnsi )
{
lpPlayerList lpPList;
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idPlayer, lpData, lpdwDataSize, dwFlags );
FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx,%u): stub\n",
This, idPlayer, lpData, lpdwDataSize, dwFlags, bAnsi );
if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
{
......@@ -1836,24 +1976,34 @@ static HRESULT WINAPI DirectPlay2AImpl_GetPlayerData
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_GetPlayerData
( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData,
LPDWORD lpdwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_GetPlayerData( This, idPlayer, lpData, lpdwDataSize,
dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_GetPlayerData
( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize, DWORD dwFlags )
( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData,
LPDWORD lpdwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, idPlayer, lpData, lpdwDataSize, dwFlags );
return DP_OK;
return DP_IF_GetPlayerData( This, idPlayer, lpData, lpdwDataSize,
dwFlags, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_GetPlayerName
( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
static HRESULT WINAPI DP_IF_GetPlayerName
( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
LPDWORD lpdwDataSize, BOOL bAnsi )
{
lpPlayerList lpPList;
LPDPNAME lpName = (LPDPNAME)lpData;
DWORD dwRequiredDataSize;
ICOM_THIS(IDirectPlay2Impl,iface);
TRACE("(%p)->(0x%08lx,%p,%p)\n", This, idPlayer, lpData, lpdwDataSize );
FIXME( "(%p)->(0x%08lx,%p,%p,%u): ANSI \n",
This, idPlayer, lpData, lpdwDataSize, bAnsi );
if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
{
......@@ -1906,12 +2056,20 @@ static HRESULT WINAPI DirectPlay2AImpl_GetPlayerName
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_GetPlayerName
( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_GetPlayerName( This, idPlayer, lpData, lpdwDataSize, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_GetPlayerName
( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, LPDWORD lpdwDataSize )
( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, idPlayer, lpData, lpdwDataSize );
return DP_OK;
return DP_IF_GetPlayerName( This, idPlayer, lpData, lpdwDataSize, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_GetSessionDesc
......@@ -1949,12 +2107,12 @@ static HRESULT WINAPI DirectPlay2WImpl_Initialize
}
static HRESULT WINAPI DirectPlay2AImpl_Open
( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
static HRESULT WINAPI DP_SecureOpen
( IDirectPlay2Impl* This, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpsd, dwFlags );
FIXME( "(%p)->(%p,0x%08lx,%p,%p): semi stub\n",
This, lpsd, dwFlags, lpSecurity, lpCredentials );
if( This->dp2->bConnectionOpen )
{
......@@ -1963,7 +2121,9 @@ static HRESULT WINAPI DirectPlay2AImpl_Open
}
/* When we open we need to stop any EnumSession activity */
IDirectPlayX_EnumSessions( iface, NULL, 0, NULL, NULL, DPENUMSESSIONS_STOPASYNC );
/* FIXME: Perhaps some sort of internal interface would be better */
IDirectPlayX_EnumSessions( (LPDIRECTPLAY2A)This, NULL, 0, NULL, NULL,
DPENUMSESSIONS_STOPASYNC );
if( dwFlags & DPOPEN_CREATE )
{
......@@ -1984,12 +2144,20 @@ static HRESULT WINAPI DirectPlay2AImpl_Open
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_Open
( LPDIRECTPLAY2A iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
TRACE("(%p)->(%p,0x%08lx)\n", This, lpsd, dwFlags );
return DP_SecureOpen( This, lpsd, dwFlags, NULL, NULL );
}
static HRESULT WINAPI DirectPlay2WImpl_Open
( LPDIRECTPLAY2 iface, LPDPSESSIONDESC2 lpsd, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpsd, dwFlags );
return DP_OK;
TRACE("(%p)->(%p,0x%08lx)\n", This, lpsd, dwFlags );
return DP_SecureOpen( This, lpsd, dwFlags, NULL, NULL );
}
static HRESULT WINAPI DirectPlay2AImpl_Receive
......@@ -2024,13 +2192,14 @@ static HRESULT WINAPI DirectPlay2WImpl_Send
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_SetGroupData
( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
static HRESULT WINAPI DP_IF_SetGroupData
( IDirectPlay2Impl* This, DPID idGroup, LPVOID lpData,
DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi )
{
lpGroupList lpGList;
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): dwFlags ignored\n", This, idGroup, lpData, dwDataSize, dwFlags );
FIXME( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx,%u): dwFlags ignored\n",
This, idGroup, lpData, dwDataSize, dwFlags, bAnsi );
/* Parameter check */
if( ( lpData == NULL ) &&
......@@ -2051,29 +2220,37 @@ static HRESULT WINAPI DirectPlay2AImpl_SetGroupData
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_SetGroupData
( LPDIRECTPLAY2A iface, DPID idGroup, LPVOID lpData,
DWORD dwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_SetGroupData( This, idGroup, lpData, dwDataSize, dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_SetGroupData
( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
( LPDIRECTPLAY2 iface, DPID idGroup, LPVOID lpData,
DWORD dwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idGroup, lpData, dwDataSize, dwFlags );
return DP_OK;
return DP_IF_SetGroupData( This, idGroup, lpData, dwDataSize, dwFlags, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_SetGroupName
( LPDIRECTPLAY2A iface, DPID idGroup, LPDPNAME lpGroupName, DWORD dwFlags )
static HRESULT WINAPI DP_IF_SetGroupName
( IDirectPlay2Impl* This, DPID idGroup, LPDPNAME lpGroupName,
DWORD dwFlags, BOOL bAnsi )
{
lpGroupList lpGList;
ICOM_THIS(IDirectPlay2Impl,iface);
TRACE("(%p)->(0x%08lx,%p,0x%08lx)\n", This, idGroup, lpGroupName, dwFlags );
TRACE( "(%p)->(0x%08lx,%p,0x%08lx,%u)\n", This, idGroup,
lpGroupName, dwFlags, bAnsi );
if( ( lpGList = DP_FindAnyGroup( This, idGroup ) ) == NULL )
{
return DPERR_INVALIDGROUP;
}
DP_CopyDPNAMEStruct( &lpGList->lpGData->name, lpGroupName, TRUE );
DP_CopyDPNAMEStruct( &lpGList->lpGData->name, lpGroupName, bAnsi );
/* Should send a DPMSG_SETPLAYERORGROUPNAME message */
FIXME( "Message not sent and dwFlags ignored\n" );
......@@ -2081,21 +2258,30 @@ static HRESULT WINAPI DirectPlay2AImpl_SetGroupName
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_SetGroupName
( LPDIRECTPLAY2A iface, DPID idGroup, LPDPNAME lpGroupName,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_SetGroupName( This, idGroup, lpGroupName, dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_SetGroupName
( LPDIRECTPLAY2 iface, DPID idGroup, LPDPNAME lpGroupName, DWORD dwFlags )
( LPDIRECTPLAY2 iface, DPID idGroup, LPDPNAME lpGroupName,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idGroup, lpGroupName, dwFlags );
return DP_OK;
return DP_IF_SetGroupName( This, idGroup, lpGroupName, dwFlags, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_SetPlayerData
( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
static HRESULT WINAPI DP_IF_SetPlayerData
( IDirectPlay2Impl* This, DPID idPlayer, LPVOID lpData,
DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi )
{
lpPlayerList lpPList;
ICOM_THIS(IDirectPlay2AImpl,iface);
TRACE("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n", This, idPlayer, lpData, dwDataSize, dwFlags );
TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx,%u)\n",
This, idPlayer, lpData, dwDataSize, dwFlags, bAnsi );
/* Parameter check */
if( ( lpData == NULL ) &&
......@@ -2121,29 +2307,39 @@ static HRESULT WINAPI DirectPlay2AImpl_SetPlayerData
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_SetPlayerData
( LPDIRECTPLAY2A iface, DPID idPlayer, LPVOID lpData,
DWORD dwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_SetPlayerData( This, idPlayer, lpData, dwDataSize,
dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_SetPlayerData
( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
( LPDIRECTPLAY2 iface, DPID idPlayer, LPVOID lpData,
DWORD dwDataSize, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n", This, idPlayer, lpData, dwDataSize, dwFlags );
return DP_OK;
return DP_IF_SetPlayerData( This, idPlayer, lpData, dwDataSize,
dwFlags, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_SetPlayerName
( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPNAME lpPlayerName, DWORD dwFlags )
static HRESULT WINAPI DP_IF_SetPlayerName
( IDirectPlay2Impl* This, DPID idPlayer, LPDPNAME lpPlayerName,
DWORD dwFlags, BOOL bAnsi )
{
lpPlayerList lpPList;
ICOM_THIS(IDirectPlay2AImpl,iface);
TRACE("(%p)->(0x%08lx,%p,0x%08lx)\n", This, idPlayer, lpPlayerName, dwFlags );
TRACE( "(%p)->(0x%08lx,%p,0x%08lx,%u)\n",
This, idPlayer, lpPlayerName, dwFlags, bAnsi );
if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
{
return DPERR_INVALIDGROUP;
}
DP_CopyDPNAMEStruct( &lpPList->lpPData->name, lpPlayerName, TRUE );
DP_CopyDPNAMEStruct( &lpPList->lpPData->name, lpPlayerName, bAnsi );
/* Should send a DPMSG_SETPLAYERORGROUPNAME message */
FIXME( "Message not sent and dwFlags ignored\n" );
......@@ -2151,12 +2347,20 @@ static HRESULT WINAPI DirectPlay2AImpl_SetPlayerName
return DP_OK;
}
static HRESULT WINAPI DirectPlay2AImpl_SetPlayerName
( LPDIRECTPLAY2A iface, DPID idPlayer, LPDPNAME lpPlayerName,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
return DP_IF_SetPlayerName( This, idPlayer, lpPlayerName, dwFlags, TRUE );
}
static HRESULT WINAPI DirectPlay2WImpl_SetPlayerName
( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPNAME lpPlayerName, DWORD dwFlags )
( LPDIRECTPLAY2 iface, DPID idPlayer, LPDPNAME lpPlayerName,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlay2Impl,iface);
FIXME("(%p)->(0x%08lx,%p,0x%08lx): stub\n", This, idPlayer, lpPlayerName, dwFlags );
return DP_OK;
return DP_IF_SetPlayerName( This, idPlayer, lpPlayerName, dwFlags, FALSE );
}
static HRESULT WINAPI DirectPlay2AImpl_SetSessionDesc
......@@ -2175,16 +2379,14 @@ static HRESULT WINAPI DirectPlay2WImpl_SetSessionDesc
return DP_OK;
}
static HRESULT WINAPI DirectPlay3AImpl_AddGroupToGroup
( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
static HRESULT WINAPI DP_IF_AddGroupToGroup
( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup )
{
lpGroupList lpGParentList;
lpGroupList lpGList;
lpGroupList lpNewGList;
ICOM_THIS(IDirectPlay3AImpl,iface);
TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, idParentGroup, idGroup );
TRACE( "(%p)->(0x%08lx,0x%08lx)\n", This, idParentGroup, idGroup );
if( ( lpGParentList = DP_FindAnyGroup( (IDirectPlay2AImpl*)This, idParentGroup ) ) == NULL )
{
......@@ -2208,7 +2410,7 @@ static HRESULT WINAPI DirectPlay3AImpl_AddGroupToGroup
lpNewGList->lpGData = lpGList->lpGData;
/* Add the player to the list of players for this group */
TAILQ_INSERT_TAIL(&lpGList->lpGData->groups,lpNewGList,groups);
DPQ_INSERT( lpGList->lpGData->groups, lpNewGList, groups );
/* Send a ADDGROUPTOGROUP message */
FIXME( "Not sending message\n" );
......@@ -2216,24 +2418,32 @@ static HRESULT WINAPI DirectPlay3AImpl_AddGroupToGroup
return DP_OK;
}
static HRESULT WINAPI DirectPlay3AImpl_AddGroupToGroup
( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
{
ICOM_THIS(IDirectPlay3Impl,iface);
return DP_IF_AddGroupToGroup( This, idParentGroup, idGroup );
}
static HRESULT WINAPI DirectPlay3WImpl_AddGroupToGroup
( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
{
ICOM_THIS(IDirectPlay3Impl,iface);
FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
return DP_OK;
return DP_IF_AddGroupToGroup( This, idParentGroup, idGroup );
}
static HRESULT WINAPI DirectPlay3AImpl_CreateGroupInGroup
( LPDIRECTPLAY3A iface, DPID idParentGroup, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
static HRESULT WINAPI DP_IF_CreateGroupInGroup
( IDirectPlay3Impl* This, DPID idParentGroup, LPDPID lpidGroup,
LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
DWORD dwFlags )
{
lpGroupList lpGParentList;
lpGroupList lpGList;
lpGroupData lpGData;
ICOM_THIS(IDirectPlay3AImpl,iface);
TRACE("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx)\n", This, idParentGroup, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
TRACE( "(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx)\n",
This, idParentGroup, lpidGroup, lpGroupName, lpData,
dwDataSize, dwFlags );
/* Verify that the specified parent is valid */
if( ( lpGParentList = DP_FindAnyGroup( (IDirectPlay2AImpl*)This,
......@@ -2265,7 +2475,7 @@ static HRESULT WINAPI DirectPlay3AImpl_CreateGroupInGroup
lpGList->lpGData = lpGData;
TAILQ_INSERT_TAIL(&lpGParentList->lpGData->groups,lpGList,groups);
DPQ_INSERT( lpGParentList->lpGData->groups, lpGList, groups );
/* FIXME: Should send DPMSG_CREATEPLAYERORGROUP message to everyone,
......@@ -2274,25 +2484,33 @@ static HRESULT WINAPI DirectPlay3AImpl_CreateGroupInGroup
FIXME( "Should broadcast group creation to everything in session\n" );
return DP_OK;
}
return DP_OK;
static HRESULT WINAPI DirectPlay3AImpl_CreateGroupInGroup
( LPDIRECTPLAY3A iface, DPID idParentGroup, LPDPID lpidGroup,
LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlay3Impl,iface);
return DP_IF_CreateGroupInGroup( This, idParentGroup, lpidGroup, lpGroupName,
lpData, dwDataSize, dwFlags );
}
static HRESULT WINAPI DirectPlay3WImpl_CreateGroupInGroup
( LPDIRECTPLAY3 iface, DPID idParentGroup, LPDPID lpidGroup, LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize, DWORD dwFlags )
( LPDIRECTPLAY3 iface, DPID idParentGroup, LPDPID lpidGroup,
LPDPNAME lpGroupName, LPVOID lpData, DWORD dwDataSize,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlay3Impl,iface);
FIXME("(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx): stub\n", This, idParentGroup, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags );
return DP_OK;
return DP_IF_CreateGroupInGroup( This, idParentGroup, lpidGroup, lpGroupName,
lpData, dwDataSize, dwFlags );
}
static HRESULT WINAPI DirectPlay3AImpl_DeleteGroupFromGroup
( LPDIRECTPLAY3A iface, DPID idParentGroup, DPID idGroup )
static HRESULT WINAPI DP_IF_DeleteGroupFromGroup
( IDirectPlay3Impl* This, DPID idParentGroup, DPID idGroup )
{
lpGroupList lpGList;
lpGroupList lpGParentList;
ICOM_THIS(IDirectPlay3AImpl,iface);
TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, idParentGroup, idGroup );
......@@ -2303,7 +2521,7 @@ static HRESULT WINAPI DirectPlay3AImpl_DeleteGroupFromGroup
}
/* Remove the group from the parent group queue */
TAILQ_REMOVE_ENTRY( &lpGParentList->lpGData->groups, groups, lpGData->dpid, idGroup, lpGList );
DPQ_REMOVE_ENTRY( lpGParentList->lpGData->groups, groups, lpGData->dpid, idGroup, lpGList );
if( lpGList == NULL )
{
......@@ -2319,12 +2537,18 @@ static HRESULT WINAPI DirectPlay3AImpl_DeleteGroupFromGroup
return DP_OK;
}
static HRESULT WINAPI DirectPlay3AImpl_DeleteGroupFromGroup
( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
{
ICOM_THIS(IDirectPlay3Impl,iface);
return DP_IF_DeleteGroupFromGroup( This, idParentGroup, idGroup );
}
static HRESULT WINAPI DirectPlay3WImpl_DeleteGroupFromGroup
( LPDIRECTPLAY3 iface, DPID idParentGroup, DPID idGroup )
{
ICOM_THIS(IDirectPlay3Impl,iface);
FIXME("(%p)->(0x%08lx,0x%08lx): stub\n", This, idParentGroup, idGroup );
return DP_OK;
return DP_IF_DeleteGroupFromGroup( This, idParentGroup, idGroup );
}
static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
......@@ -2590,7 +2814,7 @@ static HRESULT WINAPI DirectPlay3AImpl_EnumGroupsInGroup
return DPERR_INVALIDGROUP;
}
lpGiGList = lpGList->lpGData->groups.tqh_first;
lpGiGList = lpGList->lpGData->groups.lpQHFirst;
while( lpGiGList )
{
......@@ -2603,7 +2827,7 @@ static HRESULT WINAPI DirectPlay3AImpl_EnumGroupsInGroup
return DP_OK; /* User requested break */
}
if( ( lpGiGList = lpGiGList->groups.tqe_next ) == lpGList->lpGData->groups.tqh_first )
if( ( lpGiGList = lpGiGList->groups.lpQNext ) == lpGList->lpGData->groups.lpQHFirst )
{
return DP_OK; /* End of groups */
}
......@@ -2701,47 +2925,19 @@ static HRESULT WINAPI DirectPlay3WImpl_InitializeConnection
}
static HRESULT WINAPI DirectPlay3AImpl_SecureOpen
( LPDIRECTPLAY3A iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags, LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
( LPDIRECTPLAY3A iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
{
ICOM_THIS(IDirectPlay3Impl,iface);
FIXME("(%p)->(%p,0x%08lx,%p,%p): stub\n", This, lpsd, dwFlags, lpSecurity, lpCredentials );
if( This->dp2->bConnectionOpen )
{
TRACE( ": rejecting already open connection.\n" );
return DPERR_ALREADYINITIALIZED;
}
/* When we open we need to stop any EnumSession activity */
IDirectPlayX_EnumSessions( iface, NULL, 0, NULL, NULL, DPENUMSESSIONS_STOPASYNC );
if( dwFlags & DPOPEN_CREATE )
{
dwFlags &= ~DPOPEN_CREATE;
/* Rightoo - this computer is the host and the local computer needs to be
the name server so that others can join this session */
NS_SetLocalComputerAsNameServer( lpsd );
This->dp2->bHostInterface = TRUE;
}
if( dwFlags )
{
ERR( ": ignored dwFlags 0x%08lx\n", dwFlags );
}
return DP_OK;
ICOM_THIS(IDirectPlay2Impl,iface); /* Yes a dp 2 interface */
return DP_SecureOpen( This, lpsd, dwFlags, lpSecurity, lpCredentials );
}
static HRESULT WINAPI DirectPlay3WImpl_SecureOpen
( LPDIRECTPLAY3 iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags, LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
( LPDIRECTPLAY3 iface, LPCDPSESSIONDESC2 lpsd, DWORD dwFlags,
LPCDPSECURITYDESC lpSecurity, LPCDPCREDENTIALS lpCredentials )
{
ICOM_THIS(IDirectPlay3Impl,iface);
FIXME("(%p)->(%p,0x%08lx,%p,%p): stub\n", This, lpsd, dwFlags, lpSecurity, lpCredentials );
return DP_OK;
ICOM_THIS(IDirectPlay2Impl,iface); /* Yes a dp 2 interface */
return DP_SecureOpen( This, lpsd, dwFlags, lpSecurity, lpCredentials );
}
static HRESULT WINAPI DirectPlay3AImpl_SendChatMessage
......
......@@ -14,54 +14,167 @@
#include "debugtools.h"
#include "winbase.h"
#include "winerror.h"
#include "heap.h" /* Really shouldn't be using those HEAP_strdupA interfaces should I? */
#include "dplayx_global.h"
#include "dplayx_messages.h" /* For CreateMessageReceptionThread only */
DEFAULT_DEBUG_CHANNEL(dplay);
/* FIXME: Need to do all that fun other dll referencing type of stuff */
/* FIXME: Need to allocate a giant static area */
/* Static data for all processes */
static LPSTR lpszDplayxSemaName = "WINE_DPLAYX_SM";
static LPCSTR lpszDplayxSemaName = "WINE_DPLAYX_SM";
static HANDLE hDplayxSema;
static LPCSTR lpszDplayxFileMapping = "WINE_DPLAYX_FM";
static HANDLE hDplayxSharedMem;
static LPVOID lpSharedStaticData = NULL;
#define DPLAYX_AquireSemaphore() TRACE( "Waiting for DPLAYX semaphore\n" ); \
WaitForSingleObject( hDplayxSema, INFINITE );\
TRACE( "Through wait\n" )
#define DPLAYX_AquireSemaphore() TRACE( "Waiting for DPLAYX sema\n" ); \
WaitForSingleObject( hDplayxSema, INFINITE ); TRACE( "Through wait\n" )
#define DPLAYX_ReleaseSemaphore() ReleaseSemaphore( hDplayxSema, 1, NULL ); \
TRACE( "DPLAYX Sema released\n" ); /* FIXME: Is this correct? */
TRACE( "DPLAYX Semaphore released\n" ) /* FIXME: Is this correct? */
/* HACK for simple global data right now */
#define dwStaticSharedSize (128 * 1024) /* FIXME: Way too much */
#define dwDynamicSharedSize (128 * 1024) /* FIXME: Enough? */
#define dwTotalSharedSize (dwStaticSharedSize + dwDynamicSharedSize)
/* FIXME: Is there no easier way? */
/* Pretend the entire dynamic area is carved up into 512 byte blocks.
* Each block has 4 bytes which are 0 unless used */
#define dwBlockSize 512
#define dwMaxBlock (dwDynamicSharedSize/dwBlockSize)
DWORD dwBlockOn = 0;
typedef struct
{
DWORD used;
DWORD data[dwBlockSize-sizeof(DWORD)];
} DPLAYX_MEM_SLICE;
DPLAYX_MEM_SLICE* lpMemArea;
void DPLAYX_PrivHeapFree( LPVOID addr );
void DPLAYX_PrivHeapFree( LPVOID addr )
{
LPVOID lpAddrStart;
DWORD dwBlockUsed;
/* Handle getting passed a NULL */
if( addr == NULL )
{
return;
}
lpAddrStart = addr - sizeof(DWORD); /* Find block header */
dwBlockUsed = ((BYTE*)lpAddrStart - (BYTE*)lpMemArea)/dwBlockSize;
lpMemArea[ dwBlockUsed ].used = 0;
}
LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size );
LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size )
{
LPVOID lpvArea = NULL;
UINT uBlockUsed;
if( size > (dwBlockSize - sizeof(DWORD)) )
{
FIXME( "Size exceeded. Request of 0x%08lx\n", size );
size = dwBlockSize - sizeof(DWORD);
}
/* Find blank area */
uBlockUsed = 0;
while( ( lpMemArea[ uBlockUsed ].used != 0 ) && ( uBlockUsed <= dwMaxBlock ) ) { uBlockUsed++; }
if( uBlockUsed <= dwMaxBlock )
{
/* Set the area used */
lpMemArea[ uBlockUsed ].used = 1;
lpvArea = &(lpMemArea[ uBlockUsed ].data);
}
else
{
ERR( "No free block found\n" );
return NULL;
}
if( flags & HEAP_ZERO_MEMORY )
{
ZeroMemory( lpvArea, size );
}
return lpvArea;
}
LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str );
LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str )
{
LPSTR p = DPLAYX_PrivHeapAlloc( flags, strlen(str) + 1 );
if(p) {
strcpy( p, str );
}
return p;
}
LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str );
LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str )
{
INT len = lstrlenW(str) + 1;
LPWSTR p = DPLAYX_PrivHeapAlloc( flags, len * sizeof(WCHAR) );
if(p) {
lstrcpyW( p, str );
}
return p;
}
enum { numSupportedLobbies = 32, numSupportedSessions = 32 };
typedef struct tagDirectPlayLobbyData
typedef struct tagDPLAYX_LOBBYDATA
{
/* Just a DPLCONNECTION struct */
DWORD dwConnFlags;
DPSESSIONDESC2 sessionDesc;
DPNAME playerName;
GUID guidSP;
LPVOID lpAddress;
DWORD dwAddressSize;
/* Points to lpConn + block of contiguous extra memory for dynamic parts
* of the struct directly following
*/
LPDPLCONNECTION lpConn;
/* Information for dplobby interfaces */
DWORD dwAppID;
HANDLE hReceiveEvent;
DWORD dwAppLaunchedFromID;
} DirectPlayLobbyData, *lpDirectPlayLobbyData;
/* Should this lobby app send messages to creator at important life
* stages
*/
BOOL bInformOnConnect; /* FIXME: Not used yet */
BOOL bInformOnSettingRead;
BOOL bInformOnAppDeath; /* FIXME: Not used yet */
BOOL bWaitForConnectionSettings;
static DirectPlayLobbyData lobbyData[ numSupportedLobbies ];
} DPLAYX_LOBBYDATA, *LPDPLAYX_LOBBYDATA;
/* Hack for now */
static DPSESSIONDESC2 sessionData[ numSupportedSessions ];
static DPLAYX_LOBBYDATA* lobbyData = NULL;
/* static DPLAYX_LOBBYDATA lobbyData[ numSupportedLobbies ]; */
static DPSESSIONDESC2* sessionData = NULL;
/* static DPSESSIONDESC2* sessionData[ numSupportedSessions ]; */
/* Function prototypes */
BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, lpDirectPlayLobbyData* dplData );
void DPLAYX_InitializeLobbyDataEntry( lpDirectPlayLobbyData lpData );
DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpDplData );
DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpDplData );
void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src );
void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src );
BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, LPDPLAYX_LOBBYDATA* dplData );
void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData );
BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
LPCDPSESSIONDESC2 lpSessionSrc );
......@@ -71,22 +184,108 @@ BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
* Called to initialize the global data. This will only be used on the
* loading of the dll
***************************************************************************/
void DPLAYX_ConstructData(void)
BOOL DPLAYX_ConstructData(void)
{
UINT i;
SECURITY_ATTRIBUTES s_attrib;
BOOL bInitializeSharedMemory = FALSE;
LPVOID lpDesiredMemoryMapStart = (LPVOID)0x50000000;
TRACE( "DPLAYX dll loaded - construct called\n" );
/* Create a semahopre to block access to DPLAYX global data structs
It starts unblocked, and allows up to 65000 users blocked on it. Seems reasonable
for the time being */
hDplayxSema = CreateSemaphoreA( NULL, 1, 65000, lpszDplayxSemaName );
/* Create a semaphore to block access to DPLAYX global data structs */
s_attrib.bInheritHandle = TRUE;
s_attrib.lpSecurityDescriptor = NULL;
s_attrib.nLength = sizeof(s_attrib);
if( !hDplayxSema )
hDplayxSema = CreateSemaphoreA( &s_attrib, 1, 1, lpszDplayxSemaName );
/* First instance creates the semaphore. Others just use it */
if( GetLastError() == ERROR_SUCCESS )
{
/* Really don't have any choice but to continue... */
ERR( "Semaphore creation error 0x%08lx\n", GetLastError() );
TRACE( "Semaphore %u created\n", hDplayxSema );
/* The semaphore creator will also build the shared memory */
bInitializeSharedMemory = TRUE;
}
else if ( GetLastError() == ERROR_ALREADY_EXISTS )
{
TRACE( "Found semaphore handle %u\n", hDplayxSema );
}
else
{
ERR( ": semaphore error 0x%08lx\n", GetLastError() );
return FALSE;
}
SetLastError( ERROR_SUCCESS );
DPLAYX_AquireSemaphore();
hDplayxSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE,
&s_attrib,
PAGE_READWRITE | SEC_COMMIT,
0,
dwTotalSharedSize,
lpszDplayxFileMapping );
if( GetLastError() == ERROR_SUCCESS )
{
TRACE( "File mapped %u created\n", hDplayxSharedMem );
}
else if ( GetLastError() == ERROR_ALREADY_EXISTS )
{
TRACE( "Found FileMapping handle %u\n", hDplayxSharedMem );
}
else
{
ERR( ": unable to create shared memory 0x%08lx\n", GetLastError() );
return FALSE;
}
lpSharedStaticData = MapViewOfFileEx( hDplayxSharedMem,
FILE_MAP_WRITE,
0, 0, 0, lpDesiredMemoryMapStart );
if( lpSharedStaticData == NULL )
{
ERR( ": unable to map static data into process memory space: 0x%08lx\n",
GetLastError() );
return FALSE;
}
else
{
if( lpDesiredMemoryMapStart == lpSharedStaticData )
{
TRACE( "File mapped to %p\n", lpSharedStaticData );
}
else
{
/* Presently the shared data structures use pointers. If the
* files are no mapped into the same area, the pointers will no
* longer make any sense :(
* FIXME: In the future make the shared data structures have some
* sort of fixup to make them independent between data spaces.
* This will also require a rework of the session data stuff.
*/
ERR( "File mapped to %p (not %p). Expect failure\n",
lpSharedStaticData, lpDesiredMemoryMapStart );
}
}
/* Dynamic area starts just after the static area */
lpMemArea = (LPVOID)((BYTE*)lpSharedStaticData + dwStaticSharedSize);
/* FIXME: Crude hack */
lobbyData = (DPLAYX_LOBBYDATA*)lpSharedStaticData;
sessionData = (DPSESSIONDESC2*)((BYTE*)lpSharedStaticData + (dwStaticSharedSize/2));
/* Initialize shared data segments. */
if( bInitializeSharedMemory )
{
UINT i;
TRACE( "Initializing shared memory\n" );
/* Set all lobbies to be "empty" */
for( i=0; i < numSupportedLobbies; i++ )
......@@ -100,22 +299,38 @@ void DPLAYX_ConstructData(void)
sessionData[i].dwSize = 0;
}
/* Zero out the dynmaic area */
ZeroMemory( lpMemArea, dwDynamicSharedSize );
/* Just for fun sync the whole data area */
FlushViewOfFile( lpSharedStaticData, dwTotalSharedSize );
}
DPLAYX_ReleaseSemaphore();
return TRUE;
}
/***************************************************************************
* Called to destroy all global data. This will only be used on the
* unloading of the dll
***************************************************************************/
void DPLAYX_DestructData(void)
BOOL DPLAYX_DestructData(void)
{
TRACE( "DPLAYX dll unloaded - destruct called\n" );
/* delete the semaphore */
/* Delete the semaphore */
CloseHandle( hDplayxSema );
/* Delete shared memory file mapping */
UnmapViewOfFile( lpSharedStaticData );
CloseHandle( hDplayxSharedMem );
return FALSE;
}
void DPLAYX_InitializeLobbyDataEntry( lpDirectPlayLobbyData lpData )
void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData )
{
ZeroMemory( lpData, sizeof( *lpData ) );
......@@ -127,9 +342,9 @@ void DPLAYX_InitializeLobbyDataEntry( lpDirectPlayLobbyData lpData )
* TRUE/FALSE with a pointer to it's data returned. Pointer data is
* is only valid if TRUE is returned.
*/
BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, lpDirectPlayLobbyData* lplpDplData )
BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, LPDPLAYX_LOBBYDATA* lplpDplData )
{
INT i;
UINT i;
*lplpDplData = NULL;
......@@ -144,6 +359,7 @@ BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, lpDirectPlayLobbyData* lplpDplData )
if( lobbyData[ i ].dwAppID == dwAppID )
{
/* This process is lobbied */
TRACE( "Found 0x%08lx @ %u\n", dwAppID, i );
*lplpDplData = &lobbyData[ i ];
return TRUE;
}
......@@ -171,15 +387,24 @@ BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
if( lobbyData[ i ].dwAppID == 0 )
{
/* This process is now lobbied */
TRACE( "Setting lobbyData[%u] for (0x%08lx,%u,0x%08lx)\n",
i, dwAppID, hReceiveEvent, GetCurrentProcessId() );
lobbyData[ i ].dwAppID = dwAppID;
lobbyData[ i ].hReceiveEvent = hReceiveEvent;
lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId();
lobbyData[ i ].bInformOnConnect = TRUE;
lobbyData[ i ].bInformOnSettingRead = TRUE;
lobbyData[ i ].bInformOnAppDeath = TRUE;
DPLAYX_ReleaseSemaphore();
return TRUE;
}
}
ERR( "No empty lobbies\n" );
DPLAYX_ReleaseSemaphore();
return FALSE;
}
......@@ -196,7 +421,9 @@ BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID )
{
if( lobbyData[ i ].dwAppID == dwAppID )
{
/* FIXME: Should free up anything unused. Tisk tisk :0 */
/* Mark this entry unused */
TRACE( "Marking lobbyData[%u] unused\n", i );
DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
DPLAYX_ReleaseSemaphore();
......@@ -212,20 +439,11 @@ BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID )
HRESULT DPLAYX_GetConnectionSettingsA
( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
LPDWORD lpdwDataSize,
LPBOOL lpbSendHaveReadMessage )
{
lpDirectPlayLobbyData lpDplData;
LPDPLCONNECTION lpDplConnection;
/* Verify buffer size */
if ( ( lpData == NULL ) ||
( *lpdwDataSize < sizeof( DPLCONNECTION ) )
)
{
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
}
LPDPLAYX_LOBBYDATA lpDplData;
DWORD dwRequiredDataSize = 0;
DPLAYX_AquireSemaphore();
......@@ -237,153 +455,224 @@ HRESULT DPLAYX_GetConnectionSettingsA
return DPERR_NOTLOBBIED;
}
/* Copy the information */
lpDplConnection = (LPDPLCONNECTION)lpData;
dwRequiredDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn );
/* Copy everything we've got into here */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplConnection->dwSize = sizeof( DPLCONNECTION );
lpDplConnection->dwFlags = lpDplData->dwConnFlags;
/* Do they want to know the required buffer size or is the provided buffer
* big enough?
*/
if ( ( lpData == NULL ) ||
( *lpdwDataSize < dwRequiredDataSize )
)
{
DPLAYX_ReleaseSemaphore();
/* Copy LPDPSESSIONDESC2 struct */
lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->sessionDesc ) );
memcpy( lpDplConnection->lpSessionDesc, &lpDplData->sessionDesc, sizeof( lpDplData->sessionDesc ) );
*lpdwDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn );
if( lpDplData->sessionDesc.sess.lpszSessionNameA )
{
lpDplConnection->lpSessionDesc->sess.lpszSessionNameA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.sess.lpszSessionNameA );
return DPERR_BUFFERTOOSMALL;
}
if( lpDplData->sessionDesc.pass.lpszPasswordA )
{
lpDplConnection->lpSessionDesc->pass.lpszPasswordA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.pass.lpszPasswordA );
}
/* They have gotten the information */
*lpbSendHaveReadMessage = lpDplData->bInformOnSettingRead;
lpDplData->bInformOnSettingRead = FALSE;
lpDplConnection->lpSessionDesc->dwReserved1 = lpDplData->sessionDesc.dwReserved1;
lpDplConnection->lpSessionDesc->dwReserved2 = lpDplData->sessionDesc.dwReserved2;
DPLAYX_CopyConnStructA( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
/* Copy DPNAME struct - seems to be optional - check for existance first */
lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->playerName ) );
memcpy( lpDplConnection->lpPlayerName, &(lpDplData->playerName), sizeof( lpDplData->playerName ) );
DPLAYX_ReleaseSemaphore();
if( lpDplData->playerName.psn.lpszShortNameA )
return DP_OK;
}
/* Assumption: Enough contiguous space was allocated at dest */
void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
{
BYTE* lpStartOfFreeSpace;
memcpy( dest, src, sizeof( DPLCONNECTION ) );
lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION );
/* Copy the LPDPSESSIONDESC2 structure if it exists */
if( src->lpSessionDesc )
{
lpDplConnection->lpPlayerName->psn.lpszShortNameA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.psn.lpszShortNameA );
}
dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
memcpy( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
if( lpDplData->playerName.pln.lpszLongNameA )
/* Session names may or may not exist */
if( src->lpSessionDesc->sess.lpszSessionNameA )
{
lpDplConnection->lpPlayerName->pln.lpszLongNameA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.pln.lpszLongNameA );
lstrcpyA( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->sess.lpszSessionNameA );
dest->lpSessionDesc->sess.lpszSessionNameA = (LPSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace +=
lstrlenA( (LPSTR)dest->lpSessionDesc->sess.lpszSessionName ) + 1;
}
memcpy( &lpDplConnection->guidSP, &lpDplData->guidSP, sizeof( lpDplData->guidSP ) );
if( src->lpSessionDesc->pass.lpszPasswordA )
{
lstrcpyA( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->pass.lpszPasswordA );
dest->lpSessionDesc->pass.lpszPasswordA = (LPSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace +=
lstrlenA( (LPSTR)dest->lpSessionDesc->pass.lpszPasswordA ) + 1;
}
}
lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->dwAddressSize );
memcpy( lpDplConnection->lpAddress, lpDplData->lpAddress, lpDplData->dwAddressSize );
/* DPNAME structure is optional */
if( src->lpPlayerName )
{
dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof( DPNAME );
memcpy( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
if( src->lpPlayerName->psn.lpszShortNameA )
{
lstrcpyA( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->psn.lpszShortNameA );
dest->lpPlayerName->psn.lpszShortNameA = (LPSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace +=
lstrlenA( (LPSTR)dest->lpPlayerName->psn.lpszShortNameA ) + 1;
}
/* FIXME: Send a message - or only the first time? */
if( src->lpPlayerName->pln.lpszLongNameA )
{
lstrcpyA( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->pln.lpszLongNameA );
dest->lpPlayerName->pln.lpszLongNameA = (LPSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace +=
lstrlenA( (LPSTR)dest->lpPlayerName->pln.lpszLongName ) + 1 ;
}
DPLAYX_ReleaseSemaphore();
}
return DP_OK;
/* Copy address if it exists */
if( src->lpAddress )
{
dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
memcpy( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
/* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
}
}
HRESULT DPLAYX_GetConnectionSettingsW
( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
LPDWORD lpdwDataSize,
LPBOOL lpbSendHaveReadMessage )
{
lpDirectPlayLobbyData lpDplData;
LPDPLCONNECTION lpDplConnection;
LPDPLAYX_LOBBYDATA lpDplData;
DWORD dwRequiredDataSize = 0;
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
dwRequiredDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn );
/* Verify buffer size */
/* Do they want to know the required buffer size or is the provided buffer
* big enough?
*/
if ( ( lpData == NULL ) ||
( *lpdwDataSize < sizeof( DPLCONNECTION ) )
( *lpdwDataSize < dwRequiredDataSize )
)
{
*lpdwDataSize = sizeof( DPLCONNECTION );
DPLAYX_ReleaseSemaphore();
*lpdwDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn );
return DPERR_BUFFERTOOSMALL;
}
DPLAYX_AquireSemaphore();
/* They have gotten the information */
*lpbSendHaveReadMessage = lpDplData->bInformOnSettingRead;
lpDplData->bInformOnSettingRead = FALSE;
DPLAYX_CopyConnStructW( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
/* Copy the information */
lpDplConnection = (LPDPLCONNECTION)lpData;
return DP_OK;
}
/* Copy everything we've got into here */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplConnection->dwSize = sizeof( DPLCONNECTION );
lpDplConnection->dwFlags = lpDplData->dwConnFlags;
/* Assumption: Enough contiguous space was allocated at dest */
void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
{
BYTE* lpStartOfFreeSpace;
/* Copy LPDPSESSIONDESC2 struct */
lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->sessionDesc ) );
memcpy( lpDplConnection->lpSessionDesc, &lpDplData->sessionDesc, sizeof( lpDplData->sessionDesc ) );
memcpy( dest, src, sizeof( DPLCONNECTION ) );
if( lpDplData->sessionDesc.sess.lpszSessionName )
lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION );
/* Copy the LPDPSESSIONDESC2 structure if it exists */
if( src->lpSessionDesc )
{
lpDplConnection->lpSessionDesc->sess.lpszSessionName =
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.sess.lpszSessionName );
}
dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
memcpy( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
if( lpDplData->sessionDesc.pass.lpszPassword )
/* Session names may or may not exist */
if( src->lpSessionDesc->sess.lpszSessionName )
{
lpDplConnection->lpSessionDesc->pass.lpszPassword =
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.pass.lpszPassword );
lstrcpyW( (LPWSTR)lpStartOfFreeSpace, dest->lpSessionDesc->sess.lpszSessionName );
src->lpSessionDesc->sess.lpszSessionName = (LPWSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof(WCHAR) *
( lstrlenW( (LPWSTR)dest->lpSessionDesc->sess.lpszSessionName ) + 1 );
}
lpDplConnection->lpSessionDesc->dwReserved1 = lpDplData->sessionDesc.dwReserved1;
lpDplConnection->lpSessionDesc->dwReserved2 = lpDplData->sessionDesc.dwReserved2;
if( src->lpSessionDesc->pass.lpszPassword )
{
lstrcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->pass.lpszPassword );
dest->lpSessionDesc->pass.lpszPassword = (LPWSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof(WCHAR) *
( lstrlenW( (LPWSTR)dest->lpSessionDesc->pass.lpszPassword ) + 1 );
}
}
/* Copy DPNAME struct - seems to be optional - check for existance first */
lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->playerName ) );
memcpy( lpDplConnection->lpPlayerName, &(lpDplData->playerName), sizeof( lpDplData->playerName ) );
/* DPNAME structure is optional */
if( src->lpPlayerName )
{
dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof( DPNAME );
memcpy( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
if( lpDplData->playerName.psn.lpszShortName )
if( src->lpPlayerName->psn.lpszShortName )
{
lpDplConnection->lpPlayerName->psn.lpszShortName =
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.psn.lpszShortName );
lstrcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->psn.lpszShortName );
dest->lpPlayerName->psn.lpszShortName = (LPWSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof(WCHAR) *
( lstrlenW( (LPWSTR)dest->lpPlayerName->psn.lpszShortName ) + 1 );
}
if( lpDplData->playerName.pln.lpszLongName )
if( src->lpPlayerName->pln.lpszLongName )
{
lpDplConnection->lpPlayerName->pln.lpszLongName =
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.pln.lpszLongName );
lstrcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->pln.lpszLongName );
dest->lpPlayerName->pln.lpszLongName = (LPWSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof(WCHAR) *
( lstrlenW( (LPWSTR)dest->lpPlayerName->pln.lpszLongName ) + 1 );
}
memcpy( &lpDplConnection->guidSP, &lpDplData->guidSP, sizeof( lpDplData->guidSP ) );
lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->dwAddressSize );
memcpy( lpDplConnection->lpAddress, lpDplData->lpAddress, lpDplData->dwAddressSize );
lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
/* FIXME: Send a message - or only the first time? */
}
DPLAYX_ReleaseSemaphore();
/* Copy address if it exists */
if( src->lpAddress )
{
dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
memcpy( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
/* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
}
return DP_OK;
}
/* Store the structure into the shared data structre. Ensure that allocs for
* variable length strings come from the shared data structure.
* FIXME: We need to free information as well
*/
HRESULT DPLAYX_SetConnectionSettingsA
( DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
lpDirectPlayLobbyData lpDplData;
LPDPLAYX_LOBBYDATA lpDplData;
/* Paramater check */
if( dwFlags || !lpConn )
......@@ -401,35 +690,15 @@ HRESULT DPLAYX_SetConnectionSettingsA
return DPERR_INVALIDPARAMS;
}
if( dwAppID == 0 )
{
dwAppID = GetCurrentProcessId();
}
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
/* FIXME: Create a new entry for this dwAppID? */
DPLAYX_ReleaseSemaphore();
return DPERR_GENERIC;
}
/* Store information */
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
DPLAYX_ReleaseSemaphore();
ERR(": old/new DPLCONNECTION type? Size=%lu vs. expected=%u bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
return DPERR_NOTLOBBIED;
}
/* Need to investigate the lpConn->lpSessionDesc to figure out
* what type of session we need to join/create.
*/
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
......@@ -442,61 +711,32 @@ HRESULT DPLAYX_SetConnectionSettingsA
return DPERR_INVALIDPARAMS;
}
/* FIXME: How do I store this stuff so that it can be read by all processes? Static area? What about strings? Ewww...large global shared */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplData->dwConnFlags = lpConn->dwFlags;
/* Copy LPDPSESSIONDESC2 struct - this is required */
memcpy( &lpDplData->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
/* Free the existing memory */
DPLAYX_PrivHeapFree( lpDplData->lpConn );
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
lpDplData->sessionDesc.sess.lpszSessionNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionNameA );
else
lpDplData->sessionDesc.sess.lpszSessionNameA = NULL;
lpDplData->lpConn = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY,
DPLAYX_SizeOfLobbyDataA( lpConn ) );
if( lpConn->lpSessionDesc->pass.lpszPasswordA )
lpDplData->sessionDesc.pass.lpszPasswordA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPasswordA );
else
lpDplData->sessionDesc.pass.lpszPasswordA = NULL;
DPLAYX_CopyConnStructA( lpDplData->lpConn, lpConn );
lpDplData->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
lpDplData->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
if( lpConn->lpPlayerName )
{
memcpy( &lpDplData->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
if( lpConn->lpPlayerName->psn.lpszShortNameA )
lpDplData->playerName.psn.lpszShortNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortNameA );
if( lpConn->lpPlayerName->pln.lpszLongNameA )
lpDplData->playerName.pln.lpszLongNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongNameA );
}
memcpy( &lpDplData->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
lpDplData->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
memcpy( lpDplData->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
lpDplData->dwAddressSize = lpConn->dwAddressSize;
DPLAYX_ReleaseSemaphore();
/* FIXME: Send a message - I think */
DPLAYX_ReleaseSemaphore();
return DP_OK;
}
/* Store the structure into the shared data structre. Ensure that allocs for
* variable length strings come from the shared data structure.
* FIXME: We need to free information as well
*/
HRESULT DPLAYX_SetConnectionSettingsW
( DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
lpDirectPlayLobbyData lpDplData;
LPDPLAYX_LOBBYDATA lpDplData;
/* Paramater check */
if( dwFlags || !lpConn )
......@@ -514,88 +754,135 @@ HRESULT DPLAYX_SetConnectionSettingsW
return DPERR_INVALIDPARAMS;
}
if( dwAppID == 0 )
{
dwAppID = GetCurrentProcessId();
}
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
/* Need to investigate the lpConn->lpSessionDesc to figure out
* what type of session we need to join/create.
*/
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
{
/* Free the existing memory */
DPLAYX_PrivHeapFree( lpDplData->lpConn );
lpDplData->lpConn = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY,
DPLAYX_SizeOfLobbyDataW( lpConn ) );
DPLAYX_CopyConnStructW( lpDplData->lpConn, lpConn );
DPLAYX_ReleaseSemaphore();
ERR("DPSESSIONDESC passed in? Size=%lu vs. expected=%u bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
/* FIXME: Send a message - I think */
return DPERR_INVALIDPARAMS;
return DP_OK;
}
DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpConn )
{
DWORD dwTotalSize = sizeof( DPLCONNECTION );
/* Just a safety check */
if( lpConn == NULL )
{
ERR( "lpConn is NULL\n" );
return 0;
}
if( lpConn->lpSessionDesc != NULL )
{
dwTotalSize += sizeof( DPSESSIONDESC2 );
if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
{
dwTotalSize += lstrlenA( lpConn->lpSessionDesc->sess.lpszSessionNameA ) + 1;
}
/* FIXME: How do I store this stuff so that it can be read by all processes? Static area? What about strings? Ewww...large global shared */
if( lpConn->lpSessionDesc->pass.lpszPasswordA )
{
dwTotalSize += lstrlenA( lpConn->lpSessionDesc->pass.lpszPasswordA ) + 1;
}
}
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplData->dwConnFlags = lpConn->dwFlags;
if( lpConn->lpPlayerName != NULL )
{
dwTotalSize += sizeof( DPNAME );
/* Copy LPDPSESSIONDESC2 struct - this is required */
memcpy( &lpDplData->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
if( lpConn->lpPlayerName->psn.lpszShortNameA )
{
dwTotalSize += lstrlenA( lpConn->lpPlayerName->psn.lpszShortNameA ) + 1;
}
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
if( lpConn->lpSessionDesc->sess.lpszSessionName )
lpDplData->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
else
lpDplData->sessionDesc.sess.lpszSessionName = NULL;
if( lpConn->lpPlayerName->pln.lpszLongNameA )
{
dwTotalSize += lstrlenA( lpConn->lpPlayerName->pln.lpszLongNameA ) + 1;
}
if( lpConn->lpSessionDesc->pass.lpszPassword )
lpDplData->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
else
lpDplData->sessionDesc.pass.lpszPassword = NULL;
}
lpDplData->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
lpDplData->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
dwTotalSize += lpConn->dwAddressSize;
/* Copy DPNAME struct - seems to be optional - check for existance first */
if( lpConn->lpPlayerName )
return dwTotalSize;
}
DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpConn )
{
DWORD dwTotalSize = sizeof( DPLCONNECTION );
/* Just a safety check */
if( lpConn == NULL )
{
memcpy( &lpDplData->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
ERR( "lpConn is NULL\n" );
return 0;
}
if( lpConn->lpPlayerName->psn.lpszShortName )
lpDplData->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName );
if( lpConn->lpSessionDesc != NULL )
{
dwTotalSize += sizeof( DPSESSIONDESC2 );
if( lpConn->lpPlayerName->pln.lpszLongName )
lpDplData->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
if( lpConn->lpSessionDesc->sess.lpszSessionName )
{
dwTotalSize += sizeof( WCHAR ) *
( lstrlenW( lpConn->lpSessionDesc->sess.lpszSessionName ) + 1 );
}
if( lpConn->lpSessionDesc->pass.lpszPassword )
{
dwTotalSize += sizeof( WCHAR ) *
( lstrlenW( lpConn->lpSessionDesc->pass.lpszPassword ) + 1 );
}
}
memcpy( &lpDplData->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
if( lpConn->lpPlayerName != NULL )
{
dwTotalSize += sizeof( DPNAME );
lpDplData->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
memcpy( lpDplData->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
if( lpConn->lpPlayerName->psn.lpszShortName )
{
dwTotalSize += sizeof( WCHAR ) *
( lstrlenW( lpConn->lpPlayerName->psn.lpszShortName ) + 1 );
}
lpDplData->dwAddressSize = lpConn->dwAddressSize;
if( lpConn->lpPlayerName->pln.lpszLongName )
{
dwTotalSize += sizeof( WCHAR ) *
( lstrlenW( lpConn->lpPlayerName->pln.lpszLongName ) + 1 );
}
/* FIXME: Send a message - I think */
}
DPLAYX_ReleaseSemaphore();
dwTotalSize += lpConn->dwAddressSize;
return DP_OK;
return dwTotalSize;
}
LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateSessionDesc2A( LPCDPSESSIONDESC2 lpSessionSrc )
{
LPDPSESSIONDESC2 lpSessionDest = (LPDPSESSIONDESC2) HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof( *lpSessionSrc ) );
LPDPSESSIONDESC2 lpSessionDest =
(LPDPSESSIONDESC2)DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, sizeof( *lpSessionSrc ) );
DPLAYX_CopyIntoSessionDesc2A( lpSessionDest, lpSessionSrc );
return lpSessionDest;
......@@ -610,12 +897,12 @@ BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
if( lpSessionSrc->sess.lpszSessionNameA )
{
lpSessionDest->sess.lpszSessionNameA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpSessionSrc->sess.lpszSessionNameA );
DPLAYX_strdupA( HEAP_ZERO_MEMORY, lpSessionSrc->sess.lpszSessionNameA );
}
if( lpSessionSrc->pass.lpszPasswordA )
{
lpSessionDest->pass.lpszPasswordA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpSessionSrc->pass.lpszPasswordA );
DPLAYX_strdupA( HEAP_ZERO_MEMORY, lpSessionSrc->pass.lpszPasswordA );
}
return TRUE;
......@@ -657,8 +944,6 @@ void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd )
{
UINT i;
FIXME( ": stub\n" );
/* FIXME: Is this an error if it exists already? */
/* Crude/wrong implementation for now. Just always add to first empty spot */
......@@ -674,6 +959,49 @@ void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd )
}
BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait )
{
LPDPLAYX_LOBBYDATA lpLobbyData;
DPLAYX_AquireSemaphore();
if( !DPLAYX_IsAppIdLobbied( 0, &lpLobbyData ) )
{
DPLAYX_ReleaseSemaphore();
return FALSE;
}
lpLobbyData->bWaitForConnectionSettings = bWait;
DPLAYX_ReleaseSemaphore();
return TRUE;
}
BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void)
{
UINT i;
BOOL bFound = FALSE;
DPLAYX_AquireSemaphore();
for( i=0; i < numSupportedLobbies; i++ )
{
if( ( lobbyData[ i ].dwAppID != 0 ) && /* lobby initialized */
( lobbyData[ i ].bWaitForConnectionSettings ) /* Waiting */
)
{
bFound = TRUE;
break;
}
}
DPLAYX_ReleaseSemaphore();
return bFound;
}
/* NOTE: This is potentially not thread safe. You are not guaranteed to end up
with the correct string printed in the case where the HRESULT is not
known. You'll just get the last hr passed in printed. This can change
......
......@@ -4,18 +4,31 @@
#include "dplay.h"
void DPLAYX_ConstructData(void);
void DPLAYX_DestructData(void);
HRESULT DPLAYX_GetConnectionSettingsA ( DWORD dwAppID, LPVOID lpData, LPDWORD lpdwDataSize );
HRESULT DPLAYX_GetConnectionSettingsW ( DWORD dwAppID, LPVOID lpData, LPDWORD lpdwDataSize );
HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags, DWORD dwAppID, LPDPLCONNECTION lpConn );
HRESULT DPLAYX_SetConnectionSettingsW ( DWORD dwFlags, DWORD dwAppID, LPDPLCONNECTION lpConn );
BOOL DPLAYX_ConstructData(void);
BOOL DPLAYX_DestructData(void);
HRESULT DPLAYX_GetConnectionSettingsA ( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize,
LPBOOL lpbSendHaveReadMessage );
HRESULT DPLAYX_GetConnectionSettingsW ( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize,
LPBOOL lpbSendHaveReadMessage );
HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn );
HRESULT DPLAYX_SetConnectionSettingsW ( DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn );
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent );
BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID );
BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait );
BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void);
LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateLocalSession( UINT* index );
BOOL DPLAYX_CopyLocalSession( UINT* index, LPDPSESSIONDESC2 lpsd );
void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd );
......
/*
* DPLAYX.DLL LibMain
*
* Copyright 1999 - Peter Hunnisett
* Copyright 1999,2000 - Peter Hunnisett
*
* contact <hunnise@nortelnetworks.com>
*/
......@@ -17,34 +17,29 @@ static DWORD DPLAYX_dwProcessesAttached = 0;
BOOL WINAPI DPLAYX_LibMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
TRACE( "(%p,0x%08lx,%p) & 0x%08lx\n", hinstDLL, fdwReason, lpvReserved, DPLAYX_dwProcessesAttached );
TRACE( "(%u,0x%08lx,%p) & 0x%08lx\n", hinstDLL, fdwReason, lpvReserved, DPLAYX_dwProcessesAttached );
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH:
{
if ( DPLAYX_dwProcessesAttached == 0 )
if ( DPLAYX_dwProcessesAttached++ == 0 )
{
/* First instance perform construction of global processor data */
TRACE( "DPLAYX_dwProcessesAttached = 0x%08lx\n", DPLAYX_dwProcessesAttached );
DPLAYX_ConstructData();
return DPLAYX_ConstructData();
}
DPLAYX_dwProcessesAttached++;
break;
}
case DLL_PROCESS_DETACH:
{
DPLAYX_dwProcessesAttached--;
if ( DPLAYX_dwProcessesAttached == 0 )
if ( --DPLAYX_dwProcessesAttached == 0 )
{
/* Last instance perform destruction of global processor data */
DPLAYX_DestructData();
/* Last instance performs destruction of global processor data */
return DPLAYX_DestructData();
}
break;
......
/* DirectPlay & DirectPlayLobby messaging implementation
*
* Copyright 2000 - Peter Hunnisett
*
* <presently under construction - contact hunnise@nortelnetworks.com>
*
*/
#include "winbase.h"
#include "debugtools.h"
#include "dplayx_messages.h"
DEFAULT_DEBUG_CHANNEL(dplay)
static DWORD CALLBACK DPLAYX_MSG_ThreadMain( LPVOID lpContext );
/* Create the message reception thread to allow the application to receive
* asynchronous message reception
*/
DWORD CreateMessageReceptionThread( HANDLE hNotifyEvent )
{
DWORD dwMsgThreadId;
if( !DuplicateHandle( 0, hNotifyEvent, 0, NULL, 0, FALSE, 0 ) )
{
ERR( "Unable to duplicate event handle\n" );
return 0;
}
/* FIXME: Should most likely store that thread handle */
CreateThread( NULL, /* Security attribs */
0, /* Stack */
DPLAYX_MSG_ThreadMain, /* Msg reception function */
(LPVOID)hNotifyEvent, /* Msg reception function parameter */
0, /* Flags */
&dwMsgThreadId /* Updated with thread id */
);
return dwMsgThreadId;
}
static DWORD CALLBACK DPLAYX_MSG_ThreadMain( LPVOID lpContext )
{
HANDLE hMsgEvent = (HANDLE)lpContext;
for ( ;; )
{
FIXME( "Ho Hum. Msg thread with nothing to do on handle %u\n", hMsgEvent );
SleepEx( 10000, FALSE ); /* 10 secs */
}
CloseHandle( hMsgEvent );
}
#ifndef __WINE_DPLAYX_MESSAGES
#define __WINE_DPLAYX_MESSAGES
#include "windef.h"
DWORD CreateMessageReceptionThread( HANDLE hNotifyEvent );
#endif
/* Helper functions for TAILQ functions defined in <sys/queue.h>
/* A queue definition based on sys/queue.h TAILQ definitions
*
* Blame any implementation mistakes on Peter Hunnisett
* <hunnise@nortelnetworks.com>
......@@ -8,17 +7,59 @@
#ifndef __WINE_DPLAYX_QUEUE_H
#define __WINE_DPLAYX_QUEUE_H
#include <sys/queue.h>
#define DPQ_INSERT(a,b,c) DPQ_INSERT_IN_TAIL(a,b,c)
/*
* Tail queue definitions.
*/
#define DPQ_HEAD(type) \
struct { \
struct type *lpQHFirst; /* first element */ \
struct type **lpQHLast; /* addr of last next element */ \
}
#define DPQ_ENTRY(type) \
struct { \
struct type *lpQNext; /* next element */ \
struct type **lpQPrev; /* address of previous next element */ \
}
/*
* Tail queue functions.
*/
#define DPQ_INIT(head) \
do{ \
(head).lpQHFirst = NULL; \
(head).lpQHLast = &(head).lpQHFirst; \
} while(0)
#define DPQ_INSERT_IN_TAIL(head, elm, field) \
do { \
(elm)->field.lpQNext = NULL; \
(elm)->field.lpQPrev = (head).lpQHLast; \
*(head).lpQHLast = (elm); \
(head).lpQHLast = &(elm)->field.lpQNext; \
} while(0)
#define DPQ_REMOVE(head, elm, field) \
do { \
if (((elm)->field.lpQNext) != NULL) \
(elm)->field.lpQNext->field.lpQPrev = \
(elm)->field.lpQPrev; \
else \
(head).lpQHLast = (elm)->field.lpQPrev; \
*(elm)->field.lpQPrev = (elm)->field.lpQNext; \
} while(0)
/* head - pointer to TAILQ_HEAD struct
/* head - pointer to DPQ_HEAD struct
* elm - how to find the next element
* field - to be concatenated to rc to compare with fieldToEqual
* fieldToEqual - The value that we're looking for
* rc - Variable to put the return code. Same type as (head)->tqh_first
* rc - Variable to put the return code. Same type as (head).lpQHFirst
*/
#define TAILQ_FIND_ENTRY( head, elm, field, fieldToEqual, rc ) \
#define DPQ_FIND_ENTRY( head, elm, field, fieldToEqual, rc ) \
do { \
(rc) = (head)->tqh_first; /* NULL head? */ \
(rc) = (head).lpQHFirst; /* NULL head? */ \
\
while( rc ) \
{ \
......@@ -29,7 +70,7 @@ do { \
} \
\
/* End of list check */ \
if( ( (rc) = (rc)->elm.tqe_next ) == (head)->tqh_first ) \
if( ( (rc) = (rc)->elm.lpQNext ) == (head).lpQHFirst ) \
{ \
rc = NULL; \
break; \
......@@ -37,20 +78,20 @@ do { \
} \
} while(0)
/* head - pointer to TAILQ_HEAD struct
/* head - pointer to DPQ_HEAD struct
* elm - how to find the next element
* field - to be concatenated to rc to compare with fieldToEqual
* fieldToEqual - The value that we're looking for
* rc - Variable to put the return code. Same type as (head)->tqh_first
* rc - Variable to put the return code. Same type as (head).lpQHFirst
*/
#define TAILQ_REMOVE_ENTRY( head, elm, field, fieldToEqual, rc ) \
#define DPQ_REMOVE_ENTRY( head, elm, field, fieldToEqual, rc ) \
do { \
TAILQ_FIND_ENTRY( head, elm, field, fieldToEqual, rc ); \
DPQ_FIND_ENTRY( head, elm, field, fieldToEqual, rc ); \
\
/* Was the element found? */ \
if( rc ) \
{ \
TAILQ_REMOVE( head, rc, elm ); \
DPQ_REMOVE( head, rc, elm ); \
} \
} while(0)
......
......@@ -16,9 +16,19 @@
#include "dplobby.h"
#include "dpinit.h"
#include "dplayx_global.h"
#include "dplayx_messages.h"
DEFAULT_DEBUG_CHANNEL(dplay)
/*****************************************************************************
* Predeclare the interface implementation structures
*/
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyAImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyWImpl;
typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2AImpl;
typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2WImpl;
typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3AImpl;
typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3WImpl;
/* Forward declarations for this module helper methods */
HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
......@@ -32,16 +42,11 @@ HRESULT DPL_CreateAddress( REFGUID guidSP, REFGUID guidDataType, LPCVOID lpData,
static HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, LPCVOID lpAddress,
DWORD dwAddressSize, LPVOID lpContext );
static HRESULT WINAPI DPL_ConnectEx( IDirectPlayLobbyAImpl* This,
DWORD dwFlags, REFIID riid,
LPVOID* lplpDP, IUnknown* pUnk );
/*****************************************************************************
* Predeclare the interface implementation structures
*/
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyAImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyWImpl;
typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2AImpl;
typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2WImpl;
typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3AImpl;
typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3WImpl;
/*****************************************************************************
* IDirectPlayLobby {1,2,3} implementation structure
......@@ -565,11 +570,7 @@ static ULONG WINAPI IDirectPlayLobbyImpl_AddRef
ULONG refCount;
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
EnterCriticalSection( &This->unk->DPL_lock );
{
refCount = ++(This->unk->ref);
}
LeaveCriticalSection( &This->unk->DPL_lock );
refCount = InterlockedIncrement( &This->unk->ref );
TRACE("ref count incremented to %lu for %p\n", refCount, This );
......@@ -585,14 +586,9 @@ static ULONG WINAPI IDirectPlayLobbyAImpl_Release
( LPDIRECTPLAYLOBBYA iface )
{
ULONG refCount;
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
EnterCriticalSection( &This->unk->DPL_lock );
{
refCount = --(This->unk->ref);
}
LeaveCriticalSection( &This->unk->DPL_lock );
refCount = InterlockedDecrement( &This->unk->ref );
TRACE("ref count decremeneted to %lu for %p\n", refCount, This );
......@@ -618,20 +614,19 @@ static ULONG WINAPI IDirectPlayLobbyAImpl_Release
* Returns a IDirectPlay interface.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
( LPDIRECTPLAYLOBBYA iface,
static HRESULT WINAPI DPL_ConnectEx
( IDirectPlayLobbyAImpl* This,
DWORD dwFlags,
LPDIRECTPLAY2A* lplpDP,
REFIID riid,
LPVOID* lplpDP,
IUnknown* pUnk)
{
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
LPDIRECTPLAY2A lpDirectPlay2A;
/* LPDIRECTPLAY3A lpDirectPlay3A; */
/* LPDIRECTPLAYLOBBY2A lpDirectPlayLobby2A; */
HRESULT rc;
HRESULT hr;
DWORD dwOpenFlags = 0;
DWORD dwConnSize = 0;
LPDPLCONNECTION lpConn;
FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, dwFlags, lplpDP, pUnk );
FIXME("(%p)->(0x%08lx,%p,%p): semi stub\n", This, dwFlags, lplpDP, pUnk );
if( dwFlags || pUnk )
{
......@@ -639,58 +634,77 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
}
/* Create the DirectPlay interface */
if( ( rc = directPlay_QueryInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) ) != DP_OK )
if( ( hr = directPlay_QueryInterface( riid, lplpDP ) ) != DP_OK )
{
ERR("error creating Direct Play 2A interface. Return Code = 0x%lx.\n", rc );
return rc;
ERR( "error creating interface for %s:%s.\n",
debugstr_guid( riid ), DPLAYX_HresultToString( hr ) );
return hr;
}
lpDirectPlay2A = *lplpDP;
/* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
* - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
* - Call IDirectPlay::InitializeConnection
* - Call IDirectPlay::Open
*/
#if 0
IDirectPlayLobby_EnumAddress( iface, RunApplicationA_Callback,
lpConn->lpAddress, lpConn->dwAddressSize, NULL );
#endif
/* FIXME: Is it safe/correct to use appID of 0? */
hr = IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY)This,
0, NULL, &dwConnSize );
if( hr != DPERR_BUFFERTOOSMALL )
{
return hr;
}
return DP_OK;
}
lpConn = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwConnSize );
static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
LPDIRECTPLAY2* lplpDP,
IUnknown* pUnk)
{
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
LPDIRECTPLAY2* directPlay2W;
HRESULT createRC;
FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, dwFlags, lplpDP, pUnk );
if( lpConn == NULL )
{
return DPERR_NOMEMORY;
}
if( dwFlags || pUnk )
/* FIXME: Is it safe/correct to use appID of 0? */
hr = IDirectPlayLobby_GetConnectionSettings( (LPDIRECTPLAYLOBBY)This,
0, lpConn, &dwConnSize );
if( FAILED( hr ) )
{
return DPERR_INVALIDPARAMS;
return hr;
}
/* Create the DirectPlay interface */
if( ( createRC = directPlay_QueryInterface( &IID_IDirectPlay2, (LPVOID*)lplpDP ) ) != DP_OK )
/* Setup flags to pass into DirectPlay::Open */
if( dwFlags & DPCONNECT_RETURNSTATUS )
{
ERR("error creating Direct Play 2W interface. Return Code = 0x%lx.\n", createRC );
return createRC;
dwOpenFlags |= DPOPEN_RETURNSTATUS;
}
dwOpenFlags |= lpConn->dwFlags;
/* This should invoke IDirectPlay3::InitializeConnection IDirectPlay3::Open */
directPlay2W = lplpDP;
hr = IDirectPlayX_Open( (*(LPDIRECTPLAY2*)lplpDP), lpConn->lpSessionDesc,
dwOpenFlags );
return DP_OK;
HeapFree( GetProcessHeap(), 0, lpConn );
return hr;
}
static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
LPDIRECTPLAY2A* lplpDP,
IUnknown* pUnk)
{
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
return DPL_ConnectEx( This, dwFlags, &IID_IDirectPlay2A,
(LPVOID)lplpDP, pUnk );
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
LPDIRECTPLAY2* lplpDP,
IUnknown* pUnk)
{
ICOM_THIS(IDirectPlayLobbyAImpl,iface); /* Yes cast to A */
return DPL_ConnectEx( This, dwFlags, &IID_IDirectPlay2,
(LPVOID)lplpDP, pUnk );
}
/********************************************************************
......@@ -1099,15 +1113,25 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
{
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
HRESULT hr;
BOOL bSendHaveReadSettingsMessage = FALSE;
TRACE("(%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
EnterCriticalSection( &This->unk->DPL_lock );
hr = DPLAYX_GetConnectionSettingsA( dwAppID, lpData, lpdwDataSize );
hr = DPLAYX_GetConnectionSettingsA( dwAppID,
lpData,
lpdwDataSize,
&bSendHaveReadSettingsMessage
);
LeaveCriticalSection( &This->unk->DPL_lock );
if( bSendHaveReadSettingsMessage )
{
FIXME( "Send a DPSYS_CONNECTIONSETTINGSREAD message\n" );
}
return hr;
}
......@@ -1119,15 +1143,25 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
{
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
HRESULT hr;
BOOL bSendHaveReadSettingsMessage = FALSE;
TRACE("(%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
EnterCriticalSection( &This->unk->DPL_lock );
hr = DPLAYX_GetConnectionSettingsW( dwAppID, lpData, lpdwDataSize );
hr = DPLAYX_GetConnectionSettingsW( dwAppID,
lpData,
lpdwDataSize,
&bSendHaveReadSettingsMessage
);
LeaveCriticalSection( &This->unk->DPL_lock );
if( bSendHaveReadSettingsMessage )
{
FIXME( "Send a DPSYS_CONNECTIONSETTINGSREAD message\n" );
}
return hr;
}
......@@ -1274,6 +1308,7 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
STARTUPINFOA startupInfo;
PROCESS_INFORMATION newProcessInfo;
LPSTR appName;
DWORD dwSuspendCount;
TRACE( "(%p)->(0x%08lx,%p,%p,%x)\n", This, dwFlags, lpdwAppID, lpConn, hReceiveEvent );
......@@ -1282,6 +1317,11 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
return DPERR_INVALIDPARAMS;
}
if( DPLAYX_AnyLobbiesWaitingForConnSettings() )
{
FIXME( "Waiting lobby not being handled correctly\n" );
}
EnterCriticalSection( &This->unk->DPL_lock );
ZeroMemory( &enumData, sizeof( enumData ) );
......@@ -1326,7 +1366,7 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
)
)
{
FIXME( "Failed to create process for app %s\n", appName );
ERR( "Failed to create process for app %s\n", appName );
HeapFree( GetProcessHeap(), 0, appName );
HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine );
......@@ -1342,25 +1382,35 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
/* Reserve this global application id! */
if( !DPLAYX_CreateLobbyApplication( newProcessInfo.dwProcessId, hReceiveEvent ) )
{
ERR( "Unable to create global application data\n" );
ERR( "Unable to create global application data for 0x%08lx\n",
newProcessInfo.dwProcessId );
}
hr = IDirectPlayLobby_SetConnectionSettings( iface, 0, newProcessInfo.dwProcessId, lpConn );
if( hr != DP_OK )
{
FIXME( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr ) );
ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr ) );
return hr;
}
/* Everything seems to have been set correctly, update the dwAppID */
*lpdwAppID = newProcessInfo.dwProcessId;
/* Unsuspend the process */
ResumeThread( newProcessInfo.dwThreadId );
if( hReceiveEvent )
{
FIXME( "Need to store msg thread id\n" );
CreateMessageReceptionThread( hReceiveEvent );
}
LeaveCriticalSection( &This->unk->DPL_lock );
/* Unsuspend the process - should return the prev suspension count */
if( ( dwSuspendCount = ResumeThread( newProcessInfo.hThread ) ) != 1 )
{
ERR( "ResumeThread failed with 0x%08lx\n", dwSuspendCount );
}
return DP_OK;
}
......@@ -1425,6 +1475,17 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_SetConnectionSettings
hr = DPLAYX_SetConnectionSettingsW( dwFlags, dwAppID, lpConn );
/* FIXME: Don't think that this is supposed to fail, but the docuementation
is somewhat sketchy. I'll try creating a lobby application
for this... */
if( hr == DPERR_NOTLOBBIED )
{
FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
dwAppID = GetCurrentProcessId();
DPLAYX_CreateLobbyApplication( dwAppID, 0 );
hr = DPLAYX_SetConnectionSettingsW( dwFlags, dwAppID, lpConn );
}
LeaveCriticalSection( &This->unk->DPL_lock );
return hr;
......@@ -1445,6 +1506,17 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
hr = DPLAYX_SetConnectionSettingsA( dwFlags, dwAppID, lpConn );
/* FIXME: Don't think that this is supposed to fail, but the docuementation
is somewhat sketchy. I'll try creating a lobby application
for this... */
if( hr == DPERR_NOTLOBBIED )
{
FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" );
dwAppID = GetCurrentProcessId();
DPLAYX_CreateLobbyApplication( dwAppID, 0 );
hr = DPLAYX_SetConnectionSettingsA( dwFlags, dwAppID, lpConn );
}
LeaveCriticalSection( &This->unk->DPL_lock );
return hr;
......@@ -1477,12 +1549,6 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_SetLobbyMessageEvent
/* DPL 2 methods */
/********************************************************************
*
* Registers an event that will be set when a lobby message is received.
*
*/
static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateCompoundAddress
( LPDIRECTPLAYLOBBY2 iface,
LPCDPCOMPOUNDADDRESSELEMENT lpElements,
......@@ -1680,17 +1746,19 @@ HRESULT DPL_CreateCompoundAddress
/* DPL 3 methods */
static HRESULT WINAPI IDirectPlayLobby3WImpl_ConnectEx
( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags, REFIID riid, LPVOID* lplpDP, IUnknown* pUnk )
( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags, REFIID riid,
LPVOID* lplpDP, IUnknown* pUnk )
{
FIXME(":stub\n");
return DP_OK;
ICOM_THIS( IDirectPlayLobbyAImpl, iface );
return DPL_ConnectEx( This, dwFlags, riid, lplpDP, pUnk );
}
static HRESULT WINAPI IDirectPlayLobby3AImpl_ConnectEx
( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags, REFIID riid, LPVOID* lplpDP, IUnknown* pUnk )
( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags, REFIID riid,
LPVOID* lplpDP, IUnknown* pUnk )
{
FIXME(":stub\n");
return DP_OK;
ICOM_THIS( IDirectPlayLobbyAImpl, iface );
return DPL_ConnectEx( This, dwFlags, riid, lplpDP, pUnk );
}
static HRESULT WINAPI IDirectPlayLobby3WImpl_RegisterApplication
......@@ -1724,15 +1792,35 @@ static HRESULT WINAPI IDirectPlayLobby3AImpl_UnregisterApplication
static HRESULT WINAPI IDirectPlayLobby3WImpl_WaitForConnectionSettings
( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags )
{
FIXME(":stub\n");
return DP_OK;
HRESULT hr = DP_OK;
BOOL bStartWait = (dwFlags & DPLWAIT_CANCEL) ? FALSE : TRUE;
TRACE( "(%p)->(0x%08lx)\n", iface, dwFlags );
if( DPLAYX_WaitForConnectionSettings( bStartWait ) )
{
/* FIXME: What is the correct error return code? */
hr = DPERR_NOTLOBBIED;
}
return hr;
}
static HRESULT WINAPI IDirectPlayLobby3AImpl_WaitForConnectionSettings
( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags )
{
FIXME(":stub\n");
return DP_OK;
HRESULT hr = DP_OK;
BOOL bStartWait = (dwFlags & DPLWAIT_CANCEL) ? FALSE : TRUE;
TRACE( "(%p)->(0x%08lx)\n", iface, dwFlags );
if( DPLAYX_WaitForConnectionSettings( bStartWait ) )
{
/* FIXME: What is the correct error return code? */
hr = DPERR_NOTLOBBIED;
}
return hr;
}
......
......@@ -9,21 +9,41 @@ reasonably thourough description of what's going on.
Associated DirectX user header files are include/dplay.h, include/dplobby.h.
Implementation of the DPLAY and DPLAYX dlls are both in the dlls/dplayx
directory.
directory. Here's a brief description of the function of each of the files in that
directory:
dplay.c: Implementation of all the direct play object interfaces.
dplobby.c: Implementation of all the direct play lobby interfaces.
dpclassfactory.c: Implementation of the COM class factory which can create either
direct play lobby or direct play lobby interfaces.
dpinit.h: Header file so that dpclassfactory.c can access dplay and dplobby query
functions. Shouldn't be included by anything else.
dplayx_global.h,
dplayx_global.c: Implementation of all things which are associated with dplay on
the computer - ie shared resources and such. Methods in this
compilation unit should not call anything out side this unit.
compilation unit should not call anything out side this unit
excepting base windows services and an interface to start the
messaging thread.
name_server.h,
name_server.c: Implementation of all things which are associated with the name
server functionality
dplayx_main.c: LibMain executed for loading and unloading the dll. This will make
the call to dplayx_global.c to request initialization and destruction
of any global data.
dplayx_queue.h: Linked list implementation for dplay/dplobby. Based off of the BSD
version found in <sys/queue.h>
dplayx_messages.h,
dplayx_messages.c: Messaging interface required for both DirectPlay and
DirectPlayLobby.
Presently the architectural relationship between this files is a little shakey, but
isn't so sufficiently bad that it needs fixing yet.
......@@ -32,6 +52,12 @@ or direct play lobby will not work at this point. Priority will be to get
examples from the sdk running. Once they're at least partially working, I can
get down to trying to get some of the games working.
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
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
inter lobby messaging.
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
even if the native protocol, IPX or modem for instance, doesn't guarantee it. I'm going to leave
......@@ -59,7 +85,7 @@ TODO:
- (done) Fix wine dplay.h and dplobby.h header files to allow apps to create the ansi versions
- (started) Port some WineLib test programs using sdk programs (both C and C++ progs)
- (done) Implement a lib main for the dplayx dll (required for RunApplication, etc.)
- Figure out how to share the global memory correctly
- (done)Figure out how to share the global memory correctly
- Ensure that all dll stubs are present and the ordinals are correct
- (started) Implementation of functionality
- Addition of DirectX 7.0 functionality for direct play (try to catch that moving train)
......@@ -75,6 +101,19 @@ TODO:
- Handles need to be correctly reference counted
- Need to check if we need to deallocate any list objects when destroying
dplay interface
- RunApplication process spawning needs to have correct syncronization.
- Need to get inter lobby messages working.
ENHANCEMENTS:
- Improve footprint and realtime blocking by setting up a seperate data share
between lobby application and client since there can be multiple apps per
client.
- Handle everything in UNICODE (as server does) and do conversions for ANSI
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
have to do ANSI<->UNICODE transformations).
Programs to make work:
- lserver.exe (from sdk)
......@@ -91,8 +130,7 @@ Next API to implement on a per SDK program basis:
- ?
dplaunch.exe
- IDirectPlayLobbyAImpl_RunApplication
(need address space separation or else rebuild all sdk examples)
- Just needs final process startup messages to be exchanged correctly!
lserver.exe
- IDirectPlayLobby2WImpl_Connect
......
......@@ -424,6 +424,9 @@ ICOM_DEFINE(IDirectPlayLobby3,IDirectPlayLobby2)
#define IDirectPlayLobby_UnregisterApplication(p,a,b) ICOM_CALL2(UnregisterApplication,p,a,b)
#define IDirectPlayLobby_WaitForConnectionSettings(p,a) ICOM_CALL1(WaitForConnectionSettings,p,a)
/* Used for WaitForConnectionSettings */
#define DPLWAIT_CANCEL 0x00000001
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment