533 lines
16 KiB
C
533 lines
16 KiB
C
|
/* dplayx.dll global data implementation.
|
||
|
*
|
||
|
* Copyright 1999 - Peter Hunnisett
|
||
|
*
|
||
|
* <presently under construction - contact hunnise@nortelnetworks.com>
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/* NOTE: Methods that begin with DPLAYX_ are used for dealing with
|
||
|
* dplayx.dll data which is accessible from all processes.
|
||
|
*/
|
||
|
|
||
|
#include "debugtools.h"
|
||
|
#include "winbase.h"
|
||
|
#include "winerror.h"
|
||
|
#include "heap.h" /* Really shouldn't be using those HEAP_strdupA interfaces should I? */
|
||
|
|
||
|
#include "dplayx_global.h"
|
||
|
|
||
|
DEFAULT_DEBUG_CHANNEL(dplay)
|
||
|
|
||
|
/* FIXME: Need to do all that fun other dll referencing type of stuff */
|
||
|
/* FIXME: Need to allocate a giant static area - or a global data type thing for Get/Set */
|
||
|
|
||
|
/* Static data for all processes */
|
||
|
static LPSTR lpszDplayxSemaName = "DPLAYX_SM";
|
||
|
static HANDLE hDplayxSema;
|
||
|
|
||
|
|
||
|
|
||
|
#define DPLAYX_AquireSemaphore() 0L /* WaitForSingleObject( hDplayxSema, INFINITE? ) */
|
||
|
#define DPLAYX_ReleaseSemaphore() 0L /* ReleaseSemaphore( hDplayxSema, ..., ... ) */
|
||
|
|
||
|
|
||
|
/* HACK for simple global data right now */
|
||
|
enum { numSupportedLobbies = 32 };
|
||
|
typedef struct tagDirectPlayLobbyData
|
||
|
{
|
||
|
DWORD dwConnFlags;
|
||
|
DPSESSIONDESC2 sessionDesc;
|
||
|
DPNAME playerName;
|
||
|
GUID guidSP;
|
||
|
LPVOID lpAddress;
|
||
|
DWORD dwAddressSize;
|
||
|
DWORD dwAppID;
|
||
|
HANDLE hReceiveEvent;
|
||
|
} DirectPlayLobbyData, *lpDirectPlayLobbyData;
|
||
|
|
||
|
static DirectPlayLobbyData lobbyData[ numSupportedLobbies ];
|
||
|
|
||
|
/* Function prototypes */
|
||
|
BOOL DPLAYX_AppIdLobbied( DWORD dwAppId, lpDirectPlayLobbyData* dplData );
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/***************************************************************************
|
||
|
* Called to initialize the global data. This will only be used on the
|
||
|
* loading of the dll
|
||
|
***************************************************************************/
|
||
|
void DPLAYX_ConstructData(void)
|
||
|
{
|
||
|
UINT i;
|
||
|
|
||
|
TRACE( "DPLAYX dll loaded - construct called\n" );
|
||
|
|
||
|
/* FIXME: This needs to be allocated shared */
|
||
|
hDplayxSema = CreateSemaphoreA( NULL, 0, 1, lpszDplayxSemaName );
|
||
|
|
||
|
if( !hDplayxSema )
|
||
|
{
|
||
|
/* Really don't have any choice but to continue... */
|
||
|
ERR( "Semaphore creation error 0x%08lx\n", GetLastError() );
|
||
|
}
|
||
|
|
||
|
/* Set all lobbies to be "empty" */
|
||
|
for( i=0; i < numSupportedLobbies; i++ )
|
||
|
{
|
||
|
lobbyData[ i ].dwAppID = 0;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/***************************************************************************
|
||
|
* Called to destroy all global data. This will only be used on the
|
||
|
* unloading of the dll
|
||
|
***************************************************************************/
|
||
|
void DPLAYX_DestructData(void)
|
||
|
{
|
||
|
/* Hmmm...what to call to delete the semaphore? Auto delete? */
|
||
|
TRACE( "DPLAYX dll unloaded - destruct called\n" );
|
||
|
}
|
||
|
|
||
|
|
||
|
/* NOTE: This must be called with the semaphore aquired.
|
||
|
* TRUE/FALSE with a pointer to it's data returned
|
||
|
*/
|
||
|
BOOL DPLAYX_AppIdLobbied( DWORD dwAppID, lpDirectPlayLobbyData* lplpDplData )
|
||
|
{
|
||
|
INT i;
|
||
|
|
||
|
if( dwAppID == 0 )
|
||
|
{
|
||
|
dwAppID = GetCurrentProcessId();
|
||
|
}
|
||
|
|
||
|
for( i=0; i < numSupportedLobbies; i++ )
|
||
|
{
|
||
|
if( lobbyData[ i ].dwAppID == dwAppID )
|
||
|
{
|
||
|
/* This process is lobbied */
|
||
|
*lplpDplData = &lobbyData[ i ];
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
#if !defined( WORKING_PROCESS_SUSPEND )
|
||
|
/* These two functions should not exist. We would normally create a process initially
|
||
|
suspended when we RunApplication. This gives us time to actually store some data
|
||
|
before the new process might try to read it. However, process suspension doesn't
|
||
|
work yet and I'm too stupid to get it going. So, we'll just hack in fine fashion */
|
||
|
DWORD DPLAYX_AquireSemaphoreHack( void )
|
||
|
{
|
||
|
return DPLAYX_AquireSemaphore();
|
||
|
}
|
||
|
|
||
|
DWORD DPLAYX_ReleaseSemaphoreHack( void )
|
||
|
{
|
||
|
return DPLAYX_ReleaseSemaphore();
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
|
||
|
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
|
||
|
{
|
||
|
INT i;
|
||
|
|
||
|
DPLAYX_AquireSemaphore();
|
||
|
|
||
|
for( i=0; i < numSupportedLobbies; i++ )
|
||
|
{
|
||
|
if( lobbyData[ i ].dwAppID == 0 )
|
||
|
{
|
||
|
/* This process is now lobbied */
|
||
|
lobbyData[ i ].dwAppID = dwAppID;
|
||
|
lobbyData[ i ].hReceiveEvent = hReceiveEvent;
|
||
|
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HRESULT DPLAYX_GetConnectionSettingsA
|
||
|
( DWORD dwAppID,
|
||
|
LPVOID lpData,
|
||
|
LPDWORD lpdwDataSize )
|
||
|
{
|
||
|
lpDirectPlayLobbyData lpDplData;
|
||
|
LPDPLCONNECTION lpDplConnection;
|
||
|
|
||
|
DPLAYX_AquireSemaphore();
|
||
|
|
||
|
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
return DPERR_NOTLOBBIED;
|
||
|
}
|
||
|
|
||
|
/* Verify buffer size */
|
||
|
if ( ( lpData == NULL ) ||
|
||
|
( *lpdwDataSize < sizeof( DPLCONNECTION ) )
|
||
|
)
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
*lpdwDataSize = sizeof( DPLCONNECTION );
|
||
|
|
||
|
return DPERR_BUFFERTOOSMALL;
|
||
|
}
|
||
|
|
||
|
/* Copy the information */
|
||
|
lpDplConnection = (LPDPLCONNECTION)lpData;
|
||
|
|
||
|
/* Copy everything we've got into here */
|
||
|
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
|
||
|
lpDplConnection->dwSize = sizeof( DPLCONNECTION );
|
||
|
lpDplConnection->dwFlags = lpDplData->dwConnFlags;
|
||
|
|
||
|
/* Copy LPDPSESSIONDESC2 struct */
|
||
|
lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->sessionDesc ) );
|
||
|
memcpy( lpDplConnection->lpSessionDesc, &lpDplData->sessionDesc, sizeof( lpDplData->sessionDesc ) );
|
||
|
|
||
|
if( lpDplData->sessionDesc.sess.lpszSessionNameA )
|
||
|
{
|
||
|
lpDplConnection->lpSessionDesc->sess.lpszSessionNameA =
|
||
|
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.sess.lpszSessionNameA );
|
||
|
}
|
||
|
|
||
|
if( lpDplData->sessionDesc.pass.lpszPasswordA )
|
||
|
{
|
||
|
lpDplConnection->lpSessionDesc->pass.lpszPasswordA =
|
||
|
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.pass.lpszPasswordA );
|
||
|
}
|
||
|
|
||
|
lpDplConnection->lpSessionDesc->dwReserved1 = lpDplData->sessionDesc.dwReserved1;
|
||
|
lpDplConnection->lpSessionDesc->dwReserved2 = lpDplData->sessionDesc.dwReserved2;
|
||
|
|
||
|
/* Copy DPNAME struct - seems to be optional - check for existance first */
|
||
|
lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->playerName ) );
|
||
|
memcpy( lpDplConnection->lpPlayerName, &(lpDplData->playerName), sizeof( lpDplData->playerName ) );
|
||
|
|
||
|
if( lpDplData->playerName.psn.lpszShortNameA )
|
||
|
{
|
||
|
lpDplConnection->lpPlayerName->psn.lpszShortNameA =
|
||
|
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.psn.lpszShortNameA );
|
||
|
}
|
||
|
|
||
|
if( lpDplData->playerName.pln.lpszLongNameA )
|
||
|
{
|
||
|
lpDplConnection->lpPlayerName->pln.lpszLongNameA =
|
||
|
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.pln.lpszLongNameA );
|
||
|
}
|
||
|
|
||
|
memcpy( &lpDplConnection->guidSP, &lpDplData->guidSP, sizeof( lpDplData->guidSP ) );
|
||
|
|
||
|
lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->dwAddressSize );
|
||
|
memcpy( lpDplConnection->lpAddress, lpDplData->lpAddress, lpDplData->dwAddressSize );
|
||
|
|
||
|
lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
|
||
|
|
||
|
/* Send a message - or only the first time? */
|
||
|
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
return DP_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT DPLAYX_GetConnectionSettingsW
|
||
|
( DWORD dwAppID,
|
||
|
LPVOID lpData,
|
||
|
LPDWORD lpdwDataSize )
|
||
|
{
|
||
|
lpDirectPlayLobbyData lpDplData;
|
||
|
LPDPLCONNECTION lpDplConnection;
|
||
|
|
||
|
DPLAYX_AquireSemaphore();
|
||
|
|
||
|
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
return DPERR_NOTLOBBIED;
|
||
|
}
|
||
|
|
||
|
/* Verify buffer size */
|
||
|
if ( ( lpData == NULL ) ||
|
||
|
( *lpdwDataSize < sizeof( DPLCONNECTION ) )
|
||
|
)
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
*lpdwDataSize = sizeof( DPLCONNECTION );
|
||
|
|
||
|
return DPERR_BUFFERTOOSMALL;
|
||
|
}
|
||
|
|
||
|
/* Copy the information */
|
||
|
lpDplConnection = (LPDPLCONNECTION)lpData;
|
||
|
|
||
|
/* Copy everything we've got into here */
|
||
|
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
|
||
|
lpDplConnection->dwSize = sizeof( DPLCONNECTION );
|
||
|
lpDplConnection->dwFlags = lpDplData->dwConnFlags;
|
||
|
|
||
|
/* Copy LPDPSESSIONDESC2 struct */
|
||
|
lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->sessionDesc ) );
|
||
|
memcpy( lpDplConnection->lpSessionDesc, &lpDplData->sessionDesc, sizeof( lpDplData->sessionDesc ) );
|
||
|
|
||
|
if( lpDplData->sessionDesc.sess.lpszSessionName )
|
||
|
{
|
||
|
lpDplConnection->lpSessionDesc->sess.lpszSessionName =
|
||
|
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.sess.lpszSessionName );
|
||
|
}
|
||
|
|
||
|
if( lpDplData->sessionDesc.pass.lpszPassword )
|
||
|
{
|
||
|
lpDplConnection->lpSessionDesc->pass.lpszPassword =
|
||
|
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.pass.lpszPassword );
|
||
|
}
|
||
|
|
||
|
lpDplConnection->lpSessionDesc->dwReserved1 = lpDplData->sessionDesc.dwReserved1;
|
||
|
lpDplConnection->lpSessionDesc->dwReserved2 = lpDplData->sessionDesc.dwReserved2;
|
||
|
|
||
|
/* Copy DPNAME struct - seems to be optional - check for existance first */
|
||
|
lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->playerName ) );
|
||
|
memcpy( lpDplConnection->lpPlayerName, &(lpDplData->playerName), sizeof( lpDplData->playerName ) );
|
||
|
|
||
|
if( lpDplData->playerName.psn.lpszShortName )
|
||
|
{
|
||
|
lpDplConnection->lpPlayerName->psn.lpszShortName =
|
||
|
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.psn.lpszShortName );
|
||
|
}
|
||
|
|
||
|
if( lpDplData->playerName.pln.lpszLongName )
|
||
|
{
|
||
|
lpDplConnection->lpPlayerName->pln.lpszLongName =
|
||
|
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.pln.lpszLongName );
|
||
|
}
|
||
|
|
||
|
memcpy( &lpDplConnection->guidSP, &lpDplData->guidSP, sizeof( lpDplData->guidSP ) );
|
||
|
|
||
|
lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->dwAddressSize );
|
||
|
memcpy( lpDplConnection->lpAddress, lpDplData->lpAddress, lpDplData->dwAddressSize );
|
||
|
|
||
|
lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
|
||
|
|
||
|
/* Send a message - or only the first time? */
|
||
|
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
return DP_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT DPLAYX_SetConnectionSettingsA
|
||
|
( DWORD dwFlags,
|
||
|
DWORD dwAppID,
|
||
|
LPDPLCONNECTION lpConn )
|
||
|
{
|
||
|
lpDirectPlayLobbyData lpDplData;
|
||
|
|
||
|
DPLAYX_AquireSemaphore();
|
||
|
|
||
|
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
|
||
|
{
|
||
|
/* FIXME: Create a new entry for this dwAppID? */
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
return DPERR_GENERIC;
|
||
|
}
|
||
|
|
||
|
/* Paramater check */
|
||
|
if( dwFlags || !lpConn )
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
ERR("invalid parameters.\n");
|
||
|
return DPERR_INVALIDPARAMS;
|
||
|
}
|
||
|
|
||
|
/* Store information */
|
||
|
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
|
||
|
lpConn->dwSize, sizeof( DPLCONNECTION ) );
|
||
|
|
||
|
return DPERR_INVALIDPARAMS;
|
||
|
}
|
||
|
|
||
|
/* Need to investigate the lpConn->lpSessionDesc to figure out
|
||
|
* what type of session we need to join/create.
|
||
|
*/
|
||
|
if( (!lpConn->lpSessionDesc ) ||
|
||
|
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
|
||
|
)
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
|
||
|
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
|
||
|
|
||
|
return DPERR_INVALIDPARAMS;
|
||
|
}
|
||
|
|
||
|
/* FIXME: How do I store this stuff so that it can be read by all processes? Static area? What about strings? Ewww...large global shared */
|
||
|
|
||
|
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
|
||
|
lpDplData->dwConnFlags = lpConn->dwFlags;
|
||
|
|
||
|
/* Copy LPDPSESSIONDESC2 struct - this is required */
|
||
|
memcpy( &lpDplData->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
|
||
|
|
||
|
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
|
||
|
if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
|
||
|
lpDplData->sessionDesc.sess.lpszSessionNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionNameA );
|
||
|
else
|
||
|
lpDplData->sessionDesc.sess.lpszSessionNameA = NULL;
|
||
|
|
||
|
if( lpConn->lpSessionDesc->pass.lpszPasswordA )
|
||
|
lpDplData->sessionDesc.pass.lpszPasswordA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPasswordA );
|
||
|
else
|
||
|
lpDplData->sessionDesc.pass.lpszPasswordA = NULL;
|
||
|
|
||
|
lpDplData->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
|
||
|
lpDplData->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
|
||
|
|
||
|
/* Copy DPNAME struct - seems to be optional - check for existance first */
|
||
|
if( lpConn->lpPlayerName )
|
||
|
{
|
||
|
memcpy( &lpDplData->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
|
||
|
|
||
|
if( lpConn->lpPlayerName->psn.lpszShortNameA )
|
||
|
lpDplData->playerName.psn.lpszShortNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortNameA );
|
||
|
|
||
|
if( lpConn->lpPlayerName->pln.lpszLongNameA )
|
||
|
lpDplData->playerName.pln.lpszLongNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongNameA );
|
||
|
|
||
|
}
|
||
|
|
||
|
memcpy( &lpDplData->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
|
||
|
|
||
|
lpDplData->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
|
||
|
memcpy( lpDplData->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
|
||
|
|
||
|
lpDplData->dwAddressSize = lpConn->dwAddressSize;
|
||
|
|
||
|
/* Send a message - I think */
|
||
|
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
return DP_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT DPLAYX_SetConnectionSettingsW
|
||
|
( DWORD dwFlags,
|
||
|
DWORD dwAppID,
|
||
|
LPDPLCONNECTION lpConn )
|
||
|
{
|
||
|
lpDirectPlayLobbyData lpDplData;
|
||
|
|
||
|
DPLAYX_AquireSemaphore();
|
||
|
|
||
|
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
return DPERR_NOTLOBBIED;
|
||
|
}
|
||
|
|
||
|
/* Paramater check */
|
||
|
if( dwFlags || !lpConn )
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
ERR("invalid parameters.\n");
|
||
|
return DPERR_INVALIDPARAMS;
|
||
|
}
|
||
|
|
||
|
/* Store information */
|
||
|
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
|
||
|
lpConn->dwSize, sizeof( DPLCONNECTION ) );
|
||
|
|
||
|
return DPERR_INVALIDPARAMS;
|
||
|
}
|
||
|
|
||
|
/* Need to investigate the lpConn->lpSessionDesc to figure out
|
||
|
* what type of session we need to join/create.
|
||
|
*/
|
||
|
if( (!lpConn->lpSessionDesc ) ||
|
||
|
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
|
||
|
)
|
||
|
{
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
|
||
|
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
|
||
|
|
||
|
return DPERR_INVALIDPARAMS;
|
||
|
}
|
||
|
|
||
|
/* FIXME: How do I store this stuff so that it can be read by all processes? Static area? What about strings? Ewww...large global shared */
|
||
|
|
||
|
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
|
||
|
lpDplData->dwConnFlags = lpConn->dwFlags;
|
||
|
|
||
|
/* Copy LPDPSESSIONDESC2 struct - this is required */
|
||
|
memcpy( &lpDplData->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
|
||
|
|
||
|
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
|
||
|
if( lpConn->lpSessionDesc->sess.lpszSessionName )
|
||
|
lpDplData->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
|
||
|
else
|
||
|
lpDplData->sessionDesc.sess.lpszSessionName = NULL;
|
||
|
|
||
|
if( lpConn->lpSessionDesc->pass.lpszPassword )
|
||
|
lpDplData->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
|
||
|
else
|
||
|
lpDplData->sessionDesc.pass.lpszPassword = NULL;
|
||
|
|
||
|
lpDplData->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
|
||
|
lpDplData->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
|
||
|
|
||
|
/* Copy DPNAME struct - seems to be optional - check for existance first */
|
||
|
if( lpConn->lpPlayerName )
|
||
|
{
|
||
|
memcpy( &lpDplData->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
|
||
|
|
||
|
if( lpConn->lpPlayerName->psn.lpszShortName )
|
||
|
lpDplData->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName );
|
||
|
|
||
|
if( lpConn->lpPlayerName->pln.lpszLongName )
|
||
|
lpDplData->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
|
||
|
|
||
|
}
|
||
|
|
||
|
memcpy( &lpDplData->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
|
||
|
|
||
|
lpDplData->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
|
||
|
memcpy( lpDplData->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
|
||
|
|
||
|
lpDplData->dwAddressSize = lpConn->dwAddressSize;
|
||
|
|
||
|
/* Send a message - I think */
|
||
|
|
||
|
DPLAYX_ReleaseSemaphore();
|
||
|
|
||
|
return DP_OK;
|
||
|
}
|