📄 dplayx_global.c
字号:
i, dwAppID, GetCurrentProcessId() );
lobbyData[ i ].dwAppID = dwAppID;
lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId();
/* FIXME: Where is the best place for this? In interface or here? */
lobbyData[ i ].hInformOnAppStart = 0;
lobbyData[ i ].hInformOnAppDeath = 0;
lobbyData[ i ].hInformOnSettingRead = 0;
DPLAYX_ReleaseSemaphore();
return TRUE;
}
}
ERR( "No empty lobbies\n" );
DPLAYX_ReleaseSemaphore();
return FALSE;
}
/* I'm not sure when I'm going to need this, but here it is */
BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID )
{
UINT i;
DPLAYX_AquireSemaphore();
/* Find an empty space in the list and insert the data */
for( i=0; i < numSupportedLobbies; i++ )
{
if( lobbyData[ i ].dwAppID == dwAppID )
{
/* FIXME: Should free up anything unused. Tisk tisk :0 */
/* Mark this entry unused */
TRACE( "Marking lobbyData[%u] unused\n", i );
DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
DPLAYX_ReleaseSemaphore();
return TRUE;
}
}
DPLAYX_ReleaseSemaphore();
ERR( "Unable to find global entry for application\n" );
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
( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
LPDPLAYX_LOBBYDATA lpDplData;
DWORD dwRequiredDataSize = 0;
HANDLE hInformOnSettingRead;
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
TRACE( "Application 0x%08lx is not lobbied\n", dwAppID );
return DPERR_NOTLOBBIED;
}
dwRequiredDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn );
/* Do they want to know the required buffer size or is the provided buffer
* big enough?
*/
if ( ( lpData == NULL ) ||
( *lpdwDataSize < dwRequiredDataSize )
)
{
DPLAYX_ReleaseSemaphore();
*lpdwDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn );
return DPERR_BUFFERTOOSMALL;
}
DPLAYX_CopyConnStructA( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
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 %p %s\n",
hInformOnSettingRead, bSuccess ? "succeed" : "failed" );
/* Close out handle */
DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, TRUE );
}
return DP_OK;
}
/* Assumption: Enough contiguous space was allocated at dest */
void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
{
BYTE* lpStartOfFreeSpace;
CopyMemory( dest, src, sizeof( DPLCONNECTION ) );
lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION );
/* Copy the LPDPSESSIONDESC2 structure if it exists */
if( src->lpSessionDesc )
{
dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
CopyMemory( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
/* Session names may or may not exist */
if( src->lpSessionDesc->lpszSessionNameA )
{
strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszSessionNameA );
dest->lpSessionDesc->lpszSessionNameA = (LPSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace +=
strlen( (LPSTR)dest->lpSessionDesc->lpszSessionNameA ) + 1;
}
if( src->lpSessionDesc->lpszPasswordA )
{
strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszPasswordA );
dest->lpSessionDesc->lpszPasswordA = (LPSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace +=
strlen( (LPSTR)dest->lpSessionDesc->lpszPasswordA ) + 1;
}
}
/* DPNAME structure is optional */
if( src->lpPlayerName )
{
dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof( DPNAME );
CopyMemory( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
if( src->lpPlayerName->lpszShortNameA )
{
strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszShortNameA );
dest->lpPlayerName->lpszShortNameA = (LPSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace +=
strlen( (LPSTR)dest->lpPlayerName->lpszShortNameA ) + 1;
}
if( src->lpPlayerName->lpszLongNameA )
{
strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszLongNameA );
dest->lpPlayerName->lpszLongNameA = (LPSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace +=
strlen( (LPSTR)dest->lpPlayerName->lpszLongName ) + 1 ;
}
}
/* Copy address if it exists */
if( src->lpAddress )
{
dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
/* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
}
}
HRESULT DPLAYX_GetConnectionSettingsW
( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
LPDPLAYX_LOBBYDATA lpDplData;
DWORD dwRequiredDataSize = 0;
HANDLE hInformOnSettingRead;
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
dwRequiredDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn );
/* Do they want to know the required buffer size or is the provided buffer
* big enough?
*/
if ( ( lpData == NULL ) ||
( *lpdwDataSize < dwRequiredDataSize )
)
{
DPLAYX_ReleaseSemaphore();
*lpdwDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn );
return DPERR_BUFFERTOOSMALL;
}
DPLAYX_CopyConnStructW( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
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 %p %s\n",
hInformOnSettingRead, bSuccess ? "succeed" : "failed" );
/* Close out handle */
DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, TRUE );
}
return DP_OK;
}
/* Assumption: Enough contiguous space was allocated at dest */
void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
{
BYTE* lpStartOfFreeSpace;
CopyMemory( dest, src, sizeof( DPLCONNECTION ) );
lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION );
/* Copy the LPDPSESSIONDESC2 structure if it exists */
if( src->lpSessionDesc )
{
dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
CopyMemory( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
/* Session names may or may not exist */
if( src->lpSessionDesc->lpszSessionName )
{
strcpyW( (LPWSTR)lpStartOfFreeSpace, dest->lpSessionDesc->lpszSessionName );
src->lpSessionDesc->lpszSessionName = (LPWSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof(WCHAR) *
( strlenW( (LPWSTR)dest->lpSessionDesc->lpszSessionName ) + 1 );
}
if( src->lpSessionDesc->lpszPassword )
{
strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszPassword );
dest->lpSessionDesc->lpszPassword = (LPWSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof(WCHAR) *
( strlenW( (LPWSTR)dest->lpSessionDesc->lpszPassword ) + 1 );
}
}
/* DPNAME structure is optional */
if( src->lpPlayerName )
{
dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof( DPNAME );
CopyMemory( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
if( src->lpPlayerName->lpszShortName )
{
strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszShortName );
dest->lpPlayerName->lpszShortName = (LPWSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof(WCHAR) *
( strlenW( (LPWSTR)dest->lpPlayerName->lpszShortName ) + 1 );
}
if( src->lpPlayerName->lpszLongName )
{
strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszLongName );
dest->lpPlayerName->lpszLongName = (LPWSTR)lpStartOfFreeSpace;
lpStartOfFreeSpace += sizeof(WCHAR) *
( strlenW( (LPWSTR)dest->lpPlayerName->lpszLongName ) + 1 );
}
}
/* Copy address if it exists */
if( src->lpAddress )
{
dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
/* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
}
}
/* Store the structure into the shared data structre. Ensure that allocs for
* variable length strings come from the shared data structure.
* FIXME: We need to free information as well
*/
HRESULT DPLAYX_SetConnectionSettingsA
( DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
LPDPLAYX_LOBBYDATA lpDplData;
/* Parameter check */
if( dwFlags || !lpConn )
{
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
}
/* Store information */
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
}
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
{
DPLAYX_ReleaseSemaphore();
ERR("DPSESSIONDESC passed in? Size=%lu vs. expected=%u bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
}
/* Free the existing memory */
DPLAYX_PrivHeapFree( lpDplData->lpConn );
lpDplData->lpConn = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY,
DPLAYX_SizeOfLobbyDataA( lpConn ) );
DPLAYX_CopyConnStructA( lpDplData->lpConn, lpConn );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -