blob: ed8a66d4ee08ab0e9a966cd3c5b2deab96800120 [file] [log] [blame]
/* Direct Play Lobby 2 & 3 Implementation
*
* Copyright 1998,1999 - Peter Hunnisett
*
* <presently under construction - contact hunnise@nortelnetworks.com>
*
*/
#include <string.h>
#include "winerror.h"
#include "winnt.h"
#include "winreg.h"
#include "dplobby.h"
#include "heap.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(dplay)
/*****************************************************************************
* Predeclare the interface implementation structures
*/
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyAImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyWImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobby2Impl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobby2AImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobby3Impl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobby3AImpl;
/*****************************************************************************
* IDirectPlayLobby {1,2,3} implementation structure
*
* The philosophy behind this extra pointer derefernce is that I wanted to
* have the same structure for all types of objects without having to do
* alot of casting. I also only wanted to implement an interface in the
* object it was "released" with IUnknown interface being implemented in the 1 version.
* Of course, with these new interfaces comes the data required to keep the state required
* by these interfaces. So, basically, the pointers contain the data associated with
* a release. If you use the data associated with release 3 in a release 2 object, you'll
* get a run time trap, as that won't have any data.
*
*/
typedef struct tagDirectPlayLobbyIUnknownData
{
DWORD ref;
CRITICAL_SECTION DPL_lock;
} DirectPlayLobbyIUnknownData;
/* FIXME: I don't think that everything belongs here...*/
typedef struct tagDirectPlayLobbyData
{
DWORD dwConnFlags;
DPSESSIONDESC2 sessionDesc;
DPNAME playerName;
GUID guidSP;
LPVOID lpAddress;
DWORD dwAddressSize;
} DirectPlayLobbyData;
typedef struct tagDirectPlayLobby2Data
{
BOOL dummy;
} DirectPlayLobby2Data;
typedef struct tagDirectPlayLobby3Data
{
BOOL dummy;
} DirectPlayLobby3Data;
struct IDirectPlayLobbyImpl
{
ICOM_VFIELD(IDirectPlayLobby);
/* IUnknown fields */
DirectPlayLobbyIUnknownData* unk;
/* IDirectPlayLobby 1 fields */
DirectPlayLobbyData* dpl;
/* IDirectPlayLobby 2 fields */
DirectPlayLobby2Data* dpl2;
/* IDirectPlayLobby 3 fields */
DirectPlayLobby3Data* dpl3;
};
/* Forward declarations of virtual tables */
static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT;
static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyWVT;
static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT;
static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2WVT;
static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3AVT;
static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3WVT;
/* The COM interface for upversioning an interface
* We've been given a GUID (riid) and we need to replace the present
* interface with that of the requested interface.
*
* Snip from some Microsoft document:
* There are four requirements for implementations of QueryInterface (In these
* cases, "must succeed" means "must succeed barring catastrophic failure."):
*
* * The set of interfaces accessible on an object through
* IUnknown::QueryInterface must be static, not dynamic. This means that
* if a call to QueryInterface for a pointer to a specified interface
* succeeds the first time, it must succeed again, and if it fails the
* first time, it must fail on all subsequent queries.
* * It must be symmetric ~W if a client holds a pointer to an interface on
* an object, and queries for that interface, the call must succeed.
* * It must be reflexive ~W if a client holding a pointer to one interface
* queries successfully for another, a query through the obtained pointer
* for the first interface must succeed.
* * It must be transitive ~W if a client holding a pointer to one interface
* queries successfully for a second, and through that pointer queries
* successfully for a third interface, a query for the first interface
* through the pointer for the third interface must succeed.
*
* As you can see, this interface doesn't qualify but will most likely
* be good enough for the time being.
*/
BOOL DPL_CreateIUnknown( IDirectPlayLobbyImpl* lpDPL )
{
lpDPL->unk = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(lpDPL->unk) ) );
if ( lpDPL->unk != NULL )
{
InitializeCriticalSection( &lpDPL->unk->DPL_lock );
IDirectPlayLobby_AddRef( (IDirectPlayLobby*)lpDPL );
return TRUE;
}
return FALSE;
}
BOOL DPL_DestroyIUnknown( IDirectPlayLobbyImpl* lpDPL )
{
DeleteCriticalSection( &lpDPL->unk->DPL_lock );
HeapFree( GetProcessHeap(), 0, lpDPL->unk );
return TRUE;
}
BOOL DPL_CreateLobby1( IDirectPlayLobbyImpl* lpDPL )
{
lpDPL->dpl = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(lpDPL->dpl) ) );
if ( lpDPL->dpl == NULL )
{
return FALSE;
}
/* Initialize the dwSize fields for internal structures */
lpDPL->dpl->sessionDesc.dwSize = sizeof( lpDPL->dpl->sessionDesc );
lpDPL->dpl->playerName.dwSize = sizeof( lpDPL->dpl->playerName );
/* lpDPL->dpl->dwAddressSize = 0; Done in HeapAlloc */
return TRUE;
}
BOOL DPL_DestroyLobby1( IDirectPlayLobbyImpl* lpDPL )
{
/* Delete the contents */
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->sessionDesc.sess.lpszSessionNameA );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->sessionDesc.pass.lpszPasswordA );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->playerName.psn.lpszShortNameA );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->playerName.pln.lpszLongNameA );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->lpAddress );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl );
return TRUE;
}
BOOL DPL_CreateLobby2( IDirectPlayLobbyImpl* lpDPL )
{
lpDPL->dpl2 = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(lpDPL->dpl2) ) );
if ( lpDPL->dpl2 == NULL )
{
return FALSE;
}
return TRUE;
}
BOOL DPL_DestroyLobby2( IDirectPlayLobbyImpl* lpDPL )
{
HeapFree( GetProcessHeap(), 0, lpDPL->dpl2 );
return TRUE;
}
BOOL DPL_CreateLobby3( IDirectPlayLobbyImpl* lpDPL )
{
lpDPL->dpl3 = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(lpDPL->dpl3) ) );
if ( lpDPL->dpl3 == NULL )
{
return FALSE;
}
return TRUE;
}
BOOL DPL_DestroyLobby3( IDirectPlayLobbyImpl* lpDPL )
{
HeapFree( GetProcessHeap(), 0, lpDPL->dpl3 );
return TRUE;
}
/* Helper function for DirectPlayLobby QueryInterface */
extern
HRESULT directPlayLobby_QueryInterface
( REFIID riid, LPVOID* ppvObj )
{
IDirectPlayLobby3AImpl* lpDPL = NULL;
if( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
{
lpDPL = (IDirectPlayLobbyImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
if( !lpDPL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobbyWVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
else if( IsEqualGUID( &IID_IDirectPlayLobbyA, riid ) )
{
lpDPL = (IDirectPlayLobbyAImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
if( !lpDPL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobbyAVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
else if( IsEqualGUID( &IID_IDirectPlayLobby2, riid ) )
{
lpDPL = (IDirectPlayLobby2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
if( !lpDPL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobby2WVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL ) &&
DPL_CreateLobby2( lpDPL )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
else if( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
{
lpDPL = (IDirectPlayLobby2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
if( !lpDPL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobby2AVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL ) &&
DPL_CreateLobby2( lpDPL )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
else if( IsEqualGUID( &IID_IDirectPlayLobby3, riid ) )
{
lpDPL = (IDirectPlayLobby3Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
if( !lpDPL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobby3WVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL ) &&
DPL_CreateLobby2( lpDPL ) &&
DPL_CreateLobby3( lpDPL )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
else if( IsEqualGUID( &IID_IDirectPlayLobby3A, riid ) )
{
lpDPL = (IDirectPlayLobby3AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
if( !lpDPL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobby3AVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL ) &&
DPL_CreateLobby2( lpDPL ) &&
DPL_CreateLobby3( lpDPL )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
/* Check if we had problems creating an interface */
if ( lpDPL != NULL )
{
DPL_DestroyLobby3( lpDPL );
DPL_DestroyLobby2( lpDPL );
DPL_DestroyLobby1( lpDPL );
DPL_DestroyIUnknown( lpDPL );
HeapFree( GetProcessHeap(), 0, lpDPL );
*ppvObj = NULL;
return DPERR_NOMEMORY;
}
else /* Unsupported interface */
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
}
static HRESULT WINAPI IDirectPlayLobbyAImpl_QueryInterface
( LPDIRECTPLAYLOBBYA iface,
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby2Impl,iface);
TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
if( IsEqualGUID( &IID_IUnknown, riid ) ||
IsEqualGUID( &IID_IDirectPlayLobbyA, riid )
)
{
IDirectPlayLobby_AddRef( iface );
*ppvObj = This;
return S_OK;
}
return directPlayLobby_QueryInterface( riid, ppvObj );
}
static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
( LPDIRECTPLAYLOBBY iface,
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
if( IsEqualGUID( &IID_IUnknown, riid ) ||
IsEqualGUID( &IID_IDirectPlayLobby, riid )
)
{
IDirectPlayLobby_AddRef( iface );
*ppvObj = This;
return S_OK;
}
return directPlayLobby_QueryInterface( riid, ppvObj );
}
static HRESULT WINAPI IDirectPlayLobby2AImpl_QueryInterface
( LPDIRECTPLAYLOBBY2A iface,
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby2Impl,iface);
TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
/* Compare riids. We know this object is a direct play lobby 2A object.
If we are asking about the same type of interface we're fine.
*/
if( IsEqualGUID( &IID_IUnknown, riid ) ||
IsEqualGUID( &IID_IDirectPlayLobby2A, riid )
)
{
IDirectPlayLobby_AddRef( iface );
*ppvObj = This;
return S_OK;
}
return directPlayLobby_QueryInterface( riid, ppvObj );
}
static HRESULT WINAPI IDirectPlayLobby2WImpl_QueryInterface
( LPDIRECTPLAYLOBBY2 iface,
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby2Impl,iface);
/* Compare riids. We know this object is a direct play lobby 2 object.
If we are asking about the same type of interface we're fine.
*/
if( IsEqualGUID( &IID_IUnknown, riid ) ||
IsEqualGUID( &IID_IDirectPlayLobby2, riid )
)
{
IDirectPlayLobby_AddRef( iface );
*ppvObj = This;
return S_OK;
}
return directPlayLobby_QueryInterface( riid, ppvObj );
}
static HRESULT WINAPI IDirectPlayLobby3AImpl_QueryInterface
( LPDIRECTPLAYLOBBY3A iface,
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby3Impl,iface);
/* Compare riids. We know this object is a direct play lobby 3 object.
If we are asking about the same type of interface we're fine.
*/
if( IsEqualGUID( &IID_IUnknown, riid ) ||
IsEqualGUID( &IID_IDirectPlayLobby3A, riid )
)
{
IDirectPlayLobby_AddRef( This );
*ppvObj = This;
return S_OK;
}
return directPlayLobby_QueryInterface( riid, ppvObj );
}
static HRESULT WINAPI IDirectPlayLobby3WImpl_QueryInterface
( LPDIRECTPLAYLOBBY3 iface,
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby3Impl,iface);
/* Compare riids. We know this object is a direct play lobby 3 object.
If we are asking about the same type of interface we're fine.
*/
if( IsEqualGUID( &IID_IUnknown, riid ) ||
IsEqualGUID( &IID_IDirectPlayLobby3, riid )
)
{
IDirectPlayLobby_AddRef( iface );
*ppvObj = This;
return S_OK;
}
return directPlayLobby_QueryInterface( riid, ppvObj );
}
/*
* Simple procedure. Just increment the reference count to this
* structure and return the new reference count.
*/
static ULONG WINAPI IDirectPlayLobbyAImpl_AddRef
( LPDIRECTPLAYLOBBYA iface )
{
ULONG refCount;
ICOM_THIS(IDirectPlayLobby2Impl,iface);
EnterCriticalSection( &This->unk->DPL_lock );
{
refCount = ++(This->unk->ref);
}
LeaveCriticalSection( &This->unk->DPL_lock );
TRACE("ref count incremented to %lu for %p\n", refCount, This );
return refCount;
}
/*
* Simple COM procedure. Decrease the reference count to this object.
* If the object no longer has any reference counts, free up the associated
* memory.
*/
static ULONG WINAPI IDirectPlayLobbyAImpl_Release
( LPDIRECTPLAYLOBBYA iface )
{
ULONG refCount;
ICOM_THIS(IDirectPlayLobby2Impl,iface);
EnterCriticalSection( &This->unk->DPL_lock );
{
refCount = --(This->unk->ref);
}
LeaveCriticalSection( &This->unk->DPL_lock );
TRACE("ref count decremeneted to %lu for %p\n", refCount, This );
/* Deallocate if this is the last reference to the object */
if( refCount )
{
DPL_DestroyLobby3( This );
DPL_DestroyLobby2( This );
DPL_DestroyLobby1( This );
DPL_DestroyIUnknown( This );
HeapFree( GetProcessHeap(), 0, This );
}
return refCount;
}
/********************************************************************
*
* Connects an application to the session specified by the DPLCONNECTION
* structure currently stored with the DirectPlayLobby object.
*
* Returns a IDirectPlay interface.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
LPDIRECTPLAY2A* lplpDP,
IUnknown* pUnk)
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
LPDIRECTPLAY2A lpDirectPlay2A;
LPDIRECTPLAY3A lpDirectPlay3A;
LPDIRECTPLAYLOBBY2A lpDirectPlayLobby2A;
HRESULT rc;
FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, dwFlags, lplpDP, pUnk );
if( dwFlags || pUnk )
{
return DPERR_INVALIDPARAMS;
}
if( ( rc = DirectPlayCreate( (LPGUID)&IID_IDirectPlay2A, lplpDP, pUnk ) ) != DP_OK )
{
ERR("error creating Direct Play 2W interface. Return Code = 0x%lx.\n", rc );
return rc;
}
lpDirectPlay2A = *lplpDP;
/* This should invoke IDirectPlay3::InitializeConnection IDirectPlay3::Open */
/* - Use This object to get a DPL2 object using QueryInterface
* - Need to call CreateCompoundAddress to create the lpConnection param for IDirectPlay::InitializeConnection
* - Call IDirectPlay::InitializeConnection
* - Call IDirectPlay::Open
*/
#if 0
create_address:
{
DPCOMPOUNDADDRESSELEMENT compoundAddress;
/* Get lobby version capable of supporting CreateCompoundAddress */
if( ( rc = IDirectPlayLobby_QueryInterface( This, &IID_IDirectPlayLobby2A, &lpDirectPlayLobby2A ) ) != DP_OK )
{
return rc;
}
EnterCriticalSection( &This->unk->DPL_lock );
/* Actually create the compound address */
memcpy( compoundAddress.guidDataType, This->dpl->guidSP, sizeof( compoundAddress.guidDataType ) );
LeaveCriticalSection( &This->unk->DPL_lock );
rc = IDirectPlayLobby_CreateCompoundAddress( lpDirectPlayLobby2A, lpElements, dwElementCount, lpAddress, lpdwAddressSize )
/* Free the lobby object since we're done with it */
IDirectPlayLobby_Release( lpDirectPlayLobby2A );
if( rc != DP_OK )
{
return rc;
}
}
if( ( rc = IDirectPlayX_QueryInterface( directPlay2A, &IID_IDirectPlay3A, &lpDirectPlay3A ) ) != DP_OK )
{
return rc;
}
#endif
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
LPDIRECTPLAY2* lplpDP,
IUnknown* pUnk)
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
LPDIRECTPLAY2* directPlay2W;
HRESULT createRC;
FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, dwFlags, lplpDP, pUnk );
if( dwFlags || pUnk )
{
return DPERR_INVALIDPARAMS;
}
if( ( createRC = DirectPlayCreate( (LPGUID)&IID_IDirectPlay2, lplpDP, pUnk ) ) != DP_OK )
{
ERR("error creating Direct Play 2W interface. Return Code = 0x%lx.\n", createRC );
return createRC;
}
/* This should invoke IDirectPlay3::InitializeConnection IDirectPlay3::Open */
directPlay2W = lplpDP;
return DP_OK;
}
/********************************************************************
*
* Creates a DirectPlay Address, given a service provider-specific network
* address.
* Returns an address contains the globally unique identifier
* (GUID) of the service provider and data that the service provider can
* interpret as a network address.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
( LPDIRECTPLAYLOBBYA iface,
REFGUID guidSP,
REFGUID guidDataType,
LPCVOID lpData,
DWORD dwDataSize,
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
( LPDIRECTPLAYLOBBY iface,
REFGUID guidSP,
REFGUID guidDataType,
LPCVOID lpData,
DWORD dwDataSize,
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Parses out chunks from the DirectPlay Address buffer by calling the
* given callback function, with lpContext, for each of the chunks.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress
( LPDIRECTPLAYLOBBYA iface,
LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
LPCVOID lpAddress,
DWORD dwAddressSize,
LPVOID lpContext )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddress
( LPDIRECTPLAYLOBBY iface,
LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
LPCVOID lpAddress,
DWORD dwAddressSize,
LPVOID lpContext )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Enumerates all the address types that a given service provider needs to
* build the DirectPlay Address.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes
( LPDIRECTPLAYLOBBYA iface,
LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
REFGUID guidSP,
LPVOID lpContext,
DWORD dwFlags )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddressTypes
( LPDIRECTPLAYLOBBY iface,
LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback,
REFGUID guidSP,
LPVOID lpContext,
DWORD dwFlags )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Enumerates what applications are registered with DirectPlay by
* invoking the callback function with lpContext.
*
*/
static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumLocalApplications
( LPDIRECTPLAYLOBBY iface,
LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback,
LPVOID lpContext,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications
( LPDIRECTPLAYLOBBYA iface,
LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback,
LPVOID lpContext,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Retrieves the DPLCONNECTION structure that contains all the information
* needed to start and connect an application. This was generated using
* either the RunApplication or SetConnectionSettings methods.
*
* NOTES: If lpData is NULL then just return lpdwDataSize. This allows
* the data structure to be allocated by our caller which can then
* call this procedure/method again with a valid data pointer.
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
( LPDIRECTPLAYLOBBYA iface,
DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
LPDPLCONNECTION lpDplConnection;
FIXME(": semi stub (%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
/* Application is requesting us to give the required size */
if ( lpData == NULL )
{
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
}
/* Let's check the size of the buffer that the application has allocated */
if ( *lpdwDataSize < sizeof( DPLCONNECTION ) )
{
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
}
/* FIXME: Who's supposed to own the data */
/* Fill in the fields - let them just use the ptrs */
lpDplConnection = (LPDPLCONNECTION)lpData;
/* Copy everything we've got into here */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplConnection->dwFlags = This->dpl->dwConnFlags;
/* Copy LPDPSESSIONDESC2 struct */
lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( This->dpl->sessionDesc ) );
memcpy( lpDplConnection->lpSessionDesc, &This->dpl->sessionDesc, sizeof( This->dpl->sessionDesc ) );
if( This->dpl->sessionDesc.sess.lpszSessionName )
{
lpDplConnection->lpSessionDesc->sess.lpszSessionName =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->sessionDesc.sess.lpszSessionNameA );
}
if( This->dpl->sessionDesc.pass.lpszPassword )
{
lpDplConnection->lpSessionDesc->pass.lpszPassword =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->sessionDesc.pass.lpszPasswordA );
}
lpDplConnection->lpSessionDesc->dwReserved1 = This->dpl->sessionDesc.dwReserved1;
lpDplConnection->lpSessionDesc->dwReserved2 = This->dpl->sessionDesc.dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( This->dpl->playerName ) );
memcpy( lpDplConnection->lpPlayerName, &(This->dpl->playerName), sizeof( This->dpl->playerName ) );
if( This->dpl->playerName.psn.lpszShortName )
{
lpDplConnection->lpPlayerName->psn.lpszShortName =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->playerName.psn.lpszShortNameA );
}
if( This->dpl->playerName.pln.lpszLongName )
{
lpDplConnection->lpPlayerName->pln.lpszLongName =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->playerName.pln.lpszLongNameA );
}
memcpy( &lpDplConnection->guidSP, &This->dpl->guidSP, sizeof( This->dpl->guidSP ) );
lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->dwAddressSize );
memcpy( lpDplConnection->lpAddress, This->dpl->lpAddress, This->dpl->dwAddressSize );
lpDplConnection->dwAddressSize = This->dpl->dwAddressSize;
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
( LPDIRECTPLAYLOBBY iface,
DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
FIXME(":semi stub %p %08lx %p %p \n", This, dwAppID, lpData, lpdwDataSize );
/* Application is requesting us to give the required size */
if ( !lpData )
{
/* Let's check the size of the buffer that the application has allocated */
if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
{
return DP_OK;
}
else
{
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
}
}
/* Fill in the fields - see above */
FIXME("stub\n" );
return DP_OK;
}
/********************************************************************
*
* Retrieves the message sent between a lobby client and a DirectPlay
* application. All messages are queued until received.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
DWORD dwAppID,
LPDWORD lpdwMessageFlags,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
lpdwDataSize );
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_ReceiveLobbyMessage
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
DWORD dwAppID,
LPDWORD lpdwMessageFlags,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
lpdwDataSize );
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Starts an application and passes to it all the information to
* connect to a session.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
LPDWORD lpdwAppID,
LPDPLCONNECTION lpConn,
HANDLE hReceiveEvent )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_RunApplication
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
LPDWORD lpdwAppID,
LPDPLCONNECTION lpConn,
HANDLE hReceiveEvent )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Sends a message between the application and the lobby client.
* All messages are queued until received.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_SendLobbyMessage
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
DWORD dwAppID,
LPVOID lpData,
DWORD dwDataSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_SendLobbyMessage
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
DWORD dwAppID,
LPVOID lpData,
DWORD dwDataSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Modifies the DPLCONNECTION structure to contain all information
* needed to start and connect an application.
*
*/
static HRESULT WINAPI IDirectPlayLobbyWImpl_SetConnectionSettings
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
TRACE(": This=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p\n",
This, dwFlags, dwAppID, lpConn );
/* Paramater check */
if( dwFlags || !This || !lpConn )
{
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
}
/* See if there is a connection associated with this request.
* dwAppID == 0 indicates that this request isn't associated with a connection.
*/
if( dwAppID )
{
FIXME(": Connection dwAppID=%08lx given. Not implemented yet.\n",
dwAppID );
/* Need to add a check for this application Id...*/
return DPERR_NOTLOBBIED;
}
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
}
/* Need to investigate the lpConn->lpSessionDesc to figure out
* what type of session we need to join/create.
*/
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
{
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
}
EnterCriticalSection( &This->unk->DPL_lock );
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
This->dpl->dwConnFlags = lpConn->dwFlags;
/* Copy LPDPSESSIONDESC2 struct - this is required */
memcpy( &This->dpl->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
if( lpConn->lpSessionDesc->sess.lpszSessionName )
This->dpl->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
else
This->dpl->sessionDesc.sess.lpszSessionName = NULL;
if( lpConn->lpSessionDesc->pass.lpszPassword )
This->dpl->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
else
This->dpl->sessionDesc.pass.lpszPassword = NULL;
This->dpl->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
This->dpl->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
if( lpConn->lpPlayerName )
{
memcpy( &This->dpl->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
if( lpConn->lpPlayerName->psn.lpszShortName )
This->dpl->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName );
if( lpConn->lpPlayerName->pln.lpszLongName )
This->dpl->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
}
memcpy( &This->dpl->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
This->dpl->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
memcpy( This->dpl->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
This->dpl->dwAddressSize = lpConn->dwAddressSize;
LeaveCriticalSection( &This->unk->DPL_lock );
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
TRACE(": This=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p\n",
This, dwFlags, dwAppID, lpConn );
/* Paramater check */
if( dwFlags || !This || !lpConn )
{
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
}
/* See if there is a connection associated with this request.
* dwAppID == 0 indicates that this request isn't associated with a connection.
*/
if( dwAppID )
{
FIXME(": Connection dwAppID=%08lx given. Not implemented yet.\n",
dwAppID );
/* Need to add a check for this application Id...*/
return DPERR_NOTLOBBIED;
}
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
}
/* Need to investigate the lpConn->lpSessionDesc to figure out
* what type of session we need to join/create.
*/
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
{
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
}
EnterCriticalSection( &This->unk->DPL_lock );
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
This->dpl->dwConnFlags = lpConn->dwFlags;
/* Copy LPDPSESSIONDESC2 struct - this is required */
memcpy( &This->dpl->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
This->dpl->sessionDesc.sess.lpszSessionNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionNameA );
else
This->dpl->sessionDesc.sess.lpszSessionNameA = NULL;
if( lpConn->lpSessionDesc->pass.lpszPasswordA )
This->dpl->sessionDesc.pass.lpszPasswordA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPasswordA );
else
This->dpl->sessionDesc.pass.lpszPasswordA = NULL;
This->dpl->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
This->dpl->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
if( lpConn->lpPlayerName )
{
memcpy( &This->dpl->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
if( lpConn->lpPlayerName->psn.lpszShortNameA )
This->dpl->playerName.psn.lpszShortNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortNameA );
if( lpConn->lpPlayerName->pln.lpszLongNameA )
This->dpl->playerName.pln.lpszLongNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongNameA );
}
memcpy( &This->dpl->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
This->dpl->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
memcpy( This->dpl->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
This->dpl->dwAddressSize = lpConn->dwAddressSize;
LeaveCriticalSection( &This->unk->DPL_lock );
return DP_OK;
}
/********************************************************************
*
* Registers an event that will be set when a lobby message is received.
*
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_SetLobbyMessageEvent
( LPDIRECTPLAYLOBBYA iface,
DWORD dwFlags,
DWORD dwAppID,
HANDLE hReceiveEvent )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_SetLobbyMessageEvent
( LPDIRECTPLAYLOBBY iface,
DWORD dwFlags,
DWORD dwAppID,
HANDLE hReceiveEvent )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
/* DPL 2 methods - well actuall only one */
/********************************************************************
*
* Registers an event that will be set when a lobby message is received.
*
*/
static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateCompoundAddress
( LPDIRECTPLAYLOBBY2 iface,
LPCDPCOMPOUNDADDRESSELEMENT lpElements,
DWORD dwElementCount,
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
( LPDIRECTPLAYLOBBY2A iface,
LPCDPCOMPOUNDADDRESSELEMENT lpElements,
DWORD dwElementCount,
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
}
/* DPL 3 methods */
static HRESULT WINAPI IDirectPlayLobby3WImpl_ConnectEx
( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags, REFIID riid, LPVOID* lplpDP, IUnknown* pUnk )
{
FIXME(":stub\n");
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobby3AImpl_ConnectEx
( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags, REFIID riid, LPVOID* lplpDP, IUnknown* pUnk )
{
FIXME(":stub\n");
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobby3WImpl_RegisterApplication
( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags, LPDPAPPLICATIONDESC lpAppDesc )
{
FIXME(":stub\n");
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobby3AImpl_RegisterApplication
( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags, LPDPAPPLICATIONDESC lpAppDesc )
{
FIXME(":stub\n");
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobby3WImpl_UnregisterApplication
( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags, REFGUID lpAppDesc )
{
FIXME(":stub\n");
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobby3AImpl_UnregisterApplication
( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags, REFGUID lpAppDesc )
{
FIXME(":stub\n");
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobby3WImpl_WaitForConnectionSettings
( LPDIRECTPLAYLOBBY3 iface, DWORD dwFlags )
{
FIXME(":stub\n");
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobby3AImpl_WaitForConnectionSettings
( LPDIRECTPLAYLOBBY3A iface, DWORD dwFlags )
{
FIXME(":stub\n");
return DP_OK;
}
/* Virtual Table definitions for DPL{1,2,3}{A,W} */
/* Note: Hack so we can reuse the old functions without compiler warnings */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(directPlayLobbyAVT.fn##fun))
#else
# define XCAST(fun) (void*)
#endif
/* Direct Play Lobby 1 (ascii) Virtual Table for methods */
/* All lobby 1 methods are exactly the same except QueryInterface */
static struct ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobbyAImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
IDirectPlayLobbyAImpl_Connect,
IDirectPlayLobbyAImpl_CreateAddress,
IDirectPlayLobbyAImpl_EnumAddress,
IDirectPlayLobbyAImpl_EnumAddressTypes,
IDirectPlayLobbyAImpl_EnumLocalApplications,
IDirectPlayLobbyAImpl_GetConnectionSettings,
IDirectPlayLobbyAImpl_ReceiveLobbyMessage,
IDirectPlayLobbyAImpl_RunApplication,
IDirectPlayLobbyAImpl_SendLobbyMessage,
IDirectPlayLobbyAImpl_SetConnectionSettings,
IDirectPlayLobbyAImpl_SetLobbyMessageEvent
};
#undef XCAST
/* Note: Hack so we can reuse the old functions without compiler warnings */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(directPlayLobbyWVT.fn##fun))
#else
# define XCAST(fun) (void*)
#endif
/* Direct Play Lobby 1 (unicode) Virtual Table for methods */
static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyWVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobbyW_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
IDirectPlayLobbyWImpl_Connect,
IDirectPlayLobbyWImpl_CreateAddress,
IDirectPlayLobbyWImpl_EnumAddress,
IDirectPlayLobbyWImpl_EnumAddressTypes,
IDirectPlayLobbyWImpl_EnumLocalApplications,
IDirectPlayLobbyWImpl_GetConnectionSettings,
IDirectPlayLobbyWImpl_ReceiveLobbyMessage,
IDirectPlayLobbyWImpl_RunApplication,
IDirectPlayLobbyWImpl_SendLobbyMessage,
IDirectPlayLobbyWImpl_SetConnectionSettings,
IDirectPlayLobbyWImpl_SetLobbyMessageEvent
};
#undef XCAST
/* Note: Hack so we can reuse the old functions without compiler warnings */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(directPlayLobby2AVT.fn##fun))
#else
# define XCAST(fun) (void*)
#endif
/* Direct Play Lobby 2 (ascii) Virtual Table for methods */
static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobby2AImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
XCAST(Connect)IDirectPlayLobbyAImpl_Connect,
XCAST(CreateAddress)IDirectPlayLobbyAImpl_CreateAddress,
XCAST(EnumAddress)IDirectPlayLobbyAImpl_EnumAddress,
XCAST(EnumAddressTypes)IDirectPlayLobbyAImpl_EnumAddressTypes,
XCAST(EnumLocalApplications)IDirectPlayLobbyAImpl_EnumLocalApplications,
XCAST(GetConnectionSettings)IDirectPlayLobbyAImpl_GetConnectionSettings,
XCAST(ReceiveLobbyMessage)IDirectPlayLobbyAImpl_ReceiveLobbyMessage,
XCAST(RunApplication)IDirectPlayLobbyAImpl_RunApplication,
XCAST(SendLobbyMessage)IDirectPlayLobbyAImpl_SendLobbyMessage,
XCAST(SetConnectionSettings)IDirectPlayLobbyAImpl_SetConnectionSettings,
XCAST(SetLobbyMessageEvent)IDirectPlayLobbyAImpl_SetLobbyMessageEvent,
IDirectPlayLobby2AImpl_CreateCompoundAddress
};
#undef XCAST
/* Note: Hack so we can reuse the old functions without compiler warnings */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(directPlayLobby2AVT.fn##fun))
#else
# define XCAST(fun) (void*)
#endif
/* Direct Play Lobby 2 (unicode) Virtual Table for methods */
static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2WVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobby2WImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
XCAST(Connect)IDirectPlayLobbyWImpl_Connect,
XCAST(CreateAddress)IDirectPlayLobbyWImpl_CreateAddress,
XCAST(EnumAddress)IDirectPlayLobbyWImpl_EnumAddress,
XCAST(EnumAddressTypes)IDirectPlayLobbyWImpl_EnumAddressTypes,
XCAST(EnumLocalApplications)IDirectPlayLobbyWImpl_EnumLocalApplications,
XCAST(GetConnectionSettings)IDirectPlayLobbyWImpl_GetConnectionSettings,
XCAST(ReceiveLobbyMessage)IDirectPlayLobbyWImpl_ReceiveLobbyMessage,
XCAST(RunApplication)IDirectPlayLobbyWImpl_RunApplication,
XCAST(SendLobbyMessage)IDirectPlayLobbyWImpl_SendLobbyMessage,
XCAST(SetConnectionSettings)IDirectPlayLobbyWImpl_SetConnectionSettings,
XCAST(SetLobbyMessageEvent)IDirectPlayLobbyWImpl_SetLobbyMessageEvent,
IDirectPlayLobby2WImpl_CreateCompoundAddress
};
#undef XCAST
/* Direct Play Lobby 3 (ascii) Virtual Table for methods */
/* Note: Hack so we can reuse the old functions without compiler warnings */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(directPlayLobby3AVT.fn##fun))
#else
# define XCAST(fun) (void*)
#endif
static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3AVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobby3AImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
XCAST(Connect)IDirectPlayLobbyAImpl_Connect,
XCAST(CreateAddress)IDirectPlayLobbyAImpl_CreateAddress,
XCAST(EnumAddress)IDirectPlayLobbyAImpl_EnumAddress,
XCAST(EnumAddressTypes)IDirectPlayLobbyAImpl_EnumAddressTypes,
XCAST(EnumLocalApplications)IDirectPlayLobbyAImpl_EnumLocalApplications,
XCAST(GetConnectionSettings)IDirectPlayLobbyAImpl_GetConnectionSettings,
XCAST(ReceiveLobbyMessage)IDirectPlayLobbyAImpl_ReceiveLobbyMessage,
XCAST(RunApplication)IDirectPlayLobbyAImpl_RunApplication,
XCAST(SendLobbyMessage)IDirectPlayLobbyAImpl_SendLobbyMessage,
XCAST(SetConnectionSettings)IDirectPlayLobbyAImpl_SetConnectionSettings,
XCAST(SetLobbyMessageEvent)IDirectPlayLobbyAImpl_SetLobbyMessageEvent,
XCAST(CreateCompoundAddress)IDirectPlayLobby2AImpl_CreateCompoundAddress,
IDirectPlayLobby3AImpl_ConnectEx,
IDirectPlayLobby3AImpl_RegisterApplication,
IDirectPlayLobby3AImpl_UnregisterApplication,
IDirectPlayLobby3AImpl_WaitForConnectionSettings
};
#undef XCAST
/* Direct Play Lobby 3 (unicode) Virtual Table for methods */
/* Note: Hack so we can reuse the old functions without compiler warnings */
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun) (typeof(directPlayLobby3WVT.fn##fun))
#else
# define XCAST(fun) (void*)
#endif
static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3WVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobby3WImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
XCAST(Connect)IDirectPlayLobbyWImpl_Connect,
XCAST(CreateAddress)IDirectPlayLobbyWImpl_CreateAddress,
XCAST(EnumAddress)IDirectPlayLobbyWImpl_EnumAddress,
XCAST(EnumAddressTypes)IDirectPlayLobbyWImpl_EnumAddressTypes,
XCAST(EnumLocalApplications)IDirectPlayLobbyWImpl_EnumLocalApplications,
XCAST(GetConnectionSettings)IDirectPlayLobbyWImpl_GetConnectionSettings,
XCAST(ReceiveLobbyMessage)IDirectPlayLobbyWImpl_ReceiveLobbyMessage,
XCAST(RunApplication)IDirectPlayLobbyWImpl_RunApplication,
XCAST(SendLobbyMessage)IDirectPlayLobbyWImpl_SendLobbyMessage,
XCAST(SetConnectionSettings)IDirectPlayLobbyWImpl_SetConnectionSettings,
XCAST(SetLobbyMessageEvent)IDirectPlayLobbyWImpl_SetLobbyMessageEvent,
XCAST(CreateCompoundAddress)IDirectPlayLobby2WImpl_CreateCompoundAddress,
IDirectPlayLobby3WImpl_ConnectEx,
IDirectPlayLobby3WImpl_RegisterApplication,
IDirectPlayLobby3WImpl_UnregisterApplication,
IDirectPlayLobby3WImpl_WaitForConnectionSettings
};
#undef XCAST
/*********************************************************
*
* Direct Play and Direct Play Lobby Interface Implementation
*
*********************************************************/
/***************************************************************************
* DirectPlayLobbyCreateA (DPLAYX.4)
*
*/
HRESULT WINAPI DirectPlayLobbyCreateA( LPGUID lpGUIDDSP,
LPDIRECTPLAYLOBBYA *lplpDPL,
IUnknown *lpUnk,
LPVOID lpData,
DWORD dwDataSize )
{
TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
/* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
* equal 0. These fields are mostly for future expansion.
*/
if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
{
*lplpDPL = NULL;
return DPERR_INVALIDPARAMS;
}
return directPlayLobby_QueryInterface( &IID_IDirectPlayLobbyA, (void**)lplpDPL );
}
/***************************************************************************
* DirectPlayLobbyCreateW (DPLAYX.5)
*
*/
HRESULT WINAPI DirectPlayLobbyCreateW( LPGUID lpGUIDDSP,
LPDIRECTPLAYLOBBY *lplpDPL,
IUnknown *lpUnk,
LPVOID lpData,
DWORD dwDataSize )
{
TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08lx\n",
lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize);
/* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must
* equal 0. These fields are mostly for future expansion.
*/
if ( lpGUIDDSP || lpUnk || lpData || dwDataSize )
{
*lplpDPL = NULL;
ERR("Bad parameters!\n" );
return DPERR_INVALIDPARAMS;
}
return directPlayLobby_QueryInterface( &IID_IDirectPlayLobby, (void**)lplpDPL );
}