/* dplayx.dll global data implementation.
 *
 * Copyright 1999,2000 - Peter Hunnisett
 *
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 *
 * NOTES: 
 *  o Implementation of all things which are associated with dplay on
 *    the computer - i.e. shared resources and such. Methods in this
 *    compilation unit should not call anything outside of this unit
 *    except base windows services and an interface to start the
 *    messaging thread.
 *  o Methods that begin with DPLAYX_ are used for dealing with
 *    dplayx.dll data which is accessible from all processes.
 *
 */

#include <stdarg.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/unicode.h"

#include "wingdi.h"
#include "winuser.h"

#include "dplayx_global.h"
#include "dplayx_messages.h" /* For CreateMessageReceptionThread only */

WINE_DEFAULT_DEBUG_CHANNEL(dplay);

/* FIXME: Need to do all that fun other dll referencing type of stuff */

/* Static data for all processes */
static const char lpszDplayxSemaName[] = "WINE_DPLAYX_SM";
static HANDLE hDplayxSema;

static const char lpszDplayxFileMapping[] = "WINE_DPLAYX_FM";
static HANDLE hDplayxSharedMem;

static LPVOID lpSharedStaticData = NULL;


#define DPLAYX_AcquireSemaphore() TRACE( "Waiting for DPLAYX semaphore\n" ); \
                                  WaitForSingleObject( hDplayxSema, INFINITE );\
                                  TRACE( "Through wait\n" )

#define DPLAYX_ReleaseSemaphore() ReleaseSemaphore( hDplayxSema, 1, NULL ); \
                                  TRACE( "DPLAYX Semaphore released\n" ) /* FIXME: Is this correct? */


/* HACK for simple global data right now */
#define dwStaticSharedSize (128 * 1024) /* 128 KBytes */
#define dwDynamicSharedSize (512 * 1024) /* 512 KBytes */
#define dwTotalSharedSize  ( dwStaticSharedSize + dwDynamicSharedSize )


/* FIXME: Is there no easier way? */

/* Pretend the entire dynamic area is carved up into 512 byte blocks.
 * Each block has 4 bytes which are 0 unless used */
#define dwBlockSize 512
#define dwMaxBlock  (dwDynamicSharedSize/dwBlockSize)

typedef struct
{
  DWORD used;
  DWORD data[dwBlockSize-sizeof(DWORD)];
} DPLAYX_MEM_SLICE;

static DPLAYX_MEM_SLICE* lpMemArea;

static void DPLAYX_PrivHeapFree( LPVOID addr )
{
  LPVOID lpAddrStart;
  DWORD dwBlockUsed;

  /* Handle getting passed a NULL */
  if( addr == NULL )
  {
    return;
  }

  lpAddrStart = (char*)addr - sizeof(DWORD); /* Find block header */
  dwBlockUsed =  ((BYTE*)lpAddrStart - (BYTE*)lpMemArea)/dwBlockSize;

  lpMemArea[ dwBlockUsed ].used = 0;
}

static LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size )
{
  LPVOID lpvArea = NULL;
  UINT   uBlockUsed;

  if( size > (dwBlockSize - sizeof(DWORD)) )
  {
    FIXME( "Size exceeded. Request of 0x%08x\n", size );
    size = dwBlockSize - sizeof(DWORD);
  }

  /* Find blank area */
  uBlockUsed = 0;
  while( ( lpMemArea[ uBlockUsed ].used != 0 ) && ( uBlockUsed <= dwMaxBlock ) ) { uBlockUsed++; }

  if( uBlockUsed <= dwMaxBlock )
  {
    /* Set the area used */
    lpMemArea[ uBlockUsed ].used = 1;
    lpvArea = lpMemArea[ uBlockUsed ].data;
  }
  else
  {
    ERR( "No free block found\n" );
    return NULL;
  }

  if( flags & HEAP_ZERO_MEMORY )
  {
    ZeroMemory( lpvArea, size );
  }

  return lpvArea;
}


