1 /* Direct Play 2,3,4 Implementation
3 * Copyright 1998,1999,2000,2001 - Peter Hunnisett
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
27 #define NONAMELESSUNION
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
38 #include "dplayx_global.h"
39 #include "name_server.h"
40 #include "dplayx_queue.h"
41 #include "wine/dplaysp.h"
42 #include "dplay_global.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(dplay
);
46 /* FIXME: Should this be externed? */
47 extern HRESULT DPL_CreateCompoundAddress
48 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements
, DWORD dwElementCount
,
49 LPVOID lpAddress
, LPDWORD lpdwAddressSize
, BOOL bAnsiInterface
);
52 /* Local function prototypes */
53 static lpPlayerList
DP_FindPlayer( IDirectPlayImpl
*This
, DPID dpid
);
54 static BOOL
DP_CopyDPNAMEStruct( LPDPNAME lpDst
, const DPNAME
*lpSrc
, BOOL bAnsi
);
55 static void DP_SetGroupData( lpGroupData lpGData
, DWORD dwFlags
,
56 LPVOID lpData
, DWORD dwDataSize
);
57 static void DP_DeleteDPNameStruct( LPDPNAME lpDPName
);
58 static BOOL CALLBACK
cbDeletePlayerFromAllGroups( DPID dpId
,
63 static lpGroupData
DP_FindAnyGroup( IDirectPlayImpl
*This
, DPID dpid
);
65 /* Helper methods for player/group interfaces */
66 static HRESULT
DP_SetSessionDesc( IDirectPlayImpl
*This
, const DPSESSIONDESC2
*lpSessDesc
,
67 DWORD dwFlags
, BOOL bInitial
, BOOL bAnsi
);
68 static HRESULT
DP_SP_SendEx( IDirectPlayImpl
*This
, DWORD dwFlags
, void *lpData
, DWORD dwDataSize
,
69 DWORD dwPriority
, DWORD dwTimeout
, void *lpContext
, DWORD
*lpdwMsgID
);
70 static BOOL
DP_BuildSPCompoundAddr( LPGUID lpcSpGuid
, LPVOID
* lplpAddrBuf
,
71 LPDWORD lpdwBufSize
);
73 static DPID
DP_GetRemoteNextObjectId(void);
75 static DWORD
DP_CalcSessionDescSize( LPCDPSESSIONDESC2 lpSessDesc
, BOOL bAnsi
);
76 static void DP_CopySessionDesc( LPDPSESSIONDESC2 destSessionDesc
,
77 LPCDPSESSIONDESC2 srcSessDesc
, BOOL bAnsi
);
80 #define DPID_NOPARENT_GROUP 0 /* Magic number to indicate no parent of group */
81 #define DPID_SYSTEM_GROUP DPID_NOPARENT_GROUP /* If system group is supported
82 we don't have to change much */
83 #define DPID_NAME_SERVER 0x19a9d65b /* Don't ask me why */
85 /* Strip out dwFlag values which cannot be sent in the CREATEGROUP msg */
86 #define DPMSG_CREATEGROUP_DWFLAGS(x) ( (x) & DPGROUP_HIDDEN )
88 /* Strip out all dwFlags values for CREATEPLAYER msg */
89 #define DPMSG_CREATEPLAYER_DWFLAGS(x) 0
91 static LONG kludgePlayerGroupId
= 1000;
94 static inline IDirectPlayImpl
*impl_from_IDirectPlay( IDirectPlay
*iface
)
96 return CONTAINING_RECORD( iface
, IDirectPlayImpl
, IDirectPlay_iface
);
99 static inline IDirectPlayImpl
*impl_from_IDirectPlay2( IDirectPlay2
*iface
)
101 return CONTAINING_RECORD( iface
, IDirectPlayImpl
, IDirectPlay2_iface
);
104 static inline IDirectPlayImpl
*impl_from_IDirectPlay2A( IDirectPlay2A
*iface
)
106 return CONTAINING_RECORD( iface
, IDirectPlayImpl
, IDirectPlay2A_iface
);
109 static inline IDirectPlayImpl
*impl_from_IDirectPlay3A( IDirectPlay3A
*iface
)
111 return CONTAINING_RECORD( iface
, IDirectPlayImpl
, IDirectPlay3A_iface
);
114 static inline IDirectPlayImpl
*impl_from_IDirectPlay3( IDirectPlay3
*iface
)
116 return CONTAINING_RECORD( iface
, IDirectPlayImpl
, IDirectPlay3_iface
);
119 static inline IDirectPlayImpl
*impl_from_IDirectPlay4A( IDirectPlay4A
*iface
)
121 return CONTAINING_RECORD( iface
, IDirectPlayImpl
, IDirectPlay4A_iface
);
124 static inline IDirectPlayImpl
*impl_from_IDirectPlay4( IDirectPlay4
*iface
)
126 return CONTAINING_RECORD( iface
, IDirectPlayImpl
, IDirectPlay4_iface
);
129 static BOOL
DP_CreateDirectPlay2( LPVOID lpDP
)
131 IDirectPlayImpl
*This
= lpDP
;
133 This
->dp2
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *(This
->dp2
) ) );
134 if ( This
->dp2
== NULL
)
139 This
->dp2
->bConnectionOpen
= FALSE
;
141 This
->dp2
->hEnumSessionThread
= INVALID_HANDLE_VALUE
;
142 This
->dp2
->dwEnumSessionLock
= 0;
144 This
->dp2
->bHostInterface
= FALSE
;
146 DPQ_INIT(This
->dp2
->receiveMsgs
);
147 DPQ_INIT(This
->dp2
->sendMsgs
);
148 DPQ_INIT(This
->dp2
->repliesExpected
);
150 if( !NS_InitializeSessionCache( &This
->dp2
->lpNameServerData
) )
152 /* FIXME: Memory leak */
156 /* Provide an initial session desc with nothing in it */
157 This
->dp2
->lpSessionDesc
= HeapAlloc( GetProcessHeap(),
159 sizeof( *This
->dp2
->lpSessionDesc
) );
160 if( This
->dp2
->lpSessionDesc
== NULL
)
162 /* FIXME: Memory leak */
165 This
->dp2
->lpSessionDesc
->dwSize
= sizeof( *This
->dp2
->lpSessionDesc
);
167 /* We are emulating a dp 6 implementation */
168 This
->dp2
->spData
.dwSPVersion
= DPSP_MAJORVERSION
;
170 This
->dp2
->spData
.lpCB
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
171 sizeof( *This
->dp2
->spData
.lpCB
) );
172 This
->dp2
->spData
.lpCB
->dwSize
= sizeof( *This
->dp2
->spData
.lpCB
);
173 This
->dp2
->spData
.lpCB
->dwVersion
= DPSP_MAJORVERSION
;
175 /* This is the pointer to the service provider */
176 if ( FAILED( dplaysp_create( &IID_IDirectPlaySP
, (void**)&This
->dp2
->spData
.lpISP
, This
) ) )
178 /* FIXME: Memory leak */
182 /* Setup lobby provider information */
183 This
->dp2
->dplspData
.dwSPVersion
= DPSP_MAJORVERSION
;
184 This
->dp2
->dplspData
.lpCB
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
185 sizeof( *This
->dp2
->dplspData
.lpCB
) );
186 This
->dp2
->dplspData
.lpCB
->dwSize
= sizeof( *This
->dp2
->dplspData
.lpCB
);
188 if( FAILED( dplobbysp_create( &IID_IDPLobbySP
, (void**)&This
->dp2
->dplspData
.lpISP
, This
) )
191 /* FIXME: Memory leak */
198 /* Definition of the global function in dplayx_queue.h. #
199 * FIXME: Would it be better to have a dplayx_queue.c for this function? */
200 DPQ_DECL_DELETECB( cbDeleteElemFromHeap
, LPVOID
)
202 HeapFree( GetProcessHeap(), 0, elem
);
205 static BOOL
DP_DestroyDirectPlay2( LPVOID lpDP
)
207 IDirectPlayImpl
*This
= lpDP
;
209 if( This
->dp2
->hEnumSessionThread
!= INVALID_HANDLE_VALUE
)
211 TerminateThread( This
->dp2
->hEnumSessionThread
, 0 );
212 CloseHandle( This
->dp2
->hEnumSessionThread
);
215 /* Finish with the SP - have it shutdown */
216 if( This
->dp2
->spData
.lpCB
->ShutdownEx
)
218 DPSP_SHUTDOWNDATA data
;
220 TRACE( "Calling SP ShutdownEx\n" );
222 data
.lpISP
= This
->dp2
->spData
.lpISP
;
224 (*This
->dp2
->spData
.lpCB
->ShutdownEx
)( &data
);
226 else if (This
->dp2
->spData
.lpCB
->Shutdown
) /* obsolete interface */
228 TRACE( "Calling obsolete SP Shutdown\n" );
229 (*This
->dp2
->spData
.lpCB
->Shutdown
)();
232 /* Unload the SP (if it exists) */
233 if( This
->dp2
->hServiceProvider
!= 0 )
235 FreeLibrary( This
->dp2
->hServiceProvider
);
238 /* Unload the Lobby Provider (if it exists) */
239 if( This
->dp2
->hDPLobbyProvider
!= 0 )
241 FreeLibrary( This
->dp2
->hDPLobbyProvider
);
244 /* FIXME: Need to delete receive and send msgs queue contents */
246 NS_DeleteSessionCache( This
->dp2
->lpNameServerData
);
248 HeapFree( GetProcessHeap(), 0, This
->dp2
->lpSessionDesc
);
250 IDirectPlaySP_Release( This
->dp2
->spData
.lpISP
);
252 /* Delete the contents */
253 HeapFree( GetProcessHeap(), 0, This
->dp2
);
258 static void dplay_destroy(IDirectPlayImpl
*obj
)
260 DP_DestroyDirectPlay2( obj
);
261 obj
->lock
.DebugInfo
->Spare
[0] = 0;
262 DeleteCriticalSection( &obj
->lock
);
263 HeapFree( GetProcessHeap(), 0, obj
);
266 static inline DPID
DP_NextObjectId(void)
268 return (DPID
)InterlockedIncrement( &kludgePlayerGroupId
);
271 /* *lplpReply will be non NULL iff there is something to reply */
272 HRESULT
DP_HandleMessage( IDirectPlayImpl
*This
, const void *lpcMessageBody
,
273 DWORD dwMessageBodySize
, const void *lpcMessageHeader
, WORD wCommandId
, WORD wVersion
,
274 void **lplpReply
, DWORD
*lpdwMsgSize
)
276 TRACE( "(%p)->(%p,0x%08x,%p,%u,%u)\n",
277 This
, lpcMessageBody
, dwMessageBodySize
, lpcMessageHeader
, wCommandId
,
282 /* Name server needs to handle this request */
283 case DPMSGCMD_ENUMSESSIONSREQUEST
:
285 NS_ReplyToEnumSessionsRequest( lpcMessageBody
, lplpReply
, lpdwMsgSize
, This
);
288 /* Name server needs to handle this request */
289 case DPMSGCMD_ENUMSESSIONSREPLY
:
290 /* No reply expected */
291 NS_AddRemoteComputerAsNameServer( lpcMessageHeader
,
292 This
->dp2
->spData
.dwSPHeaderSize
,
294 This
->dp2
->lpNameServerData
);
297 case DPMSGCMD_REQUESTNEWPLAYERID
:
299 LPCDPMSG_REQUESTNEWPLAYERID lpcMsg
= lpcMessageBody
;
301 LPDPMSG_NEWPLAYERIDREPLY lpReply
;
303 *lpdwMsgSize
= This
->dp2
->spData
.dwSPHeaderSize
+ sizeof( *lpReply
);
305 *lplpReply
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, *lpdwMsgSize
);
307 FIXME( "Ignoring dwFlags 0x%08x in request msg\n",
310 /* Setup the reply */
311 lpReply
= (LPDPMSG_NEWPLAYERIDREPLY
)( (BYTE
*)(*lplpReply
) +
312 This
->dp2
->spData
.dwSPHeaderSize
);
314 lpReply
->envelope
.dwMagic
= DPMSGMAGIC_DPLAYMSG
;
315 lpReply
->envelope
.wCommandId
= DPMSGCMD_NEWPLAYERIDREPLY
;
316 lpReply
->envelope
.wVersion
= DPMSGVER_DP6
;
318 lpReply
->dpidNewPlayerId
= DP_NextObjectId();
320 TRACE( "Allocating new playerid 0x%08x from remote request\n",
321 lpReply
->dpidNewPlayerId
);
325 case DPMSGCMD_GETNAMETABLEREPLY
:
326 case DPMSGCMD_NEWPLAYERIDREPLY
:
327 DP_MSG_ReplyReceived( This
, wCommandId
, lpcMessageBody
, dwMessageBodySize
);
330 case DPMSGCMD_JUSTENVELOPE
:
331 TRACE( "GOT THE SELF MESSAGE: %p -> 0x%08x\n", lpcMessageHeader
, ((const DWORD
*)lpcMessageHeader
)[1] );
332 NS_SetLocalAddr( This
->dp2
->lpNameServerData
, lpcMessageHeader
, 20 );
333 DP_MSG_ReplyReceived( This
, wCommandId
, lpcMessageBody
, dwMessageBodySize
);
335 case DPMSGCMD_FORWARDADDPLAYER
:
336 TRACE( "Sending message to self to get my addr\n" );
337 DP_MSG_ToSelf( This
, 1 ); /* This is a hack right now */
340 case DPMSGCMD_FORWARDADDPLAYERNACK
:
341 DP_MSG_ErrorReceived( This
, wCommandId
, lpcMessageBody
, dwMessageBodySize
);
345 FIXME( "Unknown wCommandId %u. Ignoring message\n", wCommandId
);
350 /* FIXME: There is code in dplaysp.c to handle dplay commands. Move to here. */
356 static HRESULT WINAPI
IDirectPlayImpl_QueryInterface( IDirectPlay
*iface
, REFIID riid
, void **ppv
)
358 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
359 return IDirectPlayX_QueryInterface( &This
->IDirectPlay4_iface
, riid
, ppv
);
362 static ULONG WINAPI
IDirectPlayImpl_AddRef( IDirectPlay
*iface
)
364 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
365 ULONG ref
= InterlockedIncrement( &This
->ref
);
367 TRACE( "(%p) ref=%d\n", This
, ref
);
370 InterlockedIncrement( &This
->numIfaces
);
375 static ULONG WINAPI
IDirectPlayImpl_Release( IDirectPlay
*iface
)
377 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
378 ULONG ref
= InterlockedDecrement( &This
->ref
);
380 TRACE( "(%p) ref=%d\n", This
, ref
);
382 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
383 dplay_destroy( This
);
388 static HRESULT WINAPI
IDirectPlayImpl_AddPlayerToGroup( IDirectPlay
*iface
, DPID group
,
391 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
392 FIXME( "(%p)->(0x%08x,0x%08x): stub\n", This
, group
, player
);
396 static HRESULT WINAPI
IDirectPlayImpl_Close( IDirectPlay
*iface
)
398 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
399 FIXME( "(%p): stub\n", This
);
403 static HRESULT WINAPI
IDirectPlayImpl_CreatePlayer( IDirectPlay
*iface
, DPID
*player
,
404 LPSTR name
, LPSTR fullname
, HANDLE
*event
)
406 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
407 FIXME( "(%p)->(%p,%s,%s,%p): stub\n", This
, player
, debugstr_a( name
), debugstr_a( fullname
),
412 static HRESULT WINAPI
IDirectPlayImpl_CreateGroup( IDirectPlay
*iface
, DPID
*group
, LPSTR name
,
415 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
416 FIXME( "(%p)->(%p,%s,%s): stub\n", This
, group
, debugstr_a( name
), debugstr_a( fullname
) );
420 static HRESULT WINAPI
IDirectPlayImpl_DeletePlayerFromGroup( IDirectPlay
*iface
, DPID group
,
423 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
424 FIXME( "(%p)->(0x%08x,0x%08x): stub\n", This
, group
, player
);
428 static HRESULT WINAPI
IDirectPlayImpl_DestroyPlayer( IDirectPlay
*iface
, DPID player
)
430 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
431 FIXME( "(%p)->(0x%08x): stub\n", This
, player
);
435 static HRESULT WINAPI
IDirectPlayImpl_DestroyGroup( IDirectPlay
*iface
, DPID group
)
437 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
438 FIXME( "(%p)->(0x%08x): stub\n", This
, group
);
442 static HRESULT WINAPI
IDirectPlayImpl_EnableNewPlayers( IDirectPlay
*iface
, BOOL enable
)
444 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
445 FIXME( "(%p)->(%d): stub\n", This
, enable
);
449 static HRESULT WINAPI
IDirectPlayImpl_EnumGroupPlayers( IDirectPlay
*iface
, DPID group
,
450 LPDPENUMPLAYERSCALLBACK enumplayercb
, void *context
, DWORD flags
)
452 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
453 FIXME( "(%p)->(0x%08x,%p,%p,0x%08x): stub\n", This
, group
, enumplayercb
, context
, flags
);
457 static HRESULT WINAPI
IDirectPlayImpl_EnumGroups( IDirectPlay
*iface
, DWORD session
,
458 LPDPENUMPLAYERSCALLBACK enumplayercb
, void *context
, DWORD flags
)
460 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
461 FIXME( "(%p)->(0x%08x,%p,%p,0x%08x): stub\n", This
, session
, enumplayercb
, context
, flags
);
465 static HRESULT WINAPI
IDirectPlayImpl_EnumPlayers( IDirectPlay
*iface
, DWORD session
,
466 LPDPENUMPLAYERSCALLBACK enumplayercb
, void *context
, DWORD flags
)
468 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
469 FIXME( "(%p)->(0x%08x,%p,%p,0x%08x): stub\n", This
, session
, enumplayercb
, context
, flags
);
473 static HRESULT WINAPI
IDirectPlayImpl_EnumSessions( IDirectPlay
*iface
, DPSESSIONDESC
*sdesc
,
474 DWORD timeout
, LPDPENUMSESSIONSCALLBACK enumsessioncb
, void *context
, DWORD flags
)
476 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
477 FIXME( "(%p)->(%p,%u,%p,%p,0x%08x): stub\n", This
, sdesc
, timeout
, enumsessioncb
, context
,
482 static HRESULT WINAPI
IDirectPlayImpl_GetCaps( IDirectPlay
*iface
, DPCAPS
*caps
)
484 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
485 FIXME( "(%p)->(%p): stub\n", This
, caps
);
489 static HRESULT WINAPI
IDirectPlayImpl_GetMessageCount( IDirectPlay
*iface
, DPID player
,
492 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
493 FIXME( "(%p)->(0x%08x,%p): stub\n", This
, player
, count
);
497 static HRESULT WINAPI
IDirectPlayImpl_GetPlayerCaps( IDirectPlay
*iface
, DPID player
, DPCAPS
*caps
)
499 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
500 FIXME( "(%p)->(0x%08x,%p): stub\n", This
, player
, caps
);
504 static HRESULT WINAPI
IDirectPlayImpl_GetPlayerName( IDirectPlay
*iface
, DPID player
, LPSTR name
,
505 DWORD
*size_name
, LPSTR fullname
, DWORD
*size_fullname
)
507 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
508 FIXME( "(%p)->(0x%08x,%p,%p,%p,%p): stub\n", This
, player
, name
, size_name
, fullname
,
513 static HRESULT WINAPI
IDirectPlayImpl_Initialize( IDirectPlay
*iface
, GUID
*guid
)
515 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
516 FIXME( "(%p)->(%p): stub\n", This
, guid
);
520 static HRESULT WINAPI
IDirectPlayImpl_Open( IDirectPlay
*iface
, DPSESSIONDESC
*sdesc
)
522 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
523 FIXME( "(%p)->(%p): stub\n", This
, sdesc
);
527 static HRESULT WINAPI
IDirectPlayImpl_Receive( IDirectPlay
*iface
, DPID
*from
, DPID
*to
,
528 DWORD flags
, void *data
, DWORD
*size
)
530 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
531 FIXME( "(%p)->(%p,%p,0x%08x,%p,%p): stub\n", This
, from
, to
, flags
, data
, size
);
535 static HRESULT WINAPI
IDirectPlayImpl_SaveSession( IDirectPlay
*iface
, LPSTR reserved
)
537 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
538 FIXME( "(%p)->(%p): stub\n", This
, reserved
);
542 static HRESULT WINAPI
IDirectPlayImpl_Send( IDirectPlay
*iface
, DPID from
, DPID to
, DWORD flags
,
543 void *data
, DWORD size
)
545 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
546 FIXME( "(%p)->(0x%08x,0x%08x,0x%08x,%p,%u): stub\n", This
, from
, to
, flags
, data
, size
);
550 static HRESULT WINAPI
IDirectPlayImpl_SetPlayerName( IDirectPlay
*iface
, DPID player
, LPSTR name
,
553 IDirectPlayImpl
*This
= impl_from_IDirectPlay( iface
);
554 FIXME( "(%p)->(0x%08x,%s,%s): stub\n", This
, player
, debugstr_a( name
),
555 debugstr_a ( fullname
) );
559 static const IDirectPlayVtbl dp_vt
=
561 IDirectPlayImpl_QueryInterface
,
562 IDirectPlayImpl_AddRef
,
563 IDirectPlayImpl_Release
,
564 IDirectPlayImpl_AddPlayerToGroup
,
565 IDirectPlayImpl_Close
,
566 IDirectPlayImpl_CreatePlayer
,
567 IDirectPlayImpl_CreateGroup
,
568 IDirectPlayImpl_DeletePlayerFromGroup
,
569 IDirectPlayImpl_DestroyPlayer
,
570 IDirectPlayImpl_DestroyGroup
,
571 IDirectPlayImpl_EnableNewPlayers
,
572 IDirectPlayImpl_EnumGroupPlayers
,
573 IDirectPlayImpl_EnumGroups
,
574 IDirectPlayImpl_EnumPlayers
,
575 IDirectPlayImpl_EnumSessions
,
576 IDirectPlayImpl_GetCaps
,
577 IDirectPlayImpl_GetMessageCount
,
578 IDirectPlayImpl_GetPlayerCaps
,
579 IDirectPlayImpl_GetPlayerName
,
580 IDirectPlayImpl_Initialize
,
581 IDirectPlayImpl_Open
,
582 IDirectPlayImpl_Receive
,
583 IDirectPlayImpl_SaveSession
,
584 IDirectPlayImpl_Send
,
585 IDirectPlayImpl_SetPlayerName
,
589 static HRESULT WINAPI
IDirectPlay2AImpl_QueryInterface( IDirectPlay2A
*iface
, REFIID riid
,
592 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
593 return IDirectPlayX_QueryInterface( &This
->IDirectPlay4_iface
, riid
, ppv
);
596 static HRESULT WINAPI
IDirectPlay2Impl_QueryInterface( IDirectPlay2
*iface
, REFIID riid
,
599 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
600 return IDirectPlayX_QueryInterface( &This
->IDirectPlay4_iface
, riid
, ppv
);
603 static HRESULT WINAPI
IDirectPlay3AImpl_QueryInterface( IDirectPlay3A
*iface
, REFIID riid
,
606 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
607 return IDirectPlayX_QueryInterface( &This
->IDirectPlay4_iface
, riid
, ppv
);
610 static HRESULT WINAPI
IDirectPlay3Impl_QueryInterface( IDirectPlay3
*iface
, REFIID riid
,
613 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
614 return IDirectPlayX_QueryInterface( &This
->IDirectPlay4_iface
, riid
, ppv
);
617 static HRESULT WINAPI
IDirectPlay4AImpl_QueryInterface( IDirectPlay4A
*iface
, REFIID riid
,
620 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
621 return IDirectPlayX_QueryInterface( &This
->IDirectPlay4_iface
, riid
, ppv
);
624 static HRESULT WINAPI
IDirectPlay4Impl_QueryInterface( IDirectPlay4
*iface
, REFIID riid
,
627 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
629 if ( IsEqualGUID( &IID_IUnknown
, riid
) )
631 TRACE( "(%p)->(IID_IUnknown %p)\n", This
, ppv
);
632 *ppv
= &This
->IDirectPlay_iface
;
634 else if ( IsEqualGUID( &IID_IDirectPlay
, riid
) )
636 TRACE( "(%p)->(IID_IDirectPlay %p)\n", This
, ppv
);
637 *ppv
= &This
->IDirectPlay_iface
;
639 else if ( IsEqualGUID( &IID_IDirectPlay2A
, riid
) )
641 TRACE( "(%p)->(IID_IDirectPlay2A %p)\n", This
, ppv
);
642 *ppv
= &This
->IDirectPlay2A_iface
;
644 else if ( IsEqualGUID( &IID_IDirectPlay2
, riid
) )
646 TRACE( "(%p)->(IID_IDirectPlay2 %p)\n", This
, ppv
);
647 *ppv
= &This
->IDirectPlay2_iface
;
649 else if ( IsEqualGUID( &IID_IDirectPlay3A
, riid
) )
651 TRACE( "(%p)->(IID_IDirectPlay3A %p)\n", This
, ppv
);
652 *ppv
= &This
->IDirectPlay3A_iface
;
654 else if ( IsEqualGUID( &IID_IDirectPlay3
, riid
) )
656 TRACE( "(%p)->(IID_IDirectPlay3 %p)\n", This
, ppv
);
657 *ppv
= &This
->IDirectPlay3_iface
;
659 else if ( IsEqualGUID( &IID_IDirectPlay4A
, riid
) )
661 TRACE( "(%p)->(IID_IDirectPlay4A %p)\n", This
, ppv
);
662 *ppv
= &This
->IDirectPlay4A_iface
;
664 else if ( IsEqualGUID( &IID_IDirectPlay4
, riid
) )
666 TRACE( "(%p)->(IID_IDirectPlay4 %p)\n", This
, ppv
);
667 *ppv
= &This
->IDirectPlay4_iface
;
671 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
673 return E_NOINTERFACE
;
676 IUnknown_AddRef((IUnknown
*)*ppv
);
680 static ULONG WINAPI
IDirectPlay2AImpl_AddRef( IDirectPlay2A
*iface
)
682 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
683 ULONG ref
= InterlockedIncrement( &This
->ref2A
);
685 TRACE( "(%p) ref2A=%d\n", This
, ref
);
688 InterlockedIncrement( &This
->numIfaces
);
693 static ULONG WINAPI
IDirectPlay2Impl_AddRef( IDirectPlay2
*iface
)
695 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
696 ULONG ref
= InterlockedIncrement( &This
->ref2
);
698 TRACE( "(%p) ref2=%d\n", This
, ref
);
701 InterlockedIncrement( &This
->numIfaces
);
706 static ULONG WINAPI
IDirectPlay3AImpl_AddRef( IDirectPlay3A
*iface
)
708 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
709 ULONG ref
= InterlockedIncrement( &This
->ref3A
);
711 TRACE( "(%p) ref3A=%d\n", This
, ref
);
714 InterlockedIncrement( &This
->numIfaces
);
719 static ULONG WINAPI
IDirectPlay3Impl_AddRef( IDirectPlay3
*iface
)
721 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
722 ULONG ref
= InterlockedIncrement( &This
->ref3
);
724 TRACE( "(%p) ref3=%d\n", This
, ref
);
727 InterlockedIncrement( &This
->numIfaces
);
732 static ULONG WINAPI
IDirectPlay4AImpl_AddRef(IDirectPlay4A
*iface
)
734 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
735 ULONG ref
= InterlockedIncrement( &This
->ref4A
);
737 TRACE( "(%p) ref4A=%d\n", This
, ref
);
740 InterlockedIncrement( &This
->numIfaces
);
745 static ULONG WINAPI
IDirectPlay4Impl_AddRef(IDirectPlay4
*iface
)
747 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
748 ULONG ref
= InterlockedIncrement( &This
->ref4
);
750 TRACE( "(%p) ref4=%d\n", This
, ref
);
753 InterlockedIncrement( &This
->numIfaces
);
758 static ULONG WINAPI
IDirectPlay2AImpl_Release( IDirectPlay2A
*iface
)
760 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
761 ULONG ref
= InterlockedDecrement( &This
->ref2A
);
763 TRACE( "(%p) ref2A=%d\n", This
, ref
);
765 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
766 dplay_destroy( This
);
771 static ULONG WINAPI
IDirectPlay2Impl_Release( IDirectPlay2
*iface
)
773 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
774 ULONG ref
= InterlockedDecrement( &This
->ref2
);
776 TRACE( "(%p) ref2=%d\n", This
, ref
);
778 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
779 dplay_destroy( This
);
784 static ULONG WINAPI
IDirectPlay3AImpl_Release( IDirectPlay3A
*iface
)
786 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
787 ULONG ref
= InterlockedDecrement( &This
->ref3A
);
789 TRACE( "(%p) ref3A=%d\n", This
, ref
);
791 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
792 dplay_destroy( This
);
797 static ULONG WINAPI
IDirectPlay3Impl_Release( IDirectPlay3
*iface
)
799 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
800 ULONG ref
= InterlockedDecrement( &This
->ref3
);
802 TRACE( "(%p) ref3=%d\n", This
, ref
);
804 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
805 dplay_destroy( This
);
810 static ULONG WINAPI
IDirectPlay4AImpl_Release(IDirectPlay4A
*iface
)
812 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
813 ULONG ref
= InterlockedDecrement( &This
->ref4A
);
815 TRACE( "(%p) ref4A=%d\n", This
, ref
);
817 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
818 dplay_destroy( This
);
823 static ULONG WINAPI
IDirectPlay4Impl_Release(IDirectPlay4
*iface
)
825 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
826 ULONG ref
= InterlockedDecrement( &This
->ref4
);
828 TRACE( "(%p) ref4=%d\n", This
, ref
);
830 if ( !ref
&& !InterlockedDecrement( &This
->numIfaces
) )
831 dplay_destroy( This
);
836 static HRESULT WINAPI
IDirectPlay2AImpl_AddPlayerToGroup( IDirectPlay2A
*iface
, DPID group
,
839 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
840 return IDirectPlayX_AddPlayerToGroup( &This
->IDirectPlay4A_iface
, group
, player
);
843 static HRESULT WINAPI
IDirectPlay2Impl_AddPlayerToGroup( IDirectPlay2
*iface
, DPID group
,
846 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
847 return IDirectPlayX_AddPlayerToGroup( &This
->IDirectPlay4_iface
, group
, player
);
850 static HRESULT WINAPI
IDirectPlay3AImpl_AddPlayerToGroup( IDirectPlay3A
*iface
, DPID group
,
853 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
854 return IDirectPlayX_AddPlayerToGroup( &This
->IDirectPlay4_iface
, group
, player
);
857 static HRESULT WINAPI
IDirectPlay3Impl_AddPlayerToGroup( IDirectPlay3
*iface
, DPID group
,
860 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
861 return IDirectPlayX_AddPlayerToGroup( &This
->IDirectPlay4_iface
, group
, player
);
864 static HRESULT WINAPI
IDirectPlay4AImpl_AddPlayerToGroup( IDirectPlay4A
*iface
, DPID group
,
867 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
868 return IDirectPlayX_AddPlayerToGroup( &This
->IDirectPlay4_iface
, group
, player
);
871 static HRESULT WINAPI
IDirectPlay4Impl_AddPlayerToGroup( IDirectPlay4
*iface
, DPID group
,
874 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
877 lpPlayerList newplist
;
879 TRACE( "(%p)->(0x%08x,0x%08x)\n", This
, group
, player
);
881 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
882 return DPERR_UNINITIALIZED
;
885 if ( ( gdata
= DP_FindAnyGroup( This
, group
) ) == NULL
)
886 return DPERR_INVALIDGROUP
;
888 /* Find the player */
889 if ( ( plist
= DP_FindPlayer( This
, player
) ) == NULL
)
890 return DPERR_INVALIDPLAYER
;
892 /* Create a player list (ie "shortcut" ) */
893 newplist
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *newplist
) );
895 return DPERR_CANTADDPLAYER
;
897 /* Add the shortcut */
898 plist
->lpPData
->uRef
++;
899 newplist
->lpPData
= plist
->lpPData
;
901 /* Add the player to the list of players for this group */
902 DPQ_INSERT(gdata
->players
, newplist
, players
);
904 /* Let the SP know that we've added a player to the group */
905 if ( This
->dp2
->spData
.lpCB
->AddPlayerToGroup
)
907 DPSP_ADDPLAYERTOGROUPDATA data
;
909 TRACE( "Calling SP AddPlayerToGroup\n" );
911 data
.idPlayer
= player
;
912 data
.idGroup
= group
;
913 data
.lpISP
= This
->dp2
->spData
.lpISP
;
915 (*This
->dp2
->spData
.lpCB
->AddPlayerToGroup
)( &data
);
918 /* Inform all other peers of the addition of player to the group. If there are
919 * no peers keep this event quiet.
920 * Also, if this event was the result of another machine sending it to us,
921 * don't bother rebroadcasting it.
923 if ( This
->dp2
->lpSessionDesc
&&
924 ( This
->dp2
->lpSessionDesc
->dwFlags
& DPSESSION_MULTICASTSERVER
) )
926 DPMSG_ADDPLAYERTOGROUP msg
;
927 msg
.dwType
= DPSYS_ADDPLAYERTOGROUP
;
929 msg
.dpIdGroup
= group
;
930 msg
.dpIdPlayer
= player
;
932 /* FIXME: Correct to just use send effectively? */
933 /* FIXME: Should size include data w/ message or just message "header" */
934 /* FIXME: Check return code */
935 IDirectPlayX_SendEx( iface
, DPID_SERVERPLAYER
, DPID_ALLPLAYERS
, 0, &msg
, sizeof( msg
),
942 static HRESULT WINAPI
IDirectPlay2AImpl_Close( IDirectPlay2A
*iface
)
944 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
945 return IDirectPlayX_Close( &This
->IDirectPlay4A_iface
);
948 static HRESULT WINAPI
IDirectPlay2Impl_Close( IDirectPlay2
*iface
)
950 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
951 return IDirectPlayX_Close( &This
->IDirectPlay4_iface
);
954 static HRESULT WINAPI
IDirectPlay3AImpl_Close( IDirectPlay3A
*iface
)
956 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
957 return IDirectPlayX_Close( &This
->IDirectPlay4_iface
);
960 static HRESULT WINAPI
IDirectPlay3Impl_Close( IDirectPlay3
*iface
)
962 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
963 return IDirectPlayX_Close( &This
->IDirectPlay4_iface
);
966 static HRESULT WINAPI
IDirectPlay4AImpl_Close( IDirectPlay4A
*iface
)
968 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
969 return IDirectPlayX_Close( &This
->IDirectPlay4_iface
);
972 static HRESULT WINAPI
IDirectPlay4Impl_Close( IDirectPlay4
*iface
)
974 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
977 TRACE( "(%p)\n", This
);
979 /* FIXME: Need to find a new host I assume (how?) */
980 /* FIXME: Need to destroy all local groups */
981 /* FIXME: Need to migrate all remotely visible players to the new host */
983 /* Invoke the SP callback to inform of session close */
984 if( This
->dp2
->spData
.lpCB
->CloseEx
)
988 TRACE( "Calling SP CloseEx\n" );
989 data
.lpISP
= This
->dp2
->spData
.lpISP
;
990 hr
= (*This
->dp2
->spData
.lpCB
->CloseEx
)( &data
);
992 else if ( This
->dp2
->spData
.lpCB
->Close
) /* Try obsolete version */
994 TRACE( "Calling SP Close (obsolete interface)\n" );
995 hr
= (*This
->dp2
->spData
.lpCB
->Close
)();
1001 static lpGroupData
DP_CreateGroup( IDirectPlayImpl
*This
, const DPID
*lpid
, const DPNAME
*lpName
,
1002 DWORD dwFlags
, DPID idParent
, BOOL bAnsi
)
1004 lpGroupData lpGData
;
1006 /* Allocate the new space and add to end of high level group list */
1007 lpGData
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *lpGData
) );
1009 if( lpGData
== NULL
)
1014 DPQ_INIT(lpGData
->groups
);
1015 DPQ_INIT(lpGData
->players
);
1017 /* Set the desired player ID - no sanity checking to see if it exists */
1018 lpGData
->dpid
= *lpid
;
1020 DP_CopyDPNAMEStruct( &lpGData
->name
, lpName
, bAnsi
);
1022 /* FIXME: Should we check that the parent exists? */
1023 lpGData
->parent
= idParent
;
1025 /* FIXME: Should we validate the dwFlags? */
1026 lpGData
->dwFlags
= dwFlags
;
1028 TRACE( "Created group id 0x%08x\n", *lpid
);
1033 /* This method assumes that all links to it are already deleted */
1034 static void DP_DeleteGroup( IDirectPlayImpl
*This
, DPID dpid
)
1036 lpGroupList lpGList
;
1038 TRACE( "(%p)->(0x%08x)\n", This
, dpid
);
1040 DPQ_REMOVE_ENTRY( This
->dp2
->lpSysGroup
->groups
, groups
, lpGData
->dpid
, ==, dpid
, lpGList
);
1042 if( lpGList
== NULL
)
1044 ERR( "DPID 0x%08x not found\n", dpid
);
1048 if( --(lpGList
->lpGData
->uRef
) )
1050 FIXME( "Why is this not the last reference to group?\n" );
1055 DP_DeleteDPNameStruct( &lpGList
->lpGData
->name
);
1056 HeapFree( GetProcessHeap(), 0, lpGList
->lpGData
);
1058 /* Remove and Delete Player List object */
1059 HeapFree( GetProcessHeap(), 0, lpGList
);
1063 static lpGroupData
DP_FindAnyGroup( IDirectPlayImpl
*This
, DPID dpid
)
1065 lpGroupList lpGroups
;
1067 TRACE( "(%p)->(0x%08x)\n", This
, dpid
);
1069 if( dpid
== DPID_SYSTEM_GROUP
)
1071 return This
->dp2
->lpSysGroup
;
1075 DPQ_FIND_ENTRY( This
->dp2
->lpSysGroup
->groups
, groups
, lpGData
->dpid
, ==, dpid
, lpGroups
);
1078 if( lpGroups
== NULL
)
1083 return lpGroups
->lpGData
;
1086 static HRESULT
DP_IF_CreateGroup( IDirectPlayImpl
*This
, void *lpMsgHdr
, DPID
*lpidGroup
,
1087 DPNAME
*lpGroupName
, void *lpData
, DWORD dwDataSize
, DWORD dwFlags
, BOOL bAnsi
)
1089 lpGroupData lpGData
;
1091 TRACE( "(%p)->(%p,%p,%p,%p,0x%08x,0x%08x,%u)\n",
1092 This
, lpMsgHdr
, lpidGroup
, lpGroupName
, lpData
, dwDataSize
,
1095 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
1097 return DPERR_UNINITIALIZED
;
1100 /* If the name is not specified, we must provide one */
1101 if( DPID_UNKNOWN
== *lpidGroup
)
1103 /* If we are the name server, we decide on the group ids. If not, we
1104 * must ask for one before attempting a creation.
1106 if( This
->dp2
->bHostInterface
)
1108 *lpidGroup
= DP_NextObjectId();
1112 *lpidGroup
= DP_GetRemoteNextObjectId();
1116 lpGData
= DP_CreateGroup( This
, lpidGroup
, lpGroupName
, dwFlags
,
1117 DPID_NOPARENT_GROUP
, bAnsi
);
1119 if( lpGData
== NULL
)
1121 return DPERR_CANTADDPLAYER
; /* yes player not group */
1124 if( DPID_SYSTEM_GROUP
== *lpidGroup
)
1126 This
->dp2
->lpSysGroup
= lpGData
;
1127 TRACE( "Inserting system group\n" );
1131 /* Insert into the system group */
1132 lpGroupList lpGroup
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *lpGroup
) );
1133 lpGroup
->lpGData
= lpGData
;
1135 DPQ_INSERT( This
->dp2
->lpSysGroup
->groups
, lpGroup
, groups
);
1138 /* Something is now referencing this data */
1141 /* Set all the important stuff for the group */
1142 DP_SetGroupData( lpGData
, DPSET_REMOTE
, lpData
, dwDataSize
);
1144 /* FIXME: We should only create the system group if GetCaps returns
1145 * DPCAPS_GROUPOPTIMIZED.
1148 /* Let the SP know that we've created this group */
1149 if( This
->dp2
->spData
.lpCB
->CreateGroup
)
1151 DPSP_CREATEGROUPDATA data
;
1152 DWORD dwCreateFlags
= 0;
1154 TRACE( "Calling SP CreateGroup\n" );
1156 if( *lpidGroup
== DPID_NOPARENT_GROUP
)
1157 dwCreateFlags
|= DPLAYI_GROUP_SYSGROUP
;
1159 if( lpMsgHdr
== NULL
)
1160 dwCreateFlags
|= DPLAYI_PLAYER_PLAYERLOCAL
;
1162 if( dwFlags
& DPGROUP_HIDDEN
)
1163 dwCreateFlags
|= DPLAYI_GROUP_HIDDEN
;
1165 data
.idGroup
= *lpidGroup
;
1166 data
.dwFlags
= dwCreateFlags
;
1167 data
.lpSPMessageHeader
= lpMsgHdr
;
1168 data
.lpISP
= This
->dp2
->spData
.lpISP
;
1170 (*This
->dp2
->spData
.lpCB
->CreateGroup
)( &data
);
1173 /* Inform all other peers of the creation of a new group. If there are
1174 * no peers keep this event quiet.
1175 * Also if this message was sent to us, don't rebroadcast.
1177 if( ( lpMsgHdr
== NULL
) &&
1178 This
->dp2
->lpSessionDesc
&&
1179 ( This
->dp2
->lpSessionDesc
->dwFlags
& DPSESSION_MULTICASTSERVER
) )
1181 DPMSG_CREATEPLAYERORGROUP msg
;
1182 msg
.dwType
= DPSYS_CREATEPLAYERORGROUP
;
1184 msg
.dwPlayerType
= DPPLAYERTYPE_GROUP
;
1185 msg
.dpId
= *lpidGroup
;
1186 msg
.dwCurrentPlayers
= 0; /* FIXME: Incorrect? */
1187 msg
.lpData
= lpData
;
1188 msg
.dwDataSize
= dwDataSize
;
1189 msg
.dpnName
= *lpGroupName
;
1190 msg
.dpIdParent
= DPID_NOPARENT_GROUP
;
1191 msg
.dwFlags
= DPMSG_CREATEGROUP_DWFLAGS( dwFlags
);
1193 /* FIXME: Correct to just use send effectively? */
1194 /* FIXME: Should size include data w/ message or just message "header" */
1195 /* FIXME: Check return code */
1196 IDirectPlayX_SendEx( &This
->IDirectPlay4_iface
, DPID_SERVERPLAYER
, DPID_ALLPLAYERS
, 0, &msg
,
1197 sizeof( msg
), 0, 0, NULL
, NULL
);
1203 static HRESULT WINAPI
IDirectPlay2AImpl_CreateGroup( IDirectPlay2A
*iface
, DPID
*lpidGroup
,
1204 DPNAME
*name
, void *data
, DWORD size
, DWORD flags
)
1206 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
1207 return IDirectPlayX_CreateGroup( &This
->IDirectPlay4A_iface
, lpidGroup
, name
, data
, size
,
1211 static HRESULT WINAPI
IDirectPlay2Impl_CreateGroup( IDirectPlay2
*iface
, DPID
*lpidGroup
,
1212 DPNAME
*name
, void *data
, DWORD size
, DWORD flags
)
1214 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
1215 return IDirectPlayX_CreateGroup( &This
->IDirectPlay4_iface
, lpidGroup
, name
, data
, size
,
1219 static HRESULT WINAPI
IDirectPlay3AImpl_CreateGroup( IDirectPlay3A
*iface
, DPID
*group
,
1220 DPNAME
*name
, void *data
, DWORD size
, DWORD flags
)
1222 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
1223 return IDirectPlayX_CreateGroup( &This
->IDirectPlay4_iface
, group
, name
, data
, size
,
1227 static HRESULT WINAPI
IDirectPlay3Impl_CreateGroup( IDirectPlay3
*iface
, DPID
*lpidGroup
,
1228 DPNAME
*name
, void *data
, DWORD size
, DWORD flags
)
1230 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
1231 return IDirectPlayX_CreateGroup( &This
->IDirectPlay4_iface
, lpidGroup
, name
, data
, size
,
1235 static HRESULT WINAPI
IDirectPlay4AImpl_CreateGroup( IDirectPlay4A
*iface
, DPID
*lpidGroup
,
1236 DPNAME
*lpGroupName
, void *lpData
, DWORD dwDataSize
, DWORD dwFlags
)
1238 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
1240 *lpidGroup
= DPID_UNKNOWN
;
1242 return DP_IF_CreateGroup( This
, NULL
, lpidGroup
, lpGroupName
, lpData
, dwDataSize
, dwFlags
,
1246 static HRESULT WINAPI
IDirectPlay4Impl_CreateGroup( IDirectPlay4
*iface
, DPID
*lpidGroup
,
1247 DPNAME
*lpGroupName
, void *lpData
, DWORD dwDataSize
, DWORD dwFlags
)
1249 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
1251 *lpidGroup
= DPID_UNKNOWN
;
1253 return DP_IF_CreateGroup( This
, NULL
, lpidGroup
, lpGroupName
, lpData
, dwDataSize
, dwFlags
,
1259 DP_SetGroupData( lpGroupData lpGData
, DWORD dwFlags
,
1260 LPVOID lpData
, DWORD dwDataSize
)
1262 /* Clear out the data with this player */
1263 if( dwFlags
& DPSET_LOCAL
)
1265 if ( lpGData
->dwLocalDataSize
!= 0 )
1267 HeapFree( GetProcessHeap(), 0, lpGData
->lpLocalData
);
1268 lpGData
->lpLocalData
= NULL
;
1269 lpGData
->dwLocalDataSize
= 0;
1274 if( lpGData
->dwRemoteDataSize
!= 0 )
1276 HeapFree( GetProcessHeap(), 0, lpGData
->lpRemoteData
);
1277 lpGData
->lpRemoteData
= NULL
;
1278 lpGData
->dwRemoteDataSize
= 0;
1282 /* Reallocate for new data */
1283 if( lpData
!= NULL
)
1285 if( dwFlags
& DPSET_LOCAL
)
1287 lpGData
->lpLocalData
= lpData
;
1288 lpGData
->dwLocalDataSize
= dwDataSize
;
1292 lpGData
->lpRemoteData
= HeapAlloc( GetProcessHeap(), 0, dwDataSize
);
1293 CopyMemory( lpGData
->lpRemoteData
, lpData
, dwDataSize
);
1294 lpGData
->dwRemoteDataSize
= dwDataSize
;
1300 /* This function will just create the storage for the new player. */
1301 static lpPlayerData
DP_CreatePlayer( IDirectPlayImpl
*This
, DPID
*lpid
, DPNAME
*lpName
,
1302 DWORD dwFlags
, HANDLE hEvent
, BOOL bAnsi
)
1304 lpPlayerData lpPData
;
1306 TRACE( "(%p)->(%p,%p,%u)\n", This
, lpid
, lpName
, bAnsi
);
1308 /* Allocate the storage for the player and associate it with list element */
1309 lpPData
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *lpPData
) );
1310 if( lpPData
== NULL
)
1315 /* Set the desired player ID */
1316 lpPData
->dpid
= *lpid
;
1318 DP_CopyDPNAMEStruct( &lpPData
->name
, lpName
, bAnsi
);
1320 lpPData
->dwFlags
= dwFlags
;
1322 /* If we were given an event handle, duplicate it */
1325 if( !DuplicateHandle( GetCurrentProcess(), hEvent
,
1326 GetCurrentProcess(), &lpPData
->hEvent
,
1327 0, FALSE
, DUPLICATE_SAME_ACCESS
)
1330 /* FIXME: Memory leak */
1331 ERR( "Can't duplicate player msg handle %p\n", hEvent
);
1335 /* Initialize the SP data section */
1336 lpPData
->lpSPPlayerData
= DPSP_CreateSPPlayerData();
1338 TRACE( "Created player id 0x%08x\n", *lpid
);
1340 if( ~dwFlags
& DPLAYI_PLAYER_SYSPLAYER
)
1341 This
->dp2
->lpSessionDesc
->dwCurrentPlayers
++;
1346 /* Delete the contents of the DPNAME struct */
1348 DP_DeleteDPNameStruct( LPDPNAME lpDPName
)
1350 HeapFree( GetProcessHeap(), HEAP_ZERO_MEMORY
, lpDPName
->u1
.lpszShortNameA
);
1351 HeapFree( GetProcessHeap(), HEAP_ZERO_MEMORY
, lpDPName
->u2
.lpszLongNameA
);
1354 /* This method assumes that all links to it are already deleted */
1355 static void DP_DeletePlayer( IDirectPlayImpl
*This
, DPID dpid
)
1357 lpPlayerList lpPList
;
1359 TRACE( "(%p)->(0x%08x)\n", This
, dpid
);
1361 DPQ_REMOVE_ENTRY( This
->dp2
->lpSysGroup
->players
, players
, lpPData
->dpid
, ==, dpid
, lpPList
);
1363 if( lpPList
== NULL
)
1365 ERR( "DPID 0x%08x not found\n", dpid
);
1369 /* Verify that this is the last reference to the data */
1370 if( --(lpPList
->lpPData
->uRef
) )
1372 FIXME( "Why is this not the last reference to player?\n" );
1377 DP_DeleteDPNameStruct( &lpPList
->lpPData
->name
);
1379 CloseHandle( lpPList
->lpPData
->hEvent
);
1380 HeapFree( GetProcessHeap(), 0, lpPList
->lpPData
);
1382 /* Delete Player List object */
1383 HeapFree( GetProcessHeap(), 0, lpPList
);
1386 static lpPlayerList
DP_FindPlayer( IDirectPlayImpl
*This
, DPID dpid
)
1388 lpPlayerList lpPlayers
;
1390 TRACE( "(%p)->(0x%08x)\n", This
, dpid
);
1392 if(This
->dp2
->lpSysGroup
== NULL
)
1395 DPQ_FIND_ENTRY( This
->dp2
->lpSysGroup
->players
, players
, lpPData
->dpid
, ==, dpid
, lpPlayers
);
1400 /* Basic area for Dst must already be allocated */
1401 static BOOL
DP_CopyDPNAMEStruct( LPDPNAME lpDst
, const DPNAME
*lpSrc
, BOOL bAnsi
)
1405 ZeroMemory( lpDst
, sizeof( *lpDst
) );
1406 lpDst
->dwSize
= sizeof( *lpDst
);
1410 if( lpSrc
->dwSize
!= sizeof( *lpSrc
) )
1415 /* Delete any existing pointers */
1416 HeapFree( GetProcessHeap(), 0, lpDst
->u1
.lpszShortNameA
);
1417 HeapFree( GetProcessHeap(), 0, lpDst
->u2
.lpszLongNameA
);
1419 /* Copy as required */
1420 CopyMemory( lpDst
, lpSrc
, lpSrc
->dwSize
);
1424 if( lpSrc
->u1
.lpszShortNameA
)
1426 lpDst
->u1
.lpszShortNameA
= HeapAlloc( GetProcessHeap(), 0,
1427 strlen(lpSrc
->u1
.lpszShortNameA
)+1 );
1428 strcpy( lpDst
->u1
.lpszShortNameA
, lpSrc
->u1
.lpszShortNameA
);
1430 if( lpSrc
->u2
.lpszLongNameA
)
1432 lpDst
->u2
.lpszLongNameA
= HeapAlloc( GetProcessHeap(), 0,
1433 strlen(lpSrc
->u2
.lpszLongNameA
)+1 );
1434 strcpy( lpDst
->u2
.lpszLongNameA
, lpSrc
->u2
.lpszLongNameA
);
1439 if( lpSrc
->u1
.lpszShortNameA
)
1441 lpDst
->u1
.lpszShortName
= HeapAlloc( GetProcessHeap(), 0,
1442 (strlenW(lpSrc
->u1
.lpszShortName
)+1)*sizeof(WCHAR
) );
1443 strcpyW( lpDst
->u1
.lpszShortName
, lpSrc
->u1
.lpszShortName
);
1445 if( lpSrc
->u2
.lpszLongNameA
)
1447 lpDst
->u2
.lpszLongName
= HeapAlloc( GetProcessHeap(), 0,
1448 (strlenW(lpSrc
->u2
.lpszLongName
)+1)*sizeof(WCHAR
) );
1449 strcpyW( lpDst
->u2
.lpszLongName
, lpSrc
->u2
.lpszLongName
);
1457 DP_SetPlayerData( lpPlayerData lpPData
, DWORD dwFlags
,
1458 LPVOID lpData
, DWORD dwDataSize
)
1460 /* Clear out the data with this player */
1461 if( dwFlags
& DPSET_LOCAL
)
1463 if ( lpPData
->dwLocalDataSize
!= 0 )
1465 HeapFree( GetProcessHeap(), 0, lpPData
->lpLocalData
);
1466 lpPData
->lpLocalData
= NULL
;
1467 lpPData
->dwLocalDataSize
= 0;
1472 if( lpPData
->dwRemoteDataSize
!= 0 )
1474 HeapFree( GetProcessHeap(), 0, lpPData
->lpRemoteData
);
1475 lpPData
->lpRemoteData
= NULL
;
1476 lpPData
->dwRemoteDataSize
= 0;
1480 /* Reallocate for new data */
1481 if( lpData
!= NULL
)
1484 if( dwFlags
& DPSET_LOCAL
)
1486 lpPData
->lpLocalData
= lpData
;
1487 lpPData
->dwLocalDataSize
= dwDataSize
;
1491 lpPData
->lpRemoteData
= HeapAlloc( GetProcessHeap(), 0, dwDataSize
);
1492 CopyMemory( lpPData
->lpRemoteData
, lpData
, dwDataSize
);
1493 lpPData
->dwRemoteDataSize
= dwDataSize
;
1499 /* Note: lpMsgHdr is NULL for local creation, non NULL for remote creation */
1500 static HRESULT
DP_IF_CreatePlayer( IDirectPlayImpl
*This
, void *lpMsgHdr
, DPID
*lpidPlayer
,
1501 DPNAME
*lpPlayerName
, HANDLE hEvent
, void *lpData
, DWORD dwDataSize
, DWORD dwFlags
,
1505 lpPlayerData lpPData
;
1506 lpPlayerList lpPList
;
1507 DWORD dwCreateFlags
= 0;
1509 TRACE( "(%p)->(%p,%p,%p,%p,0x%08x,0x%08x,%u)\n",
1510 This
, lpidPlayer
, lpPlayerName
, hEvent
, lpData
,
1511 dwDataSize
, dwFlags
, bAnsi
);
1512 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
1514 return DPERR_UNINITIALIZED
;
1519 dwFlags
= DPPLAYER_SPECTATOR
;
1522 if( lpidPlayer
== NULL
)
1524 return DPERR_INVALIDPARAMS
;
1528 /* Determine the creation flags for the player. These will be passed
1529 * to the name server if requesting a player id and to the SP when
1530 * informing it of the player creation
1533 if( dwFlags
& DPPLAYER_SERVERPLAYER
)
1535 if( *lpidPlayer
== DPID_SERVERPLAYER
)
1537 /* Server player for the host interface */
1538 dwCreateFlags
|= DPLAYI_PLAYER_APPSERVER
;
1540 else if( *lpidPlayer
== DPID_NAME_SERVER
)
1542 /* Name server - master of everything */
1543 dwCreateFlags
|= (DPLAYI_PLAYER_NAMESRVR
|DPLAYI_PLAYER_SYSPLAYER
);
1547 /* Server player for a non host interface */
1548 dwCreateFlags
|= DPLAYI_PLAYER_SYSPLAYER
;
1552 if( lpMsgHdr
== NULL
)
1553 dwCreateFlags
|= DPLAYI_PLAYER_PLAYERLOCAL
;
1556 /* Verify we know how to handle all the flags */
1557 if( !( ( dwFlags
& DPPLAYER_SERVERPLAYER
) ||
1558 ( dwFlags
& DPPLAYER_SPECTATOR
)
1562 /* Assume non fatal failure */
1563 ERR( "unknown dwFlags = 0x%08x\n", dwFlags
);
1566 /* If the name is not specified, we must provide one */
1567 if( *lpidPlayer
== DPID_UNKNOWN
)
1569 /* If we are the session master, we dish out the group/player ids */
1570 if( This
->dp2
->bHostInterface
)
1572 *lpidPlayer
= DP_NextObjectId();
1576 hr
= DP_MSG_SendRequestPlayerId( This
, dwCreateFlags
, lpidPlayer
);
1580 ERR( "Request for ID failed: %s\n", DPLAYX_HresultToString( hr
) );
1587 /* FIXME: Would be nice to perhaps verify that we don't already have
1592 /* We pass creation flags, so we can distinguish sysplayers and not count them in the current
1594 lpPData
= DP_CreatePlayer( This
, lpidPlayer
, lpPlayerName
, dwCreateFlags
,
1597 if( lpPData
== NULL
)
1599 return DPERR_CANTADDPLAYER
;
1602 /* Create the list object and link it in */
1603 lpPList
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *lpPList
) );
1604 if( lpPList
== NULL
)
1606 FIXME( "Memory leak\n" );
1607 return DPERR_CANTADDPLAYER
;
1611 lpPList
->lpPData
= lpPData
;
1613 /* Add the player to the system group */
1614 DPQ_INSERT( This
->dp2
->lpSysGroup
->players
, lpPList
, players
);
1616 /* Update the information and send it to all players in the session */
1617 DP_SetPlayerData( lpPData
, DPSET_REMOTE
, lpData
, dwDataSize
);
1619 /* Let the SP know that we've created this player */
1620 if( This
->dp2
->spData
.lpCB
->CreatePlayer
)
1622 DPSP_CREATEPLAYERDATA data
;
1624 data
.idPlayer
= *lpidPlayer
;
1625 data
.dwFlags
= dwCreateFlags
;
1626 data
.lpSPMessageHeader
= lpMsgHdr
;
1627 data
.lpISP
= This
->dp2
->spData
.lpISP
;
1629 TRACE( "Calling SP CreatePlayer 0x%08x: dwFlags: 0x%08x lpMsgHdr: %p\n",
1630 *lpidPlayer
, data
.dwFlags
, data
.lpSPMessageHeader
);
1632 hr
= (*This
->dp2
->spData
.lpCB
->CreatePlayer
)( &data
);
1637 ERR( "Failed to create player with sp: %s\n", DPLAYX_HresultToString(hr
) );
1641 /* Now let the SP know that this player is a member of the system group */
1642 if( This
->dp2
->spData
.lpCB
->AddPlayerToGroup
)
1644 DPSP_ADDPLAYERTOGROUPDATA data
;
1646 data
.idPlayer
= *lpidPlayer
;
1647 data
.idGroup
= DPID_SYSTEM_GROUP
;
1648 data
.lpISP
= This
->dp2
->spData
.lpISP
;
1650 TRACE( "Calling SP AddPlayerToGroup (sys group)\n" );
1652 hr
= (*This
->dp2
->spData
.lpCB
->AddPlayerToGroup
)( &data
);
1657 ERR( "Failed to add player to sys group with sp: %s\n",
1658 DPLAYX_HresultToString(hr
) );
1663 if( !This
->dp2
->bHostInterface
)
1665 /* Let the name server know about the creation of this player */
1666 /* FIXME: Is this only to be done for the creation of a server player or
1667 * is this used for regular players? If only for server players, move
1668 * this call to DP_SecureOpen(...);
1671 TRACE( "Sending message to self to get my addr\n" );
1672 DP_MSG_ToSelf( This
, *lpidPlayer
); /* This is a hack right now */
1675 hr
= DP_MSG_ForwardPlayerCreation( This
, *lpidPlayer
);
1678 /* Inform all other peers of the creation of a new player. If there are
1679 * no peers keep this quiet.
1680 * Also, if this was a remote event, no need to rebroadcast it.
1682 if( ( lpMsgHdr
== NULL
) &&
1683 This
->dp2
->lpSessionDesc
&&
1684 ( This
->dp2
->lpSessionDesc
->dwFlags
& DPSESSION_MULTICASTSERVER
) )
1686 DPMSG_CREATEPLAYERORGROUP msg
;
1687 msg
.dwType
= DPSYS_CREATEPLAYERORGROUP
;
1689 msg
.dwPlayerType
= DPPLAYERTYPE_PLAYER
;
1690 msg
.dpId
= *lpidPlayer
;
1691 msg
.dwCurrentPlayers
= 0; /* FIXME: Incorrect */
1692 msg
.lpData
= lpData
;
1693 msg
.dwDataSize
= dwDataSize
;
1694 msg
.dpnName
= *lpPlayerName
;
1695 msg
.dpIdParent
= DPID_NOPARENT_GROUP
;
1696 msg
.dwFlags
= DPMSG_CREATEPLAYER_DWFLAGS( dwFlags
);
1698 /* FIXME: Correct to just use send effectively? */
1699 /* FIXME: Should size include data w/ message or just message "header" */
1700 /* FIXME: Check return code */
1701 hr
= IDirectPlayX_SendEx( &This
->IDirectPlay4_iface
, DPID_SERVERPLAYER
, DPID_ALLPLAYERS
, 0,
1702 &msg
, sizeof( msg
), 0, 0, NULL
, NULL
);
1709 static HRESULT WINAPI
IDirectPlay2AImpl_CreatePlayer( IDirectPlay2A
*iface
, DPID
*lpidPlayer
,
1710 DPNAME
*name
, HANDLE event
, void *data
, DWORD size
, DWORD flags
)
1712 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
1713 return IDirectPlayX_CreatePlayer( &This
->IDirectPlay4A_iface
, lpidPlayer
, name
, event
, data
,
1717 static HRESULT WINAPI
IDirectPlay2Impl_CreatePlayer( IDirectPlay2
*iface
, DPID
*lpidPlayer
,
1718 DPNAME
*name
, HANDLE event
, void *data
, DWORD size
, DWORD flags
)
1720 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
1721 return IDirectPlayX_CreatePlayer( &This
->IDirectPlay4_iface
, lpidPlayer
, name
, event
, data
,
1725 static HRESULT WINAPI
IDirectPlay3AImpl_CreatePlayer( IDirectPlay3A
*iface
, DPID
*lpidPlayer
,
1726 DPNAME
*name
, HANDLE event
, void *data
, DWORD size
, DWORD flags
)
1728 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
1729 return IDirectPlayX_CreatePlayer( &This
->IDirectPlay4_iface
, lpidPlayer
, name
, event
, data
,
1733 static HRESULT WINAPI
IDirectPlay3Impl_CreatePlayer( IDirectPlay3
*iface
, DPID
*lpidPlayer
,
1734 DPNAME
*name
, HANDLE event
, void *data
, DWORD size
, DWORD flags
)
1736 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
1737 return IDirectPlayX_CreatePlayer( &This
->IDirectPlay4_iface
, lpidPlayer
, name
, event
, data
,
1741 static HRESULT WINAPI
IDirectPlay4AImpl_CreatePlayer( IDirectPlay4A
*iface
, DPID
*lpidPlayer
,
1742 DPNAME
*lpPlayerName
, HANDLE hEvent
, void *lpData
, DWORD dwDataSize
, DWORD dwFlags
)
1744 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
1746 if( lpidPlayer
== NULL
)
1748 return DPERR_INVALIDPARAMS
;
1751 if( dwFlags
& DPPLAYER_SERVERPLAYER
)
1753 *lpidPlayer
= DPID_SERVERPLAYER
;
1757 *lpidPlayer
= DPID_UNKNOWN
;
1760 return DP_IF_CreatePlayer( This
, NULL
, lpidPlayer
, lpPlayerName
, hEvent
,
1761 lpData
, dwDataSize
, dwFlags
, TRUE
);
1764 static HRESULT WINAPI
IDirectPlay4Impl_CreatePlayer( IDirectPlay4
*iface
, DPID
*lpidPlayer
,
1765 DPNAME
*lpPlayerName
, HANDLE hEvent
, void *lpData
, DWORD dwDataSize
, DWORD dwFlags
)
1767 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
1769 if( lpidPlayer
== NULL
)
1771 return DPERR_INVALIDPARAMS
;
1774 if( dwFlags
& DPPLAYER_SERVERPLAYER
)
1776 *lpidPlayer
= DPID_SERVERPLAYER
;
1780 *lpidPlayer
= DPID_UNKNOWN
;
1783 return DP_IF_CreatePlayer( This
, NULL
, lpidPlayer
, lpPlayerName
, hEvent
,
1784 lpData
, dwDataSize
, dwFlags
, FALSE
);
1787 static DPID
DP_GetRemoteNextObjectId(void)
1792 return DP_NextObjectId();
1795 static HRESULT WINAPI
IDirectPlay2AImpl_DeletePlayerFromGroup( IDirectPlay2A
*iface
, DPID group
,
1798 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
1799 return IDirectPlayX_DeletePlayerFromGroup( &This
->IDirectPlay4A_iface
, group
, player
);
1802 static HRESULT WINAPI
IDirectPlay2Impl_DeletePlayerFromGroup( IDirectPlay2
*iface
, DPID group
,
1805 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
1806 return IDirectPlayX_DeletePlayerFromGroup( &This
->IDirectPlay4_iface
, group
, player
);
1809 static HRESULT WINAPI
IDirectPlay3AImpl_DeletePlayerFromGroup( IDirectPlay3A
*iface
, DPID group
,
1812 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
1813 return IDirectPlayX_DeletePlayerFromGroup( &This
->IDirectPlay4_iface
, group
, player
);
1816 static HRESULT WINAPI
IDirectPlay3Impl_DeletePlayerFromGroup( IDirectPlay3
*iface
, DPID group
,
1819 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
1820 return IDirectPlayX_DeletePlayerFromGroup( &This
->IDirectPlay4_iface
, group
, player
);
1823 static HRESULT WINAPI
IDirectPlay4AImpl_DeletePlayerFromGroup( IDirectPlay4A
*iface
, DPID group
,
1826 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
1827 return IDirectPlayX_DeletePlayerFromGroup( &This
->IDirectPlay4_iface
, group
, player
);
1830 static HRESULT WINAPI
IDirectPlay4Impl_DeletePlayerFromGroup( IDirectPlay4
*iface
, DPID group
,
1833 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
1839 TRACE( "(%p)->(0x%08x,0x%08x)\n", This
, group
, player
);
1841 /* Find the group */
1842 if ( ( gdata
= DP_FindAnyGroup( This
, group
) ) == NULL
)
1843 return DPERR_INVALIDGROUP
;
1845 /* Find the player */
1846 if ( DP_FindPlayer( This
, player
) == NULL
)
1847 return DPERR_INVALIDPLAYER
;
1849 /* Remove the player shortcut from the group */
1850 DPQ_REMOVE_ENTRY( gdata
->players
, players
, lpPData
->dpid
, ==, player
, plist
);
1853 return DPERR_INVALIDPLAYER
;
1855 /* One less reference */
1856 plist
->lpPData
->uRef
--;
1858 /* Delete the Player List element */
1859 HeapFree( GetProcessHeap(), 0, plist
);
1861 /* Inform the SP if they care */
1862 if ( This
->dp2
->spData
.lpCB
->RemovePlayerFromGroup
)
1864 DPSP_REMOVEPLAYERFROMGROUPDATA data
;
1866 TRACE( "Calling SP RemovePlayerFromGroup\n" );
1867 data
.idPlayer
= player
;
1868 data
.idGroup
= group
;
1869 data
.lpISP
= This
->dp2
->spData
.lpISP
;
1870 hr
= (*This
->dp2
->spData
.lpCB
->RemovePlayerFromGroup
)( &data
);
1873 /* Need to send a DELETEPLAYERFROMGROUP message */
1874 FIXME( "Need to send a message\n" );
1879 typedef struct _DPRGOPContext
1881 IDirectPlayImpl
*This
;
1884 } DPRGOPContext
, *lpDPRGOPContext
;
1886 static BOOL CALLBACK
1887 cbRemoveGroupOrPlayer(
1894 lpDPRGOPContext lpCtxt
= (lpDPRGOPContext
)lpContext
;
1896 TRACE( "Removing element:0x%08x (type:0x%08x) from element:0x%08x\n",
1897 dpId
, dwPlayerType
, lpCtxt
->idGroup
);
1899 if( dwPlayerType
== DPPLAYERTYPE_GROUP
)
1901 if ( FAILED( IDirectPlayX_DeleteGroupFromGroup( &lpCtxt
->This
->IDirectPlay4_iface
,
1902 lpCtxt
->idGroup
, dpId
) ) )
1903 ERR( "Unable to delete group 0x%08x from group 0x%08x\n", dpId
, lpCtxt
->idGroup
);
1905 else if ( FAILED( IDirectPlayX_DeletePlayerFromGroup( &lpCtxt
->This
->IDirectPlay4_iface
,
1906 lpCtxt
->idGroup
, dpId
) ) )
1907 ERR( "Unable to delete player 0x%08x from grp 0x%08x\n", dpId
, lpCtxt
->idGroup
);
1909 return TRUE
; /* Continue enumeration */
1912 static HRESULT
DP_IF_DestroyGroup( IDirectPlayImpl
*This
, void *lpMsgHdr
, DPID idGroup
, BOOL bAnsi
)
1914 lpGroupData lpGData
;
1915 DPRGOPContext context
;
1917 FIXME( "(%p)->(%p,0x%08x,%u): semi stub\n",
1918 This
, lpMsgHdr
, idGroup
, bAnsi
);
1920 /* Find the group */
1921 if( ( lpGData
= DP_FindAnyGroup( This
, idGroup
) ) == NULL
)
1923 return DPERR_INVALIDPLAYER
; /* yes player */
1926 context
.This
= This
;
1927 context
.bAnsi
= bAnsi
;
1928 context
.idGroup
= idGroup
;
1930 /* Remove all players that this group has */
1931 IDirectPlayX_EnumGroupPlayers( &This
->IDirectPlay4_iface
, idGroup
, NULL
, cbRemoveGroupOrPlayer
,
1934 /* Remove all links to groups that this group has since this is dp3 */
1935 IDirectPlayX_EnumGroupsInGroup( &This
->IDirectPlay4_iface
, idGroup
, NULL
, cbRemoveGroupOrPlayer
,
1936 (void*)&context
, 0 );
1938 /* Remove this group from the parent group - if it has one */
1939 if( ( idGroup
!= DPID_SYSTEM_GROUP
) && ( lpGData
->parent
!= DPID_SYSTEM_GROUP
) )
1940 IDirectPlayX_DeleteGroupFromGroup( &This
->IDirectPlay4_iface
, lpGData
->parent
, idGroup
);
1942 /* Now delete this group data and list from the system group */
1943 DP_DeleteGroup( This
, idGroup
);
1945 /* Let the SP know that we've destroyed this group */
1946 if( This
->dp2
->spData
.lpCB
->DeleteGroup
)
1948 DPSP_DELETEGROUPDATA data
;
1950 FIXME( "data.dwFlags is incorrect\n" );
1952 data
.idGroup
= idGroup
;
1954 data
.lpISP
= This
->dp2
->spData
.lpISP
;
1956 (*This
->dp2
->spData
.lpCB
->DeleteGroup
)( &data
);
1959 FIXME( "Send out a DESTORYPLAYERORGROUP message\n" );
1964 static HRESULT WINAPI
IDirectPlay2AImpl_DestroyGroup( IDirectPlay2A
*iface
, DPID group
)
1966 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
1967 return IDirectPlayX_DestroyGroup( &This
->IDirectPlay4A_iface
, group
);
1970 static HRESULT WINAPI
IDirectPlay2Impl_DestroyGroup( IDirectPlay2
*iface
, DPID group
)
1972 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
1973 return IDirectPlayX_DestroyGroup( &This
->IDirectPlay4_iface
, group
);
1976 static HRESULT WINAPI
IDirectPlay3AImpl_DestroyGroup( IDirectPlay3A
*iface
, DPID group
)
1978 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
1979 return IDirectPlayX_DestroyGroup( &This
->IDirectPlay4_iface
, group
);
1982 static HRESULT WINAPI
IDirectPlay3Impl_DestroyGroup( IDirectPlay3
*iface
, DPID group
)
1984 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
1985 return IDirectPlayX_DestroyGroup( &This
->IDirectPlay4_iface
, group
);
1988 static HRESULT WINAPI
IDirectPlay4AImpl_DestroyGroup( IDirectPlay4A
*iface
, DPID idGroup
)
1990 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
1991 return DP_IF_DestroyGroup( This
, NULL
, idGroup
, TRUE
);
1994 static HRESULT WINAPI
IDirectPlay4Impl_DestroyGroup( IDirectPlay4
*iface
, DPID idGroup
)
1996 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
1997 return DP_IF_DestroyGroup( This
, NULL
, idGroup
, FALSE
);
2000 typedef struct _DPFAGContext
2002 IDirectPlayImpl
*This
;
2005 } DPFAGContext
, *lpDPFAGContext
;
2007 static HRESULT
DP_IF_DestroyPlayer( IDirectPlayImpl
*This
, void *lpMsgHdr
, DPID idPlayer
,
2010 DPFAGContext cbContext
;
2012 FIXME( "(%p)->(%p,0x%08x,%u): semi stub\n",
2013 This
, lpMsgHdr
, idPlayer
, bAnsi
);
2015 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
2017 return DPERR_UNINITIALIZED
;
2020 if( DP_FindPlayer( This
, idPlayer
) == NULL
)
2022 return DPERR_INVALIDPLAYER
;
2025 /* FIXME: If the player is remote, we must be the host to delete this */
2027 cbContext
.This
= This
;
2028 cbContext
.idPlayer
= idPlayer
;
2029 cbContext
.bAnsi
= bAnsi
;
2031 /* Find each group and call DeletePlayerFromGroup if the player is a
2032 member of the group */
2033 IDirectPlayX_EnumGroups( &This
->IDirectPlay4_iface
, NULL
, cbDeletePlayerFromAllGroups
, &cbContext
,
2036 /* Now delete player and player list from the sys group */
2037 DP_DeletePlayer( This
, idPlayer
);
2039 /* Let the SP know that we've destroyed this group */
2040 if( This
->dp2
->spData
.lpCB
->DeletePlayer
)
2042 DPSP_DELETEPLAYERDATA data
;
2044 FIXME( "data.dwFlags is incorrect\n" );
2046 data
.idPlayer
= idPlayer
;
2048 data
.lpISP
= This
->dp2
->spData
.lpISP
;
2050 (*This
->dp2
->spData
.lpCB
->DeletePlayer
)( &data
);
2053 FIXME( "Send a DELETEPLAYERORGROUP msg\n" );
2058 static BOOL CALLBACK
2059 cbDeletePlayerFromAllGroups(
2066 lpDPFAGContext lpCtxt
= (lpDPFAGContext
)lpContext
;
2068 if( dwPlayerType
== DPPLAYERTYPE_GROUP
)
2070 IDirectPlayX_DeletePlayerFromGroup( &lpCtxt
->This
->IDirectPlay4_iface
, dpId
, lpCtxt
->idPlayer
);
2072 /* Enumerate all groups in this group since this will normally only
2073 * be called for top level groups
2075 IDirectPlayX_EnumGroupsInGroup( &lpCtxt
->This
->IDirectPlay4_iface
, dpId
, NULL
,
2076 cbDeletePlayerFromAllGroups
, lpContext
, DPENUMGROUPS_ALL
);
2081 ERR( "Group callback has dwPlayerType = 0x%08x\n", dwPlayerType
);
2087 static HRESULT WINAPI
IDirectPlay2AImpl_DestroyPlayer( IDirectPlay2A
*iface
, DPID player
)
2089 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2090 return IDirectPlayX_DestroyPlayer( &This
->IDirectPlay4A_iface
, player
);
2093 static HRESULT WINAPI
IDirectPlay2Impl_DestroyPlayer( IDirectPlay2
*iface
, DPID player
)
2095 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2096 return IDirectPlayX_DestroyPlayer( &This
->IDirectPlay4_iface
, player
);
2099 static HRESULT WINAPI
IDirectPlay3AImpl_DestroyPlayer( IDirectPlay3A
*iface
, DPID player
)
2101 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2102 return IDirectPlayX_DestroyPlayer( &This
->IDirectPlay4_iface
, player
);
2105 static HRESULT WINAPI
IDirectPlay3Impl_DestroyPlayer( IDirectPlay3
*iface
, DPID player
)
2107 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2108 return IDirectPlayX_DestroyPlayer( &This
->IDirectPlay4_iface
, player
);
2111 static HRESULT WINAPI
IDirectPlay4AImpl_DestroyPlayer( IDirectPlay4A
*iface
, DPID idPlayer
)
2113 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
2114 return DP_IF_DestroyPlayer( This
, NULL
, idPlayer
, TRUE
);
2117 static HRESULT WINAPI
IDirectPlay4Impl_DestroyPlayer( IDirectPlay4
*iface
, DPID idPlayer
)
2119 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
2120 return DP_IF_DestroyPlayer( This
, NULL
, idPlayer
, FALSE
);
2123 static HRESULT WINAPI
IDirectPlay2AImpl_EnumGroupPlayers( IDirectPlay2A
*iface
, DPID group
,
2124 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2126 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2127 return IDirectPlayX_EnumGroupPlayers( &This
->IDirectPlay4A_iface
, group
, instance
,
2128 enumplayercb
, context
, flags
);
2131 static HRESULT WINAPI
IDirectPlay2Impl_EnumGroupPlayers( IDirectPlay2
*iface
, DPID group
,
2132 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2134 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2135 return IDirectPlayX_EnumGroupPlayers( &This
->IDirectPlay4_iface
, group
, instance
,
2136 enumplayercb
, context
, flags
);
2139 static HRESULT WINAPI
IDirectPlay3AImpl_EnumGroupPlayers( IDirectPlay3A
*iface
, DPID group
,
2140 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2142 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2143 return IDirectPlayX_EnumGroupPlayers( &This
->IDirectPlay4_iface
, group
, instance
,
2144 enumplayercb
, context
, flags
);
2147 static HRESULT WINAPI
IDirectPlay3Impl_EnumGroupPlayers( IDirectPlay3
*iface
, DPID group
,
2148 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2150 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2151 return IDirectPlayX_EnumGroupPlayers( &This
->IDirectPlay4_iface
, group
, instance
,
2152 enumplayercb
, context
, flags
);
2155 static HRESULT WINAPI
IDirectPlay4AImpl_EnumGroupPlayers( IDirectPlay4A
*iface
, DPID group
,
2156 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2158 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
2159 return IDirectPlayX_EnumGroupPlayers( &This
->IDirectPlay4_iface
, group
, instance
, enumplayercb
,
2163 static HRESULT WINAPI
IDirectPlay4Impl_EnumGroupPlayers( IDirectPlay4
*iface
, DPID group
,
2164 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2166 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
2170 FIXME( "(%p)->(0x%08x,%p,%p,%p,0x%08x): semi stub\n", This
, group
, instance
, enumplayercb
,
2173 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
2174 return DPERR_UNINITIALIZED
;
2176 /* Find the group */
2177 if ( ( gdata
= DP_FindAnyGroup( This
, group
) ) == NULL
)
2178 return DPERR_INVALIDGROUP
;
2180 if ( DPQ_IS_EMPTY( gdata
->players
) )
2183 /* Walk the players in this group */
2184 for( plist
= DPQ_FIRST( gdata
->players
); ; plist
= DPQ_NEXT( plist
->players
) )
2186 /* We do not enum the name server or app server as they are of no
2187 * consequence to the end user.
2189 if ( ( plist
->lpPData
->dpid
!= DPID_NAME_SERVER
) &&
2190 ( plist
->lpPData
->dpid
!= DPID_SERVERPLAYER
) )
2192 /* FIXME: Need to add stuff for flags checking */
2193 if ( !enumplayercb( plist
->lpPData
->dpid
, DPPLAYERTYPE_PLAYER
,
2194 &plist
->lpPData
->name
, plist
->lpPData
->dwFlags
, context
) )
2195 /* User requested break */
2199 if ( DPQ_IS_ENDOFLIST( plist
->players
) )
2205 /* NOTE: This only enumerates top level groups (created with CreateGroup) */
2206 static HRESULT WINAPI
IDirectPlay2AImpl_EnumGroups( IDirectPlay2A
*iface
, GUID
*instance
,
2207 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2209 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2210 return IDirectPlayX_EnumGroups( &This
->IDirectPlay4A_iface
, instance
, enumplayercb
, context
,
2214 static HRESULT WINAPI
IDirectPlay2Impl_EnumGroups( IDirectPlay2
*iface
, GUID
*instance
,
2215 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2217 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2218 return IDirectPlayX_EnumGroups( &This
->IDirectPlay4_iface
, instance
, enumplayercb
, context
,
2222 static HRESULT WINAPI
IDirectPlay3AImpl_EnumGroups( IDirectPlay3A
*iface
, GUID
*instance
,
2223 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2225 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2226 return IDirectPlayX_EnumGroups( &This
->IDirectPlay4_iface
, instance
, enumplayercb
, context
,
2230 static HRESULT WINAPI
IDirectPlay3Impl_EnumGroups( IDirectPlay3
*iface
, GUID
*instance
,
2231 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2233 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2234 return IDirectPlayX_EnumGroups( &This
->IDirectPlay4_iface
, instance
, enumplayercb
, context
,
2238 static HRESULT WINAPI
IDirectPlay4AImpl_EnumGroups( IDirectPlay4A
*iface
, GUID
*instance
,
2239 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2241 return IDirectPlayX_EnumGroupsInGroup( iface
, DPID_SYSTEM_GROUP
, instance
, enumplayercb
,
2245 static HRESULT WINAPI
IDirectPlay4Impl_EnumGroups ( IDirectPlay4
*iface
, GUID
*instance
,
2246 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2248 return IDirectPlayX_EnumGroupsInGroup( iface
, DPID_SYSTEM_GROUP
, instance
, enumplayercb
,
2252 static HRESULT WINAPI
IDirectPlay2AImpl_EnumPlayers( IDirectPlay2A
*iface
, GUID
*instance
,
2253 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2255 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2256 return IDirectPlayX_EnumPlayers( &This
->IDirectPlay4A_iface
, instance
, enumplayercb
, context
,
2260 static HRESULT WINAPI
IDirectPlay2Impl_EnumPlayers( IDirectPlay2
*iface
, GUID
*instance
,
2261 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2263 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2264 return IDirectPlayX_EnumPlayers( &This
->IDirectPlay4_iface
, instance
, enumplayercb
, context
,
2268 static HRESULT WINAPI
IDirectPlay3AImpl_EnumPlayers( IDirectPlay3A
*iface
, GUID
*instance
,
2269 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2271 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2272 return IDirectPlayX_EnumPlayers( &This
->IDirectPlay4_iface
, instance
, enumplayercb
, context
,
2276 static HRESULT WINAPI
IDirectPlay3Impl_EnumPlayers( IDirectPlay3
*iface
, GUID
*instance
,
2277 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2279 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2280 return IDirectPlayX_EnumPlayers( &This
->IDirectPlay4_iface
, instance
, enumplayercb
, context
,
2284 static HRESULT WINAPI
IDirectPlay4AImpl_EnumPlayers( IDirectPlay4A
*iface
, GUID
*instance
,
2285 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2287 return IDirectPlayX_EnumGroupPlayers( iface
, DPID_SYSTEM_GROUP
, instance
, enumplayercb
,
2291 static HRESULT WINAPI
IDirectPlay4Impl_EnumPlayers( IDirectPlay4
*iface
, GUID
*instance
,
2292 LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
2294 return IDirectPlayX_EnumGroupPlayers( iface
, DPID_SYSTEM_GROUP
, instance
, enumplayercb
,
2298 /* This function should call the registered callback function that the user
2299 passed into EnumSessions for each entry available.
2301 static void DP_InvokeEnumSessionCallbacks
2302 ( LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2
,
2307 LPDPSESSIONDESC2 lpSessionDesc
;
2309 FIXME( ": not checking for conditions\n" );
2311 /* Not sure if this should be pruning but it's convenient */
2312 NS_PruneSessionCache( lpNSInfo
);
2314 NS_ResetSessionEnumeration( lpNSInfo
);
2316 /* Enumerate all sessions */
2317 /* FIXME: Need to indicate ANSI */
2318 while( (lpSessionDesc
= NS_WalkSessions( lpNSInfo
) ) != NULL
)
2320 TRACE( "EnumSessionsCallback2 invoked\n" );
2321 if( !lpEnumSessionsCallback2( lpSessionDesc
, &dwTimeout
, 0, lpContext
) )
2327 /* Invoke one last time to indicate that there is no more to come */
2328 lpEnumSessionsCallback2( NULL
, &dwTimeout
, DPESC_TIMEDOUT
, lpContext
);
2331 static DWORD CALLBACK
DP_EnumSessionsSendAsyncRequestThread( LPVOID lpContext
)
2333 EnumSessionAsyncCallbackData
* data
= lpContext
;
2334 HANDLE hSuicideRequest
= data
->hSuicideRequest
;
2335 DWORD dwTimeout
= data
->dwTimeout
;
2337 TRACE( "Thread started with timeout = 0x%08x\n", dwTimeout
);
2343 /* Sleep up to dwTimeout waiting for request to terminate thread */
2344 if( WaitForSingleObject( hSuicideRequest
, dwTimeout
) == WAIT_OBJECT_0
)
2346 TRACE( "Thread terminating on terminate request\n" );
2350 /* Now resend the enum request */
2351 hr
= NS_SendSessionRequestBroadcast( &data
->requestGuid
,
2352 data
->dwEnumSessionFlags
,
2357 ERR( "Enum broadcase request failed: %s\n", DPLAYX_HresultToString(hr
) );
2358 /* FIXME: Should we kill this thread? How to inform the main thread? */
2363 TRACE( "Thread terminating\n" );
2365 /* Clean up the thread data */
2366 CloseHandle( hSuicideRequest
);
2367 HeapFree( GetProcessHeap(), 0, lpContext
);
2369 /* FIXME: Need to have some notification to main app thread that this is
2370 * dead. It would serve two purposes. 1) allow sync on termination
2371 * so that we don't actually send something to ourselves when we
2372 * become name server (race condition) and 2) so that if we die
2373 * abnormally something else will be able to tell.
2379 static void DP_KillEnumSessionThread( IDirectPlayImpl
*This
)
2381 /* Does a thread exist? If so we were doing an async enum session */
2382 if( This
->dp2
->hEnumSessionThread
!= INVALID_HANDLE_VALUE
)
2384 TRACE( "Killing EnumSession thread %p\n",
2385 This
->dp2
->hEnumSessionThread
);
2387 /* Request that the thread kill itself nicely */
2388 SetEvent( This
->dp2
->hKillEnumSessionThreadEvent
);
2389 CloseHandle( This
->dp2
->hKillEnumSessionThreadEvent
);
2391 /* We no longer need to know about the thread */
2392 CloseHandle( This
->dp2
->hEnumSessionThread
);
2394 This
->dp2
->hEnumSessionThread
= INVALID_HANDLE_VALUE
;
2398 static HRESULT WINAPI
IDirectPlay2AImpl_EnumSessions( IDirectPlay2A
*iface
, DPSESSIONDESC2
*sdesc
,
2399 DWORD timeout
, LPDPENUMSESSIONSCALLBACK2 enumsessioncb
, void *context
, DWORD flags
)
2401 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2402 return IDirectPlayX_EnumSessions( &This
->IDirectPlay4A_iface
, sdesc
, timeout
, enumsessioncb
,
2406 static HRESULT WINAPI
IDirectPlay2Impl_EnumSessions( IDirectPlay2
*iface
, DPSESSIONDESC2
*sdesc
,
2407 DWORD timeout
, LPDPENUMSESSIONSCALLBACK2 enumsessioncb
, void *context
, DWORD flags
)
2409 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2410 return IDirectPlayX_EnumSessions( &This
->IDirectPlay4_iface
, sdesc
, timeout
, enumsessioncb
,
2414 static HRESULT WINAPI
IDirectPlay3AImpl_EnumSessions( IDirectPlay3A
*iface
, DPSESSIONDESC2
*sdesc
,
2415 DWORD timeout
, LPDPENUMSESSIONSCALLBACK2 enumsessioncb
, void *context
, DWORD flags
)
2417 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2418 return IDirectPlayX_EnumSessions( &This
->IDirectPlay4_iface
, sdesc
, timeout
, enumsessioncb
,
2422 static HRESULT WINAPI
IDirectPlay3Impl_EnumSessions( IDirectPlay3
*iface
, DPSESSIONDESC2
*sdesc
,
2423 DWORD timeout
, LPDPENUMSESSIONSCALLBACK2 enumsessioncb
, void *context
, DWORD flags
)
2425 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2426 return IDirectPlayX_EnumSessions( &This
->IDirectPlay4_iface
, sdesc
, timeout
, enumsessioncb
,
2430 static HRESULT WINAPI
IDirectPlay4AImpl_EnumSessions( IDirectPlay4A
*iface
, DPSESSIONDESC2
*sdesc
,
2431 DWORD timeout
, LPDPENUMSESSIONSCALLBACK2 enumsessioncb
, void *context
, DWORD flags
)
2433 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
2434 return IDirectPlayX_EnumSessions( &This
->IDirectPlay4_iface
, sdesc
, timeout
, enumsessioncb
,
2438 static HRESULT WINAPI
IDirectPlay4Impl_EnumSessions( IDirectPlay4
*iface
, DPSESSIONDESC2
*sdesc
,
2439 DWORD timeout
, LPDPENUMSESSIONSCALLBACK2 enumsessioncb
, void *context
, DWORD flags
)
2441 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
2446 TRACE( "(%p)->(%p,0x%08x,%p,%p,0x%08x)\n", This
, sdesc
, timeout
, enumsessioncb
,
2449 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
2450 return DPERR_UNINITIALIZED
;
2452 /* Can't enumerate if the interface is already open */
2453 if ( This
->dp2
->bConnectionOpen
)
2454 return DPERR_GENERIC
;
2456 /* The loading of a lobby provider _seems_ to require a backdoor loading
2457 * of the service provider to also associate with this DP object. This is
2458 * because the app doesn't seem to have to call EnumConnections and
2459 * InitializeConnection for the SP before calling this method. As such
2460 * we'll do their dirty work for them with a quick hack so as to always
2461 * load the TCP/IP service provider.
2463 * The correct solution would seem to involve creating a dialog box which
2464 * contains the possible SPs. These dialog boxes most likely follow SDK
2467 if ( This
->dp2
->bDPLSPInitialized
&& !This
->dp2
->bSPInitialized
)
2469 WARN( "Hack providing TCP/IP SP for lobby provider activated\n" );
2471 if ( !DP_BuildSPCompoundAddr( (GUID
*)&DPSPGUID_TCPIP
, &connection
, &size
) )
2473 ERR( "Can't build compound addr\n" );
2474 return DPERR_GENERIC
;
2477 hr
= IDirectPlayX_InitializeConnection( &This
->IDirectPlay4_iface
, connection
, 0 );
2481 HeapFree( GetProcessHeap(), 0, connection
);
2482 This
->dp2
->bSPInitialized
= TRUE
;
2486 /* Use the service provider default? */
2490 caps
.dwSize
= sizeof( caps
);
2492 IDirectPlayX_GetCaps( &This
->IDirectPlay4_iface
, &caps
, 0 );
2493 timeout
= caps
.dwTimeout
;
2495 timeout
= DPMSG_WAIT_5_SECS
; /* Provide the TCP/IP default */
2498 if ( flags
& DPENUMSESSIONS_STOPASYNC
)
2500 DP_KillEnumSessionThread( This
);
2504 if ( flags
& DPENUMSESSIONS_ASYNC
)
2506 /* Enumerate everything presently in the local session cache */
2507 DP_InvokeEnumSessionCallbacks( enumsessioncb
, This
->dp2
->lpNameServerData
, timeout
,
2510 if ( This
->dp2
->dwEnumSessionLock
)
2511 return DPERR_CONNECTING
;
2513 /* See if we've already created a thread to service this interface */
2514 if ( This
->dp2
->hEnumSessionThread
== INVALID_HANDLE_VALUE
)
2517 This
->dp2
->dwEnumSessionLock
++;
2519 /* Send the first enum request inline since the user may cancel a dialog
2520 * if one is presented. Also, may also have a connecting return code.
2522 hr
= NS_SendSessionRequestBroadcast( &sdesc
->guidApplication
, flags
,
2523 &This
->dp2
->spData
);
2525 if ( SUCCEEDED(hr
) )
2527 EnumSessionAsyncCallbackData
* data
= HeapAlloc( GetProcessHeap(),
2528 HEAP_ZERO_MEMORY
, sizeof( *data
) );
2529 /* FIXME: need to kill the thread on object deletion */
2530 data
->lpSpData
= &This
->dp2
->spData
;
2531 data
->requestGuid
= sdesc
->guidApplication
;
2532 data
->dwEnumSessionFlags
= flags
;
2533 data
->dwTimeout
= timeout
;
2535 This
->dp2
->hKillEnumSessionThreadEvent
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
2536 if ( !DuplicateHandle( GetCurrentProcess(), This
->dp2
->hKillEnumSessionThreadEvent
,
2537 GetCurrentProcess(), &data
->hSuicideRequest
, 0, FALSE
,
2538 DUPLICATE_SAME_ACCESS
) )
2539 ERR( "Can't duplicate thread killing handle\n" );
2541 TRACE( ": creating EnumSessionsRequest thread\n" );
2542 This
->dp2
->hEnumSessionThread
= CreateThread( NULL
, 0,
2543 DP_EnumSessionsSendAsyncRequestThread
, data
, 0, &tid
);
2545 This
->dp2
->dwEnumSessionLock
--;
2550 /* Invalidate the session cache for the interface */
2551 NS_InvalidateSessionCache( This
->dp2
->lpNameServerData
);
2552 /* Send the broadcast for session enumeration */
2553 hr
= NS_SendSessionRequestBroadcast( &sdesc
->guidApplication
, flags
, &This
->dp2
->spData
);
2554 SleepEx( timeout
, FALSE
);
2555 DP_InvokeEnumSessionCallbacks( enumsessioncb
, This
->dp2
->lpNameServerData
, timeout
,
2562 static HRESULT WINAPI
IDirectPlay2AImpl_GetCaps( IDirectPlay2A
*iface
, DPCAPS
*caps
, DWORD flags
)
2564 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2565 return IDirectPlayX_GetCaps( &This
->IDirectPlay4A_iface
, caps
, flags
);
2568 static HRESULT WINAPI
IDirectPlay2Impl_GetCaps( IDirectPlay2
*iface
, DPCAPS
*caps
, DWORD flags
)
2570 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2571 return IDirectPlayX_GetCaps( &This
->IDirectPlay4_iface
, caps
, flags
);
2574 static HRESULT WINAPI
IDirectPlay3AImpl_GetCaps( IDirectPlay3A
*iface
, DPCAPS
*caps
, DWORD flags
)
2576 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2577 return IDirectPlayX_GetCaps( &This
->IDirectPlay4_iface
, caps
, flags
);
2580 static HRESULT WINAPI
IDirectPlay3Impl_GetCaps( IDirectPlay3
*iface
, DPCAPS
*caps
, DWORD flags
)
2582 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2583 return IDirectPlayX_GetCaps( &This
->IDirectPlay4_iface
, caps
, flags
);
2586 static HRESULT WINAPI
IDirectPlay4AImpl_GetCaps( IDirectPlay4A
*iface
, DPCAPS
*caps
, DWORD flags
)
2588 return IDirectPlayX_GetPlayerCaps( iface
, DPID_ALLPLAYERS
, caps
, flags
);
2591 static HRESULT WINAPI
IDirectPlay4Impl_GetCaps( IDirectPlay4
*iface
, DPCAPS
*caps
, DWORD flags
)
2593 return IDirectPlayX_GetPlayerCaps( iface
, DPID_ALLPLAYERS
, caps
, flags
);
2596 static HRESULT WINAPI
IDirectPlay2AImpl_GetGroupData( IDirectPlay2A
*iface
, DPID group
, void *data
,
2597 DWORD
*size
, DWORD flags
)
2599 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2600 return IDirectPlayX_GetGroupData( &This
->IDirectPlay4A_iface
, group
, data
, size
, flags
);
2603 static HRESULT WINAPI
IDirectPlay2Impl_GetGroupData( IDirectPlay2
*iface
, DPID group
, void *data
,
2604 DWORD
*size
, DWORD flags
)
2606 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2607 return IDirectPlayX_GetGroupData( &This
->IDirectPlay4_iface
, group
, data
, size
, flags
);
2610 static HRESULT WINAPI
IDirectPlay3AImpl_GetGroupData( IDirectPlay3A
*iface
, DPID group
, void *data
,
2611 DWORD
*size
, DWORD flags
)
2613 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2614 return IDirectPlayX_GetGroupData( &This
->IDirectPlay4_iface
, group
, data
, size
, flags
);
2617 static HRESULT WINAPI
IDirectPlay3Impl_GetGroupData( IDirectPlay3
*iface
, DPID group
, void *data
,
2618 DWORD
*size
, DWORD flags
)
2620 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2621 return IDirectPlayX_GetGroupData( &This
->IDirectPlay4_iface
, group
, data
, size
, flags
);
2624 static HRESULT WINAPI
IDirectPlay4AImpl_GetGroupData( IDirectPlay4A
*iface
, DPID group
,
2625 void *data
, DWORD
*size
, DWORD flags
)
2627 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
2628 return IDirectPlayX_GetGroupData( &This
->IDirectPlay4_iface
, group
, data
, size
, flags
);
2631 static HRESULT WINAPI
IDirectPlay4Impl_GetGroupData( IDirectPlay4
*iface
, DPID group
,
2632 void *data
, DWORD
*size
, DWORD flags
)
2634 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
2639 TRACE( "(%p)->(0x%08x,%p,%p,0x%08x)\n", This
, group
, data
, size
, flags
);
2641 if ( ( gdata
= DP_FindAnyGroup( This
, group
) ) == NULL
)
2642 return DPERR_INVALIDGROUP
;
2644 /* How much buffer is required? */
2645 if ( flags
& DPSET_LOCAL
)
2647 bufsize
= gdata
->dwLocalDataSize
;
2648 src
= gdata
->lpLocalData
;
2652 bufsize
= gdata
->dwRemoteDataSize
;
2653 src
= gdata
->lpRemoteData
;
2656 /* Is the user requesting to know how big a buffer is required? */
2657 if ( !data
|| *size
< bufsize
)
2660 return DPERR_BUFFERTOOSMALL
;
2663 CopyMemory( data
, src
, bufsize
);
2668 static HRESULT
DP_IF_GetGroupName( IDirectPlayImpl
*This
, DPID idGroup
, void *lpData
,
2669 DWORD
*lpdwDataSize
, BOOL bAnsi
)
2671 lpGroupData lpGData
;
2672 LPDPNAME lpName
= lpData
;
2673 DWORD dwRequiredDataSize
;
2675 FIXME("(%p)->(0x%08x,%p,%p,%u) ANSI ignored\n",
2676 This
, idGroup
, lpData
, lpdwDataSize
, bAnsi
);
2678 if( ( lpGData
= DP_FindAnyGroup( This
, idGroup
) ) == NULL
)
2680 return DPERR_INVALIDGROUP
;
2683 dwRequiredDataSize
= lpGData
->name
.dwSize
;
2685 if( lpGData
->name
.u1
.lpszShortNameA
)
2687 dwRequiredDataSize
+= strlen( lpGData
->name
.u1
.lpszShortNameA
) + 1;
2690 if( lpGData
->name
.u2
.lpszLongNameA
)
2692 dwRequiredDataSize
+= strlen( lpGData
->name
.u2
.lpszLongNameA
) + 1;
2695 if( ( lpData
== NULL
) ||
2696 ( *lpdwDataSize
< dwRequiredDataSize
)
2699 *lpdwDataSize
= dwRequiredDataSize
;
2700 return DPERR_BUFFERTOOSMALL
;
2703 /* Copy the structure */
2704 CopyMemory( lpName
, &lpGData
->name
, lpGData
->name
.dwSize
);
2706 if( lpGData
->name
.u1
.lpszShortNameA
)
2708 strcpy( ((char*)lpName
)+lpGData
->name
.dwSize
,
2709 lpGData
->name
.u1
.lpszShortNameA
);
2713 lpName
->u1
.lpszShortNameA
= NULL
;
2716 if( lpGData
->name
.u1
.lpszShortNameA
)
2718 strcpy( ((char*)lpName
)+lpGData
->name
.dwSize
,
2719 lpGData
->name
.u2
.lpszLongNameA
);
2723 lpName
->u2
.lpszLongNameA
= NULL
;
2729 static HRESULT WINAPI
IDirectPlay2AImpl_GetGroupName( IDirectPlay2A
*iface
, DPID group
, void *data
,
2732 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2733 return IDirectPlayX_GetGroupName( &This
->IDirectPlay4A_iface
, group
, data
, size
);
2736 static HRESULT WINAPI
IDirectPlay2Impl_GetGroupName( IDirectPlay2
*iface
, DPID group
, void *data
,
2739 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2740 return IDirectPlayX_GetGroupName( &This
->IDirectPlay4_iface
, group
, data
, size
);
2743 static HRESULT WINAPI
IDirectPlay3AImpl_GetGroupName( IDirectPlay3A
*iface
, DPID group
, void *data
,
2746 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2747 return IDirectPlayX_GetGroupName( &This
->IDirectPlay4_iface
, group
, data
, size
);
2750 static HRESULT WINAPI
IDirectPlay3Impl_GetGroupName( IDirectPlay3
*iface
, DPID group
, void *data
,
2753 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2754 return IDirectPlayX_GetGroupName( &This
->IDirectPlay4_iface
, group
, data
, size
);
2757 static HRESULT WINAPI
IDirectPlay4AImpl_GetGroupName( IDirectPlay4A
*iface
, DPID idGroup
,
2758 void *lpData
, DWORD
*lpdwDataSize
)
2760 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
2761 return DP_IF_GetGroupName( This
, idGroup
, lpData
, lpdwDataSize
, TRUE
);
2764 static HRESULT WINAPI
IDirectPlay4Impl_GetGroupName( IDirectPlay4
*iface
, DPID idGroup
,
2765 void *lpData
, DWORD
*lpdwDataSize
)
2767 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
2768 return DP_IF_GetGroupName( This
, idGroup
, lpData
, lpdwDataSize
, FALSE
);
2771 static HRESULT WINAPI
IDirectPlay2AImpl_GetMessageCount( IDirectPlay2A
*iface
, DPID player
,
2774 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2775 return IDirectPlayX_GetMessageCount( &This
->IDirectPlay4A_iface
, player
, count
);
2778 static HRESULT WINAPI
IDirectPlay2Impl_GetMessageCount( IDirectPlay2
*iface
, DPID player
,
2781 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2782 return IDirectPlayX_GetMessageCount( &This
->IDirectPlay4_iface
, player
, count
);
2785 static HRESULT WINAPI
IDirectPlay3AImpl_GetMessageCount( IDirectPlay3A
*iface
, DPID player
,
2788 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2789 return IDirectPlayX_GetMessageCount( &This
->IDirectPlay4_iface
, player
, count
);
2792 static HRESULT WINAPI
IDirectPlay3Impl_GetMessageCount( IDirectPlay3
*iface
, DPID player
,
2795 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2796 return IDirectPlayX_GetMessageCount( &This
->IDirectPlay4_iface
, player
, count
);
2799 static HRESULT WINAPI
IDirectPlay4AImpl_GetMessageCount( IDirectPlay4A
*iface
, DPID player
,
2802 return IDirectPlayX_GetMessageQueue( iface
, 0, player
, DPMESSAGEQUEUE_RECEIVE
, count
, NULL
);
2805 static HRESULT WINAPI
IDirectPlay4Impl_GetMessageCount( IDirectPlay4
*iface
, DPID player
,
2808 return IDirectPlayX_GetMessageQueue( iface
, 0, player
, DPMESSAGEQUEUE_RECEIVE
, count
, NULL
);
2811 static HRESULT WINAPI
IDirectPlay2AImpl_GetPlayerAddress( IDirectPlay2A
*iface
, DPID player
,
2812 void *data
, DWORD
*size
)
2814 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2815 return IDirectPlayX_GetPlayerAddress( &This
->IDirectPlay4A_iface
, player
, data
, size
);
2818 static HRESULT WINAPI
IDirectPlay2Impl_GetPlayerAddress( IDirectPlay2
*iface
, DPID player
,
2819 void *data
, DWORD
*size
)
2821 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2822 return IDirectPlayX_GetPlayerAddress( &This
->IDirectPlay4_iface
, player
, data
, size
);
2825 static HRESULT WINAPI
IDirectPlay3AImpl_GetPlayerAddress( IDirectPlay3A
*iface
, DPID player
,
2826 void *data
, DWORD
*size
)
2828 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2829 return IDirectPlayX_GetPlayerAddress( &This
->IDirectPlay4_iface
, player
, data
, size
);
2832 static HRESULT WINAPI
IDirectPlay3Impl_GetPlayerAddress( IDirectPlay3
*iface
, DPID player
,
2833 void *data
, DWORD
*size
)
2835 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2836 return IDirectPlayX_GetPlayerAddress( &This
->IDirectPlay4_iface
, player
, data
, size
);
2839 static HRESULT WINAPI
IDirectPlay4AImpl_GetPlayerAddress( IDirectPlay4A
*iface
, DPID player
,
2840 void *data
, DWORD
*size
)
2842 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
2843 FIXME("(%p)->(0x%08x,%p,%p): stub\n", This
, player
, data
, size
);
2847 static HRESULT WINAPI
IDirectPlay4Impl_GetPlayerAddress( IDirectPlay4
*iface
, DPID player
,
2848 void *data
, DWORD
*size
)
2850 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
2851 FIXME( "(%p)->(0x%08x,%p,%p): stub\n", This
, player
, data
, size
);
2855 static HRESULT WINAPI
IDirectPlay2AImpl_GetPlayerCaps( IDirectPlay2A
*iface
, DPID player
,
2856 DPCAPS
*caps
, DWORD flags
)
2858 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2859 return IDirectPlayX_GetPlayerCaps( &This
->IDirectPlay4A_iface
, player
, caps
, flags
);
2862 static HRESULT WINAPI
IDirectPlay2Impl_GetPlayerCaps( IDirectPlay2
*iface
, DPID player
,
2863 DPCAPS
*caps
, DWORD flags
)
2865 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2866 return IDirectPlayX_GetPlayerCaps( &This
->IDirectPlay4_iface
, player
, caps
, flags
);
2869 static HRESULT WINAPI
IDirectPlay3AImpl_GetPlayerCaps( IDirectPlay3A
*iface
, DPID player
,
2870 DPCAPS
*caps
, DWORD flags
)
2872 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2873 return IDirectPlayX_GetPlayerCaps( &This
->IDirectPlay4_iface
, player
, caps
, flags
);
2876 static HRESULT WINAPI
IDirectPlay3Impl_GetPlayerCaps( IDirectPlay3
*iface
, DPID player
,
2877 DPCAPS
*caps
, DWORD flags
)
2879 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2880 return IDirectPlayX_GetPlayerCaps( &This
->IDirectPlay4_iface
, player
, caps
, flags
);
2883 static HRESULT WINAPI
IDirectPlay4AImpl_GetPlayerCaps( IDirectPlay4A
*iface
, DPID player
,
2884 DPCAPS
*caps
, DWORD flags
)
2886 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
2887 return IDirectPlayX_GetPlayerCaps( &This
->IDirectPlay4_iface
, player
, caps
, flags
);
2890 static HRESULT WINAPI
IDirectPlay4Impl_GetPlayerCaps( IDirectPlay4
*iface
, DPID player
,
2891 DPCAPS
*caps
, DWORD flags
)
2893 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
2894 DPSP_GETCAPSDATA data
;
2896 TRACE( "(%p)->(0x%08x,%p,0x%08x)\n", This
, player
, caps
, flags
);
2898 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
2899 return DPERR_UNINITIALIZED
;
2901 /* Query the service provider */
2902 data
.idPlayer
= player
;
2903 data
.dwFlags
= flags
;
2905 data
.lpISP
= This
->dp2
->spData
.lpISP
;
2907 return (*This
->dp2
->spData
.lpCB
->GetCaps
)( &data
);
2910 static HRESULT WINAPI
IDirectPlay2AImpl_GetPlayerData( IDirectPlay2A
*iface
, DPID player
,
2911 void *data
, DWORD
*size
, DWORD flags
)
2913 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
2914 return IDirectPlayX_GetPlayerData( &This
->IDirectPlay4A_iface
, player
, data
, size
, flags
);
2917 static HRESULT WINAPI
IDirectPlay2Impl_GetPlayerData( IDirectPlay2
*iface
, DPID player
,
2918 void *data
, DWORD
*size
, DWORD flags
)
2920 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
2921 return IDirectPlayX_GetPlayerData( &This
->IDirectPlay4_iface
, player
, data
, size
, flags
);
2924 static HRESULT WINAPI
IDirectPlay3AImpl_GetPlayerData( IDirectPlay3A
*iface
, DPID player
,
2925 void *data
, DWORD
*size
, DWORD flags
)
2927 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
2928 return IDirectPlayX_GetPlayerData( &This
->IDirectPlay4_iface
, player
, data
, size
, flags
);
2931 static HRESULT WINAPI
IDirectPlay3Impl_GetPlayerData( IDirectPlay3
*iface
, DPID player
,
2932 void *data
, DWORD
*size
, DWORD flags
)
2934 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
2935 return IDirectPlayX_GetPlayerData( &This
->IDirectPlay4_iface
, player
, data
, size
, flags
);
2938 static HRESULT WINAPI
IDirectPlay4AImpl_GetPlayerData( IDirectPlay4A
*iface
, DPID player
,
2939 void *data
, DWORD
*size
, DWORD flags
)
2941 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
2942 return IDirectPlayX_GetPlayerData( &This
->IDirectPlay4_iface
, player
, data
, size
, flags
);
2945 static HRESULT WINAPI
IDirectPlay4Impl_GetPlayerData( IDirectPlay4
*iface
, DPID player
,
2946 void *data
, DWORD
*size
, DWORD flags
)
2948 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
2953 TRACE( "(%p)->(0x%08x,%p,%p,0x%08x)\n", This
, player
, data
, size
, flags
);
2955 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
2956 return DPERR_UNINITIALIZED
;
2958 if ( ( plist
= DP_FindPlayer( This
, player
) ) == NULL
)
2959 return DPERR_INVALIDPLAYER
;
2961 if ( flags
& DPSET_LOCAL
)
2963 bufsize
= plist
->lpPData
->dwLocalDataSize
;
2964 src
= plist
->lpPData
->lpLocalData
;
2968 bufsize
= plist
->lpPData
->dwRemoteDataSize
;
2969 src
= plist
->lpPData
->lpRemoteData
;
2972 /* Is the user requesting to know how big a buffer is required? */
2973 if ( !data
|| *size
< bufsize
)
2976 return DPERR_BUFFERTOOSMALL
;
2979 CopyMemory( data
, src
, bufsize
);
2984 static HRESULT
DP_IF_GetPlayerName( IDirectPlayImpl
*This
, DPID idPlayer
, void *lpData
,
2985 DWORD
*lpdwDataSize
, BOOL bAnsi
)
2987 lpPlayerList lpPList
;
2988 LPDPNAME lpName
= lpData
;
2989 DWORD dwRequiredDataSize
;
2991 FIXME( "(%p)->(0x%08x,%p,%p,%u): ANSI\n",
2992 This
, idPlayer
, lpData
, lpdwDataSize
, bAnsi
);
2994 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
2996 return DPERR_UNINITIALIZED
;
2999 if( ( lpPList
= DP_FindPlayer( This
, idPlayer
) ) == NULL
)
3001 return DPERR_INVALIDPLAYER
;
3004 dwRequiredDataSize
= lpPList
->lpPData
->name
.dwSize
;
3006 if( lpPList
->lpPData
->name
.u1
.lpszShortNameA
)
3008 dwRequiredDataSize
+= strlen( lpPList
->lpPData
->name
.u1
.lpszShortNameA
) + 1;
3011 if( lpPList
->lpPData
->name
.u2
.lpszLongNameA
)
3013 dwRequiredDataSize
+= strlen( lpPList
->lpPData
->name
.u2
.lpszLongNameA
) + 1;
3016 if( ( lpData
== NULL
) ||
3017 ( *lpdwDataSize
< dwRequiredDataSize
)
3020 *lpdwDataSize
= dwRequiredDataSize
;
3021 return DPERR_BUFFERTOOSMALL
;
3024 /* Copy the structure */
3025 CopyMemory( lpName
, &lpPList
->lpPData
->name
, lpPList
->lpPData
->name
.dwSize
);
3027 if( lpPList
->lpPData
->name
.u1
.lpszShortNameA
)
3029 strcpy( ((char*)lpName
)+lpPList
->lpPData
->name
.dwSize
,
3030 lpPList
->lpPData
->name
.u1
.lpszShortNameA
);
3034 lpName
->u1
.lpszShortNameA
= NULL
;
3037 if( lpPList
->lpPData
->name
.u1
.lpszShortNameA
)
3039 strcpy( ((char*)lpName
)+lpPList
->lpPData
->name
.dwSize
,
3040 lpPList
->lpPData
->name
.u2
.lpszLongNameA
);
3044 lpName
->u2
.lpszLongNameA
= NULL
;
3050 static HRESULT WINAPI
IDirectPlay2AImpl_GetPlayerName( IDirectPlay2A
*iface
, DPID player
,
3051 void *data
, DWORD
*size
)
3053 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3054 return IDirectPlayX_GetPlayerName( &This
->IDirectPlay4A_iface
, player
, data
, size
);
3057 static HRESULT WINAPI
IDirectPlay2Impl_GetPlayerName( IDirectPlay2
*iface
, DPID player
,
3058 void *data
, DWORD
*size
)
3060 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3061 return IDirectPlayX_GetPlayerName( &This
->IDirectPlay4_iface
, player
, data
, size
);
3064 static HRESULT WINAPI
IDirectPlay3AImpl_GetPlayerName( IDirectPlay3A
*iface
, DPID player
,
3065 void *data
, DWORD
*size
)
3067 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3068 return IDirectPlayX_GetPlayerName( &This
->IDirectPlay4_iface
, player
, data
, size
);
3071 static HRESULT WINAPI
IDirectPlay3Impl_GetPlayerName( IDirectPlay3
*iface
, DPID player
,
3072 void *data
, DWORD
*size
)
3074 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3075 return IDirectPlayX_GetPlayerName( &This
->IDirectPlay4_iface
, player
, data
, size
);
3078 static HRESULT WINAPI
IDirectPlay4AImpl_GetPlayerName( IDirectPlay4A
*iface
, DPID idPlayer
,
3079 void *lpData
, DWORD
*lpdwDataSize
)
3081 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3082 return DP_IF_GetPlayerName( This
, idPlayer
, lpData
, lpdwDataSize
, TRUE
);
3085 static HRESULT WINAPI
IDirectPlay4Impl_GetPlayerName( IDirectPlay4
*iface
, DPID idPlayer
,
3086 void *lpData
, DWORD
*lpdwDataSize
)
3088 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3089 return DP_IF_GetPlayerName( This
, idPlayer
, lpData
, lpdwDataSize
, FALSE
);
3092 static HRESULT
DP_GetSessionDesc( IDirectPlayImpl
*This
, void *lpData
, DWORD
*lpdwDataSize
,
3095 DWORD dwRequiredSize
;
3097 TRACE( "(%p)->(%p,%p,%u)\n", This
, lpData
, lpdwDataSize
, bAnsi
);
3099 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
3101 return DPERR_UNINITIALIZED
;
3104 if( ( lpData
== NULL
) && ( lpdwDataSize
== NULL
) )
3106 return DPERR_INVALIDPARAMS
;
3109 /* FIXME: Get from This->dp2->lpSessionDesc */
3110 dwRequiredSize
= DP_CalcSessionDescSize( This
->dp2
->lpSessionDesc
, bAnsi
);
3112 if ( ( lpData
== NULL
) ||
3113 ( *lpdwDataSize
< dwRequiredSize
)
3116 *lpdwDataSize
= dwRequiredSize
;
3117 return DPERR_BUFFERTOOSMALL
;
3120 DP_CopySessionDesc( lpData
, This
->dp2
->lpSessionDesc
, bAnsi
);
3125 static HRESULT WINAPI
IDirectPlay2AImpl_GetSessionDesc( IDirectPlay2A
*iface
, void *data
,
3128 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3129 return IDirectPlayX_GetSessionDesc( &This
->IDirectPlay4A_iface
, data
, size
);
3132 static HRESULT WINAPI
IDirectPlay2Impl_GetSessionDesc( IDirectPlay2
*iface
, void *data
,
3135 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3136 return IDirectPlayX_GetSessionDesc( &This
->IDirectPlay4_iface
, data
, size
);
3139 static HRESULT WINAPI
IDirectPlay3AImpl_GetSessionDesc( IDirectPlay3A
*iface
, void *data
,
3142 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3143 return IDirectPlayX_GetSessionDesc( &This
->IDirectPlay4_iface
, data
, size
);
3146 static HRESULT WINAPI
IDirectPlay3Impl_GetSessionDesc( IDirectPlay3
*iface
, void *data
,
3149 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3150 return IDirectPlayX_GetSessionDesc( &This
->IDirectPlay4_iface
, data
, size
);
3153 static HRESULT WINAPI
IDirectPlay4AImpl_GetSessionDesc( IDirectPlay4A
*iface
, void *lpData
,
3154 DWORD
*lpdwDataSize
)
3156 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3157 return DP_GetSessionDesc( This
, lpData
, lpdwDataSize
, TRUE
);
3160 static HRESULT WINAPI
IDirectPlay4Impl_GetSessionDesc( IDirectPlay4
*iface
, void *lpData
,
3161 DWORD
*lpdwDataSize
)
3163 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3164 return DP_GetSessionDesc( This
, lpData
, lpdwDataSize
, TRUE
);
3167 static HRESULT WINAPI
IDirectPlay2AImpl_Initialize( IDirectPlay2A
*iface
, GUID
*guid
)
3169 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3170 return IDirectPlayX_Initialize( &This
->IDirectPlay4A_iface
, guid
);
3173 static HRESULT WINAPI
IDirectPlay2Impl_Initialize( IDirectPlay2
*iface
, GUID
*guid
)
3175 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3176 return IDirectPlayX_Initialize( &This
->IDirectPlay4_iface
, guid
);
3179 static HRESULT WINAPI
IDirectPlay3AImpl_Initialize( IDirectPlay3A
*iface
, GUID
*guid
)
3181 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3182 return IDirectPlayX_Initialize( &This
->IDirectPlay4_iface
, guid
);
3185 static HRESULT WINAPI
IDirectPlay3Impl_Initialize( IDirectPlay3
*iface
, GUID
*guid
)
3187 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3188 return IDirectPlayX_Initialize( &This
->IDirectPlay4_iface
, guid
);
3191 /* Intended only for COM compatibility. Always returns an error. */
3192 static HRESULT WINAPI
IDirectPlay4AImpl_Initialize( IDirectPlay4A
*iface
, GUID
*guid
)
3194 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3195 TRACE("(%p)->(%p): no-op\n", This
, guid
);
3196 return DPERR_ALREADYINITIALIZED
;
3199 static HRESULT WINAPI
IDirectPlay4Impl_Initialize( IDirectPlay4
*iface
, GUID
*guid
)
3201 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3202 TRACE( "(%p)->(%p): no-op\n", This
, guid
);
3203 return DPERR_ALREADYINITIALIZED
;
3207 static HRESULT
DP_SecureOpen( IDirectPlayImpl
*This
, const DPSESSIONDESC2
*lpsd
, DWORD dwFlags
,
3208 const DPSECURITYDESC
*lpSecurity
, const DPCREDENTIALS
*lpCredentials
, BOOL bAnsi
)
3212 FIXME( "(%p)->(%p,0x%08x,%p,%p): partial stub\n",
3213 This
, lpsd
, dwFlags
, lpSecurity
, lpCredentials
);
3215 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
3217 return DPERR_UNINITIALIZED
;
3220 if( lpsd
->dwSize
!= sizeof(DPSESSIONDESC2
) )
3222 TRACE( ": rejecting invalid dpsd size (%d).\n", lpsd
->dwSize
);
3223 return DPERR_INVALIDPARAMS
;
3226 if( This
->dp2
->bConnectionOpen
)
3228 TRACE( ": rejecting already open connection.\n" );
3229 return DPERR_ALREADYINITIALIZED
;
3232 /* If we're enumerating, kill the thread */
3233 DP_KillEnumSessionThread( This
);
3235 if( dwFlags
& DPOPEN_CREATE
)
3237 /* Rightoo - this computer is the host and the local computer needs to be
3238 the name server so that others can join this session */
3239 NS_SetLocalComputerAsNameServer( lpsd
, This
->dp2
->lpNameServerData
);
3241 This
->dp2
->bHostInterface
= TRUE
;
3243 hr
= DP_SetSessionDesc( This
, lpsd
, 0, TRUE
, bAnsi
);
3246 ERR( "Unable to set session desc: %s\n", DPLAYX_HresultToString( hr
) );
3251 /* Invoke the conditional callback for the service provider */
3252 if( This
->dp2
->spData
.lpCB
->Open
)
3256 FIXME( "Not all data fields are correct. Need new parameter\n" );
3258 data
.bCreate
= (dwFlags
& DPOPEN_CREATE
) != 0;
3259 data
.lpSPMessageHeader
= (dwFlags
& DPOPEN_CREATE
) ? NULL
3260 : NS_GetNSAddr( This
->dp2
->lpNameServerData
);
3261 data
.lpISP
= This
->dp2
->spData
.lpISP
;
3262 data
.bReturnStatus
= (dwFlags
& DPOPEN_RETURNSTATUS
) != 0;
3263 data
.dwOpenFlags
= dwFlags
;
3264 data
.dwSessionFlags
= This
->dp2
->lpSessionDesc
->dwFlags
;
3266 hr
= (*This
->dp2
->spData
.lpCB
->Open
)(&data
);
3269 ERR( "Unable to open session: %s\n", DPLAYX_HresultToString( hr
) );
3275 /* Create the system group of which everything is a part of */
3276 DPID systemGroup
= DPID_SYSTEM_GROUP
;
3278 hr
= DP_IF_CreateGroup( This
, NULL
, &systemGroup
, NULL
,
3283 if( dwFlags
& DPOPEN_JOIN
)
3285 DPID dpidServerId
= DPID_UNKNOWN
;
3287 /* Create the server player for this interface. This way we can receive
3288 * messages for this session.
3290 /* FIXME: I suppose that we should be setting an event for a receive
3291 * type of thing. That way the messaging thread could know to wake
3292 * up. DPlay would then trigger the hEvent for the player the
3293 * message is directed to.
3295 hr
= DP_IF_CreatePlayer( This
, NULL
, &dpidServerId
, NULL
, 0, NULL
,
3297 DPPLAYER_SERVERPLAYER
| DPPLAYER_LOCAL
, bAnsi
);
3300 else if( dwFlags
& DPOPEN_CREATE
)
3302 DPID dpidNameServerId
= DPID_NAME_SERVER
;
3304 hr
= DP_IF_CreatePlayer( This
, NULL
, &dpidNameServerId
, NULL
, 0, NULL
,
3305 0, DPPLAYER_SERVERPLAYER
, bAnsi
);
3310 ERR( "Couldn't create name server/system player: %s\n",
3311 DPLAYX_HresultToString(hr
) );
3317 static HRESULT WINAPI
IDirectPlay2AImpl_Open( IDirectPlay2A
*iface
, DPSESSIONDESC2
*sdesc
,
3320 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3321 return IDirectPlayX_Open( &This
->IDirectPlay4A_iface
, sdesc
, flags
);
3324 static HRESULT WINAPI
IDirectPlay2Impl_Open( IDirectPlay2
*iface
, DPSESSIONDESC2
*sdesc
,
3327 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3328 return IDirectPlayX_Open( &This
->IDirectPlay4_iface
, sdesc
, flags
);
3331 static HRESULT WINAPI
IDirectPlay3AImpl_Open( IDirectPlay3A
*iface
, DPSESSIONDESC2
*sdesc
,
3334 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3335 return IDirectPlayX_Open( &This
->IDirectPlay4_iface
, sdesc
, flags
);
3338 static HRESULT WINAPI
IDirectPlay3Impl_Open( IDirectPlay3
*iface
, DPSESSIONDESC2
*sdesc
,
3341 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3342 return IDirectPlayX_Open( &This
->IDirectPlay4_iface
, sdesc
, flags
);
3345 static HRESULT WINAPI
IDirectPlay4AImpl_Open( IDirectPlay4A
*iface
, DPSESSIONDESC2
*sdesc
,
3348 return IDirectPlayX_SecureOpen( iface
, sdesc
, flags
, NULL
, NULL
);
3351 static HRESULT WINAPI
IDirectPlay4Impl_Open( IDirectPlay4
*iface
, DPSESSIONDESC2
*sdesc
,
3354 return IDirectPlayX_SecureOpen( iface
, sdesc
, flags
, NULL
, NULL
);
3357 static HRESULT
DP_IF_Receive( IDirectPlayImpl
*This
, DPID
*lpidFrom
, DPID
*lpidTo
, DWORD dwFlags
,
3358 void *lpData
, DWORD
*lpdwDataSize
, BOOL bAnsi
)
3360 LPDPMSG lpMsg
= NULL
;
3362 FIXME( "(%p)->(%p,%p,0x%08x,%p,%p,%u): stub\n",
3363 This
, lpidFrom
, lpidTo
, dwFlags
, lpData
, lpdwDataSize
, bAnsi
);
3365 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
3367 return DPERR_UNINITIALIZED
;
3372 dwFlags
= DPRECEIVE_ALL
;
3375 /* If the lpData is NULL, we must be peeking the message */
3376 if( ( lpData
== NULL
) &&
3377 !( dwFlags
& DPRECEIVE_PEEK
)
3380 return DPERR_INVALIDPARAMS
;
3383 if( dwFlags
& DPRECEIVE_ALL
)
3385 lpMsg
= This
->dp2
->receiveMsgs
.lpQHFirst
;
3387 if( !( dwFlags
& DPRECEIVE_PEEK
) )
3389 FIXME( "Remove from queue\n" );
3392 else if( ( dwFlags
& DPRECEIVE_TOPLAYER
) ||
3393 ( dwFlags
& DPRECEIVE_FROMPLAYER
)
3396 FIXME( "Find matching message 0x%08x\n", dwFlags
);
3400 ERR( "Hmmm..dwFlags 0x%08x\n", dwFlags
);
3405 return DPERR_NOMESSAGES
;
3408 /* Copy into the provided buffer */
3409 if (lpData
) CopyMemory( lpData
, lpMsg
->msg
, *lpdwDataSize
);
3414 static HRESULT WINAPI
IDirectPlay2AImpl_Receive( IDirectPlay2A
*iface
, DPID
*from
, DPID
*to
,
3415 DWORD flags
, void *data
, DWORD
*size
)
3417 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3418 return IDirectPlayX_Receive( &This
->IDirectPlay4A_iface
, from
, to
, flags
, data
, size
);
3421 static HRESULT WINAPI
IDirectPlay2Impl_Receive( IDirectPlay2
*iface
, DPID
*from
, DPID
*to
,
3422 DWORD flags
, void *data
, DWORD
*size
)
3424 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3425 return IDirectPlayX_Receive( &This
->IDirectPlay4_iface
, from
, to
, flags
, data
, size
);
3428 static HRESULT WINAPI
IDirectPlay3AImpl_Receive( IDirectPlay3A
*iface
, DPID
*from
, DPID
*to
,
3429 DWORD flags
, void *data
, DWORD
*size
)
3431 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3432 return IDirectPlayX_Receive( &This
->IDirectPlay4_iface
, from
, to
, flags
, data
, size
);
3435 static HRESULT WINAPI
IDirectPlay3Impl_Receive( IDirectPlay3
*iface
, DPID
*from
, DPID
*to
,
3436 DWORD flags
, void *data
, DWORD
*size
)
3438 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3439 return IDirectPlayX_Receive( &This
->IDirectPlay4_iface
, from
, to
, flags
, data
, size
);
3442 static HRESULT WINAPI
IDirectPlay4AImpl_Receive( IDirectPlay4A
*iface
, DPID
*lpidFrom
,
3443 DPID
*lpidTo
, DWORD dwFlags
, void *lpData
, DWORD
*lpdwDataSize
)
3445 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3446 return DP_IF_Receive( This
, lpidFrom
, lpidTo
, dwFlags
, lpData
, lpdwDataSize
, TRUE
);
3449 static HRESULT WINAPI
IDirectPlay4Impl_Receive( IDirectPlay4
*iface
, DPID
*lpidFrom
,
3450 DPID
*lpidTo
, DWORD dwFlags
, void *lpData
, DWORD
*lpdwDataSize
)
3452 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3453 return DP_IF_Receive( This
, lpidFrom
, lpidTo
, dwFlags
, lpData
, lpdwDataSize
, FALSE
);
3456 static HRESULT WINAPI
IDirectPlay2AImpl_Send( IDirectPlay2A
*iface
, DPID from
, DPID to
,
3457 DWORD flags
, void *data
, DWORD size
)
3459 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3460 return IDirectPlayX_Send( &This
->IDirectPlay4A_iface
, from
, to
, flags
, data
, size
);
3463 static HRESULT WINAPI
IDirectPlay2Impl_Send( IDirectPlay2
*iface
, DPID from
, DPID to
,
3464 DWORD flags
, void *data
, DWORD size
)
3466 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3467 return IDirectPlayX_Send( &This
->IDirectPlay4_iface
, from
, to
, flags
, data
, size
);
3470 static HRESULT WINAPI
IDirectPlay3AImpl_Send( IDirectPlay3A
*iface
, DPID from
, DPID to
,
3471 DWORD flags
, void *data
, DWORD size
)
3473 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3474 return IDirectPlayX_Send( &This
->IDirectPlay4_iface
, from
, to
, flags
, data
, size
);
3477 static HRESULT WINAPI
IDirectPlay3Impl_Send( IDirectPlay3
*iface
, DPID from
, DPID to
,
3478 DWORD flags
, void *data
, DWORD size
)
3480 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3481 return IDirectPlayX_Send( &This
->IDirectPlay4_iface
, from
, to
, flags
, data
, size
);
3484 static HRESULT WINAPI
IDirectPlay4AImpl_Send( IDirectPlay4A
*iface
, DPID from
, DPID to
,
3485 DWORD flags
, void *data
, DWORD size
)
3487 return IDirectPlayX_SendEx( iface
, from
, to
, flags
, data
, size
, 0, 0, NULL
, NULL
);
3490 static HRESULT WINAPI
IDirectPlay4Impl_Send( IDirectPlay4
*iface
, DPID from
, DPID to
,
3491 DWORD flags
, void *data
, DWORD size
)
3493 return IDirectPlayX_SendEx( iface
, from
, to
, flags
, data
, size
, 0, 0, NULL
, NULL
);
3496 static HRESULT WINAPI
IDirectPlay2AImpl_SetGroupData( IDirectPlay2A
*iface
, DPID group
, void *data
,
3497 DWORD size
, DWORD flags
)
3499 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3500 return IDirectPlayX_SetGroupData( &This
->IDirectPlay4A_iface
, group
, data
, size
, flags
);
3503 static HRESULT WINAPI
IDirectPlay2Impl_SetGroupData( IDirectPlay2
*iface
, DPID group
, void *data
,
3504 DWORD size
, DWORD flags
)
3506 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3507 return IDirectPlayX_SetGroupData( &This
->IDirectPlay4_iface
, group
, data
, size
, flags
);
3510 static HRESULT WINAPI
IDirectPlay3AImpl_SetGroupData( IDirectPlay3A
*iface
, DPID group
, void *data
,
3511 DWORD size
, DWORD flags
)
3513 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3514 return IDirectPlayX_SetGroupData( &This
->IDirectPlay4_iface
, group
, data
, size
, flags
);
3517 static HRESULT WINAPI
IDirectPlay3Impl_SetGroupData( IDirectPlay3
*iface
, DPID group
, void *data
,
3518 DWORD size
, DWORD flags
)
3520 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3521 return IDirectPlayX_SetGroupData( &This
->IDirectPlay4_iface
, group
, data
, size
, flags
);
3524 static HRESULT WINAPI
IDirectPlay4AImpl_SetGroupData( IDirectPlay4A
*iface
, DPID group
, void *data
,
3525 DWORD size
, DWORD flags
)
3527 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3528 return IDirectPlayX_SetGroupData( &This
->IDirectPlay4_iface
, group
, data
, size
, flags
);
3531 static HRESULT WINAPI
IDirectPlay4Impl_SetGroupData( IDirectPlay4
*iface
, DPID group
, void *data
,
3532 DWORD size
, DWORD flags
)
3534 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3537 TRACE( "(%p)->(0x%08x,%p,0x%08x,0x%08x)\n", This
, group
, data
, size
, flags
);
3539 /* Parameter check */
3540 if ( !data
&& size
)
3541 return DPERR_INVALIDPARAMS
;
3543 /* Find the pointer to the data for this player */
3544 if ( ( gdata
= DP_FindAnyGroup( This
, group
) ) == NULL
)
3545 return DPERR_INVALIDOBJECT
;
3547 if ( !(flags
& DPSET_LOCAL
) )
3549 FIXME( "Was this group created by this interface?\n" );
3550 /* FIXME: If this is a remote update need to allow it but not
3555 DP_SetGroupData( gdata
, flags
, data
, size
);
3557 /* FIXME: Only send a message if this group is local to the session otherwise
3558 * it will have been rejected above
3560 if ( !(flags
& DPSET_LOCAL
) )
3561 FIXME( "Send msg?\n" );
3566 static HRESULT
DP_IF_SetGroupName( IDirectPlayImpl
*This
, DPID idGroup
, DPNAME
*lpGroupName
,
3567 DWORD dwFlags
, BOOL bAnsi
)
3569 lpGroupData lpGData
;
3571 TRACE( "(%p)->(0x%08x,%p,0x%08x,%u)\n", This
, idGroup
,
3572 lpGroupName
, dwFlags
, bAnsi
);
3574 if( ( lpGData
= DP_FindAnyGroup( This
, idGroup
) ) == NULL
)
3576 return DPERR_INVALIDGROUP
;
3579 DP_CopyDPNAMEStruct( &lpGData
->name
, lpGroupName
, bAnsi
);
3581 /* Should send a DPMSG_SETPLAYERORGROUPNAME message */
3582 FIXME( "Message not sent and dwFlags ignored\n" );
3587 static HRESULT WINAPI
IDirectPlay2AImpl_SetGroupName( IDirectPlay2A
*iface
, DPID group
,
3588 DPNAME
*name
, DWORD flags
)
3590 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3591 return IDirectPlayX_SetGroupName( &This
->IDirectPlay4A_iface
, group
, name
, flags
);
3594 static HRESULT WINAPI
IDirectPlay2Impl_SetGroupName( IDirectPlay2
*iface
, DPID group
,
3595 DPNAME
*name
, DWORD flags
)
3597 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3598 return IDirectPlayX_SetGroupName( &This
->IDirectPlay4_iface
, group
, name
, flags
);
3601 static HRESULT WINAPI
IDirectPlay3AImpl_SetGroupName( IDirectPlay3A
*iface
, DPID group
,
3602 DPNAME
*name
, DWORD flags
)
3604 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3605 return IDirectPlayX_SetGroupName( &This
->IDirectPlay4_iface
, group
, name
, flags
);
3608 static HRESULT WINAPI
IDirectPlay3Impl_SetGroupName( IDirectPlay3
*iface
, DPID group
,
3609 DPNAME
*name
, DWORD flags
)
3611 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3612 return IDirectPlayX_SetGroupName( &This
->IDirectPlay4_iface
, group
, name
, flags
);
3615 static HRESULT WINAPI
IDirectPlay4AImpl_SetGroupName( IDirectPlay4A
*iface
, DPID idGroup
,
3616 DPNAME
*lpGroupName
, DWORD dwFlags
)
3618 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3619 return DP_IF_SetGroupName( This
, idGroup
, lpGroupName
, dwFlags
, TRUE
);
3622 static HRESULT WINAPI
IDirectPlay4Impl_SetGroupName( IDirectPlay4
*iface
, DPID idGroup
,
3623 DPNAME
*lpGroupName
, DWORD dwFlags
)
3625 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3626 return DP_IF_SetGroupName( This
, idGroup
, lpGroupName
, dwFlags
, FALSE
);
3629 static HRESULT WINAPI
IDirectPlay2AImpl_SetPlayerData( IDirectPlay2A
*iface
, DPID player
,
3630 void *data
, DWORD size
, DWORD flags
)
3632 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3633 return IDirectPlayX_SetPlayerData( &This
->IDirectPlay4A_iface
, player
, data
, size
, flags
);
3636 static HRESULT WINAPI
IDirectPlay2Impl_SetPlayerData( IDirectPlay2
*iface
, DPID player
,
3637 void *data
, DWORD size
, DWORD flags
)
3639 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3640 return IDirectPlayX_SetPlayerData( &This
->IDirectPlay4_iface
, player
, data
, size
, flags
);
3643 static HRESULT WINAPI
IDirectPlay3AImpl_SetPlayerData( IDirectPlay3A
*iface
, DPID player
,
3644 void *data
, DWORD size
, DWORD flags
)
3646 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3647 return IDirectPlayX_SetPlayerData( &This
->IDirectPlay4_iface
, player
, data
, size
, flags
);
3650 static HRESULT WINAPI
IDirectPlay3Impl_SetPlayerData( IDirectPlay3
*iface
, DPID player
,
3651 void *data
, DWORD size
, DWORD flags
)
3653 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3654 return IDirectPlayX_SetPlayerData( &This
->IDirectPlay4_iface
, player
, data
, size
, flags
);
3657 static HRESULT WINAPI
IDirectPlay4AImpl_SetPlayerData( IDirectPlay4A
*iface
, DPID player
,
3658 void *data
, DWORD size
, DWORD flags
)
3660 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3661 return IDirectPlayX_SetPlayerData( &This
->IDirectPlay4_iface
, player
, data
, size
, flags
);
3664 static HRESULT WINAPI
IDirectPlay4Impl_SetPlayerData( IDirectPlay4
*iface
, DPID player
,
3665 void *data
, DWORD size
, DWORD flags
)
3667 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3670 TRACE( "(%p)->(0x%08x,%p,0x%08x,0x%08x)\n", This
, player
, data
, size
, flags
);
3672 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
3673 return DPERR_UNINITIALIZED
;
3675 /* Parameter check */
3676 if ( !data
&& size
)
3677 return DPERR_INVALIDPARAMS
;
3679 /* Find the pointer to the data for this player */
3680 if ( (plist
= DP_FindPlayer( This
, player
)) == NULL
)
3681 return DPERR_INVALIDPLAYER
;
3683 if ( !(flags
& DPSET_LOCAL
) )
3685 FIXME( "Was this group created by this interface?\n" );
3686 /* FIXME: If this is a remote update need to allow it but not
3691 DP_SetPlayerData( plist
->lpPData
, flags
, data
, size
);
3693 if ( !(flags
& DPSET_LOCAL
) )
3694 FIXME( "Send msg?\n" );
3699 static HRESULT
DP_IF_SetPlayerName( IDirectPlayImpl
*This
, DPID idPlayer
, DPNAME
*lpPlayerName
,
3700 DWORD dwFlags
, BOOL bAnsi
)
3702 lpPlayerList lpPList
;
3704 TRACE( "(%p)->(0x%08x,%p,0x%08x,%u)\n",
3705 This
, idPlayer
, lpPlayerName
, dwFlags
, bAnsi
);
3707 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
3709 return DPERR_UNINITIALIZED
;
3712 if( ( lpPList
= DP_FindPlayer( This
, idPlayer
) ) == NULL
)
3714 return DPERR_INVALIDGROUP
;
3717 DP_CopyDPNAMEStruct( &lpPList
->lpPData
->name
, lpPlayerName
, bAnsi
);
3719 /* Should send a DPMSG_SETPLAYERORGROUPNAME message */
3720 FIXME( "Message not sent and dwFlags ignored\n" );
3725 static HRESULT WINAPI
IDirectPlay2AImpl_SetPlayerName( IDirectPlay2A
*iface
, DPID player
,
3726 DPNAME
*name
, DWORD flags
)
3728 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3729 return IDirectPlayX_SetPlayerName( &This
->IDirectPlay4A_iface
, player
, name
, flags
);
3732 static HRESULT WINAPI
IDirectPlay2Impl_SetPlayerName( IDirectPlay2
*iface
, DPID player
,
3733 DPNAME
*name
, DWORD flags
)
3735 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3736 return IDirectPlayX_SetPlayerName( &This
->IDirectPlay4_iface
, player
, name
, flags
);
3739 static HRESULT WINAPI
IDirectPlay3AImpl_SetPlayerName( IDirectPlay3A
*iface
, DPID player
,
3740 DPNAME
*name
, DWORD flags
)
3742 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3743 return IDirectPlayX_SetPlayerName( &This
->IDirectPlay4_iface
, player
, name
, flags
);
3746 static HRESULT WINAPI
IDirectPlay3Impl_SetPlayerName( IDirectPlay3
*iface
, DPID player
,
3747 DPNAME
*name
, DWORD flags
)
3749 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3750 return IDirectPlayX_SetPlayerName( &This
->IDirectPlay4_iface
, player
, name
, flags
);
3753 static HRESULT WINAPI
IDirectPlay4AImpl_SetPlayerName( IDirectPlay4A
*iface
, DPID idPlayer
,
3754 DPNAME
*lpPlayerName
, DWORD dwFlags
)
3756 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3757 return DP_IF_SetPlayerName( This
, idPlayer
, lpPlayerName
, dwFlags
, TRUE
);
3760 static HRESULT WINAPI
IDirectPlay4Impl_SetPlayerName( IDirectPlay4
*iface
, DPID idPlayer
,
3761 DPNAME
*lpPlayerName
, DWORD dwFlags
)
3763 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3764 return DP_IF_SetPlayerName( This
, idPlayer
, lpPlayerName
, dwFlags
, FALSE
);
3767 static HRESULT
DP_SetSessionDesc( IDirectPlayImpl
*This
, const DPSESSIONDESC2
*lpSessDesc
,
3768 DWORD dwFlags
, BOOL bInitial
, BOOL bAnsi
)
3770 DWORD dwRequiredSize
;
3771 LPDPSESSIONDESC2 lpTempSessDesc
;
3773 TRACE( "(%p)->(%p,0x%08x,%u,%u)\n",
3774 This
, lpSessDesc
, dwFlags
, bInitial
, bAnsi
);
3776 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
3778 return DPERR_UNINITIALIZED
;
3783 return DPERR_INVALIDPARAMS
;
3786 /* Only the host is allowed to update the session desc */
3787 if( !This
->dp2
->bHostInterface
)
3789 return DPERR_ACCESSDENIED
;
3792 /* FIXME: Copy into This->dp2->lpSessionDesc */
3793 dwRequiredSize
= DP_CalcSessionDescSize( lpSessDesc
, bAnsi
);
3794 lpTempSessDesc
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwRequiredSize
);
3796 if( lpTempSessDesc
== NULL
)
3798 return DPERR_OUTOFMEMORY
;
3802 HeapFree( GetProcessHeap(), 0, This
->dp2
->lpSessionDesc
);
3804 This
->dp2
->lpSessionDesc
= lpTempSessDesc
;
3806 DP_CopySessionDesc( This
->dp2
->lpSessionDesc
, lpSessDesc
, bAnsi
);
3809 /*Initializing session GUID*/
3810 CoCreateGuid( &(This
->dp2
->lpSessionDesc
->guidInstance
) );
3812 /* If this is an external invocation of the interface, we should be
3813 * letting everyone know that things have changed. Otherwise this is
3814 * just an initialization and it doesn't need to be propagated.
3818 FIXME( "Need to send a DPMSG_SETSESSIONDESC msg to everyone\n" );
3824 static HRESULT WINAPI
IDirectPlay2AImpl_SetSessionDesc( IDirectPlay2A
*iface
, DPSESSIONDESC2
*sdesc
,
3827 IDirectPlayImpl
*This
= impl_from_IDirectPlay2A( iface
);
3828 return IDirectPlayX_SetSessionDesc( &This
->IDirectPlay4A_iface
, sdesc
, flags
);
3831 static HRESULT WINAPI
IDirectPlay2Impl_SetSessionDesc( IDirectPlay2
*iface
, DPSESSIONDESC2
*sdesc
,
3834 IDirectPlayImpl
*This
= impl_from_IDirectPlay2( iface
);
3835 return IDirectPlayX_SetSessionDesc( &This
->IDirectPlay4_iface
, sdesc
, flags
);
3838 static HRESULT WINAPI
IDirectPlay3AImpl_SetSessionDesc( IDirectPlay3A
*iface
, DPSESSIONDESC2
*sdesc
,
3841 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3842 return IDirectPlayX_SetSessionDesc( &This
->IDirectPlay4_iface
, sdesc
, flags
);
3845 static HRESULT WINAPI
IDirectPlay3Impl_SetSessionDesc( IDirectPlay3
*iface
, DPSESSIONDESC2
*sdesc
,
3848 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3849 return IDirectPlayX_SetSessionDesc( &This
->IDirectPlay4_iface
, sdesc
, flags
);
3852 static HRESULT WINAPI
IDirectPlay4AImpl_SetSessionDesc( IDirectPlay4A
*iface
,
3853 DPSESSIONDESC2
*lpSessDesc
, DWORD dwFlags
)
3855 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3856 return DP_SetSessionDesc( This
, lpSessDesc
, dwFlags
, FALSE
, TRUE
);
3859 static HRESULT WINAPI
IDirectPlay4Impl_SetSessionDesc( IDirectPlay4
*iface
,
3860 DPSESSIONDESC2
*lpSessDesc
, DWORD dwFlags
)
3862 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3863 return DP_SetSessionDesc( This
, lpSessDesc
, dwFlags
, FALSE
, TRUE
);
3866 /* FIXME: See about merging some of this stuff with dplayx_global.c stuff */
3867 static DWORD
DP_CalcSessionDescSize( LPCDPSESSIONDESC2 lpSessDesc
, BOOL bAnsi
)
3871 if( lpSessDesc
== NULL
)
3873 /* Hmmm..don't need any size? */
3874 ERR( "NULL lpSessDesc\n" );
3878 dwSize
+= sizeof( *lpSessDesc
);
3882 if( lpSessDesc
->u1
.lpszSessionNameA
)
3884 dwSize
+= lstrlenA( lpSessDesc
->u1
.lpszSessionNameA
) + 1;
3887 if( lpSessDesc
->u2
.lpszPasswordA
)
3889 dwSize
+= lstrlenA( lpSessDesc
->u2
.lpszPasswordA
) + 1;
3894 if( lpSessDesc
->u1
.lpszSessionName
)
3896 dwSize
+= sizeof( WCHAR
) *
3897 ( lstrlenW( lpSessDesc
->u1
.lpszSessionName
) + 1 );
3900 if( lpSessDesc
->u2
.lpszPassword
)
3902 dwSize
+= sizeof( WCHAR
) *
3903 ( lstrlenW( lpSessDesc
->u2
.lpszPassword
) + 1 );
3910 /* Assumes that contiguous buffers are already allocated. */
3911 static void DP_CopySessionDesc( LPDPSESSIONDESC2 lpSessionDest
,
3912 LPCDPSESSIONDESC2 lpSessionSrc
, BOOL bAnsi
)
3914 BYTE
* lpStartOfFreeSpace
;
3916 if( lpSessionDest
== NULL
)
3918 ERR( "NULL lpSessionDest\n" );
3922 CopyMemory( lpSessionDest
, lpSessionSrc
, sizeof( *lpSessionSrc
) );
3924 lpStartOfFreeSpace
= ((BYTE
*)lpSessionDest
) + sizeof( *lpSessionSrc
);
3928 if( lpSessionSrc
->u1
.lpszSessionNameA
)
3930 lstrcpyA( (LPSTR
)lpStartOfFreeSpace
,
3931 lpSessionDest
->u1
.lpszSessionNameA
);
3932 lpSessionDest
->u1
.lpszSessionNameA
= (LPSTR
)lpStartOfFreeSpace
;
3933 lpStartOfFreeSpace
+=
3934 lstrlenA( lpSessionDest
->u1
.lpszSessionNameA
) + 1;
3937 if( lpSessionSrc
->u2
.lpszPasswordA
)
3939 lstrcpyA( (LPSTR
)lpStartOfFreeSpace
,
3940 lpSessionDest
->u2
.lpszPasswordA
);
3941 lpSessionDest
->u2
.lpszPasswordA
= (LPSTR
)lpStartOfFreeSpace
;
3946 if( lpSessionSrc
->u1
.lpszSessionName
)
3948 lstrcpyW( (LPWSTR
)lpStartOfFreeSpace
,
3949 lpSessionDest
->u1
.lpszSessionName
);
3950 lpSessionDest
->u1
.lpszSessionName
= (LPWSTR
)lpStartOfFreeSpace
;
3951 lpStartOfFreeSpace
+= sizeof(WCHAR
) *
3952 ( lstrlenW( lpSessionDest
->u1
.lpszSessionName
) + 1 );
3955 if( lpSessionSrc
->u2
.lpszPassword
)
3957 lstrcpyW( (LPWSTR
)lpStartOfFreeSpace
,
3958 lpSessionDest
->u2
.lpszPassword
);
3959 lpSessionDest
->u2
.lpszPassword
= (LPWSTR
)lpStartOfFreeSpace
;
3964 static HRESULT WINAPI
IDirectPlay3AImpl_AddGroupToGroup( IDirectPlay3A
*iface
, DPID parent
,
3967 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
3968 return IDirectPlayX_AddGroupToGroup( &This
->IDirectPlay4A_iface
, parent
, group
);
3971 static HRESULT WINAPI
IDirectPlay3Impl_AddGroupToGroup( IDirectPlay3
*iface
, DPID parent
,
3974 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
3975 return IDirectPlayX_AddGroupToGroup( &This
->IDirectPlay4_iface
, parent
, group
);
3978 static HRESULT WINAPI
IDirectPlay4AImpl_AddGroupToGroup( IDirectPlay4A
*iface
, DPID parent
,
3981 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
3982 return IDirectPlayX_AddGroupToGroup( &This
->IDirectPlay4_iface
, parent
, group
);
3985 static HRESULT WINAPI
IDirectPlay4Impl_AddGroupToGroup( IDirectPlay4
*iface
, DPID parent
,
3988 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
3992 TRACE( "(%p)->(0x%08x,0x%08x)\n", This
, parent
, group
);
3994 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
3995 return DPERR_UNINITIALIZED
;
3997 if ( !DP_FindAnyGroup(This
, parent
) )
3998 return DPERR_INVALIDGROUP
;
4000 if ( ( gdata
= DP_FindAnyGroup(This
, group
) ) == NULL
)
4001 return DPERR_INVALIDGROUP
;
4003 /* Create a player list (ie "shortcut" ) */
4004 glist
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *glist
) );
4006 return DPERR_CANTADDPLAYER
;
4008 /* Add the shortcut */
4010 glist
->lpGData
= gdata
;
4012 /* Add the player to the list of players for this group */
4013 DPQ_INSERT( gdata
->groups
, glist
, groups
);
4015 /* Send a ADDGROUPTOGROUP message */
4016 FIXME( "Not sending message\n" );
4021 static HRESULT
DP_IF_CreateGroupInGroup( IDirectPlayImpl
*This
, void *lpMsgHdr
, DPID idParentGroup
,
4022 DPID
*lpidGroup
, DPNAME
*lpGroupName
, void *lpData
, DWORD dwDataSize
, DWORD dwFlags
,
4025 lpGroupData lpGParentData
;
4026 lpGroupList lpGList
;
4027 lpGroupData lpGData
;
4029 TRACE( "(%p)->(0x%08x,%p,%p,%p,0x%08x,0x%08x,%u)\n",
4030 This
, idParentGroup
, lpidGroup
, lpGroupName
, lpData
,
4031 dwDataSize
, dwFlags
, bAnsi
);
4033 if( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
4035 return DPERR_UNINITIALIZED
;
4038 /* Verify that the specified parent is valid */
4039 if( ( lpGParentData
= DP_FindAnyGroup(This
, idParentGroup
) ) == NULL
)
4040 return DPERR_INVALIDGROUP
;
4042 lpGData
= DP_CreateGroup(This
, lpidGroup
, lpGroupName
, dwFlags
, idParentGroup
, bAnsi
);
4044 if( lpGData
== NULL
)
4046 return DPERR_CANTADDPLAYER
; /* yes player not group */
4049 /* Something else is referencing this data */
4052 DP_SetGroupData( lpGData
, DPSET_REMOTE
, lpData
, dwDataSize
);
4054 /* The list has now been inserted into the interface group list. We now
4055 need to put a "shortcut" to this group in the parent group */
4056 lpGList
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *lpGList
) );
4057 if( lpGList
== NULL
)
4059 FIXME( "Memory leak\n" );
4060 return DPERR_CANTADDPLAYER
; /* yes player not group */
4063 lpGList
->lpGData
= lpGData
;
4065 DPQ_INSERT( lpGParentData
->groups
, lpGList
, groups
);
4067 /* Let the SP know that we've created this group */
4068 if( This
->dp2
->spData
.lpCB
->CreateGroup
)
4070 DPSP_CREATEGROUPDATA data
;
4072 TRACE( "Calling SP CreateGroup\n" );
4074 data
.idGroup
= *lpidGroup
;
4075 data
.dwFlags
= dwFlags
;
4076 data
.lpSPMessageHeader
= lpMsgHdr
;
4077 data
.lpISP
= This
->dp2
->spData
.lpISP
;
4079 (*This
->dp2
->spData
.lpCB
->CreateGroup
)( &data
);
4082 /* Inform all other peers of the creation of a new group. If there are
4083 * no peers keep this quiet.
4085 if( This
->dp2
->lpSessionDesc
&&
4086 ( This
->dp2
->lpSessionDesc
->dwFlags
& DPSESSION_MULTICASTSERVER
) )
4088 DPMSG_CREATEPLAYERORGROUP msg
;
4090 msg
.dwType
= DPSYS_CREATEPLAYERORGROUP
;
4091 msg
.dwPlayerType
= DPPLAYERTYPE_GROUP
;
4092 msg
.dpId
= *lpidGroup
;
4093 msg
.dwCurrentPlayers
= idParentGroup
; /* FIXME: Incorrect? */
4094 msg
.lpData
= lpData
;
4095 msg
.dwDataSize
= dwDataSize
;
4096 msg
.dpnName
= *lpGroupName
;
4098 /* FIXME: Correct to just use send effectively? */
4099 /* FIXME: Should size include data w/ message or just message "header" */
4100 /* FIXME: Check return code */
4101 IDirectPlayX_SendEx( &This
->IDirectPlay4_iface
, DPID_SERVERPLAYER
, DPID_ALLPLAYERS
, 0, &msg
,
4102 sizeof( msg
), 0, 0, NULL
, NULL
);
4108 static HRESULT WINAPI
IDirectPlay3AImpl_CreateGroupInGroup( IDirectPlay3A
*iface
, DPID parent
,
4109 DPID
*group
, DPNAME
*name
, void *data
, DWORD size
, DWORD flags
)
4111 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4112 return IDirectPlayX_CreateGroupInGroup( &This
->IDirectPlay4A_iface
, parent
, group
, name
,
4113 data
, size
, flags
);
4116 static HRESULT WINAPI
IDirectPlay3Impl_CreateGroupInGroup( IDirectPlay3
*iface
, DPID parent
,
4117 DPID
*group
, DPNAME
*name
, void *data
, DWORD size
, DWORD flags
)
4119 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4120 return IDirectPlayX_CreateGroupInGroup( &This
->IDirectPlay4_iface
, parent
, group
, name
,
4121 data
, size
, flags
);
4124 static HRESULT WINAPI
IDirectPlay4AImpl_CreateGroupInGroup( IDirectPlay4A
*iface
,
4125 DPID idParentGroup
, DPID
*lpidGroup
, DPNAME
*lpGroupName
, void *lpData
, DWORD dwDataSize
,
4128 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4130 *lpidGroup
= DPID_UNKNOWN
;
4132 return DP_IF_CreateGroupInGroup( This
, NULL
, idParentGroup
, lpidGroup
, lpGroupName
, lpData
,
4133 dwDataSize
, dwFlags
, TRUE
);
4136 static HRESULT WINAPI
IDirectPlay4Impl_CreateGroupInGroup( IDirectPlay4
*iface
, DPID idParentGroup
,
4137 DPID
*lpidGroup
, DPNAME
*lpGroupName
, void *lpData
, DWORD dwDataSize
, DWORD dwFlags
)
4139 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4141 *lpidGroup
= DPID_UNKNOWN
;
4143 return DP_IF_CreateGroupInGroup( This
, NULL
, idParentGroup
, lpidGroup
, lpGroupName
, lpData
,
4144 dwDataSize
, dwFlags
, FALSE
);
4147 static HRESULT WINAPI
IDirectPlay3AImpl_DeleteGroupFromGroup( IDirectPlay3A
*iface
, DPID parent
,
4150 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4151 return IDirectPlayX_DeleteGroupFromGroup( &This
->IDirectPlay4A_iface
, parent
, group
);
4154 static HRESULT WINAPI
IDirectPlay3Impl_DeleteGroupFromGroup( IDirectPlay3
*iface
, DPID parent
,
4157 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4158 return IDirectPlayX_DeleteGroupFromGroup( &This
->IDirectPlay4_iface
, parent
, group
);
4161 static HRESULT WINAPI
IDirectPlay4AImpl_DeleteGroupFromGroup( IDirectPlay4A
*iface
, DPID parent
,
4164 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4165 return IDirectPlayX_DeleteGroupFromGroup( &This
->IDirectPlay4_iface
, parent
, group
);
4168 static HRESULT WINAPI
IDirectPlay4Impl_DeleteGroupFromGroup( IDirectPlay4
*iface
, DPID parent
,
4171 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4173 lpGroupData parentdata
;
4175 TRACE("(%p)->(0x%08x,0x%08x)\n", This
, parent
, group
);
4177 /* Is the parent group valid? */
4178 if ( ( parentdata
= DP_FindAnyGroup(This
, parent
) ) == NULL
)
4179 return DPERR_INVALIDGROUP
;
4181 /* Remove the group from the parent group queue */
4182 DPQ_REMOVE_ENTRY( parentdata
->groups
, groups
, lpGData
->dpid
, ==, group
, glist
);
4184 if ( glist
== NULL
)
4185 return DPERR_INVALIDGROUP
;
4187 /* Decrement the ref count */
4188 glist
->lpGData
->uRef
--;
4190 /* Free up the list item */
4191 HeapFree( GetProcessHeap(), 0, glist
);
4193 /* Should send a DELETEGROUPFROMGROUP message */
4194 FIXME( "message not sent\n" );
4199 static BOOL
DP_BuildSPCompoundAddr( LPGUID lpcSpGuid
, LPVOID
* lplpAddrBuf
,
4200 LPDWORD lpdwBufSize
)
4202 DPCOMPOUNDADDRESSELEMENT dpCompoundAddress
;
4205 dpCompoundAddress
.dwDataSize
= sizeof( GUID
);
4206 dpCompoundAddress
.guidDataType
= DPAID_ServiceProvider
;
4207 dpCompoundAddress
.lpData
= lpcSpGuid
;
4209 *lplpAddrBuf
= NULL
;
4212 hr
= DPL_CreateCompoundAddress( &dpCompoundAddress
, 1, *lplpAddrBuf
,
4213 lpdwBufSize
, TRUE
);
4215 if( hr
!= DPERR_BUFFERTOOSMALL
)
4217 ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr
) );
4221 /* Now allocate the buffer */
4222 *lplpAddrBuf
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
4225 hr
= DPL_CreateCompoundAddress( &dpCompoundAddress
, 1, *lplpAddrBuf
,
4226 lpdwBufSize
, TRUE
);
4229 ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr
) );
4236 static HRESULT WINAPI
IDirectPlay3AImpl_EnumConnections( IDirectPlay3A
*iface
,
4237 const GUID
*application
, LPDPENUMCONNECTIONSCALLBACK enumcb
, void *context
, DWORD flags
)
4239 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4240 return IDirectPlayX_EnumConnections( &This
->IDirectPlay4A_iface
, application
, enumcb
, context
,
4244 static HRESULT WINAPI
IDirectPlay3Impl_EnumConnections( IDirectPlay3
*iface
,
4245 const GUID
*application
, LPDPENUMCONNECTIONSCALLBACK enumcb
, void *context
, DWORD flags
)
4247 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4248 return IDirectPlayX_EnumConnections( &This
->IDirectPlay4_iface
, application
, enumcb
, context
,
4252 static HRESULT WINAPI
IDirectPlay4AImpl_EnumConnections( IDirectPlay4A
*iface
,
4253 const GUID
*lpguidApplication
, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback
, void *lpContext
,
4256 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4257 TRACE("(%p)->(%p,%p,%p,0x%08x)\n", This
, lpguidApplication
, lpEnumCallback
, lpContext
, dwFlags
);
4259 /* A default dwFlags (0) is backwards compatible -- DPCONNECTION_DIRECTPLAY */
4262 dwFlags
= DPCONNECTION_DIRECTPLAY
;
4265 if( ! ( ( dwFlags
& DPCONNECTION_DIRECTPLAY
) ||
4266 ( dwFlags
& DPCONNECTION_DIRECTPLAYLOBBY
) )
4269 return DPERR_INVALIDFLAGS
;
4272 if( !lpEnumCallback
)
4274 return DPERR_INVALIDPARAMS
;
4277 /* Enumerate DirectPlay service providers */
4278 if( dwFlags
& DPCONNECTION_DIRECTPLAY
)
4281 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
4282 LPCSTR guidDataSubKey
= "Guid";
4283 char subKeyName
[51];
4284 DWORD dwIndex
, sizeOfSubKeyName
=50;
4287 /* Need to loop over the service providers in the registry */
4288 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
4289 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
4291 /* Hmmm. Does this mean that there are no service providers? */
4292 ERR(": no service providers?\n");
4297 /* Traverse all the service providers we have available */
4299 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
4300 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
4301 ++dwIndex
, sizeOfSubKeyName
=51 )
4304 HKEY hkServiceProvider
;
4305 GUID serviceProviderGUID
;
4306 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
4307 char returnBuffer
[51];
4312 LPVOID lpAddressBuffer
= NULL
;
4313 DWORD dwAddressBufferSize
= 0;
4315 TRACE(" this time through: %s\n", subKeyName
);
4317 /* Get a handle for this particular service provider */
4318 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
4319 &hkServiceProvider
) != ERROR_SUCCESS
)
4321 ERR(": what the heck is going on?\n" );
4325 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
4326 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
4327 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
4329 ERR(": missing GUID registry data members\n" );
4330 RegCloseKey(hkServiceProvider
);
4333 RegCloseKey(hkServiceProvider
);
4335 /* FIXME: Check return types to ensure we're interpreting data right */
4336 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
4337 CLSIDFromString( buff
, &serviceProviderGUID
);
4338 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
4340 /* Fill in the DPNAME struct for the service provider */
4341 dpName
.dwSize
= sizeof( dpName
);
4343 dpName
.u1
.lpszShortNameA
= subKeyName
;
4344 dpName
.u2
.lpszLongNameA
= NULL
;
4346 /* Create the compound address for the service provider.
4347 * NOTE: This is a gruesome architectural scar right now. DP
4348 * uses DPL and DPL uses DP. Nasty stuff. This may be why the
4349 * native dll just gets around this little bit by allocating an
4350 * 80 byte buffer which isn't even filled with a valid compound
4351 * address. Oh well. Creating a proper compound address is the
4352 * way to go anyways despite this method taking slightly more
4353 * heap space and realtime :) */
4355 bBuildPass
= DP_BuildSPCompoundAddr( &serviceProviderGUID
,
4357 &dwAddressBufferSize
);
4360 ERR( "Can't build compound addr\n" );
4361 return DPERR_GENERIC
;
4364 /* The enumeration will return FALSE if we are not to continue */
4365 if( !lpEnumCallback( &serviceProviderGUID
, lpAddressBuffer
, dwAddressBufferSize
,
4366 &dpName
, dwFlags
, lpContext
) )
4373 /* Enumerate DirectPlayLobby service providers */
4374 if( dwFlags
& DPCONNECTION_DIRECTPLAYLOBBY
)
4377 LPCSTR searchSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Lobby Providers";
4378 LPCSTR guidDataSubKey
= "Guid";
4379 char subKeyName
[51];
4380 DWORD dwIndex
, sizeOfSubKeyName
=50;
4383 /* Need to loop over the service providers in the registry */
4384 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
4385 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
4387 /* Hmmm. Does this mean that there are no service providers? */
4388 ERR(": no service providers?\n");
4393 /* Traverse all the lobby providers we have available */
4395 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
4396 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
4397 ++dwIndex
, sizeOfSubKeyName
=51 )
4400 HKEY hkServiceProvider
;
4401 GUID serviceProviderGUID
;
4402 DWORD returnTypeGUID
, sizeOfReturnBuffer
= 50;
4403 char returnBuffer
[51];
4408 DPCOMPOUNDADDRESSELEMENT dpCompoundAddress
;
4409 LPVOID lpAddressBuffer
= NULL
;
4410 DWORD dwAddressBufferSize
= 0;
4412 TRACE(" this time through: %s\n", subKeyName
);
4414 /* Get a handle for this particular service provider */
4415 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
4416 &hkServiceProvider
) != ERROR_SUCCESS
)
4418 ERR(": what the heck is going on?\n" );
4422 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
4423 NULL
, &returnTypeGUID
, (LPBYTE
)returnBuffer
,
4424 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
4426 ERR(": missing GUID registry data members\n" );
4427 RegCloseKey(hkServiceProvider
);
4430 RegCloseKey(hkServiceProvider
);
4432 /* FIXME: Check return types to ensure we're interpreting data right */
4433 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
4434 CLSIDFromString( buff
, &serviceProviderGUID
);
4435 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
4437 /* Fill in the DPNAME struct for the service provider */
4438 dpName
.dwSize
= sizeof( dpName
);
4440 dpName
.u1
.lpszShortNameA
= subKeyName
;
4441 dpName
.u2
.lpszLongNameA
= NULL
;
4443 /* Create the compound address for the service provider.
4444 NOTE: This is a gruesome architectural scar right now. DP uses DPL and DPL uses DP
4445 nast stuff. This may be why the native dll just gets around this little bit by
4446 allocating an 80 byte buffer which isn't even a filled with a valid compound
4447 address. Oh well. Creating a proper compound address is the way to go anyways
4448 despite this method taking slightly more heap space and realtime :) */
4450 dpCompoundAddress
.guidDataType
= DPAID_LobbyProvider
;
4451 dpCompoundAddress
.dwDataSize
= sizeof( GUID
);
4452 dpCompoundAddress
.lpData
= &serviceProviderGUID
;
4454 if( ( hr
= DPL_CreateCompoundAddress( &dpCompoundAddress
, 1, lpAddressBuffer
,
4455 &dwAddressBufferSize
, TRUE
) ) != DPERR_BUFFERTOOSMALL
)
4457 ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr
) );
4461 /* Now allocate the buffer */
4462 lpAddressBuffer
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwAddressBufferSize
);
4464 if( ( hr
= DPL_CreateCompoundAddress( &dpCompoundAddress
, 1, lpAddressBuffer
,
4465 &dwAddressBufferSize
, TRUE
) ) != DP_OK
)
4467 ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr
) );
4468 HeapFree( GetProcessHeap(), 0, lpAddressBuffer
);
4472 /* The enumeration will return FALSE if we are not to continue */
4473 if( !lpEnumCallback( &serviceProviderGUID
, lpAddressBuffer
, dwAddressBufferSize
,
4474 &dpName
, dwFlags
, lpContext
) )
4476 HeapFree( GetProcessHeap(), 0, lpAddressBuffer
);
4479 HeapFree( GetProcessHeap(), 0, lpAddressBuffer
);
4486 static HRESULT WINAPI
IDirectPlay4Impl_EnumConnections( IDirectPlay4
*iface
,
4487 const GUID
*application
, LPDPENUMCONNECTIONSCALLBACK enumcb
, void *context
, DWORD flags
)
4489 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4490 FIXME( "(%p)->(%p,%p,%p,0x%08x): stub\n", This
, application
, enumcb
, context
, flags
);
4494 static HRESULT WINAPI
IDirectPlay3AImpl_EnumGroupsInGroup( IDirectPlay3A
*iface
, DPID group
,
4495 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
4497 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4498 return IDirectPlayX_EnumGroupsInGroup( &This
->IDirectPlay4A_iface
, group
, instance
,
4499 enumplayercb
, context
, flags
);
4502 static HRESULT WINAPI
IDirectPlay3Impl_EnumGroupsInGroup( IDirectPlay3
*iface
, DPID group
,
4503 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
4505 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4506 return IDirectPlayX_EnumGroupsInGroup( &This
->IDirectPlay4_iface
, group
, instance
,
4507 enumplayercb
, context
, flags
);
4510 static HRESULT WINAPI
IDirectPlay4AImpl_EnumGroupsInGroup( IDirectPlay4A
*iface
, DPID group
,
4511 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
4513 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4514 return IDirectPlayX_EnumGroupsInGroup( &This
->IDirectPlay4_iface
, group
, instance
,
4515 enumplayercb
, context
, flags
);
4518 static HRESULT WINAPI
IDirectPlay4Impl_EnumGroupsInGroup( IDirectPlay4
*iface
, DPID group
,
4519 GUID
*instance
, LPDPENUMPLAYERSCALLBACK2 enumplayercb
, void *context
, DWORD flags
)
4521 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4525 FIXME( "(%p)->(0x%08x,%p,%p,%p,0x%08x): semi stub\n", This
, group
, instance
, enumplayercb
,
4528 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
4529 return DPERR_UNINITIALIZED
;
4531 if ( ( gdata
= DP_FindAnyGroup(This
, group
) ) == NULL
)
4532 return DPERR_INVALIDGROUP
;
4534 if ( DPQ_IS_EMPTY( gdata
->groups
) )
4538 for( glist
= DPQ_FIRST( gdata
->groups
); ; glist
= DPQ_NEXT( glist
->groups
) )
4540 /* FIXME: Should check flags for match here */
4541 if ( !(*enumplayercb
)( glist
->lpGData
->dpid
, DPPLAYERTYPE_GROUP
, &glist
->lpGData
->name
,
4543 return DP_OK
; /* User requested break */
4545 if ( DPQ_IS_ENDOFLIST( glist
->groups
) )
4552 static HRESULT WINAPI
IDirectPlay3AImpl_GetGroupConnectionSettings( IDirectPlay3A
*iface
,
4553 DWORD flags
, DPID group
, void *data
, DWORD
*size
)
4555 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4556 return IDirectPlayX_GetGroupConnectionSettings( &This
->IDirectPlay4A_iface
, flags
, group
,
4560 static HRESULT WINAPI
IDirectPlay3Impl_GetGroupConnectionSettings( IDirectPlay3
*iface
,
4561 DWORD flags
, DPID group
, void *data
, DWORD
*size
)
4563 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4564 return IDirectPlayX_GetGroupConnectionSettings( &This
->IDirectPlay4_iface
, flags
, group
,
4568 static HRESULT WINAPI
IDirectPlay4AImpl_GetGroupConnectionSettings( IDirectPlay4A
*iface
,
4569 DWORD flags
, DPID group
, void *data
, DWORD
*size
)
4571 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4572 FIXME("(%p)->(0x%08x,0x%08x,%p,%p): stub\n", This
, flags
, group
, data
, size
);
4576 static HRESULT WINAPI
IDirectPlay4Impl_GetGroupConnectionSettings( IDirectPlay4
*iface
, DWORD flags
,
4577 DPID group
, void *data
, DWORD
*size
)
4579 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4580 FIXME( "(%p)->(0x%08x,0x%08x,%p,%p): stub\n", This
, flags
, group
, data
, size
);
4584 static BOOL CALLBACK
DP_GetSpLpGuidFromCompoundAddress(
4585 REFGUID guidDataType
,
4590 /* Looking for the GUID of the provider to load */
4591 if( ( IsEqualGUID( guidDataType
, &DPAID_ServiceProvider
) ) ||
4592 ( IsEqualGUID( guidDataType
, &DPAID_LobbyProvider
) )
4595 TRACE( "Found SP/LP (%s) %s (data size = 0x%08x)\n",
4596 debugstr_guid( guidDataType
), debugstr_guid( lpData
), dwDataSize
);
4598 if( dwDataSize
!= sizeof( GUID
) )
4600 ERR( "Invalid sp/lp guid size 0x%08x\n", dwDataSize
);
4603 memcpy( lpContext
, lpData
, dwDataSize
);
4605 /* There shouldn't be more than 1 GUID/compound address */
4609 /* Still waiting for what we want */
4614 /* Find and perform a LoadLibrary on the requested SP or LP GUID */
4615 static HMODULE
DP_LoadSP( LPCGUID lpcGuid
, LPSPINITDATA lpSpData
, LPBOOL lpbIsDpSp
)
4618 LPCSTR spSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
4619 LPCSTR lpSubKey
= "SOFTWARE\\Microsoft\\DirectPlay\\Lobby Providers";
4620 LPCSTR guidDataSubKey
= "Guid";
4621 LPCSTR majVerDataSubKey
= "dwReserved1";
4622 LPCSTR minVerDataSubKey
= "dwReserved2";
4623 LPCSTR pathSubKey
= "Path";
4625 TRACE( " request to load %s\n", debugstr_guid( lpcGuid
) );
4627 /* FIXME: Cloned code with a quick hack. */
4628 for( i
=0; i
<2; i
++ )
4631 LPCSTR searchSubKey
;
4632 char subKeyName
[51];
4633 DWORD dwIndex
, sizeOfSubKeyName
=50;
4636 (i
== 0) ? (searchSubKey
= spSubKey
) : (searchSubKey
= lpSubKey
);
4637 *lpbIsDpSp
= (i
== 0);
4640 /* Need to loop over the service providers in the registry */
4641 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE
, searchSubKey
,
4642 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
4644 /* Hmmm. Does this mean that there are no service providers? */
4645 ERR(": no service providers?\n");
4649 /* Traverse all the service providers we have available */
4651 RegEnumKeyExA( hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
4652 NULL
, NULL
, NULL
, &filetime
) != ERROR_NO_MORE_ITEMS
;
4653 ++dwIndex
, sizeOfSubKeyName
=51 )
4656 HKEY hkServiceProvider
;
4657 GUID serviceProviderGUID
;
4658 DWORD returnType
, sizeOfReturnBuffer
= 255;
4659 char returnBuffer
[256];
4663 TRACE(" this time through: %s\n", subKeyName
);
4665 /* Get a handle for this particular service provider */
4666 if( RegOpenKeyExA( hkResult
, subKeyName
, 0, KEY_READ
,
4667 &hkServiceProvider
) != ERROR_SUCCESS
)
4669 ERR(": what the heck is going on?\n" );
4673 if( RegQueryValueExA( hkServiceProvider
, guidDataSubKey
,
4674 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
4675 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
4677 ERR(": missing GUID registry data members\n" );
4681 /* FIXME: Check return types to ensure we're interpreting data right */
4682 MultiByteToWideChar( CP_ACP
, 0, returnBuffer
, -1, buff
, sizeof(buff
)/sizeof(WCHAR
) );
4683 CLSIDFromString( buff
, &serviceProviderGUID
);
4684 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */
4686 /* Determine if this is the Service Provider that the user asked for */
4687 if( !IsEqualGUID( &serviceProviderGUID
, lpcGuid
) )
4692 if( i
== 0 ) /* DP SP */
4694 len
= MultiByteToWideChar( CP_ACP
, 0, subKeyName
, -1, NULL
, 0 );
4695 lpSpData
->lpszName
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
4696 MultiByteToWideChar( CP_ACP
, 0, subKeyName
, -1, lpSpData
->lpszName
, len
);
4699 sizeOfReturnBuffer
= 255;
4701 /* Get dwReserved1 */
4702 if( RegQueryValueExA( hkServiceProvider
, majVerDataSubKey
,
4703 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
4704 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
4706 ERR(": missing dwReserved1 registry data members\n") ;
4711 memcpy( &lpSpData
->dwReserved1
, returnBuffer
, sizeof(lpSpData
->dwReserved1
) );
4713 sizeOfReturnBuffer
= 255;
4715 /* Get dwReserved2 */
4716 if( RegQueryValueExA( hkServiceProvider
, minVerDataSubKey
,
4717 NULL
, &returnType
, (LPBYTE
)returnBuffer
,
4718 &sizeOfReturnBuffer
) != ERROR_SUCCESS
)
4720 ERR(": missing dwReserved1 registry data members\n") ;
4725 memcpy( &lpSpData
->dwReserved2
, returnBuffer
, sizeof(lpSpData
->dwReserved2
) );
4727 sizeOfReturnBuffer
= 255;
4729 /* Get the path for this service provider */
4730 if( ( dwTemp
= RegQueryValueExA( hkServiceProvider
, pathSubKey
,
4731 NULL
, NULL
, (LPBYTE
)returnBuffer
,
4732 &sizeOfReturnBuffer
) ) != ERROR_SUCCESS
)
4734 ERR(": missing PATH registry data members: 0x%08x\n", dwTemp
);
4738 TRACE( "Loading %s\n", returnBuffer
);
4739 return LoadLibraryA( returnBuffer
);
4746 static HRESULT
DP_InitializeDPSP( IDirectPlayImpl
*This
, HMODULE hServiceProvider
)
4749 LPDPSP_SPINIT SPInit
;
4751 /* Initialize the service provider by calling SPInit */
4752 SPInit
= (LPDPSP_SPINIT
)GetProcAddress( hServiceProvider
, "SPInit" );
4754 if( SPInit
== NULL
)
4756 ERR( "Service provider doesn't provide SPInit interface?\n" );
4757 FreeLibrary( hServiceProvider
);
4758 return DPERR_UNAVAILABLE
;
4761 TRACE( "Calling SPInit (DP SP entry point)\n" );
4763 hr
= (*SPInit
)( &This
->dp2
->spData
);
4767 ERR( "DP SP Initialization failed: %s\n", DPLAYX_HresultToString(hr
) );
4768 FreeLibrary( hServiceProvider
);
4772 /* FIXME: Need to verify the sanity of the returned callback table
4773 * using IsBadCodePtr */
4774 This
->dp2
->bSPInitialized
= TRUE
;
4776 /* This interface is now initialized as a DP object */
4777 This
->dp2
->connectionInitialized
= DP_SERVICE_PROVIDER
;
4779 /* Store the handle of the module so that we can unload it later */
4780 This
->dp2
->hServiceProvider
= hServiceProvider
;
4785 static HRESULT
DP_InitializeDPLSP( IDirectPlayImpl
*This
, HMODULE hLobbyProvider
)
4788 LPSP_INIT DPLSPInit
;
4790 /* Initialize the service provider by calling SPInit */
4791 DPLSPInit
= (LPSP_INIT
)GetProcAddress( hLobbyProvider
, "DPLSPInit" );
4793 if( DPLSPInit
== NULL
)
4795 ERR( "Service provider doesn't provide DPLSPInit interface?\n" );
4796 FreeLibrary( hLobbyProvider
);
4797 return DPERR_UNAVAILABLE
;
4800 TRACE( "Calling DPLSPInit (DPL SP entry point)\n" );
4802 hr
= (*DPLSPInit
)( &This
->dp2
->dplspData
);
4806 ERR( "DPL SP Initialization failed: %s\n", DPLAYX_HresultToString(hr
) );
4807 FreeLibrary( hLobbyProvider
);
4811 /* FIXME: Need to verify the sanity of the returned callback table
4812 * using IsBadCodePtr */
4814 This
->dp2
->bDPLSPInitialized
= TRUE
;
4816 /* This interface is now initialized as a lobby object */
4817 This
->dp2
->connectionInitialized
= DP_LOBBY_PROVIDER
;
4819 /* Store the handle of the module so that we can unload it later */
4820 This
->dp2
->hDPLobbyProvider
= hLobbyProvider
;
4825 static HRESULT WINAPI
IDirectPlay3AImpl_InitializeConnection( IDirectPlay3A
*iface
,
4826 void *connection
, DWORD flags
)
4828 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4829 return IDirectPlayX_InitializeConnection( &This
->IDirectPlay4A_iface
, connection
, flags
);
4832 static HRESULT WINAPI
IDirectPlay3Impl_InitializeConnection( IDirectPlay3
*iface
,
4833 void *connection
, DWORD flags
)
4835 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4836 return IDirectPlayX_InitializeConnection( &This
->IDirectPlay4_iface
, connection
, flags
);
4839 static HRESULT WINAPI
IDirectPlay4AImpl_InitializeConnection( IDirectPlay4A
*iface
,
4840 void *connection
, DWORD flags
)
4842 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4843 return IDirectPlayX_InitializeConnection( &This
->IDirectPlay4_iface
, connection
, flags
);
4846 static HRESULT WINAPI
IDirectPlay4Impl_InitializeConnection( IDirectPlay4
*iface
,
4847 void *connection
, DWORD flags
)
4849 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4852 const DWORD size
= 80; /* FIXME: Need to calculate it correctly */
4853 BOOL is_dp_sp
; /* TRUE if Direct Play SP, FALSE if Direct Play Lobby SP */
4856 TRACE( "(%p)->(%p,0x%08x)\n", This
, connection
, flags
);
4859 return DPERR_INVALIDPARAMS
;
4862 return DPERR_INVALIDFLAGS
;
4864 if ( This
->dp2
->connectionInitialized
!= NO_PROVIDER
)
4865 return DPERR_ALREADYINITIALIZED
;
4867 /* Find out what the requested SP is and how large this buffer is */
4868 hr
= DPL_EnumAddress( DP_GetSpLpGuidFromCompoundAddress
, connection
, size
, &sp
);
4872 ERR( "Invalid compound address?\n" );
4873 return DPERR_UNAVAILABLE
;
4876 /* Load the service provider */
4877 servprov
= DP_LoadSP( &sp
, &This
->dp2
->spData
, &is_dp_sp
);
4881 ERR( "Unable to load service provider %s\n", debugstr_guid(&sp
) );
4882 return DPERR_UNAVAILABLE
;
4887 /* Fill in what we can of the Service Provider required information.
4888 * The rest was be done in DP_LoadSP
4890 This
->dp2
->spData
.lpAddress
= connection
;
4891 This
->dp2
->spData
.dwAddressSize
= size
;
4892 This
->dp2
->spData
.lpGuid
= &sp
;
4893 hr
= DP_InitializeDPSP( This
, servprov
);
4897 This
->dp2
->dplspData
.lpAddress
= connection
;
4898 hr
= DP_InitializeDPLSP( This
, servprov
);
4907 static HRESULT WINAPI
IDirectPlay3AImpl_SecureOpen( IDirectPlay3A
*iface
,
4908 const DPSESSIONDESC2
*sdesc
, DWORD flags
, const DPSECURITYDESC
*security
,
4909 const DPCREDENTIALS
*credentials
)
4911 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4912 return IDirectPlayX_SecureOpen( &This
->IDirectPlay4A_iface
, sdesc
, flags
, security
,
4916 static HRESULT WINAPI
IDirectPlay3Impl_SecureOpen( IDirectPlay3
*iface
,
4917 const DPSESSIONDESC2
*sdesc
, DWORD flags
, const DPSECURITYDESC
*security
,
4918 const DPCREDENTIALS
*credentials
)
4920 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4921 return IDirectPlayX_SecureOpen( &This
->IDirectPlay4_iface
, sdesc
, flags
, security
,
4925 static HRESULT WINAPI
IDirectPlay4AImpl_SecureOpen( IDirectPlay4A
*iface
,
4926 const DPSESSIONDESC2
*lpsd
, DWORD dwFlags
, const DPSECURITYDESC
*lpSecurity
,
4927 const DPCREDENTIALS
*lpCredentials
)
4929 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4930 return DP_SecureOpen( This
, lpsd
, dwFlags
, lpSecurity
, lpCredentials
, TRUE
);
4933 static HRESULT WINAPI
IDirectPlay4Impl_SecureOpen( IDirectPlay4
*iface
,
4934 const DPSESSIONDESC2
*lpsd
, DWORD dwFlags
, const DPSECURITYDESC
*lpSecurity
,
4935 const DPCREDENTIALS
*lpCredentials
)
4937 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4938 return DP_SecureOpen( This
, lpsd
, dwFlags
, lpSecurity
, lpCredentials
, FALSE
);
4941 static HRESULT WINAPI
IDirectPlay3AImpl_SendChatMessage( IDirectPlay3A
*iface
, DPID from
, DPID to
,
4942 DWORD flags
, DPCHAT
*chatmsg
)
4944 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4945 return IDirectPlayX_SendChatMessage( &This
->IDirectPlay4A_iface
, from
, to
, flags
, chatmsg
);
4948 static HRESULT WINAPI
IDirectPlay3Impl_SendChatMessage( IDirectPlay3
*iface
, DPID from
, DPID to
,
4949 DWORD flags
, DPCHAT
*chatmsg
)
4951 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4952 return IDirectPlayX_SendChatMessage( &This
->IDirectPlay4_iface
, from
, to
, flags
, chatmsg
);
4955 static HRESULT WINAPI
IDirectPlay4AImpl_SendChatMessage( IDirectPlay4A
*iface
, DPID from
,
4956 DPID to
, DWORD flags
, DPCHAT
*chatmsg
)
4958 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4959 FIXME("(%p)->(0x%08x,0x%08x,0x%08x,%p): stub\n", This
, from
, to
, flags
, chatmsg
);
4963 static HRESULT WINAPI
IDirectPlay4Impl_SendChatMessage( IDirectPlay4
*iface
, DPID from
, DPID to
,
4964 DWORD flags
, DPCHAT
*chatmsg
)
4966 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4967 FIXME( "(%p)->(0x%08x,0x%08x,0x%08x,%p): stub\n", This
, from
, to
, flags
, chatmsg
);
4971 static HRESULT WINAPI
IDirectPlay3AImpl_SetGroupConnectionSettings( IDirectPlay3A
*iface
,
4972 DWORD flags
, DPID group
, DPLCONNECTION
*connection
)
4974 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
4975 return IDirectPlayX_SetGroupConnectionSettings( &This
->IDirectPlay4A_iface
, flags
, group
,
4979 static HRESULT WINAPI
IDirectPlay3Impl_SetGroupConnectionSettings( IDirectPlay3
*iface
,
4980 DWORD flags
, DPID group
, DPLCONNECTION
*connection
)
4982 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
4983 return IDirectPlayX_SetGroupConnectionSettings( &This
->IDirectPlay4_iface
, flags
, group
,
4987 static HRESULT WINAPI
IDirectPlay4AImpl_SetGroupConnectionSettings( IDirectPlay4A
*iface
,
4988 DWORD flags
, DPID group
, DPLCONNECTION
*connection
)
4990 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
4991 FIXME("(%p)->(0x%08x,0x%08x,%p): stub\n", This
, flags
, group
, connection
);
4995 static HRESULT WINAPI
IDirectPlay4Impl_SetGroupConnectionSettings( IDirectPlay4
*iface
, DWORD flags
,
4996 DPID group
, DPLCONNECTION
*connection
)
4998 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
4999 FIXME( "(%p)->(0x%08x,0x%08x,%p): stub\n", This
, flags
, group
, connection
);
5003 static HRESULT WINAPI
IDirectPlay3AImpl_StartSession( IDirectPlay3A
*iface
, DWORD flags
,
5006 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
5007 return IDirectPlayX_StartSession( &This
->IDirectPlay4A_iface
, flags
, group
);
5010 static HRESULT WINAPI
IDirectPlay3Impl_StartSession( IDirectPlay3
*iface
, DWORD flags
,
5013 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
5014 return IDirectPlayX_StartSession( &This
->IDirectPlay4_iface
, flags
, group
);
5017 static HRESULT WINAPI
IDirectPlay4AImpl_StartSession( IDirectPlay4A
*iface
, DWORD flags
,
5020 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5021 return IDirectPlayX_StartSession( &This
->IDirectPlay4_iface
, flags
, group
);
5024 static HRESULT WINAPI
IDirectPlay4Impl_StartSession( IDirectPlay4
*iface
, DWORD flags
, DPID group
)
5026 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5027 FIXME( "(%p)->(0x%08x,0x%08x): stub\n", This
, flags
, group
);
5031 static HRESULT WINAPI
IDirectPlay3AImpl_GetGroupFlags( IDirectPlay3A
*iface
, DPID group
,
5034 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
5035 return IDirectPlayX_GetGroupFlags( &This
->IDirectPlay4A_iface
, group
, flags
);
5038 static HRESULT WINAPI
IDirectPlay3Impl_GetGroupFlags( IDirectPlay3
*iface
, DPID group
,
5041 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
5042 return IDirectPlayX_GetGroupFlags( &This
->IDirectPlay4_iface
, group
, flags
);
5045 static HRESULT WINAPI
IDirectPlay4AImpl_GetGroupFlags( IDirectPlay4A
*iface
, DPID group
,
5048 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5049 return IDirectPlayX_GetGroupFlags( &This
->IDirectPlay4_iface
, group
, flags
);
5052 static HRESULT WINAPI
IDirectPlay4Impl_GetGroupFlags( IDirectPlay4
*iface
, DPID group
,
5055 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5056 FIXME( "(%p)->(0x%08x,%p): stub\n", This
, group
, flags
);
5060 static HRESULT WINAPI
IDirectPlay3AImpl_GetGroupParent( IDirectPlay3A
*iface
, DPID group
,
5063 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
5064 return IDirectPlayX_GetGroupParent( &This
->IDirectPlay4A_iface
, group
, parent
);
5067 static HRESULT WINAPI
IDirectPlay3Impl_GetGroupParent( IDirectPlay3
*iface
, DPID group
,
5070 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
5071 return IDirectPlayX_GetGroupParent( &This
->IDirectPlay4_iface
, group
, parent
);
5074 static HRESULT WINAPI
IDirectPlay4AImpl_GetGroupParent( IDirectPlay4A
*iface
, DPID group
,
5077 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5078 return IDirectPlayX_GetGroupParent( &This
->IDirectPlay4_iface
, group
, parent
);
5081 static HRESULT WINAPI
IDirectPlay4Impl_GetGroupParent( IDirectPlay4
*iface
, DPID group
,
5084 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5087 TRACE( "(%p)->(0x%08x,%p)\n", This
, group
, parent
);
5089 if ( ( gdata
= DP_FindAnyGroup( This
, group
) ) == NULL
)
5090 return DPERR_INVALIDGROUP
;
5092 *parent
= gdata
->dpid
;
5097 static HRESULT WINAPI
IDirectPlay3AImpl_GetPlayerAccount( IDirectPlay3A
*iface
, DPID player
,
5098 DWORD flags
, void *data
, DWORD
*size
)
5100 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
5101 return IDirectPlayX_GetPlayerAccount( &This
->IDirectPlay4A_iface
, player
, flags
, data
, size
);
5104 static HRESULT WINAPI
IDirectPlay3Impl_GetPlayerAccount( IDirectPlay3
*iface
, DPID player
,
5105 DWORD flags
, void *data
, DWORD
*size
)
5107 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
5108 return IDirectPlayX_GetPlayerAccount( &This
->IDirectPlay4_iface
, player
, flags
, data
, size
);
5111 static HRESULT WINAPI
IDirectPlay4AImpl_GetPlayerAccount( IDirectPlay4A
*iface
, DPID player
,
5112 DWORD flags
, void *data
, DWORD
*size
)
5114 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5115 FIXME("(%p)->(0x%08x,0x%08x,%p,%p): stub\n", This
, player
, flags
, data
, size
);
5119 static HRESULT WINAPI
IDirectPlay4Impl_GetPlayerAccount( IDirectPlay4
*iface
, DPID player
,
5120 DWORD flags
, void *data
, DWORD
*size
)
5122 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5123 FIXME( "(%p)->(0x%08x,0x%08x,%p,%p): stub\n", This
, player
, flags
, data
, size
);
5127 static HRESULT WINAPI
IDirectPlay3AImpl_GetPlayerFlags( IDirectPlay3A
*iface
, DPID player
,
5130 IDirectPlayImpl
*This
= impl_from_IDirectPlay3A( iface
);
5131 return IDirectPlayX_GetPlayerFlags( &This
->IDirectPlay4A_iface
, player
, flags
);
5134 static HRESULT WINAPI
IDirectPlay3Impl_GetPlayerFlags( IDirectPlay3
*iface
, DPID player
,
5137 IDirectPlayImpl
*This
= impl_from_IDirectPlay3( iface
);
5138 return IDirectPlayX_GetPlayerFlags( &This
->IDirectPlay4_iface
, player
, flags
);
5141 static HRESULT WINAPI
IDirectPlay4AImpl_GetPlayerFlags( IDirectPlay4A
*iface
, DPID player
,
5144 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5145 return IDirectPlayX_GetPlayerFlags( &This
->IDirectPlay4_iface
, player
, flags
);
5148 static HRESULT WINAPI
IDirectPlay4Impl_GetPlayerFlags( IDirectPlay4
*iface
, DPID player
,
5151 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5152 FIXME( "(%p)->(0x%08x,%p): stub\n", This
, player
, flags
);
5156 static HRESULT WINAPI
IDirectPlay4AImpl_GetGroupOwner( IDirectPlay4A
*iface
, DPID group
,
5159 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5160 return IDirectPlayX_GetGroupOwner( &This
->IDirectPlay4_iface
, group
, owner
);
5163 static HRESULT WINAPI
IDirectPlay4Impl_GetGroupOwner( IDirectPlay4
*iface
, DPID group
,
5166 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5167 FIXME( "(%p)->(0x%08x,%p): stub\n", This
, group
, owner
);
5171 static HRESULT WINAPI
IDirectPlay4AImpl_SetGroupOwner( IDirectPlay4A
*iface
, DPID group
,
5174 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5175 return IDirectPlayX_SetGroupOwner( &This
->IDirectPlay4_iface
, group
, owner
);
5178 static HRESULT WINAPI
IDirectPlay4Impl_SetGroupOwner( IDirectPlay4
*iface
, DPID group
,
5181 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5182 FIXME( "(%p)->(0x%08x,0x%08x): stub\n", This
, group
, owner
);
5186 static HRESULT WINAPI
IDirectPlay4AImpl_SendEx( IDirectPlay4A
*iface
, DPID from
, DPID to
,
5187 DWORD flags
, void *data
, DWORD size
, DWORD priority
, DWORD timeout
, void *context
,
5190 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5191 return IDirectPlayX_SendEx( &This
->IDirectPlay4_iface
, from
, to
, flags
, data
, size
, priority
,
5192 timeout
, context
, msgid
);
5195 static HRESULT WINAPI
IDirectPlay4Impl_SendEx( IDirectPlay4
*iface
, DPID from
, DPID to
,
5196 DWORD flags
, void *data
, DWORD size
, DWORD priority
, DWORD timeout
, void *context
,
5199 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5201 FIXME( "(%p)->(0x%08x,0x%08x,0x%08x,%p,0x%08x,0x%08x,0x%08x,%p,%p): semi-stub\n",
5202 This
, from
, to
, flags
, data
, size
, priority
, timeout
, context
, msgid
);
5204 if ( This
->dp2
->connectionInitialized
== NO_PROVIDER
)
5205 return DPERR_UNINITIALIZED
;
5207 /* FIXME: Add parameter checking */
5208 /* FIXME: First call to this needs to acquire a message id which will be
5209 * used for multiple sends
5212 /* NOTE: Can't send messages to yourself - this will be trapped in receive */
5214 /* Verify that the message is being sent from a valid local player. The
5215 * from player may be anonymous DPID_UNKNOWN
5217 if ( from
!= DPID_UNKNOWN
&& !DP_FindPlayer( This
, from
) )
5219 WARN( "INFO: Invalid from player 0x%08x\n", from
);
5220 return DPERR_INVALIDPLAYER
;
5223 /* Verify that the message is being sent to a valid player, group or to
5224 * everyone. If it's valid, send it to those players.
5226 if ( to
== DPID_ALLPLAYERS
)
5228 /* See if SP has the ability to multicast. If so, use it */
5229 if ( This
->dp2
->spData
.lpCB
->SendToGroupEx
)
5230 FIXME( "Use group sendex to group 0\n" );
5231 else if ( This
->dp2
->spData
.lpCB
->SendToGroup
) /* obsolete interface */
5232 FIXME( "Use obsolete group send to group 0\n" );
5233 else /* No multicast, multiplicate */
5234 FIXME( "Send to all players using EnumPlayersInGroup\n" );
5236 else if ( DP_FindPlayer( This
, to
) )
5238 /* Have the service provider send this message */
5239 /* FIXME: Could optimize for local interface sends */
5240 return DP_SP_SendEx( This
, flags
, data
, size
, priority
, timeout
, context
, msgid
);
5242 else if ( DP_FindAnyGroup( This
, to
) )
5244 /* See if SP has the ability to multicast. If so, use it */
5245 if ( This
->dp2
->spData
.lpCB
->SendToGroupEx
)
5246 FIXME( "Use group sendex\n" );
5247 else if ( This
->dp2
->spData
.lpCB
->SendToGroup
) /* obsolete interface */
5248 FIXME( "Use obsolete group send to group\n" );
5249 else /* No multicast, multiplicate */
5250 FIXME( "Send to all players using EnumPlayersInGroup\n" );
5254 return DPERR_INVALIDPLAYER
;
5256 /* FIXME: Should return what the send returned */
5260 static HRESULT
DP_SP_SendEx( IDirectPlayImpl
*This
, DWORD dwFlags
, void *lpData
, DWORD dwDataSize
,
5261 DWORD dwPriority
, DWORD dwTimeout
, void *lpContext
, DWORD
*lpdwMsgID
)
5265 FIXME( ": stub\n" );
5267 /* FIXME: This queuing should only be for async messages */
5269 lpMElem
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof( *lpMElem
) );
5270 lpMElem
->msg
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDataSize
);
5272 CopyMemory( lpMElem
->msg
, lpData
, dwDataSize
);
5274 /* FIXME: Need to queue based on priority */
5275 DPQ_INSERT( This
->dp2
->sendMsgs
, lpMElem
, msgs
);
5280 static HRESULT WINAPI
IDirectPlay4AImpl_GetMessageQueue( IDirectPlay4A
*iface
, DPID from
, DPID to
,
5281 DWORD flags
, DWORD
*msgs
, DWORD
*bytes
)
5283 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5284 return IDirectPlayX_GetMessageQueue( &This
->IDirectPlay4_iface
, from
, to
, flags
, msgs
, bytes
);
5287 static HRESULT WINAPI
IDirectPlay4Impl_GetMessageQueue( IDirectPlay4
*iface
, DPID from
, DPID to
,
5288 DWORD flags
, DWORD
*msgs
, DWORD
*bytes
)
5290 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5293 FIXME( "(%p)->(0x%08x,0x%08x,0x%08x,%p,%p): semi-stub\n", This
, from
, to
, flags
, msgs
, bytes
);
5295 /* FIXME: Do we need to do from and to sanity checking here? */
5296 /* FIXME: What about sends which are not immediate? */
5298 if ( This
->dp2
->spData
.lpCB
->GetMessageQueue
)
5300 DPSP_GETMESSAGEQUEUEDATA data
;
5302 FIXME( "Calling SP GetMessageQueue - is it right?\n" );
5304 /* FIXME: None of this is documented :( */
5305 data
.lpISP
= This
->dp2
->spData
.lpISP
;
5306 data
.dwFlags
= flags
;
5309 data
.lpdwNumMsgs
= msgs
;
5310 data
.lpdwNumBytes
= bytes
;
5312 hr
= (*This
->dp2
->spData
.lpCB
->GetMessageQueue
)( &data
);
5315 FIXME( "No SP for GetMessageQueue - fake some data\n" );
5320 static HRESULT
dplay_cancelmsg ( IDirectPlayImpl
* This
, DWORD msgid
, DWORD flags
, DWORD minprio
,
5325 FIXME( "(%p)->(0x%08x,0x%08x): semi stub\n", This
, msgid
, flags
);
5327 if ( This
->dp2
->spData
.lpCB
->Cancel
)
5329 DPSP_CANCELDATA data
;
5331 TRACE( "Calling SP Cancel\n" );
5333 /* FIXME: Undocumented callback */
5335 data
.lpISP
= This
->dp2
->spData
.lpISP
;
5336 data
.dwFlags
= flags
;
5337 data
.lprglpvSPMsgID
= NULL
;
5338 data
.cSPMsgID
= msgid
;
5339 data
.dwMinPriority
= minprio
;
5340 data
.dwMaxPriority
= maxprio
;
5342 hr
= (*This
->dp2
->spData
.lpCB
->Cancel
)( &data
);
5345 FIXME( "SP doesn't implement Cancel\n" );
5350 static HRESULT WINAPI
IDirectPlay4AImpl_CancelMessage( IDirectPlay4A
*iface
, DWORD msgid
,
5353 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5354 return IDirectPlayX_CancelMessage( &This
->IDirectPlay4_iface
, msgid
, flags
);
5357 static HRESULT WINAPI
IDirectPlay4Impl_CancelMessage( IDirectPlay4
*iface
, DWORD msgid
,
5360 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5363 return DPERR_INVALIDFLAGS
;
5366 flags
|= DPCANCELSEND_ALL
;
5368 return dplay_cancelmsg( This
, msgid
, flags
, 0, 0 );
5371 static HRESULT WINAPI
IDirectPlay4AImpl_CancelPriority( IDirectPlay4A
*iface
, DWORD minprio
,
5372 DWORD maxprio
, DWORD flags
)
5374 IDirectPlayImpl
*This
= impl_from_IDirectPlay4A( iface
);
5375 return IDirectPlayX_CancelPriority( &This
->IDirectPlay4_iface
, minprio
, maxprio
, flags
);
5378 static HRESULT WINAPI
IDirectPlay4Impl_CancelPriority( IDirectPlay4
*iface
, DWORD minprio
,
5379 DWORD maxprio
, DWORD flags
)
5381 IDirectPlayImpl
*This
= impl_from_IDirectPlay4( iface
);
5384 return DPERR_INVALIDFLAGS
;
5386 return dplay_cancelmsg( This
, 0, DPCANCELSEND_PRIORITY
, minprio
, maxprio
);
5389 static const IDirectPlay2Vtbl dp2_vt
=
5391 IDirectPlay2Impl_QueryInterface
,
5392 IDirectPlay2Impl_AddRef
,
5393 IDirectPlay2Impl_Release
,
5394 IDirectPlay2Impl_AddPlayerToGroup
,
5395 IDirectPlay2Impl_Close
,
5396 IDirectPlay2Impl_CreateGroup
,
5397 IDirectPlay2Impl_CreatePlayer
,
5398 IDirectPlay2Impl_DeletePlayerFromGroup
,
5399 IDirectPlay2Impl_DestroyGroup
,
5400 IDirectPlay2Impl_DestroyPlayer
,
5401 IDirectPlay2Impl_EnumGroupPlayers
,
5402 IDirectPlay2Impl_EnumGroups
,
5403 IDirectPlay2Impl_EnumPlayers
,
5404 IDirectPlay2Impl_EnumSessions
,
5405 IDirectPlay2Impl_GetCaps
,
5406 IDirectPlay2Impl_GetGroupData
,
5407 IDirectPlay2Impl_GetGroupName
,
5408 IDirectPlay2Impl_GetMessageCount
,
5409 IDirectPlay2Impl_GetPlayerAddress
,
5410 IDirectPlay2Impl_GetPlayerCaps
,
5411 IDirectPlay2Impl_GetPlayerData
,
5412 IDirectPlay2Impl_GetPlayerName
,
5413 IDirectPlay2Impl_GetSessionDesc
,
5414 IDirectPlay2Impl_Initialize
,
5415 IDirectPlay2Impl_Open
,
5416 IDirectPlay2Impl_Receive
,
5417 IDirectPlay2Impl_Send
,
5418 IDirectPlay2Impl_SetGroupData
,
5419 IDirectPlay2Impl_SetGroupName
,
5420 IDirectPlay2Impl_SetPlayerData
,
5421 IDirectPlay2Impl_SetPlayerName
,
5422 IDirectPlay2Impl_SetSessionDesc
5425 static const IDirectPlay2Vtbl dp2A_vt
=
5427 IDirectPlay2AImpl_QueryInterface
,
5428 IDirectPlay2AImpl_AddRef
,
5429 IDirectPlay2AImpl_Release
,
5430 IDirectPlay2AImpl_AddPlayerToGroup
,
5431 IDirectPlay2AImpl_Close
,
5432 IDirectPlay2AImpl_CreateGroup
,
5433 IDirectPlay2AImpl_CreatePlayer
,
5434 IDirectPlay2AImpl_DeletePlayerFromGroup
,
5435 IDirectPlay2AImpl_DestroyGroup
,
5436 IDirectPlay2AImpl_DestroyPlayer
,
5437 IDirectPlay2AImpl_EnumGroupPlayers
,
5438 IDirectPlay2AImpl_EnumGroups
,
5439 IDirectPlay2AImpl_EnumPlayers
,
5440 IDirectPlay2AImpl_EnumSessions
,
5441 IDirectPlay2AImpl_GetCaps
,
5442 IDirectPlay2AImpl_GetGroupData
,
5443 IDirectPlay2AImpl_GetGroupName
,
5444 IDirectPlay2AImpl_GetMessageCount
,
5445 IDirectPlay2AImpl_GetPlayerAddress
,
5446 IDirectPlay2AImpl_GetPlayerCaps
,
5447 IDirectPlay2AImpl_GetPlayerData
,
5448 IDirectPlay2AImpl_GetPlayerName
,
5449 IDirectPlay2AImpl_GetSessionDesc
,
5450 IDirectPlay2AImpl_Initialize
,
5451 IDirectPlay2AImpl_Open
,
5452 IDirectPlay2AImpl_Receive
,
5453 IDirectPlay2AImpl_Send
,
5454 IDirectPlay2AImpl_SetGroupData
,
5455 IDirectPlay2AImpl_SetGroupName
,
5456 IDirectPlay2AImpl_SetPlayerData
,
5457 IDirectPlay2AImpl_SetPlayerName
,
5458 IDirectPlay2AImpl_SetSessionDesc
5461 static const IDirectPlay3Vtbl dp3_vt
=
5463 IDirectPlay3Impl_QueryInterface
,
5464 IDirectPlay3Impl_AddRef
,
5465 IDirectPlay3Impl_Release
,
5466 IDirectPlay3Impl_AddPlayerToGroup
,
5467 IDirectPlay3Impl_Close
,
5468 IDirectPlay3Impl_CreateGroup
,
5469 IDirectPlay3Impl_CreatePlayer
,
5470 IDirectPlay3Impl_DeletePlayerFromGroup
,
5471 IDirectPlay3Impl_DestroyGroup
,
5472 IDirectPlay3Impl_DestroyPlayer
,
5473 IDirectPlay3Impl_EnumGroupPlayers
,
5474 IDirectPlay3Impl_EnumGroups
,
5475 IDirectPlay3Impl_EnumPlayers
,
5476 IDirectPlay3Impl_EnumSessions
,
5477 IDirectPlay3Impl_GetCaps
,
5478 IDirectPlay3Impl_GetGroupData
,
5479 IDirectPlay3Impl_GetGroupName
,
5480 IDirectPlay3Impl_GetMessageCount
,
5481 IDirectPlay3Impl_GetPlayerAddress
,
5482 IDirectPlay3Impl_GetPlayerCaps
,
5483 IDirectPlay3Impl_GetPlayerData
,
5484 IDirectPlay3Impl_GetPlayerName
,
5485 IDirectPlay3Impl_GetSessionDesc
,
5486 IDirectPlay3Impl_Initialize
,
5487 IDirectPlay3Impl_Open
,
5488 IDirectPlay3Impl_Receive
,
5489 IDirectPlay3Impl_Send
,
5490 IDirectPlay3Impl_SetGroupData
,
5491 IDirectPlay3Impl_SetGroupName
,
5492 IDirectPlay3Impl_SetPlayerData
,
5493 IDirectPlay3Impl_SetPlayerName
,
5494 IDirectPlay3Impl_SetSessionDesc
,
5495 IDirectPlay3Impl_AddGroupToGroup
,
5496 IDirectPlay3Impl_CreateGroupInGroup
,
5497 IDirectPlay3Impl_DeleteGroupFromGroup
,
5498 IDirectPlay3Impl_EnumConnections
,
5499 IDirectPlay3Impl_EnumGroupsInGroup
,
5500 IDirectPlay3Impl_GetGroupConnectionSettings
,
5501 IDirectPlay3Impl_InitializeConnection
,
5502 IDirectPlay3Impl_SecureOpen
,
5503 IDirectPlay3Impl_SendChatMessage
,
5504 IDirectPlay3Impl_SetGroupConnectionSettings
,
5505 IDirectPlay3Impl_StartSession
,
5506 IDirectPlay3Impl_GetGroupFlags
,
5507 IDirectPlay3Impl_GetGroupParent
,
5508 IDirectPlay3Impl_GetPlayerAccount
,
5509 IDirectPlay3Impl_GetPlayerFlags
5512 static const IDirectPlay3Vtbl dp3A_vt
=
5514 IDirectPlay3AImpl_QueryInterface
,
5515 IDirectPlay3AImpl_AddRef
,
5516 IDirectPlay3AImpl_Release
,
5517 IDirectPlay3AImpl_AddPlayerToGroup
,
5518 IDirectPlay3AImpl_Close
,
5519 IDirectPlay3AImpl_CreateGroup
,
5520 IDirectPlay3AImpl_CreatePlayer
,
5521 IDirectPlay3AImpl_DeletePlayerFromGroup
,
5522 IDirectPlay3AImpl_DestroyGroup
,
5523 IDirectPlay3AImpl_DestroyPlayer
,
5524 IDirectPlay3AImpl_EnumGroupPlayers
,
5525 IDirectPlay3AImpl_EnumGroups
,
5526 IDirectPlay3AImpl_EnumPlayers
,
5527 IDirectPlay3AImpl_EnumSessions
,
5528 IDirectPlay3AImpl_GetCaps
,
5529 IDirectPlay3AImpl_GetGroupData
,
5530 IDirectPlay3AImpl_GetGroupName
,
5531 IDirectPlay3AImpl_GetMessageCount
,
5532 IDirectPlay3AImpl_GetPlayerAddress
,
5533 IDirectPlay3AImpl_GetPlayerCaps
,
5534 IDirectPlay3AImpl_GetPlayerData
,
5535 IDirectPlay3AImpl_GetPlayerName
,
5536 IDirectPlay3AImpl_GetSessionDesc
,
5537 IDirectPlay3AImpl_Initialize
,
5538 IDirectPlay3AImpl_Open
,
5539 IDirectPlay3AImpl_Receive
,
5540 IDirectPlay3AImpl_Send
,
5541 IDirectPlay3AImpl_SetGroupData
,
5542 IDirectPlay3AImpl_SetGroupName
,
5543 IDirectPlay3AImpl_SetPlayerData
,
5544 IDirectPlay3AImpl_SetPlayerName
,
5545 IDirectPlay3AImpl_SetSessionDesc
,
5546 IDirectPlay3AImpl_AddGroupToGroup
,
5547 IDirectPlay3AImpl_CreateGroupInGroup
,
5548 IDirectPlay3AImpl_DeleteGroupFromGroup
,
5549 IDirectPlay3AImpl_EnumConnections
,
5550 IDirectPlay3AImpl_EnumGroupsInGroup
,
5551 IDirectPlay3AImpl_GetGroupConnectionSettings
,
5552 IDirectPlay3AImpl_InitializeConnection
,
5553 IDirectPlay3AImpl_SecureOpen
,
5554 IDirectPlay3AImpl_SendChatMessage
,
5555 IDirectPlay3AImpl_SetGroupConnectionSettings
,
5556 IDirectPlay3AImpl_StartSession
,
5557 IDirectPlay3AImpl_GetGroupFlags
,
5558 IDirectPlay3AImpl_GetGroupParent
,
5559 IDirectPlay3AImpl_GetPlayerAccount
,
5560 IDirectPlay3AImpl_GetPlayerFlags
5563 static const IDirectPlay4Vtbl dp4_vt
=
5565 IDirectPlay4Impl_QueryInterface
,
5566 IDirectPlay4Impl_AddRef
,
5567 IDirectPlay4Impl_Release
,
5568 IDirectPlay4Impl_AddPlayerToGroup
,
5569 IDirectPlay4Impl_Close
,
5570 IDirectPlay4Impl_CreateGroup
,
5571 IDirectPlay4Impl_CreatePlayer
,
5572 IDirectPlay4Impl_DeletePlayerFromGroup
,
5573 IDirectPlay4Impl_DestroyGroup
,
5574 IDirectPlay4Impl_DestroyPlayer
,
5575 IDirectPlay4Impl_EnumGroupPlayers
,
5576 IDirectPlay4Impl_EnumGroups
,
5577 IDirectPlay4Impl_EnumPlayers
,
5578 IDirectPlay4Impl_EnumSessions
,
5579 IDirectPlay4Impl_GetCaps
,
5580 IDirectPlay4Impl_GetGroupData
,
5581 IDirectPlay4Impl_GetGroupName
,
5582 IDirectPlay4Impl_GetMessageCount
,
5583 IDirectPlay4Impl_GetPlayerAddress
,
5584 IDirectPlay4Impl_GetPlayerCaps
,
5585 IDirectPlay4Impl_GetPlayerData
,
5586 IDirectPlay4Impl_GetPlayerName
,
5587 IDirectPlay4Impl_GetSessionDesc
,
5588 IDirectPlay4Impl_Initialize
,
5589 IDirectPlay4Impl_Open
,
5590 IDirectPlay4Impl_Receive
,
5591 IDirectPlay4Impl_Send
,
5592 IDirectPlay4Impl_SetGroupData
,
5593 IDirectPlay4Impl_SetGroupName
,
5594 IDirectPlay4Impl_SetPlayerData
,
5595 IDirectPlay4Impl_SetPlayerName
,
5596 IDirectPlay4Impl_SetSessionDesc
,
5597 IDirectPlay4Impl_AddGroupToGroup
,
5598 IDirectPlay4Impl_CreateGroupInGroup
,
5599 IDirectPlay4Impl_DeleteGroupFromGroup
,
5600 IDirectPlay4Impl_EnumConnections
,
5601 IDirectPlay4Impl_EnumGroupsInGroup
,
5602 IDirectPlay4Impl_GetGroupConnectionSettings
,
5603 IDirectPlay4Impl_InitializeConnection
,
5604 IDirectPlay4Impl_SecureOpen
,
5605 IDirectPlay4Impl_SendChatMessage
,
5606 IDirectPlay4Impl_SetGroupConnectionSettings
,
5607 IDirectPlay4Impl_StartSession
,
5608 IDirectPlay4Impl_GetGroupFlags
,
5609 IDirectPlay4Impl_GetGroupParent
,
5610 IDirectPlay4Impl_GetPlayerAccount
,
5611 IDirectPlay4Impl_GetPlayerFlags
,
5612 IDirectPlay4Impl_GetGroupOwner
,
5613 IDirectPlay4Impl_SetGroupOwner
,
5614 IDirectPlay4Impl_SendEx
,
5615 IDirectPlay4Impl_GetMessageQueue
,
5616 IDirectPlay4Impl_CancelMessage
,
5617 IDirectPlay4Impl_CancelPriority
5620 static const IDirectPlay4Vtbl dp4A_vt
=
5622 IDirectPlay4AImpl_QueryInterface
,
5623 IDirectPlay4AImpl_AddRef
,
5624 IDirectPlay4AImpl_Release
,
5625 IDirectPlay4AImpl_AddPlayerToGroup
,
5626 IDirectPlay4AImpl_Close
,
5627 IDirectPlay4AImpl_CreateGroup
,
5628 IDirectPlay4AImpl_CreatePlayer
,
5629 IDirectPlay4AImpl_DeletePlayerFromGroup
,
5630 IDirectPlay4AImpl_DestroyGroup
,
5631 IDirectPlay4AImpl_DestroyPlayer
,
5632 IDirectPlay4AImpl_EnumGroupPlayers
,
5633 IDirectPlay4AImpl_EnumGroups
,
5634 IDirectPlay4AImpl_EnumPlayers
,
5635 IDirectPlay4AImpl_EnumSessions
,
5636 IDirectPlay4AImpl_GetCaps
,
5637 IDirectPlay4AImpl_GetGroupData
,
5638 IDirectPlay4AImpl_GetGroupName
,
5639 IDirectPlay4AImpl_GetMessageCount
,
5640 IDirectPlay4AImpl_GetPlayerAddress
,
5641 IDirectPlay4AImpl_GetPlayerCaps
,
5642 IDirectPlay4AImpl_GetPlayerData
,
5643 IDirectPlay4AImpl_GetPlayerName
,
5644 IDirectPlay4AImpl_GetSessionDesc
,
5645 IDirectPlay4AImpl_Initialize
,
5646 IDirectPlay4AImpl_Open
,
5647 IDirectPlay4AImpl_Receive
,
5648 IDirectPlay4AImpl_Send
,
5649 IDirectPlay4AImpl_SetGroupData
,
5650 IDirectPlay4AImpl_SetGroupName
,
5651 IDirectPlay4AImpl_SetPlayerData
,
5652 IDirectPlay4AImpl_SetPlayerName
,
5653 IDirectPlay4AImpl_SetSessionDesc
,
5654 IDirectPlay4AImpl_AddGroupToGroup
,
5655 IDirectPlay4AImpl_CreateGroupInGroup
,
5656 IDirectPlay4AImpl_DeleteGroupFromGroup
,
5657 IDirectPlay4AImpl_EnumConnections
,
5658 IDirectPlay4AImpl_EnumGroupsInGroup
,
5659 IDirectPlay4AImpl_GetGroupConnectionSettings
,
5660 IDirectPlay4AImpl_InitializeConnection
,
5661 IDirectPlay4AImpl_SecureOpen
,
5662 IDirectPlay4AImpl_SendChatMessage
,
5663 IDirectPlay4AImpl_SetGroupConnectionSettings
,
5664 IDirectPlay4AImpl_StartSession
,
5665 IDirectPlay4AImpl_GetGroupFlags
,
5666 IDirectPlay4AImpl_GetGroupParent
,
5667 IDirectPlay4AImpl_GetPlayerAccount
,
5668 IDirectPlay4AImpl_GetPlayerFlags
,
5669 IDirectPlay4AImpl_GetGroupOwner
,
5670 IDirectPlay4AImpl_SetGroupOwner
,
5671 IDirectPlay4AImpl_SendEx
,
5672 IDirectPlay4AImpl_GetMessageQueue
,
5673 IDirectPlay4AImpl_CancelMessage
,
5674 IDirectPlay4AImpl_CancelPriority
5677 HRESULT
dplay_create( REFIID riid
, void **ppv
)
5679 IDirectPlayImpl
*obj
;
5682 TRACE( "(%s, %p)\n", debugstr_guid( riid
), ppv
);
5685 obj
= HeapAlloc( GetProcessHeap(), 0, sizeof( *obj
) );
5687 return DPERR_OUTOFMEMORY
;
5689 obj
->IDirectPlay_iface
.lpVtbl
= &dp_vt
;
5690 obj
->IDirectPlay2A_iface
.lpVtbl
= &dp2A_vt
;
5691 obj
->IDirectPlay2_iface
.lpVtbl
= &dp2_vt
;
5692 obj
->IDirectPlay3A_iface
.lpVtbl
= &dp3A_vt
;
5693 obj
->IDirectPlay3_iface
.lpVtbl
= &dp3_vt
;
5694 obj
->IDirectPlay4A_iface
.lpVtbl
= &dp4A_vt
;
5695 obj
->IDirectPlay4_iface
.lpVtbl
= &dp4_vt
;
5705 InitializeCriticalSection( &obj
->lock
);
5706 obj
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IDirectPlayImpl.lock");
5708 if ( DP_CreateDirectPlay2( obj
) )
5709 hr
= IDirectPlayX_QueryInterface( &obj
->IDirectPlay4_iface
, riid
, ppv
);
5711 hr
= DPERR_NOMEMORY
;
5712 IDirectPlayX_Release( &obj
->IDirectPlay4_iface
);
5718 HRESULT
DP_GetSPPlayerData( IDirectPlayImpl
*lpDP
, DPID idPlayer
, void **lplpData
)
5720 lpPlayerList lpPlayer
= DP_FindPlayer( lpDP
, idPlayer
);
5722 if( lpPlayer
== NULL
)
5724 return DPERR_INVALIDPLAYER
;
5727 *lplpData
= lpPlayer
->lpPData
->lpSPPlayerData
;
5732 HRESULT
DP_SetSPPlayerData( IDirectPlayImpl
*lpDP
, DPID idPlayer
, void *lpData
)
5734 lpPlayerList lpPlayer
= DP_FindPlayer( lpDP
, idPlayer
);
5736 if( lpPlayer
== NULL
)
5738 return DPERR_INVALIDPLAYER
;
5741 lpPlayer
->lpPData
->lpSPPlayerData
= lpData
;
5746 /***************************************************************************
5747 * DirectPlayEnumerateAW
5749 * The pointer to the structure lpContext will be filled with the
5750 * appropriate data for each service offered by the OS. These services are
5751 * not necessarily available on this particular machine but are defined
5752 * as simple service providers under the "Service Providers" registry key.
5753 * This structure is then passed to lpEnumCallback for each of the different
5756 * This API is useful only for applications written using DirectX3 or
5757 * worse. It is superseded by IDirectPlay3::EnumConnections which also
5758 * gives information on the actual connections.
5760 * defn of a service provider:
5761 * A dynamic-link library used by DirectPlay to communicate over a network.
5762 * The service provider contains all the network-specific code required
5763 * to send and receive messages. Online services and network operators can
5764 * supply service providers to use specialized hardware, protocols, communications
5765 * media, and network resources.
5768 static HRESULT
DirectPlayEnumerateAW(LPDPENUMDPCALLBACKA lpEnumCallbackA
,
5769 LPDPENUMDPCALLBACKW lpEnumCallbackW
,
5773 static const WCHAR searchSubKey
[] = {
5774 'S', 'O', 'F', 'T', 'W', 'A', 'R', 'E', '\\',
5775 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '\\',
5776 'D', 'i', 'r', 'e', 'c', 't', 'P', 'l', 'a', 'y', '\\',
5777 'S', 'e', 'r', 'v', 'i', 'c', 'e', ' ', 'P', 'r', 'o', 'v', 'i', 'd', 'e', 'r', 's', 0 };
5778 static const WCHAR guidKey
[] = { 'G', 'u', 'i', 'd', 0 };
5779 static const WCHAR descW
[] = { 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 'W', 0 };
5784 char *descriptionA
= NULL
;
5785 DWORD max_sizeOfDescriptionA
= 0;
5786 WCHAR
*descriptionW
= NULL
;
5787 DWORD max_sizeOfDescriptionW
= 0;
5788 DWORD sizeOfSubKeyName
;
5789 WCHAR subKeyName
[255]; /* 255 is the maximum key size according to MSDN */
5791 static GUID
*guid_cache
;
5792 static int cache_count
;
5794 if (!lpEnumCallbackA
&& !lpEnumCallbackW
)
5796 return DPERR_INVALIDPARAMS
;
5799 /* Need to loop over the service providers in the registry */
5800 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, searchSubKey
,
5801 0, KEY_READ
, &hkResult
) != ERROR_SUCCESS
)
5803 /* Hmmm. Does this mean that there are no service providers? */
5804 ERR(": no service provider key in the registry - check your Wine installation !!!\n");
5805 return DPERR_GENERIC
;
5811 sizeOfSubKeyName
= sizeof(subKeyName
) / sizeof(WCHAR
);
5812 ret_value
= RegEnumKeyW(hkResult
, dwIndex
, subKeyName
, sizeOfSubKeyName
);
5815 while (ret_value
== ERROR_SUCCESS
);
5816 /* The game Swing from bug 37185 expects GUID values to persist after
5817 * the end of the enumeration. */
5818 if (cache_count
< dwIndex
)
5820 HeapFree(GetProcessHeap(), 0, guid_cache
);
5821 guid_cache
= HeapAlloc(GetProcessHeap(), 0, sizeof(GUID
) * dwIndex
);
5824 ERR(": failed to alloc required memory.\n");
5825 return DPERR_EXCEPTION
;
5827 cache_count
= dwIndex
;
5829 /* Traverse all the service providers we have available */
5833 HKEY hkServiceProvider
;
5834 WCHAR guidKeyContent
[(2 * 16) + 1 + 6 /* This corresponds to '{....-..-..-..-......}' */ ];
5835 DWORD sizeOfGuidKeyContent
= sizeof(guidKeyContent
);
5837 sizeOfSubKeyName
= sizeof(subKeyName
) / sizeof(WCHAR
);
5838 ret_value
= RegEnumKeyExW(hkResult
, dwIndex
, subKeyName
, &sizeOfSubKeyName
,
5839 NULL
, NULL
, NULL
, &filetime
);
5840 if (ret_value
== ERROR_NO_MORE_ITEMS
)
5842 else if (ret_value
!= ERROR_SUCCESS
)
5844 ERR(": could not enumerate on service provider key.\n");
5845 return DPERR_EXCEPTION
;
5847 TRACE(" this time through sub-key %s.\n", debugstr_w(subKeyName
));
5849 /* Open the key for this service provider */
5850 if (RegOpenKeyExW(hkResult
, subKeyName
, 0, KEY_READ
, &hkServiceProvider
) != ERROR_SUCCESS
)
5852 ERR(": could not open registry key for service provider %s.\n", debugstr_w(subKeyName
));
5856 /* Get the GUID from the registry */
5857 if (RegQueryValueExW(hkServiceProvider
, guidKey
,
5858 NULL
, NULL
, (LPBYTE
) guidKeyContent
, &sizeOfGuidKeyContent
) != ERROR_SUCCESS
)
5860 ERR(": missing GUID registry data member for service provider %s.\n", debugstr_w(subKeyName
));
5863 if (sizeOfGuidKeyContent
!= sizeof(guidKeyContent
))
5865 ERR(": invalid format for the GUID registry data member for service provider %s (%s).\n", debugstr_w(subKeyName
), debugstr_w(guidKeyContent
));
5868 CLSIDFromString(guidKeyContent
, &guid_cache
[dwIndex
]);
5870 /* The enumeration will return FALSE if we are not to continue.
5872 * Note: on my windows box, major / minor version is 6 / 0 for all service providers
5873 * and have no relation to any of the two dwReserved1 and dwReserved2 keys.
5874 * I think that it simply means that they are in-line with DirectX 6.0
5876 if (lpEnumCallbackA
)
5878 DWORD sizeOfDescription
= 0;
5880 /* Note that this is the A case of this function, so use the A variant to get the description string */
5881 if (RegQueryValueExA(hkServiceProvider
, "DescriptionA",
5882 NULL
, NULL
, NULL
, &sizeOfDescription
) != ERROR_SUCCESS
)
5884 ERR(": missing 'DescriptionA' registry data member for service provider %s.\n", debugstr_w(subKeyName
));
5887 if (sizeOfDescription
> max_sizeOfDescriptionA
)
5889 HeapFree(GetProcessHeap(), 0, descriptionA
);
5890 max_sizeOfDescriptionA
= sizeOfDescription
;
5892 descriptionA
= HeapAlloc(GetProcessHeap(), 0, sizeOfDescription
);
5893 RegQueryValueExA(hkServiceProvider
, "DescriptionA",
5894 NULL
, NULL
, (LPBYTE
) descriptionA
, &sizeOfDescription
);
5896 if (!lpEnumCallbackA(&guid_cache
[dwIndex
], descriptionA
, 6, 0, lpContext
))
5901 DWORD sizeOfDescription
= 0;
5903 if (RegQueryValueExW(hkServiceProvider
, descW
,
5904 NULL
, NULL
, NULL
, &sizeOfDescription
) != ERROR_SUCCESS
)
5906 ERR(": missing 'DescriptionW' registry data member for service provider %s.\n", debugstr_w(subKeyName
));
5909 if (sizeOfDescription
> max_sizeOfDescriptionW
)
5911 HeapFree(GetProcessHeap(), 0, descriptionW
);
5912 max_sizeOfDescriptionW
= sizeOfDescription
;
5914 descriptionW
= HeapAlloc(GetProcessHeap(), 0, sizeOfDescription
);
5915 RegQueryValueExW(hkServiceProvider
, descW
,
5916 NULL
, NULL
, (LPBYTE
) descriptionW
, &sizeOfDescription
);
5918 if (!lpEnumCallbackW(&guid_cache
[dwIndex
], descriptionW
, 6, 0, lpContext
))
5926 HeapFree(GetProcessHeap(), 0, descriptionA
);
5927 HeapFree(GetProcessHeap(), 0, descriptionW
);
5932 /***************************************************************************
5933 * DirectPlayEnumerate [DPLAYX.9]
5934 * DirectPlayEnumerateA [DPLAYX.2]
5936 HRESULT WINAPI
DirectPlayEnumerateA(LPDPENUMDPCALLBACKA lpEnumCallback
, LPVOID lpContext
)
5938 TRACE("(%p,%p)\n", lpEnumCallback
, lpContext
);
5940 return DirectPlayEnumerateAW(lpEnumCallback
, NULL
, lpContext
);
5943 /***************************************************************************
5944 * DirectPlayEnumerateW [DPLAYX.3]
5946 HRESULT WINAPI
DirectPlayEnumerateW(LPDPENUMDPCALLBACKW lpEnumCallback
, LPVOID lpContext
)
5948 TRACE("(%p,%p)\n", lpEnumCallback
, lpContext
);
5950 return DirectPlayEnumerateAW(NULL
, lpEnumCallback
, lpContext
);
5953 typedef struct tagCreateEnum
5957 } CreateEnumData
, *lpCreateEnumData
;
5959 /* Find and copy the matching connection for the SP guid */
5960 static BOOL CALLBACK
cbDPCreateEnumConnections(
5962 LPVOID lpConnection
,
5963 DWORD dwConnectionSize
,
5968 lpCreateEnumData lpData
= (lpCreateEnumData
)lpContext
;
5970 if( IsEqualGUID( lpguidSP
, lpData
->lpGuid
) )
5972 TRACE( "Found SP entry with guid %s\n", debugstr_guid(lpData
->lpGuid
) );
5974 lpData
->lpConn
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
5976 CopyMemory( lpData
->lpConn
, lpConnection
, dwConnectionSize
);
5978 /* Found the record that we were looking for */
5982 /* Haven't found what were looking for yet */
5987 /***************************************************************************
5988 * DirectPlayCreate [DPLAYX.1]
5991 HRESULT WINAPI DirectPlayCreate
5992 ( LPGUID lpGUID
, LPDIRECTPLAY
*lplpDP
, IUnknown
*pUnk
)
5995 LPDIRECTPLAY3A lpDP3A
;
5996 CreateEnumData cbData
;
5998 TRACE( "lpGUID=%s lplpDP=%p pUnk=%p\n", debugstr_guid(lpGUID
), lplpDP
, pUnk
);
6002 return CLASS_E_NOAGGREGATION
;
6005 if( (lplpDP
== NULL
) || (lpGUID
== NULL
) )
6007 return DPERR_INVALIDPARAMS
;
6010 if ( dplay_create( &IID_IDirectPlay
, (void**)lplpDP
) != DP_OK
)
6011 return DPERR_UNAVAILABLE
;
6013 if( IsEqualGUID( &GUID_NULL
, lpGUID
) )
6015 /* The GUID_NULL means don't bind a service provider. Just return the
6020 /* Bind the desired service provider since lpGUID is non NULL */
6021 TRACE( "Service Provider binding for %s\n", debugstr_guid(lpGUID
) );
6023 /* We're going to use a DP3 interface */
6024 hr
= IDirectPlayX_QueryInterface( *lplpDP
, &IID_IDirectPlay3A
,
6028 ERR( "Failed to get DP3 interface: %s\n", DPLAYX_HresultToString(hr
) );
6032 cbData
.lpConn
= NULL
;
6033 cbData
.lpGuid
= lpGUID
;
6035 /* We were given a service provider, find info about it... */
6036 hr
= IDirectPlayX_EnumConnections( lpDP3A
, NULL
, cbDPCreateEnumConnections
,
6037 &cbData
, DPCONNECTION_DIRECTPLAY
);
6038 if( ( FAILED(hr
) ) ||
6039 ( cbData
.lpConn
== NULL
)
6042 ERR( "Failed to get Enum for SP: %s\n", DPLAYX_HresultToString(hr
) );
6043 IDirectPlayX_Release( lpDP3A
);
6044 return DPERR_UNAVAILABLE
;
6047 /* Initialize the service provider */
6048 hr
= IDirectPlayX_InitializeConnection( lpDP3A
, cbData
.lpConn
, 0 );
6051 ERR( "Failed to Initialize SP: %s\n", DPLAYX_HresultToString(hr
) );
6052 HeapFree( GetProcessHeap(), 0, cbData
.lpConn
);
6053 IDirectPlayX_Release( lpDP3A
);
6057 /* Release our version of the interface now that we're done with it */
6058 IDirectPlayX_Release( lpDP3A
);
6059 HeapFree( GetProcessHeap(), 0, cbData
.lpConn
);