Commit ef6dca5c authored by Peter Hunnisett's avatar Peter Hunnisett Committed by Alexandre Julliard

- Implemented loading and initialization of service providers

- Created service provider COM object - Lots of dplay/dplobby implementation/fixes - Clean up of ole/guid.c
parent 217a682b
......@@ -9,6 +9,7 @@ IMPORTS = ole32 advapi32 kernel32
C_SRCS = \
dpclassfactory.c \
dplay.c \
dplaysp.c \
dplayx_global.c \
dplayx_main.c \
dplayx_messages.c \
......
......@@ -39,7 +39,6 @@ static ULONG WINAPI DP_and_DPL_Release(LPCLASSFACTORY iface) {
return --(This->ref);
}
/* Not the most efficient implementation, but it's simple */
static HRESULT WINAPI DP_and_DPL_CreateInstance(
LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
) {
......@@ -47,12 +46,11 @@ static HRESULT WINAPI DP_and_DPL_CreateInstance(
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
/* FIXME: reuse already created DP/DPL object if present? */
if ( directPlayLobby_QueryInterface( riid, ppobj ) == S_OK )
if ( DPL_CreateInterface( riid, ppobj ) == S_OK )
{
return S_OK;
}
else if ( directPlay_QueryInterface( riid, ppobj ) == S_OK )
else if ( DP_CreateInterface( riid, ppobj ) == S_OK )
{
return S_OK;
}
......@@ -110,13 +108,3 @@ DWORD WINAPI DPLAYX_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
ERR("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
return CLASS_E_CLASSNOTAVAILABLE;
}
/***********************************************************************
* DllCanUnloadNow (DPLAYX.@)
*/
HRESULT WINAPI DPLAYX_DllCanUnloadNow(void)
{
FIXME("(void): stub\n");
return S_FALSE;
}
......@@ -2,7 +2,12 @@
#ifndef __WINE_DPINIT_H
#define __WINE_DPINIT_H
extern HRESULT directPlay_QueryInterface( REFIID riid, LPVOID* ppvObj );
extern HRESULT directPlayLobby_QueryInterface( REFIID riid, LPVOID* ppvObj );
#include "wtypes.h"
#include "dplay_global.h"
extern HRESULT DP_CreateInterface( REFIID riid, LPVOID* ppvObj );
extern HRESULT DPL_CreateInterface( REFIID riid, LPVOID* ppvObj );
extern HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj,
IDirectPlay2Impl* dp );
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef __WINE_DPLAY_GLOBAL_INCLUDED
#define __WINE_DPLAY_GLOBAL_INCLUDED
#include "dplaysp.h"
#include "dplayx_queue.h"
extern HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
LPCVOID lpAddress, DWORD dwAddressSize,
LPVOID lpContext );
extern DWORD DP_CalcSessionDescSize( LPCDPSESSIONDESC2 lpSessDesc, BOOL bAnsi );
/*****************************************************************************
* Predeclare the interface implementation structures
*/
typedef struct IDirectPlay2Impl IDirectPlay2AImpl;
typedef struct IDirectPlay2Impl IDirectPlay2Impl;
typedef struct IDirectPlay3Impl IDirectPlay3AImpl;
typedef struct IDirectPlay3Impl IDirectPlay3Impl;
typedef struct IDirectPlay4Impl IDirectPlay4AImpl;
typedef struct IDirectPlay4Impl IDirectPlay4Impl;
typedef struct tagDirectPlayIUnknownData
{
ULONG ulObjRef;
CRITICAL_SECTION DP_lock;
} DirectPlayIUnknownData;
typedef struct tagEnumSessionAsyncCallbackData
{
LPSPINITDATA lpSpData;
GUID requestGuid;
DWORD dwEnumSessionFlags;
DWORD dwTimeout;
HANDLE hSuicideRequest;
} EnumSessionAsyncCallbackData;
struct PlayerData
{
/* Individual player information */
DPID dpid;
DPNAME name;
HANDLE hEvent;
/* View of local data */
LPVOID lpLocalData;
DWORD dwLocalDataSize;
/* View of remote data */
LPVOID lpRemoteData;
DWORD dwRemoteDataSize;
DWORD dwFlags; /* Special remarks about the type of player */
};
typedef struct PlayerData* lpPlayerData;
struct PlayerList
{
DPQ_ENTRY(PlayerList) players;
lpPlayerData lpPData;
};
typedef struct PlayerList* lpPlayerList;
struct GroupData
{
/* Internal information */
DPID parent; /* If parent == 0 it's a top level group */
DPQ_HEAD(GroupList) groups; /* A group has [0..n] groups */
DPQ_HEAD(PlayerList) players; /* A group has [0..n] players */
DPID idGroupOwner; /* ID of player who owns the group */
DWORD dwFlags; /* Flags describing anything special about the group */
DPID dpid;
DPNAME name;
/* View of local data */
LPVOID lpLocalData;
DWORD dwLocalDataSize;
/* View of remote data */
LPVOID lpRemoteData;
DWORD dwRemoteDataSize;
};
typedef struct GroupData GroupData;
typedef struct GroupData* lpGroupData;
struct GroupList
{
DPQ_ENTRY(GroupList) groups;
lpGroupData lpGData;
};
typedef struct GroupList* lpGroupList;
struct DPMSG
{
DPQ_ENTRY( DPMSG ) msgs;
DPMSG_GENERIC* msg;
};
typedef struct DPMSG* LPDPMSG;
/* Contains all dp1 and dp2 data members */
typedef struct tagDirectPlay2Data
{
BOOL bConnectionOpen;
/* For async EnumSessions requests */
HANDLE hEnumSessionThread;
HANDLE hKillEnumSessionThreadEvent;
LPVOID lpNameServerData; /* DPlay interface doesn't know contents */
BOOL bHostInterface; /* Did this interface create the session */
#if 0
DPQ_HEAD(PlayerList) players; /* All players w/ interface */
DPQ_HEAD(GroupList) groups; /* All main groups w/ interface */
#else
lpGroupData lpSysGroup; /* System group with _everything_ in it */
#endif
LPDPSESSIONDESC2 lpSessionDesc;
/* I/O Msg queues */
DPQ_HEAD( DPMSG ) receiveMsgs; /* Msg receive queue */
DPQ_HEAD( DPMSG ) sendMsgs; /* Msg send pending queue */
/* Information about the service provider active on this connection */
SPINITDATA spData;
/* Our service provider */
HMODULE hServiceProvider;
BOOL bConnectionInitialized;
} DirectPlay2Data;
typedef struct tagDirectPlay3Data
{
BOOL dummy;
} DirectPlay3Data;
typedef struct tagDirectPlay4Data
{
BOOL dummy;
} DirectPlay4Data;
#define DP_IMPL_FIELDS \
ULONG ulInterfaceRef; \
DirectPlayIUnknownData* unk; \
DirectPlay2Data* dp2; \
DirectPlay3Data* dp3; \
DirectPlay4Data* dp4;
struct IDirectPlay2Impl
{
ICOM_VFIELD(IDirectPlay2);
DP_IMPL_FIELDS
};
struct IDirectPlay3Impl
{
ICOM_VFIELD(IDirectPlay3);
DP_IMPL_FIELDS
};
struct IDirectPlay4Impl
{
ICOM_VFIELD(IDirectPlay4);
DP_IMPL_FIELDS
};
/* Forward declarations of virtual tables */
extern ICOM_VTABLE(IDirectPlay2) directPlay2AVT;
extern ICOM_VTABLE(IDirectPlay3) directPlay3AVT;
extern ICOM_VTABLE(IDirectPlay4) directPlay4AVT;
extern ICOM_VTABLE(IDirectPlay2) directPlay2WVT;
extern ICOM_VTABLE(IDirectPlay3) directPlay3WVT;
extern ICOM_VTABLE(IDirectPlay4) directPlay4WVT;
#endif /* __WINE_DPLAY_GLOBAL_INCLUDED */
......@@ -9,12 +9,10 @@ BOOL DPLAYX_DestructData(void);
HRESULT DPLAYX_GetConnectionSettingsA ( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize,
LPBOOL lpbSendHaveReadMessage );
LPDWORD lpdwDataSize );
HRESULT DPLAYX_GetConnectionSettingsW ( DWORD dwAppID,
LPVOID lpData,
LPDWORD lpdwDataSize,
LPBOOL lpbSendHaveReadMessage );
LPDWORD lpdwDataSize );
HRESULT DPLAYX_SetConnectionSettingsA ( DWORD dwFlags,
DWORD dwAppID,
......@@ -23,16 +21,33 @@ HRESULT DPLAYX_SetConnectionSettingsW ( DWORD dwFlags,
DWORD dwAppID,
LPDPLCONNECTION lpConn );
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent );
BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID );
BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID );
BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait );
BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void);
BOOL DPLAYX_SetLobbyHandles( DWORD dwAppID,
HANDLE hStart, HANDLE hDeath, HANDLE hConnRead );
BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart,
LPHANDLE lphDeath,
LPHANDLE lphConnRead, BOOL bClearSetHandles );
LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateLocalSession( UINT* index );
BOOL DPLAYX_CopyLocalSession( UINT* index, LPDPSESSIONDESC2 lpsd );
void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd );
BOOL DPLAYX_SetLobbyMsgThreadId( DWORD dwAppId, DWORD dwThreadId );
/* FIXME: This should not be here */
LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size );
void DPLAYX_PrivHeapFree( LPVOID addr );
LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str );
LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str );
/* FIXME: End shared data alloc which should be local */
/* Convert a DP or DPL HRESULT code into a string for human consumption */
LPCSTR DPLAYX_HresultToString( HRESULT hr );
......
......@@ -5,19 +5,24 @@
*
* contact <hunnise@nortelnetworks.com>
*/
#include "winerror.h"
#include "winbase.h"
#include "debugtools.h"
#include "initguid.h"
#include "dplay.h"
#include "dplobby.h"
#include "initguid.h" /* To define the GUIDs */
#include "dplaysp.h"
#include "dplayx_global.h"
DEFAULT_DEBUG_CHANNEL(dplay);
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
static DWORD DPLAYX_dwProcessesAttached = 0;
/* This is a globally exported variable at ordinal 6 of DPLAYX.DLL */
DWORD gdwDPlaySPRefCount = 0; /* FIXME: Should it be initialized here? */
BOOL WINAPI DPLAYX_LibMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
......@@ -59,3 +64,20 @@ BOOL WINAPI DPLAYX_LibMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReser
return TRUE;
}
/***********************************************************************
* DllCanUnloadNow (DPLAYX.10)
*/
HRESULT WINAPI DPLAYX_DllCanUnloadNow(void)
{
HRESULT hr = ( gdwDPlaySPRefCount > 0 ) ? S_FALSE : S_OK;
/* FIXME: Should I be putting a check in for class factory objects
* as well
*/
TRACE( ": returning 0x%08lx\n", hr );
return hr;
}
......@@ -9,48 +9,130 @@
#include "winbase.h"
#include "debugtools.h"
#include "wingdi.h"
#include "winuser.h"
#include "dplayx_messages.h"
DEFAULT_DEBUG_CHANNEL(dplay)
typedef struct tagMSGTHREADINFO
{
HANDLE hStart;
HANDLE hDeath;
HANDLE hSettingRead;
HANDLE hNotifyEvent;
} MSGTHREADINFO, *LPMSGTHREADINFO;
static DWORD CALLBACK DPLAYX_MSG_ThreadMain( LPVOID lpContext );
static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext );
/* Create the message reception thread to allow the application to receive
* asynchronous message reception
*/
DWORD CreateMessageReceptionThread( HANDLE hNotifyEvent )
DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
HANDLE hDeath, HANDLE hConnRead )
{
DWORD dwMsgThreadId;
DWORD dwMsgThreadId;
LPMSGTHREADINFO lpThreadInfo;
if( !DuplicateHandle( 0, hNotifyEvent, 0, NULL, 0, FALSE, 0 ) )
lpThreadInfo = HeapAlloc( GetProcessHeap(), 0, sizeof( *lpThreadInfo ) );
if( lpThreadInfo == NULL )
{
ERR( "Unable to duplicate event handle\n" );
return 0;
}
/* FIXME: Should most likely store that thread handle */
CreateThread( NULL, /* Security attribs */
0, /* Stack */
DPLAYX_MSG_ThreadMain, /* Msg reception function */
(LPVOID)hNotifyEvent, /* Msg reception function parameter */
0, /* Flags */
&dwMsgThreadId /* Updated with thread id */
);
/* The notify event may or may not exist. Depends if async comm or not */
if( hNotifyEvent &&
!DuplicateHandle( GetCurrentProcess(), hNotifyEvent,
GetCurrentProcess(), &lpThreadInfo->hNotifyEvent,
0, FALSE, DUPLICATE_SAME_ACCESS ) )
{
ERR( "Unable to duplicate event handle\n" );
goto error;
}
/* These 3 handles don't need to be duplicated because we don't keep a
* reference to them where they're created. They're created specifically
* for the message thread
*/
lpThreadInfo->hStart = hStart;
lpThreadInfo->hDeath = hDeath;
lpThreadInfo->hSettingRead = hConnRead;
if( !CreateThread( NULL, /* Security attribs */
0, /* Stack */
DPL_MSG_ThreadMain, /* Msg reception function */
lpThreadInfo, /* Msg reception func parameter */
0, /* Flags */
&dwMsgThreadId /* Updated with thread id */
)
)
{
ERR( "Unable to create msg thread\n" );
goto error;
}
/* FIXME: Should I be closing the handle to the thread or does that
terminate the thread? */
return dwMsgThreadId;
error:
HeapFree( GetProcessHeap(), 0, lpThreadInfo );
return 0;
}
static DWORD CALLBACK DPLAYX_MSG_ThreadMain( LPVOID lpContext )
static DWORD CALLBACK DPL_MSG_ThreadMain( LPVOID lpContext )
{
HANDLE hMsgEvent = (HANDLE)lpContext;
LPMSGTHREADINFO lpThreadInfo = (LPMSGTHREADINFO)lpContext;
DWORD dwWaitResult;
TRACE( "Msg thread created. Waiting on app startup\n" );
/* Wait to ensure that the lobby application is started w/ 1 min timeout */
dwWaitResult = WaitForSingleObject( lpThreadInfo->hStart, 10000 /* 10 sec */ );
if( dwWaitResult == WAIT_TIMEOUT )
{
FIXME( "Should signal app/wait creation failure (0x%08lx)\n", dwWaitResult );
goto end_of_thread;
}
/* Close this handle as it's not needed anymore */
CloseHandle( lpThreadInfo->hStart );
lpThreadInfo->hStart = 0;
/* Wait until the lobby knows what it is */
dwWaitResult = WaitForSingleObject( lpThreadInfo->hSettingRead, INFINITE );
if( dwWaitResult == WAIT_TIMEOUT )
{
ERR( "App Read connection setting timeout fail (0x%08lx)\n", dwWaitResult );
}
/* Close this handle as it's not needed anymore */
CloseHandle( lpThreadInfo->hSettingRead );
lpThreadInfo->hSettingRead = 0;
TRACE( "App created && intialized starting main message reception loop\n" );
for ( ;; )
{
FIXME( "Ho Hum. Msg thread with nothing to do on handle %u\n", hMsgEvent );
MSG lobbyMsg;
#ifdef STRICT
HANDLE hNullHandle = NULL;
#else
HANDLE hNullHandle = 0;
#endif
SleepEx( 10000, FALSE ); /* 10 secs */
GetMessageW( &lobbyMsg, hNullHandle, 0, 0 );
}
CloseHandle( hMsgEvent );
end_of_thread:
TRACE( "Msg thread exiting!\n" );
HeapFree( GetProcessHeap(), 0, lpThreadInfo );
return 0;
}
#ifndef __WINE_DPLAYX_MESSAGES
#define __WINE_DPLAYX_MESSAGES
#ifndef __WINE_DPLAYX_MESSAGES__
#define __WINE_DPLAYX_MESSAGES__
#include "windef.h"
#include "dplay.h"
#include "rpc.h" /* For GUID */
DWORD CreateMessageReceptionThread( HANDLE hNotifyEvent );
DWORD CreateLobbyMessageReceptionThread( HANDLE hNotifyEvent, HANDLE hStart,
HANDLE hDeath, HANDLE hConnRead );
/* Message types etc. */
#include "pshpack1.h"
/* Non provided messages for DPLAY - guess work which may be wrong :( */
#define DPMSGCMD_ENUMSESSIONSREPLY 1
#define DPMSGCMD_ENUMSESSIONSREQUEST 2
#define DPMSGCMD_GETSETNAMETABLE 3 /* Request info from NS about
existing players/groups etc. Is
also used for reply */
#define DPMSGCMD_REQUESTNEWPLAYERID 5
#define DPMSGCMD_NEWPLAYERIDREPLY 7
#define DPMSGCMD_CREATESESSION 8
#define DPMSGCMD_CREATENEWPLAYER 9
#define DPMSGCMD_SYSTEMMESSAGE 10
#define DPMSGCMD_DELETEGROUP 12
#define DPMSGCMD_ENUMGROUPS 17
/* This is what DP 6 defines it as. Don't know what it means. All messages
* defined below are DPMSGVER_DP6.
*/
#define DPMSGVER_DP6 11
/* MAGIC number at the start of all dplay packets ("play" in ASCII) */
#define DPMSGMAGIC_DPLAYMSG 0x79616c70
/* All messages sent from the system are sent with this at the beginning of
* the message.
*/
/* Size is 4 bytes */
typedef struct tagDPMSG_SENDENVELOPE
{
DWORD dwMagic;
WORD wCommandId;
WORD wVersion;
} DPMSG_SENDENVELOPE, *LPDPMSG_SENDENVELOPE;
typedef const DPMSG_SENDENVELOPE* LPCDPMSG_SENDENVELOPE;
typedef struct tagDPMSG_SYSMSGENVELOPE
{
DWORD dwPlayerFrom;
DWORD dwPlayerTo;
} DPMSG_SYSMSGENVELOPE, *LPDPMSG_SYSMSGENVELOPE;
typedef const DPMSG_SYSMSGENVELOPE* LPCDPMSG_SYSMSGENVELOPE;
typedef struct tagDPMSG_ENUMSESSIONSREPLY
{
DPMSG_SENDENVELOPE envelope;
#if 0
DWORD dwSize; /* Size of DPSESSIONDESC2 struct */
DWORD dwFlags; /* Sessions flags */
GUID guidInstance; /* Not 100% sure this is what it is... */
GUID guidApplication;
DWORD dwMaxPlayers;
DWORD dwCurrentPlayers;
BYTE unknown[36];
#else
DPSESSIONDESC2 sd;
#endif
DWORD dwUnknown; /* Seems to be equal to 0x5c which is a "\\" */
/* Encryption package string? */
/* At the end we have ... */
/* WCHAR wszSessionName[1]; Var length with NULL terminal */
} DPMSG_ENUMSESSIONSREPLY, *LPDPMSG_ENUMSESSIONSREPLY;
typedef const DPMSG_ENUMSESSIONSREPLY* LPCDPMSG_ENUMSESSIONSREPLY;
typedef struct tagDPMSG_ENUMSESSIONSREQUEST
{
DPMSG_SENDENVELOPE envelope;
GUID guidApplication;
DWORD dwPasswordSize; /* A Guess. This is normally 0x00000000. */
/* This might be the name server DPID which
is needed for the reply */
DWORD dwFlags; /* dwFlags from EnumSessions */
} DPMSG_ENUMSESSIONSREQUEST, *LPDPMSG_ENUMSESSIONSREQUEST;
typedef const DPMSG_ENUMSESSIONSREQUEST* LPCDPMSG_ENUMSESSIONSREQUEST;
/* Size is 146 received - with 18 or 20 bytes header = ~128 bytes */
typedef struct tagDPMSG_CREATESESSION
{
DPMSG_SENDENVELOPE envelope;
} DPMSG_CREATESESSION, *LPDPMSG_CREATESESSION;
typedef const DPMSG_CREATESESSION* LPCDPMSG_CREATESESSION;
/* 28 bytes - ~18 header ~= 10 bytes msg */
typedef struct tagDPMSG_REQUESTNEWPLAYERID
{
DPMSG_SENDENVELOPE envelope;
} DPMSG_REQUESTNEWPLAYERID, *LPDPMSG_REQUESTNEWPLAYERID;
typedef const DPMSG_REQUESTNEWPLAYERID* LPCDPMSG_REQUESTNEWPLAYERID;
/* 64 byte - ~18 header ~= 46 bytes msg */
typedef struct tagDPMSG_NEWPLAYERIDREPLY
{
DPMSG_SENDENVELOPE envelope;
} DPMSG_NEWPLAYERIDREPLY, *LPDPMSG_NEWPLAYERIDREPLY;
typedef const DPMSG_NEWPLAYERIDREPLY* LPCDPMSG_NEWPLAYERIDREPLY;
#include "poppack.h"
#endif
......@@ -7,6 +7,8 @@
#ifndef __WINE_DPLAYX_QUEUE_H
#define __WINE_DPLAYX_QUEUE_H
#include "winbase.h"
#define DPQ_INSERT(a,b,c) DPQ_INSERT_IN_TAIL(a,b,c)
/*
......@@ -33,6 +35,19 @@ do{ \
(head).lpQHLast = &(head).lpQHFirst; \
} while(0)
/* Front of the queue */
#define DPQ_FIRST( head ) ( (head).lpQHFirst )
/* Check if the queue has any elements */
#define DPQ_IS_EMPTY( head ) ( DPQ_FIRST(head) == NULL )
/* Next entry -- FIXME: Convert everything over to this macro ... */
#define DPQ_NEXT( elem ) (elem).lpQNext
#define DPQ_IS_ENDOFLIST( elem ) \
( DPQ_NEXT(elem) == NULL )
/* Insert element at end of queue */
#define DPQ_INSERT_IN_TAIL(head, elm, field) \
do { \
(elm)->field.lpQNext = NULL; \
......@@ -41,6 +56,7 @@ do { \
(head).lpQHLast = &(elm)->field.lpQNext; \
} while(0)
/* Remove element from the queue */
#define DPQ_REMOVE(head, elm, field) \
do { \
if (((elm)->field.lpQNext) != NULL) \
......@@ -53,18 +69,20 @@ do { \
/* head - pointer to DPQ_HEAD struct
* elm - how to find the next element
* field - to be concatenated to rc to compare with fieldToEqual
* fieldToEqual - The value that we're looking for
* field - to be concatenated to rc to compare with fieldToCompare
* fieldToCompare - The value that we're comparing against
* fieldCompareOperator - The logical operator to compare field and
* fieldToCompare.
* rc - Variable to put the return code. Same type as (head).lpQHFirst
*/
#define DPQ_FIND_ENTRY( head, elm, field, fieldToEqual, rc ) \
#define DPQ_FIND_ENTRY( head, elm, field, fieldCompareOperator, fieldToCompare, rc )\
do { \
(rc) = (head).lpQHFirst; /* NULL head? */ \
\
while( rc ) \
{ \
/* What we're searching for? */ \
if( (rc)->field == (fieldToEqual) ) \
if( (rc)->field fieldCompareOperator (fieldToCompare) ) \
{ \
break; /* rc == correct element */ \
} \
......@@ -81,12 +99,14 @@ do { \
/* head - pointer to DPQ_HEAD struct
* elm - how to find the next element
* field - to be concatenated to rc to compare with fieldToEqual
* fieldToEqual - The value that we're looking for
* fieldToCompare - The value that we're comparing against
* fieldCompareOperator - The logical operator to compare field and
* fieldToCompare.
* rc - Variable to put the return code. Same type as (head).lpQHFirst
*/
#define DPQ_REMOVE_ENTRY( head, elm, field, fieldToEqual, rc ) \
#define DPQ_REMOVE_ENTRY( head, elm, field, fieldCompareOperator, fieldToCompare, rc )\
do { \
DPQ_FIND_ENTRY( head, elm, field, fieldToEqual, rc ); \
DPQ_FIND_ENTRY( head, elm, field, fieldCompareOperator, fieldToCompare, rc );\
\
/* Was the element found? */ \
if( rc ) \
......@@ -95,4 +115,24 @@ do { \
} \
} while(0)
/* Delete the entire queue
* head - pointer to the head of the queue
* field - field to access the next elements of the queue
* type - type of the pointer to the element element
* df - a delete function to be called. Declared with DPQ_DECL_DELETECB.
*/
#define DPQ_DELETEQ( head, field, type, df ) \
while( !DPQ_IS_EMPTY(head) ) \
{ \
type holder = (head).lpQHFirst; \
DPQ_REMOVE( head, holder, field ); \
df( holder ); \
}
/* How to define the method to be passed to DPQ_DELETEQ */
#define DPQ_DECL_DELETECB( name, type ) void name( type elem )
/* Prototype of a method which just performs a HeapFree on the elem */
DPQ_DECL_DELETECB( cbDeleteElemFromHeap, LPVOID );
#endif /* __WINE_DPLAYX_QUEUE_H */
......@@ -3,14 +3,33 @@
#define __WINE_DPLAYX_NAMESERVER
#include "dplay.h"
#include "dplaysp.h"
#include "dplayx_messages.h"
#include "dplay_global.h"
void NS_SetLocalComputerAsNameServer( LPCDPSESSIONDESC2 lpsd );
void NS_SendSessionRequestBroadcast( LPVOID lpNSInfo );
void NS_SetRemoteComputerAsNameServer( LPVOID lpNSAddrHdr,
DWORD dwHdrSize,
LPDPMSG_ENUMSESSIONSREPLY lpMsg,
LPVOID lpNSInfo );
LPVOID NS_GetNSAddr( LPVOID lpNSInfo );
void NS_ReplyToEnumSessionsRequest( LPVOID lpMsg,
LPDPSP_REPLYDATA lpReplyData,
IDirectPlay2Impl* lpDP );
HRESULT NS_SendSessionRequestBroadcast( LPCGUID lpcGuid,
DWORD dwFlags,
LPSPINITDATA lpSpData );
BOOL NS_InitializeSessionCache( LPVOID* lplpNSInfo );
void NS_DeleteSessionCache( LPVOID lpNSInfo );
void NS_InvalidateSessionCache( LPVOID lpNSInfo );
void NS_ResetSessionEnumeration( LPVOID lpNSInfo );
LPDPSESSIONDESC2 NS_WalkSessions( LPVOID lpNSInfo );
void NS_PruneSessionCache( LPVOID lpNSInfo );
#endif /* __WINE_DPLAYX_NAMESERVER */
......@@ -13,6 +13,13 @@ extern "C" {
#include "pshpack1.h"
typedef LPVOID (*LPRGLPVOID)[];
typedef LPRGLPVOID PRGPVOID, LPRGPVOID, PRGLPVOID, PAPVOID, LPAPVOID, PALPVOID, LPALPVOID;
#define VOL volatile
typedef VOID *VOL LPVOIDV;
/*****************************************************************************
* Predeclare the interfaces
*/
......@@ -283,6 +290,13 @@ typedef struct tagDPCHAT
}msgstr;
} DPCHAT, *LPDPCHAT;
typedef struct
{
UINT len;
PUCHAR pData;
} SGBUFFER, *PSGBUFFER, *LPSGBUFFER;
typedef struct tagDPSECURITYDESC
{
DWORD dwSize; /* Size of structure */
......@@ -342,14 +356,7 @@ typedef BOOL CALLBACK (*LPDPENUMDPCALLBACKA)(
DWORD dwMinorVersion, /* Minor # of driver spec in lpguidSP */
LPVOID lpContext); /* User given */
/* NOTE: This isn't in the dplay.h header file, but this shouldn't be
* a problem. We require this because we include all these header files
* which declare GUIDs in guid.c
*/
#ifndef __LPCGUID_DEFINED__
#define __LPCGUID_DEFINED__
typedef const GUID *LPCGUID;
#endif
typedef const DPNAME *LPCDPNAME;
......
......@@ -6,7 +6,6 @@ VPATH = @srcdir@
MODULE = ole
C_SRCS = \
guid.c \
ole2nls.c
EXTRASUBDIRS = nls
......
#define INITGUID
/* FIXME: we include all the header files containing GUIDs
* so that the corresponding variables get defined. But they
* don't even all belong to the same DLL !!!
*
* Therefore, as the builtin DLL's get teased apart (e.g. for elf-dlls)
* then this file will have to be partitioned into per dll files.
*/
#include "initguid.h"
#if 0
#include "shlguid.h"
#include "docobj.h"
#include "olectl.h"
#include "oleidl.h"
#include "oaidl.h"
#include "ocidl.h"
#include "objbase.h"
#include "servprov.h"
#include "ddraw.h"
#include "d3d.h"
#include "dinput.h"
#include "dsound.h"
#include "dplay.h"
#include "dplobby.h"
#include "vfw.h"
#include "shlobj.h"
#endif
/* and now for the one assumed GUID... */
DEFINE_GUID(GUID_NULL, 0,0,0,0,0,0,0,0,0,0,0);
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