- 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
This commit is contained in:
parent
a69bc02958
commit
88d89f93ea
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1579,13 +1641,11 @@ HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
|
|||
LPVOID lpContext )
|
||||
{
|
||||
|
||||
HKEY hkResult;
|
||||
HKEY hkResult;
|
||||
LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
|
||||
LPSTR guidDataSubKey = "Guid";
|
||||
LPSTR majVerDataSubKey = "dwReserved1";
|
||||
LPSTR minVerDataSubKey = "dwReserved0";
|
||||
DWORD dwIndex, sizeOfSubKeyName=50;
|
||||
char subKeyName[51];
|
||||
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 );
|
||||
|
||||
/* 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];
|
||||
|
||||
WINE_StringFromCLSID( lpGUID, &lpGUIDString[0] );
|
||||
|
||||
TRACE("lpGUID=%p lplpDP=%p pUnk=%p\n", lpGUID,lplpDP,pUnk);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name dplayx
|
||||
type win32
|
||||
init DPLAYX_LibMain
|
||||
|
||||
1 stdcall DirectPlayCreate(ptr ptr ptr ptr) DirectPlayCreate
|
||||
2 stdcall DirectPlayEnumerateA(ptr ptr) DirectPlayEnumerateA
|
||||
|
|
|
@ -0,0 +1,532 @@
|
|||
/* 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;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
#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 */
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue