| /* dplayx.dll global data implementation. |
| * |
| * Copyright 1999,2000 - 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 <stdio.h> |
| #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 */ |
| |
| /* Static data for all processes */ |
| static LPSTR lpszDplayxSemaName = "WINE_DPLAYX_SM"; |
| static HANDLE hDplayxSema; |
| |
| |
| |
| #define DPLAYX_AquireSemaphore() TRACE( "Waiting for DPLAYX sema\n" ); \ |
| WaitForSingleObject( hDplayxSema, INFINITE ); TRACE( "Through wait\n" ) |
| #define DPLAYX_ReleaseSemaphore() ReleaseSemaphore( hDplayxSema, 1, NULL ); \ |
| TRACE( "DPLAYX Sema released\n" ); /* FIXME: Is this correct? */ |
| |
| |
| /* HACK for simple global data right now */ |
| enum { numSupportedLobbies = 32, numSupportedSessions = 32 }; |
| typedef struct tagDirectPlayLobbyData |
| { |
| /* Just a DPLCONNECTION struct */ |
| DWORD dwConnFlags; |
| DPSESSIONDESC2 sessionDesc; |
| DPNAME playerName; |
| GUID guidSP; |
| LPVOID lpAddress; |
| DWORD dwAddressSize; |
| |
| /* Information for dplobby interfaces */ |
| DWORD dwAppID; |
| HANDLE hReceiveEvent; |
| DWORD dwAppLaunchedFromID; |
| |
| } DirectPlayLobbyData, *lpDirectPlayLobbyData; |
| |
| static DirectPlayLobbyData lobbyData[ numSupportedLobbies ]; |
| |
| /* Hack for now */ |
| static DPSESSIONDESC2 sessionData[ numSupportedSessions ]; |
| |
| /* Function prototypes */ |
| BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, lpDirectPlayLobbyData* dplData ); |
| void DPLAYX_InitializeLobbyDataEntry( lpDirectPlayLobbyData lpData ); |
| BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest, |
| LPCDPSESSIONDESC2 lpSessionSrc ); |
| |
| |
| |
| /*************************************************************************** |
| * 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" ); |
| |
| /* Create a semahopre to block access to DPLAYX global data structs |
| It starts unblocked, and allows up to 65000 users blocked on it. Seems reasonable |
| for the time being */ |
| hDplayxSema = CreateSemaphoreA( NULL, 1, 65000, 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++ ) |
| { |
| DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] ); |
| } |
| |
| /* Set all sessions to be "empty" */ |
| for( i=0; i < numSupportedSessions; i++ ) |
| { |
| sessionData[i].dwSize = 0; |
| } |
| |
| } |
| |
| /*************************************************************************** |
| * Called to destroy all global data. This will only be used on the |
| * unloading of the dll |
| ***************************************************************************/ |
| void DPLAYX_DestructData(void) |
| { |
| TRACE( "DPLAYX dll unloaded - destruct called\n" ); |
| |
| /* delete the semaphore */ |
| CloseHandle( hDplayxSema ); |
| } |
| |
| |
| void DPLAYX_InitializeLobbyDataEntry( lpDirectPlayLobbyData lpData ) |
| { |
| ZeroMemory( lpData, sizeof( *lpData ) ); |
| |
| /* Set the handle to a better invalid value */ |
| lpData->hReceiveEvent = INVALID_HANDLE_VALUE; |
| } |
| |
| /* NOTE: This must be called with the semaphore aquired. |
| * TRUE/FALSE with a pointer to it's data returned. Pointer data is |
| * is only valid if TRUE is returned. |
| */ |
| BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, lpDirectPlayLobbyData* lplpDplData ) |
| { |
| INT i; |
| |
| *lplpDplData = NULL; |
| |
| if( dwAppID == 0 ) |
| { |
| dwAppID = GetCurrentProcessId(); |
| TRACE( "Translated dwAppID == 0 into 0x%08lx\n", dwAppID ); |
| } |
| |
| for( i=0; i < numSupportedLobbies; i++ ) |
| { |
| if( lobbyData[ i ].dwAppID == dwAppID ) |
| { |
| /* This process is lobbied */ |
| *lplpDplData = &lobbyData[ i ]; |
| return TRUE; |
| } |
| } |
| |
| return FALSE; |
| } |
| |
| /* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */ |
| BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent ) |
| { |
| UINT i; |
| |
| /* 0 is the marker for unused application data slots */ |
| if( dwAppID == 0 ) |
| { |
| return FALSE; |
| } |
| |
| DPLAYX_AquireSemaphore(); |
| |
| /* 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 */ |
| lobbyData[ i ].dwAppID = dwAppID; |
| lobbyData[ i ].hReceiveEvent = hReceiveEvent; |
| lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId(); |
| |
| DPLAYX_ReleaseSemaphore(); |
| return TRUE; |
| } |
| } |
| |
| 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 ) |
| { |
| /* Mark this entry unused */ |
| DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] ); |
| |
| DPLAYX_ReleaseSemaphore(); |
| return TRUE; |
| } |
| } |
| |
| DPLAYX_ReleaseSemaphore(); |
| ERR( "Unable to find global entry for application\n" ); |
| return FALSE; |
| } |
| |
| HRESULT DPLAYX_GetConnectionSettingsA |
| ( DWORD dwAppID, |
| LPVOID lpData, |
| LPDWORD lpdwDataSize ) |
| { |
| lpDirectPlayLobbyData lpDplData; |
| LPDPLCONNECTION lpDplConnection; |
| |
| /* Verify buffer size */ |
| if ( ( lpData == NULL ) || |
| ( *lpdwDataSize < sizeof( DPLCONNECTION ) ) |
| ) |
| { |
| *lpdwDataSize = sizeof( DPLCONNECTION ); |
| |
| return DPERR_BUFFERTOOSMALL; |
| } |
| |
| DPLAYX_AquireSemaphore(); |
| |
| if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) ) |
| { |
| DPLAYX_ReleaseSemaphore(); |
| |
| TRACE( "Application 0x%08lx is not lobbied\n", dwAppID ); |
| return DPERR_NOTLOBBIED; |
| } |
| |
| /* 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; |
| |
| /* FIXME: 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; |
| |
| /* Verify buffer size */ |
| if ( ( lpData == NULL ) || |
| ( *lpdwDataSize < sizeof( DPLCONNECTION ) ) |
| ) |
| { |
| *lpdwDataSize = sizeof( DPLCONNECTION ); |
| |
| return DPERR_BUFFERTOOSMALL; |
| } |
| |
| DPLAYX_AquireSemaphore(); |
| |
| if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) ) |
| { |
| DPLAYX_ReleaseSemaphore(); |
| return DPERR_NOTLOBBIED; |
| } |
| |
| /* 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; |
| |
| /* FIXME: Send a message - or only the first time? */ |
| |
| DPLAYX_ReleaseSemaphore(); |
| |
| return DP_OK; |
| } |
| |
| |
| HRESULT DPLAYX_SetConnectionSettingsA |
| ( DWORD dwFlags, |
| DWORD dwAppID, |
| LPDPLCONNECTION lpConn ) |
| { |
| lpDirectPlayLobbyData lpDplData; |
| |
| /* Paramater 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; |
| } |
| |
| if( dwAppID == 0 ) |
| { |
| dwAppID = GetCurrentProcessId(); |
| } |
| |
| DPLAYX_AquireSemaphore(); |
| |
| if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) ) |
| { |
| /* FIXME: Create a new entry for this dwAppID? */ |
| DPLAYX_ReleaseSemaphore(); |
| |
| return DPERR_GENERIC; |
| } |
| |
| /* Store information */ |
| if( lpConn->dwSize != sizeof(DPLCONNECTION) ) |
| { |
| DPLAYX_ReleaseSemaphore(); |
| |
| ERR(": old/new DPLCONNECTION type? Size=%lu vs. expected=%u 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=%lu vs. expected=%u 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; |
| |
| /* FIXME: Send a message - I think */ |
| |
| DPLAYX_ReleaseSemaphore(); |
| |
| return DP_OK; |
| } |
| |
| HRESULT DPLAYX_SetConnectionSettingsW |
| ( DWORD dwFlags, |
| DWORD dwAppID, |
| LPDPLCONNECTION lpConn ) |
| { |
| lpDirectPlayLobbyData lpDplData; |
| |
| /* Paramater check */ |
| if( dwFlags || !lpConn ) |
| { |
| ERR("invalid parameters.\n"); |
| return DPERR_INVALIDPARAMS; |
| } |
| |
| /* Store information */ |
| if( lpConn->dwSize != sizeof(DPLCONNECTION) ) |
| { |
| ERR(": old/new DPLCONNECTION type? Size=%lu vs. expected=%u bytes\n", |
| lpConn->dwSize, sizeof( DPLCONNECTION ) ); |
| |
| return DPERR_INVALIDPARAMS; |
| } |
| |
| if( dwAppID == 0 ) |
| { |
| dwAppID = GetCurrentProcessId(); |
| } |
| |
| DPLAYX_AquireSemaphore(); |
| |
| if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) ) |
| { |
| DPLAYX_ReleaseSemaphore(); |
| return DPERR_NOTLOBBIED; |
| } |
| |
| /* 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=%lu vs. expected=%u 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; |
| |
| /* FIXME: Send a message - I think */ |
| |
| DPLAYX_ReleaseSemaphore(); |
| |
| return DP_OK; |
| } |
| |
| LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateSessionDesc2A( LPCDPSESSIONDESC2 lpSessionSrc ) |
| { |
| LPDPSESSIONDESC2 lpSessionDest = (LPDPSESSIONDESC2) HeapAlloc( GetProcessHeap(), |
| HEAP_ZERO_MEMORY, |
| sizeof( *lpSessionSrc ) ); |
| DPLAYX_CopyIntoSessionDesc2A( lpSessionDest, lpSessionSrc ); |
| |
| return lpSessionDest; |
| } |
| |
| /* Copy an ANSI session desc structure to the given buffer */ |
| BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest, |
| LPCDPSESSIONDESC2 lpSessionSrc ) |
| { |
| memcpy( lpSessionDest, lpSessionSrc, sizeof( *lpSessionSrc ) ); |
| |
| if( lpSessionSrc->sess.lpszSessionNameA ) |
| { |
| lpSessionDest->sess.lpszSessionNameA = |
| HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpSessionSrc->sess.lpszSessionNameA ); |
| } |
| if( lpSessionSrc->pass.lpszPasswordA ) |
| { |
| lpSessionDest->pass.lpszPasswordA = |
| HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpSessionSrc->pass.lpszPasswordA ); |
| } |
| |
| return TRUE; |
| } |
| |
| /* Start the index at 0. index will be updated to equal that which should |
| be passed back into this function for the next element */ |
| LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateLocalSession( UINT* index ) |
| { |
| for( ; (*index) < numSupportedSessions; (*index)++ ) |
| { |
| if( sessionData[(*index)].dwSize != 0 ) |
| { |
| return DPLAYX_CopyAndAllocateSessionDesc2A( &sessionData[(*index)++] ); |
| } |
| } |
| |
| /* No more sessions */ |
| return NULL; |
| } |
| |
| /* Start the index at 0. index will be updated to equal that which should |
| be passed back into this function for the next element */ |
| BOOL DPLAYX_CopyLocalSession( UINT* index, LPDPSESSIONDESC2 lpsd ) |
| { |
| for( ; (*index) < numSupportedSessions; (*index)++ ) |
| { |
| if( sessionData[(*index)].dwSize != 0 ) |
| { |
| return DPLAYX_CopyIntoSessionDesc2A( lpsd, &sessionData[(*index)++] ); |
| } |
| } |
| |
| /* No more sessions */ |
| return FALSE; |
| } |
| |
| void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd ) |
| { |
| UINT i; |
| |
| FIXME( ": stub\n" ); |
| |
| /* FIXME: Is this an error if it exists already? */ |
| |
| /* Crude/wrong implementation for now. Just always add to first empty spot */ |
| for( i=0; i < numSupportedSessions; i++ ) |
| { |
| /* Is this one empty? */ |
| if( sessionData[i].dwSize == 0 ) |
| { |
| DPLAYX_CopyIntoSessionDesc2A( &sessionData[i], lpsd ); |
| break; |
| } |
| } |
| |
| } |
| |
| /* 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'll just get the last hr passed in printed. This can change |
| over time if this method is used alot :) */ |
| 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"; |
| /* This one isn't defined yet in WINE sources. I don't know the value |
| 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%08lx\n", hr ); |
| sprintf( szTempStr, "0x%08lx", hr ); |
| return szTempStr; |
| } |
| } |
| |