enum { numSupportedLobbies = 32, numSupportedSessions = 32 };
typedef struct tagDPLAYX_LOBBYDATA
{
  /* Points to lpConn + block of contiguous extra memory for dynamic parts
   * of the struct directly following
   */
  LPDPLCONNECTION lpConn;

  /* Information for dplobby interfaces */
  DWORD           dwAppID;
  DWORD           dwAppLaunchedFromID;

  /* Should this lobby app send messages to creator at important life
   * stages
   */
  HANDLE hInformOnAppStart;
  HANDLE hInformOnAppDeath;
  HANDLE hInformOnSettingRead;

  /* Sundries */
  BOOL bWaitForConnectionSettings;
  DWORD dwLobbyMsgThreadId;


} DPLAYX_LOBBYDATA, *LPDPLAYX_LOBBYDATA;

static DPLAYX_LOBBYDATA* lobbyData = NULL;
/* static DPLAYX_LOBBYDATA lobbyData[ numSupportedLobbies ]; */

static DPSESSIONDESC2* sessionData = NULL;
/* static DPSESSIONDESC2* sessionData[ numSupportedSessions ]; */


static void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData )
{
  ZeroMemory( lpData, sizeof( *lpData ) );
}

/* NOTE: This must be called with the semaphore acquired.
 * TRUE/FALSE with a pointer to it's data returned. Pointer data is
 * is only valid if TRUE is returned.
 */
static BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, LPDPLAYX_LOBBYDATA* lplpDplData )
{
  UINT i;

  *lplpDplData = NULL;

  if( dwAppID == 0 )
  {
    dwAppID = GetCurrentProcessId();
    TRACE( "Translated dwAppID == 0 into 0x%08x\n", dwAppID );
  }

  for( i=0; i < numSupportedLobbies; i++ )
  {
    if( lobbyData[ i ].dwAppID == dwAppID )
    {
      /* This process is lobbied */
      TRACE( "Found 0x%08x @ %u\n", dwAppID, i );
      *lplpDplData = &lobbyData[ i ];
      return TRUE;
    }
  }

  return FALSE;
}

