mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 12:49:45 +00:00
- 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
This commit is contained in:
parent
6c8a67c3af
commit
88a2954a97
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,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,
|
||||
|
Loading…
Reference in New Issue
Block a user