721 lines
19 KiB
C++
721 lines
19 KiB
C++
/*==========================================================================
|
|
*
|
|
* Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: ClassFac.cpp
|
|
* Content: DirectPlay Lobby COM Class Factory
|
|
*@@BEGIN_MSINTERNAL
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 02/21/00 mjn Created
|
|
* 03/22/2000 jtk Changed interface names
|
|
* 04/18/2000 rmt Updated object create to set param validation flag
|
|
* 05/09/2000 rmt Bug #34306 QueryInterface on lobbyclient for lobbiedapp works (and shouldn't).
|
|
* 06/07/2000 rmt Bug #34383 Must provide CLSID for each IID to fix issues with Whistler
|
|
* 06/20/2000 rmt Bugfix - QueryInterface had bug which was limiting interface list to 2 elements
|
|
* 07/08/2000 rmt Added guard bytes
|
|
* 08/05/2000 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
|
|
* 08/08/2000 rmt Removed assert which wasn't needed
|
|
* 01/11/2001 rmt MANBUG #48487 - DPLAY: Crashes if CoCreate() isn't called.
|
|
* 03/14/2001 rmt WINBUG #342420 - Restore COM emulation layer to operation.
|
|
*@@END_MSINTERNAL
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "dnlobbyi.h"
|
|
|
|
|
|
//**********************************************************************
|
|
// Constant definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Macro definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Structure definitions
|
|
//**********************************************************************
|
|
|
|
typedef STDMETHODIMP IUnknownQueryInterface( IUnknown *pInterface, REFIID riid, LPVOID *ppvObj );
|
|
typedef STDMETHODIMP_(ULONG) IUnknownAddRef( IUnknown *pInterface );
|
|
typedef STDMETHODIMP_(ULONG) IUnknownRelease( IUnknown *pInterface );
|
|
|
|
//
|
|
// VTable for IUnknown interface
|
|
//
|
|
IUnknownVtbl DN_UnknownVtbl =
|
|
{
|
|
(IUnknownQueryInterface*) DPL_QueryInterface,
|
|
(IUnknownAddRef*) DPL_AddRef,
|
|
(IUnknownRelease*) DPL_Release
|
|
};
|
|
|
|
|
|
//
|
|
// VTable for Class Factory
|
|
//
|
|
IDirectPlayLobbyClassFactVtbl DPLCF_Vtbl =
|
|
{
|
|
DPLCF_QueryInterface,
|
|
DPLCF_AddRef,
|
|
DPLCF_Release,
|
|
DPLCF_CreateInstance,
|
|
DPLCF_LockServer
|
|
};
|
|
|
|
//**********************************************************************
|
|
// Variable definitions
|
|
//**********************************************************************
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
extern DWORD GdwHLocks;
|
|
extern DWORD GdwHObjects;
|
|
|
|
//**********************************************************************
|
|
// Function prototypes
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Function definitions
|
|
//**********************************************************************
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLCF_QueryInterface"
|
|
|
|
STDMETHODIMP DPLCF_QueryInterface(IDirectPlayLobbyClassFact *pInterface,
|
|
REFIID riid,
|
|
LPVOID *ppv)
|
|
{
|
|
_PIDirectPlayLobbyClassFact lpcfObj;
|
|
HRESULT hResultCode = S_OK;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: pInterface [0x%p], riid [0x%p], ppv [0x%p]",pInterface,riid,ppv);
|
|
|
|
lpcfObj = (_PIDirectPlayLobbyClassFact)pInterface;
|
|
if (IsEqualIID(riid,IID_IUnknown))
|
|
{
|
|
DPFX(DPFPREP, 5,"riid = IID_IUnknown");
|
|
*ppv = pInterface;
|
|
lpcfObj->lpVtbl->AddRef( pInterface );
|
|
}
|
|
else if (IsEqualIID(riid,IID_IClassFactory))
|
|
{
|
|
DPFX(DPFPREP, 5,"riid = IID_IClassFactory");
|
|
*ppv = pInterface;
|
|
lpcfObj->lpVtbl->AddRef( pInterface );
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 5,"riid not found !");
|
|
*ppv = NULL;
|
|
hResultCode = E_NOINTERFACE;
|
|
}
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx], *ppv = [%p]",hResultCode,*ppv);
|
|
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLCF_AddRef"
|
|
|
|
STDMETHODIMP_(ULONG) DPLCF_AddRef(IDirectPlayLobbyClassFact *pInterface)
|
|
{
|
|
_PIDirectPlayLobbyClassFact lpcfObj;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: pInterface [%p]",pInterface);
|
|
|
|
lpcfObj = (_PIDirectPlayLobbyClassFact)pInterface;
|
|
InterlockedIncrement( &lpcfObj->lRefCount );
|
|
|
|
DPFX(DPFPREP, 3,"Returning: lpcfObj->lRefCount = [%lx]",lpcfObj->lRefCount);
|
|
|
|
return(lpcfObj->lRefCount);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLCF_Release"
|
|
|
|
STDMETHODIMP_(ULONG) DPLCF_Release(IDirectPlayLobbyClassFact *pInterface)
|
|
{
|
|
_PIDirectPlayLobbyClassFact lpcfObj;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: pInterface [%p]",pInterface);
|
|
|
|
lpcfObj = (_PIDirectPlayLobbyClassFact)pInterface;
|
|
DPFX(DPFPREP, 5,"Original : lpcfObj->lRefCount = %ld",lpcfObj->lRefCount);
|
|
if( InterlockedDecrement( &lpcfObj->lRefCount ) == 0 )
|
|
{
|
|
DPFX(DPFPREP, 5,"Freeing class factory object: lpcfObj [%p]",lpcfObj);
|
|
DNFree(lpcfObj);
|
|
|
|
GdwHObjects--;
|
|
|
|
return(0);
|
|
}
|
|
DPFX(DPFPREP, 3,"Returning: lpcfObj->lRefCount = [%lx]",lpcfObj->lRefCount);
|
|
|
|
return(lpcfObj->lRefCount);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLCF_CreateObject"
|
|
|
|
HRESULT DPLCF_CreateObject(IDirectPlayLobbyClassFact *pInterface,
|
|
LPVOID *lplpv,
|
|
REFIID riid)
|
|
{
|
|
|
|
HRESULT hResultCode = S_OK;
|
|
OSVERSIONINFOA ver;
|
|
PDIRECTPLAYLOBBYOBJECT pdpLobbyObject = NULL;
|
|
_PIDirectPlayLobbyClassFact lpcfObj = (_PIDirectPlayLobbyClassFact)pInterface;
|
|
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lplpv [%p]",lplpv);
|
|
|
|
/*
|
|
*
|
|
* TIME BOMB
|
|
*
|
|
*/
|
|
|
|
#ifndef DX_FINAL_RELEASE
|
|
{
|
|
#pragma message("BETA EXPIRATION TIME BOMB! Remove for final build!")
|
|
SYSTEMTIME st;
|
|
GetSystemTime(&st);
|
|
|
|
if ( st.wYear > DX_EXPIRE_YEAR || ((st.wYear == DX_EXPIRE_YEAR) && (MAKELONG(st.wDay, st.wMonth) > MAKELONG(DX_EXPIRE_DAY, DX_EXPIRE_MONTH))) )
|
|
{
|
|
MessageBox(0, DX_EXPIRE_TEXT,TEXT("Microsoft Direct Play"), MB_OK);
|
|
// return E_FAIL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if ((pdpLobbyObject = (PDIRECTPLAYLOBBYOBJECT)DNMalloc(sizeof(DIRECTPLAYLOBBYOBJECT))) == NULL)
|
|
{
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
DPFX(DPFPREP, 5,"pdpLobbyObject [%p]",pdpLobbyObject);
|
|
|
|
// Set allocatable elements to NULL to simplify free'ing later on
|
|
pdpLobbyObject->dwSignature = DPLSIGNATURE_LOBBYOBJECT;
|
|
pdpLobbyObject->hReceiveThread = NULL;
|
|
pdpLobbyObject->dwFlags = 0;
|
|
pdpLobbyObject->hConnectEvent = NULL;
|
|
pdpLobbyObject->pfnMessageHandler = NULL;
|
|
pdpLobbyObject->pvUserContext = NULL;
|
|
pdpLobbyObject->lLaunchCount = 0;
|
|
pdpLobbyObject->dpnhLaunchedConnection = NULL;
|
|
|
|
pdpLobbyObject->pReceiveQueue = NULL;
|
|
|
|
pdpLobbyObject->dwPID = GetCurrentProcessId();
|
|
|
|
if ((hResultCode = H_Initialize(&pdpLobbyObject->hsHandles,
|
|
DPL_NUM_APP_HANDLES)) != DPN_OK)
|
|
{
|
|
DPLCF_FreeObject(pdpLobbyObject);
|
|
return(hResultCode);
|
|
}
|
|
if ((pdpLobbyObject->hConnectEvent = CreateEvent(NULL,TRUE,FALSE,NULL)) == NULL)
|
|
{
|
|
DPLCF_FreeObject(pdpLobbyObject);
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
return(hResultCode);
|
|
}
|
|
|
|
if ((pdpLobbyObject->hLobbyLaunchConnectEvent = CreateEvent(NULL,TRUE,FALSE,NULL)) == NULL )
|
|
{
|
|
DPLCF_FreeObject(pdpLobbyObject);
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
return(hResultCode);
|
|
}
|
|
|
|
pdpLobbyObject->phHandleBuffer = NULL;
|
|
pdpLobbyObject->dwHandleBufferSize = 0;
|
|
|
|
DPFX(DPFPREP, 5,"InitializeHandles() succeeded");
|
|
|
|
if (IsEqualIID(riid,IID_IDirectPlay8LobbyClient) ||
|
|
(riid == IID_IUnknown && lpcfObj->clsid == CLSID_DirectPlay8LobbyClient ) )
|
|
{
|
|
DPFX(DPFPREP, 5,"DirectPlay Lobby Client");
|
|
pdpLobbyObject->dwFlags |= DPL_OBJECT_FLAG_LOBBYCLIENT;
|
|
}
|
|
else if (IsEqualIID(riid,IID_IDirectPlay8LobbiedApplication) ||
|
|
(riid == IID_IUnknown && lpcfObj->clsid == CLSID_DirectPlay8LobbiedApplication ) )
|
|
{
|
|
DPFX(DPFPREP, 5,"DirectPlay Lobbied Application");
|
|
pdpLobbyObject->dwFlags |= DPL_OBJECT_FLAG_LOBBIEDAPPLICATION;
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 5,"Invalid DirectPlay Lobby Interface");
|
|
DPLCF_FreeObject(pdpLobbyObject);
|
|
return(E_NOTIMPL);
|
|
}
|
|
|
|
pdpLobbyObject->dwFlags |= DPL_OBJECT_FLAG_PARAMVALIDATION;
|
|
|
|
// Determine platform
|
|
// Just always call the ANSI function
|
|
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
|
if(!GetVersionExA(&ver))
|
|
{
|
|
DPFX(DPFPREP, 0, "Unable to determinte platform -- setting flag to ANSI");
|
|
pdpLobbyObject->bIsUnicodePlatform = FALSE;
|
|
}
|
|
else
|
|
{
|
|
switch(ver.dwPlatformId)
|
|
{
|
|
case VER_PLATFORM_WIN32_WINDOWS:
|
|
DPFX(DPFPREP, 1, "Platform detected as non-NT -- setting flag to ANSI");
|
|
pdpLobbyObject->bIsUnicodePlatform = FALSE;
|
|
break;
|
|
|
|
case VER_PLATFORM_WIN32_NT:
|
|
DPFX(DPFPREP, 1, "Platform detected as NT -- setting flag to Unicode");
|
|
pdpLobbyObject->bIsUnicodePlatform = TRUE;
|
|
break;
|
|
|
|
default:
|
|
DPFX(DPFPREP, 0, "Unable to determine platform -- setting flag to ANSI");
|
|
pdpLobbyObject->bIsUnicodePlatform = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
*lplpv = pdpLobbyObject;
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx], *lplpv = [%p]",hResultCode,*lplpv);
|
|
return(hResultCode);
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DirectPlay8LobbyCreate"
|
|
HRESULT WINAPI DirectPlay8LobbyCreate( const GUID * pcIID, void **ppvInterface, IUnknown *pUnknown)
|
|
{
|
|
GUID clsid;
|
|
|
|
if( pcIID == NULL ||
|
|
!DNVALID_READPTR( pcIID, sizeof( GUID ) ) )
|
|
{
|
|
DPFERR( "Invalid pointer specified for interface GUID" );
|
|
return DPNERR_INVALIDPOINTER;
|
|
}
|
|
|
|
if( *pcIID != IID_IDirectPlay8LobbyClient &&
|
|
*pcIID != IID_IDirectPlay8LobbiedApplication )
|
|
{
|
|
DPFERR("Interface ID is not recognized" );
|
|
return DPNERR_INVALIDPARAM;
|
|
}
|
|
|
|
if( ppvInterface == NULL || !DNVALID_WRITEPTR( ppvInterface, sizeof( void * ) ) )
|
|
{
|
|
DPFERR( "Invalid pointer specified to receive interface" );
|
|
return DPNERR_INVALIDPOINTER;
|
|
}
|
|
|
|
if( pUnknown != NULL )
|
|
{
|
|
DPFERR( "Aggregation is not supported by this object yet" );
|
|
return DPNERR_INVALIDPARAM;
|
|
}
|
|
|
|
if( *pcIID == IID_IDirectPlay8LobbyClient )
|
|
{
|
|
clsid = CLSID_DirectPlay8LobbyClient;
|
|
}
|
|
else if( *pcIID == IID_IDirectPlay8LobbiedApplication )
|
|
{
|
|
clsid = CLSID_DirectPlay8LobbiedApplication;
|
|
}
|
|
else
|
|
{
|
|
DPFERR( "Invalid IID specified" );
|
|
return DPNERR_INVALIDINTERFACE;
|
|
}
|
|
|
|
return COM_CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, *pcIID, ppvInterface, TRUE );
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLCF_FreeObject"
|
|
|
|
HRESULT DPLCF_FreeObject(LPVOID lpv)
|
|
{
|
|
HRESULT hResultCode = S_OK;
|
|
PDIRECTPLAYLOBBYOBJECT pdpLobbyObject = NULL;
|
|
|
|
if (lpv != NULL)
|
|
{
|
|
pdpLobbyObject = (PDIRECTPLAYLOBBYOBJECT)lpv;
|
|
|
|
if( pdpLobbyObject->phHandleBuffer )
|
|
delete [] pdpLobbyObject->phHandleBuffer;
|
|
|
|
if (pdpLobbyObject->pReceiveQueue)
|
|
delete pdpLobbyObject->pReceiveQueue;
|
|
|
|
if (pdpLobbyObject->hLobbyLaunchConnectEvent)
|
|
CloseHandle(pdpLobbyObject->hLobbyLaunchConnectEvent);
|
|
|
|
if (pdpLobbyObject->hConnectEvent)
|
|
CloseHandle(pdpLobbyObject->hConnectEvent);
|
|
|
|
// Free application handles
|
|
H_Terminate(&pdpLobbyObject->hsHandles);
|
|
|
|
pdpLobbyObject->dwSignature = DPLSIGNATURE_LOBBYOBJECT_FREE;
|
|
|
|
DPFX(DPFPREP, 5,"free pdpLobbyObject [%p]",pdpLobbyObject);
|
|
DNFree(pdpLobbyObject);
|
|
}
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
|
|
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLCF_CreateInstance"
|
|
|
|
STDMETHODIMP DPLCF_CreateInstance(IDirectPlayLobbyClassFact *pInterface,
|
|
LPUNKNOWN lpUnkOuter,
|
|
REFIID riid,
|
|
LPVOID *ppv)
|
|
{
|
|
HRESULT hResultCode = S_OK;
|
|
LPINTERFACE_LIST lpIntList = NULL;
|
|
LPOBJECT_DATA lpObjectData = NULL;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: pInterface [0x%p], lpUnkOuter [0x%p], riid [0x%p], ppv [0x%p]",pInterface,lpUnkOuter,riid,ppv);
|
|
|
|
if (lpUnkOuter != NULL)
|
|
return(CLASS_E_NOAGGREGATION);
|
|
|
|
if ((lpObjectData = (LPOBJECT_DATA)DNMalloc(sizeof(OBJECT_DATA))) == NULL)
|
|
{
|
|
DPFERR("DNMalloc() failed");
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
DPFX(DPFPREP, 5,"lpObjectData [%p]",lpObjectData);
|
|
|
|
// Object creation and initialization
|
|
if ((hResultCode = DPLCF_CreateObject(pInterface,&lpObjectData->lpvData,riid)) != S_OK)
|
|
{
|
|
DNFree(lpObjectData);
|
|
return(hResultCode);
|
|
}
|
|
DPFX(DPFPREP, 5,"Created and initialized object");
|
|
|
|
// Get requested interface
|
|
if ((hResultCode = DPL_CreateInterface(lpObjectData,riid,&lpIntList)) != S_OK)
|
|
{
|
|
DPLCF_FreeObject(lpObjectData->lpvData);
|
|
DNFree(lpObjectData);
|
|
return(hResultCode);
|
|
}
|
|
DPFX(DPFPREP, 5,"Found interface");
|
|
|
|
lpObjectData->lpIntList = lpIntList;
|
|
lpObjectData->lRefCount = 1;
|
|
InterlockedIncrement( &lpIntList->lRefCount );
|
|
GdwHObjects++;
|
|
*ppv = lpIntList;
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx], *ppv = [%p]",hResultCode,*ppv);
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLCF_LockServer"
|
|
|
|
STDMETHODIMP DPLCF_LockServer(IDirectPlayLobbyClassFact *pInterface,
|
|
BOOL bLock)
|
|
{
|
|
DPFX(DPFPREP, 3,"Parameters: lpv [%p], bLock [%lx]",pInterface,bLock);
|
|
|
|
if (bLock)
|
|
{
|
|
GdwHLocks++;
|
|
}
|
|
else
|
|
{
|
|
GdwHLocks--;
|
|
}
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPL_CreateInterface"
|
|
|
|
static HRESULT DPL_CreateInterface(LPOBJECT_DATA lpObject,
|
|
REFIID riid,
|
|
LPINTERFACE_LIST *const ppv)
|
|
{
|
|
LPINTERFACE_LIST lpIntNew;
|
|
LPVOID lpVtbl;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpObject [%p], riid [%p], ppv [%p]",lpObject,riid,ppv);
|
|
|
|
if (IsEqualIID(riid,IID_IUnknown))
|
|
{
|
|
DPFX(DPFPREP, 5,"riid = IID_IUnknown");
|
|
lpVtbl = &DN_UnknownVtbl;
|
|
}
|
|
else if (IsEqualIID(riid,IID_IDirectPlay8LobbyClient))
|
|
{
|
|
DPFX(DPFPREP, 5,"riid = IID_IDirectPlay8LobbyClient");
|
|
lpVtbl = &DPL_Lobby8ClientVtbl;
|
|
}
|
|
else if (IsEqualIID(riid,IID_IDirectPlay8LobbiedApplication))
|
|
{
|
|
DPFX(DPFPREP, 5,"riid = IID_IDirectPlay8LobbiedApplication");
|
|
lpVtbl = &DPL_8LobbiedApplicationVtbl;
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 5,"riid not found !");
|
|
return(E_NOINTERFACE);
|
|
}
|
|
|
|
if ((lpIntNew = (LPINTERFACE_LIST)DNMalloc(sizeof(INTERFACE_LIST))) == NULL)
|
|
{
|
|
DPFERR("DNMalloc() failed");
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
lpIntNew->lpVtbl = lpVtbl;
|
|
lpIntNew->lRefCount = 0;
|
|
lpIntNew->lpIntNext = NULL;
|
|
DBG_CASSERT( sizeof( lpIntNew->iid ) == sizeof( riid ) );
|
|
memcpy( &(lpIntNew->iid), &riid, sizeof( lpIntNew->iid ) );
|
|
lpIntNew->lpObject = lpObject;
|
|
|
|
*ppv = lpIntNew;
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [S_OK], *ppv = [%p]",*ppv);
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPL_FindInterface"
|
|
|
|
LPINTERFACE_LIST DPL_FindInterface(LPVOID lpv, REFIID riid)
|
|
{
|
|
LPINTERFACE_LIST lpIntList;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpv [%p], riid [%p]",lpv,riid);
|
|
|
|
lpIntList = ((LPINTERFACE_LIST)lpv)->lpObject->lpIntList; // Find first interface
|
|
|
|
while (lpIntList != NULL)
|
|
{
|
|
if (IsEqualIID(riid,lpIntList->iid))
|
|
break;
|
|
lpIntList = lpIntList->lpIntNext;
|
|
}
|
|
DPFX(DPFPREP, 3,"Returning: lpIntList = [%p]",lpIntList);
|
|
|
|
return(lpIntList);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPL_QueryInterface"
|
|
|
|
STDMETHODIMP DPL_QueryInterface(LPVOID lpv,REFIID riid,LPVOID *ppv)
|
|
{
|
|
LPINTERFACE_LIST lpIntList;
|
|
LPINTERFACE_LIST lpIntNew;
|
|
HRESULT hResultCode;
|
|
PDIRECTPLAYLOBBYOBJECT pdpLobbyObject;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpv [0x%p], riid [0x%p], ppv [0x%p]",lpv,riid,ppv);
|
|
|
|
TRY
|
|
{
|
|
pdpLobbyObject = static_cast<DIRECTPLAYLOBBYOBJECT*>(GET_OBJECT_FROM_INTERFACE(lpv));
|
|
lpIntList = (LPINTERFACE_LIST)lpv;
|
|
|
|
if( FAILED( hResultCode = DPL_ValidateQueryInterface( lpv,riid,ppv ) ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error validating QueryInterface params hr=[0x%lx]", hResultCode );
|
|
DPF_RETURN(hResultCode);
|
|
}
|
|
|
|
if( pdpLobbyObject->dwFlags & DPL_OBJECT_FLAG_LOBBIEDAPPLICATION &&
|
|
riid == IID_IDirectPlay8LobbyClient )
|
|
{
|
|
DPFERR( "Cannot request lobbyclient interface from lobbyapp object" );
|
|
return DPNERR_NOINTERFACE;
|
|
}
|
|
|
|
if( pdpLobbyObject->dwFlags & DPL_OBJECT_FLAG_LOBBYCLIENT &&
|
|
riid == IID_IDirectPlay8LobbiedApplication )
|
|
{
|
|
DPFERR( "Cannot request lobbied application interface from lobbyclient object" );
|
|
return DPNERR_NOINTERFACE;
|
|
}
|
|
|
|
}
|
|
EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
DPFERR("Invalid object" );
|
|
DPF_RETURN(DPNERR_INVALIDOBJECT);
|
|
}
|
|
|
|
if ((lpIntList = DPL_FindInterface(lpv,riid)) == NULL)
|
|
{ // Interface must be created
|
|
lpIntList = ((LPINTERFACE_LIST)lpv)->lpObject->lpIntList;
|
|
if ((hResultCode = DPL_CreateInterface(lpIntList->lpObject,riid,&lpIntNew)) != S_OK)
|
|
{
|
|
DPF_RETURN(hResultCode);
|
|
}
|
|
lpIntNew->lpIntNext = lpIntList;
|
|
((LPINTERFACE_LIST)lpv)->lpObject->lpIntList = lpIntNew;
|
|
lpIntList = lpIntNew;
|
|
}
|
|
if (lpIntList->lRefCount == 0) // New interface exposed
|
|
{
|
|
InterlockedIncrement( &lpIntList->lpObject->lRefCount );
|
|
}
|
|
InterlockedIncrement( &lpIntList->lRefCount );
|
|
*ppv = lpIntList;
|
|
|
|
DPF_RETURN(S_OK);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPL_AddRef"
|
|
|
|
STDMETHODIMP_(ULONG) DPL_AddRef(LPVOID lpv)
|
|
{
|
|
LPINTERFACE_LIST lpIntList;
|
|
PDIRECTPLAYLOBBYOBJECT pdpLobbyObject;
|
|
HRESULT hResultCode;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpv [%p]",lpv);
|
|
|
|
TRY
|
|
{
|
|
pdpLobbyObject = static_cast<DIRECTPLAYLOBBYOBJECT*>(GET_OBJECT_FROM_INTERFACE(lpv));
|
|
lpIntList = (LPINTERFACE_LIST)lpv;
|
|
|
|
if( FAILED( hResultCode = DPL_ValidateAddRef( lpv ) ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error validating AddRef params hr=[0x%lx]", hResultCode );
|
|
DPF_RETURN(0);
|
|
}
|
|
}
|
|
EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
DPFERR("Invalid object" );
|
|
DPF_RETURN(0);
|
|
}
|
|
|
|
InterlockedIncrement( &lpIntList->lRefCount );
|
|
|
|
DPF_RETURN(lpIntList->lRefCount);
|
|
}
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPL_Release"
|
|
|
|
STDMETHODIMP_(ULONG) DPL_Release(LPVOID lpv)
|
|
{
|
|
LPINTERFACE_LIST lpIntList;
|
|
LPINTERFACE_LIST lpIntCurrent;
|
|
PDIRECTPLAYLOBBYOBJECT pdpLobbyObject;
|
|
HRESULT hResultCode;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpv [%p]",lpv);
|
|
|
|
TRY
|
|
{
|
|
pdpLobbyObject = static_cast<DIRECTPLAYLOBBYOBJECT*>(GET_OBJECT_FROM_INTERFACE(lpv));
|
|
lpIntList = (LPINTERFACE_LIST)lpv;
|
|
|
|
if( FAILED( hResultCode = DPL_ValidateRelease( lpv ) ) )
|
|
{
|
|
DPFX(DPFPREP, 0, "Error validating release params hr=[0x%lx]", hResultCode );
|
|
DPF_RETURN(0);
|
|
}
|
|
}
|
|
EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
DPFERR("Invalid object" );
|
|
DPF_RETURN(0);
|
|
}
|
|
|
|
DPFX(DPFPREP, 5,"Original : lpIntList->lRefCount = %ld",lpIntList->lRefCount);
|
|
DPFX(DPFPREP, 5,"Original : lpIntList->lpObject->lRefCount = %ld",lpIntList->lpObject->lRefCount);
|
|
|
|
if( InterlockedDecrement( &lpIntList->lRefCount ) == 0 )
|
|
{ // Decrease interface count
|
|
if( InterlockedDecrement( &lpIntList->lpObject->lRefCount ) == 0 )
|
|
{ // Free object and all interfaces
|
|
DPFX(DPFPREP, 5,"Free object");
|
|
|
|
if( pdpLobbyObject->pReceiveQueue )
|
|
{
|
|
DPFX(DPFPREP, 0, "*******************************************************************" );
|
|
DPFX(DPFPREP, 0, "ERROR: Releasing object without calling close!" );
|
|
DPFX(DPFPREP, 0, "You MUST call Close before destroying the object" );
|
|
DPFX(DPFPREP, 0, "*******************************************************************" );
|
|
|
|
DPL_Close( lpv, 0 );
|
|
}
|
|
|
|
// Free object here
|
|
DPLCF_FreeObject(lpIntList->lpObject->lpvData);
|
|
lpIntList = lpIntList->lpObject->lpIntList; // Get head of interface list
|
|
DPFX(DPFPREP, 5,"lpIntList->lpObject [%p]",lpIntList->lpObject);
|
|
DNFree(lpIntList->lpObject);
|
|
|
|
// Free Interfaces
|
|
DPFX(DPFPREP, 5,"Free interfaces");
|
|
while(lpIntList != NULL)
|
|
{
|
|
lpIntCurrent = lpIntList;
|
|
lpIntList = lpIntList->lpIntNext;
|
|
DPFX(DPFPREP, 5,"\tinterface [%p]",lpIntCurrent);
|
|
DNFree(lpIntCurrent);
|
|
}
|
|
|
|
GdwHObjects--;
|
|
DPFX(DPFPREP, 3,"Returning: 0");
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
DPFX(DPFPREP, 3,"Returning: lpIntList->lRefCount = [%lx]",lpIntList->lRefCount);
|
|
|
|
DPF_RETURN(lpIntList->lRefCount);
|
|
}
|
|
|