/* Reserve a spot for the new application. TRUE means success and FALSE failure.  */
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID )
{
  UINT i;

  /* 0 is the marker for unused application data slots */
  if( dwAppID == 0 )
  {
    return FALSE;
  }

  DPLAYX_AcquireSemaphore();

  /* Find an empty space in the list and insert the data */
  for( i=0; i < numSupportedLobbies; i++ )
  {
    if( lobbyData[ i ].dwAppID == 0 )
    {
      /* This process is now lobbied */
      TRACE( "Setting lobbyData[%u] for (0x%08x,0x%08x)\n",
              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;
}

BOOL DPLAYX_SetLobbyHandles( DWORD dwAppID,
                             HANDLE hStart, HANDLE hDeath, HANDLE hConnRead )
{
  LPDPLAYX_LOBBYDATA lpLData;

  /* Need to explicitly give lobby application. Can't set for yourself */
  if( dwAppID == 0 )
  {
    return FALSE;
  }

  DPLAYX_AcquireSemaphore();

  if( !DPLAYX_IsAppIdLobbied( dwAppID, &lpLData ) )
  {
    DPLAYX_ReleaseSemaphore();
    return FALSE;
  }

  lpLData->hInformOnAppStart    = hStart;
  lpLData->hInformOnAppDeath    = hDeath;
  lpLData->hInformOnSettingRead = hConnRead;

  DPLAYX_ReleaseSemaphore();

  return TRUE;
}

static BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart,
                                        LPHANDLE lphDeath,
                                        LPHANDLE lphConnRead,
                                        BOOL     bClearSetHandles )
{
  LPDPLAYX_LOBBYDATA lpLData;

  DPLAYX_AcquireSemaphore();

  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;
}

/***************************************************************************
 * Called to initialize the global data. This will only be used on the
 * loading of the dll
 ***************************************************************************/
BOOL DPLAYX_ConstructData(void)
{
  SECURITY_ATTRIBUTES s_attrib;
  BOOL                bInitializeSharedMemory = FALSE;
  LPVOID              lpDesiredMemoryMapStart = (LPVOID)0x50000000;
  HANDLE              hInformOnStart;

  TRACE( "DPLAYX dll loaded - construct called\n" );

  /* Create a semaphore to block access to DPLAYX global data structs */

  s_attrib.bInheritHandle       = TRUE;
  s_attrib.lpSecurityDescriptor = NULL;
  s_attrib.nLength              = sizeof(s_attrib);

  hDplayxSema = CreateSemaphoreA( &s_attrib, 0, 1, lpszDplayxSemaName );

  /* First instance creates the semaphore. Others just use it */
  if( GetLastError() == ERROR_SUCCESS )
  {
    TRACE( "Semaphore %p created\n", hDplayxSema );

    /* The semaphore creator will also build the shared memory */
    bInitializeSharedMemory = TRUE;
  }
  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
  {
    TRACE( "Found semaphore handle %p\n", hDplayxSema );
    DPLAYX_AcquireSemaphore();
  }
  else
  {
    ERR( ": semaphore error %d\n", GetLastError() );
    return FALSE;
  }

  SetLastError( ERROR_SUCCESS );

  hDplayxSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE,
                                         &s_attrib,
                                         PAGE_READWRITE | SEC_COMMIT,
                                         0,
                                         dwTotalSharedSize,
                                         lpszDplayxFileMapping );

  if( GetLastError() == ERROR_SUCCESS )
  {
    TRACE( "File mapped %p created\n", hDplayxSharedMem );
  }
  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
  {
    TRACE( "Found FileMapping handle %p\n", hDplayxSharedMem );
  }
  else
  {
    ERR( ": unable to create shared memory (%d)\n", GetLastError() );
    DPLAYX_ReleaseSemaphore();
    return FALSE;
  }

  lpSharedStaticData = MapViewOfFileEx( hDplayxSharedMem,
                                        FILE_MAP_WRITE,
                                        0, 0, 0, lpDesiredMemoryMapStart );

  if( lpSharedStaticData == NULL )
  {
    ERR( ": unable to map static data into process memory space (%d)\n",
         GetLastError() );
    DPLAYX_ReleaseSemaphore();
    return FALSE;
  }
  else
  {
    if( lpDesiredMemoryMapStart == lpSharedStaticData )
    {
      TRACE( "File mapped to %p\n", lpSharedStaticData );
    }
    else
    {
      /* Presently the shared data structures use pointers. If the
       * files are not mapped into the same area, the pointers will no
       * longer make any sense :(
       * FIXME: In the future make the shared data structures have some
       *        sort of fixup to make them independent between data spaces.
       *        This will also require a rework of the session data stuff.
       */
      ERR( "File mapped to %p (not %p). Expect failure\n",
            lpSharedStaticData, lpDesiredMemoryMapStart );
    }
  }

  /* Dynamic area starts just after the static area */
  lpMemArea = (LPVOID)((BYTE*)lpSharedStaticData + dwStaticSharedSize);

  /* FIXME: Crude hack */
  lobbyData   = lpSharedStaticData;
  sessionData = (DPSESSIONDESC2*)((BYTE*)lpSharedStaticData + (dwStaticSharedSize/2));

  /* Initialize shared data segments. */
  if( bInitializeSharedMemory )
  {
    UINT i;

    TRACE( "Initializing shared memory\n" );

    /* Set all lobbies to be "empty" */
    for( i=0; i < numSupportedLobbies; i++ )
    {
      DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
    }

    /* Set all sessions to be "empty" */
    for( i=0; i < numSupportedSessions; i++ )
    {
      sessionData[i].dwSize = 0;
    }

    /* Zero out the dynamic area */
    ZeroMemory( lpMemArea, dwDynamicSharedSize );

    /* Just for fun sync the whole data area */
    FlushViewOfFile( lpSharedStaticData, dwTotalSharedSize );
  }

  DPLAYX_ReleaseSemaphore();

  /* Everything was created correctly. Signal the lobby client that
   * we started up correctly
   */
  if( DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, FALSE ) &&
      hInformOnStart
    )
  {
    BOOL bSuccess;
    bSuccess = SetEvent( hInformOnStart );
    TRACE( "Signalling lobby app start event %p %s\n",
             hInformOnStart, bSuccess ? "succeed" : "failed" );

    /* Close out handle */
    DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, TRUE );
  }

  return TRUE;
}

