|
|
/*==========================================================================
* * 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; }
|