- Implemented loading and initialization of service providers
- Created service provider COM object - Lots of dplay/dplobby implementation/fixes - Clean up of ole/guid.c
This commit is contained in:
parent
217a682b4f
commit
ef6dca5c37
|
@ -9,6 +9,7 @@ IMPORTS = ole32 advapi32 kernel32
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
dpclassfactory.c \
|
dpclassfactory.c \
|
||||||
dplay.c \
|
dplay.c \
|
||||||
|
dplaysp.c \
|
||||||
dplayx_global.c \
|
dplayx_global.c \
|
||||||
dplayx_main.c \
|
dplayx_main.c \
|
||||||
dplayx_messages.c \
|
dplayx_messages.c \
|
||||||
|
|
|
@ -39,7 +39,6 @@ static ULONG WINAPI DP_and_DPL_Release(LPCLASSFACTORY iface) {
|
||||||
return --(This->ref);
|
return --(This->ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not the most efficient implementation, but it's simple */
|
|
||||||
static HRESULT WINAPI DP_and_DPL_CreateInstance(
|
static HRESULT WINAPI DP_and_DPL_CreateInstance(
|
||||||
LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
|
LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
|
||||||
) {
|
) {
|
||||||
|
@ -47,12 +46,11 @@ static HRESULT WINAPI DP_and_DPL_CreateInstance(
|
||||||
|
|
||||||
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
|
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
|
||||||
|
|
||||||
/* FIXME: reuse already created DP/DPL object if present? */
|
if ( DPL_CreateInterface( riid, ppobj ) == S_OK )
|
||||||
if ( directPlayLobby_QueryInterface( riid, ppobj ) == S_OK )
|
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
else if ( directPlay_QueryInterface( riid, ppobj ) == S_OK )
|
else if ( DP_CreateInterface( riid, ppobj ) == S_OK )
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -110,13 +108,3 @@ DWORD WINAPI DPLAYX_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
|
||||||
ERR("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
ERR("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
||||||
return CLASS_E_CLASSNOTAVAILABLE;
|
return CLASS_E_CLASSNOTAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* DllCanUnloadNow (DPLAYX.@)
|
|
||||||
*/
|
|
||||||
HRESULT WINAPI DPLAYX_DllCanUnloadNow(void)
|
|
||||||
{
|
|
||||||
FIXME("(void): stub\n");
|
|
||||||
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,7 +2,12 @@
|
||||||
#ifndef __WINE_DPINIT_H
|
#ifndef __WINE_DPINIT_H
|
||||||
#define __WINE_DPINIT_H
|
#define __WINE_DPINIT_H
|
||||||
|
|
||||||
extern HRESULT directPlay_QueryInterface( REFIID riid, LPVOID* ppvObj );
|
#include "wtypes.h"
|
||||||
extern HRESULT directPlayLobby_QueryInterface( REFIID riid, LPVOID* ppvObj );
|
#include "dplay_global.h"
|
||||||
|
|
||||||
|
extern HRESULT DP_CreateInterface( REFIID riid, LPVOID* ppvObj );
|
||||||
|
extern HRESULT DPL_CreateInterface( REFIID riid, LPVOID* ppvObj );
|
||||||
|
extern HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj,
|
||||||
|
IDirectPlay2Impl* dp );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
3321
dlls/dplayx/dplay.c
3321
dlls/dplayx/dplay.c
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,185 @@
|
||||||
|
#ifndef __WINE_DPLAY_GLOBAL_INCLUDED
|
||||||
|
#define __WINE_DPLAY_GLOBAL_INCLUDED
|
||||||
|
|
||||||
|
#include "dplaysp.h"
|
||||||
|
#include "dplayx_queue.h"
|
||||||
|
|
||||||
|
extern HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
|
||||||
|
LPCVOID lpAddress, DWORD dwAddressSize,
|
||||||
|
LPVOID lpContext );
|
||||||
|
|
||||||
|
extern DWORD DP_CalcSessionDescSize( LPCDPSESSIONDESC2 lpSessDesc, BOOL bAnsi );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Predeclare the interface implementation structures
|
||||||
|
*/
|
||||||
|
typedef struct IDirectPlay2Impl IDirectPlay2AImpl;
|
||||||
|
typedef struct IDirectPlay2Impl IDirectPlay2Impl;
|
||||||
|
typedef struct IDirectPlay3Impl IDirectPlay3AImpl;
|
||||||
|
typedef struct IDirectPlay3Impl IDirectPlay3Impl;
|
||||||
|
typedef struct IDirectPlay4Impl IDirectPlay4AImpl;
|
||||||
|
typedef struct IDirectPlay4Impl IDirectPlay4Impl;
|
||||||
|
|
||||||
|
typedef struct tagDirectPlayIUnknownData
|
||||||
|
{
|
||||||
|
ULONG ulObjRef;
|
||||||
|
CRITICAL_SECTION DP_lock;
|
||||||
|
} DirectPlayIUnknownData;
|
||||||
|
|
||||||
|
typedef struct tagEnumSessionAsyncCallbackData
|
||||||
|
{
|
||||||
|
LPSPINITDATA lpSpData;
|
||||||
|
GUID requestGuid;
|
||||||
|
DWORD dwEnumSessionFlags;
|
||||||
|
DWORD dwTimeout;
|
||||||
|
HANDLE hSuicideRequest;
|
||||||
|
} EnumSessionAsyncCallbackData;
|
||||||
|
|
||||||
|
struct PlayerData
|
||||||
|
{
|
||||||
|
/* Individual player information */
|
||||||
|
DPID dpid;
|
||||||
|
|
||||||
|
DPNAME name;
|
||||||
|
HANDLE hEvent;
|
||||||
|
|
||||||
|
/* View of local data */
|
||||||
|
LPVOID lpLocalData;
|
||||||
|
DWORD dwLocalDataSize;
|
||||||
|
|
||||||
|
/* View of remote data */
|
||||||
|
LPVOID lpRemoteData;
|
||||||
|
DWORD dwRemoteDataSize;
|
||||||
|
|
||||||
|
DWORD dwFlags; /* Special remarks about the type of player */
|
||||||
|
};
|
||||||
|
typedef struct PlayerData* lpPlayerData;
|
||||||
|
|
||||||
|
struct PlayerList
|
||||||
|
{
|
||||||
|
DPQ_ENTRY(PlayerList) players;
|
||||||
|
|
||||||
|
lpPlayerData lpPData;
|
||||||
|
};
|
||||||
|
typedef struct PlayerList* lpPlayerList;
|
||||||
|
|
||||||
|
struct GroupData
|
||||||
|
{
|
||||||
|
/* Internal information */
|
||||||
|
DPID parent; /* If parent == 0 it's a top level group */
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
DWORD dwFlags; /* Flags describing anything special about the group */
|
||||||
|
|
||||||
|
DPID dpid;
|
||||||
|
DPNAME name;
|
||||||
|
|
||||||
|
/* View of local data */
|
||||||
|
LPVOID lpLocalData;
|
||||||
|
DWORD dwLocalDataSize;
|
||||||
|
|
||||||
|
/* View of remote data */
|
||||||
|
LPVOID lpRemoteData;
|
||||||
|
DWORD dwRemoteDataSize;
|
||||||
|
};
|
||||||
|
typedef struct GroupData GroupData;
|
||||||
|
typedef struct GroupData* lpGroupData;
|
||||||
|
|
||||||
|
struct GroupList
|
||||||
|
{
|
||||||
|
DPQ_ENTRY(GroupList) groups;
|
||||||
|
|
||||||
|
lpGroupData lpGData;
|
||||||
|
};
|
||||||
|
typedef struct GroupList* lpGroupList;
|
||||||
|
|
||||||
|
struct DPMSG
|
||||||
|
{
|
||||||
|
DPQ_ENTRY( DPMSG ) msgs;
|
||||||
|
DPMSG_GENERIC* msg;
|
||||||
|
};
|
||||||
|
typedef struct DPMSG* LPDPMSG;
|
||||||
|
|
||||||
|
/* Contains all dp1 and dp2 data members */
|
||||||
|
typedef struct tagDirectPlay2Data
|
||||||
|
{
|
||||||
|
BOOL bConnectionOpen;
|
||||||
|
|
||||||
|
/* For async EnumSessions requests */
|
||||||
|
HANDLE hEnumSessionThread;
|
||||||
|
HANDLE hKillEnumSessionThreadEvent;
|
||||||
|
|
||||||
|
LPVOID lpNameServerData; /* DPlay interface doesn't know contents */
|
||||||
|
|
||||||
|
BOOL bHostInterface; /* Did this interface create the session */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
DPQ_HEAD(PlayerList) players; /* All players w/ interface */
|
||||||
|
DPQ_HEAD(GroupList) groups; /* All main groups w/ interface */
|
||||||
|
#else
|
||||||
|
lpGroupData lpSysGroup; /* System group with _everything_ in it */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LPDPSESSIONDESC2 lpSessionDesc;
|
||||||
|
|
||||||
|
/* I/O Msg queues */
|
||||||
|
DPQ_HEAD( DPMSG ) receiveMsgs; /* Msg receive queue */
|
||||||
|
DPQ_HEAD( DPMSG ) sendMsgs; /* Msg send pending queue */
|
||||||
|
|
||||||
|
/* Information about the service provider active on this connection */
|
||||||
|
SPINITDATA spData;
|
||||||
|
|
||||||
|
/* Our service provider */
|
||||||
|
HMODULE hServiceProvider;
|
||||||
|
|
||||||
|
BOOL bConnectionInitialized;
|
||||||
|
} DirectPlay2Data;
|
||||||
|
|
||||||
|
typedef struct tagDirectPlay3Data
|
||||||
|
{
|
||||||
|
BOOL dummy;
|
||||||
|
} DirectPlay3Data;
|
||||||
|
typedef struct tagDirectPlay4Data
|
||||||
|
{
|
||||||
|
BOOL dummy;
|
||||||
|
} DirectPlay4Data;
|
||||||
|
|
||||||
|
#define DP_IMPL_FIELDS \
|
||||||
|
ULONG ulInterfaceRef; \
|
||||||
|
DirectPlayIUnknownData* unk; \
|
||||||
|
DirectPlay2Data* dp2; \
|
||||||
|
DirectPlay3Data* dp3; \
|
||||||
|
DirectPlay4Data* dp4;
|
||||||
|
|
||||||
|
struct IDirectPlay2Impl
|
||||||
|
{
|
||||||
|
ICOM_VFIELD(IDirectPlay2);
|
||||||
|
DP_IMPL_FIELDS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IDirectPlay3Impl
|
||||||
|
{
|
||||||
|
ICOM_VFIELD(IDirectPlay3);
|
||||||
|
DP_IMPL_FIELDS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IDirectPlay4Impl
|
||||||
|
{
|
||||||
|
ICOM_VFIELD(IDirectPlay4);
|
||||||
|
DP_IMPL_FIELDS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Forward declarations of virtual tables */
|
||||||
|
extern ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
|
||||||
|
extern ICOM_VTABLE(IDirectPlay3) directPlay3AVT;
|
||||||
|
extern ICOM_VTABLE(IDirectPlay4) directPlay4AVT;
|
||||||
|
|
||||||
|
extern ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
|
||||||
|
extern ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
|
||||||
|
extern ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
|
||||||
|
|
||||||
|
#endif /* __WINE_DPLAY_GLOBAL_INCLUDED */
|
|
@ -0,0 +1,880 @@
|
||||||
|
/* This contains the implementation of the interface Service
|
||||||
|
* Providers require to communicate with Direct Play
|
||||||
|
*
|
||||||
|
* Copyright 2000 Peter Hunnisett <hunnise@nortelnetworks.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "heap.h"
|
||||||
|
#include "winerror.h"
|
||||||
|
#include "debugtools.h"
|
||||||
|
|
||||||
|
#include "dpinit.h"
|
||||||
|
#include "dplaysp.h"
|
||||||
|
#include "dplay_global.h"
|
||||||
|
#include "name_server.h"
|
||||||
|
#include "dplayx_messages.h"
|
||||||
|
|
||||||
|
#include "dplayx_global.h" /* FIXME: For global hack */
|
||||||
|
|
||||||
|
/* FIXME: Need to add interface locking inside procedures */
|
||||||
|
|
||||||
|
DEFAULT_DEBUG_CHANNEL(dplay);
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
static BOOL DPSP_CreateIUnknown( LPVOID lpSP );
|
||||||
|
static BOOL DPSP_DestroyIUnknown( LPVOID lpSP );
|
||||||
|
static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp );
|
||||||
|
static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP );
|
||||||
|
|
||||||
|
|
||||||
|
/* Predefine the interface */
|
||||||
|
typedef struct IDirectPlaySPImpl IDirectPlaySPImpl;
|
||||||
|
|
||||||
|
typedef struct tagDirectPlaySPIUnknownData
|
||||||
|
{
|
||||||
|
ULONG ulObjRef;
|
||||||
|
CRITICAL_SECTION DPSP_lock;
|
||||||
|
} DirectPlaySPIUnknownData;
|
||||||
|
|
||||||
|
typedef struct tagDirectPlaySPData
|
||||||
|
{
|
||||||
|
LPVOID lpSpRemoteData;
|
||||||
|
DWORD dwSpRemoteDataSize; /* Size of data pointed to by lpSpRemoteData */
|
||||||
|
|
||||||
|
LPVOID lpSpLocalData;
|
||||||
|
DWORD dwSpLocalDataSize; /* Size of data pointed to by lpSpLocalData */
|
||||||
|
|
||||||
|
IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */
|
||||||
|
|
||||||
|
LPVOID lpPlayerData; /* FIXME: Need to figure out how this actually behaves */
|
||||||
|
DWORD dwPlayerDataSize;
|
||||||
|
} DirectPlaySPData;
|
||||||
|
|
||||||
|
#define DPSP_IMPL_FIELDS \
|
||||||
|
ULONG ulInterfaceRef; \
|
||||||
|
DirectPlaySPIUnknownData* unk; \
|
||||||
|
DirectPlaySPData* sp;
|
||||||
|
|
||||||
|
struct IDirectPlaySPImpl
|
||||||
|
{
|
||||||
|
ICOM_VFIELD(IDirectPlaySP);
|
||||||
|
DPSP_IMPL_FIELDS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Forward declaration of virtual tables */
|
||||||
|
static ICOM_VTABLE(IDirectPlaySP) directPlaySPVT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Create the SP interface */
|
||||||
|
extern
|
||||||
|
HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
|
||||||
|
{
|
||||||
|
TRACE( " for %s\n", debugstr_guid( riid ) );
|
||||||
|
|
||||||
|
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
sizeof( IDirectPlaySPImpl ) );
|
||||||
|
|
||||||
|
if( *ppvObj == NULL )
|
||||||
|
{
|
||||||
|
return DPERR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,*ppvObj);
|
||||||
|
ICOM_VTBL(This) = &directPlaySPVT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Unsupported interface */
|
||||||
|
HeapFree( GetProcessHeap(), 0, *ppvObj );
|
||||||
|
*ppvObj = NULL;
|
||||||
|
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize it */
|
||||||
|
if( DPSP_CreateIUnknown( *ppvObj ) &&
|
||||||
|
DPSP_CreateDirectPlaySP( *ppvObj, dp )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize failed, destroy it */
|
||||||
|
DPSP_DestroyDirectPlaySP( *ppvObj );
|
||||||
|
DPSP_DestroyIUnknown( *ppvObj );
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, *ppvObj );
|
||||||
|
*ppvObj = NULL;
|
||||||
|
|
||||||
|
return DPERR_NOMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL DPSP_CreateIUnknown( LPVOID lpSP )
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,lpSP);
|
||||||
|
|
||||||
|
This->unk = (DirectPlaySPIUnknownData*)HeapAlloc( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
sizeof( *(This->unk) ) );
|
||||||
|
|
||||||
|
if ( This->unk == NULL )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeCriticalSection( &This->unk->DPSP_lock );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL DPSP_DestroyIUnknown( LPVOID lpSP )
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,lpSP);
|
||||||
|
|
||||||
|
DeleteCriticalSection( &This->unk->DPSP_lock );
|
||||||
|
HeapFree( GetProcessHeap(), 0, This->unk );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp )
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,lpSP);
|
||||||
|
|
||||||
|
This->sp = (DirectPlaySPData*)HeapAlloc( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
sizeof( *(This->sp) ) );
|
||||||
|
|
||||||
|
if ( This->sp == NULL )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
This->sp->dplay = dp;
|
||||||
|
|
||||||
|
/* Normally we should be keeping a reference, but since only the dplay
|
||||||
|
* interface that created us can destroy us, we do not keep a reference
|
||||||
|
* to it (ie we'd be stuck with always having one reference to the dplay
|
||||||
|
* object, and hence us, around).
|
||||||
|
* NOTE: The dp object does reference count us.
|
||||||
|
*/
|
||||||
|
/* IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp ); */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP )
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,lpSP);
|
||||||
|
|
||||||
|
/* Normally we should be keeping a reference, but since only the dplay
|
||||||
|
* interface that created us can destroy us, we do not keep a reference
|
||||||
|
* to it (ie we'd be stuck with always having one reference to the dplay
|
||||||
|
* object, and hence us, around).
|
||||||
|
* NOTE: The dp object does reference count us.
|
||||||
|
*/
|
||||||
|
/*IDirectPlayX_Release( (LPDIRECTPLAY2)This->sp->dplay ); */
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
|
||||||
|
HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
|
||||||
|
|
||||||
|
/* FIXME: Need to delete player queue */
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, This->sp );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interface implementation */
|
||||||
|
|
||||||
|
static HRESULT WINAPI DPSP_QueryInterface
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
REFIID riid,
|
||||||
|
LPVOID* ppvObj )
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
|
||||||
|
|
||||||
|
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
sizeof( IDirectPlaySPImpl ) );
|
||||||
|
|
||||||
|
if( *ppvObj == NULL )
|
||||||
|
{
|
||||||
|
return DPERR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory( *ppvObj, iface, sizeof( IDirectPlaySPImpl ) );
|
||||||
|
(*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0;
|
||||||
|
|
||||||
|
if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,*ppvObj);
|
||||||
|
ICOM_VTBL(This) = &directPlaySPVT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Unsupported interface */
|
||||||
|
HeapFree( GetProcessHeap(), 0, *ppvObj );
|
||||||
|
*ppvObj = NULL;
|
||||||
|
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI DPSP_AddRef
|
||||||
|
( LPDIRECTPLAYSP iface )
|
||||||
|
{
|
||||||
|
ULONG ulInterfaceRefCount, ulObjRefCount;
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
ulObjRefCount = InterlockedIncrement( &This->unk->ulObjRef );
|
||||||
|
ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef );
|
||||||
|
|
||||||
|
TRACE( "ref count incremented to %lu:%lu for %p\n",
|
||||||
|
ulInterfaceRefCount, ulObjRefCount, This );
|
||||||
|
|
||||||
|
return ulObjRefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI DPSP_Release
|
||||||
|
( LPDIRECTPLAYSP iface )
|
||||||
|
{
|
||||||
|
ULONG ulInterfaceRefCount, ulObjRefCount;
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
ulObjRefCount = InterlockedDecrement( &This->unk->ulObjRef );
|
||||||
|
ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef );
|
||||||
|
|
||||||
|
TRACE( "ref count decremented to %lu:%lu for %p\n",
|
||||||
|
ulInterfaceRefCount, ulObjRefCount, This );
|
||||||
|
|
||||||
|
/* Deallocate if this is the last reference to the object */
|
||||||
|
if( ulObjRefCount == 0 )
|
||||||
|
{
|
||||||
|
DPSP_DestroyDirectPlaySP( This );
|
||||||
|
DPSP_DestroyIUnknown( This );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulInterfaceRefCount == 0 )
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, This );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulInterfaceRefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
LPCWSTR lpSection,
|
||||||
|
LPCWSTR lpKey,
|
||||||
|
LPCVOID lpData,
|
||||||
|
DWORD dwDataSize,
|
||||||
|
DWORD dwMaxEntries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
FIXME( "(%p)->(%p,%p%p,0x%08lx,0x%08lx): stub\n",
|
||||||
|
This, lpSection, lpKey, lpData, dwDataSize, dwMaxEntries );
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_CreateAddress
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
REFGUID guidSP,
|
||||||
|
REFGUID guidDataType,
|
||||||
|
LPCVOID lpData,
|
||||||
|
DWORD dwDataSize,
|
||||||
|
LPVOID lpAddress,
|
||||||
|
LPDWORD lpdwAddressSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
FIXME( "(%p)->(%s,%s,%p,0x%08lx,%p,%p): stub\n",
|
||||||
|
This, debugstr_guid(guidSP), debugstr_guid(guidDataType),
|
||||||
|
lpData, dwDataSize, lpAddress, lpdwAddressSize );
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_EnumAddress
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
|
||||||
|
LPCVOID lpAddress,
|
||||||
|
DWORD dwAddressSize,
|
||||||
|
LPVOID lpContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
TRACE( "(%p)->(%p,%p,0x%08lx,%p)\n",
|
||||||
|
This, lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
|
||||||
|
|
||||||
|
DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
LPCWSTR lpSection,
|
||||||
|
LPCWSTR lpKey,
|
||||||
|
LPENUMMRUCALLBACK lpEnumMRUCallback,
|
||||||
|
LPVOID lpContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
FIXME( "(%p)->(%p,%p,%p,%p,): stub\n",
|
||||||
|
This, lpSection, lpKey, lpEnumMRUCallback, lpContext );
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_GetPlayerFlags
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
DPID idPlayer,
|
||||||
|
LPDWORD lpdwPlayerFlags
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
FIXME( "(%p)->(0x%08lx,%p): stub\n",
|
||||||
|
This, idPlayer, lpdwPlayerFlags );
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
DPID idPlayer,
|
||||||
|
LPVOID* lplpData,
|
||||||
|
LPDWORD lpdwDataSize,
|
||||||
|
DWORD dwFlags
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
||||||
|
FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n",
|
||||||
|
This, idPlayer, lplpData, lpdwDataSize, dwFlags );
|
||||||
|
|
||||||
|
*lplpData = This->sp->lpPlayerData;
|
||||||
|
*lpdwDataSize = This->sp->dwPlayerDataSize;
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
LPVOID lpMessageBody,
|
||||||
|
DWORD dwMessageBodySize,
|
||||||
|
LPVOID lpMessageHeader
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LPDPMSG_SENDENVELOPE lpMsg = (LPDPMSG_SENDENVELOPE)lpMessageBody;
|
||||||
|
HRESULT hr = DPERR_GENERIC;
|
||||||
|
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
||||||
|
FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n",
|
||||||
|
This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
|
||||||
|
|
||||||
|
TRACE( "Incomming message has envelope of 0x%08lx, %u, %u\n",
|
||||||
|
lpMsg->dwMagic, lpMsg->wCommandId, lpMsg->wVersion );
|
||||||
|
|
||||||
|
if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG )
|
||||||
|
{
|
||||||
|
FIXME( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( lpMsg->wCommandId )
|
||||||
|
{
|
||||||
|
case DPMSGCMD_ENUMSESSIONSREQUEST:
|
||||||
|
{
|
||||||
|
DPSP_REPLYDATA data;
|
||||||
|
|
||||||
|
data.lpSPMessageHeader = lpMessageHeader;
|
||||||
|
data.idNameServer = 0;
|
||||||
|
data.lpISP = iface;
|
||||||
|
|
||||||
|
NS_ReplyToEnumSessionsRequest( lpMessageBody, &data, This->sp->dplay );
|
||||||
|
|
||||||
|
hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
|
||||||
|
|
||||||
|
if( FAILED(hr) )
|
||||||
|
{
|
||||||
|
ERR( "Reply failed 0x%08lx\n", hr );
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPMSGCMD_ENUMSESSIONSREPLY:
|
||||||
|
{
|
||||||
|
NS_SetRemoteComputerAsNameServer( lpMessageHeader,
|
||||||
|
This->sp->dplay->dp2->spData.dwSPHeaderSize,
|
||||||
|
(LPDPMSG_ENUMSESSIONSREPLY)lpMessageBody,
|
||||||
|
This->sp->dplay->dp2->lpNameServerData );
|
||||||
|
|
||||||
|
/* No reply expected */
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
FIXME( "Unknown Command of %u\n", lpMsg->wCommandId );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
HRESULT hr = DP_OK;
|
||||||
|
HANDLE hReceiveEvent = 0;
|
||||||
|
/* FIXME: Aquire some sort of interface lock */
|
||||||
|
/* FIXME: Need some sort of context for this callback. Need to determine
|
||||||
|
* how this is actually done with the SP
|
||||||
|
*/
|
||||||
|
/* FIXME: Add in size checks for all messages to determine corrupt messages */ /* FIXME: Who needs to delete the message when done? */
|
||||||
|
/* FIXME: Does this get invoked as soon as the message arrives, or as soon
|
||||||
|
* as it's removed from the queue (or peeked in queue?)
|
||||||
|
*/
|
||||||
|
switch( lpMsg->dwType )
|
||||||
|
{
|
||||||
|
case DPSYS_CREATEPLAYERORGROUP:
|
||||||
|
{
|
||||||
|
LPDPMSG_CREATEPLAYERORGROUP msg = (LPDPMSG_CREATEPLAYERORGROUP)lpMsg;
|
||||||
|
|
||||||
|
if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
|
||||||
|
{
|
||||||
|
hr = DP_IF_CreatePlayer( This, lpMessageHeader, msg->dpId,
|
||||||
|
&msg->dpnName, 0, msg->lpData,
|
||||||
|
msg->dwDataSize, msg->dwFlags, ... );
|
||||||
|
}
|
||||||
|
else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
|
||||||
|
{
|
||||||
|
/* Group in group situation? */
|
||||||
|
if( msg->dpIdParent == DPID_NOPARENT_GROUP )
|
||||||
|
{
|
||||||
|
hr = DP_IF_CreateGroup( This, lpMessageHeader, msg->dpId,
|
||||||
|
&msg->dpnName, 0, msg->lpData,
|
||||||
|
msg->dwDataSize, msg->dwFlags, ... );
|
||||||
|
}
|
||||||
|
else /* Group in Group */
|
||||||
|
{
|
||||||
|
hr = DP_IF_CreateGroupInGroup( This, lpMessageHeader, msg->dpIdParent,
|
||||||
|
&msg->dpnName, 0, msg->lpData,
|
||||||
|
msg->dwDataSize, msg->dwFlags, ... );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* Hmmm? */
|
||||||
|
{
|
||||||
|
ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_DESTROYPLAYERORGROUP:
|
||||||
|
{
|
||||||
|
LPDPMSG_DESTROYPLAYERORGROUP msg = (LPDPMSG_DESTROYPLAYERORGROUP)lpMsg;
|
||||||
|
|
||||||
|
if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
|
||||||
|
{
|
||||||
|
hr = DP_IF_DestroyPlayer( This, msg->dpId, ... );
|
||||||
|
}
|
||||||
|
else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
|
||||||
|
{
|
||||||
|
hr = DP_IF_DestroyGroup( This, msg->dpId, ... );
|
||||||
|
}
|
||||||
|
else /* Hmmm? */
|
||||||
|
{
|
||||||
|
ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_ADDPLAYERTOGROUP:
|
||||||
|
{
|
||||||
|
LPDPMSG_ADDPLAYERTOGROUP msg = (LPDPMSG_ADDPLAYERTOGROUP)lpMsg;
|
||||||
|
|
||||||
|
hr = DP_IF_AddPlayerToGroup( This, msg->dpIdGroup, msg->dpIdPlayer, ... );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_DELETEPLAYERFROMGROUP:
|
||||||
|
{
|
||||||
|
LPDPMSG_DELETEPLAYERFROMGROUP msg = (LPDPMSG_DELETEPLAYERFROMGROUP)lpMsg;
|
||||||
|
|
||||||
|
hr = DP_IF_DeletePlayerFromGroup( This, msg->dpIdGroup, msg->dpIdPlayer,
|
||||||
|
... );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_SESSIONLOST:
|
||||||
|
{
|
||||||
|
LPDPMSG_SESSIONLOST msg = (LPDPMSG_SESSIONLOST)lpMsg;
|
||||||
|
|
||||||
|
FIXME( "DPSYS_SESSIONLOST not handled\n" );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_HOST:
|
||||||
|
{
|
||||||
|
LPDPMSG_HOST msg = (LPDPMSG_HOST)lpMsg;
|
||||||
|
|
||||||
|
FIXME( "DPSYS_HOST not handled\n" );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_SETPLAYERORGROUPDATA:
|
||||||
|
{
|
||||||
|
LPDPMSG_SETPLAYERORGROUPDATA msg = (LPDPMSG_SETPLAYERORGROUPDATA)lpMsg;
|
||||||
|
|
||||||
|
if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
|
||||||
|
{
|
||||||
|
hr = DP_IF_SetPlayerData( This, msg->dpId, msg->lpData, msg->dwDataSize, DPSET_REMOTE, ... );
|
||||||
|
}
|
||||||
|
else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
|
||||||
|
{
|
||||||
|
hr = DP_IF_SetGroupData( This, msg->dpId, msg->lpData, msg->dwDataSize,
|
||||||
|
DPSET_REMOTE, ... );
|
||||||
|
}
|
||||||
|
else /* Hmmm? */
|
||||||
|
{
|
||||||
|
ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_SETPLAYERORGROUPNAME:
|
||||||
|
{
|
||||||
|
LPDPMSG_SETPLAYERORGROUPNAME msg = (LPDPMSG_SETPLAYERORGROUPNAME)lpMsg;
|
||||||
|
|
||||||
|
if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
|
||||||
|
{
|
||||||
|
hr = DP_IF_SetPlayerName( This, msg->dpId, msg->dpnName, ... );
|
||||||
|
}
|
||||||
|
else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
|
||||||
|
{
|
||||||
|
hr = DP_IF_SetGroupName( This, msg->dpId, msg->dpnName, ... );
|
||||||
|
}
|
||||||
|
else /* Hmmm? */
|
||||||
|
{
|
||||||
|
ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_SETSESSIONDESC;
|
||||||
|
{
|
||||||
|
LPDPMSG_SETSESSIONDESC msg = (LPDPMSG_SETSESSIONDESC)lpMsg;
|
||||||
|
|
||||||
|
hr = DP_IF_SetSessionDesc( This, &msg->dpDesc );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_ADDGROUPTOGROUP:
|
||||||
|
{
|
||||||
|
LPDPMSG_ADDGROUPTOGROUP msg = (LPDPMSG_ADDGROUPTOGROUP)lpMsg;
|
||||||
|
|
||||||
|
hr = DP_IF_AddGroupToGroup( This, msg->dpIdParentGroup, msg->dpIdGroup,
|
||||||
|
... );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_DELETEGROUPFROMGROUP:
|
||||||
|
{
|
||||||
|
LPDPMSG_DELETEGROUPFROMGROUP msg = (LPDPMSG_DELETEGROUPFROMGROUP)lpMsg;
|
||||||
|
|
||||||
|
hr = DP_IF_DeleteGroupFromGroup( This, msg->dpIdParentGroup,
|
||||||
|
msg->dpIdGroup, ... );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_SECUREMESSAGE:
|
||||||
|
{
|
||||||
|
LPDPMSG_SECUREMESSAGE msg = (LPDPMSG_SECUREMESSAGE)lpMsg;
|
||||||
|
|
||||||
|
FIXME( "DPSYS_SECUREMESSAGE not implemented\n" );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_STARTSESSION:
|
||||||
|
{
|
||||||
|
LPDPMSG_STARTSESSION msg = (LPDPMSG_STARTSESSION)lpMsg;
|
||||||
|
|
||||||
|
FIXME( "DPSYS_STARTSESSION not implemented\n" );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_CHAT:
|
||||||
|
{
|
||||||
|
LPDPMSG_CHAT msg = (LPDPMSG_CHAT)lpMsg;
|
||||||
|
|
||||||
|
FIXME( "DPSYS_CHAT not implemeneted\n" );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_SETGROUPOWNER:
|
||||||
|
{
|
||||||
|
LPDPMSG_SETGROUPOWNER msg = (LPDPMSG_SETGROUPOWNER)lpMsg;
|
||||||
|
|
||||||
|
FIXME( "DPSYS_SETGROUPOWNER not implemented\n" );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DPSYS_SENDCOMPLETE:
|
||||||
|
{
|
||||||
|
LPDPMSG_SENDCOMPLETE msg = (LPDPMSG_SENDCOMPLETE)lpMsg;
|
||||||
|
|
||||||
|
FIXME( "DPSYS_SENDCOMPLETE not implemented\n" );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
/* NOTE: This should be a user defined type. There is nothing that we
|
||||||
|
* need to do with it except queue it.
|
||||||
|
*/
|
||||||
|
TRACE( "Received user message type(?) 0x%08lx through SP.\n",
|
||||||
|
lpMsg->dwType );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FIXME( "Queue message in the receive queue. Need some context data!\n" );
|
||||||
|
|
||||||
|
if( FAILED(hr) )
|
||||||
|
{
|
||||||
|
ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg->dwType );
|
||||||
|
}
|
||||||
|
/* If a receieve event was registered for this player, invoke it */
|
||||||
|
if( hReceiveEvent )
|
||||||
|
{
|
||||||
|
SetEvent( hReceiveEvent );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
DPID idPlayer,
|
||||||
|
LPVOID lpData,
|
||||||
|
DWORD dwDataSize,
|
||||||
|
DWORD dwFlags
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
/* FIXME: I'm not sure if this stuff should be associated with the DPlay
|
||||||
|
* player lists. How else would this stuff get deleted?
|
||||||
|
*/
|
||||||
|
|
||||||
|
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
||||||
|
FIXME( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx): stub\n",
|
||||||
|
This, idPlayer, lpData, dwDataSize, dwFlags );
|
||||||
|
|
||||||
|
This->sp->lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
|
||||||
|
|
||||||
|
This->sp->dwPlayerDataSize = dwDataSize;
|
||||||
|
CopyMemory( This->sp->lpPlayerData, lpData, dwDataSize );
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
LPCDPCOMPOUNDADDRESSELEMENT lpElements,
|
||||||
|
DWORD dwElementCount,
|
||||||
|
LPVOID lpAddress,
|
||||||
|
LPDWORD lpdwAddressSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
FIXME( "(%p)->(%p,0x%08lx,%p,%p): stub\n",
|
||||||
|
This, lpElements, dwElementCount, lpAddress, lpdwAddressSize );
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
LPVOID* lplpData,
|
||||||
|
LPDWORD lpdwDataSize,
|
||||||
|
DWORD dwFlags
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
||||||
|
TRACE( "(%p)->(%p,%p,0x%08lx)\n",
|
||||||
|
This, lplpData, lpdwDataSize, dwFlags );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* This is what the documentation says... */
|
||||||
|
if( dwFlags != 0 )
|
||||||
|
{
|
||||||
|
return DPERR_INVALIDPARAMS;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* ... but most service providers call this with 1 */
|
||||||
|
/* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
|
||||||
|
* thing?
|
||||||
|
*/
|
||||||
|
if( dwFlags != 0 )
|
||||||
|
{
|
||||||
|
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Yes, we're supposed to return a pointer to the memory we have stored! */
|
||||||
|
if( dwFlags == DPSET_REMOTE )
|
||||||
|
{
|
||||||
|
*lpdwDataSize = This->sp->dwSpRemoteDataSize;
|
||||||
|
*lplpData = This->sp->lpSpRemoteData;
|
||||||
|
}
|
||||||
|
else if( dwFlags == DPSET_LOCAL )
|
||||||
|
{
|
||||||
|
*lpdwDataSize = This->sp->dwSpLocalDataSize;
|
||||||
|
*lplpData = This->sp->lpSpLocalData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
LPVOID lpData,
|
||||||
|
DWORD dwDataSize,
|
||||||
|
DWORD dwFlags
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LPVOID lpSpData;
|
||||||
|
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() );
|
||||||
|
TRACE( "(%p)->(%p,0x%08lx,0x%08lx)\n",
|
||||||
|
This, lpData, dwDataSize, dwFlags );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* This is what the documentation says... */
|
||||||
|
if( dwFlags != 0 )
|
||||||
|
{
|
||||||
|
return DPERR_INVALIDPARAMS;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* ... but most service providers call this with 1 */
|
||||||
|
/* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
|
||||||
|
* thing?
|
||||||
|
*/
|
||||||
|
if( dwFlags != 0 )
|
||||||
|
{
|
||||||
|
FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( dwFlags == DPSET_REMOTE )
|
||||||
|
{
|
||||||
|
lpSpData = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, dwDataSize );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory( lpSpData, lpData, dwDataSize );
|
||||||
|
|
||||||
|
/* If we have data already allocated, free it and replace it */
|
||||||
|
if( dwFlags == DPSET_REMOTE )
|
||||||
|
{
|
||||||
|
/* FIXME: This doesn't strictly make sense as there is no means to share
|
||||||
|
* this shared data. Must be misinterpreting something...
|
||||||
|
*/
|
||||||
|
if( This->sp->lpSpRemoteData )
|
||||||
|
{
|
||||||
|
DPLAYX_PrivHeapFree( This->sp->lpSpRemoteData );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: dwDataSize is also stored in the heap structure */
|
||||||
|
This->sp->dwSpRemoteDataSize = dwDataSize;
|
||||||
|
This->sp->lpSpRemoteData = lpSpData;
|
||||||
|
}
|
||||||
|
else if ( dwFlags == DPSET_LOCAL )
|
||||||
|
{
|
||||||
|
if( This->sp->lpSpLocalData )
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
|
||||||
|
}
|
||||||
|
|
||||||
|
This->sp->lpSpLocalData = lpSpData;
|
||||||
|
This->sp->dwSpLocalDataSize = dwDataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID WINAPI IDirectPlaySPImpl_SendComplete
|
||||||
|
( LPDIRECTPLAYSP iface,
|
||||||
|
LPVOID unknownA,
|
||||||
|
DWORD unknownB
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ICOM_THIS(IDirectPlaySPImpl,iface);
|
||||||
|
|
||||||
|
FIXME( "(%p)->(%p,0x%08lx): stub\n",
|
||||||
|
This, unknownA, unknownB );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct ICOM_VTABLE(IDirectPlaySP) directPlaySPVT =
|
||||||
|
{
|
||||||
|
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
||||||
|
|
||||||
|
DPSP_QueryInterface,
|
||||||
|
DPSP_AddRef,
|
||||||
|
DPSP_Release,
|
||||||
|
|
||||||
|
IDirectPlaySPImpl_AddMRUEntry,
|
||||||
|
IDirectPlaySPImpl_CreateAddress,
|
||||||
|
IDirectPlaySPImpl_EnumAddress,
|
||||||
|
IDirectPlaySPImpl_EnumMRUEntries,
|
||||||
|
IDirectPlaySPImpl_GetPlayerFlags,
|
||||||
|
IDirectPlaySPImpl_GetSPPlayerData,
|
||||||
|
IDirectPlaySPImpl_HandleMessage,
|
||||||
|
IDirectPlaySPImpl_SetSPPlayerData,
|
||||||
|
IDirectPlaySPImpl_CreateCompoundAddress,
|
||||||
|
IDirectPlaySPImpl_GetSPData,
|
||||||
|
IDirectPlaySPImpl_SetSPData,
|
||||||
|
IDirectPlaySPImpl_SendComplete
|
||||||
|
};
|
|
@ -0,0 +1,337 @@
|
||||||
|
#ifndef __WINE_DIRECT_PLAY_SP_H
|
||||||
|
#define __WINE_DIRECT_PLAY_SP_H
|
||||||
|
|
||||||
|
#include "dplay.h"
|
||||||
|
#include "dplobby.h"
|
||||||
|
|
||||||
|
/* GUID for IDirectPlaySP {0C9F6360-CC61-11cf-ACEC-00AA006886E3} */
|
||||||
|
DEFINE_GUID(IID_IDirectPlaySP, 0xc9f6360, 0xcc61, 0x11cf, 0xac, 0xec, 0x0, 0xaa, 0x0, 0x68, 0x86, 0xe3);
|
||||||
|
typedef struct IDirectPlaySP IDirectPlaySP, *LPDIRECTPLAYSP;
|
||||||
|
|
||||||
|
|
||||||
|
typedef BOOL (CALLBACK* LPENUMMRUCALLBACK)( LPCVOID lpData,
|
||||||
|
DWORD dwDataSize,
|
||||||
|
LPVOID lpContext );
|
||||||
|
|
||||||
|
/* For SP. Top 16 bits is dplay, bottom 16 is SP */
|
||||||
|
#define DPSP_MAJORVERSION 0x00060000
|
||||||
|
#define DPSP_DX5VERSION 0x00050000
|
||||||
|
#define DPSP_DX3VERSION 0x00040000
|
||||||
|
|
||||||
|
#define DPSP_MAJORVERSIONMASK 0xFFFF0000
|
||||||
|
#define DPSP_MINORVERSIONMASK 0x0000FFFF
|
||||||
|
|
||||||
|
|
||||||
|
/* Some flags */
|
||||||
|
#define DPLAYI_PLAYER_SYSPLAYER 0x00000001
|
||||||
|
#define DPLAYI_PLAYER_NAMESRVR 0x00000002
|
||||||
|
#define DPLAYI_PLAYER_PLAYERINGROUP 0x00000004
|
||||||
|
#define DPLAYI_PLAYER_PLAYERLOCAL 0x00000008
|
||||||
|
#define DPLAYI_GROUP_SYSGROUP 0x00000020
|
||||||
|
#define DPLAYI_GROUP_DPLAYOWNS 0x00000040
|
||||||
|
#define DPLAYI_PLAYER_APPSERVER 0x00000080
|
||||||
|
#define DPLAYI_GROUP_HIDDEN 0x00000400
|
||||||
|
|
||||||
|
/* Define the COM interface */
|
||||||
|
#define ICOM_INTERFACE IDirectPlaySP
|
||||||
|
#define IDirectPlaySP_METHODS \
|
||||||
|
ICOM_METHOD5(HRESULT,AddMRUEntry, LPCWSTR,lpSection, LPCWSTR,lpKey, LPCVOID,lpData, DWORD,dwDataSize, DWORD,dwMaxEntries ) \
|
||||||
|
ICOM_METHOD6(HRESULT,CreateAddress, REFGUID,guidSP, REFGUID,guidDataType, LPCVOID,lpData, DWORD,dwDataSize, LPVOID,lpAddress,LPDWORD,lpdwAddressSize) \
|
||||||
|
ICOM_METHOD4(HRESULT,EnumAddress, LPDPENUMADDRESSCALLBACK,lpEnumAddressCallback, LPCVOID,lpAddress, DWORD,dwAddressSize, LPVOID,lpContext ) \
|
||||||
|
ICOM_METHOD4(HRESULT,EnumMRUEntries, LPCWSTR,lpSection, LPCWSTR,lpKey, LPENUMMRUCALLBACK,lpEnumMRUCallback, LPVOID,lpContext ) \
|
||||||
|
ICOM_METHOD2(HRESULT,GetPlayerFlags, DPID,idPlayer, LPDWORD,lpdwPlayerFlags ) \
|
||||||
|
ICOM_METHOD4(HRESULT,GetSPPlayerData, DPID,idPlayer, LPVOID*,lplpData, LPDWORD,lpdwDataSize, DWORD,dwFlags ) \
|
||||||
|
ICOM_METHOD3(HRESULT,HandleMessage, LPVOID,lpMessageBody, DWORD,dwMessageBodySize, LPVOID,lpMessageHeader ) \
|
||||||
|
ICOM_METHOD4(HRESULT,SetSPPlayerData, DPID,idPlayer, LPVOID,lpData, DWORD,dwDataSize, DWORD,dwFlags ) \
|
||||||
|
ICOM_METHOD4(HRESULT,CreateCompoundAddress, LPCDPCOMPOUNDADDRESSELEMENT,lpElements, DWORD,dwElementCount, LPVOID,lpAddress, LPDWORD,lpdwAddressSize ) \
|
||||||
|
ICOM_METHOD3(HRESULT,GetSPData, LPVOID*,lplpData, LPDWORD,dwDataSize, DWORD,dwFlags ) \
|
||||||
|
ICOM_METHOD3(HRESULT,SetSPData, LPVOID,lpData, DWORD,dwDataSize, DWORD,dwFlags ) \
|
||||||
|
ICOM_METHOD2(VOID,SendComplete, LPVOID,, DWORD, )
|
||||||
|
|
||||||
|
#define IDirectPlaySP_IMETHODS \
|
||||||
|
IUnknown_IMETHODS \
|
||||||
|
IDirectPlaySP_METHODS
|
||||||
|
|
||||||
|
ICOM_DEFINE(IDirectPlaySP,IUnknown)
|
||||||
|
#undef ICOM_INTERFACE
|
||||||
|
|
||||||
|
/*** IUnknown methods ***/
|
||||||
|
#define IDirectPlaySP_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
|
||||||
|
#define IDirectPlaySP_AddRef(p) ICOM_CALL (AddRef,p)
|
||||||
|
#define IDirectPlaySP_Release(p) ICOM_CALL (Release,p)
|
||||||
|
/*** IDirectPlaySP methods ***/
|
||||||
|
#define IDirectPlaySP_AddMRUEntry ICOM_CALL5(AddMRUEntry,p,a,b,c,d,e)
|
||||||
|
#define IDirectPlaySP_CreateAddress ICOM_CALL6(CreateAddress,p,a,b,c,d,e,f)
|
||||||
|
#define IDirectPlaySP_EnumAddress ICOM_CALL4(EnumAddress,p,a,b,c,d)
|
||||||
|
#define IDirectPlaySP_EnumMRUEntries ICOM_CALL4(EnumMRUEntries,p,a,b,c,d)
|
||||||
|
#define IDirectPlaySP_GetPlayerFlags ICOM_CALL2(GetPlayerFlags,p,a,b)
|
||||||
|
#define IDirectPlaySP_GetSPPlayerData ICOM_CALL4(GetSPPlayerData,p,a,b,c,d)
|
||||||
|
#define IDirectPlaySP_HandleMessage ICOM_CALL3(HandleMessage,p,a,b,c)
|
||||||
|
#define IDirectPlaySP_SetSPPlayerData ICOM_CALL4(SetSPPlayerData,p,a,b,c,d)
|
||||||
|
#define IDirectPlaySP_CreateCompoundAddress ICOM_CALL4(CreateCompoundAddress,p,a,b,c,d)
|
||||||
|
#define IDirectPlaySP_GetSPData ICOM_CALL3(GetSPData,p,a,b,c)
|
||||||
|
#define IDirectPlaySP_SetSPData ICOM_CALL3(SetSPData,p,a,b,c)
|
||||||
|
#define IDirectPlaySP_SendComplete ICOM_CALL2(SendComplete,p,a,b)
|
||||||
|
|
||||||
|
/* SP Callback stuff */
|
||||||
|
|
||||||
|
typedef struct tagDPSP_ADDPLAYERTOGROUPDATA
|
||||||
|
{
|
||||||
|
DPID idPlayer;
|
||||||
|
DPID idGroup;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_ADDPLAYERTOGROUPDATA, *LPDPSP_ADDPLAYERTOGROUPDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_CLOSEDATA
|
||||||
|
{
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_CLOSEDATA, *LPDPSP_CLOSEDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_CREATEGROUPDATA
|
||||||
|
{
|
||||||
|
DPID idGroup;
|
||||||
|
DWORD dwFlags;
|
||||||
|
LPVOID lpSPMessageHeader;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_CREATEGROUPDATA, *LPDPSP_CREATEGROUPDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_CREATEPLAYERDATA
|
||||||
|
{
|
||||||
|
DPID idPlayer;
|
||||||
|
DWORD dwFlags;
|
||||||
|
LPVOID lpSPMessageHeader;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_CREATEPLAYERDATA, *LPDPSP_CREATEPLAYERDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_DELETEGROUPDATA
|
||||||
|
{
|
||||||
|
DPID idGroup;
|
||||||
|
DWORD dwFlags;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_DELETEGROUPDATA, *LPDPSP_DELETEGROUPDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_DELETEPLAYERDATA
|
||||||
|
{
|
||||||
|
DPID idPlayer;
|
||||||
|
DWORD dwFlags;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_DELETEPLAYERDATA, *LPDPSP_DELETEPLAYERDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_ENUMSESSIONSDATA
|
||||||
|
{
|
||||||
|
LPVOID lpMessage;
|
||||||
|
DWORD dwMessageSize;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
BOOL bReturnStatus;
|
||||||
|
} DPSP_ENUMSESSIONSDATA, *LPDPSP_ENUMSESSIONSDATA;
|
||||||
|
|
||||||
|
typedef struct _DPSP_GETADDRESSDATA
|
||||||
|
{
|
||||||
|
DPID idPlayer;
|
||||||
|
DWORD dwFlags;
|
||||||
|
LPDPADDRESS lpAddress;
|
||||||
|
LPDWORD lpdwAddressSize;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_GETADDRESSDATA, *LPDPSP_GETADDRESSDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_GETADDRESSCHOICESDATA
|
||||||
|
{
|
||||||
|
LPDPADDRESS lpAddress;
|
||||||
|
LPDWORD lpdwAddressSize;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_GETADDRESSCHOICESDATA, *LPDPSP_GETADDRESSCHOICESDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_GETCAPSDATA
|
||||||
|
{
|
||||||
|
DPID idPlayer;
|
||||||
|
LPDPCAPS lpCaps;
|
||||||
|
DWORD dwFlags;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_GETCAPSDATA, *LPDPSP_GETCAPSDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_OPENDATA
|
||||||
|
{
|
||||||
|
BOOL bCreate;
|
||||||
|
LPVOID lpSPMessageHeader;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
BOOL bReturnStatus;
|
||||||
|
DWORD dwOpenFlags;
|
||||||
|
DWORD dwSessionFlags;
|
||||||
|
} DPSP_OPENDATA, *LPDPSP_OPENDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_REMOVEPLAYERFROMGROUPDATA
|
||||||
|
{
|
||||||
|
DPID idPlayer;
|
||||||
|
DPID idGroup;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_REMOVEPLAYERFROMGROUPDATA, *LPDPSP_REMOVEPLAYERFROMGROUPDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_REPLYDATA
|
||||||
|
{
|
||||||
|
LPVOID lpSPMessageHeader;
|
||||||
|
LPVOID lpMessage;
|
||||||
|
DWORD dwMessageSize;
|
||||||
|
DPID idNameServer;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_REPLYDATA, *LPDPSP_REPLYDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_SENDDATA
|
||||||
|
{
|
||||||
|
DWORD dwFlags;
|
||||||
|
DPID idPlayerTo;
|
||||||
|
DPID idPlayerFrom;
|
||||||
|
LPVOID lpMessage;
|
||||||
|
DWORD dwMessageSize;
|
||||||
|
BOOL bSystemMessage;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_SENDDATA, *LPDPSP_SENDDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_SENDTOGROUPDATA
|
||||||
|
{
|
||||||
|
DWORD dwFlags;
|
||||||
|
DPID idGroupTo;
|
||||||
|
DPID idPlayerFrom;
|
||||||
|
LPVOID lpMessage;
|
||||||
|
DWORD dwMessageSize;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_SENDTOGROUPDATA, *LPDPSP_SENDTOGROUPDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_SENDEXDATA
|
||||||
|
{
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
DWORD dwFlags;
|
||||||
|
DPID idPlayerTo;
|
||||||
|
DPID idPlayerFrom;
|
||||||
|
LPSGBUFFER lpSendBuffers;
|
||||||
|
DWORD cBuffers;
|
||||||
|
DWORD dwMessageSize;
|
||||||
|
DWORD dwPriority;
|
||||||
|
DWORD dwTimeout;
|
||||||
|
LPVOID lpDPContext;
|
||||||
|
LPDWORD lpdwSPMsgID;
|
||||||
|
BOOL bSystemMessage;
|
||||||
|
} DPSP_SENDEXDATA, *LPDPSP_SENDEXDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_SENDTOGROUPEXDATA
|
||||||
|
{
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
DWORD dwFlags;
|
||||||
|
DPID idGroupTo;
|
||||||
|
DPID idPlayerFrom;
|
||||||
|
LPSGBUFFER lpSendBuffers;
|
||||||
|
DWORD cBuffers;
|
||||||
|
DWORD dwMessageSize;
|
||||||
|
DWORD dwPriority;
|
||||||
|
DWORD dwTimeout;
|
||||||
|
LPVOID lpDPContext;
|
||||||
|
LPDWORD lpdwSPMsgID;
|
||||||
|
} DPSP_SENDTOGROUPEXDATA, *LPDPSP_SENDTOGROUPEXDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_GETMESSAGEQUEUEDATA
|
||||||
|
{
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
DWORD dwFlags;
|
||||||
|
DPID idFrom;
|
||||||
|
DPID idTo;
|
||||||
|
LPDWORD lpdwNumMsgs;
|
||||||
|
LPDWORD lpdwNumBytes;
|
||||||
|
} DPSP_GETMESSAGEQUEUEDATA, *LPDPSP_GETMESSAGEQUEUEDATA;
|
||||||
|
|
||||||
|
#define DPCANCELSEND_PRIORITY 0x00000001
|
||||||
|
#define DPCANCELSEND_ALL 0x00000002
|
||||||
|
|
||||||
|
typedef struct tagDPSP_CANCELDATA
|
||||||
|
{
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
DWORD dwFlags;
|
||||||
|
LPRGLPVOID lprglpvSPMsgID;
|
||||||
|
DWORD cSPMsgID;
|
||||||
|
DWORD dwMinPriority;
|
||||||
|
DWORD dwMaxPriority;
|
||||||
|
} DPSP_CANCELDATA, *LPDPSP_CANCELDATA;
|
||||||
|
|
||||||
|
typedef struct tagDPSP_SHUTDOWNDATA
|
||||||
|
{
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
} DPSP_SHUTDOWNDATA, *LPDPSP_SHUTDOWNDATA;
|
||||||
|
|
||||||
|
|
||||||
|
/* Prototypes returned by SPInit */
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_CREATEPLAYER)(LPDPSP_CREATEPLAYERDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_DELETEPLAYER)(LPDPSP_DELETEPLAYERDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_SEND)(LPDPSP_SENDDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_ENUMSESSIONS)(LPDPSP_ENUMSESSIONSDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_REPLY)(LPDPSP_REPLYDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_SHUTDOWN)(void);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_CREATEGROUP)(LPDPSP_CREATEGROUPDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_DELETEGROUP)(LPDPSP_DELETEGROUPDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_ADDPLAYERTOGROUP)(LPDPSP_ADDPLAYERTOGROUPDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_REMOVEPLAYERFROMGROUP)(LPDPSP_REMOVEPLAYERFROMGROUPDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_GETCAPS)(LPDPSP_GETCAPSDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_GETADDRESS)(LPDPSP_GETADDRESSDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_GETADDRESSCHOICES)(LPDPSP_GETADDRESSCHOICESDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_OPEN)(LPDPSP_OPENDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_CLOSE)(void);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_SENDTOGROUP)(LPDPSP_SENDTOGROUPDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_SHUTDOWNEX)(LPDPSP_SHUTDOWNDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_CLOSEEX)(LPDPSP_CLOSEDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_SENDEX)(LPDPSP_SENDEXDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_SENDTOGROUPEX)(LPDPSP_SENDTOGROUPEXDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_CANCEL)(LPDPSP_CANCELDATA);
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_GETMESSAGEQUEUE)(LPDPSP_GETMESSAGEQUEUEDATA);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct tagDPSP_SPCALLBACKS
|
||||||
|
{
|
||||||
|
DWORD dwSize;
|
||||||
|
DWORD dwVersion;
|
||||||
|
|
||||||
|
LPDPSP_ENUMSESSIONS EnumSessions; /* Must be provided */
|
||||||
|
LPDPSP_REPLY Reply; /* Must be provided */
|
||||||
|
LPDPSP_SEND Send; /* Must be provided */
|
||||||
|
LPDPSP_ADDPLAYERTOGROUP AddPlayerToGroup; /* Optional */
|
||||||
|
LPDPSP_CLOSE Close; /* Optional */
|
||||||
|
LPDPSP_CREATEGROUP CreateGroup; /* Optional */
|
||||||
|
LPDPSP_CREATEPLAYER CreatePlayer; /* Optional */
|
||||||
|
LPDPSP_DELETEGROUP DeleteGroup; /* Optional */
|
||||||
|
LPDPSP_DELETEPLAYER DeletePlayer; /* Optional */
|
||||||
|
LPDPSP_GETADDRESS GetAddress; /* Optional */
|
||||||
|
LPDPSP_GETCAPS GetCaps; /* Optional */
|
||||||
|
LPDPSP_OPEN Open; /* Optional */
|
||||||
|
LPDPSP_REMOVEPLAYERFROMGROUP RemovePlayerFromGroup; /* Optional */
|
||||||
|
LPDPSP_SENDTOGROUP SendToGroup; /* Optional */
|
||||||
|
LPDPSP_SHUTDOWN Shutdown; /* Optional */
|
||||||
|
|
||||||
|
LPDPSP_CLOSEEX CloseEx; /* Optional */
|
||||||
|
LPDPSP_SHUTDOWNEX ShutdownEx; /* Optional */
|
||||||
|
LPDPSP_GETADDRESSCHOICES GetAddressChoices; /* Optional */
|
||||||
|
|
||||||
|
LPDPSP_SENDEX SendEx; /* Optional */
|
||||||
|
LPDPSP_SENDTOGROUPEX SendToGroupEx; /* Optional */
|
||||||
|
LPDPSP_CANCEL Cancel; /* Optional */
|
||||||
|
LPDPSP_GETMESSAGEQUEUE GetMessageQueue; /* Optional */
|
||||||
|
} DPSP_SPCALLBACKS, *LPDPSP_SPCALLBACKS;
|
||||||
|
|
||||||
|
typedef struct tagSPINITDATA
|
||||||
|
{
|
||||||
|
LPDPSP_SPCALLBACKS lpCB;
|
||||||
|
IDirectPlaySP* lpISP;
|
||||||
|
LPWSTR lpszName;
|
||||||
|
LPGUID lpGuid;
|
||||||
|
DWORD dwReserved1;
|
||||||
|
DWORD dwReserved2;
|
||||||
|
DWORD dwSPHeaderSize;
|
||||||
|
LPDPADDRESS lpAddress;
|
||||||
|
DWORD dwAddressSize;
|
||||||
|
DWORD dwSPVersion;
|
||||||
|
} SPINITDATA, *LPSPINITDATA;
|
||||||
|
|
||||||
|
typedef HRESULT (WINAPI *LPDPSP_SPINIT)(LPSPINITDATA);
|
||||||
|
|
||||||
|
/* This variable is exported from the DLL at ordinal 6 to be accessed by the
|
||||||
|
* SP directly
|
||||||
|
*/
|
||||||
|
extern DWORD gdwDPlaySPRefCount;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -10,11 +10,14 @@
|
||||||
* dplayx.dll data which is accessible from all processes.
|
* dplayx.dll data which is accessible from all processes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
|
#include "heap.h"
|
||||||
|
|
||||||
|
#include "wingdi.h"
|
||||||
|
#include "winuser.h"
|
||||||
|
|
||||||
#include "dplayx_global.h"
|
#include "dplayx_global.h"
|
||||||
#include "dplayx_messages.h" /* For CreateMessageReceptionThread only */
|
#include "dplayx_messages.h" /* For CreateMessageReceptionThread only */
|
||||||
|
@ -42,9 +45,9 @@ static LPVOID lpSharedStaticData = NULL;
|
||||||
|
|
||||||
|
|
||||||
/* HACK for simple global data right now */
|
/* HACK for simple global data right now */
|
||||||
#define dwStaticSharedSize (128 * 1024) /* FIXME: Way too much */
|
#define dwStaticSharedSize (128 * 1024) /* 128 KBytes */
|
||||||
#define dwDynamicSharedSize (128 * 1024) /* FIXME: Enough? */
|
#define dwDynamicSharedSize (512 * 1024) /* 512 KBytes */
|
||||||
#define dwTotalSharedSize (dwStaticSharedSize + dwDynamicSharedSize)
|
#define dwTotalSharedSize ( dwStaticSharedSize + dwDynamicSharedSize )
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: Is there no easier way? */
|
/* FIXME: Is there no easier way? */
|
||||||
|
@ -53,7 +56,6 @@ static LPVOID lpSharedStaticData = NULL;
|
||||||
* Each block has 4 bytes which are 0 unless used */
|
* Each block has 4 bytes which are 0 unless used */
|
||||||
#define dwBlockSize 512
|
#define dwBlockSize 512
|
||||||
#define dwMaxBlock (dwDynamicSharedSize/dwBlockSize)
|
#define dwMaxBlock (dwDynamicSharedSize/dwBlockSize)
|
||||||
DWORD dwBlockOn = 0;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -61,7 +63,7 @@ typedef struct
|
||||||
DWORD data[dwBlockSize-sizeof(DWORD)];
|
DWORD data[dwBlockSize-sizeof(DWORD)];
|
||||||
} DPLAYX_MEM_SLICE;
|
} DPLAYX_MEM_SLICE;
|
||||||
|
|
||||||
DPLAYX_MEM_SLICE* lpMemArea;
|
static DPLAYX_MEM_SLICE* lpMemArea;
|
||||||
|
|
||||||
void DPLAYX_PrivHeapFree( LPVOID addr );
|
void DPLAYX_PrivHeapFree( LPVOID addr );
|
||||||
void DPLAYX_PrivHeapFree( LPVOID addr )
|
void DPLAYX_PrivHeapFree( LPVOID addr )
|
||||||
|
@ -81,6 +83,7 @@ void DPLAYX_PrivHeapFree( LPVOID addr )
|
||||||
lpMemArea[ dwBlockUsed ].used = 0;
|
lpMemArea[ dwBlockUsed ].used = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: This should be static, but is being used for a hack right now */
|
||||||
LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size );
|
LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size );
|
||||||
LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size )
|
LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size )
|
||||||
{
|
{
|
||||||
|
@ -149,17 +152,19 @@ typedef struct tagDPLAYX_LOBBYDATA
|
||||||
|
|
||||||
/* Information for dplobby interfaces */
|
/* Information for dplobby interfaces */
|
||||||
DWORD dwAppID;
|
DWORD dwAppID;
|
||||||
HANDLE hReceiveEvent;
|
|
||||||
DWORD dwAppLaunchedFromID;
|
DWORD dwAppLaunchedFromID;
|
||||||
|
|
||||||
/* Should this lobby app send messages to creator at important life
|
/* Should this lobby app send messages to creator at important life
|
||||||
* stages
|
* stages
|
||||||
*/
|
*/
|
||||||
BOOL bInformOnConnect; /* FIXME: Not used yet */
|
HANDLE hInformOnAppStart;
|
||||||
BOOL bInformOnSettingRead;
|
HANDLE hInformOnAppDeath;
|
||||||
BOOL bInformOnAppDeath; /* FIXME: Not used yet */
|
HANDLE hInformOnSettingRead;
|
||||||
|
|
||||||
|
/* Sundries */
|
||||||
BOOL bWaitForConnectionSettings;
|
BOOL bWaitForConnectionSettings;
|
||||||
|
DWORD dwLobbyMsgThreadId;
|
||||||
|
|
||||||
|
|
||||||
} DPLAYX_LOBBYDATA, *LPDPLAYX_LOBBYDATA;
|
} DPLAYX_LOBBYDATA, *LPDPLAYX_LOBBYDATA;
|
||||||
|
|
||||||
|
@ -190,6 +195,7 @@ BOOL DPLAYX_ConstructData(void)
|
||||||
SECURITY_ATTRIBUTES s_attrib;
|
SECURITY_ATTRIBUTES s_attrib;
|
||||||
BOOL bInitializeSharedMemory = FALSE;
|
BOOL bInitializeSharedMemory = FALSE;
|
||||||
LPVOID lpDesiredMemoryMapStart = (LPVOID)0x50000000;
|
LPVOID lpDesiredMemoryMapStart = (LPVOID)0x50000000;
|
||||||
|
HANDLE hInformOnStart;
|
||||||
|
|
||||||
TRACE( "DPLAYX dll loaded - construct called\n" );
|
TRACE( "DPLAYX dll loaded - construct called\n" );
|
||||||
|
|
||||||
|
@ -309,6 +315,22 @@ BOOL DPLAYX_ConstructData(void)
|
||||||
|
|
||||||
DPLAYX_ReleaseSemaphore();
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
|
||||||
|
/* Everything was created correctly. Signal the lobby client that
|
||||||
|
* we started up correctly
|
||||||
|
*/
|
||||||
|
if( DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, FALSE ) &&
|
||||||
|
hInformOnStart
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOL bSuccess;
|
||||||
|
bSuccess = SetEvent( hInformOnStart );
|
||||||
|
TRACE( "Signalling lobby app start event %u %s\n",
|
||||||
|
hInformOnStart, bSuccess ? "succeed" : "failed" );
|
||||||
|
|
||||||
|
/* Close out handle */
|
||||||
|
DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,8 +340,26 @@ BOOL DPLAYX_ConstructData(void)
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
BOOL DPLAYX_DestructData(void)
|
BOOL DPLAYX_DestructData(void)
|
||||||
{
|
{
|
||||||
|
HANDLE hInformOnDeath;
|
||||||
|
|
||||||
TRACE( "DPLAYX dll unloaded - destruct called\n" );
|
TRACE( "DPLAYX dll unloaded - destruct called\n" );
|
||||||
|
|
||||||
|
/* If required, inform that this app is dying */
|
||||||
|
if( DPLAYX_GetThisLobbyHandles( NULL, &hInformOnDeath, NULL, FALSE ) &&
|
||||||
|
hInformOnDeath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOL bSuccess;
|
||||||
|
bSuccess = SetEvent( hInformOnDeath );
|
||||||
|
TRACE( "Signalling lobby app death event %u %s\n",
|
||||||
|
hInformOnDeath, bSuccess ? "succeed" : "failed" );
|
||||||
|
|
||||||
|
/* Close out handle */
|
||||||
|
DPLAYX_GetThisLobbyHandles( NULL, &hInformOnDeath, NULL, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DO CLEAN UP (LAST) */
|
||||||
|
|
||||||
/* Delete the semaphore */
|
/* Delete the semaphore */
|
||||||
CloseHandle( hDplayxSema );
|
CloseHandle( hDplayxSema );
|
||||||
|
|
||||||
|
@ -334,9 +374,6 @@ BOOL DPLAYX_DestructData(void)
|
||||||
void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData )
|
void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData )
|
||||||
{
|
{
|
||||||
ZeroMemory( lpData, sizeof( *lpData ) );
|
ZeroMemory( lpData, sizeof( *lpData ) );
|
||||||
|
|
||||||
/* Set the handle to a better invalid value */
|
|
||||||
lpData->hReceiveEvent = INVALID_HANDLE_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: This must be called with the semaphore aquired.
|
/* NOTE: This must be called with the semaphore aquired.
|
||||||
|
@ -370,7 +407,7 @@ BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, LPDPLAYX_LOBBYDATA* lplpDplData )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
|
/* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
|
||||||
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
|
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID )
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
|
@ -388,16 +425,16 @@ BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
|
||||||
if( lobbyData[ i ].dwAppID == 0 )
|
if( lobbyData[ i ].dwAppID == 0 )
|
||||||
{
|
{
|
||||||
/* This process is now lobbied */
|
/* This process is now lobbied */
|
||||||
TRACE( "Setting lobbyData[%u] for (0x%08lx,%u,0x%08lx)\n",
|
TRACE( "Setting lobbyData[%u] for (0x%08lx,0x%08lx)\n",
|
||||||
i, dwAppID, hReceiveEvent, GetCurrentProcessId() );
|
i, dwAppID, GetCurrentProcessId() );
|
||||||
|
|
||||||
lobbyData[ i ].dwAppID = dwAppID;
|
lobbyData[ i ].dwAppID = dwAppID;
|
||||||
lobbyData[ i ].hReceiveEvent = hReceiveEvent;
|
|
||||||
lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId();
|
lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId();
|
||||||
|
|
||||||
lobbyData[ i ].bInformOnConnect = TRUE;
|
/* FIXME: Where is the best place for this? In interface or here? */
|
||||||
lobbyData[ i ].bInformOnSettingRead = TRUE;
|
lobbyData[ i ].hInformOnAppStart = 0;
|
||||||
lobbyData[ i ].bInformOnAppDeath = TRUE;
|
lobbyData[ i ].hInformOnAppDeath = 0;
|
||||||
|
lobbyData[ i ].hInformOnSettingRead = 0;
|
||||||
|
|
||||||
DPLAYX_ReleaseSemaphore();
|
DPLAYX_ReleaseSemaphore();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -437,14 +474,114 @@ BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL DPLAYX_SetLobbyHandles( DWORD dwAppID,
|
||||||
|
HANDLE hStart, HANDLE hDeath, HANDLE hConnRead )
|
||||||
|
{
|
||||||
|
LPDPLAYX_LOBBYDATA lpLData;
|
||||||
|
|
||||||
|
/* Need to explictly give lobby application. Can't set for yourself */
|
||||||
|
if( dwAppID == 0 )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPLAYX_AquireSemaphore();
|
||||||
|
|
||||||
|
if( !DPLAYX_IsAppIdLobbied( dwAppID, &lpLData ) )
|
||||||
|
{
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lpLData->hInformOnAppStart = hStart;
|
||||||
|
lpLData->hInformOnAppDeath = hDeath;
|
||||||
|
lpLData->hInformOnSettingRead = hConnRead;
|
||||||
|
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart,
|
||||||
|
LPHANDLE lphDeath,
|
||||||
|
LPHANDLE lphConnRead,
|
||||||
|
BOOL bClearSetHandles )
|
||||||
|
{
|
||||||
|
LPDPLAYX_LOBBYDATA lpLData;
|
||||||
|
|
||||||
|
DPLAYX_AquireSemaphore();
|
||||||
|
|
||||||
|
if( !DPLAYX_IsAppIdLobbied( 0, &lpLData ) )
|
||||||
|
{
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lphStart != NULL )
|
||||||
|
{
|
||||||
|
if( lpLData->hInformOnAppStart == 0 )
|
||||||
|
{
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lphStart = lpLData->hInformOnAppStart;
|
||||||
|
|
||||||
|
if( bClearSetHandles )
|
||||||
|
{
|
||||||
|
CloseHandle( lpLData->hInformOnAppStart );
|
||||||
|
lpLData->hInformOnAppStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lphDeath != NULL )
|
||||||
|
{
|
||||||
|
if( lpLData->hInformOnAppDeath == 0 )
|
||||||
|
{
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lphDeath = lpLData->hInformOnAppDeath;
|
||||||
|
|
||||||
|
if( bClearSetHandles )
|
||||||
|
{
|
||||||
|
CloseHandle( lpLData->hInformOnAppDeath );
|
||||||
|
lpLData->hInformOnAppDeath = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lphConnRead != NULL )
|
||||||
|
{
|
||||||
|
if( lpLData->hInformOnSettingRead == 0 )
|
||||||
|
{
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lphConnRead = lpLData->hInformOnSettingRead;
|
||||||
|
|
||||||
|
if( bClearSetHandles )
|
||||||
|
{
|
||||||
|
CloseHandle( lpLData->hInformOnSettingRead );
|
||||||
|
lpLData->hInformOnSettingRead = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT DPLAYX_GetConnectionSettingsA
|
HRESULT DPLAYX_GetConnectionSettingsA
|
||||||
( DWORD dwAppID,
|
( DWORD dwAppID,
|
||||||
LPVOID lpData,
|
LPVOID lpData,
|
||||||
LPDWORD lpdwDataSize,
|
LPDWORD lpdwDataSize )
|
||||||
LPBOOL lpbSendHaveReadMessage )
|
|
||||||
{
|
{
|
||||||
LPDPLAYX_LOBBYDATA lpDplData;
|
LPDPLAYX_LOBBYDATA lpDplData;
|
||||||
DWORD dwRequiredDataSize = 0;
|
DWORD dwRequiredDataSize = 0;
|
||||||
|
HANDLE hInformOnSettingRead;
|
||||||
|
|
||||||
DPLAYX_AquireSemaphore();
|
DPLAYX_AquireSemaphore();
|
||||||
|
|
||||||
|
@ -472,23 +609,33 @@ HRESULT DPLAYX_GetConnectionSettingsA
|
||||||
return DPERR_BUFFERTOOSMALL;
|
return DPERR_BUFFERTOOSMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* They have gotten the information */
|
|
||||||
*lpbSendHaveReadMessage = lpDplData->bInformOnSettingRead;
|
|
||||||
lpDplData->bInformOnSettingRead = FALSE;
|
|
||||||
|
|
||||||
DPLAYX_CopyConnStructA( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
|
DPLAYX_CopyConnStructA( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
|
||||||
|
|
||||||
DPLAYX_ReleaseSemaphore();
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
|
||||||
|
/* They have gotten the information - signal the event if required */
|
||||||
|
if( DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, FALSE ) &&
|
||||||
|
hInformOnSettingRead
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOL bSuccess;
|
||||||
|
bSuccess = SetEvent( hInformOnSettingRead );
|
||||||
|
TRACE( "Signalling setting read event %u %s\n",
|
||||||
|
hInformOnSettingRead, bSuccess ? "succeed" : "failed" );
|
||||||
|
|
||||||
|
/* Close out handle */
|
||||||
|
DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
return DP_OK;
|
return DP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assumption: Enough contiguous space was allocated at dest */
|
/* Assumption: Enough contiguous space was allocated at dest */
|
||||||
void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
{
|
{
|
||||||
BYTE* lpStartOfFreeSpace;
|
BYTE* lpStartOfFreeSpace;
|
||||||
|
|
||||||
memcpy( dest, src, sizeof( DPLCONNECTION ) );
|
CopyMemory( dest, src, sizeof( DPLCONNECTION ) );
|
||||||
|
|
||||||
lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION );
|
lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION );
|
||||||
|
|
||||||
|
@ -497,7 +644,7 @@ void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
{
|
{
|
||||||
dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
|
dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
|
||||||
lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
|
lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
|
||||||
memcpy( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
|
CopyMemory( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
|
||||||
|
|
||||||
/* Session names may or may not exist */
|
/* Session names may or may not exist */
|
||||||
if( src->lpSessionDesc->sess.lpszSessionNameA )
|
if( src->lpSessionDesc->sess.lpszSessionNameA )
|
||||||
|
@ -505,7 +652,7 @@ void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->sess.lpszSessionNameA );
|
strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->sess.lpszSessionNameA );
|
||||||
dest->lpSessionDesc->sess.lpszSessionNameA = (LPSTR)lpStartOfFreeSpace;
|
dest->lpSessionDesc->sess.lpszSessionNameA = (LPSTR)lpStartOfFreeSpace;
|
||||||
lpStartOfFreeSpace +=
|
lpStartOfFreeSpace +=
|
||||||
strlen( (LPSTR)dest->lpSessionDesc->sess.lpszSessionName ) + 1;
|
strlen( (LPSTR)dest->lpSessionDesc->sess.lpszSessionNameA ) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( src->lpSessionDesc->pass.lpszPasswordA )
|
if( src->lpSessionDesc->pass.lpszPasswordA )
|
||||||
|
@ -522,7 +669,7 @@ void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
{
|
{
|
||||||
dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
|
dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
|
||||||
lpStartOfFreeSpace += sizeof( DPNAME );
|
lpStartOfFreeSpace += sizeof( DPNAME );
|
||||||
memcpy( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
|
CopyMemory( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
|
||||||
|
|
||||||
if( src->lpPlayerName->psn.lpszShortNameA )
|
if( src->lpPlayerName->psn.lpszShortNameA )
|
||||||
{
|
{
|
||||||
|
@ -546,7 +693,7 @@ void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
if( src->lpAddress )
|
if( src->lpAddress )
|
||||||
{
|
{
|
||||||
dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
|
dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
|
||||||
memcpy( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
|
CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
|
||||||
/* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
|
/* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,11 +701,11 @@ void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
HRESULT DPLAYX_GetConnectionSettingsW
|
HRESULT DPLAYX_GetConnectionSettingsW
|
||||||
( DWORD dwAppID,
|
( DWORD dwAppID,
|
||||||
LPVOID lpData,
|
LPVOID lpData,
|
||||||
LPDWORD lpdwDataSize,
|
LPDWORD lpdwDataSize )
|
||||||
LPBOOL lpbSendHaveReadMessage )
|
|
||||||
{
|
{
|
||||||
LPDPLAYX_LOBBYDATA lpDplData;
|
LPDPLAYX_LOBBYDATA lpDplData;
|
||||||
DWORD dwRequiredDataSize = 0;
|
DWORD dwRequiredDataSize = 0;
|
||||||
|
HANDLE hInformOnSettingRead;
|
||||||
|
|
||||||
DPLAYX_AquireSemaphore();
|
DPLAYX_AquireSemaphore();
|
||||||
|
|
||||||
|
@ -584,14 +731,24 @@ HRESULT DPLAYX_GetConnectionSettingsW
|
||||||
return DPERR_BUFFERTOOSMALL;
|
return DPERR_BUFFERTOOSMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* They have gotten the information */
|
|
||||||
*lpbSendHaveReadMessage = lpDplData->bInformOnSettingRead;
|
|
||||||
lpDplData->bInformOnSettingRead = FALSE;
|
|
||||||
|
|
||||||
DPLAYX_CopyConnStructW( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
|
DPLAYX_CopyConnStructW( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
|
||||||
|
|
||||||
DPLAYX_ReleaseSemaphore();
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
|
||||||
|
/* They have gotten the information - signal the event if required */
|
||||||
|
if( DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, FALSE ) &&
|
||||||
|
hInformOnSettingRead
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOL bSuccess;
|
||||||
|
bSuccess = SetEvent( hInformOnSettingRead );
|
||||||
|
TRACE( "Signalling setting read event %u %s\n",
|
||||||
|
hInformOnSettingRead, bSuccess ? "succeed" : "failed" );
|
||||||
|
|
||||||
|
/* Close out handle */
|
||||||
|
DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
return DP_OK;
|
return DP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +757,7 @@ void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
{
|
{
|
||||||
BYTE* lpStartOfFreeSpace;
|
BYTE* lpStartOfFreeSpace;
|
||||||
|
|
||||||
memcpy( dest, src, sizeof( DPLCONNECTION ) );
|
CopyMemory( dest, src, sizeof( DPLCONNECTION ) );
|
||||||
|
|
||||||
lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION );
|
lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION );
|
||||||
|
|
||||||
|
@ -609,7 +766,7 @@ void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
{
|
{
|
||||||
dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
|
dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
|
||||||
lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
|
lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
|
||||||
memcpy( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
|
CopyMemory( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
|
||||||
|
|
||||||
/* Session names may or may not exist */
|
/* Session names may or may not exist */
|
||||||
if( src->lpSessionDesc->sess.lpszSessionName )
|
if( src->lpSessionDesc->sess.lpszSessionName )
|
||||||
|
@ -634,7 +791,7 @@ void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
{
|
{
|
||||||
dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
|
dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
|
||||||
lpStartOfFreeSpace += sizeof( DPNAME );
|
lpStartOfFreeSpace += sizeof( DPNAME );
|
||||||
memcpy( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
|
CopyMemory( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
|
||||||
|
|
||||||
if( src->lpPlayerName->psn.lpszShortName )
|
if( src->lpPlayerName->psn.lpszShortName )
|
||||||
{
|
{
|
||||||
|
@ -658,7 +815,7 @@ void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
|
||||||
if( src->lpAddress )
|
if( src->lpAddress )
|
||||||
{
|
{
|
||||||
dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
|
dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
|
||||||
memcpy( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
|
CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
|
||||||
/* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
|
/* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -883,7 +1040,8 @@ DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpConn )
|
||||||
LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateSessionDesc2A( LPCDPSESSIONDESC2 lpSessionSrc )
|
LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateSessionDesc2A( LPCDPSESSIONDESC2 lpSessionSrc )
|
||||||
{
|
{
|
||||||
LPDPSESSIONDESC2 lpSessionDest =
|
LPDPSESSIONDESC2 lpSessionDest =
|
||||||
(LPDPSESSIONDESC2)DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, sizeof( *lpSessionSrc ) );
|
(LPDPSESSIONDESC2)HeapAlloc( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY, sizeof( *lpSessionSrc ) );
|
||||||
DPLAYX_CopyIntoSessionDesc2A( lpSessionDest, lpSessionSrc );
|
DPLAYX_CopyIntoSessionDesc2A( lpSessionDest, lpSessionSrc );
|
||||||
|
|
||||||
return lpSessionDest;
|
return lpSessionDest;
|
||||||
|
@ -893,17 +1051,19 @@ LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateSessionDesc2A( LPCDPSESSIONDESC2 lpSessio
|
||||||
BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
|
BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
|
||||||
LPCDPSESSIONDESC2 lpSessionSrc )
|
LPCDPSESSIONDESC2 lpSessionSrc )
|
||||||
{
|
{
|
||||||
memcpy( lpSessionDest, lpSessionSrc, sizeof( *lpSessionSrc ) );
|
CopyMemory( lpSessionDest, lpSessionSrc, sizeof( *lpSessionSrc ) );
|
||||||
|
|
||||||
if( lpSessionSrc->sess.lpszSessionNameA )
|
if( lpSessionSrc->sess.lpszSessionNameA )
|
||||||
{
|
{
|
||||||
lpSessionDest->sess.lpszSessionNameA =
|
lpSessionDest->sess.lpszSessionNameA =
|
||||||
DPLAYX_strdupA( HEAP_ZERO_MEMORY, lpSessionSrc->sess.lpszSessionNameA );
|
HEAP_strdupA( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY, lpSessionSrc->sess.lpszSessionNameA );
|
||||||
}
|
}
|
||||||
if( lpSessionSrc->pass.lpszPasswordA )
|
if( lpSessionSrc->pass.lpszPasswordA )
|
||||||
{
|
{
|
||||||
lpSessionDest->pass.lpszPasswordA =
|
lpSessionDest->pass.lpszPasswordA =
|
||||||
DPLAYX_strdupA( HEAP_ZERO_MEMORY, lpSessionSrc->pass.lpszPasswordA );
|
HEAP_strdupA( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY, lpSessionSrc->pass.lpszPasswordA );
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1002,6 +1162,24 @@ BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void)
|
||||||
return bFound;
|
return bFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL DPLAYX_SetLobbyMsgThreadId( DWORD dwAppId, DWORD dwThreadId )
|
||||||
|
{
|
||||||
|
LPDPLAYX_LOBBYDATA lpLobbyData;
|
||||||
|
|
||||||
|
DPLAYX_AquireSemaphore();
|
||||||
|
|
||||||
|
if( !DPLAYX_IsAppIdLobbied( dwAppId, &lpLobbyData ) )
|
||||||
|
{
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lpLobbyData->dwLobbyMsgThreadId = dwThreadId;
|
||||||
|
|
||||||
|
DPLAYX_ReleaseSemaphore();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* NOTE: This is potentially not thread safe. You are not guaranteed to end up
|
/* 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
|
with the correct string printed in the case where the HRESULT is not
|
||||||
|
@ -1149,7 +1327,7 @@ LPCSTR DPLAYX_HresultToString(HRESULT hr)
|
||||||
/* For errors not in the list, return HRESULT as a string
|
/* For errors not in the list, return HRESULT as a string
|
||||||
This part is not thread safe */
|
This part is not thread safe */
|
||||||
WARN( "Unknown error 0x%08lx\n", hr );
|
WARN( "Unknown error 0x%08lx\n", hr );
|
||||||
sprintf( szTempStr, "0x%08lx", hr );
|
wsprintfA( szTempStr, "0x%08lx", hr );
|
||||||
return szTempStr;
|
return szTempStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,10 @@ BOOL DPLAYX_DestructData(void);
|
||||||
|
|
||||||
HRESULT DPLAYX_GetConnectionSettingsA ( DWORD dwAppID,
|
HRESULT DPLAYX_GetConnectionSettingsA ( DWORD dwAppID,
|
||||||
LPVOID lpData,
|
LPVOID lpData,
|
||||||
LPDWORD lpdwDataSize,
|
LPDWORD lpdwDataSize );
|
||||||
LPBOOL lpbSendHaveReadMessage );
|
|
||||||
HRESULT DPLAYX_GetConnectionSettingsW ( DWORD dwAppID,
|
HRESULT DPLAYX_GetConnectionSettingsW ( DWORD dwAppID,
|
||||||
LPVOID lpData,
|
LPVOID lpData,
|
||||||
LPDWORD lpdwDataSize,
|
LPDWORD lpdwDataSize );
|
||||||
LPBOOL lpbSendHaveReadMessage );
|
|
||||||
|
|
||||||
HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags,
|
HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags,
|
||||||
DWORD dwAppID,
|
DWORD dwAppID,
|
||||||
|
@ -23,16 +21,33 @@ HRESULT DPLAYX_SetConnectionSettingsW ( DWORD dwFlags,
|
||||||
DWORD dwAppID,
|
DWORD dwAppID,
|
||||||
LPDPLCONNECTION lpConn );
|
LPDPLCONNECTION lpConn );
|
||||||
|
|
||||||
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent );
|
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID );
|
||||||
BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID );
|
BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID );
|
||||||
|
|
||||||
BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait );
|
BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait );
|
||||||
BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void);
|
BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void);
|
||||||
|
|
||||||
|
BOOL DPLAYX_SetLobbyHandles( DWORD dwAppID,
|
||||||
|
HANDLE hStart, HANDLE hDeath, HANDLE hConnRead );
|
||||||
|
BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart,
|
||||||
|
LPHANDLE lphDeath,
|
||||||
|
LPHANDLE lphConnRead, BOOL bClearSetHandles );
|
||||||
|
|
||||||
LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateLocalSession( UINT* index );
|
LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateLocalSession( UINT* index );
|
||||||
BOOL DPLAYX_CopyLocalSession( UINT* index, LPDPSESSIONDESC2 lpsd );
|
BOOL DPLAYX_CopyLocalSession( UINT* index, LPDPSESSIONDESC2 lpsd );
|
||||||
void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd );
|
void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd );
|
||||||
|
|
||||||
|
BOOL DPLAYX_SetLobbyMsgThreadId( DWORD dwAppId, DWORD dwThreadId );
|
||||||
|
|
||||||
|
/* FIXME: This should not be here */
|
||||||
|
LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size );
|
||||||
|
void DPLAYX_PrivHeapFree( LPVOID addr );
|
||||||
|
|
||||||
|
LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str );
|
||||||
|
LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str );
|
||||||
|
/* FIXME: End shared data alloc which should be local */
|
||||||
|
|
||||||
|
|
||||||
/* Convert a DP or DPL HRESULT code into a string for human consumption */
|
/* Convert a DP or DPL HRESULT code into a string for human consumption */
|
||||||
LPCSTR DPLAYX_HresultToString( HRESULT hr );
|
LPCSTR DPLAYX_HresultToString( HRESULT hr );
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,24 @@
|
||||||
*
|
*
|
||||||
* contact <hunnise@nortelnetworks.com>
|
* contact <hunnise@nortelnetworks.com>
|
||||||
*/
|
*/
|
||||||
|
#include "winerror.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
|
||||||
#include "initguid.h"
|
#include "initguid.h" /* To define the GUIDs */
|
||||||
#include "dplay.h"
|
#include "dplaysp.h"
|
||||||
#include "dplobby.h"
|
|
||||||
#include "dplayx_global.h"
|
#include "dplayx_global.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(dplay);
|
DEFAULT_DEBUG_CHANNEL(dplay);
|
||||||
|
|
||||||
|
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
|
||||||
|
|
||||||
static DWORD DPLAYX_dwProcessesAttached = 0;
|
static DWORD DPLAYX_dwProcessesAttached = 0;
|
||||||
|
|
||||||
|
/* This is a globally exported variable at ordinal 6 of DPLAYX.DLL */
|
||||||
|
DWORD gdwDPlaySPRefCount = 0; /* FIXME: Should it be initialized here? */
|
||||||
|
|
||||||
|
|
||||||
BOOL WINAPI DPLAYX_LibMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
|
BOOL WINAPI DPLAYX_LibMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -59,3 +64,20 @@ BOOL WINAPI DPLAYX_LibMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReser
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* DllCanUnloadNow (DPLAYX.10)
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI DPLAYX_DllCanUnloadNow(void)
|
||||||
|
{
|
||||||
|
HRESULT hr = ( gdwDPlaySPRefCount > 0 ) ? S_FALSE : S_OK;
|
||||||
|
|
||||||
|
/* FIXME: Should I be putting a check in for class factory objects
|
||||||
|
* as well
|
||||||
|
*/
|
||||||
|
|
||||||
|
TRACE( ": returning 0x%08lx\n", hr );
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,48 +9,130 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
|
||||||
|
#include "wingdi.h"
|
||||||
|
#include "winuser.h"
|
||||||
|
|
||||||
#include "dplayx_messages.h"
|
#include "dplayx_messages.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(dplay)
|
DEFAULT_DEBUG_CHANNEL(dplay)
|
||||||
|
|
||||||
|
typedef struct tagMSGTHREADINFO
|
||||||
|
{
|
||||||
|
HANDLE hStart;
|
||||||
|
HANDLE hDeath;
|
||||||
|
HANDLE hSettingRead;
|
||||||
|
HANDLE hNotifyEvent;
|
||||||
|
} MSGTHREADINFO, *LPMSGTHREADINFO;
|
||||||
|
|
||||||
static DWORD CALLBACK DPLAYX_MSG_ThreadMain( LPVOID lpContext );
|
|
||||||
|
static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext );
|
||||||
|
|
||||||
/* Create the message reception thread to allow the application to receive
|
/* Create the message reception thread to allow the application to receive
|
||||||
* asynchronous message reception
|
* asynchronous message reception
|
||||||
*/
|
*/
|
||||||
DWORD CreateMessageReceptionThread( HANDLE hNotifyEvent )
|
DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
|
HANDLE hDeath, HANDLE hConnRead )
|
||||||
{
|
{
|
||||||
DWORD dwMsgThreadId;
|
DWORD dwMsgThreadId;
|
||||||
|
LPMSGTHREADINFO lpThreadInfo;
|
||||||
|
|
||||||
if( !DuplicateHandle( 0, hNotifyEvent, 0, NULL, 0, FALSE, 0 ) )
|
lpThreadInfo = HeapAlloc( GetProcessHeap(), 0, sizeof( *lpThreadInfo ) );
|
||||||
|
if( lpThreadInfo == NULL )
|
||||||
{
|
{
|
||||||
ERR( "Unable to duplicate event handle\n" );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Should most likely store that thread handle */
|
/* The notify event may or may not exist. Depends if async comm or not */
|
||||||
CreateThread( NULL, /* Security attribs */
|
if( hNotifyEvent &&
|
||||||
0, /* Stack */
|
!DuplicateHandle( GetCurrentProcess(), hNotifyEvent,
|
||||||
DPLAYX_MSG_ThreadMain, /* Msg reception function */
|
GetCurrentProcess(), &lpThreadInfo->hNotifyEvent,
|
||||||
(LPVOID)hNotifyEvent, /* Msg reception function parameter */
|
0, FALSE, DUPLICATE_SAME_ACCESS ) )
|
||||||
0, /* Flags */
|
{
|
||||||
&dwMsgThreadId /* Updated with thread id */
|
ERR( "Unable to duplicate event handle\n" );
|
||||||
);
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* These 3 handles don't need to be duplicated because we don't keep a
|
||||||
|
* reference to them where they're created. They're created specifically
|
||||||
|
* for the message thread
|
||||||
|
*/
|
||||||
|
lpThreadInfo->hStart = hStart;
|
||||||
|
lpThreadInfo->hDeath = hDeath;
|
||||||
|
lpThreadInfo->hSettingRead = hConnRead;
|
||||||
|
|
||||||
|
if( !CreateThread( NULL, /* Security attribs */
|
||||||
|
0, /* Stack */
|
||||||
|
DPL_MSG_ThreadMain, /* Msg reception function */
|
||||||
|
lpThreadInfo, /* Msg reception func parameter */
|
||||||
|
0, /* Flags */
|
||||||
|
&dwMsgThreadId /* Updated with thread id */
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ERR( "Unable to create msg thread\n" );
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Should I be closing the handle to the thread or does that
|
||||||
|
terminate the thread? */
|
||||||
|
|
||||||
return dwMsgThreadId;
|
return dwMsgThreadId;
|
||||||
|
|
||||||
|
error:
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, lpThreadInfo );
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
static DWORD CALLBACK DPLAYX_MSG_ThreadMain( LPVOID lpContext )
|
|
||||||
|
static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext )
|
||||||
{
|
{
|
||||||
HANDLE hMsgEvent = (HANDLE)lpContext;
|
LPMSGTHREADINFO lpThreadInfo = (LPMSGTHREADINFO)lpContext;
|
||||||
|
DWORD dwWaitResult;
|
||||||
|
|
||||||
|
TRACE( "Msg thread created. Waiting on app startup\n" );
|
||||||
|
|
||||||
|
/* Wait to ensure that the lobby application is started w/ 1 min timeout */
|
||||||
|
dwWaitResult = WaitForSingleObject( lpThreadInfo->hStart, 10000 /* 10 sec */ );
|
||||||
|
if( dwWaitResult == WAIT_TIMEOUT )
|
||||||
|
{
|
||||||
|
FIXME( "Should signal app/wait creation failure (0x%08lx)\n", dwWaitResult );
|
||||||
|
goto end_of_thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close this handle as it's not needed anymore */
|
||||||
|
CloseHandle( lpThreadInfo->hStart );
|
||||||
|
lpThreadInfo->hStart = 0;
|
||||||
|
|
||||||
|
/* Wait until the lobby knows what it is */
|
||||||
|
dwWaitResult = WaitForSingleObject( lpThreadInfo->hSettingRead, INFINITE );
|
||||||
|
if( dwWaitResult == WAIT_TIMEOUT )
|
||||||
|
{
|
||||||
|
ERR( "App Read connection setting timeout fail (0x%08lx)\n", dwWaitResult );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close this handle as it's not needed anymore */
|
||||||
|
CloseHandle( lpThreadInfo->hSettingRead );
|
||||||
|
lpThreadInfo->hSettingRead = 0;
|
||||||
|
|
||||||
|
TRACE( "App created && intialized starting main message reception loop\n" );
|
||||||
|
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
FIXME( "Ho Hum. Msg thread with nothing to do on handle %u\n", hMsgEvent );
|
MSG lobbyMsg;
|
||||||
|
#ifdef STRICT
|
||||||
|
HANDLE hNullHandle = NULL;
|
||||||
|
#else
|
||||||
|
HANDLE hNullHandle = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
SleepEx( 10000, FALSE ); /* 10 secs */
|
GetMessageW( &lobbyMsg, hNullHandle, 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle( hMsgEvent );
|
end_of_thread:
|
||||||
|
TRACE( "Msg thread exiting!\n" );
|
||||||
|
HeapFree( GetProcessHeap(), 0, lpThreadInfo );
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,136 @@
|
||||||
|
|
||||||
#ifndef __WINE_DPLAYX_MESSAGES
|
#ifndef __WINE_DPLAYX_MESSAGES__
|
||||||
#define __WINE_DPLAYX_MESSAGES
|
#define __WINE_DPLAYX_MESSAGES__
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
#include "dplay.h"
|
||||||
|
#include "rpc.h" /* For GUID */
|
||||||
|
|
||||||
DWORD CreateMessageReceptionThread( HANDLE hNotifyEvent );
|
DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
|
||||||
|
HANDLE hDeath, HANDLE hConnRead );
|
||||||
|
|
||||||
|
|
||||||
|
/* Message types etc. */
|
||||||
|
#include "pshpack1.h"
|
||||||
|
|
||||||
|
/* Non provided messages for DPLAY - guess work which may be wrong :( */
|
||||||
|
#define DPMSGCMD_ENUMSESSIONSREPLY 1
|
||||||
|
#define DPMSGCMD_ENUMSESSIONSREQUEST 2
|
||||||
|
|
||||||
|
#define DPMSGCMD_GETSETNAMETABLE 3 /* Request info from NS about
|
||||||
|
existing players/groups etc. Is
|
||||||
|
also used for reply */
|
||||||
|
|
||||||
|
#define DPMSGCMD_REQUESTNEWPLAYERID 5
|
||||||
|
|
||||||
|
#define DPMSGCMD_NEWPLAYERIDREPLY 7
|
||||||
|
#define DPMSGCMD_CREATESESSION 8
|
||||||
|
#define DPMSGCMD_CREATENEWPLAYER 9
|
||||||
|
#define DPMSGCMD_SYSTEMMESSAGE 10
|
||||||
|
|
||||||
|
#define DPMSGCMD_DELETEGROUP 12
|
||||||
|
|
||||||
|
#define DPMSGCMD_ENUMGROUPS 17
|
||||||
|
|
||||||
|
/* This is what DP 6 defines it as. Don't know what it means. All messages
|
||||||
|
* defined below are DPMSGVER_DP6.
|
||||||
|
*/
|
||||||
|
#define DPMSGVER_DP6 11
|
||||||
|
|
||||||
|
/* MAGIC number at the start of all dplay packets ("play" in ASCII) */
|
||||||
|
#define DPMSGMAGIC_DPLAYMSG 0x79616c70
|
||||||
|
|
||||||
|
/* All messages sent from the system are sent with this at the beginning of
|
||||||
|
* the message.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Size is 4 bytes */
|
||||||
|
typedef struct tagDPMSG_SENDENVELOPE
|
||||||
|
{
|
||||||
|
DWORD dwMagic;
|
||||||
|
WORD wCommandId;
|
||||||
|
WORD wVersion;
|
||||||
|
} DPMSG_SENDENVELOPE, *LPDPMSG_SENDENVELOPE;
|
||||||
|
typedef const DPMSG_SENDENVELOPE* LPCDPMSG_SENDENVELOPE;
|
||||||
|
|
||||||
|
typedef struct tagDPMSG_SYSMSGENVELOPE
|
||||||
|
{
|
||||||
|
DWORD dwPlayerFrom;
|
||||||
|
DWORD dwPlayerTo;
|
||||||
|
} DPMSG_SYSMSGENVELOPE, *LPDPMSG_SYSMSGENVELOPE;
|
||||||
|
typedef const DPMSG_SYSMSGENVELOPE* LPCDPMSG_SYSMSGENVELOPE;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct tagDPMSG_ENUMSESSIONSREPLY
|
||||||
|
{
|
||||||
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
DWORD dwSize; /* Size of DPSESSIONDESC2 struct */
|
||||||
|
DWORD dwFlags; /* Sessions flags */
|
||||||
|
|
||||||
|
GUID guidInstance; /* Not 100% sure this is what it is... */
|
||||||
|
|
||||||
|
GUID guidApplication;
|
||||||
|
|
||||||
|
DWORD dwMaxPlayers;
|
||||||
|
DWORD dwCurrentPlayers;
|
||||||
|
|
||||||
|
BYTE unknown[36];
|
||||||
|
#else
|
||||||
|
DPSESSIONDESC2 sd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DWORD dwUnknown; /* Seems to be equal to 0x5c which is a "\\" */
|
||||||
|
/* Encryption package string? */
|
||||||
|
|
||||||
|
/* At the end we have ... */
|
||||||
|
/* WCHAR wszSessionName[1]; Var length with NULL terminal */
|
||||||
|
|
||||||
|
} DPMSG_ENUMSESSIONSREPLY, *LPDPMSG_ENUMSESSIONSREPLY;
|
||||||
|
typedef const DPMSG_ENUMSESSIONSREPLY* LPCDPMSG_ENUMSESSIONSREPLY;
|
||||||
|
|
||||||
|
typedef struct tagDPMSG_ENUMSESSIONSREQUEST
|
||||||
|
{
|
||||||
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
|
||||||
|
GUID guidApplication;
|
||||||
|
|
||||||
|
DWORD dwPasswordSize; /* A Guess. This is normally 0x00000000. */
|
||||||
|
/* This might be the name server DPID which
|
||||||
|
is needed for the reply */
|
||||||
|
|
||||||
|
DWORD dwFlags; /* dwFlags from EnumSessions */
|
||||||
|
|
||||||
|
} DPMSG_ENUMSESSIONSREQUEST, *LPDPMSG_ENUMSESSIONSREQUEST;
|
||||||
|
typedef const DPMSG_ENUMSESSIONSREQUEST* LPCDPMSG_ENUMSESSIONSREQUEST;
|
||||||
|
|
||||||
|
/* Size is 146 received - with 18 or 20 bytes header = ~128 bytes */
|
||||||
|
typedef struct tagDPMSG_CREATESESSION
|
||||||
|
{
|
||||||
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
} DPMSG_CREATESESSION, *LPDPMSG_CREATESESSION;
|
||||||
|
typedef const DPMSG_CREATESESSION* LPCDPMSG_CREATESESSION;
|
||||||
|
|
||||||
|
/* 28 bytes - ~18 header ~= 10 bytes msg */
|
||||||
|
typedef struct tagDPMSG_REQUESTNEWPLAYERID
|
||||||
|
{
|
||||||
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} DPMSG_REQUESTNEWPLAYERID, *LPDPMSG_REQUESTNEWPLAYERID;
|
||||||
|
typedef const DPMSG_REQUESTNEWPLAYERID* LPCDPMSG_REQUESTNEWPLAYERID;
|
||||||
|
|
||||||
|
/* 64 byte - ~18 header ~= 46 bytes msg */
|
||||||
|
typedef struct tagDPMSG_NEWPLAYERIDREPLY
|
||||||
|
{
|
||||||
|
DPMSG_SENDENVELOPE envelope;
|
||||||
|
|
||||||
|
} DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_NEWPLAYERIDREPLY;
|
||||||
|
typedef const DPMSG_NEWPLAYERIDREPLY* LPCDPMSG_NEWPLAYERIDREPLY;
|
||||||
|
|
||||||
|
|
||||||
|
#include "poppack.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#ifndef __WINE_DPLAYX_QUEUE_H
|
#ifndef __WINE_DPLAYX_QUEUE_H
|
||||||
#define __WINE_DPLAYX_QUEUE_H
|
#define __WINE_DPLAYX_QUEUE_H
|
||||||
|
|
||||||
|
#include "winbase.h"
|
||||||
|
|
||||||
#define DPQ_INSERT(a,b,c) DPQ_INSERT_IN_TAIL(a,b,c)
|
#define DPQ_INSERT(a,b,c) DPQ_INSERT_IN_TAIL(a,b,c)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -33,6 +35,19 @@ do{ \
|
||||||
(head).lpQHLast = &(head).lpQHFirst; \
|
(head).lpQHLast = &(head).lpQHFirst; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* Front of the queue */
|
||||||
|
#define DPQ_FIRST( head ) ( (head).lpQHFirst )
|
||||||
|
|
||||||
|
/* Check if the queue has any elements */
|
||||||
|
#define DPQ_IS_EMPTY( head ) ( DPQ_FIRST(head) == NULL )
|
||||||
|
|
||||||
|
/* Next entry -- FIXME: Convert everything over to this macro ... */
|
||||||
|
#define DPQ_NEXT( elem ) (elem).lpQNext
|
||||||
|
|
||||||
|
#define DPQ_IS_ENDOFLIST( elem ) \
|
||||||
|
( DPQ_NEXT(elem) == NULL )
|
||||||
|
|
||||||
|
/* Insert element at end of queue */
|
||||||
#define DPQ_INSERT_IN_TAIL(head, elm, field) \
|
#define DPQ_INSERT_IN_TAIL(head, elm, field) \
|
||||||
do { \
|
do { \
|
||||||
(elm)->field.lpQNext = NULL; \
|
(elm)->field.lpQNext = NULL; \
|
||||||
|
@ -41,6 +56,7 @@ do { \
|
||||||
(head).lpQHLast = &(elm)->field.lpQNext; \
|
(head).lpQHLast = &(elm)->field.lpQNext; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* Remove element from the queue */
|
||||||
#define DPQ_REMOVE(head, elm, field) \
|
#define DPQ_REMOVE(head, elm, field) \
|
||||||
do { \
|
do { \
|
||||||
if (((elm)->field.lpQNext) != NULL) \
|
if (((elm)->field.lpQNext) != NULL) \
|
||||||
|
@ -53,18 +69,20 @@ do { \
|
||||||
|
|
||||||
/* head - pointer to DPQ_HEAD struct
|
/* head - pointer to DPQ_HEAD struct
|
||||||
* elm - how to find the next element
|
* elm - how to find the next element
|
||||||
* field - to be concatenated to rc to compare with fieldToEqual
|
* field - to be concatenated to rc to compare with fieldToCompare
|
||||||
* fieldToEqual - The value that we're looking for
|
* fieldToCompare - The value that we're comparing against
|
||||||
|
* fieldCompareOperator - The logical operator to compare field and
|
||||||
|
* fieldToCompare.
|
||||||
* rc - Variable to put the return code. Same type as (head).lpQHFirst
|
* rc - Variable to put the return code. Same type as (head).lpQHFirst
|
||||||
*/
|
*/
|
||||||
#define DPQ_FIND_ENTRY( head, elm, field, fieldToEqual, rc ) \
|
#define DPQ_FIND_ENTRY( head, elm, field, fieldCompareOperator, fieldToCompare, rc )\
|
||||||
do { \
|
do { \
|
||||||
(rc) = (head).lpQHFirst; /* NULL head? */ \
|
(rc) = (head).lpQHFirst; /* NULL head? */ \
|
||||||
\
|
\
|
||||||
while( rc ) \
|
while( rc ) \
|
||||||
{ \
|
{ \
|
||||||
/* What we're searching for? */ \
|
/* What we're searching for? */ \
|
||||||
if( (rc)->field == (fieldToEqual) ) \
|
if( (rc)->field fieldCompareOperator (fieldToCompare) ) \
|
||||||
{ \
|
{ \
|
||||||
break; /* rc == correct element */ \
|
break; /* rc == correct element */ \
|
||||||
} \
|
} \
|
||||||
|
@ -81,12 +99,14 @@ do { \
|
||||||
/* head - pointer to DPQ_HEAD struct
|
/* head - pointer to DPQ_HEAD struct
|
||||||
* elm - how to find the next element
|
* elm - how to find the next element
|
||||||
* field - to be concatenated to rc to compare with fieldToEqual
|
* field - to be concatenated to rc to compare with fieldToEqual
|
||||||
* fieldToEqual - The value that we're looking for
|
* fieldToCompare - The value that we're comparing against
|
||||||
|
* fieldCompareOperator - The logical operator to compare field and
|
||||||
|
* fieldToCompare.
|
||||||
* rc - Variable to put the return code. Same type as (head).lpQHFirst
|
* rc - Variable to put the return code. Same type as (head).lpQHFirst
|
||||||
*/
|
*/
|
||||||
#define DPQ_REMOVE_ENTRY( head, elm, field, fieldToEqual, rc ) \
|
#define DPQ_REMOVE_ENTRY( head, elm, field, fieldCompareOperator, fieldToCompare, rc )\
|
||||||
do { \
|
do { \
|
||||||
DPQ_FIND_ENTRY( head, elm, field, fieldToEqual, rc ); \
|
DPQ_FIND_ENTRY( head, elm, field, fieldCompareOperator, fieldToCompare, rc );\
|
||||||
\
|
\
|
||||||
/* Was the element found? */ \
|
/* Was the element found? */ \
|
||||||
if( rc ) \
|
if( rc ) \
|
||||||
|
@ -95,4 +115,24 @@ do { \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* Delete the entire queue
|
||||||
|
* head - pointer to the head of the queue
|
||||||
|
* field - field to access the next elements of the queue
|
||||||
|
* type - type of the pointer to the element element
|
||||||
|
* df - a delete function to be called. Declared with DPQ_DECL_DELETECB.
|
||||||
|
*/
|
||||||
|
#define DPQ_DELETEQ( head, field, type, df ) \
|
||||||
|
while( !DPQ_IS_EMPTY(head) ) \
|
||||||
|
{ \
|
||||||
|
type holder = (head).lpQHFirst; \
|
||||||
|
DPQ_REMOVE( head, holder, field ); \
|
||||||
|
df( holder ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* How to define the method to be passed to DPQ_DELETEQ */
|
||||||
|
#define DPQ_DECL_DELETECB( name, type ) void name( type elem )
|
||||||
|
|
||||||
|
/* Prototype of a method which just performs a HeapFree on the elem */
|
||||||
|
DPQ_DECL_DELETECB( cbDeleteElemFromHeap, LPVOID );
|
||||||
|
|
||||||
#endif /* __WINE_DPLAYX_QUEUE_H */
|
#endif /* __WINE_DPLAYX_QUEUE_H */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,101 +10,190 @@
|
||||||
|
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
#include "heap.h"
|
||||||
|
|
||||||
#include "dplayx_global.h"
|
#include "dplayx_global.h"
|
||||||
#include "name_server.h"
|
#include "name_server.h"
|
||||||
|
#include "dplaysp.h"
|
||||||
|
#include "dplayx_messages.h"
|
||||||
|
#include "dplayx_queue.h"
|
||||||
|
|
||||||
/* FIXME: Need to aquire the interface semaphore before didlling data */
|
/* Can't seem to solve unresolved reference even with import */
|
||||||
|
#define HACK_TIMEGETTIME
|
||||||
|
|
||||||
|
#if defined( HACK_TIMEGETTIME )
|
||||||
|
static DWORD timeGetTime(void);
|
||||||
|
#else
|
||||||
|
#include "mmsystem.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: Need to create a crit section, store and use it */
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(dplay);
|
DEFAULT_DEBUG_CHANNEL(dplay);
|
||||||
|
|
||||||
/* NS specific structures */
|
/* NS specific structures */
|
||||||
typedef struct tagNSCacheData
|
struct NSCacheData
|
||||||
{
|
{
|
||||||
struct tagNSCacheData* next;
|
DPQ_ENTRY(NSCacheData) next;
|
||||||
|
|
||||||
|
DWORD dwTime; /* Time at which data was last known valid */
|
||||||
LPDPSESSIONDESC2 data;
|
LPDPSESSIONDESC2 data;
|
||||||
|
|
||||||
} NSCacheData, *lpNSCacheData;
|
LPVOID lpNSAddrHdr;
|
||||||
|
|
||||||
typedef struct tagNSCache
|
};
|
||||||
|
typedef struct NSCacheData NSCacheData, *lpNSCacheData;
|
||||||
|
|
||||||
|
struct NSCache
|
||||||
{
|
{
|
||||||
lpNSCacheData present; /* keep track of what is to be looked at */
|
lpNSCacheData present; /* keep track of what is to be looked at when walking */
|
||||||
lpNSCacheData first;
|
|
||||||
} NSCache, *lpNSCache;
|
|
||||||
|
|
||||||
/* Local Prototypes */
|
|
||||||
static void NS_InvalidateSessionCache( lpNSCache lpCache );
|
|
||||||
|
|
||||||
|
DPQ_HEAD(NSCacheData) first;
|
||||||
|
};
|
||||||
|
typedef struct NSCache NSCache, *lpNSCache;
|
||||||
|
|
||||||
/* Name Server functions
|
/* Name Server functions
|
||||||
* ---------------------
|
* ---------------------
|
||||||
*/
|
*/
|
||||||
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd )
|
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd )
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
DPLAYX_SetLocalSession( lpsd );
|
DPLAYX_SetLocalSession( lpsd );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the given NS remote address for future reference */
|
||||||
|
void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
|
||||||
|
DWORD dwHdrSize,
|
||||||
|
LPDPMSG_ENUMSESSIONSREPLY lpMsg,
|
||||||
|
LPVOID lpNSInfo )
|
||||||
|
{
|
||||||
|
lpNSCache lpCache = (lpNSCache)lpNSInfo;
|
||||||
|
lpNSCacheData lpCacheNode;
|
||||||
|
|
||||||
|
TRACE( "%p, %p, %p\n", lpNSAddrHdr, lpMsg, lpNSInfo );
|
||||||
|
|
||||||
|
/* FIXME: Should check to see if the reply is for an existing session. If
|
||||||
|
* so we just update the contents and update the timestamp.
|
||||||
|
*/
|
||||||
|
lpCacheNode = (lpNSCacheData)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
sizeof( *lpCacheNode ) );
|
||||||
|
|
||||||
|
if( lpCacheNode == NULL )
|
||||||
|
{
|
||||||
|
ERR( "no memory for NS node\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lpCacheNode->lpNSAddrHdr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
dwHdrSize );
|
||||||
|
CopyMemory( lpCacheNode->lpNSAddrHdr, lpNSAddrHdr, dwHdrSize );
|
||||||
|
|
||||||
|
|
||||||
|
lpCacheNode->data = (LPDPSESSIONDESC2)HeapAlloc( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
sizeof( *lpCacheNode->data ) );
|
||||||
|
|
||||||
|
if( lpCacheNode->data == NULL )
|
||||||
|
{
|
||||||
|
ERR( "no memory for SESSIONDESC2\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory( lpCacheNode->data, &lpMsg->sd, sizeof( *lpCacheNode->data ) );
|
||||||
|
lpCacheNode->data->sess.lpszSessionNameA = HEAP_strdupWtoA( GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
(LPWSTR)(lpMsg+1) );
|
||||||
|
|
||||||
|
lpCacheNode->dwTime = timeGetTime();
|
||||||
|
|
||||||
|
DPQ_INSERT(lpCache->first, lpCacheNode, next );
|
||||||
|
|
||||||
|
lpCache->present = lpCacheNode;
|
||||||
|
|
||||||
|
/* Use this message as an oportunity to weed out any old sessions so
|
||||||
|
* that we don't enum them again
|
||||||
|
*/
|
||||||
|
NS_PruneSessionCache( lpNSInfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
LPVOID NS_GetNSAddr( LPVOID lpNSInfo )
|
||||||
|
{
|
||||||
|
lpNSCache lpCache = (lpNSCache)lpNSInfo;
|
||||||
|
|
||||||
|
FIXME( ":quick stub\n" );
|
||||||
|
|
||||||
|
/* Ok. Cheat and don't search for the correct stuff just take the first.
|
||||||
|
* FIXME: In the future how are we to know what is _THE_ enum we used?
|
||||||
|
*/
|
||||||
|
|
||||||
|
return lpCache->first.lpQHFirst->lpNSAddrHdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is responsible for sending a request for all other known
|
/* This function is responsible for sending a request for all other known
|
||||||
nameservers to send us what sessions they have registered locally
|
nameservers to send us what sessions they have registered locally
|
||||||
*/
|
*/
|
||||||
void NS_SendSessionRequestBroadcast( LPVOID lpNSInfo )
|
HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid,
|
||||||
|
DWORD dwFlags,
|
||||||
|
LPSPINITDATA lpSpData )
|
||||||
|
|
||||||
{
|
{
|
||||||
UINT index = 0;
|
DPSP_ENUMSESSIONSDATA data;
|
||||||
lpNSCache lpCache = (lpNSCache)lpNSInfo;
|
LPDPMSG_ENUMSESSIONSREQUEST lpMsg;
|
||||||
LPDPSESSIONDESC2 lpTmp = NULL;
|
|
||||||
|
|
||||||
/* Invalidate the session cache for the interface */
|
TRACE( "enumerating for guid %s\n", debugstr_guid( lpcGuid ) );
|
||||||
NS_InvalidateSessionCache( lpCache );
|
|
||||||
|
|
||||||
/* Add the local known sessions to the cache */
|
|
||||||
if( ( lpTmp = DPLAYX_CopyAndAllocateLocalSession( &index ) ) != NULL )
|
|
||||||
{
|
|
||||||
lpCache->first = (lpNSCacheData)HeapAlloc( GetProcessHeap(),
|
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
sizeof( *(lpCache->first) ) );
|
|
||||||
lpCache->first->data = lpTmp;
|
|
||||||
lpCache->first->next = NULL;
|
|
||||||
lpCache->present = lpCache->first;
|
|
||||||
|
|
||||||
while( ( lpTmp = DPLAYX_CopyAndAllocateLocalSession( &index ) ) != NULL )
|
/* Get the SP to deal with sending the EnumSessions request */
|
||||||
{
|
FIXME( ": not all data fields are correct\n" );
|
||||||
lpCache->present->next = (lpNSCacheData)HeapAlloc( GetProcessHeap(),
|
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
sizeof( *(lpCache->present) ) );
|
|
||||||
lpCache->present = lpCache->present->next;
|
|
||||||
lpCache->present->data = lpTmp;
|
|
||||||
lpCache->present->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lpCache->present = lpCache->first;
|
data.dwMessageSize = lpSpData->dwSPHeaderSize + sizeof( *lpMsg ); /*FIXME!*/
|
||||||
}
|
data.lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
data.dwMessageSize );
|
||||||
|
data.lpISP = lpSpData->lpISP;
|
||||||
|
data.bReturnStatus = (dwFlags & DPENUMSESSIONS_RETURNSTATUS) ? TRUE : FALSE;
|
||||||
|
|
||||||
/* Send out requests for matching sessions to all other known computers */
|
|
||||||
FIXME( ": no remote requests sent\n" );
|
lpMsg = (LPDPMSG_ENUMSESSIONSREQUEST)(((BYTE*)data.lpMessage)+lpSpData->dwSPHeaderSize);
|
||||||
/* FIXME - how to handle responses to messages anyways? */
|
|
||||||
|
/* Setup EnumSession reqest message */
|
||||||
|
lpMsg->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
|
||||||
|
lpMsg->envelope.wCommandId = DPMSGCMD_ENUMSESSIONSREQUEST;
|
||||||
|
lpMsg->envelope.wVersion = DPMSGVER_DP6;
|
||||||
|
|
||||||
|
lpMsg->dwPasswordSize = 0; /* FIXME: If enumerating passwords..? */
|
||||||
|
lpMsg->dwFlags = dwFlags;
|
||||||
|
|
||||||
|
CopyMemory( &lpMsg->guidApplication, lpcGuid, sizeof( *lpcGuid ) );
|
||||||
|
|
||||||
|
return (lpSpData->lpCB->EnumSessions)( &data );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Render all data in a session cache invalid */
|
DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData );
|
||||||
static void NS_InvalidateSessionCache( lpNSCache lpCache )
|
DPQ_DECL_DELETECB( cbDeleteNSNodeFromHeap, lpNSCacheData )
|
||||||
{
|
{
|
||||||
|
/* FIXME: Memory leak on data (contained ptrs) */
|
||||||
|
HeapFree( GetProcessHeap(), 0, elem->data );
|
||||||
|
HeapFree( GetProcessHeap(), 0, elem->lpNSAddrHdr );
|
||||||
|
HeapFree( GetProcessHeap(), 0, elem );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Render all data in a session cache invalid */
|
||||||
|
void NS_InvalidateSessionCache( LPVOID lpNSInfo )
|
||||||
|
{
|
||||||
|
lpNSCache lpCache = (lpNSCache)lpNSInfo;
|
||||||
|
|
||||||
if( lpCache == NULL )
|
if( lpCache == NULL )
|
||||||
{
|
{
|
||||||
ERR( ": invalidate non existant cache\n" );
|
ERR( ": invalidate non existant cache\n" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove everything from the cache */
|
DPQ_DELETEQ( lpCache->first, next, lpNSCacheData, cbDeleteNSNodeFromHeap );
|
||||||
while( lpCache->first )
|
|
||||||
{
|
|
||||||
lpCache->present = lpCache->first;
|
|
||||||
lpCache->first = lpCache->first->next;
|
|
||||||
HeapFree( GetProcessHeap(), 0, lpCache->present );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NULL out the cache pointers */
|
/* NULL out the walking pointer */
|
||||||
lpCache->present = NULL;
|
lpCache->present = NULL;
|
||||||
lpCache->first = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create and initialize a session cache */
|
/* Create and initialize a session cache */
|
||||||
|
@ -121,7 +210,8 @@ BOOL NS_InitializeSessionCache( LPVOID* lplpNSInfo )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpCache->first = lpCache->present = NULL;
|
DPQ_INIT(lpCache->first);
|
||||||
|
lpCache->present = NULL;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +226,7 @@ void NS_DeleteSessionCache( LPVOID lpNSInfo )
|
||||||
void NS_ResetSessionEnumeration( LPVOID lpNSInfo )
|
void NS_ResetSessionEnumeration( LPVOID lpNSInfo )
|
||||||
{
|
{
|
||||||
|
|
||||||
((lpNSCache)lpNSInfo)->present = ((lpNSCache)lpNSInfo)->first;
|
((lpNSCache)lpNSInfo)->present = ((lpNSCache)lpNSInfo)->first.lpQHFirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo )
|
LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo )
|
||||||
|
@ -144,6 +234,8 @@ LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo )
|
||||||
LPDPSESSIONDESC2 lpSessionDesc;
|
LPDPSESSIONDESC2 lpSessionDesc;
|
||||||
lpNSCache lpCache = (lpNSCache)lpNSInfo;
|
lpNSCache lpCache = (lpNSCache)lpNSInfo;
|
||||||
|
|
||||||
|
/* FIXME: The pointers could disappear when walking if a prune happens */
|
||||||
|
|
||||||
/* Test for end of the list */
|
/* Test for end of the list */
|
||||||
if( lpCache->present == NULL )
|
if( lpCache->present == NULL )
|
||||||
{
|
{
|
||||||
|
@ -153,7 +245,93 @@ LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo )
|
||||||
lpSessionDesc = lpCache->present->data;
|
lpSessionDesc = lpCache->present->data;
|
||||||
|
|
||||||
/* Advance tracking pointer */
|
/* Advance tracking pointer */
|
||||||
lpCache->present = lpCache->present->next;
|
lpCache->present = lpCache->present->next.lpQNext;
|
||||||
|
|
||||||
return lpSessionDesc;
|
return lpSessionDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This method should check to see if there are any sessions which are
|
||||||
|
* older than the criteria. If so, just delete that information.
|
||||||
|
*/
|
||||||
|
void NS_PruneSessionCache( LPVOID lpNSInfo )
|
||||||
|
{
|
||||||
|
lpNSCache lpCache = lpNSInfo;
|
||||||
|
lpNSCacheData lpCacheEntry;
|
||||||
|
|
||||||
|
DWORD dwPresentTime = timeGetTime();
|
||||||
|
#if defined( HACK_TIMEGETTIME )
|
||||||
|
DWORD dwPruneTime = dwPresentTime - 2; /* One iteration with safety */
|
||||||
|
#else
|
||||||
|
DWORD dwPruneTime = dwPresentTime - 10000 /* 10 secs? */;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FIXME( ": semi stub\n" );
|
||||||
|
|
||||||
|
/* FIXME: This doesn't handle time roll over correctly */
|
||||||
|
/* FIXME: Session memory leak on delete */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DPQ_FIND_ENTRY( lpCache->first, next, dwTime, <=, dwPruneTime, lpCacheEntry );
|
||||||
|
}
|
||||||
|
while( lpCacheEntry != NULL );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Message stuff */
|
||||||
|
void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
|
||||||
|
LPDPSP_REPLYDATA lpReplyData,
|
||||||
|
IDirectPlay2Impl* lpDP )
|
||||||
|
{
|
||||||
|
LPDPMSG_ENUMSESSIONSREPLY rmsg;
|
||||||
|
DWORD dwVariableSize;
|
||||||
|
DWORD dwVariableLen;
|
||||||
|
LPWSTR string;
|
||||||
|
/* LPDPMSG_ENUMSESSIONSREQUEST msg = (LPDPMSG_ENUMSESSIONSREQUEST)lpMsg; */
|
||||||
|
BOOL bAnsi = TRUE; /* FIXME: This needs to be in the DPLAY interface */
|
||||||
|
|
||||||
|
FIXME( ": few fixed + need to check request for response\n" );
|
||||||
|
|
||||||
|
dwVariableLen = bAnsi ? lstrlenA( lpDP->dp2->lpSessionDesc->sess.lpszSessionNameA ) + 1
|
||||||
|
: lstrlenW( lpDP->dp2->lpSessionDesc->sess.lpszSessionName ) + 1;
|
||||||
|
|
||||||
|
dwVariableSize = dwVariableLen * sizeof( WCHAR );
|
||||||
|
|
||||||
|
lpReplyData->dwMessageSize = lpDP->dp2->spData.dwSPHeaderSize +
|
||||||
|
sizeof( *rmsg ) + dwVariableSize;
|
||||||
|
lpReplyData->lpMessage = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
lpReplyData->dwMessageSize );
|
||||||
|
|
||||||
|
rmsg = (LPDPMSG_ENUMSESSIONSREPLY)lpReplyData->lpMessage;
|
||||||
|
|
||||||
|
rmsg->envelope.dwMagic = DPMSGMAGIC_DPLAYMSG;
|
||||||
|
rmsg->envelope.wCommandId = DPMSGCMD_ENUMSESSIONSREPLY;
|
||||||
|
rmsg->envelope.wVersion = DPMSGVER_DP6;
|
||||||
|
|
||||||
|
CopyMemory( &rmsg->sd, lpDP->dp2->lpSessionDesc,
|
||||||
|
sizeof( lpDP->dp2->lpSessionDesc->dwSize ) );
|
||||||
|
rmsg->dwUnknown = 0x0000005c;
|
||||||
|
if( bAnsi )
|
||||||
|
{
|
||||||
|
string = HEAP_strdupAtoW( GetProcessHeap(), 0,
|
||||||
|
lpDP->dp2->lpSessionDesc->sess.lpszSessionNameA );
|
||||||
|
/* FIXME: Memory leak */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string = lpDP->dp2->lpSessionDesc->sess.lpszSessionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
lstrcpyW( (LPWSTR)rmsg+1, string );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined( HACK_TIMEGETTIME )
|
||||||
|
DWORD timeGetTime(void)
|
||||||
|
{
|
||||||
|
static DWORD time = 0;
|
||||||
|
|
||||||
|
return time++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -3,14 +3,33 @@
|
||||||
#define __WINE_DPLAYX_NAMESERVER
|
#define __WINE_DPLAYX_NAMESERVER
|
||||||
|
|
||||||
#include "dplay.h"
|
#include "dplay.h"
|
||||||
|
#include "dplaysp.h"
|
||||||
|
#include "dplayx_messages.h"
|
||||||
|
#include "dplay_global.h"
|
||||||
|
|
||||||
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd );
|
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd );
|
||||||
void NS_SendSessionRequestBroadcast( LPVOID lpNSInfo );
|
void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
|
||||||
|
DWORD dwHdrSize,
|
||||||
|
LPDPMSG_ENUMSESSIONSREPLY lpMsg,
|
||||||
|
LPVOID lpNSInfo );
|
||||||
|
LPVOID NS_GetNSAddr( LPVOID lpNSInfo );
|
||||||
|
|
||||||
|
void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
|
||||||
|
LPDPSP_REPLYDATA lpReplyData,
|
||||||
|
IDirectPlay2Impl* lpDP );
|
||||||
|
|
||||||
|
HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid,
|
||||||
|
DWORD dwFlags,
|
||||||
|
LPSPINITDATA lpSpData );
|
||||||
|
|
||||||
|
|
||||||
BOOL NS_InitializeSessionCache( LPVOID* lplpNSInfo );
|
BOOL NS_InitializeSessionCache( LPVOID* lplpNSInfo );
|
||||||
void NS_DeleteSessionCache( LPVOID lpNSInfo );
|
void NS_DeleteSessionCache( LPVOID lpNSInfo );
|
||||||
|
void NS_InvalidateSessionCache( LPVOID lpNSInfo );
|
||||||
|
|
||||||
|
|
||||||
void NS_ResetSessionEnumeration( LPVOID lpNSInfo );
|
void NS_ResetSessionEnumeration( LPVOID lpNSInfo );
|
||||||
LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo );
|
LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo );
|
||||||
|
void NS_PruneSessionCache( LPVOID lpNSInfo );
|
||||||
|
|
||||||
#endif /* __WINE_DPLAYX_NAMESERVER */
|
#endif /* __WINE_DPLAYX_NAMESERVER */
|
||||||
|
|
|
@ -13,6 +13,13 @@ extern "C" {
|
||||||
|
|
||||||
#include "pshpack1.h"
|
#include "pshpack1.h"
|
||||||
|
|
||||||
|
typedef LPVOID (*LPRGLPVOID)[];
|
||||||
|
typedef LPRGLPVOID PRGPVOID, LPRGPVOID, PRGLPVOID, PAPVOID, LPAPVOID, PALPVOID, LPALPVOID;
|
||||||
|
|
||||||
|
#define VOL volatile
|
||||||
|
typedef VOID *VOL LPVOIDV;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Predeclare the interfaces
|
* Predeclare the interfaces
|
||||||
*/
|
*/
|
||||||
|
@ -283,6 +290,13 @@ typedef struct tagDPCHAT
|
||||||
}msgstr;
|
}msgstr;
|
||||||
} DPCHAT, *LPDPCHAT;
|
} DPCHAT, *LPDPCHAT;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UINT len;
|
||||||
|
PUCHAR pData;
|
||||||
|
} SGBUFFER, *PSGBUFFER, *LPSGBUFFER;
|
||||||
|
|
||||||
|
|
||||||
typedef struct tagDPSECURITYDESC
|
typedef struct tagDPSECURITYDESC
|
||||||
{
|
{
|
||||||
DWORD dwSize; /* Size of structure */
|
DWORD dwSize; /* Size of structure */
|
||||||
|
@ -342,14 +356,7 @@ typedef BOOL CALLBACK (*LPDPENUMDPCALLBACKA)(
|
||||||
DWORD dwMinorVersion, /* Minor # of driver spec in lpguidSP */
|
DWORD dwMinorVersion, /* Minor # of driver spec in lpguidSP */
|
||||||
LPVOID lpContext); /* User given */
|
LPVOID lpContext); /* User given */
|
||||||
|
|
||||||
/* NOTE: This isn't in the dplay.h header file, but this shouldn't be
|
|
||||||
* a problem. We require this because we include all these header files
|
|
||||||
* which declare GUIDs in guid.c
|
|
||||||
*/
|
|
||||||
#ifndef __LPCGUID_DEFINED__
|
|
||||||
#define __LPCGUID_DEFINED__
|
|
||||||
typedef const GUID *LPCGUID;
|
typedef const GUID *LPCGUID;
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef const DPNAME *LPCDPNAME;
|
typedef const DPNAME *LPCDPNAME;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ VPATH = @srcdir@
|
||||||
MODULE = ole
|
MODULE = ole
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
guid.c \
|
|
||||||
ole2nls.c
|
ole2nls.c
|
||||||
|
|
||||||
EXTRASUBDIRS = nls
|
EXTRASUBDIRS = nls
|
||||||
|
|
32
ole/guid.c
32
ole/guid.c
|
@ -1,32 +0,0 @@
|
||||||
#define INITGUID
|
|
||||||
|
|
||||||
/* FIXME: we include all the header files containing GUIDs
|
|
||||||
* so that the corresponding variables get defined. But they
|
|
||||||
* don't even all belong to the same DLL !!!
|
|
||||||
*
|
|
||||||
* Therefore, as the builtin DLL's get teased apart (e.g. for elf-dlls)
|
|
||||||
* then this file will have to be partitioned into per dll files.
|
|
||||||
*/
|
|
||||||
#include "initguid.h"
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#include "shlguid.h"
|
|
||||||
#include "docobj.h"
|
|
||||||
#include "olectl.h"
|
|
||||||
#include "oleidl.h"
|
|
||||||
#include "oaidl.h"
|
|
||||||
#include "ocidl.h"
|
|
||||||
#include "objbase.h"
|
|
||||||
#include "servprov.h"
|
|
||||||
#include "ddraw.h"
|
|
||||||
#include "d3d.h"
|
|
||||||
#include "dinput.h"
|
|
||||||
#include "dsound.h"
|
|
||||||
#include "dplay.h"
|
|
||||||
#include "dplobby.h"
|
|
||||||
#include "vfw.h"
|
|
||||||
#include "shlobj.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* and now for the one assumed GUID... */
|
|
||||||
DEFINE_GUID(GUID_NULL, 0,0,0,0,0,0,0,0,0,0,0);
|
|
Loading…
Reference in New Issue