/***************************************************************************
 * Called to destroy all global data. This will only be used on the
 * unloading of the dll
 ***************************************************************************/
BOOL DPLAYX_DestructData(void)
{
  HANDLE hInformOnDeath;

  TRACE( "DPLAYX dll unloaded - destruct called\n" );

  /* If required, inform that this app is dying */
  if( DPLAYX_GetThisLobbyHandles( NULL, &hInformOnDeath, NULL, FALSE ) &&
      hInformOnDeath
    )
  {
    BOOL bSuccess;
    bSuccess = SetEvent( hInformOnDeath );
    TRACE( "Signalling lobby app death event %p %s\n",
             hInformOnDeath, bSuccess ? "succeed" : "failed" );

    /* Close out handle */
    DPLAYX_GetThisLobbyHandles( NULL, &hInformOnDeath, NULL, TRUE );
  }

  /* DO CLEAN UP (LAST) */

  /* Delete the semaphore */
  CloseHandle( hDplayxSema );

  /* Delete shared memory file mapping */
  UnmapViewOfFile( lpSharedStaticData );
  CloseHandle( hDplayxSharedMem );

  return FALSE;
}


/* Assumption: Enough contiguous space was allocated at dest */
static void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, const DPLCONNECTION *src )
{
  BYTE* lpStartOfFreeSpace;

  *dest = *src;

  lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION );

  /* Copy the LPDPSESSIONDESC2 structure if it exists */
  if( src->lpSessionDesc )
  {
    dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
    lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
    *dest->lpSessionDesc = *src->lpSessionDesc;

    /* Session names may or may not exist */
    if( src->lpSessionDesc->u1.lpszSessionNameA )
    {
      strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->u1.lpszSessionNameA );
      dest->lpSessionDesc->u1.lpszSessionNameA = (LPSTR)lpStartOfFreeSpace;
      lpStartOfFreeSpace +=
        strlen( dest->lpSessionDesc->u1.lpszSessionNameA ) + 1;
    }

    if( src->lpSessionDesc->u2.lpszPasswordA )
    {
      strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->u2.lpszPasswordA );
      dest->lpSessionDesc->u2.lpszPasswordA = (LPSTR)lpStartOfFreeSpace;
      lpStartOfFreeSpace +=
        strlen( dest->lpSessionDesc->u2.lpszPasswordA ) + 1;
    }
  }

  /* DPNAME structure is optional */
  if( src->lpPlayerName )
  {
    dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
    lpStartOfFreeSpace += sizeof( DPNAME );
    *dest->lpPlayerName = *src->lpPlayerName;

    if( src->lpPlayerName->u1.lpszShortNameA )
    {
      strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->u1.lpszShortNameA );
      dest->lpPlayerName->u1.lpszShortNameA = (LPSTR)lpStartOfFreeSpace;
      lpStartOfFreeSpace +=
        strlen( dest->lpPlayerName->u1.lpszShortNameA ) + 1;
    }

    if( src->lpPlayerName->u2.lpszLongNameA )
    {
      strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->u2.lpszLongNameA );
      dest->lpPlayerName->u2.lpszLongNameA = (LPSTR)lpStartOfFreeSpace;
      lpStartOfFreeSpace +=
        strlen( (LPSTR)dest->lpPlayerName->u2.lpszLongName ) + 1 ;
    }

  }

  /* Copy address if it exists */
  if( src->lpAddress )
  {
    dest->lpAddress = lpStartOfFreeSpace;
    CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
    /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
  }
}

