Commit 88a2954a authored by Peter Hunnisett's avatar Peter Hunnisett Committed by Alexandre Julliard

- Added global data mutual exclusion

- Removed hack for creating processes suspended now that it's implemented - Fixed ordinal numbering and added spec stubs - Fixed EnumConnections callback to fill in all parameters with valid data - Made direct play allocation/deallocation follow the same pattern as direct play lobby
parent 6c8a67c3
......@@ -15,6 +15,12 @@
#include "debugtools.h"
#include "dpinit.h"
#include "dplayx_global.h"
/* FIXME: This stuff shouldn't really be here. It indicates a poor architectural coupling */
#include "dplobby.h"
extern HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
DEFAULT_DEBUG_CHANNEL(dplay)
......@@ -22,12 +28,71 @@ DEFAULT_DEBUG_CHANNEL(dplay)
/*****************************************************************************
* Predeclare the interface implementation structures
*/
typedef struct IDirectPlayImpl IDirectPlay2AImpl;
typedef struct IDirectPlayImpl IDirectPlay2Impl;
typedef struct IDirectPlayImpl IDirectPlay3AImpl;
typedef struct IDirectPlayImpl IDirectPlay3Impl;
typedef struct IDirectPlayImpl IDirectPlay4AImpl;
typedef struct IDirectPlayImpl IDirectPlay4Impl;
typedef struct IDirectPlay2Impl IDirectPlay2AImpl;
typedef struct IDirectPlay2Impl IDirectPlay2Impl;
typedef struct IDirectPlay3Impl IDirectPlay3AImpl;
typedef struct IDirectPlay3Impl IDirectPlay3Impl;
typedef struct IDirectPlay4Impl IDirectPlay4AImpl;
typedef struct IDirectPlay4Impl IDirectPlay4Impl;
/*****************************************************************************
* IDirectPlay implementation structure
*
* The philosophy behind this extra pointer derefernce is that I wanted to
* have the same structure for all types of objects without having to do
* alot of casting. I also only wanted to implement an interface in the
* object it was "released" with IUnknown interface being implemented in the 1 version.
* Of course, with these new interfaces comes the data required to keep the state required
* by these interfaces. So, basically, the pointers contain the data associated with
* a release. If you use the data associated with release 3 in a release 2 object, you'll
* get a run time trap, as that won't have any data.
*
*/
typedef struct tagDirectPlayIUnknownData
{
DWORD ref;
CRITICAL_SECTION DP_lock;
} DirectPlayIUnknownData;
/* Contains all dp1 and dp2 data members */
typedef struct tagDirectPlay2Data
{
BOOL dummy;
} DirectPlay2Data;
typedef struct tagDirectPlay3Data
{
BOOL connectionInitialized;
} DirectPlay3Data;
typedef struct tagDirectPlay4Data
{
BOOL dummy;
} DirectPlay4Data;
#define DP_IMPL_FIELDS \
DirectPlayIUnknownData* unk; \
DirectPlay2Data* dp2; \
DirectPlay3Data* dp3; \
DirectPlay4Data* dp4;
struct IDirectPlay2Impl
{
ICOM_VFIELD(IDirectPlay2);
DP_IMPL_FIELDS
};
struct IDirectPlay3Impl
{
ICOM_VFIELD(IDirectPlay3);
DP_IMPL_FIELDS
};
struct IDirectPlay4Impl
{
ICOM_VFIELD(IDirectPlay4);
DP_IMPL_FIELDS
};
/* Forward declarations of virtual tables */
static ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
......@@ -38,21 +103,107 @@ static ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
static ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
static ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
/*****************************************************************************
* IDirectPlay implementation structure
*/
struct IDirectPlayImpl
BOOL DP_CreateIUnknown( LPVOID lpDP )
{
/* IUnknown fields */
ICOM_VFIELD(IDirectPlay4);
DWORD ref;
CRITICAL_SECTION DP_lock;
/* IDirectPlay3Impl fields */
/* none so far */
/* IDirectPlay4Impl fields */
/* none so far */
};
ICOM_THIS(IDirectPlay2AImpl,lpDP);
This->unk = (DirectPlayIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->unk) ) );
if ( This->unk == NULL )
{
return FALSE;
}
InitializeCriticalSection( &This->unk->DP_lock );
IDirectPlay_AddRef( (LPDIRECTPLAY2A)lpDP );
return TRUE;
}
BOOL DP_DestroyIUnknown( LPVOID lpDP )
{
ICOM_THIS(IDirectPlay2AImpl,lpDP);
DeleteCriticalSection( &This->unk->DP_lock );
HeapFree( GetProcessHeap(), 0, This->unk );
return TRUE;
}
BOOL DP_CreateDirectPlay2( LPVOID lpDP )
{
ICOM_THIS(IDirectPlay2AImpl,lpDP);
This->dp2 = (DirectPlay2Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->dp2) ) );
if ( This->dp2 == NULL )
{
return FALSE;
}
return TRUE;
}
BOOL DP_DestroyDirectPlay2( LPVOID lpDP )
{
ICOM_THIS(IDirectPlay2AImpl,lpDP);
/* Delete the contents */
HeapFree( GetProcessHeap(), 0, This->dp2 );
return TRUE;
}
BOOL DP_CreateDirectPlay3( LPVOID lpDP )
{
ICOM_THIS(IDirectPlay3AImpl,lpDP);
This->dp3 = (DirectPlay3Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->dp3) ) );
if ( This->dp3 == NULL )
{
return FALSE;
}
This->dp3->connectionInitialized = FALSE;
return TRUE;
}
BOOL DP_DestroyDirectPlay3( LPVOID lpDP )
{
ICOM_THIS(IDirectPlay3AImpl,lpDP);
/* Delete the contents */
HeapFree( GetProcessHeap(), 0, This->dp3 );
return TRUE;
}
BOOL DP_CreateDirectPlay4( LPVOID lpDP )
{
ICOM_THIS(IDirectPlay4AImpl,lpDP);
This->dp4 = (DirectPlay4Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->dp4) ) );
if ( This->dp4 == NULL )
{
return FALSE;
}
return TRUE;
}
BOOL DP_DestroyDirectPlay4( LPVOID lpDP )
{
ICOM_THIS(IDirectPlay3AImpl,lpDP);
/* Delete the contents */
HeapFree( GetProcessHeap(), 0, This->dp4 );
return TRUE;
}
/* Get a new interface. To be used by QueryInterface. */
......@@ -63,134 +214,188 @@ HRESULT directPlay_QueryInterface
if( IsEqualGUID( &IID_IDirectPlay2, riid ) )
{
IDirectPlay2Impl* lpDP;
lpDP = (IDirectPlay2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDP ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlay2Impl ) );
if( !lpDP )
if( *ppvObj == NULL )
{
return DPERR_OUTOFMEMORY;
}
ICOM_VTBL(lpDP) = &directPlay2WVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
/* new scope for variable declaration */
{
ICOM_THIS(IDirectPlay2Impl,*ppvObj);
*ppvObj = lpDP;
ICOM_VTBL(This) = &directPlay2WVT;
if ( DP_CreateIUnknown( (LPVOID)This ) &&
DP_CreateDirectPlay2( (LPVOID)This )
)
{
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
{
IDirectPlay2AImpl* lpDP;
lpDP = (IDirectPlay2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDP ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlay2AImpl ) );
if( !lpDP )
if( *ppvObj == NULL )
{
return DPERR_OUTOFMEMORY;
}
ICOM_VTBL(lpDP) = &directPlay2AVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
/* new scope for variable declaration */
{
ICOM_THIS(IDirectPlay2AImpl,*ppvObj);
*ppvObj = lpDP;
ICOM_VTBL(This) = &directPlay2AVT;
if ( DP_CreateIUnknown( (LPVOID)This ) &&
DP_CreateDirectPlay2( (LPVOID)This )
)
{
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlay3, riid ) )
{
IDirectPlay3Impl* lpDP;
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlay3Impl ) );
lpDP = (IDirectPlay3Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDP ) );
if( !lpDP )
if( *ppvObj == NULL )
{
return DPERR_OUTOFMEMORY;
}
ICOM_VTBL(lpDP) = &directPlay3WVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
/* new scope for variable declaration */
{
ICOM_THIS(IDirectPlay3Impl,*ppvObj);
*ppvObj = lpDP;
ICOM_VTBL(This) = &directPlay3WVT;
if ( DP_CreateIUnknown( (LPVOID)This ) &&
DP_CreateDirectPlay2( (LPVOID)This ) &&
DP_CreateDirectPlay3( (LPVOID)This )
)
{
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
{
IDirectPlay3AImpl* lpDP;
lpDP = (IDirectPlay3AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDP ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlay3AImpl ) );
if( !lpDP )
if( *ppvObj == NULL )
{
return DPERR_OUTOFMEMORY;
}
ICOM_VTBL(lpDP) = &directPlay3AVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
/* new scope for variable declaration */
{
ICOM_THIS(IDirectPlay3AImpl,*ppvObj);
*ppvObj = lpDP;
ICOM_VTBL(This) = &directPlay3AVT;
if ( DP_CreateIUnknown( (LPVOID)This ) &&
DP_CreateDirectPlay2( (LPVOID)This ) &&
DP_CreateDirectPlay3( (LPVOID)This )
)
{
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlay4, riid ) )
{
IDirectPlay4Impl* lpDP;
lpDP = (IDirectPlay4Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDP ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlay4Impl ) );
if( !lpDP )
if( *ppvObj == NULL )
{
return DPERR_OUTOFMEMORY;
}
ICOM_VTBL(lpDP) = &directPlay4WVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
/* new scope for variable declaration */
{
ICOM_THIS(IDirectPlay4Impl,*ppvObj);
*ppvObj = lpDP;
ICOM_VTBL(This) = &directPlay4WVT;
if ( DP_CreateIUnknown( (LPVOID)This ) &&
DP_CreateDirectPlay2( (LPVOID)This ) &&
DP_CreateDirectPlay3( (LPVOID)This ) &&
DP_CreateDirectPlay4( (LPVOID)This )
)
{
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlay4A, riid ) )
{
IDirectPlay4AImpl* lpDP;
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlay4AImpl ) );
lpDP = (IDirectPlay4AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDP ) );
if( !lpDP )
if( *ppvObj == NULL )
{
return DPERR_OUTOFMEMORY;
}
ICOM_VTBL(lpDP) = &directPlay4AVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
/* new scope for variable declaration */
{
ICOM_THIS(IDirectPlay4AImpl,*ppvObj);
*ppvObj = lpDP;
ICOM_VTBL(This) = &directPlay4AVT;
if ( DP_CreateIUnknown( (LPVOID)This ) &&
DP_CreateDirectPlay2( (LPVOID)This ) &&
DP_CreateDirectPlay3( (LPVOID)This ) &&
DP_CreateDirectPlay4( (LPVOID)This )
)
{
return S_OK;
}
}
goto error;
}
/* Unsupported interface */
*ppvObj = NULL;
return E_NOINTERFACE;
error:
DP_DestroyDirectPlay4( *ppvObj );
DP_DestroyDirectPlay3( *ppvObj );
DP_DestroyDirectPlay2( *ppvObj );
DP_DestroyIUnknown( *ppvObj );
HeapFree( GetProcessHeap(), 0, *ppvObj );
*ppvObj = NULL;
return DPERR_NOMEMORY;
}
......@@ -311,15 +516,15 @@ static ULONG WINAPI DirectPlay2AImpl_AddRef
ULONG refCount;
ICOM_THIS(IDirectPlay3Impl,iface);
EnterCriticalSection( &This->DP_lock );
EnterCriticalSection( &This->unk->DP_lock );
{
refCount = ++(This->ref);
refCount = ++(This->unk->ref);
}
LeaveCriticalSection( &This->DP_lock );
LeaveCriticalSection( &This->unk->DP_lock );
TRACE("ref count incremented to %lu for %p\n", refCount, This );
return (This->ref);
return refCount;
}
static ULONG WINAPI DirectPlay2AImpl_Release
......@@ -329,20 +534,21 @@ static ULONG WINAPI DirectPlay2AImpl_Release
ICOM_THIS(IDirectPlay3Impl,iface);
EnterCriticalSection( &This->DP_lock );
EnterCriticalSection( &This->unk->DP_lock );
{
refCount = --(This->ref);
refCount = --(This->unk->ref);
}
LeaveCriticalSection( &This->DP_lock );
LeaveCriticalSection( &This->unk->DP_lock );
TRACE("ref count decremeneted to %lu for %p\n", refCount, This );
/* Deallocate if this is the last reference to the object */
if( refCount == 0 )
{
FIXME("memory leak\n" );
/* Implement memory deallocation */
DP_DestroyDirectPlay4( This );
DP_DestroyDirectPlay3( This );
DP_DestroyDirectPlay2( This );
DP_DestroyIUnknown( This );
HeapFree( GetProcessHeap(), 0, This );
}
......@@ -924,6 +1130,11 @@ static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
char returnBuffer[51];
LPWSTR lpWGUIDString;
DPNAME dpName;
HRESULT hr;
DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
LPVOID lpAddressBuffer = NULL;
DWORD dwAddressBufferSize = 0;
TRACE(" this time through: %s\n", subKeyName );
......@@ -949,16 +1160,46 @@ static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
HeapFree( GetProcessHeap(), 0, lpWGUIDString );
/* FIXME: Have I got a memory leak on the serviceProviderGUID? */
/* Fill in the DPNAME struct for the service provider */
dpName.dwSize = sizeof( dpName );
dpName.dwFlags = 0;
dpName.psn.lpszShortNameA = subKeyName; /* FIXME: Is this right? */
dpName.pln.lpszLongNameA = subKeyName; /* FIXME: Is this right? */
dpName.psn.lpszShortNameA = subKeyName;
dpName.pln.lpszLongNameA = NULL;
/* Create the compound address for the service provider.
NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
nast stuff. This may be why the native dll just gets around this little bit by
allocating an 80 byte buffer which isn't even a filled with a valid compound
address. Oh well. Creating a proper compound address is the way to go anyways
despite this method taking slightly more heap space and realtime :) */
dpCompoundAddress.guidDataType = DPAID_ServiceProvider;
dpCompoundAddress.dwDataSize = sizeof( GUID );
dpCompoundAddress.lpData = &serviceProviderGUID;
if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
&dwAddressBufferSize, TRUE ) ) != DPERR_BUFFERTOOSMALL )
{
ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
return hr;
}
/* Now allocate the buffer */
lpAddressBuffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAddressBufferSize );
if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, lpAddressBuffer,
&dwAddressBufferSize, TRUE ) ) != DP_OK )
{
ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
return hr;
}
/* The enumeration will return FALSE if we are not to continue */
if( !lpEnumCallback( &serviceProviderGUID, NULL,0, &dpName, 0, lpContext ) )
if( !lpEnumCallback( &serviceProviderGUID, lpAddressBuffer, dwAddressBufferSize,
&dpName, DPCONNECTION_DIRECTPLAY, lpContext ) )
{
WARN("lpEnumCallback returning FALSE\n" );
break;
return DP_OK;
}
}
}
......@@ -1015,7 +1256,13 @@ static HRESULT WINAPI DirectPlay3WImpl_GetGroupConnectionSettings
static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
( LPDIRECTPLAY3A iface, LPVOID lpConnection, DWORD dwFlags )
{
HMODULE hServiceProvider;
typedef DWORD (WINAPI *SP_SPInit)(LPVOID lpCompoundAddress, ...); /* FIXME: How many arguments? */
SP_SPInit SPInit;
DWORD dwReturnValue = 0;
ICOM_THIS(IDirectPlay3Impl,iface);
FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
if( dwFlags != 0 )
......@@ -1023,6 +1270,42 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
return DPERR_INVALIDFLAGS;
}
if( This->dp3->connectionInitialized == TRUE )
{
return DPERR_ALREADYINITIALIZED;
}
/* Parse lpConnection as a compound address for the service provider */
/* Take service provider GUID and find the path to it */
/* FIXME: Hard coded to only load the tcp/ip service provider for now... */
hServiceProvider = LoadLibraryA( "dpwsockx.dll" );
if( hServiceProvider == 0 )
{
ERR( "Unable to load service provider\n" );
return DPERR_UNAVAILABLE;
}
/* Initialize the service provider by calling SPInit */
SPInit = (SP_SPInit)GetProcAddress( hServiceProvider, "SPInit" );
if( SPInit == NULL )
{
ERR( "Service provider doesn't provide SPInit interface?\n" );
}
#if 0
/* NOTE: This will crash until I know what parameters/interface this has */
/* FIXME: Take a guess that we just pass the compound address to the SP */
/* Hmmm...how to say which parameters need to be gotten from the SP. They must
come from the compound address, but how do we communicate what's required? */
dwReturnValue = (*SPInit)( lpConnection );
#endif
/* This interface is now initialized */
This->dp3->connectionInitialized = TRUE;
return DP_OK;
}
......
......@@ -20,16 +20,18 @@
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 */
/* FIXME: Need to allocate a giant static area */
/* Static data for all processes */
static LPSTR lpszDplayxSemaName = "DPLAYX_SM";
static LPSTR lpszDplayxSemaName = "WINE_DPLAYX_SM";
static HANDLE hDplayxSema;
#define DPLAYX_AquireSemaphore() 0L /* WaitForSingleObject( hDplayxSema, INFINITE? ) */
#define DPLAYX_ReleaseSemaphore() 0L /* ReleaseSemaphore( 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 */
......@@ -44,12 +46,15 @@ typedef struct tagDirectPlayLobbyData
DWORD dwAddressSize;
DWORD dwAppID;
HANDLE hReceiveEvent;
DWORD dwAppLaunchedFromID;
} DirectPlayLobbyData, *lpDirectPlayLobbyData;
static DirectPlayLobbyData lobbyData[ numSupportedLobbies ];
/* Function prototypes */
BOOL DPLAYX_AppIdLobbied( DWORD dwAppId, lpDirectPlayLobbyData* dplData );
BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, lpDirectPlayLobbyData* dplData );
void DPLAYX_InitializeLobbyDataEntry( lpDirectPlayLobbyData lpData );
......@@ -64,8 +69,10 @@ void DPLAYX_ConstructData(void)
TRACE( "DPLAYX dll loaded - construct called\n" );
/* FIXME: This needs to be allocated shared */
hDplayxSema = CreateSemaphoreA( NULL, 0, 1, lpszDplayxSemaName );
/* 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 )
{
......@@ -76,7 +83,7 @@ void DPLAYX_ConstructData(void)
/* Set all lobbies to be "empty" */
for( i=0; i < numSupportedLobbies; i++ )
{
lobbyData[ i ].dwAppID = 0;
DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
}
}
......@@ -87,21 +94,35 @@ void DPLAYX_ConstructData(void)
***************************************************************************/
void DPLAYX_DestructData(void)
{
/* Hmmm...what to call to delete the semaphore? Auto delete? */
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
* TRUE/FALSE with a pointer to it's data returned. Pointer data is
* is only valid if TRUE is returned.
*/
BOOL DPLAYX_AppIdLobbied( DWORD dwAppID, lpDirectPlayLobbyData* lplpDplData )
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++ )
......@@ -117,40 +138,52 @@ BOOL DPLAYX_AppIdLobbied( DWORD dwAppID, lpDirectPlayLobbyData* lplpDplData )
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 )
/* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
{
return DPLAYX_AquireSemaphore();
}
UINT i;
DWORD DPLAYX_ReleaseSemaphoreHack( void )
{
return DPLAYX_ReleaseSemaphore();
}
/* 0 is the marker for unused application data slots */
if( dwAppID == 0 )
{
return FALSE;
}
#endif
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;
}
/* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
/* I'm not sure when I'm going to need this, but here it is */
BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID )
{
INT i;
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 == 0 )
if( lobbyData[ i ].dwAppID == dwAppID )
{
/* This process is now lobbied */
lobbyData[ i ].dwAppID = dwAppID;
lobbyData[ i ].hReceiveEvent = hReceiveEvent;
/* Mark this entry unused */
DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
DPLAYX_ReleaseSemaphore();
return TRUE;
......@@ -158,6 +191,7 @@ BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
}
DPLAYX_ReleaseSemaphore();
ERR( "Unable to find global entry for application\n" );
return FALSE;
}
......@@ -169,26 +203,24 @@ HRESULT DPLAYX_GetConnectionSettingsA
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;
}
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
/* Copy the information */
lpDplConnection = (LPDPLCONNECTION)lpData;
......@@ -239,7 +271,7 @@ HRESULT DPLAYX_GetConnectionSettingsA
lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
/* Send a message - or only the first time? */
/* FIXME: Send a message - or only the first time? */
DPLAYX_ReleaseSemaphore();
......@@ -254,26 +286,24 @@ HRESULT DPLAYX_GetConnectionSettingsW
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;
}
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
/* Copy the information */
lpDplConnection = (LPDPLCONNECTION)lpData;
......@@ -324,7 +354,7 @@ HRESULT DPLAYX_GetConnectionSettingsW
lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
/* Send a message - or only the first time? */
/* FIXME: Send a message - or only the first time? */
DPLAYX_ReleaseSemaphore();
......@@ -339,23 +369,35 @@ HRESULT DPLAYX_SetConnectionSettingsA
{
lpDirectPlayLobbyData lpDplData;
DPLAYX_AquireSemaphore();
/* Paramater check */
if( dwFlags || !lpConn )
{
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
}
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
/* Store information */
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
/* FIXME: Create a new entry for this dwAppID? */
DPLAYX_ReleaseSemaphore();
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_GENERIC;
return DPERR_INVALIDPARAMS;
}
/* Paramater check */
if( dwFlags || !lpConn )
if( dwAppID == 0 )
{
dwAppID = GetCurrentProcessId();
}
DPLAYX_AquireSemaphore();
if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
{
/* FIXME: Create a new entry for this dwAppID? */
DPLAYX_ReleaseSemaphore();
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
return DPERR_GENERIC;
}
/* Store information */
......@@ -363,7 +405,7 @@ HRESULT DPLAYX_SetConnectionSettingsA
{
DPLAYX_ReleaseSemaphore();
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
ERR(": old/new DPLCONNECTION type? Size=%lu vs. expected=%u bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
......@@ -378,7 +420,7 @@ HRESULT DPLAYX_SetConnectionSettingsA
{
DPLAYX_ReleaseSemaphore();
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
ERR("DPSESSIONDESC passed in? Size=%lu vs. expected=%u bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
......@@ -426,7 +468,7 @@ HRESULT DPLAYX_SetConnectionSettingsA
lpDplData->dwAddressSize = lpConn->dwAddressSize;
/* Send a message - I think */
/* FIXME: Send a message - I think */
DPLAYX_ReleaseSemaphore();
......@@ -440,18 +482,9 @@ HRESULT DPLAYX_SetConnectionSettingsW
{
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;
}
......@@ -459,14 +492,25 @@ HRESULT DPLAYX_SetConnectionSettingsW
/* Store information */
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
DPLAYX_ReleaseSemaphore();
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
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.
*/
......@@ -476,7 +520,7 @@ HRESULT DPLAYX_SetConnectionSettingsW
{
DPLAYX_ReleaseSemaphore();
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
ERR("DPSESSIONDESC passed in? Size=%lu vs. expected=%u bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
......@@ -524,9 +568,161 @@ HRESULT DPLAYX_SetConnectionSettingsW
lpDplData->dwAddressSize = lpConn->dwAddressSize;
/* Send a message - I think */
/* FIXME: Send a message - I think */
DPLAYX_ReleaseSemaphore();
return DP_OK;
}
/* 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;
}
}
......@@ -14,14 +14,9 @@ HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags, DWORD dwAppID, LPDPLCONNE
HRESULT DPLAYX_SetConnectionSettingsW ( DWORD dwFlags, DWORD dwAppID, LPDPLCONNECTION lpConn );
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent );
BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID );
/* This is a hack to ensure synchronization during application spawn */
#if !defined( WORKING_PROCESS_SUSPEND )
DWORD DPLAYX_AquireSemaphoreHack( void );
DWORD DPLAYX_ReleaseSemaphoreHack( void );
#endif
/* Convert a DP or DPL HRESULT code into a string for human consumption */
LPCSTR DPLAYX_HresultToString( HRESULT hr );
#endif /* __WINE_DPLAYX_GLOBAL */
......@@ -20,13 +20,15 @@
DEFAULT_DEBUG_CHANNEL(dplay)
/* FIXME: All the data structures are presently not needed except for unk */
/* FIXME: Move lock from unk to dpl */
/* Forward declarations for this module helper methods */
static HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
HRESULT DPL_CreateAddress( REFGUID guidSP, REFGUID guidDataType, LPCVOID lpData, DWORD dwDataSize,
LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
static HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, LPCVOID lpAddress,
DWORD dwAddressSize, LPVOID lpContext );
......@@ -76,7 +78,8 @@ typedef struct tagDirectPlayLobby3Data
BOOL dummy;
} DirectPlayLobby3Data;
#define LOBBY_IMPL_FIELDS DirectPlayLobbyIUnknownData* unk; \
#define DPL_IMPL_FIELDS \
DirectPlayLobbyIUnknownData* unk; \
DirectPlayLobbyData* dpl; \
DirectPlayLobby2Data* dpl2; \
DirectPlayLobby3Data* dpl3;
......@@ -84,19 +87,19 @@ typedef struct tagDirectPlayLobby3Data
struct IDirectPlayLobbyImpl
{
ICOM_VFIELD(IDirectPlayLobby);
LOBBY_IMPL_FIELDS
DPL_IMPL_FIELDS
};
struct IDirectPlayLobby2Impl
{
ICOM_VFIELD(IDirectPlayLobby2);
LOBBY_IMPL_FIELDS
DPL_IMPL_FIELDS
};
struct IDirectPlayLobby3Impl
{
ICOM_VFIELD(IDirectPlayLobby3);
LOBBY_IMPL_FIELDS
DPL_IMPL_FIELDS
};
......@@ -146,16 +149,16 @@ BOOL DPL_CreateIUnknown( LPVOID lpDPL )
This->unk = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->unk) ) );
if ( This->unk != NULL )
if ( This->unk == NULL )
{
return FALSE;
}
InitializeCriticalSection( &This->unk->DPL_lock );
IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBYA)lpDPL );
return TRUE;
}
return FALSE;
}
BOOL DPL_DestroyIUnknown( LPVOID lpDPL )
......@@ -710,27 +713,8 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
const DWORD dwNumAddElements = 2; /* Service Provide & address data type */
DPCOMPOUNDADDRESSELEMENT addressElements[ dwNumAddElements ];
TRACE( "(%p)->(%p,%p,%p,0x%08lx,%p,%p)\n", This, guidSP, guidDataType, lpData,
dwDataSize, lpAddress, lpdwAddressSize );
addressElements[ 0 ].guidDataType = DPAID_ServiceProvider;
addressElements[ 0 ].dwDataSize = sizeof( GUID );
addressElements[ 0 ].lpData = (LPVOID)guidSP;
addressElements[ 1 ].guidDataType = *guidDataType;
addressElements[ 1 ].dwDataSize = dwDataSize;
addressElements[ 1 ].lpData = (LPVOID)lpData;
/* Call CreateCompoundAddress to cut down on code.
NOTE: We can do this because we don't support DPL 1 interfaces! */
return IDirectPlayLobby_CreateCompoundAddress( (LPDIRECTPLAYLOBBY2A)iface,
addressElements, dwNumAddElements,
lpAddress, lpdwAddressSize );
return DPL_CreateAddress( guidSP, guidDataType, lpData, dwDataSize,
lpAddress, lpdwAddressSize, TRUE );
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
......@@ -742,12 +726,24 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
return DPL_CreateAddress( guidSP, guidDataType, lpData, dwDataSize,
lpAddress, lpdwAddressSize, FALSE );
}
HRESULT DPL_CreateAddress(
REFGUID guidSP,
REFGUID guidDataType,
LPCVOID lpData,
DWORD dwDataSize,
LPVOID lpAddress,
LPDWORD lpdwAddressSize,
BOOL bAnsiInterface )
{
const DWORD dwNumAddElements = 2; /* Service Provide & address data type */
DPCOMPOUNDADDRESSELEMENT addressElements[ dwNumAddElements ];
TRACE( "(%p)->(%p,%p,%p,0x%08lx,%p,%p)\n", This, guidSP, guidDataType, lpData,
dwDataSize, lpAddress, lpdwAddressSize );
TRACE( "(%p)->(%p,%p,0x%08lx,%p,%p,%d)\n", guidSP, guidDataType, lpData, dwDataSize,
lpAddress, lpdwAddressSize, bAnsiInterface );
addressElements[ 0 ].guidDataType = DPAID_ServiceProvider;
addressElements[ 0 ].dwDataSize = sizeof( GUID );
......@@ -759,12 +755,12 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
/* Call CreateCompoundAddress to cut down on code.
NOTE: We can do this because we don't support DPL 1 interfaces! */
return IDirectPlayLobby_CreateCompoundAddress( (LPDIRECTPLAYLOBBY2)iface,
addressElements, dwNumAddElements,
lpAddress, lpdwAddressSize );
return DPL_CreateCompoundAddress( addressElements, dwNumAddElements,
lpAddress, lpdwAddressSize, bAnsiInterface );
}
/********************************************************************
*
* Parses out chunks from the DirectPlay Address buffer by calling the
......@@ -1274,7 +1270,7 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
PROCESS_INFORMATION newProcessInfo;
LPSTR appName;
FIXME( "(%p)->(0x%08lx,%p,%p,%p):semi stub\n", This, dwFlags, lpdwAppID, lpConn, hReceiveEvent );
TRACE( "(%p)->(0x%08lx,%p,%p,%p)\n", This, dwFlags, lpdwAppID, lpConn, hReceiveEvent );
if( dwFlags != 0 )
{
......@@ -1312,10 +1308,6 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
ZeroMemory( &newProcessInfo, sizeof( newProcessInfo ) );
#if !defined( WORKING_PROCESS_SUSPEND )
DPLAYX_AquireSemaphoreHack();
#endif
if( !CreateProcessA( appName,
enumData.lpszCommandLine,
NULL,
......@@ -1330,6 +1322,12 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
)
{
FIXME( "Failed to create process for app %s\n", appName );
HeapFree( GetProcessHeap(), 0, appName );
HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine );
HeapFree( GetProcessHeap(), 0, enumData.lpszCurrentDirectory );
return DPERR_CANTCREATEPROCESS;
}
HeapFree( GetProcessHeap(), 0, appName );
......@@ -1346,19 +1344,15 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
if( hr != DP_OK )
{
FIXME( "SetConnectionSettings failure 0x%08lx\n", hr );
FIXME( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr ) );
return hr;
}
/* Everything seems to have been set correctly, update the dwAppID */
*lpdwAppID = newProcessInfo.dwProcessId;
#if !defined( WORKING_PROCESS_SUSPEND )
FIXME( ": It would be at this point that we would allow the process to resume\n" );
DPLAYX_ReleaseSemaphoreHack();
#else
/* Unsuspend the process */
ResumeThread( newProcessInfo.dwThreadId );
#endif
LeaveCriticalSection( &This->unk->DPL_lock );
......@@ -1504,7 +1498,7 @@ static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
return DPL_CreateCompoundAddress( lpElements, dwElementCount, lpAddress, lpdwAddressSize, TRUE );
}
static HRESULT DPL_CreateCompoundAddress
HRESULT DPL_CreateCompoundAddress
( LPCDPCOMPOUNDADDRESSELEMENT lpElements,
DWORD dwElementCount,
LPVOID lpAddress,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment