338 lines
7.8 KiB
C++
338 lines
7.8 KiB
C++
|
/*==========================================================================
|
||
|
*
|
||
|
* Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* File: dpvxdplay.cpp
|
||
|
* Content: Useful dplay utility functions lib for sample apps
|
||
|
*
|
||
|
* History:
|
||
|
* Date By Reason
|
||
|
* ==== == ======
|
||
|
* 10/07/99 rodtoll Created It
|
||
|
* 10/27/99 pnewson Added support for application flags
|
||
|
* 11/02/99 rodtoll Bug #116677 - Can't use lobby clients that don't hang around
|
||
|
* 12/16/99 rodtoll Bug #122629 - Player was being created as server player exposed
|
||
|
* by new host migration
|
||
|
* 03/03/2000 rodtoll Updated to handle alternative gamevoice build.
|
||
|
* 08/31/2000 rodtoll Whistler Bug #171844, 171842
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include "dpvxlibpch.h"
|
||
|
|
||
|
|
||
|
// Start a session with the specified settings.
|
||
|
HRESULT DPVDX_DP_StartSession(
|
||
|
// Input
|
||
|
LPDIRECTPLAY4A lpDirectPlay,
|
||
|
GUID guidApplicationID,
|
||
|
DWORD dwFlags,
|
||
|
LPTSTR lpszPlayerName,
|
||
|
LPTSTR lpszSessionName,
|
||
|
DWORD dwMaxPlayers,
|
||
|
// Output
|
||
|
LPDPID lpdpidServerID,
|
||
|
LPHANDLE lpReceiveEvent,
|
||
|
LPGUID lpguidInstanceGUID
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
// Create and intialize the server
|
||
|
DPSESSIONDESC2 dpSessionDesc;
|
||
|
|
||
|
memset( &dpSessionDesc, 0, sizeof( DPSESSIONDESC2 ) );
|
||
|
dpSessionDesc.dwSize = sizeof( DPSESSIONDESC2 );
|
||
|
dpSessionDesc.dwFlags = DPSESSION_DIRECTPLAYPROTOCOL;
|
||
|
dpSessionDesc.dwFlags |= dwFlags;
|
||
|
|
||
|
dpSessionDesc.guidApplication = guidApplicationID;
|
||
|
dpSessionDesc.dwMaxPlayers = dwMaxPlayers;
|
||
|
dpSessionDesc.lpszSessionNameA = lpszSessionName;
|
||
|
dpSessionDesc.lpszPasswordA = NULL;
|
||
|
|
||
|
DPNAME tmpName;
|
||
|
|
||
|
tmpName.dwSize = sizeof(DPNAME);
|
||
|
tmpName.lpszShortNameA = lpszPlayerName;
|
||
|
tmpName.lpszLongNameA = lpszPlayerName;
|
||
|
|
||
|
hr = lpDirectPlay->Open( &dpSessionDesc, DPOPEN_CREATE );
|
||
|
|
||
|
if( FAILED( hr ) )
|
||
|
{
|
||
|
goto STARTSESSION_ERROR;
|
||
|
}
|
||
|
|
||
|
*lpReceiveEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||
|
|
||
|
hr = lpDirectPlay->CreatePlayer( lpdpidServerID, &tmpName, *lpReceiveEvent, NULL, 0, (dwFlags & DPSESSION_CLIENTSERVER) ? DPPLAYER_SERVERPLAYER : 0 );
|
||
|
|
||
|
if( FAILED( hr ) )
|
||
|
{
|
||
|
goto STARTSESSION_ERROR;
|
||
|
}
|
||
|
|
||
|
return DV_OK;
|
||
|
|
||
|
STARTSESSION_ERROR:
|
||
|
|
||
|
return hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT DPVDX_DP_Init( LPDIRECTPLAY4A lpDirectPlay, GUID guidServiceProvider, LPSTR lpstrAddress )
|
||
|
{
|
||
|
if( lpDirectPlay == NULL )
|
||
|
return E_POINTER;
|
||
|
|
||
|
HRESULT hr = DV_OK;
|
||
|
DPCOMPOUNDADDRESSELEMENT elements[2];
|
||
|
BYTE *buffer = NULL;
|
||
|
DWORD dwSize = 0;
|
||
|
LPDIRECTPLAYLOBBY2 directPlayLobby2 = NULL;
|
||
|
DWORD dwNumElements = 1;
|
||
|
|
||
|
hr = CoCreateInstance( DPLAY_CLSID_DPLOBBY, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayLobby2, (void **) &directPlayLobby2 );
|
||
|
|
||
|
if( FAILED( hr ) )
|
||
|
goto DPINIT_CLEANUP;
|
||
|
|
||
|
elements[0].guidDataType = DPAID_ServiceProvider;
|
||
|
elements[0].dwDataSize = sizeof( GUID );
|
||
|
elements[0].lpData = (LPVOID) &guidServiceProvider;
|
||
|
|
||
|
if( lpstrAddress != NULL )
|
||
|
{
|
||
|
dwNumElements = 2;
|
||
|
elements[1].guidDataType = DPAID_INet;
|
||
|
elements[1].dwDataSize = strlen( lpstrAddress );
|
||
|
elements[1].lpData = lpstrAddress;
|
||
|
}
|
||
|
|
||
|
// Determine size of the buffer we need
|
||
|
hr = directPlayLobby2->CreateCompoundAddress( elements, dwNumElements, NULL, &dwSize );
|
||
|
|
||
|
if( hr != DPERR_BUFFERTOOSMALL && FAILED( hr ) )
|
||
|
goto DPINIT_CLEANUP;
|
||
|
|
||
|
buffer = new BYTE[dwSize];
|
||
|
|
||
|
if( buffer == NULL )
|
||
|
{
|
||
|
hr = DVERR_OUTOFMEMORY;
|
||
|
goto DPINIT_CLEANUP;
|
||
|
}
|
||
|
|
||
|
// Actually allocate the connection information
|
||
|
hr = directPlayLobby2->CreateCompoundAddress( elements, dwNumElements, buffer, &dwSize );
|
||
|
|
||
|
if( FAILED( hr ) )
|
||
|
{
|
||
|
goto DPINIT_CLEANUP;
|
||
|
}
|
||
|
|
||
|
hr = lpDirectPlay->InitializeConnection( buffer, 0 );
|
||
|
|
||
|
if( FAILED( hr ) )
|
||
|
{
|
||
|
goto DPINIT_CLEANUP;
|
||
|
}
|
||
|
|
||
|
hr = DV_OK;
|
||
|
|
||
|
DPINIT_CLEANUP:
|
||
|
|
||
|
if( buffer != NULL )
|
||
|
delete [] buffer;
|
||
|
|
||
|
if( directPlayLobby2 != NULL )
|
||
|
directPlayLobby2->Release();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
BOOL FAR PASCAL DPVDX_EnumHandler(
|
||
|
LPCDPSESSIONDESC2 lpThisSD,
|
||
|
LPDWORD lpdwTimeOut,
|
||
|
DWORD dwFlags,
|
||
|
LPVOID lpContext
|
||
|
)
|
||
|
{
|
||
|
LPGUID tmpGUID = (LPGUID) lpContext;
|
||
|
|
||
|
if( lpThisSD != NULL && tmpGUID != NULL )
|
||
|
{
|
||
|
*tmpGUID = lpThisSD->guidInstance;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT DPVDX_DP_FindSessionGUID(
|
||
|
LPDIRECTPLAY4A lpDirectPlay,
|
||
|
// Input
|
||
|
GUID guidApplicationID,
|
||
|
DWORD dwTimeout,
|
||
|
// Output
|
||
|
LPGUID lpguidInstance )
|
||
|
{
|
||
|
HRESULT hr = DV_OK;
|
||
|
DPSESSIONDESC2 dpSessionDesc;
|
||
|
DWORD dwTime;
|
||
|
|
||
|
if( lpguidInstance == NULL )
|
||
|
return E_POINTER;
|
||
|
|
||
|
memset( &dpSessionDesc, 0, sizeof( DPSESSIONDESC2 ) );
|
||
|
dpSessionDesc.dwSize = sizeof( DPSESSIONDESC2 );
|
||
|
dpSessionDesc.guidApplication = guidApplicationID;
|
||
|
dpSessionDesc.lpszPassword = NULL;
|
||
|
|
||
|
dwTime = GetTickCount();
|
||
|
|
||
|
while( (GetTickCount() - dwTime) < dwTimeout )
|
||
|
{
|
||
|
lpDirectPlay->EnumSessions( &dpSessionDesc, 0, DPVDX_EnumHandler, &dpSessionDesc.guidInstance, DPENUMSESSIONS_ASYNC );
|
||
|
|
||
|
if( dpSessionDesc.guidInstance != GUID_NULL )
|
||
|
break;
|
||
|
|
||
|
Sleep( 10 );
|
||
|
}
|
||
|
|
||
|
// lpDirectPlay->EnumSessions( &dpSessionDesc, 0, DPVDX_EnumHandler, NULL, DPENUMSESSIONS_STOPASYNC );
|
||
|
|
||
|
if( dpSessionDesc.guidInstance == GUID_NULL )
|
||
|
{
|
||
|
return DPERR_NOSESSIONS;
|
||
|
}
|
||
|
|
||
|
*lpguidInstance = dpSessionDesc.guidInstance;
|
||
|
|
||
|
return DV_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT DPVDX_DP_ConnectToSession(
|
||
|
// Input
|
||
|
LPDIRECTPLAY4A lpDirectPlay,
|
||
|
GUID guidApplication,
|
||
|
GUID guidInstance,
|
||
|
LPTSTR lpszPlayerName,
|
||
|
// Output
|
||
|
LPDPID lpdpidClientID,
|
||
|
LPHANDLE lpReceiveEvent
|
||
|
)
|
||
|
{
|
||
|
DPSESSIONDESC2 dpSessionDesc;
|
||
|
HRESULT hr;
|
||
|
DPNAME dpnameTmp;
|
||
|
|
||
|
memset( &dpSessionDesc, 0, sizeof( DPSESSIONDESC2 ) );
|
||
|
dpSessionDesc.dwSize = sizeof( DPSESSIONDESC2 );
|
||
|
dpSessionDesc.guidApplication = guidApplication;
|
||
|
dpSessionDesc.guidInstance = guidInstance;
|
||
|
dpSessionDesc.lpszPassword = NULL;
|
||
|
|
||
|
hr = lpDirectPlay->Open( &dpSessionDesc, DPOPEN_JOIN );
|
||
|
|
||
|
if( FAILED( hr ) )
|
||
|
return hr;
|
||
|
|
||
|
dpnameTmp.dwSize = sizeof(DPNAME);
|
||
|
dpnameTmp.lpszShortNameA = lpszPlayerName;
|
||
|
dpnameTmp.lpszLongNameA = lpszPlayerName;
|
||
|
|
||
|
*lpReceiveEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||
|
|
||
|
hr = lpDirectPlay->CreatePlayer( lpdpidClientID, NULL, *lpReceiveEvent, NULL, 0, 0 );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DPVDX_DP_RegisterApplication(
|
||
|
LPSTR lpstrAppName,
|
||
|
GUID guidApplication,
|
||
|
LPTSTR lpstrExeName,
|
||
|
LPTSTR lpstrCommandLine,
|
||
|
LPTSTR lpstrDescription,
|
||
|
DWORD dwFlags
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
LPDIRECTPLAYLOBBY3A lpdpLobby;
|
||
|
DPAPPLICATIONDESC dpappDesc;
|
||
|
|
||
|
if( !lpstrAppName || !lpstrExeName || !lpstrCommandLine || !lpstrDescription )
|
||
|
{
|
||
|
return DVERR_GENERIC;
|
||
|
}
|
||
|
|
||
|
char szEXEPathname[_MAX_PATH];
|
||
|
szEXEPathname[0] = 0;
|
||
|
|
||
|
if( !GetModuleFileName(NULL, szEXEPathname, _MAX_PATH) )
|
||
|
{
|
||
|
return DVERR_GENERIC;
|
||
|
}
|
||
|
|
||
|
hr = CoCreateInstance( DPLAY_CLSID_DPLOBBY, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayLobby3A, (void **) &lpdpLobby );
|
||
|
|
||
|
if( FAILED( hr ) )
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
szEXEPathname[strlen(szEXEPathname)-strlen(lpstrExeName)] = 0;
|
||
|
|
||
|
dpappDesc.dwSize = sizeof(DPAPPLICATIONDESC);
|
||
|
|
||
|
dpappDesc.dwFlags = dwFlags;
|
||
|
dpappDesc.lpszApplicationNameA = lpstrAppName;
|
||
|
dpappDesc.lpszFilenameA = lpstrExeName;
|
||
|
dpappDesc.lpszCommandLineA = lpstrCommandLine;
|
||
|
dpappDesc.lpszPathA = szEXEPathname;
|
||
|
dpappDesc.lpszCurrentDirectoryA = szEXEPathname;
|
||
|
dpappDesc.lpszDescriptionA = lpstrDescription;
|
||
|
|
||
|
wchar_t lpwstrTmp[_MAX_PATH];
|
||
|
|
||
|
if( DPVDX_AnsiToWide( lpwstrTmp, lpstrDescription, _MAX_PATH ) != 0 )
|
||
|
{
|
||
|
dpappDesc.lpszDescriptionW = lpwstrTmp;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dpappDesc.lpszDescriptionW = NULL;
|
||
|
}
|
||
|
|
||
|
dpappDesc.guidApplication = guidApplication;
|
||
|
|
||
|
hr = lpdpLobby->RegisterApplication( 0, &dpappDesc );
|
||
|
|
||
|
lpdpLobby->Release();
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT DPVDX_DP_UnRegisterApplication( GUID guidApplication )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
LPDIRECTPLAYLOBBY3A lpdpLobby;
|
||
|
|
||
|
hr = CoCreateInstance( DPLAY_CLSID_DPLOBBY, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlayLobby3A, (void **) &lpdpLobby );
|
||
|
|
||
|
if( FAILED( hr ) )
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
hr = lpdpLobby->UnregisterApplication( 0, guidApplication );
|
||
|
|
||
|
lpdpLobby->Release();
|
||
|
|
||
|
return hr;
|
||
|
}
|