/* Assumption: Enough contiguous space was allocated at dest */
static void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, const DPLCONNECTION *src )
{
  BYTE*              lpStartOfFreeSpace;

  *dest = *src;

  lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION );

  /* Copy the LPDPSESSIONDESC2 structure if it exists */
  if( src->lpSessionDesc )
  {
    dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
    lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
    *dest->lpSessionDesc = *src->lpSessionDesc;

    /* Session names may or may not exist */
    if( src->lpSessionDesc->u1.lpszSessionName )
    {
      strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u1.lpszSessionName );
      dest->lpSessionDesc->u1.lpszSessionName = (LPWSTR)lpStartOfFreeSpace;
      lpStartOfFreeSpace +=  sizeof(WCHAR) *
        ( strlenW( dest->lpSessionDesc->u1.lpszSessionName ) + 1 );
    }

    if( src->lpSessionDesc->u2.lpszPassword )
    {
      strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->u2.lpszPassword );
      dest->lpSessionDesc->u2.lpszPassword = (LPWSTR)lpStartOfFreeSpace;
      lpStartOfFreeSpace +=  sizeof(WCHAR) *
        ( strlenW( dest->lpSessionDesc->u2.lpszPassword ) + 1 );
    }
  }

  /* DPNAME structure is optional */
  if( src->lpPlayerName )
  {
    dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
    lpStartOfFreeSpace += sizeof( DPNAME );
    *dest->lpPlayerName = *src->lpPlayerName;

    if( src->lpPlayerName->u1.lpszShortName )
    {
      strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u1.lpszShortName );
      dest->lpPlayerName->u1.lpszShortName = (LPWSTR)lpStartOfFreeSpace;
      lpStartOfFreeSpace +=  sizeof(WCHAR) *
        ( strlenW( dest->lpPlayerName->u1.lpszShortName ) + 1 );
    }

    if( src->lpPlayerName->u2.lpszLongName )
    {
      strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->u2.lpszLongName );
      dest->lpPlayerName->u2.lpszLongName = (LPWSTR)lpStartOfFreeSpace;
      lpStartOfFreeSpace +=  sizeof(WCHAR) *
        ( strlenW( dest->lpPlayerName->u2.lpszLongName ) + 1 );
    }

  }

  /* Copy address if it exists */
  if( src->lpAddress )
  {
    dest->lpAddress = lpStartOfFreeSpace;
    CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
    /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
  }

}

static DWORD DPLAYX_SizeOfLobbyDataA( const DPLCONNECTION *lpConn )
{
  DWORD dwTotalSize = sizeof( DPLCONNECTION );

  /* Just a safety check */
  if( lpConn == NULL )
  {
    ERR( "lpConn is NULL\n" );
    return 0;
  }

  if( lpConn->lpSessionDesc != NULL )
  {
    dwTotalSize += sizeof( DPSESSIONDESC2 );

    if( lpConn->lpSessionDesc->u1.lpszSessionNameA )
    {
      dwTotalSize += strlen( lpConn->lpSessionDesc->u1.lpszSessionNameA ) + 1;
    }

    if( lpConn->lpSessionDesc->u2.lpszPasswordA )
    {
      dwTotalSize += strlen( lpConn->lpSessionDesc->u2.lpszPasswordA ) + 1;
    }
  }

  if( lpConn->lpPlayerName != NULL )
  {
    dwTotalSize += sizeof( DPNAME );

    if( lpConn->lpPlayerName->u1.lpszShortNameA )
    {
      dwTotalSize += strlen( lpConn->lpPlayerName->u1.lpszShortNameA ) + 1;
    }

    if( lpConn->lpPlayerName->u2.lpszLongNameA )
    {
      dwTotalSize += strlen( lpConn->lpPlayerName->u2.lpszLongNameA ) + 1;
    }

  }

  dwTotalSize += lpConn->dwAddressSize;

  return dwTotalSize;
}

