diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index 8a81edc440c..543a073d8a8 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -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; + *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof( IDirectPlay2Impl ) ); - lpDP = (IDirectPlay2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof( *lpDP ) ); - - if( !lpDP ) + if( *ppvObj == NULL ) { return DPERR_OUTOFMEMORY; } - ICOM_VTBL(lpDP) = &directPlay2WVT; + /* new scope for variable declaration */ + { + ICOM_THIS(IDirectPlay2Impl,*ppvObj); - InitializeCriticalSection( &lpDP->DP_lock ); - IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP ); + ICOM_VTBL(This) = &directPlay2WVT; - *ppvObj = lpDP; + if ( DP_CreateIUnknown( (LPVOID)This ) && + DP_CreateDirectPlay2( (LPVOID)This ) + ) + { + return S_OK; + } - return S_OK; + } + + goto error; } else if( IsEqualGUID( &IID_IDirectPlay2A, riid ) ) { - IDirectPlay2AImpl* lpDP; + *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof( IDirectPlay2AImpl ) ); - lpDP = (IDirectPlay2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof( *lpDP ) ); - - if( !lpDP ) + if( *ppvObj == NULL ) { return DPERR_OUTOFMEMORY; } - ICOM_VTBL(lpDP) = &directPlay2AVT; + /* new scope for variable declaration */ + { + ICOM_THIS(IDirectPlay2AImpl,*ppvObj); - InitializeCriticalSection( &lpDP->DP_lock ); - IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP ); + ICOM_VTBL(This) = &directPlay2AVT; - *ppvObj = lpDP; + if ( DP_CreateIUnknown( (LPVOID)This ) && + DP_CreateDirectPlay2( (LPVOID)This ) + ) + { + return S_OK; + } - 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; + /* new scope for variable declaration */ + { + ICOM_THIS(IDirectPlay3Impl,*ppvObj); - InitializeCriticalSection( &lpDP->DP_lock ); - IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP ); + ICOM_VTBL(This) = &directPlay3WVT; - *ppvObj = lpDP; + if ( DP_CreateIUnknown( (LPVOID)This ) && + DP_CreateDirectPlay2( (LPVOID)This ) && + DP_CreateDirectPlay3( (LPVOID)This ) + ) + { + return S_OK; + } - return S_OK; + } + + goto error; } else if( IsEqualGUID( &IID_IDirectPlay3A, riid ) ) { - IDirectPlay3AImpl* lpDP; + *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof( IDirectPlay3AImpl ) ); - lpDP = (IDirectPlay3AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof( *lpDP ) ); - - if( !lpDP ) + if( *ppvObj == NULL ) { return DPERR_OUTOFMEMORY; } - ICOM_VTBL(lpDP) = &directPlay3AVT; + /* new scope for variable declaration */ + { + ICOM_THIS(IDirectPlay3AImpl,*ppvObj); - InitializeCriticalSection( &lpDP->DP_lock ); - IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP ); + ICOM_VTBL(This) = &directPlay3AVT; - *ppvObj = lpDP; + if ( DP_CreateIUnknown( (LPVOID)This ) && + DP_CreateDirectPlay2( (LPVOID)This ) && + DP_CreateDirectPlay3( (LPVOID)This ) + ) + { + return S_OK; + } - return S_OK; + } + + goto error; } else if( IsEqualGUID( &IID_IDirectPlay4, riid ) ) { - IDirectPlay4Impl* lpDP; + *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof( IDirectPlay4Impl ) ); - lpDP = (IDirectPlay4Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof( *lpDP ) ); - - if( !lpDP ) + if( *ppvObj == NULL ) { return DPERR_OUTOFMEMORY; } - ICOM_VTBL(lpDP) = &directPlay4WVT; + /* new scope for variable declaration */ + { + ICOM_THIS(IDirectPlay4Impl,*ppvObj); - InitializeCriticalSection( &lpDP->DP_lock ); - IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP ); + ICOM_VTBL(This) = &directPlay4WVT; - *ppvObj = lpDP; + if ( DP_CreateIUnknown( (LPVOID)This ) && + DP_CreateDirectPlay2( (LPVOID)This ) && + DP_CreateDirectPlay3( (LPVOID)This ) && + DP_CreateDirectPlay4( (LPVOID)This ) + ) + { + return S_OK; + } - 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; + /* new scope for variable declaration */ + { + ICOM_THIS(IDirectPlay4AImpl,*ppvObj); - InitializeCriticalSection( &lpDP->DP_lock ); - IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP ); + ICOM_VTBL(This) = &directPlay4AVT; - *ppvObj = lpDP; + if ( DP_CreateIUnknown( (LPVOID)This ) && + DP_CreateDirectPlay2( (LPVOID)This ) && + DP_CreateDirectPlay3( (LPVOID)This ) && + DP_CreateDirectPlay4( (LPVOID)This ) + ) + { + return S_OK; + } - 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,21 +534,22 @@ 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 */ - - HeapFree( GetProcessHeap(), 0, This ); + DP_DestroyDirectPlay4( This ); + DP_DestroyDirectPlay3( This ); + DP_DestroyDirectPlay2( This ); + DP_DestroyIUnknown( This ); + HeapFree( GetProcessHeap(), 0, This ); } return refCount; @@ -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; } diff --git a/dlls/dplayx/dplayx_global.c b/dlls/dplayx/dplayx_global.c index 92706dddbff..accdee0ef50 100644 --- a/dlls/dplayx/dplayx_global.c +++ b/dlls/dplayx/dplayx_global.c @@ -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,28 @@ 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 ) -{ - 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; + 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 ].dwAppID = dwAppID; + lobbyData[ i ].hReceiveEvent = hReceiveEvent; + lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId(); DPLAYX_ReleaseSemaphore(); return TRUE; @@ -161,6 +170,31 @@ BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent ) 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, @@ -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,21 +369,9 @@ HRESULT DPLAYX_SetConnectionSettingsA { 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; } @@ -361,9 +379,33 @@ HRESULT DPLAYX_SetConnectionSettingsA /* 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(); - ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n", + 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; @@ -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; + } +} + diff --git a/dlls/dplayx/dplayx_global.h b/dlls/dplayx/dplayx_global.h index 268f5790482..6f49e42002e 100644 --- a/dlls/dplayx/dplayx_global.h +++ b/dlls/dplayx/dplayx_global.h @@ -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 */ diff --git a/dlls/dplayx/dplobby.c b/dlls/dplayx/dplobby.c index 7d6a4bc5f9e..862074a6cd9 100644 --- a/dlls/dplayx/dplobby.c +++ b/dlls/dplayx/dplobby.c @@ -20,12 +20,14 @@ 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, - LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface ); +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,27 +78,28 @@ typedef struct tagDirectPlayLobby3Data BOOL dummy; } DirectPlayLobby3Data; -#define LOBBY_IMPL_FIELDS DirectPlayLobbyIUnknownData* unk; \ - DirectPlayLobbyData* dpl; \ - DirectPlayLobby2Data* dpl2; \ - DirectPlayLobby3Data* dpl3; +#define DPL_IMPL_FIELDS \ + DirectPlayLobbyIUnknownData* unk; \ + DirectPlayLobbyData* dpl; \ + DirectPlayLobby2Data* dpl2; \ + DirectPlayLobby3Data* dpl3; 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 ) { - InitializeCriticalSection( &This->unk->DPL_lock ); - - IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBYA)lpDPL ); - - return TRUE; + return FALSE; } - return FALSE; + InitializeCriticalSection( &This->unk->DPL_lock ); + + IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBYA)lpDPL ); + + return TRUE; } 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,