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

- Added dplayx LibMain for initialization of all dplayx 'global' data

- Added start for global data manipulation - TODO list updated - Added some missing header file definitions - Added the ansi versions of dplay and dplobby - Fixed invalid macro for IDirectPlay4 - Cleaned up compiler warnings - More implementation, bug fixes and critical region protection
parent a69bc029
......@@ -9,7 +9,9 @@ SPEC_SRCS = dplay.spec dplayx.spec
C_SRCS = dplay.c \
dplobby.c \
dpclassfactory.c
dpclassfactory.c \
dplayx_main.c \
dplayx_global.c
all: $(MODULE).o
......
......@@ -6,6 +6,7 @@
*
*/
#include <string.h>
#include "winerror.h"
#include "winnt.h"
#include "winreg.h"
......@@ -13,6 +14,8 @@
#include "heap.h"
#include "debugtools.h"
#include "dpinit.h"
DEFAULT_DEBUG_CHANNEL(dplay)
......@@ -27,13 +30,14 @@ typedef struct IDirectPlayImpl IDirectPlay4AImpl;
typedef struct IDirectPlayImpl IDirectPlay4Impl;
/* Forward declarations of virtual tables */
static ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
static ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
static ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
static ICOM_VTABLE(IDirectPlay3) directPlay3AVT;
static ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
static ICOM_VTABLE(IDirectPlay4) directPlay4AVT;
static ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
static ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
static ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
/*****************************************************************************
* IDirectPlay implementation structure
*/
......@@ -50,6 +54,7 @@ struct IDirectPlayImpl
};
/* Get a new interface. To be used by QueryInterface. */
extern
HRESULT directPlay_QueryInterface
......@@ -71,7 +76,7 @@ HRESULT directPlay_QueryInterface
ICOM_VTBL(lpDP) = &directPlay2WVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( lpDP );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
*ppvObj = lpDP;
......@@ -90,8 +95,9 @@ HRESULT directPlay_QueryInterface
}
ICOM_VTBL(lpDP) = &directPlay2AVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( lpDP );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
*ppvObj = lpDP;
......@@ -110,8 +116,9 @@ HRESULT directPlay_QueryInterface
}
ICOM_VTBL(lpDP) = &directPlay3WVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( lpDP );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
*ppvObj = lpDP;
......@@ -130,8 +137,9 @@ HRESULT directPlay_QueryInterface
}
ICOM_VTBL(lpDP) = &directPlay3AVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( lpDP );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
*ppvObj = lpDP;
......@@ -150,8 +158,9 @@ HRESULT directPlay_QueryInterface
}
ICOM_VTBL(lpDP) = &directPlay4WVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( lpDP );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
*ppvObj = lpDP;
......@@ -170,8 +179,9 @@ HRESULT directPlay_QueryInterface
}
ICOM_VTBL(lpDP) = &directPlay4AVT;
InitializeCriticalSection( &lpDP->DP_lock );
IDirectPlayX_AddRef( lpDP );
IDirectPlayX_AddRef( (LPDIRECTPLAY2A)lpDP );
*ppvObj = lpDP;
......@@ -859,29 +869,11 @@ static HRESULT WINAPI DirectPlay3WImpl_DeleteGroupFromGroup
return DP_OK;
}
#if 0
typedef BOOL (CALLBACK* LPDPENUMDPCALLBACKA)(
LPGUID lpguidSP,
LPSTR lpSPName, /* ptr to str w/ driver description */
DWORD dwMajorVersion, /* Major # of driver spec in lpguidSP */
DWORD dwMinorVersion, /* Minor # of driver spec in lpguidSP */
LPVOID lpContext); /* User given */
typedef BOOL (CALLBACK* LPDPENUMCONNECTIONSCALLBACK)(
LPCGUID lpguidSP,
LPVOID lpConnection,
DWORD dwConnectionSize,
LPCDPNAME lpName,
DWORD dwFlags,
LPVOID lpContext);
#endif
static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
( LPDIRECTPLAY3A iface, LPCGUID lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, LPVOID lpContext, DWORD dwFlags )
{
ICOM_THIS(IDirectPlay3Impl,iface);
FIXME("(%p)->(%p,%p,%p,0x%08lx): stub\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
TRACE("(%p)->(%p,%p,%p,0x%08lx)\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
/* A default dwFlags (0) is backwards compatible -- DPCONNECTION_DIRECTPLAY */
if( dwFlags == 0 )
......@@ -896,21 +888,85 @@ static HRESULT WINAPI DirectPlay3AImpl_EnumConnections
return DPERR_INVALIDFLAGS;
}
if( lpguidApplication != NULL )
if( !lpEnumCallback || !*lpEnumCallback )
{
FIXME( ": don't know how to deal with a non NULL lpguidApplication yet\n" );
return DPERR_INVALIDPARAMS;
}
/* Enumerate DirectPlay service providers */
if( dwFlags & DPCONNECTION_DIRECTPLAY )
{
HKEY hkResult;
LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
LPSTR guidDataSubKey = "Guid";
DWORD dwIndex, sizeOfSubKeyName=50;
char subKeyName[51];
/* Need to loop over the service providers in the registry */
if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
{
/* Hmmm. Does this mean that there are no service providers? */
ERR(": no service providers?\n");
return DP_OK;
}
/* Traverse all the service providers we have available */
for( dwIndex=0;
RegEnumKeyA( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) != ERROR_NO_MORE_ITEMS;
++dwIndex )
{
HKEY hkServiceProvider;
GUID serviceProviderGUID;
DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
char returnBuffer[51];
LPWSTR lpWGUIDString;
DPNAME dpName;
TRACE(" this time through: %s\n", subKeyName );
/* Get a handle for this particular service provider */
if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
&hkServiceProvider ) != ERROR_SUCCESS )
{
ERR(": what the heck is going on?\n" );
continue;
}
if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
NULL, &returnTypeGUID, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR(": missing GUID registry data members\n" );
continue;
}
/* FIXME: Check return types to ensure we're interpreting data right */
lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
HeapFree( GetProcessHeap(), 0, lpWGUIDString );
/* FIXME: Have I got a memory leak on the serviceProviderGUID? */
dpName.dwSize = sizeof( dpName );
dpName.dwFlags = 0;
dpName.psn.lpszShortNameA = subKeyName; /* FIXME: Is this right? */
dpName.pln.lpszLongNameA = subKeyName; /* FIXME: Is this right? */
/* The enumeration will return FALSE if we are not to continue */
if( !lpEnumCallback( &serviceProviderGUID, NULL,0, &dpName, 0, lpContext ) )
{
WARN("lpEnumCallback returning FALSE\n" );
break;
}
}
}
/* Enumerate DirectPlayLobby service providers */
if( dwFlags & DPCONNECTION_DIRECTPLAYLOBBY )
{
FIXME( "DPCONNECTION_DIRECTPLAYLOBBY flag not handled\n" );
}
return DP_OK;
......@@ -961,6 +1017,12 @@ static HRESULT WINAPI DirectPlay3AImpl_InitializeConnection
{
ICOM_THIS(IDirectPlay3Impl,iface);
FIXME("(%p)->(%p,0x%08lx): stub\n", This, lpConnection, dwFlags );
if( dwFlags != 0 )
{
return DPERR_INVALIDFLAGS;
}
return DP_OK;
}
......@@ -1581,10 +1643,8 @@ HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
HKEY hkResult;
LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
LPSTR guidDataSubKey = "Guid";
LPSTR majVerDataSubKey = "dwReserved1";
LPSTR minVerDataSubKey = "dwReserved0";
DWORD dwIndex, sizeOfSubKeyName=50;
DWORD dwIndex;
DWORD sizeOfSubKeyName=50;
char subKeyName[51];
TRACE(": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
......@@ -1608,6 +1668,9 @@ HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
RegEnumKeyA( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) != ERROR_NO_MORE_ITEMS;
++dwIndex )
{
LPSTR majVerDataSubKey = "dwReserved1";
LPSTR minVerDataSubKey = "dwReserved2";
LPSTR guidDataSubKey = "Guid";
HKEY hkServiceProvider;
GUID serviceProviderGUID;
DWORD returnTypeGUID, returnTypeReserved, sizeOfReturnBuffer = 50;
......@@ -1641,8 +1704,9 @@ HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
HeapFree( GetProcessHeap(), 0, lpWGUIDString );
sizeOfReturnBuffer = 50;
/* FIXME: Need to know which of dwReserved1 and dwReserved2 are maj and min */
sizeOfReturnBuffer = 50;
if( RegQueryValueExA( hkServiceProvider, majVerDataSubKey,
NULL, &returnTypeReserved, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
......@@ -1651,17 +1715,14 @@ HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
continue;
}
/* FIXME: This couldn't possibly be right...*/
majVersionNum = GET_DWORD( returnBuffer );
sizeOfReturnBuffer = 50;
if( RegQueryValueExA( hkServiceProvider, minVerDataSubKey,
NULL, &returnTypeReserved, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR(": missing dwReserved0 registry data members\n") ;
ERR(": missing dwReserved2 registry data members\n") ;
continue;
}
......@@ -1701,25 +1762,54 @@ HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID
HRESULT WINAPI DirectPlayCreate
( LPGUID lpGUID, LPDIRECTPLAY2 *lplpDP, IUnknown *pUnk)
{
char lpGUIDString[51];
TRACE("lpGUID=%p lplpDP=%p pUnk=%p\n", lpGUID,lplpDP,pUnk);
WINE_StringFromCLSID( lpGUID, &lpGUIDString[0] );
TRACE( "lpGUID=%s lplpDP=%p pUnk=%p\n", &lpGUIDString[0], lplpDP, pUnk );
if( pUnk != NULL )
{
/* Hmmm...wonder what this means! */
ERR("What does a NULL here mean?\n" );
return DPERR_OUTOFMEMORY;
return CLASS_E_NOAGGREGATION;
}
/* One possibility is that they want an exact dplay interface */
if( IsEqualGUID( &IID_IDirectPlay2A, lpGUID ) )
{
return directPlay_QueryInterface( lpGUID, lplpDP );
return directPlay_QueryInterface( lpGUID, (LPVOID*)lplpDP );
}
else if( IsEqualGUID( &IID_IDirectPlay2, lpGUID ) )
{
return directPlay_QueryInterface( lpGUID, lplpDP );
return directPlay_QueryInterface( lpGUID, (LPVOID*)lplpDP );
}
/* Unknown interface type */
return DPERR_NOINTERFACE;
/* Create an IDirectPlay object. We don't support that so we'll cheat and
give them an IDirectPlay2A object and hope that doesn't cause problems */
if( directPlay_QueryInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) != DP_OK )
{
return DPERR_UNAVAILABLE;
}
/* Bind the desired service provider */
if( IsEqualGUID( lpGUID, &DPSPGUID_MODEM ) )
{
FIXME( "Modem binding not supported yet\n" );
IDirectPlayX_Release( *lplpDP );
*lplpDP = NULL;
return DPERR_INVALIDPARAMS;
}
/* The GUID_NULL means don't bind a service provider. Just return the
interface. However, if it isn't we were given a bogus GUID, return an ERROR */
if( !IsEqualGUID( lpGUID, &GUID_NULL ) )
{
WARN( "unknown GUID %s\n", &lpGUIDString[0] );
}
IDirectPlayX_Release( *lplpDP );
*lplpDP = NULL;
return DPERR_INVALIDPARAMS;
}
name dplayx
type win32
init DPLAYX_LibMain
1 stdcall DirectPlayCreate(ptr ptr ptr ptr) DirectPlayCreate
2 stdcall DirectPlayEnumerateA(ptr ptr) DirectPlayEnumerateA
......
/* dplayx.dll global data implementation.
*
* Copyright 1999 - Peter Hunnisett
*
* <presently under construction - contact hunnise@nortelnetworks.com>
*
*/
/* NOTE: Methods that begin with DPLAYX_ are used for dealing with
* dplayx.dll data which is accessible from all processes.
*/
#include "debugtools.h"
#include "winbase.h"
#include "winerror.h"
#include "heap.h" /* Really shouldn't be using those HEAP_strdupA interfaces should I? */
#include "dplayx_global.h"
DEFAULT_DEBUG_CHANNEL(dplay)
/* FIXME: Need to do all that fun other dll referencing type of stuff */
/* FIXME: Need to allocate a giant static area - or a global data type thing for Get/Set */
/* Static data for all processes */
static LPSTR lpszDplayxSemaName = "DPLAYX_SM";
static HANDLE hDplayxSema;
#define DPLAYX_AquireSemaphore() 0L /* WaitForSingleObject( hDplayxSema, INFINITE? ) */
#define DPLAYX_ReleaseSemaphore() 0L /* ReleaseSemaphore( hDplayxSema, ..., ... ) */
/* HACK for simple global data right now */
enum { numSupportedLobbies = 32 };
typedef struct tagDirectPlayLobbyData
{
DWORD dwConnFlags;
DPSESSIONDESC2 sessionDesc;
DPNAME playerName;
GUID guidSP;
LPVOID lpAddress;
DWORD dwAddressSize;
DWORD dwAppID;
HANDLE hReceiveEvent;
} DirectPlayLobbyData, *lpDirectPlayLobbyData;
static DirectPlayLobbyData lobbyData[ numSupportedLobbies ];
/* Function prototypes */
BOOL DPLAYX_AppIdLobbied( DWORD dwAppId, lpDirectPlayLobbyData* dplData );
/***************************************************************************
* Called to initialize the global data. This will only be used on the
* loading of the dll
***************************************************************************/
void DPLAYX_ConstructData(void)
{
UINT i;
TRACE( "DPLAYX dll loaded - construct called\n" );
/* FIXME: This needs to be allocated shared */
hDplayxSema = CreateSemaphoreA( NULL, 0, 1, lpszDplayxSemaName );
if( !hDplayxSema )
{
/* Really don't have any choice but to continue... */
ERR( "Semaphore creation error 0x%08lx\n", GetLastError() );
}
/* Set all lobbies to be "empty" */
for( i=0; i < numSupportedLobbies; i++ )
{
lobbyData[ i ].dwAppID = 0;
}
}
/***************************************************************************
* Called to destroy all global data. This will only be used on the
* unloading of the dll
***************************************************************************/
void DPLAYX_DestructData(void)
{
/* Hmmm...what to call to delete the semaphore? Auto delete? */
TRACE( "DPLAYX dll unloaded - destruct called\n" );
}
/* NOTE: This must be called with the semaphore aquired.
* TRUE/FALSE with a pointer to it's data returned
*/
BOOL DPLAYX_AppIdLobbied( DWORD dwAppID, lpDirectPlayLobbyData* lplpDplData )
{
INT i;
if( dwAppID == 0 )
{
dwAppID = GetCurrentProcessId();
}
for( i=0; i < numSupportedLobbies; i++ )
{
if( lobbyData[ i ].dwAppID == dwAppID )
{
/* This process is lobbied */
*lplpDplData = &lobbyData[ i ];
return TRUE;
}
}
return FALSE;
}
#if !defined( WORKING_PROCESS_SUSPEND )
/* These two functions should not exist. We would normally create a process initially
suspended when we RunApplication. This gives us time to actually store some data
before the new process might try to read it. However, process suspension doesn't
work yet and I'm too stupid to get it going. So, we'll just hack in fine fashion */
DWORD DPLAYX_AquireSemaphoreHack( void )
{
return DPLAYX_AquireSemaphore();
}
DWORD DPLAYX_ReleaseSemaphoreHack( void )
{
return DPLAYX_ReleaseSemaphore();
}
#endif
/* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
{
INT i;
DPLAYX_AquireSemaphore();
for( i=0; i < numSupportedLobbies; i++ )
{
if( lobbyData[ i ].dwAppID == 0 )
{
/* This process is now lobbied */
lobbyData[ i ].dwAppID = dwAppID;
lobbyData[ i ].hReceiveEvent = hReceiveEvent;
DPLAYX_ReleaseSemaphore();
return TRUE;
}
}
DPLAYX_ReleaseSemaphore();
return FALSE;
}
HRESULT DPLAYX_GetConnectionSettingsA
( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
lpDirectPlayLobbyData lpDplData;
LPDPLCONNECTION lpDplConnection;
DPLAYX_AquireSemaphore();
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
/* Verify buffer size */
if ( ( lpData == NULL ) ||
( *lpdwDataSize < sizeof( DPLCONNECTION ) )
)
{
DPLAYX_ReleaseSemaphore();
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
}
/* Copy the information */
lpDplConnection = (LPDPLCONNECTION)lpData;
/* Copy everything we've got into here */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplConnection->dwSize = sizeof( DPLCONNECTION );
lpDplConnection->dwFlags = lpDplData->dwConnFlags;
/* Copy LPDPSESSIONDESC2 struct */
lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->sessionDesc ) );
memcpy( lpDplConnection->lpSessionDesc, &lpDplData->sessionDesc, sizeof( lpDplData->sessionDesc ) );
if( lpDplData->sessionDesc.sess.lpszSessionNameA )
{
lpDplConnection->lpSessionDesc->sess.lpszSessionNameA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.sess.lpszSessionNameA );
}
if( lpDplData->sessionDesc.pass.lpszPasswordA )
{
lpDplConnection->lpSessionDesc->pass.lpszPasswordA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.pass.lpszPasswordA );
}
lpDplConnection->lpSessionDesc->dwReserved1 = lpDplData->sessionDesc.dwReserved1;
lpDplConnection->lpSessionDesc->dwReserved2 = lpDplData->sessionDesc.dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->playerName ) );
memcpy( lpDplConnection->lpPlayerName, &(lpDplData->playerName), sizeof( lpDplData->playerName ) );
if( lpDplData->playerName.psn.lpszShortNameA )
{
lpDplConnection->lpPlayerName->psn.lpszShortNameA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.psn.lpszShortNameA );
}
if( lpDplData->playerName.pln.lpszLongNameA )
{
lpDplConnection->lpPlayerName->pln.lpszLongNameA =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.pln.lpszLongNameA );
}
memcpy( &lpDplConnection->guidSP, &lpDplData->guidSP, sizeof( lpDplData->guidSP ) );
lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->dwAddressSize );
memcpy( lpDplConnection->lpAddress, lpDplData->lpAddress, lpDplData->dwAddressSize );
lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
/* Send a message - or only the first time? */
DPLAYX_ReleaseSemaphore();
return DP_OK;
}
HRESULT DPLAYX_GetConnectionSettingsW
( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
lpDirectPlayLobbyData lpDplData;
LPDPLCONNECTION lpDplConnection;
DPLAYX_AquireSemaphore();
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
/* Verify buffer size */
if ( ( lpData == NULL ) ||
( *lpdwDataSize < sizeof( DPLCONNECTION ) )
)
{
DPLAYX_ReleaseSemaphore();
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
}
/* Copy the information */
lpDplConnection = (LPDPLCONNECTION)lpData;
/* Copy everything we've got into here */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplConnection->dwSize = sizeof( DPLCONNECTION );
lpDplConnection->dwFlags = lpDplData->dwConnFlags;
/* Copy LPDPSESSIONDESC2 struct */
lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->sessionDesc ) );
memcpy( lpDplConnection->lpSessionDesc, &lpDplData->sessionDesc, sizeof( lpDplData->sessionDesc ) );
if( lpDplData->sessionDesc.sess.lpszSessionName )
{
lpDplConnection->lpSessionDesc->sess.lpszSessionName =
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.sess.lpszSessionName );
}
if( lpDplData->sessionDesc.pass.lpszPassword )
{
lpDplConnection->lpSessionDesc->pass.lpszPassword =
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.pass.lpszPassword );
}
lpDplConnection->lpSessionDesc->dwReserved1 = lpDplData->sessionDesc.dwReserved1;
lpDplConnection->lpSessionDesc->dwReserved2 = lpDplData->sessionDesc.dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->playerName ) );
memcpy( lpDplConnection->lpPlayerName, &(lpDplData->playerName), sizeof( lpDplData->playerName ) );
if( lpDplData->playerName.psn.lpszShortName )
{
lpDplConnection->lpPlayerName->psn.lpszShortName =
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.psn.lpszShortName );
}
if( lpDplData->playerName.pln.lpszLongName )
{
lpDplConnection->lpPlayerName->pln.lpszLongName =
HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.pln.lpszLongName );
}
memcpy( &lpDplConnection->guidSP, &lpDplData->guidSP, sizeof( lpDplData->guidSP ) );
lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->dwAddressSize );
memcpy( lpDplConnection->lpAddress, lpDplData->lpAddress, lpDplData->dwAddressSize );
lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
/* Send a message - or only the first time? */
DPLAYX_ReleaseSemaphore();
return DP_OK;
}
HRESULT DPLAYX_SetConnectionSettingsA
( DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
lpDirectPlayLobbyData lpDplData;
DPLAYX_AquireSemaphore();
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
{
/* FIXME: Create a new entry for this dwAppID? */
DPLAYX_ReleaseSemaphore();
return DPERR_GENERIC;
}
/* Paramater check */
if( dwFlags || !lpConn )
{
DPLAYX_ReleaseSemaphore();
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
}
/* Store information */
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
DPLAYX_ReleaseSemaphore();
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
}
/* Need to investigate the lpConn->lpSessionDesc to figure out
* what type of session we need to join/create.
*/
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
{
DPLAYX_ReleaseSemaphore();
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
}
/* FIXME: How do I store this stuff so that it can be read by all processes? Static area? What about strings? Ewww...large global shared */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplData->dwConnFlags = lpConn->dwFlags;
/* Copy LPDPSESSIONDESC2 struct - this is required */
memcpy( &lpDplData->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
lpDplData->sessionDesc.sess.lpszSessionNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionNameA );
else
lpDplData->sessionDesc.sess.lpszSessionNameA = NULL;
if( lpConn->lpSessionDesc->pass.lpszPasswordA )
lpDplData->sessionDesc.pass.lpszPasswordA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPasswordA );
else
lpDplData->sessionDesc.pass.lpszPasswordA = NULL;
lpDplData->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
lpDplData->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
if( lpConn->lpPlayerName )
{
memcpy( &lpDplData->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
if( lpConn->lpPlayerName->psn.lpszShortNameA )
lpDplData->playerName.psn.lpszShortNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortNameA );
if( lpConn->lpPlayerName->pln.lpszLongNameA )
lpDplData->playerName.pln.lpszLongNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongNameA );
}
memcpy( &lpDplData->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
lpDplData->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
memcpy( lpDplData->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
lpDplData->dwAddressSize = lpConn->dwAddressSize;
/* Send a message - I think */
DPLAYX_ReleaseSemaphore();
return DP_OK;
}
HRESULT DPLAYX_SetConnectionSettingsW
( DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
lpDirectPlayLobbyData lpDplData;
DPLAYX_AquireSemaphore();
if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
{
DPLAYX_ReleaseSemaphore();
return DPERR_NOTLOBBIED;
}
/* Paramater check */
if( dwFlags || !lpConn )
{
DPLAYX_ReleaseSemaphore();
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
}
/* Store information */
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
DPLAYX_ReleaseSemaphore();
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
}
/* Need to investigate the lpConn->lpSessionDesc to figure out
* what type of session we need to join/create.
*/
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
{
DPLAYX_ReleaseSemaphore();
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
}
/* FIXME: How do I store this stuff so that it can be read by all processes? Static area? What about strings? Ewww...large global shared */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplData->dwConnFlags = lpConn->dwFlags;
/* Copy LPDPSESSIONDESC2 struct - this is required */
memcpy( &lpDplData->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
if( lpConn->lpSessionDesc->sess.lpszSessionName )
lpDplData->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
else
lpDplData->sessionDesc.sess.lpszSessionName = NULL;
if( lpConn->lpSessionDesc->pass.lpszPassword )
lpDplData->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
else
lpDplData->sessionDesc.pass.lpszPassword = NULL;
lpDplData->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
lpDplData->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
if( lpConn->lpPlayerName )
{
memcpy( &lpDplData->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
if( lpConn->lpPlayerName->psn.lpszShortName )
lpDplData->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName );
if( lpConn->lpPlayerName->pln.lpszLongName )
lpDplData->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
}
memcpy( &lpDplData->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
lpDplData->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
memcpy( lpDplData->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
lpDplData->dwAddressSize = lpConn->dwAddressSize;
/* Send a message - I think */
DPLAYX_ReleaseSemaphore();
return DP_OK;
}
#ifndef __WINE_DPLAYX_GLOBAL
#define __WINE_DPLAYX_GLOBAL
#include "dplay.h"
void DPLAYX_ConstructData(void);
void DPLAYX_DestructData(void);
HRESULT DPLAYX_GetConnectionSettingsA ( DWORD dwAppID, LPVOID lpData, LPDWORD lpdwDataSize );
HRESULT DPLAYX_GetConnectionSettingsW ( DWORD dwAppID, LPVOID lpData, LPDWORD lpdwDataSize );
HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags, DWORD dwAppID, LPDPLCONNECTION lpConn );
HRESULT DPLAYX_SetConnectionSettingsW ( DWORD dwFlags, DWORD dwAppID, LPDPLCONNECTION lpConn );
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent );
/* This is a hack to ensure synchronization during application spawn */
#if !defined( WORKING_PROCESS_SUSPEND )
DWORD DPLAYX_AquireSemaphoreHack( void );
DWORD DPLAYX_ReleaseSemaphoreHack( void );
#endif
#endif /* __WINE_DPLAYX_GLOBAL */
/*
* DPLAYX.DLL LibMain
*
* Copyright 1999 - Peter Hunnisett
*
* contact <hunnise@nortelnetworks.com>
*/
#include "winbase.h"
#include "debugtools.h"
#include "dplayx_global.h"
DEFAULT_DEBUG_CHANNEL(dplay)
static DWORD DPLAYX_dwProcessesAttached = 0;
BOOL WINAPI DPLAYX_LibMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH:
{
if ( DPLAYX_dwProcessesAttached == 0 )
{
/* First instance perform construction of global processor data */
DPLAYX_ConstructData();
}
DPLAYX_dwProcessesAttached++;
break;
}
case DLL_PROCESS_DETACH:
{
DPLAYX_dwProcessesAttached--;
if ( DPLAYX_dwProcessesAttached == 0 )
{
/* Last instance perform destruction of global processor data */
DPLAYX_DestructData();
}
break;
}
case DLL_THREAD_ATTACH: /* Do nothing */
case DLL_THREAD_DETACH: /* Do nothing */
break;
default:
break;
}
return TRUE;
}
......@@ -6,25 +6,40 @@
*
*/
#include <string.h>
#include "winerror.h"
#include "winnt.h"
#include "winreg.h"
#include "dplobby.h"
#include "heap.h"
#include "debugtools.h"
#include "dplobby.h"
#include "dpinit.h"
#include "dplayx_global.h"
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 );
static HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, LPCVOID lpAddress,
DWORD dwAddressSize, LPVOID lpContext );
/*****************************************************************************
* Predeclare the interface implementation structures
*/
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyAImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobbyWImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobby2Impl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobby2AImpl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobby3Impl;
typedef struct IDirectPlayLobbyImpl IDirectPlayLobby3AImpl;
typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2AImpl;
typedef struct IDirectPlayLobby2Impl IDirectPlayLobby2WImpl;
typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3AImpl;
typedef struct IDirectPlayLobby3Impl IDirectPlayLobby3WImpl;
/*****************************************************************************
* IDirectPlayLobby {1,2,3} implementation structure
......@@ -46,15 +61,9 @@ typedef struct tagDirectPlayLobbyIUnknownData
CRITICAL_SECTION DPL_lock;
} DirectPlayLobbyIUnknownData;
/* FIXME: I don't think that everything belongs here...*/
typedef struct tagDirectPlayLobbyData
{
DWORD dwConnFlags;
DPSESSIONDESC2 sessionDesc;
DPNAME playerName;
GUID guidSP;
LPVOID lpAddress;
DWORD dwAddressSize;
HKEY hkCallbackKeyHack;
} DirectPlayLobbyData;
typedef struct tagDirectPlayLobby2Data
......@@ -67,31 +76,39 @@ typedef struct tagDirectPlayLobby3Data
BOOL dummy;
} DirectPlayLobby3Data;
#define LOBBY_IMPL_FIELDS DirectPlayLobbyIUnknownData* unk; \
DirectPlayLobbyData* dpl; \
DirectPlayLobby2Data* dpl2; \
DirectPlayLobby3Data* dpl3;
struct IDirectPlayLobbyImpl
{
ICOM_VFIELD(IDirectPlayLobby);
LOBBY_IMPL_FIELDS
};
/* IUnknown fields */
DirectPlayLobbyIUnknownData* unk;
/* IDirectPlayLobby 1 fields */
DirectPlayLobbyData* dpl;
/* IDirectPlayLobby 2 fields */
DirectPlayLobby2Data* dpl2;
struct IDirectPlayLobby2Impl
{
ICOM_VFIELD(IDirectPlayLobby2);
LOBBY_IMPL_FIELDS
};
/* IDirectPlayLobby 3 fields */
DirectPlayLobby3Data* dpl3;
struct IDirectPlayLobby3Impl
{
ICOM_VFIELD(IDirectPlayLobby3);
LOBBY_IMPL_FIELDS
};
/* Forward declarations of virtual tables */
static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT;
static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyWVT;
static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT;
static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2WVT;
static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3AVT;
static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3WVT;
static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT;
static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT;
static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3AVT;
......@@ -123,15 +140,17 @@ static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3WVT;
*/
BOOL DPL_CreateIUnknown( IDirectPlayLobbyImpl* lpDPL )
BOOL DPL_CreateIUnknown( LPVOID lpDPL )
{
lpDPL->unk = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(lpDPL->unk) ) );
if ( lpDPL->unk != NULL )
ICOM_THIS(IDirectPlayLobbyAImpl,lpDPL);
This->unk = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->unk) ) );
if ( This->unk != NULL )
{
InitializeCriticalSection( &lpDPL->unk->DPL_lock );
InitializeCriticalSection( &This->unk->DPL_lock );
IDirectPlayLobby_AddRef( (IDirectPlayLobby*)lpDPL );
IDirectPlayLobby_AddRef( (LPDIRECTPLAYLOBBYA)lpDPL );
return TRUE;
}
......@@ -139,53 +158,47 @@ BOOL DPL_CreateIUnknown( IDirectPlayLobbyImpl* lpDPL )
return FALSE;
}
BOOL DPL_DestroyIUnknown( IDirectPlayLobbyImpl* lpDPL )
BOOL DPL_DestroyIUnknown( LPVOID lpDPL )
{
DeleteCriticalSection( &lpDPL->unk->DPL_lock );
HeapFree( GetProcessHeap(), 0, lpDPL->unk );
ICOM_THIS(IDirectPlayLobbyAImpl,lpDPL);
DeleteCriticalSection( &This->unk->DPL_lock );
HeapFree( GetProcessHeap(), 0, This->unk );
return TRUE;
}
BOOL DPL_CreateLobby1( IDirectPlayLobbyImpl* lpDPL )
BOOL DPL_CreateLobby1( LPVOID lpDPL )
{
lpDPL->dpl = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(lpDPL->dpl) ) );
if ( lpDPL->dpl == NULL )
ICOM_THIS(IDirectPlayLobbyAImpl,lpDPL);
This->dpl = (DirectPlayLobbyData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->dpl) ) );
if ( This->dpl == NULL )
{
return FALSE;
}
/* Initialize the dwSize fields for internal structures */
lpDPL->dpl->sessionDesc.dwSize = sizeof( lpDPL->dpl->sessionDesc );
lpDPL->dpl->playerName.dwSize = sizeof( lpDPL->dpl->playerName );
/* lpDPL->dpl->dwAddressSize = 0; Done in HeapAlloc */
return TRUE;
}
BOOL DPL_DestroyLobby1( IDirectPlayLobbyImpl* lpDPL )
BOOL DPL_DestroyLobby1( LPVOID lpDPL )
{
/* Delete the contents */
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->sessionDesc.sess.lpszSessionNameA );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->sessionDesc.pass.lpszPasswordA );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->playerName.psn.lpszShortNameA );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->playerName.pln.lpszLongNameA );
HeapFree( GetProcessHeap(), 0, lpDPL->dpl->lpAddress );
ICOM_THIS(IDirectPlayLobbyAImpl,lpDPL);
HeapFree( GetProcessHeap(), 0, lpDPL->dpl );
/* Delete the contents */
HeapFree( GetProcessHeap(), 0, This->dpl );
return TRUE;
}
BOOL DPL_CreateLobby2( IDirectPlayLobbyImpl* lpDPL )
BOOL DPL_CreateLobby2( LPVOID lpDPL )
{
lpDPL->dpl2 = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(lpDPL->dpl2) ) );
if ( lpDPL->dpl2 == NULL )
ICOM_THIS(IDirectPlayLobby2AImpl,lpDPL);
This->dpl2 = (DirectPlayLobby2Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->dpl2) ) );
if ( This->dpl2 == NULL )
{
return FALSE;
}
......@@ -193,18 +206,22 @@ BOOL DPL_CreateLobby2( IDirectPlayLobbyImpl* lpDPL )
return TRUE;
}
BOOL DPL_DestroyLobby2( IDirectPlayLobbyImpl* lpDPL )
BOOL DPL_DestroyLobby2( LPVOID lpDPL )
{
HeapFree( GetProcessHeap(), 0, lpDPL->dpl2 );
ICOM_THIS(IDirectPlayLobby2AImpl,lpDPL);
HeapFree( GetProcessHeap(), 0, This->dpl2 );
return TRUE;
}
BOOL DPL_CreateLobby3( IDirectPlayLobbyImpl* lpDPL )
BOOL DPL_CreateLobby3( LPVOID lpDPL )
{
lpDPL->dpl3 = (DirectPlayLobbyIUnknownData*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(lpDPL->dpl3) ) );
if ( lpDPL->dpl3 == NULL )
ICOM_THIS(IDirectPlayLobby3AImpl,lpDPL);
This->dpl3 = (DirectPlayLobby3Data*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *(This->dpl3) ) );
if ( This->dpl3 == NULL )
{
return FALSE;
}
......@@ -212,9 +229,11 @@ BOOL DPL_CreateLobby3( IDirectPlayLobbyImpl* lpDPL )
return TRUE;
}
BOOL DPL_DestroyLobby3( IDirectPlayLobbyImpl* lpDPL )
BOOL DPL_DestroyLobby3( LPVOID lpDPL )
{
HeapFree( GetProcessHeap(), 0, lpDPL->dpl3 );
ICOM_THIS(IDirectPlayLobby3AImpl,lpDPL);
HeapFree( GetProcessHeap(), 0, This->dpl3 );
return TRUE;
}
......@@ -225,153 +244,179 @@ extern
HRESULT directPlayLobby_QueryInterface
( REFIID riid, LPVOID* ppvObj )
{
IDirectPlayLobby3AImpl* lpDPL = NULL;
if( IsEqualGUID( &IID_IDirectPlayLobby, riid ) )
{
lpDPL = (IDirectPlayLobbyImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlayLobbyWImpl ) );
if( !lpDPL )
if( *ppvObj == NULL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobbyWVT;
/* new scope for variable declaration */
{
ICOM_THIS(IDirectPlayLobbyWImpl,*ppvObj);
ICOM_VTBL(This) = &directPlayLobbyWVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL )
if ( DPL_CreateIUnknown( (LPVOID)This ) &&
DPL_CreateLobby1( (LPVOID)This )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlayLobbyA, riid ) )
{
lpDPL = (IDirectPlayLobbyAImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlayLobbyAImpl ) );
if( !lpDPL )
if( *ppvObj == NULL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobbyAVT;
{
ICOM_THIS(IDirectPlayLobbyAImpl,*ppvObj);
ICOM_VTBL(This) = &directPlayLobbyAVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL )
if ( DPL_CreateIUnknown( (LPVOID)This ) &&
DPL_CreateLobby1( (LPVOID)This )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlayLobby2, riid ) )
{
lpDPL = (IDirectPlayLobby2Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlayLobby2WImpl ) );
if( !lpDPL )
if( *ppvObj == NULL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobby2WVT;
{
ICOM_THIS(IDirectPlayLobby2WImpl,*ppvObj);
ICOM_VTBL(This) = &directPlayLobby2WVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL ) &&
DPL_CreateLobby2( lpDPL )
if ( DPL_CreateIUnknown( (LPVOID)This ) &&
DPL_CreateLobby1( (LPVOID)This ) &&
DPL_CreateLobby2( (LPVOID)This )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) )
{
lpDPL = (IDirectPlayLobby2AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlayLobby2AImpl ) );
if( !lpDPL )
if( *ppvObj == NULL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobby2AVT;
{
ICOM_THIS(IDirectPlayLobby2AImpl,*ppvObj);
ICOM_VTBL(This) = &directPlayLobby2AVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL ) &&
DPL_CreateLobby2( lpDPL )
if ( DPL_CreateIUnknown( (LPVOID)This ) &&
DPL_CreateLobby1( (LPVOID)This ) &&
DPL_CreateLobby2( (LPVOID)This )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlayLobby3, riid ) )
{
lpDPL = (IDirectPlayLobby3Impl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlayLobby3WImpl ) );
if( !lpDPL )
if( *ppvObj == NULL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobby3WVT;
{
ICOM_THIS(IDirectPlayLobby3WImpl,*ppvObj);
ICOM_VTBL(This) = &directPlayLobby3WVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL ) &&
DPL_CreateLobby2( lpDPL ) &&
DPL_CreateLobby3( lpDPL )
if ( DPL_CreateIUnknown( *ppvObj ) &&
DPL_CreateLobby1( *ppvObj ) &&
DPL_CreateLobby2( *ppvObj ) &&
DPL_CreateLobby3( *ppvObj )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
goto error;
}
else if( IsEqualGUID( &IID_IDirectPlayLobby3A, riid ) )
{
lpDPL = (IDirectPlayLobby3AImpl*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( *lpDPL ) );
*ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof( IDirectPlayLobby3AImpl ) );
if( !lpDPL )
if( *ppvObj == NULL )
{
return E_OUTOFMEMORY;
}
ICOM_VTBL(lpDPL) = &directPlayLobby3AVT;
{
ICOM_THIS(IDirectPlayLobby3AImpl,*ppvObj);
ICOM_VTBL(This) = &directPlayLobby3AVT;
if ( DPL_CreateIUnknown( lpDPL ) &&
DPL_CreateLobby1( lpDPL ) &&
DPL_CreateLobby2( lpDPL ) &&
DPL_CreateLobby3( lpDPL )
if ( DPL_CreateIUnknown( *ppvObj ) &&
DPL_CreateLobby1( *ppvObj ) &&
DPL_CreateLobby2( *ppvObj ) &&
DPL_CreateLobby3( *ppvObj )
)
{
*ppvObj = lpDPL;
return S_OK;
}
}
/* Check if we had problems creating an interface */
if ( lpDPL != NULL )
{
DPL_DestroyLobby3( lpDPL );
DPL_DestroyLobby2( lpDPL );
DPL_DestroyLobby1( lpDPL );
DPL_DestroyIUnknown( lpDPL );
HeapFree( GetProcessHeap(), 0, lpDPL );
goto error;
}
/* Unsupported interface */
*ppvObj = NULL;
return E_NOINTERFACE;
error:
DPL_DestroyLobby3( *ppvObj );
DPL_DestroyLobby2( *ppvObj );
DPL_DestroyLobby1( *ppvObj );
DPL_DestroyIUnknown( *ppvObj );
HeapFree( GetProcessHeap(), 0, *ppvObj );
return DPERR_NOMEMORY;
}
else /* Unsupported interface */
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
return DPERR_NOMEMORY;
}
static HRESULT WINAPI IDirectPlayLobbyAImpl_QueryInterface
......@@ -379,7 +424,7 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_QueryInterface
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby2Impl,iface);
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
if( IsEqualGUID( &IID_IUnknown, riid ) ||
......@@ -400,7 +445,7 @@ static HRESULT WINAPI IDirectPlayLobbyW_QueryInterface
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
if( IsEqualGUID( &IID_IUnknown, riid ) ||
......@@ -421,7 +466,7 @@ static HRESULT WINAPI IDirectPlayLobby2AImpl_QueryInterface
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby2Impl,iface);
ICOM_THIS(IDirectPlayLobby2AImpl,iface);
TRACE("(%p)->(%p,%p)\n", This, riid, ppvObj );
/* Compare riids. We know this object is a direct play lobby 2A object.
......@@ -443,7 +488,7 @@ static HRESULT WINAPI IDirectPlayLobby2WImpl_QueryInterface
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby2Impl,iface);
ICOM_THIS(IDirectPlayLobby2WImpl,iface);
/* Compare riids. We know this object is a direct play lobby 2 object.
If we are asking about the same type of interface we're fine.
......@@ -466,7 +511,7 @@ static HRESULT WINAPI IDirectPlayLobby3AImpl_QueryInterface
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby3Impl,iface);
ICOM_THIS(IDirectPlayLobby3AImpl,iface);
/* Compare riids. We know this object is a direct play lobby 3 object.
If we are asking about the same type of interface we're fine.
......@@ -475,7 +520,7 @@ static HRESULT WINAPI IDirectPlayLobby3AImpl_QueryInterface
IsEqualGUID( &IID_IDirectPlayLobby3A, riid )
)
{
IDirectPlayLobby_AddRef( This );
IDirectPlayLobby_AddRef( iface );
*ppvObj = This;
return S_OK;
}
......@@ -489,7 +534,7 @@ static HRESULT WINAPI IDirectPlayLobby3WImpl_QueryInterface
REFIID riid,
LPVOID* ppvObj )
{
ICOM_THIS(IDirectPlayLobby3Impl,iface);
ICOM_THIS(IDirectPlayLobby3WImpl,iface);
/* Compare riids. We know this object is a direct play lobby 3 object.
If we are asking about the same type of interface we're fine.
......@@ -511,11 +556,11 @@ static HRESULT WINAPI IDirectPlayLobby3WImpl_QueryInterface
* Simple procedure. Just increment the reference count to this
* structure and return the new reference count.
*/
static ULONG WINAPI IDirectPlayLobbyAImpl_AddRef
( LPDIRECTPLAYLOBBYA iface )
static ULONG WINAPI IDirectPlayLobbyImpl_AddRef
( LPDIRECTPLAYLOBBY iface )
{
ULONG refCount;
ICOM_THIS(IDirectPlayLobby2Impl,iface);
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
EnterCriticalSection( &This->unk->DPL_lock );
{
......@@ -538,7 +583,7 @@ static ULONG WINAPI IDirectPlayLobbyAImpl_Release
{
ULONG refCount;
ICOM_THIS(IDirectPlayLobby2Impl,iface);
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
EnterCriticalSection( &This->unk->DPL_lock );
{
......@@ -576,11 +621,11 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
LPDIRECTPLAY2A* lplpDP,
IUnknown* pUnk)
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
LPDIRECTPLAY2A lpDirectPlay2A;
LPDIRECTPLAY3A lpDirectPlay3A;
LPDIRECTPLAYLOBBY2A lpDirectPlayLobby2A;
/* LPDIRECTPLAY3A lpDirectPlay3A; */
/* LPDIRECTPLAYLOBBY2A lpDirectPlayLobby2A; */
HRESULT rc;
FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, dwFlags, lplpDP, pUnk );
......@@ -590,55 +635,26 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect
return DPERR_INVALIDPARAMS;
}
if( ( rc = DirectPlayCreate( (LPGUID)&IID_IDirectPlay2A, lplpDP, pUnk ) ) != DP_OK )
/* Create the DirectPlay interface */
if( ( rc = directPlay_QueryInterface( &IID_IDirectPlay2A, (LPVOID*)lplpDP ) ) != DP_OK )
{
ERR("error creating Direct Play 2W interface. Return Code = 0x%lx.\n", rc );
ERR("error creating Direct Play 2A interface. Return Code = 0x%lx.\n", rc );
return rc;
}
lpDirectPlay2A = *lplpDP;
/* This should invoke IDirectPlay3::InitializeConnection IDirectPlay3::Open */
/* - Use This object to get a DPL2 object using QueryInterface
* - Need to call CreateCompoundAddress to create the lpConnection param for IDirectPlay::InitializeConnection
/* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information
* - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection
* - Call IDirectPlay::InitializeConnection
* - Call IDirectPlay::Open
*/
#if 0
create_address:
{
DPCOMPOUNDADDRESSELEMENT compoundAddress;
/* Get lobby version capable of supporting CreateCompoundAddress */
if( ( rc = IDirectPlayLobby_QueryInterface( This, &IID_IDirectPlayLobby2A, &lpDirectPlayLobby2A ) ) != DP_OK )
{
return rc;
}
EnterCriticalSection( &This->unk->DPL_lock );
/* Actually create the compound address */
memcpy( compoundAddress.guidDataType, This->dpl->guidSP, sizeof( compoundAddress.guidDataType ) );
LeaveCriticalSection( &This->unk->DPL_lock );
rc = IDirectPlayLobby_CreateCompoundAddress( lpDirectPlayLobby2A, lpElements, dwElementCount, lpAddress, lpdwAddressSize )
/* Free the lobby object since we're done with it */
IDirectPlayLobby_Release( lpDirectPlayLobby2A );
if( rc != DP_OK )
{
return rc;
}
}
if( ( rc = IDirectPlayX_QueryInterface( directPlay2A, &IID_IDirectPlay3A, &lpDirectPlay3A ) ) != DP_OK )
{
return rc;
}
IDirectPlayLobby_EnumAddress( iface, RunApplicationA_Callback,
lpConn->lpAddress, lpConn->dwAddressSize, NULL );
#endif
return DP_OK;
}
......@@ -649,7 +665,7 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
LPDIRECTPLAY2* lplpDP,
IUnknown* pUnk)
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
LPDIRECTPLAY2* directPlay2W;
HRESULT createRC;
......@@ -660,7 +676,8 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
return DPERR_INVALIDPARAMS;
}
if( ( createRC = DirectPlayCreate( (LPGUID)&IID_IDirectPlay2, lplpDP, pUnk ) ) != DP_OK )
/* Create the DirectPlay interface */
if( ( createRC = directPlay_QueryInterface( &IID_IDirectPlay2, (LPVOID*)lplpDP ) ) != DP_OK )
{
ERR("error creating Direct Play 2W interface. Return Code = 0x%lx.\n", createRC );
return createRC;
......@@ -681,6 +698,8 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_Connect
* (GUID) of the service provider and data that the service provider can
* interpret as a network address.
*
* NOTE: It appears that this method is supposed to be really really stupid
* with no error checking on the contents.
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
( LPDIRECTPLAYLOBBYA iface,
......@@ -691,8 +710,27 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
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 );
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
......@@ -704,8 +742,26 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_CreateAddress
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
ICOM_THIS(IDirectPlayLobbyWImpl,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( (LPDIRECTPLAYLOBBY2)iface,
addressElements, dwNumAddElements,
lpAddress, lpdwAddressSize );
}
......@@ -722,8 +778,12 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress
DWORD dwAddressSize,
LPVOID lpContext )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This, lpEnumAddressCallback, lpAddress,
dwAddressSize, lpContext );
return DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddress
......@@ -733,8 +793,39 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddress
DWORD dwAddressSize,
LPVOID lpContext )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
TRACE("(%p)->(%p,%p,0x%08lx,%p)\n", This, lpEnumAddressCallback, lpAddress,
dwAddressSize, lpContext );
return DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
}
static HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, LPCVOID lpAddress,
DWORD dwAddressSize, LPVOID lpContext )
{
DWORD dwTotalSizeEnumerated = 0;
/* FIXME: First chunk is always the total size chunk - Should we report it? */
while ( dwTotalSizeEnumerated < dwAddressSize )
{
LPDPADDRESS lpElements = (LPDPADDRESS)lpAddress;
DWORD dwSizeThisEnumeration;
/* Invoke the enum method. If false is returned, stop enumeration */
if ( !lpEnumAddressCallback( &lpElements->guidDataType, lpElements->dwDataSize,
lpElements + sizeof( DPADDRESS ), lpContext ) )
{
break;
}
dwSizeThisEnumeration = sizeof( DPADDRESS ) + lpElements->dwDataSize;
lpAddress += dwSizeThisEnumeration;
dwTotalSizeEnumerated += dwSizeThisEnumeration;
}
return DP_OK;
}
/********************************************************************
......@@ -750,8 +841,121 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes
LPVOID lpContext,
DWORD dwFlags )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
HKEY hkResult;
LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
DWORD dwIndex, sizeOfSubKeyName=50;
char subKeyName[51];
TRACE(" (%p)->(%p,%p,%p,0x%08lx)\n", This, lpEnumAddressTypeCallback, guidSP, lpContext, dwFlags );
if( dwFlags != 0 )
{
return DPERR_INVALIDPARAMS;
}
if( !lpEnumAddressTypeCallback || !*lpEnumAddressTypeCallback )
{
return DPERR_INVALIDPARAMS;
}
if( guidSP == NULL )
{
return DPERR_INVALIDOBJECT;
}
/* Need to loop over the service providers in the registry */
if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
{
/* Hmmm. Does this mean that there are no service providers? */
ERR(": no service providers?\n");
return DP_OK;
}
/* Traverse all the service providers we have available */
for( dwIndex=0;
RegEnumKeyA( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) != ERROR_NO_MORE_ITEMS;
++dwIndex )
{
HKEY hkServiceProvider, hkServiceProviderAt;
GUID serviceProviderGUID;
DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
char atSubKey[51];
char returnBuffer[51];
LPWSTR lpWGUIDString;
DWORD dwAtIndex;
LPSTR atKey = "Address Types";
LPSTR guidDataSubKey = "Guid";
TRACE(" this time through: %s\n", subKeyName );
/* Get a handle for this particular service provider */
if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
&hkServiceProvider ) != ERROR_SUCCESS )
{
ERR(": what the heck is going on?\n" );
continue;
}
if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
NULL, &returnTypeGUID, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR(": missing GUID registry data members\n" );
continue;
}
/* FIXME: Check return types to ensure we're interpreting data right */
lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
HeapFree( GetProcessHeap(), 0, lpWGUIDString );
/* FIXME: Have I got a memory leak on the serviceProviderGUID? */
/* Determine if this is the Service Provider that the user asked for */
if( !IsEqualGUID( &serviceProviderGUID, guidSP ) )
{
continue;
}
/* Get a handle for this particular service provider */
if( RegOpenKeyExA( hkServiceProvider, atKey, 0, KEY_QUERY_VALUE,
&hkServiceProviderAt ) != ERROR_SUCCESS )
{
WARN(": No Address Types registry data sub key/members\n" );
break;
}
/* Traverse all the address type we have available */
for( dwAtIndex=0;
RegEnumKeyA( hkServiceProviderAt, dwAtIndex, atSubKey, sizeOfSubKeyName ) != ERROR_NO_MORE_ITEMS;
++dwAtIndex )
{
TRACE( "Found Address Type GUID %s\n", atSubKey );
/* FIXME: Check return types to ensure we're interpreting data right */
lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, atSubKey );
CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
HeapFree( GetProcessHeap(), 0, lpWGUIDString );
/* FIXME: Have I got a memory leak on the serviceProviderGUID? */
/* The enumeration will return FALSE if we are not to continue */
if( !lpEnumAddressTypeCallback( &serviceProviderGUID, lpContext, 0 ) )
{
WARN("lpEnumCallback returning FALSE\n" );
break; /* FIXME: This most likely has to break from the procedure...*/
}
}
/* We only enumerate address types for 1 GUID. We've found it, so quit looking */
break;
}
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumAddressTypes
......@@ -777,7 +981,7 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_EnumLocalApplications
LPVOID lpContext,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
......@@ -790,100 +994,120 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications
LPVOID lpContext,
DWORD dwFlags )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
FIXME("(%p)->(%p,%p,0x%08lx):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
return DPERR_OUTOFMEMORY;
}
/********************************************************************
*
* Retrieves the DPLCONNECTION structure that contains all the information
* needed to start and connect an application. This was generated using
* either the RunApplication or SetConnectionSettings methods.
*
* NOTES: If lpData is NULL then just return lpdwDataSize. This allows
* the data structure to be allocated by our caller which can then
* call this procedure/method again with a valid data pointer.
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
( LPDIRECTPLAYLOBBYA iface,
DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
LPDPLCONNECTION lpDplConnection;
HKEY hkResult;
LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Applications";
LPSTR guidDataSubKey = "Guid";
DWORD dwIndex, sizeOfSubKeyName=50;
char subKeyName[51];
FIXME(": semi stub (%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
TRACE("(%p)->(%p,%p,0x%08lx)\n", This, lpEnumLocalAppCallback, lpContext, dwFlags );
/* Application is requesting us to give the required size */
if ( lpData == NULL )
if( dwFlags != 0 )
{
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
return DPERR_INVALIDPARAMS;
}
/* Let's check the size of the buffer that the application has allocated */
if ( *lpdwDataSize < sizeof( DPLCONNECTION ) )
if( !lpEnumLocalAppCallback || !*lpEnumLocalAppCallback )
{
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
return DPERR_INVALIDPARAMS;
}
/* FIXME: Who's supposed to own the data */
/* Need to loop over the service providers in the registry */
if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
0, KEY_ENUMERATE_SUB_KEYS, &hkResult ) != ERROR_SUCCESS )
{
/* Hmmm. Does this mean that there are no service providers? */
ERR(": no service providers?\n");
return DP_OK;
}
/* Fill in the fields - let them just use the ptrs */
lpDplConnection = (LPDPLCONNECTION)lpData;
/* Traverse all registered applications */
for( dwIndex=0;
RegEnumKeyA( hkResult, dwIndex, subKeyName, sizeOfSubKeyName ) != ERROR_NO_MORE_ITEMS;
++dwIndex )
{
/* Copy everything we've got into here */
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
lpDplConnection->dwFlags = This->dpl->dwConnFlags;
HKEY hkServiceProvider;
GUID serviceProviderGUID;
DWORD returnTypeGUID, sizeOfReturnBuffer = 50;
char returnBuffer[51];
LPWSTR lpWGUIDString;
DPLAPPINFO dplAppInfo;
/* Copy LPDPSESSIONDESC2 struct */
lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( This->dpl->sessionDesc ) );
memcpy( lpDplConnection->lpSessionDesc, &This->dpl->sessionDesc, sizeof( This->dpl->sessionDesc ) );
TRACE(" this time through: %s\n", subKeyName );
if( This->dpl->sessionDesc.sess.lpszSessionName )
/* Get a handle for this particular service provider */
if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_QUERY_VALUE,
&hkServiceProvider ) != ERROR_SUCCESS )
{
lpDplConnection->lpSessionDesc->sess.lpszSessionName =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->sessionDesc.sess.lpszSessionNameA );
ERR(": what the heck is going on?\n" );
continue;
}
if( This->dpl->sessionDesc.pass.lpszPassword )
if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
NULL, &returnTypeGUID, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
lpDplConnection->lpSessionDesc->pass.lpszPassword =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->sessionDesc.pass.lpszPasswordA );
ERR(": missing GUID registry data members\n" );
continue;
}
lpDplConnection->lpSessionDesc->dwReserved1 = This->dpl->sessionDesc.dwReserved1;
lpDplConnection->lpSessionDesc->dwReserved2 = This->dpl->sessionDesc.dwReserved2;
/* FIXME: Check return types to ensure we're interpreting data right */
lpWGUIDString = HEAP_strdupAtoW( GetProcessHeap(), 0, returnBuffer );
CLSIDFromString( (LPCOLESTR)lpWGUIDString, &serviceProviderGUID );
HeapFree( GetProcessHeap(), 0, lpWGUIDString );
/* FIXME: Have I got a memory leak on the serviceProviderGUID? */
/* Copy DPNAME struct - seems to be optional - check for existance first */
lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( This->dpl->playerName ) );
memcpy( lpDplConnection->lpPlayerName, &(This->dpl->playerName), sizeof( This->dpl->playerName ) );
dplAppInfo.dwSize = sizeof( dplAppInfo );
dplAppInfo.guidApplication = serviceProviderGUID;
dplAppInfo.appName.lpszAppNameA = subKeyName;
if( This->dpl->playerName.psn.lpszShortName )
EnterCriticalSection( &This->unk->DPL_lock );
memcpy( &This->dpl->hkCallbackKeyHack, &hkServiceProvider, sizeof( hkServiceProvider ) );
if( !lpEnumLocalAppCallback( &dplAppInfo, lpContext, dwFlags ) )
{
lpDplConnection->lpPlayerName->psn.lpszShortName =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->playerName.psn.lpszShortNameA );
LeaveCriticalSection( &This->unk->DPL_lock );
break;
}
if( This->dpl->playerName.pln.lpszLongName )
{
lpDplConnection->lpPlayerName->pln.lpszLongName =
HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->playerName.pln.lpszLongNameA );
LeaveCriticalSection( &This->unk->DPL_lock );
}
memcpy( &lpDplConnection->guidSP, &This->dpl->guidSP, sizeof( This->dpl->guidSP ) );
return DP_OK;
}
lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, This->dpl->dwAddressSize );
memcpy( lpDplConnection->lpAddress, This->dpl->lpAddress, This->dpl->dwAddressSize );
/********************************************************************
*
* Retrieves the DPLCONNECTION structure that contains all the information
* needed to start and connect an application. This was generated using
* either the RunApplication or SetConnectionSettings methods.
*
* NOTES: If lpData is NULL then just return lpdwDataSize. This allows
* the data structure to be allocated by our caller which can then
* call this procedure/method again with a valid data pointer.
*/
static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings
( LPDIRECTPLAYLOBBYA iface,
DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
HRESULT hr;
lpDplConnection->dwAddressSize = This->dpl->dwAddressSize;
TRACE("(%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
return DP_OK;
EnterCriticalSection( &This->unk->DPL_lock );
hr = DPLAYX_GetConnectionSettingsA( dwAppID, lpData, lpdwDataSize );
LeaveCriticalSection( &This->unk->DPL_lock );
return hr;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
......@@ -892,28 +1116,18 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_GetConnectionSettings
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
FIXME(":semi stub %p %08lx %p %p \n", This, dwAppID, lpData, lpdwDataSize );
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
HRESULT hr;
/* Application is requesting us to give the required size */
if ( !lpData )
{
/* Let's check the size of the buffer that the application has allocated */
if( *lpdwDataSize >= sizeof( DPLCONNECTION ) )
{
return DP_OK;
}
else
{
*lpdwDataSize = sizeof( DPLCONNECTION );
return DPERR_BUFFERTOOSMALL;
}
}
TRACE("(%p)->(0x%08lx,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize );
EnterCriticalSection( &This->unk->DPL_lock );
/* Fill in the fields - see above */
FIXME("stub\n" );
hr = DPLAYX_GetConnectionSettingsW( dwAppID, lpData, lpdwDataSize );
return DP_OK;
LeaveCriticalSection( &This->unk->DPL_lock );
return hr;
}
/********************************************************************
......@@ -930,7 +1144,7 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
lpdwDataSize );
return DPERR_OUTOFMEMORY;
......@@ -944,12 +1158,101 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_ReceiveLobbyMessage
LPVOID lpData,
LPDWORD lpdwDataSize )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
FIXME(":stub %p %08lx %08lx %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData,
lpdwDataSize );
return DPERR_OUTOFMEMORY;
}
typedef struct tagRunApplicationEnumStruct
{
IDirectPlayLobbyAImpl* This;
GUID appGUID;
LPSTR lpszPath;
LPSTR lpszFileName;
LPSTR lpszCommandLine;
LPSTR lpszCurrentDirectory;
} RunApplicationEnumStruct, *lpRunApplicationEnumStruct;
/* To be called by RunApplication to find how to invoke the function */
static BOOL CALLBACK RunApplicationA_EnumLocalApplications
( LPCDPLAPPINFO lpAppInfo,
LPVOID lpContext,
DWORD dwFlags )
{
lpRunApplicationEnumStruct lpData = (lpRunApplicationEnumStruct)lpContext;
if( IsEqualGUID( &lpAppInfo->guidApplication, &lpData->appGUID ) )
{
char returnBuffer[200];
DWORD returnType, sizeOfReturnBuffer;
LPSTR clSubKey = "CommandLine";
LPSTR cdSubKey = "CurrentDirectory";
LPSTR fileSubKey = "File";
LPSTR pathSubKey = "Path";
/* FIXME: Lazy man hack - dplay struct has the present reg key saved */
sizeOfReturnBuffer = 200;
/* Get all the appropriate data from the registry */
if( RegQueryValueExA( lpData->This->dpl->hkCallbackKeyHack, clSubKey,
NULL, &returnType, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR( ": missing CommandLine registry data member\n" );
}
else
{
lpData->lpszCommandLine = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, returnBuffer );
}
sizeOfReturnBuffer = 200;
if( RegQueryValueExA( lpData->This->dpl->hkCallbackKeyHack, cdSubKey,
NULL, &returnType, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR( ": missing CurrentDirectory registry data member\n" );
}
else
{
lpData->lpszCurrentDirectory = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, returnBuffer );
}
sizeOfReturnBuffer = 200;
if( RegQueryValueExA( lpData->This->dpl->hkCallbackKeyHack, fileSubKey,
NULL, &returnType, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR( ": missing File registry data member\n" );
}
else
{
lpData->lpszFileName = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, returnBuffer );
}
sizeOfReturnBuffer = 200;
if( RegQueryValueExA( lpData->This->dpl->hkCallbackKeyHack, pathSubKey,
NULL, &returnType, returnBuffer,
&sizeOfReturnBuffer ) != ERROR_SUCCESS )
{
ERR( ": missing Path registry data member\n" );
}
else
{
lpData->lpszPath = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, returnBuffer );
}
return FALSE; /* No need to keep going as we found what we wanted */
}
return TRUE; /* Keep enumerating, haven't found the application yet */
}
/********************************************************************
*
* Starts an application and passes to it all the information to
......@@ -963,8 +1266,103 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication
LPDPLCONNECTION lpConn,
HANDLE hReceiveEvent )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
HRESULT hr;
RunApplicationEnumStruct enumData;
char temp[200];
STARTUPINFOA startupInfo;
PROCESS_INFORMATION newProcessInfo;
LPSTR appName;
FIXME( "(%p)->(0x%08lx,%p,%p,%p):semi stub\n", This, dwFlags, lpdwAppID, lpConn, hReceiveEvent );
if( dwFlags != 0 )
{
return DPERR_INVALIDPARAMS;
}
EnterCriticalSection( &This->unk->DPL_lock );
ZeroMemory( &enumData, sizeof( enumData ) );
enumData.This = This;
enumData.appGUID = lpConn->lpSessionDesc->guidApplication;
/* Our callback function will fill up the enumData structure with all the information
required to start a new process */
IDirectPlayLobby_EnumLocalApplications( iface, RunApplicationA_EnumLocalApplications,
(LPVOID)(&enumData), 0 );
/* First the application name */
strcpy( temp, enumData.lpszPath );
strcat( temp, "\\" );
strcat( temp, enumData.lpszFileName );
HeapFree( GetProcessHeap(), 0, enumData.lpszPath );
HeapFree( GetProcessHeap(), 0, enumData.lpszFileName );
appName = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, temp );
/* Now the command line */
strcat( temp, " " );
strcat( temp, enumData.lpszCommandLine );
HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine );
enumData.lpszCommandLine = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, temp );
ZeroMemory( &startupInfo, sizeof( startupInfo ) );
startupInfo.cb = sizeof( startupInfo );
/* FIXME: Should any fields be filled in? */
ZeroMemory( &newProcessInfo, sizeof( newProcessInfo ) );
#if !defined( WORKING_PROCESS_SUSPEND )
DPLAYX_AquireSemaphoreHack();
#endif
if( !CreateProcessA( appName,
enumData.lpszCommandLine,
NULL,
NULL,
FALSE,
CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_SUSPENDED, /* Creation Flags */
NULL,
enumData.lpszCurrentDirectory,
&startupInfo,
&newProcessInfo
)
)
{
FIXME( "Failed to create process for app %s\n", appName );
}
HeapFree( GetProcessHeap(), 0, appName );
HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine );
HeapFree( GetProcessHeap(), 0, enumData.lpszCurrentDirectory );
/* Reserve this global application id! */
if( !DPLAYX_CreateLobbyApplication( newProcessInfo.dwProcessId, hReceiveEvent ) )
{
ERR( "Unable to create global application data\n" );
}
hr = IDirectPlayLobby_SetConnectionSettings( iface, 0, newProcessInfo.dwProcessId, lpConn );
if( hr != DP_OK )
{
FIXME( "SetConnectionSettings failure 0x%08lx\n", 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
ResumeThread( newProcessInfo.dwThreadId );
#endif
LeaveCriticalSection( &This->unk->DPL_lock );
return DP_OK;
}
static HRESULT WINAPI IDirectPlayLobbyWImpl_RunApplication
......@@ -974,7 +1372,8 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_RunApplication
LPDPLCONNECTION lpConn,
HANDLE hReceiveEvent )
{
FIXME(":stub\n");
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
FIXME( "(%p)->(0x%08lx,%p,%p,%p):stub\n", This, dwFlags, lpdwAppID, lpConn, hReceiveEvent );
return DPERR_OUTOFMEMORY;
}
......@@ -1018,93 +1417,18 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_SetConnectionSettings
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
TRACE(": This=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p\n",
This, dwFlags, dwAppID, lpConn );
ICOM_THIS(IDirectPlayLobbyWImpl,iface);
HRESULT hr;
/* Paramater check */
if( dwFlags || !This || !lpConn )
{
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
}
/* See if there is a connection associated with this request.
* dwAppID == 0 indicates that this request isn't associated with a connection.
*/
if( dwAppID )
{
FIXME(": Connection dwAppID=%08lx given. Not implemented yet.\n",
dwAppID );
/* Need to add a check for this application Id...*/
return DPERR_NOTLOBBIED;
}
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
}
/* Need to investigate the lpConn->lpSessionDesc to figure out
* what type of session we need to join/create.
*/
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
{
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
}
TRACE("(%p)->(0x%08lx,0x%08lx,%p)\n", This, dwFlags, dwAppID, lpConn );
EnterCriticalSection( &This->unk->DPL_lock );
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
This->dpl->dwConnFlags = lpConn->dwFlags;
/* Copy LPDPSESSIONDESC2 struct - this is required */
memcpy( &This->dpl->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
if( lpConn->lpSessionDesc->sess.lpszSessionName )
This->dpl->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
else
This->dpl->sessionDesc.sess.lpszSessionName = NULL;
if( lpConn->lpSessionDesc->pass.lpszPassword )
This->dpl->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
else
This->dpl->sessionDesc.pass.lpszPassword = NULL;
This->dpl->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
This->dpl->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
if( lpConn->lpPlayerName )
{
memcpy( &This->dpl->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
if( lpConn->lpPlayerName->psn.lpszShortName )
This->dpl->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName );
if( lpConn->lpPlayerName->pln.lpszLongName )
This->dpl->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
}
memcpy( &This->dpl->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
This->dpl->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
memcpy( This->dpl->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
This->dpl->dwAddressSize = lpConn->dwAddressSize;
hr = DPLAYX_SetConnectionSettingsW( dwFlags, dwAppID, lpConn );
LeaveCriticalSection( &This->unk->DPL_lock );
return DP_OK;
return hr;
}
static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
......@@ -1113,93 +1437,18 @@ static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings
DWORD dwAppID,
LPDPLCONNECTION lpConn )
{
ICOM_THIS(IDirectPlayLobbyImpl,iface);
TRACE(": This=%p, dwFlags=%08lx, dwAppId=%08lx, lpConn=%p\n",
This, dwFlags, dwAppID, lpConn );
/* Paramater check */
if( dwFlags || !This || !lpConn )
{
ERR("invalid parameters.\n");
return DPERR_INVALIDPARAMS;
}
/* See if there is a connection associated with this request.
* dwAppID == 0 indicates that this request isn't associated with a connection.
*/
if( dwAppID )
{
FIXME(": Connection dwAppID=%08lx given. Not implemented yet.\n",
dwAppID );
/* Need to add a check for this application Id...*/
return DPERR_NOTLOBBIED;
}
if( lpConn->dwSize != sizeof(DPLCONNECTION) )
{
ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
lpConn->dwSize, sizeof( DPLCONNECTION ) );
return DPERR_INVALIDPARAMS;
}
ICOM_THIS(IDirectPlayLobbyAImpl,iface);
HRESULT hr;
/* Need to investigate the lpConn->lpSessionDesc to figure out
* what type of session we need to join/create.
*/
if( (!lpConn->lpSessionDesc ) ||
( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
)
{
ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
return DPERR_INVALIDPARAMS;
}
TRACE("(%p)->(0x%08lx,0x%08lx,%p)\n", This, dwFlags, dwAppID, lpConn );
EnterCriticalSection( &This->unk->DPL_lock );
/* Need to actually store the stuff here. Check if we've already allocated each field first. */
This->dpl->dwConnFlags = lpConn->dwFlags;
/* Copy LPDPSESSIONDESC2 struct - this is required */
memcpy( &This->dpl->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
/* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
This->dpl->sessionDesc.sess.lpszSessionNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionNameA );
else
This->dpl->sessionDesc.sess.lpszSessionNameA = NULL;
if( lpConn->lpSessionDesc->pass.lpszPasswordA )
This->dpl->sessionDesc.pass.lpszPasswordA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPasswordA );
else
This->dpl->sessionDesc.pass.lpszPasswordA = NULL;
This->dpl->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
This->dpl->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
/* Copy DPNAME struct - seems to be optional - check for existance first */
if( lpConn->lpPlayerName )
{
memcpy( &This->dpl->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
if( lpConn->lpPlayerName->psn.lpszShortNameA )
This->dpl->playerName.psn.lpszShortNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortNameA );
if( lpConn->lpPlayerName->pln.lpszLongNameA )
This->dpl->playerName.pln.lpszLongNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongNameA );
}
memcpy( &This->dpl->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
This->dpl->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
memcpy( This->dpl->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
This->dpl->dwAddressSize = lpConn->dwAddressSize;
hr = DPLAYX_SetConnectionSettingsA( dwFlags, dwAppID, lpConn );
LeaveCriticalSection( &This->unk->DPL_lock );
return DP_OK;
return hr;
}
/********************************************************************
......@@ -1228,7 +1477,7 @@ static HRESULT WINAPI IDirectPlayLobbyWImpl_SetLobbyMessageEvent
}
/* DPL 2 methods - well actuall only one */
/* DPL 2 methods */
/********************************************************************
*
......@@ -1242,8 +1491,7 @@ static HRESULT WINAPI IDirectPlayLobby2WImpl_CreateCompoundAddress
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
return DPL_CreateCompoundAddress( lpElements, dwElementCount, lpAddress, lpdwAddressSize, FALSE );
}
static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
......@@ -1253,8 +1501,185 @@ static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress
LPVOID lpAddress,
LPDWORD lpdwAddressSize )
{
FIXME(":stub\n");
return DPERR_OUTOFMEMORY;
return DPL_CreateCompoundAddress( lpElements, dwElementCount, lpAddress, lpdwAddressSize, TRUE );
}
static HRESULT DPL_CreateCompoundAddress
( LPCDPCOMPOUNDADDRESSELEMENT lpElements,
DWORD dwElementCount,
LPVOID lpAddress,
LPDWORD lpdwAddressSize,
BOOL bAnsiInterface )
{
DWORD dwSizeRequired = 0;
DWORD dwElements;
LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements = lpElements;
TRACE("(%p,0x%08lx,%p,%p)\n", lpElements, dwElementCount, lpAddress, lpdwAddressSize );
/* Parameter check */
if( ( lpElements == NULL ) ||
( dwElementCount == 0 ) /* FIXME: Not sure if this is a failure case */
)
{
return DPERR_INVALIDPARAMS;
}
/* Add the total size chunk */
dwSizeRequired += sizeof( DPADDRESS ) + sizeof( DWORD );
/* Calculate the size of the buffer required */
for ( dwElements = dwElementCount; dwElements > 0; --dwElements, ++lpElements )
{
if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ServiceProvider ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_LobbyProvider ) )
)
{
dwSizeRequired += sizeof( DPADDRESS ) + sizeof( GUID );
}
else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Phone ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_Modem ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_INet ) )
)
{
if( !bAnsiInterface )
{
ERR( "Ansi GUIDs used for unicode interface\n" );
return DPERR_INVALIDFLAGS;
}
dwSizeRequired += sizeof( DPADDRESS ) + lpElements->dwDataSize;
}
else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_PhoneW ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_ModemW ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetW ) )
)
{
if( bAnsiInterface )
{
ERR( "Unicode GUIDs used for ansi interface\n" );
return DPERR_INVALIDFLAGS;
}
FIXME( "Right size for unicode interface?\n" );
dwSizeRequired += sizeof( DPADDRESS ) + lpElements->dwDataSize * sizeof( WCHAR );
}
else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetPort ) )
{
dwSizeRequired += sizeof( DPADDRESS ) + sizeof( WORD );
}
else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ComPort ) )
{
FIXME( "Right size for unicode interface?\n" );
dwSizeRequired += sizeof( DPADDRESS ) + sizeof( DPCOMPORTADDRESS ); /* FIXME: Right size? */
}
else
{
char lpGUIDString[51];
WINE_StringFromCLSID( &lpElements->guidDataType, &lpGUIDString[0] );
ERR( "Unknown GUID %s\n", &lpGUIDString[0] );
return DPERR_INVALIDFLAGS;
}
}
/* The user wants to know how big a buffer to allocate for us */
if( ( lpAddress == NULL ) ||
( *lpdwAddressSize < dwSizeRequired )
)
{
*lpdwAddressSize = dwSizeRequired;
return DPERR_BUFFERTOOSMALL;
}
/* Add the total size chunk */
{
LPDPADDRESS lpdpAddress = (LPDPADDRESS)lpAddress;
lpdpAddress->guidDataType = DPAID_TotalSize;
lpdpAddress->dwDataSize = sizeof( DWORD );
lpAddress += sizeof( DPADDRESS );
*(LPDWORD)lpAddress = dwSizeRequired;
lpAddress += sizeof( DWORD );
}
/* Calculate the size of the buffer required */
for( dwElements = dwElementCount, lpElements = lpOrigElements;
dwElements > 0;
--dwElements, ++lpElements )
{
if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ServiceProvider ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_LobbyProvider ) )
)
{
LPDPADDRESS lpdpAddress = (LPDPADDRESS)lpAddress;
lpdpAddress->guidDataType = lpElements->guidDataType;
lpdpAddress->dwDataSize = sizeof( GUID );
lpAddress += sizeof( DPADDRESS );
*((LPGUID)lpAddress) = *((LPGUID)lpElements->lpData);
lpAddress += sizeof( GUID );
}
else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Phone ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_Modem ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_INet ) )
)
{
LPDPADDRESS lpdpAddress = (LPDPADDRESS)lpAddress;
lpdpAddress->guidDataType = lpElements->guidDataType;
lpdpAddress->dwDataSize = lpElements->dwDataSize;
lpAddress += sizeof( DPADDRESS );
lstrcpynA( (LPSTR)lpAddress,
(LPCSTR)lpElements->lpData,
lpElements->dwDataSize );
lpAddress += lpElements->dwDataSize;
}
else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_PhoneW ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_ModemW ) ) ||
( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetW ) )
)
{
LPDPADDRESS lpdpAddress = (LPDPADDRESS)lpAddress;
lpdpAddress->guidDataType = lpElements->guidDataType;
lpdpAddress->dwDataSize = lpElements->dwDataSize;
lpAddress += sizeof( DPADDRESS );
lstrcpynW( (LPWSTR)lpAddress,
(LPCWSTR)lpElements->lpData,
lpElements->dwDataSize );
lpAddress += lpElements->dwDataSize * sizeof( WCHAR );
}
else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetPort ) )
{
LPDPADDRESS lpdpAddress = (LPDPADDRESS)lpAddress;
lpdpAddress->guidDataType = lpElements->guidDataType;
lpdpAddress->dwDataSize = lpElements->dwDataSize;
lpAddress += sizeof( DPADDRESS );
*((LPWORD)lpAddress) = *((LPWORD)lpElements->lpData);
lpAddress += sizeof( WORD );
}
else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ComPort ) )
{
LPDPADDRESS lpdpAddress = (LPDPADDRESS)lpAddress;
lpdpAddress->guidDataType = lpElements->guidDataType;
lpdpAddress->dwDataSize = lpElements->dwDataSize;
lpAddress += sizeof( DPADDRESS );
memcpy( lpAddress, lpElements->lpData, sizeof( DPADDRESS ) );
lpAddress += sizeof( DPADDRESS );
}
}
return DP_OK;
}
/* DPL 3 methods */
......@@ -1332,7 +1757,7 @@ static struct ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyAVT =
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobbyAImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(AddRef)IDirectPlayLobbyImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
IDirectPlayLobbyAImpl_Connect,
......@@ -1363,7 +1788,7 @@ static ICOM_VTABLE(IDirectPlayLobby) directPlayLobbyWVT =
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobbyW_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(AddRef)IDirectPlayLobbyImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
IDirectPlayLobbyWImpl_Connect,
......@@ -1393,7 +1818,7 @@ static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2AVT =
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobby2AImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(AddRef)IDirectPlayLobbyImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
XCAST(Connect)IDirectPlayLobbyAImpl_Connect,
......@@ -1425,7 +1850,7 @@ static ICOM_VTABLE(IDirectPlayLobby2) directPlayLobby2WVT =
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobby2WImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(AddRef)IDirectPlayLobbyImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
XCAST(Connect)IDirectPlayLobbyWImpl_Connect,
......@@ -1457,7 +1882,7 @@ static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3AVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobby3AImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(AddRef)IDirectPlayLobbyImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
XCAST(Connect)IDirectPlayLobbyAImpl_Connect,
......@@ -1494,7 +1919,7 @@ static ICOM_VTABLE(IDirectPlayLobby3) directPlayLobby3WVT =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IDirectPlayLobby3WImpl_QueryInterface,
XCAST(AddRef)IDirectPlayLobbyAImpl_AddRef,
XCAST(AddRef)IDirectPlayLobbyImpl_AddRef,
XCAST(Release)IDirectPlayLobbyAImpl_Release,
XCAST(Connect)IDirectPlayLobbyWImpl_Connect,
......
......@@ -32,34 +32,42 @@ TODO:
- (done) Create and move to correct dll directories (dplay and dplayx)
- (done) Implement dplay in terms of dplayx
- (started) Need a better internal implementation for the objects which scales and
preferably doesn't involve casting structures
preferably doesn't involve casting structures (dplobby done)
- (started) More generic initialization and destruction helper methods based off
the chosen internal implementation
- How to deal with all the incorrect interfaces for IUnknown methods. The standard
wine macros are incorrect in that they always give IUnknown* rather than DirectPlayLobby2A
for instance. Are we forced to cast?
- Implement a lib main for the dplayx dll
the chosen internal implementation (dplobby done)
- Use only windows routines where an equivalent is available
- (done) Fix wine dplay.h and dplobby.h header files to allow apps to create the ansi versions
- (started) Port some WineLib test programs using sdk programs (both C and C++ progs)
- (done) Implement a lib main for the dplayx dll (required for RunApplication, etc.)
- Figure out how to share the global memory correctly
- Ensure that all dll stubs are present and the ordinals are correct
- Implementation of functionality
- (started)Implementation of functionality
- Addition of DirectX 7.0 functionality for direct play (try to catch that moving train)
- bug fixes ;)
- Implement some WineLib test programs using sdk programs as a skeleton
Programs to make work:
- lserver.exe (from sdk)
- override.exe (from sdk)
- dpchat.exe (from sdk)
- duel.exe (from sdk)
- dplaunch.exe (from sdk)
Next API to implement on a per program basis:
override.exe
- IDirectPlay3AImp_EnumConnections
- fixme:dplay:DirectPlayCreate Modem binding not supported yet
- DirectPlay3AImpl_InitializeConnection
- DirectPlay2AImpl_Open
- ?
dplaunch.exe
- IDirectPlayLobbyAImpl_EnumLocalApplications
- IDirectPlayLobby2AImpl_CreateCompoundAddress
- IDirectPlayLobbyAImpl_RunApplication
- ?
lserver.exe
- IDirectPlayLobby2WImpl_Connect
- fixme:dplay:DirectPlayCreate Modem binding not supported yet
- IDirectPlay3WImpl_CreatePlayer
- IDirectPlay3WImpl_CreateGroup
- IDirectPlay3WImpl_SetGroupData
......@@ -67,12 +75,19 @@ Next API to implement on a per program basis:
- ?
bellhop.exe
- DirectPlay3AImpl_EnumConnections
- DirectPlay3AImpl_EnumConnections (lobby applications)
- ?
dpslots.exe
- IDirectPlayLobbyAImpl_SetConnectionSettings
- IDirectPlayAImpl_EnumConnections
- IDirectPlayLobby3AImpl_ConnectEx
- ?
Other TODO:
- look at problem with parsing the resource file for dplaunch. wrc problem?
- I should be getting the dialog box to come up for dpchat when something is selected
Call OLE32.7: CoCreateInstance(010017f0,00000000,00000001,010017e0,010094b4) ret=01002f38 fs=0237
Call ADVAPI32.188: RegOpenKeyExA(80000002,5e08dd90 "Software\\Microsoft\\DirectPlay\\Compatibility",00000000,00020019,40e7f49c) ret=5e0b6e5a fs=0237
Peter Hunnisett - hunnise@nortelnetworks.com
......@@ -384,6 +384,8 @@ typedef BOOL (CALLBACK* LPDPENUMSESSIONSCALLBACK2)(
DWORD dwFlags,
LPVOID lpContext );
#define DPESC_TIMEDOUT 0x00000001
#include "poppack.h"
/*****************************************************************************
......@@ -449,7 +451,7 @@ ICOM_DEFINE(IDirectPlay,IUnknown)
/*****************************************************************************
* IDirectPlay2 interface
* IDirectPlay2 and IDirectPlay2A interface
*/
#define ICOM_INTERFACE IDirectPlay2
#define IDirectPlay2_METHODS \
......@@ -525,7 +527,7 @@ ICOM_DEFINE(IDirectPlay2,IUnknown)
/*****************************************************************************
* IDirectPlay3 interface
* IDirectPlay3 and IDirectPlay3A interface
*/
#define ICOM_INTERFACE IDirectPlay3
#define IDirectPlay3_METHODS \
......@@ -602,11 +604,7 @@ ICOM_DEFINE(IDirectPlay3,IDirectPlay2)
#define IDirectPlay3_GetPlayerFlags(p,a,b) ICOM_CALL2(GetPlayerFlags,p,a,b)
/*****************************************************************************
* IDirectPlay4 interface - this is also known as IDirectPlayX. Apparently people
* are realizing that declaring all the darn interfaces as IDirectPlay{2,3,...} is
* just plain dumb. It's now going to be just IDirectPlayX since they're just macros
* anyways. That's good because I'm tired of typing these entries :)
* The compiler should catch any problems with invocation of invalid method :)
* IDirectPlay4 and IDirectPlay4A interface
*/
#define ICOM_INTERFACE IDirectPlay4
#define IDirectPlay4_METHODS \
......@@ -617,11 +615,10 @@ ICOM_DEFINE(IDirectPlay3,IDirectPlay2)
ICOM_METHOD2( HRESULT, CancelMessage, DWORD,, DWORD, ) \
ICOM_METHOD3( HRESULT, CancelPriority, DWORD,, DWORD,, DWORD, )
#define IDirectPlay4_IMETHODS
#define IDirectPlay4_IMETHODS \
IDirectPlay3_IMETHODS \
IDirectPlay4_METHODS
ICOM_DEFINE(IDirectPlay4,IDirectPlay3)
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
......@@ -682,6 +679,7 @@ ICOM_DEFINE(IDirectPlay4,IDirectPlay3)
#define IDirectPlayX_CancelMessage(p,a,b) ICOM_CALL2(CancelMessage,a,b)
#define IDirectPlayX_CancelPriority(p,a,b,c) ICOM_CALL3(CancelPriority,a,b,c)
/* For DirectPlay::EnumConnections */
#define DPCONNECTION_DIRECTPLAY 0x00000001
#define DPCONNECTION_DIRECTPLAYLOBBY 0x00000002
......
......@@ -34,7 +34,7 @@ DEFINE_GUID(IID_IDirectPlayLobby3, 0x2db72490, 0x652c, 0x11d1, 0xa7, 0xa8, 0x0,
typedef struct IDirectPlayLobby3 IDirectPlayLobby3, *LPDIRECTPLAYLOBBY3;
DEFINE_GUID(IID_IDirectPlayLobby3A, 0x2db72491, 0x652c, 0x11d1, 0xa7, 0xa8, 0x0, 0x0, 0xf8, 0x3, 0xab, 0xfc);
typedef struct IDirectPlayLobby3A IDirectPlayLobby3A, *LPDIRECTPLAYLOBBY3A;
typedef struct IDirectPlayLobby3 IDirectPlayLobby3A, *LPDIRECTPLAYLOBBY3A;
/*****************************************************************************
......@@ -223,7 +223,7 @@ DEFINE_GUID(DPAID_INet, 0xc4a54da0, 0xe0af, 0x11cf, 0x9c, 0x4e, 0x0, 0xa0, 0xc9,
DEFINE_GUID(DPAID_INetW, 0xe63232a0, 0x9dbf, 0x11d0, 0x9c, 0xc1, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
/* DPAID_INetPort {E4524541-8EA5-11d1-8A96-006097B01411}
* Chunk purpose: Chunk is a port number used for creating TCP and UDP sockets.
* Chunk purpose: Chunk is a port number used for creating TCP and UDP sockets. (WORD)
*/
DEFINE_GUID(DPAID_INetPort, 0xe4524541, 0x8ea5, 0x11d1, 0x8a, 0x96, 0x0, 0x60, 0x97, 0xb0, 0x14, 0x11);
......@@ -331,8 +331,8 @@ typedef struct tagDPAPPLICATIONDESC
extern HRESULT WINAPI DirectPlayLobbyCreateW(LPGUID, LPDIRECTPLAYLOBBY *, IUnknown *, LPVOID, DWORD );
extern HRESULT WINAPI DirectPlayLobbyCreateA(LPGUID, LPDIRECTPLAYLOBBYA *, IUnknown *, LPVOID, DWORD );
extern HRESULT WINAPI DirectPlayLobbyCreateW(LPGUID, LPDIRECTPLAYLOBBY*, IUnknown*, LPVOID, DWORD );
extern HRESULT WINAPI DirectPlayLobbyCreateA(LPGUID, LPDIRECTPLAYLOBBYA*, IUnknown*, LPVOID, DWORD );
......@@ -355,7 +355,7 @@ typedef BOOL (CALLBACK* LPDPLENUMLOCALAPPLICATIONSCALLBACK)(
#include "poppack.h"
/*****************************************************************************
* IDirectPlayLobby interface
* IDirectPlayLobby and IDirectPlayLobbyA interface
*/
#define ICOM_INTERFACE IDirectPlayLobby
#define IDirectPlayLobby_METHODS \
......@@ -377,7 +377,7 @@ ICOM_DEFINE(IDirectPlayLobby,IUnknown)
#undef ICOM_INTERFACE
/*****************************************************************************
* IDirectPlayLobby2 interface
* IDirectPlayLobby2 and IDirectPlayLobby2A interface
*/
#define ICOM_INTERFACE IDirectPlayLobby2
#define IDirectPlayLobby2_METHODS \
......@@ -389,9 +389,8 @@ ICOM_DEFINE(IDirectPlayLobby2,IDirectPlayLobby)
#undef ICOM_INTERFACE
/*****************************************************************************
* IDirectPlayLobby3 interface
* IDirectPlayLobby3 and IDirectPlayLobby3A interface
*/
#define ICOM_INTERFACE IDirectPlayLobby3
#define IDirectPlayLobby3_METHODS \
ICOM_METHOD4( HRESULT, ConnectEx, DWORD,, REFIID,, LPVOID *,, IUnknown *,) \
......@@ -405,11 +404,9 @@ ICOM_DEFINE(IDirectPlayLobby2,IDirectPlayLobby)
ICOM_DEFINE(IDirectPlayLobby3,IDirectPlayLobby2)
#undef ICOM_INTERFACE
/*** IUnknown methods ***/
#define IDirectPlayLobby_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
#define IDirectPlayLobby_AddRef(p) ICOM_CALL (AddRef,p)
#define IDirectPlayLobby_Release(p) ICOM_CALL (Release,p)
/*** IDirectPlayLobby methods ***/
#define IDirectPlayLobby_Connect(p,a,b,c) ICOM_CALL3(Connect,p,a,b,c)
#define IDirectPlayLobby_ConnectEx(p,a,b,c,d) ICOM_CALL4(ConnectEx,p,a,b,c,d)
#define IDirectPlayLobby_CreateAddress(p,a,b,c,d,e,f) ICOM_CALL6(CreateAddress,p,a,b,c,d,e,f)
......
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