static DWORD DPLAYX_SizeOfLobbyDataW( const DPLCONNECTION *lpConn )
{
  DWORD dwTotalSize = sizeof( DPLCONNECTION );

  /* Just a safety check */
  if( lpConn == NULL )
  {
    ERR( "lpConn is NULL\n" );
    return 0;
  }

  if( lpConn->lpSessionDesc != NULL )
  {
    dwTotalSize += sizeof( DPSESSIONDESC2 );

    if( lpConn->lpSessionDesc->u1.lpszSessionName )
    {
      dwTotalSize += sizeof( WCHAR ) *
        ( strlenW( lpConn->lpSessionDesc->u1.lpszSessionName ) + 1 );
    }

    if( lpConn->lpSessionDesc->u2.lpszPassword )
    {
      dwTotalSize += sizeof( WCHAR ) *
        ( strlenW( lpConn->lpSessionDesc->u2.lpszPassword ) + 1 );
    }
  }

  if( lpConn->lpPlayerName != NULL )
  {
    dwTotalSize += sizeof( DPNAME );

    if( lpConn->lpPlayerName->u1.lpszShortName )
    {
      dwTotalSize += sizeof( WCHAR ) *
        ( strlenW( lpConn->lpPlayerName->u1.lpszShortName ) + 1 );
    }

    if( lpConn->lpPlayerName->u2.lpszLongName )
    {
      dwTotalSize += sizeof( WCHAR ) *
        ( strlenW( lpConn->lpPlayerName->u2.lpszLongName ) + 1 );
    }

  }

  dwTotalSize += lpConn->dwAddressSize;

  return dwTotalSize;
}

HRESULT DPLAYX_GetConnectionSettingsA
( DWORD dwAppID,
  LPVOID lpData,
  LPDWORD lpdwDataSize )
{
  LPDPLAYX_LOBBYDATA lpDplData;
  DWORD              dwRequiredDataSize = 0;
  HANDLE             hInformOnSettingRead;

  DPLAYX_AcquireSemaphore();

  if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
  {
    DPLAYX_ReleaseSemaphore();

    TRACE( "Application 0x%08x 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( 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;
}

HRESULT DPLAYX_GetConnectionSettingsW
( DWORD dwAppID,
  LPVOID lpData,
  LPDWORD lpdwDataSize )
{
  LPDPLAYX_LOBBYDATA lpDplData;
  DWORD              dwRequiredDataSize = 0;
  HANDLE             hInformOnSettingRead;

  DPLAYX_AcquireSemaphore();

  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( 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;
}

/* Store the structure into the shared data structure. 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,
  const DPLCONNECTION *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=%08x\n", lpConn->dwSize );

    return DPERR_INVALIDPARAMS;
  }

  DPLAYX_AcquireSemaphore();

  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=%u\n",
        lpConn->lpSessionDesc?lpConn->lpSessionDesc->dwSize:0 );

    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 );


  DPLAYX_ReleaseSemaphore();

  /* FIXME: Send a message - I think */

  return DP_OK;
}

/* Store the structure into the shared data structure. Ensure that allocs for
 * variable length strings come from the shared data structure.
 * FIXME: We need to free information as well
 */
HRESULT DPLAYX_SetConnectionSettingsW
( DWORD dwFlags,
  DWORD dwAppID,
  const DPLCONNECTION *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=%u\n", lpConn->dwSize );

    return DPERR_INVALIDPARAMS;
  }

  DPLAYX_AcquireSemaphore();

  if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
  {
    DPLAYX_ReleaseSemaphore();

    return DPERR_NOTLOBBIED;
  }

  /* Free the existing memory */
  DPLAYX_PrivHeapFree( lpDplData->lpConn );

  lpDplData->lpConn = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY,
                                            DPLAYX_SizeOfLobbyDataW( lpConn ) );

  DPLAYX_CopyConnStructW( lpDplData->lpConn, lpConn );


  DPLAYX_ReleaseSemaphore();

  /* FIXME: Send a message - I think */

  return DP_OK;
}

BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait )
{
  LPDPLAYX_LOBBYDATA lpLobbyData;

  DPLAYX_AcquireSemaphore();

  if( !DPLAYX_IsAppIdLobbied( 0, &lpLobbyData ) )
  {
    DPLAYX_ReleaseSemaphore();
    return FALSE;
  }

  lpLobbyData->bWaitForConnectionSettings = bWait;

  DPLAYX_ReleaseSemaphore();

  return TRUE;
}

BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void)
{
  UINT i;
  BOOL bFound = FALSE;

  DPLAYX_AcquireSemaphore();

  for( i=0; i < numSupportedLobbies; i++ )
  {
    if( ( lobbyData[ i ].dwAppID != 0 ) &&            /* lobby initialized */
        ( lobbyData[ i ].bWaitForConnectionSettings ) /* Waiting */
      )
    {
      bFound = TRUE;
      break;
    }
  }

  DPLAYX_ReleaseSemaphore();

  return bFound;
}

BOOL DPLAYX_SetLobbyMsgThreadId( DWORD dwAppId, DWORD dwThreadId )
{
  LPDPLAYX_LOBBYDATA lpLobbyData;

  DPLAYX_AcquireSemaphore();

  if( !DPLAYX_IsAppIdLobbied( dwAppId, &lpLobbyData ) )
  {
    DPLAYX_ReleaseSemaphore();
    return FALSE;
  }

  lpLobbyData->dwLobbyMsgThreadId = dwThreadId;

  DPLAYX_ReleaseSemaphore();

  return TRUE;
}

/* NOTE: This is potentially not thread safe. You are not guaranteed to end up
         with the correct string printed in the case where the HRESULT is not
         known. You will just get the last hr passed in. This can change
         over time if this method is used a lot :) */
LPCSTR DPLAYX_HresultToString(HRESULT hr)
{
  static char szTempStr[12];

  switch (hr)
  {
    case DP_OK:
      return "DP_OK";
    case DPERR_ALREADYINITIALIZED:
      return "DPERR_ALREADYINITIALIZED";
    case DPERR_ACCESSDENIED:
      return "DPERR_ACCESSDENIED";
    case DPERR_ACTIVEPLAYERS:
      return "DPERR_ACTIVEPLAYERS";
    case DPERR_BUFFERTOOSMALL:
      return "DPERR_BUFFERTOOSMALL";
    case DPERR_CANTADDPLAYER:
      return "DPERR_CANTADDPLAYER";
    case DPERR_CANTCREATEGROUP:
      return "DPERR_CANTCREATEGROUP";
    case DPERR_CANTCREATEPLAYER:
      return "DPERR_CANTCREATEPLAYER";
    case DPERR_CANTCREATESESSION:
      return "DPERR_CANTCREATESESSION";
    case DPERR_CAPSNOTAVAILABLEYET:
      return "DPERR_CAPSNOTAVAILABLEYET";
    case DPERR_EXCEPTION:
      return "DPERR_EXCEPTION";
    case DPERR_GENERIC:
      return "DPERR_GENERIC";
    case DPERR_INVALIDFLAGS:
      return "DPERR_INVALIDFLAGS";
    case DPERR_INVALIDOBJECT:
      return "DPERR_INVALIDOBJECT";
    case DPERR_INVALIDPARAMS:
      return "DPERR_INVALIDPARAMS";
    case DPERR_INVALIDPLAYER:
      return "DPERR_INVALIDPLAYER";
    case DPERR_INVALIDGROUP:
      return "DPERR_INVALIDGROUP";
    case DPERR_NOCAPS:
      return "DPERR_NOCAPS";
    case DPERR_NOCONNECTION:
      return "DPERR_NOCONNECTION";
    case DPERR_OUTOFMEMORY:
      return "DPERR_OUTOFMEMORY";
    case DPERR_NOMESSAGES:
      return "DPERR_NOMESSAGES";
    case DPERR_NONAMESERVERFOUND:
      return "DPERR_NONAMESERVERFOUND";
    case DPERR_NOPLAYERS:
      return "DPERR_NOPLAYERS";
    case DPERR_NOSESSIONS:
      return "DPERR_NOSESSIONS";
    case DPERR_PENDING:
      return "DPERR_PENDING";
    case DPERR_SENDTOOBIG:
      return "DPERR_SENDTOOBIG";
    case DPERR_TIMEOUT:
      return "DPERR_TIMEOUT";
    case DPERR_UNAVAILABLE:
      return "DPERR_UNAVAILABLE";
    case DPERR_UNSUPPORTED:
      return "DPERR_UNSUPPORTED";
    case DPERR_BUSY:
      return "DPERR_BUSY";
    case DPERR_USERCANCEL:
      return "DPERR_USERCANCEL";
    case DPERR_NOINTERFACE:
      return "DPERR_NOINTERFACE";
    case DPERR_CANNOTCREATESERVER:
      return "DPERR_CANNOTCREATESERVER";
    case DPERR_PLAYERLOST:
      return "DPERR_PLAYERLOST";
    case DPERR_SESSIONLOST:
      return "DPERR_SESSIONLOST";
    case DPERR_UNINITIALIZED:
      return "DPERR_UNINITIALIZED";
    case DPERR_NONEWPLAYERS:
      return "DPERR_NONEWPLAYERS";
    case DPERR_INVALIDPASSWORD:
      return "DPERR_INVALIDPASSWORD";
    case DPERR_CONNECTING:
      return "DPERR_CONNECTING";
    case DPERR_CONNECTIONLOST:
      return "DPERR_CONNECTIONLOST";
    case DPERR_UNKNOWNMESSAGE:
      return "DPERR_UNKNOWNMESSAGE";
    case DPERR_CANCELFAILED:
      return "DPERR_CANCELFAILED";
    case DPERR_INVALIDPRIORITY:
      return "DPERR_INVALIDPRIORITY";
    case DPERR_NOTHANDLED:
      return "DPERR_NOTHANDLED";
    case DPERR_CANCELLED:
      return "DPERR_CANCELLED";
    case DPERR_ABORTED:
      return "DPERR_ABORTED";
    case DPERR_BUFFERTOOLARGE:
      return "DPERR_BUFFERTOOLARGE";
    case DPERR_CANTCREATEPROCESS:
      return "DPERR_CANTCREATEPROCESS";
    case DPERR_APPNOTSTARTED:
      return "DPERR_APPNOTSTARTED";
    case DPERR_INVALIDINTERFACE:
      return "DPERR_INVALIDINTERFACE";
    case DPERR_NOSERVICEPROVIDER:
      return "DPERR_NOSERVICEPROVIDER";
    case DPERR_UNKNOWNAPPLICATION:
      return "DPERR_UNKNOWNAPPLICATION";
    case DPERR_NOTLOBBIED:
      return "DPERR_NOTLOBBIED";
    case DPERR_SERVICEPROVIDERLOADED:
      return "DPERR_SERVICEPROVIDERLOADED";
    case DPERR_ALREADYREGISTERED:
      return "DPERR_ALREADYREGISTERED";
    case DPERR_NOTREGISTERED:
      return "DPERR_NOTREGISTERED";
    case DPERR_AUTHENTICATIONFAILED:
      return "DPERR_AUTHENTICATIONFAILED";
    case DPERR_CANTLOADSSPI:
      return "DPERR_CANTLOADSSPI";
    case DPERR_ENCRYPTIONFAILED:
      return "DPERR_ENCRYPTIONFAILED";
    case DPERR_SIGNFAILED:
      return "DPERR_SIGNFAILED";
    case DPERR_CANTLOADSECURITYPACKAGE:
      return "DPERR_CANTLOADSECURITYPACKAGE";
    case DPERR_ENCRYPTIONNOTSUPPORTED:
      return "DPERR_ENCRYPTIONNOTSUPPORTED";
    case DPERR_CANTLOADCAPI:
      return "DPERR_CANTLOADCAPI";
    case DPERR_NOTLOGGEDIN:
      return "DPERR_NOTLOGGEDIN";
    case DPERR_LOGONDENIED:
      return "DPERR_LOGONDENIED";
    default:
      /* For errors not in the list, return HRESULT as a string
         This part is not thread safe */
      WARN( "Unknown error 0x%08x\n", hr );
      wsprintfA( szTempStr, "0x%08lx", hr );
      return szTempStr;
  }
}
