ReactOS 0.4.17-dev-966-gf06eace
dplay.c
Go to the documentation of this file.
1/* Direct Play 2,3,4 Implementation
2 *
3 * Copyright 1998,1999,2000,2001 - Peter Hunnisett
4 *
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.
9 *
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.
14 *
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
18 */
19
20#define COBJMACROS
21
22#include <stdarg.h>
23#include <string.h>
24#include <limits.h>
25
26#include "windef.h"
27#include "winerror.h"
28#include "winbase.h"
29#include "winnt.h"
30#include "winreg.h"
31#include "winnls.h"
32#include "wine/debug.h"
33
34#include "dplayx_global.h"
35#include "name_server.h"
36#include "dplayx_queue.h"
37#include "wine/dplaysp.h"
38#include "dplay_global.h"
39
41
42/* FIXME: Should this be externed? */
44( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount,
45 LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface );
46
47
48/* Local function prototypes */
50static DPNAME *DP_DuplicateName( const DPNAME *src, BOOL dstAnsi, BOOL srcAnsi );
51static void DP_SetGroupData( lpGroupData lpGData, DWORD dwFlags,
52 LPVOID lpData, DWORD dwDataSize );
54 DWORD dwPlayerType,
57 LPVOID lpContext );
59
60/* Helper methods for player/group interfaces */
62 DWORD dwFlags, BOOL bInitial, BOOL bAnsi );
63static void DP_SetPlayerData( lpPlayerData lpPData, DWORD dwFlags,
64 LPVOID lpData, DWORD dwDataSize );
65static BOOL DP_BuildSPCompoundAddr( LPGUID lpcSpGuid, LPVOID* lplpAddrBuf,
66 LPDWORD lpdwBufSize );
67
69
70static DWORD DP_CopySessionDesc( LPDPSESSIONDESC2 destSessionDesc,
71 LPCDPSESSIONDESC2 srcSessDesc, BOOL dstAnsi, BOOL srcAnsi );
72
73
74#define DPID_NOPARENT_GROUP 0 /* Magic number to indicate no parent of group */
75#define DPID_SYSTEM_GROUP DPID_NOPARENT_GROUP /* If system group is supported
76 we don't have to change much */
77#define DPID_NAME_SERVER 0x19a9d65b /* Don't ask me why */
78
79/* Strip out dwFlag values which cannot be sent in the CREATEGROUP msg */
80#define DPMSG_CREATEGROUP_DWFLAGS(x) ( (x) & DPGROUP_HIDDEN )
81
82/* Strip out all dwFlags values for CREATEPLAYER msg */
83#define DPMSG_CREATEPLAYER_DWFLAGS(x) 0
85static LONG kludgePlayerGroupId = 1000;
86
88static inline IDirectPlayImpl *impl_from_IDirectPlay( IDirectPlay *iface )
89{
90 return CONTAINING_RECORD( iface, IDirectPlayImpl, IDirectPlay_iface );
91}
93static inline IDirectPlayImpl *impl_from_IDirectPlay2( IDirectPlay2 *iface )
94{
95 return CONTAINING_RECORD( iface, IDirectPlayImpl, IDirectPlay2_iface );
96}
99{
100 return CONTAINING_RECORD( iface, IDirectPlayImpl, IDirectPlay2A_iface );
101}
104{
105 return CONTAINING_RECORD( iface, IDirectPlayImpl, IDirectPlay3A_iface );
106}
108static inline IDirectPlayImpl *impl_from_IDirectPlay3( IDirectPlay3 *iface )
109{
110 return CONTAINING_RECORD( iface, IDirectPlayImpl, IDirectPlay3_iface );
111}
114{
115 return CONTAINING_RECORD( iface, IDirectPlayImpl, IDirectPlay4A_iface );
116}
118static inline IDirectPlayImpl *impl_from_IDirectPlay4( IDirectPlay4 *iface )
119{
120 return CONTAINING_RECORD( iface, IDirectPlayImpl, IDirectPlay4_iface );
121}
123static BOOL DP_CreateDirectPlay2( LPVOID lpDP )
124{
125 IDirectPlayImpl *This = lpDP;
126
127 This->dp2 = calloc( 1, sizeof( *(This->dp2) ) );
128 if ( This->dp2 == NULL )
129 {
130 return FALSE;
131 }
132
133 This->dp2->bConnectionOpen = FALSE;
134
135 This->dp2->hEnumSessionThread = INVALID_HANDLE_VALUE;
136 This->dp2->dwEnumSessionLock = 0;
137
138 This->dp2->bHostInterface = FALSE;
139
140 DPQ_INIT(This->dp2->receiveMsgs);
141 DPQ_INIT(This->dp2->repliesExpected);
142
143 if( !NS_InitializeSessionCache( &This->dp2->lpNameServerData ) )
144 {
145 /* FIXME: Memory leak */
146 return FALSE;
147 }
148
149 /* Provide an initial session desc with nothing in it */
150 This->dp2->lpSessionDesc = calloc( 1, sizeof( *This->dp2->lpSessionDesc ) );
151 if( This->dp2->lpSessionDesc == NULL )
152 {
153 /* FIXME: Memory leak */
154 return FALSE;
155 }
156 This->dp2->lpSessionDesc->dwSize = sizeof( *This->dp2->lpSessionDesc );
157
158 /* We are emulating a dp 6 implementation */
159 This->dp2->spData.dwSPVersion = DPSP_MAJORVERSION;
160
161 This->dp2->spData.lpCB = calloc( 1, sizeof( *This->dp2->spData.lpCB ) );
162 This->dp2->spData.lpCB->dwSize = sizeof( *This->dp2->spData.lpCB );
163 This->dp2->spData.lpCB->dwVersion = DPSP_MAJORVERSION;
164
165 /* This is the pointer to the service provider */
166 if ( FAILED( dplaysp_create( &IID_IDirectPlaySP, (void**)&This->dp2->spData.lpISP, This ) ) )
167 {
168 /* FIXME: Memory leak */
169 return FALSE;
170 }
171
172 /* Setup lobby provider information */
173 This->dp2->dplspData.dwSPVersion = DPSP_MAJORVERSION;
174 This->dp2->dplspData.lpCB = calloc( 1, sizeof( *This->dp2->dplspData.lpCB ) );
175 This->dp2->dplspData.lpCB->dwSize = sizeof( *This->dp2->dplspData.lpCB );
176
177 if( FAILED( dplobbysp_create( &IID_IDPLobbySP, (void**)&This->dp2->dplspData.lpISP, This ) )
178 )
179 {
180 /* FIXME: Memory leak */
181 return FALSE;
182 }
183
184 return TRUE;
185}
186
187/* Definition of the global function in dplayx_queue.h. #
188 * FIXME: Would it be better to have a dplayx_queue.c for this function? */
189DPQ_DECL_DELETECB( cbDeleteElemFromHeap, LPVOID )
190{
191 free( elem );
192}
194static BOOL DP_DestroyDirectPlay2( LPVOID lpDP )
195{
196 IDirectPlayImpl *This = lpDP;
197
198 if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
199 {
200 TerminateThread( This->dp2->hEnumSessionThread, 0 );
201 CloseHandle( This->dp2->hEnumSessionThread );
202 }
203
204 /* Finish with the SP - have it shutdown */
205 if( This->dp2->spData.lpCB->ShutdownEx )
206 {
208
209 TRACE( "Calling SP ShutdownEx\n" );
210
211 data.lpISP = This->dp2->spData.lpISP;
212
213 (*This->dp2->spData.lpCB->ShutdownEx)( &data );
214 }
215 else if (This->dp2->spData.lpCB->Shutdown ) /* obsolete interface */
216 {
217 TRACE( "Calling obsolete SP Shutdown\n" );
218 (*This->dp2->spData.lpCB->Shutdown)();
219 }
220
221 /* Unload the SP (if it exists) */
222 if( This->dp2->hServiceProvider != 0 )
223 {
224 FreeLibrary( This->dp2->hServiceProvider );
225 }
226
227 /* Unload the Lobby Provider (if it exists) */
228 if( This->dp2->hDPLobbyProvider != 0 )
229 {
230 FreeLibrary( This->dp2->hDPLobbyProvider );
231 }
232
233 /* FIXME: Need to delete receive and send msgs queue contents */
234
235 NS_DeleteSessionCache( This->dp2->lpNameServerData );
236
237 free( This->dp2->dplspData.lpCB);
238 free( This->dp2->lpSessionDesc );
239
240 IDirectPlaySP_Release( This->dp2->spData.lpISP );
241
242 /* Delete the contents */
243 free( This->dp2 );
244
245 return TRUE;
246}
249{
251 obj->lock.DebugInfo->Spare[0] = 0;
252 DeleteCriticalSection( &obj->lock );
253 free( obj );
254}
256static inline DPID DP_NextObjectId(void)
257{
259}
261static DWORD DP_CopyString( char **dst, const void *src, BOOL dstAnsi, BOOL srcAnsi, void *buffer, DWORD offset )
262{
263 void *dstPtr = NULL;
264 DWORD dstSize = 0;
265 DWORD size;
266
267 if ( !src )
268 {
269 if ( buffer )
270 *dst = NULL;
271
272 return 0;
273 }
274
275 if ( buffer )
276 {
277 dstPtr = (char *) buffer + offset;
278 dstSize = INT_MAX;
279 *dst = dstPtr;
280 }
281
282 if ( dstAnsi == srcAnsi )
283 {
284 if ( srcAnsi )
285 size = strlen( src ) + 1;
286 else
287 size = (wcslen( src ) + 1) * sizeof( WCHAR );
288
289 if ( dstPtr )
290 memcpy( dstPtr, src, size );
291 }
292 else
293 {
294 if ( srcAnsi )
295 size = MultiByteToWideChar( CP_ACP, 0, src, -1, dstPtr, dstSize ) * sizeof( WCHAR );
296 else
297 size = WideCharToMultiByte( CP_ACP, 0, src, -1, dstPtr, dstSize, NULL, NULL );
298 }
299
300 return size;
301}
303static void *DP_DuplicateString( const void *src, BOOL dstAnsi, BOOL srcAnsi )
304{
305 DWORD size;
306 char *dst;
307
308 if ( !src )
309 return NULL;
310
311 size = DP_CopyString( NULL, src, dstAnsi, srcAnsi, NULL, 0 );
312
313 dst = malloc( size );
314 if ( !dst )
315 return NULL;
316
317 DP_CopyString( &dst, src, dstAnsi, srcAnsi, dst, 0 );
318
319 return dst;
320}
322static HRESULT DP_QueuePlayerMessage( IDirectPlayImpl *This, DPID fromId, struct PlayerData *player,
323 DPID excludeId, void *msg, FN_COPY_MESSAGE *copyMessage,
324 DWORD genericSize )
325{
326 struct DPMSG *elem;
327 DWORD msgSize;
328
329 if ( !( player->dwFlags & DPLAYI_PLAYER_PLAYERLOCAL ) )
330 return DP_OK;
331 if ( player->dwFlags & DPLAYI_PLAYER_SYSPLAYER )
332 return DP_OK;
333 if ( player->dpid == excludeId )
334 return DP_OK;
335
336 elem = calloc( 1, sizeof( struct DPMSG ) );
337 if( !elem )
338 return DPERR_OUTOFMEMORY;
339
340 msgSize = copyMessage( NULL, msg, genericSize, FALSE );
341 elem->msg = malloc( msgSize );
342 if ( !elem->msg )
343 {
344 free( elem );
345 return DPERR_OUTOFMEMORY;
346 }
348
349 elem->fromId = fromId;
350 elem->toId = player->dpid;
351 elem->copyMessage = copyMessage;
352 elem->genericSize = genericSize;
353
354 DPQ_INSERT_IN_TAIL( This->dp2->receiveMsgs, elem, msgs );
355
356 if( player->hEvent )
357 SetEvent( player->hEvent );
358
359 return DP_OK;
360}
364{
365 struct PlayerList *plist;
366 struct GroupData *group;
367 HRESULT hr;
368
369 plist = DP_FindPlayer( This, toId );
370 if ( plist )
371 return DP_QueuePlayerMessage( This, fromId, plist->lpPData, excludeId, msg, copyMessage,
372 genericSize );
373
374 group = DP_FindAnyGroup( This, toId );
375 if( group )
376 {
377 for( plist = DPQ_FIRST( group->players ); plist; plist = DPQ_NEXT( plist->players ) )
378 {
379 hr = DP_QueuePlayerMessage( This, fromId, plist->lpPData, excludeId, msg, copyMessage,
380 genericSize );
381 if ( FAILED( hr ) )
382 return hr;
383 }
384
385 return DP_OK;
386 }
387
388 return DPERR_INVALIDPLAYER;
389}
391static DWORD DP_CopyGeneric( DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc,
392 DWORD genericSize, BOOL ansi )
393{
394 if ( !genericDst )
395 return genericSize;
396
397 memcpy( genericDst, genericSrc, genericSize );
398
399 return genericSize;
400}
402static DWORD DP_CopyCreatePlayerOrGroup( DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc,
403 DWORD genericSize, BOOL ansi )
404{
408
409 if ( dst )
410 *dst = *src;
411
412 if ( src->lpData )
413 {
414 if ( dst )
415 {
416 dst->lpData = (char *) dst + offset;
417 memcpy( dst->lpData, src->lpData, src->dwDataSize );
418 }
419 offset += src->dwDataSize;
420 }
421
422 offset += DP_CopyString( &dst->dpnName.lpszShortNameA, src->dpnName.lpszShortNameA, ansi, FALSE,
423 genericDst, offset );
424 offset += DP_CopyString( &dst->dpnName.lpszLongNameA, src->dpnName.lpszLongNameA, ansi, FALSE,
425 genericDst, offset );
426
427 return offset;
428}
430static DWORD DP_CopySetPlayerOrGroupData( DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc,
431 DWORD genericSize, BOOL ansi )
432{
436
437 if ( dst )
438 *dst = *src;
439
440 if ( src->lpData )
441 {
442 if ( dst )
443 {
444 dst->lpData = (char *) dst + offset;
445 memcpy( dst->lpData, src->lpData, src->dwDataSize );
446 }
447 offset += src->dwDataSize;
448 }
449
450 return offset;
451}
452
453/* *lplpReply will be non NULL iff there is something to reply */
454HRESULT DP_HandleMessage( IDirectPlayImpl *This, void *messageBody,
455 DWORD dwMessageBodySize, void *messageHeader, WORD wCommandId, WORD wVersion,
456 void **lplpReply, DWORD *lpdwMsgSize )
457{
458 TRACE( "(%p)->(%p,0x%08lx,%p,%u,%u)\n",
459 This, messageBody, dwMessageBodySize, messageHeader, wCommandId,
460 wVersion );
461
462 switch( wCommandId )
463 {
464 /* Name server needs to handle this request */
466 /* Reply expected */
467 NS_ReplyToEnumSessionsRequest( messageBody, lplpReply, lpdwMsgSize, This );
468 break;
469
470 /* Name server needs to handle this request */
472 EnterCriticalSection( &This->lock );
473
474 /* No reply expected */
476 This->dp2->spData.dwSPHeaderSize,
477 messageBody,
478 dwMessageBodySize,
479 This->dp2->lpNameServerData );
480
481 LeaveCriticalSection( &This->lock );
482 break;
483
485 {
486 LPCDPMSG_REQUESTNEWPLAYERID lpcMsg = messageBody;
487
489
490 *lpdwMsgSize = This->dp2->spData.dwSPHeaderSize + sizeof( *lpReply );
491
492 *lplpReply = calloc( 1, *lpdwMsgSize );
493
494 FIXME( "Ignoring dwFlags 0x%08lx in request msg\n",
495 lpcMsg->dwFlags );
496
497 /* Setup the reply */
498 lpReply = (LPDPMSG_NEWPLAYERIDREPLY)( (BYTE*)(*lplpReply) +
499 This->dp2->spData.dwSPHeaderSize );
500
503 lpReply->envelope.wVersion = DPMSGVER_DP6;
504
505 lpReply->dpidNewPlayerId = DP_NextObjectId();
506
507 TRACE( "Allocating new playerid 0x%08lx from remote request\n",
508 lpReply->dpidNewPlayerId );
509 break;
510 }
511
514 DPPLAYERINFO playerInfo;
515 DWORD offset = 0;
516 HRESULT hr;
517
518 if( dwMessageBodySize < sizeof( DPMSG_CREATESESSION ) )
519 return DPERR_GENERIC;
520 msg = (DPMSG_CREATESESSION *)messageBody;
521 offset += sizeof( DPMSG_CREATESESSION );
522
523 hr = DP_MSG_ReadPackedPlayer( (char *)messageBody, &offset, dwMessageBodySize, &playerInfo );
524 if ( FAILED( hr ) )
525 return hr;
526
527 if ( dwMessageBodySize - offset < 6 )
528 return DPERR_GENERIC;
529
530 EnterCriticalSection( &This->lock );
531
532 if ( !This->dp2->bConnectionOpen )
533 {
534 LeaveCriticalSection( &This->lock );
535 return DP_OK;
536 }
537
538 hr = DP_CreatePlayer( This, messageHeader, &msg->playerId, &playerInfo.name,
539 playerInfo.playerData, playerInfo.playerDataLength, playerInfo.spData,
540 playerInfo.spDataLength, playerInfo.flags & ~DPLAYI_PLAYER_PLAYERLOCAL,
541 NULL, NULL, FALSE );
542
543 if ( FAILED( hr ) )
544 {
545 LeaveCriticalSection( &This->lock );
546 return hr;
547 }
548
549 LeaveCriticalSection( &This->lock );
550
551 break;
552 }
553
558 DP_MSG_ReplyReceived( This, wCommandId, messageBody, dwMessageBodySize, messageHeader );
559 break;
560
562 DPMSG_SETPLAYERORGROUPDATA setPlayerOrGroupDataMsg;
564 struct GroupData *group;
565 HRESULT hr;
566 void *data;
567
568 if( dwMessageBodySize < sizeof( DPSP_MSG_GROUPDATACHANGED ) )
569 return DPERR_GENERIC;
570 msg = (DPSP_MSG_GROUPDATACHANGED *)messageBody;
571
572 if( dwMessageBodySize < msg->dataOffset )
573 return DPERR_GENERIC;
574 if( dwMessageBodySize - msg->dataOffset < msg->dataSize )
575 return DPERR_GENERIC;
576 data = (char *)messageBody + msg->dataOffset;
577
578 EnterCriticalSection( &This->lock );
579
580 if( !This->dp2->bConnectionOpen )
581 {
582 LeaveCriticalSection( &This->lock );
583 return DP_OK;
584 }
585
586 group = DP_FindAnyGroup( This, msg->groupId );
587 if( !group )
588 {
589 LeaveCriticalSection( &This->lock );
590 return DPERR_GENERIC;
591 }
592
593 DP_SetGroupData( group, DPSET_REMOTE, data, msg->dataSize );
594
595 setPlayerOrGroupDataMsg.dwType = DPSYS_SETPLAYERORGROUPDATA;
596 setPlayerOrGroupDataMsg.dwPlayerType = DPPLAYERTYPE_GROUP;
597 setPlayerOrGroupDataMsg.dpId = msg->groupId;
598 setPlayerOrGroupDataMsg.lpData = data;
599 setPlayerOrGroupDataMsg.dwDataSize = msg->dataSize;
600
601 hr = DP_QueueMessage( This, DPID_SYSMSG, DPID_ALLPLAYERS, 0, &setPlayerOrGroupDataMsg,
603 if ( FAILED( hr ) )
604 {
605 LeaveCriticalSection( &This->lock );
606 return hr;
607 }
608
609 LeaveCriticalSection( &This->lock );
610
611 break;
612 }
613
615 TRACE( "GOT THE SELF MESSAGE: %p -> 0x%08lx\n", messageHeader, ((const DWORD *)messageHeader)[1] );
616 NS_SetLocalAddr( This->dp2->lpNameServerData, messageHeader, 20 );
617 DP_MSG_ReplyReceived( This, wCommandId, messageBody, dwMessageBodySize, messageHeader );
618
620 TRACE( "Sending message to self to get my addr\n" );
621 DP_MSG_ToSelf( This, 1 ); /* This is a hack right now */
622 break;
623
624 case DPMSGCMD_PING: {
625 const DPSP_MSG_PING *msg;
626
627 if( dwMessageBodySize < sizeof( DPSP_MSG_PING ) )
628 return DPERR_GENERIC;
629 msg = (const DPSP_MSG_PING *)messageBody;
630
631 EnterCriticalSection( &This->lock );
632
633 if ( !This->dp2->bConnectionOpen )
634 {
635 LeaveCriticalSection( &This->lock );
636 return DP_OK;
637 }
638
639 LeaveCriticalSection( &This->lock );
640
641 DP_MSG_SendPingReply( This, msg->fromId, This->dp2->systemPlayerId, msg->tickCount );
642
643 break;
644 }
645
646 case DPMSGCMD_ADDFORWARD: {
648 DPPLAYERINFO playerInfo;
649 DWORD offset = 0;
650 HRESULT hr;
651
652 if( dwMessageBodySize < sizeof( DPSP_MSG_ADDFORWARD ) )
653 return DPERR_GENERIC;
654 msg = (DPSP_MSG_ADDFORWARD *) messageBody;
655 offset += sizeof( DPSP_MSG_ADDFORWARD );
656
657 hr = DP_MSG_ReadPackedPlayer( (char *) messageBody, &offset, dwMessageBodySize, &playerInfo );
658 if ( FAILED( hr ) )
659 return hr;
660
661 EnterCriticalSection( &This->lock );
662
663 if ( !This->dp2->bConnectionOpen )
664 {
665 LeaveCriticalSection( &This->lock );
666 return DP_OK;
667 }
668
669 hr = DP_CreatePlayer( This, messageHeader, &msg->playerId, &playerInfo.name,
670 playerInfo.playerData, playerInfo.playerDataLength, playerInfo.spData,
671 playerInfo.spDataLength, playerInfo.flags & ~DPLAYI_PLAYER_PLAYERLOCAL,
672 NULL, NULL, FALSE );
673 if ( FAILED( hr ) )
674 {
675 LeaveCriticalSection( &This->lock );
676 return hr;
677 }
678
679 LeaveCriticalSection( &This->lock );
680
681 DP_MSG_SendAddForwardAck( This, msg->playerId );
682
683 break;
684 }
685
686 default:
687 FIXME( "Unknown wCommandId %u. Ignoring message\n", wCommandId );
688 break;
689 }
690
691 /* FIXME: There is code in dplaysp.c to handle dplay commands. Move to here. */
692
693 return DP_OK;
694}
696HRESULT DP_HandleGameMessage( IDirectPlayImpl *This, void *messageBody, DWORD messageBodySize,
697 DPID fromId, DPID toId )
698{
700 DWORD msgSize;
701 HRESULT hr;
702
703 TRACE( "(%p)->(%p,0x%08lx,0x%08lx,0x%08lx)\n", This, messageBody, messageBodySize, fromId, toId );
704
705 msg = (DPMSG_GENERIC *) ((char *) messageBody + sizeof( DPMSG_SYSMSGENVELOPE ));
706 msgSize = messageBodySize - sizeof( DPMSG_SYSMSGENVELOPE );
707
708 EnterCriticalSection( &This->lock );
709
710 hr = DP_QueueMessage( This, fromId, toId, 0, msg, DP_CopyGeneric, msgSize );
711
712 LeaveCriticalSection( &This->lock );
713
714 return hr;
715}
717static HRESULT WINAPI IDirectPlayImpl_QueryInterface( IDirectPlay *iface, REFIID riid, void **ppv )
718{
720 return IDirectPlayX_QueryInterface( &This->IDirectPlay4_iface, riid, ppv );
721}
723static ULONG WINAPI IDirectPlayImpl_AddRef( IDirectPlay *iface )
724{
727
728 TRACE( "(%p) ref=%ld\n", This, ref );
729
730 return ref;
731}
733static ULONG WINAPI IDirectPlayImpl_Release( IDirectPlay *iface )
734{
737
738 TRACE( "(%p) ref=%ld\n", This, ref );
739
740 if ( !ref )
742
743 return ref;
744}
746static HRESULT WINAPI IDirectPlayImpl_AddPlayerToGroup( IDirectPlay *iface, DPID group,
747 DPID player )
748{
750 FIXME( "(%p)->(0x%08lx,0x%08lx): stub\n", This, group, player );
751 return E_NOTIMPL;
752}
754static HRESULT WINAPI IDirectPlayImpl_Close( IDirectPlay *iface )
755{
757 FIXME( "(%p): stub\n", This );
758 return E_NOTIMPL;
759}
761static HRESULT WINAPI IDirectPlayImpl_CreatePlayer( IDirectPlay *iface, DPID *player,
763{
765 FIXME( "(%p)->(%p,%s,%s,%p): stub\n", This, player, debugstr_a( name ), debugstr_a( fullname ),
766 event );
767 return E_NOTIMPL;
768}
770static HRESULT WINAPI IDirectPlayImpl_CreateGroup( IDirectPlay *iface, DPID *group, LPSTR name,
772{
774 FIXME( "(%p)->(%p,%s,%s): stub\n", This, group, debugstr_a( name ), debugstr_a( fullname ) );
775 return E_NOTIMPL;
776}
779 DPID player )
780{
782 FIXME( "(%p)->(0x%08lx,0x%08lx): stub\n", This, group, player );
783 return E_NOTIMPL;
784}
786static HRESULT WINAPI IDirectPlayImpl_DestroyPlayer( IDirectPlay *iface, DPID player )
787{
789 FIXME( "(%p)->(0x%08lx): stub\n", This, player );
790 return E_NOTIMPL;
791}
793static HRESULT WINAPI IDirectPlayImpl_DestroyGroup( IDirectPlay *iface, DPID group )
794{
796 FIXME( "(%p)->(0x%08lx): stub\n", This, group );
797 return E_NOTIMPL;
798}
800static HRESULT WINAPI IDirectPlayImpl_EnableNewPlayers( IDirectPlay *iface, BOOL enable )
801{
803 FIXME( "(%p)->(%d): stub\n", This, enable );
804 return E_NOTIMPL;
805}
807static HRESULT WINAPI IDirectPlayImpl_EnumGroupPlayers( IDirectPlay *iface, DPID group,
808 LPDPENUMPLAYERSCALLBACK enumplayercb, void *context, DWORD flags )
809{
811 FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, group, enumplayercb, context, flags );
812 return E_NOTIMPL;
813}
815static HRESULT WINAPI IDirectPlayImpl_EnumGroups( IDirectPlay *iface, DWORD session,
816 LPDPENUMPLAYERSCALLBACK enumplayercb, void *context, DWORD flags )
817{
819 FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, session, enumplayercb, context, flags );
820 return E_NOTIMPL;
821}
823static HRESULT WINAPI IDirectPlayImpl_EnumPlayers( IDirectPlay *iface, DWORD session,
824 LPDPENUMPLAYERSCALLBACK enumplayercb, void *context, DWORD flags )
825{
827 FIXME( "(%p)->(0x%08lx,%p,%p,0x%08lx): stub\n", This, session, enumplayercb, context, flags );
828 return E_NOTIMPL;
829}
831static HRESULT WINAPI IDirectPlayImpl_EnumSessions( IDirectPlay *iface, DPSESSIONDESC *sdesc,
833{
835 FIXME( "(%p)->(%p,%lu,%p,%p,0x%08lx): stub\n", This, sdesc, timeout, enumsessioncb, context,
836 flags );
837 return E_NOTIMPL;
838}
840static HRESULT WINAPI IDirectPlayImpl_GetCaps( IDirectPlay *iface, DPCAPS *caps )
841{
843 FIXME( "(%p)->(%p): stub\n", This, caps );
844 return E_NOTIMPL;
845}
847static HRESULT WINAPI IDirectPlayImpl_GetMessageCount( IDirectPlay *iface, DPID player,
848 DWORD *count )
849{
851 FIXME( "(%p)->(0x%08lx,%p): stub\n", This, player, count );
852 return E_NOTIMPL;
853}
855static HRESULT WINAPI IDirectPlayImpl_GetPlayerCaps( IDirectPlay *iface, DPID player, DPCAPS *caps )
856{
858 FIXME( "(%p)->(0x%08lx,%p): stub\n", This, player, caps );
859 return E_NOTIMPL;
860}
862static HRESULT WINAPI IDirectPlayImpl_GetPlayerName( IDirectPlay *iface, DPID player, LPSTR name,
863 DWORD *size_name, LPSTR fullname, DWORD *size_fullname )
864{
866 FIXME( "(%p)->(0x%08lx,%p,%p,%p,%p): stub\n", This, player, name, size_name, fullname,
867 size_fullname );
868 return E_NOTIMPL;
869}
871static HRESULT WINAPI IDirectPlayImpl_Initialize( IDirectPlay *iface, GUID *guid )
872{
874 FIXME( "(%p)->(%p): stub\n", This, guid );
875 return E_NOTIMPL;
876}
878static HRESULT WINAPI IDirectPlayImpl_Open( IDirectPlay *iface, DPSESSIONDESC *sdesc )
879{
881 FIXME( "(%p)->(%p): stub\n", This, sdesc );
882 return E_NOTIMPL;
883}
885static HRESULT WINAPI IDirectPlayImpl_Receive( IDirectPlay *iface, DPID *from, DPID *to,
886 DWORD flags, void *data, DWORD *size )
887{
889 FIXME( "(%p)->(%p,%p,0x%08lx,%p,%p): stub\n", This, from, to, flags, data, size );
890 return E_NOTIMPL;
891}
893static HRESULT WINAPI IDirectPlayImpl_SaveSession( IDirectPlay *iface, LPSTR reserved )
894{
896 FIXME( "(%p)->(%p): stub\n", This, reserved );
897 return E_NOTIMPL;
898}
900static HRESULT WINAPI IDirectPlayImpl_Send( IDirectPlay *iface, DPID from, DPID to, DWORD flags,
901 void *data, DWORD size )
902{
904 FIXME( "(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%lu): stub\n", This, from, to, flags, data, size );
905 return E_NOTIMPL;
906}
908static HRESULT WINAPI IDirectPlayImpl_SetPlayerName( IDirectPlay *iface, DPID player, LPSTR name,
910{
912 FIXME( "(%p)->(0x%08lx,%s,%s): stub\n", This, player, debugstr_a( name ),
913 debugstr_a ( fullname ) );
914 return E_NOTIMPL;
915}
917static const IDirectPlayVtbl dp_vt =
918{
944};
945
948 void **ppv )
949{
951 return IDirectPlayX_QueryInterface( &This->IDirectPlay4_iface, riid, ppv );
952}
954static HRESULT WINAPI IDirectPlay2Impl_QueryInterface( IDirectPlay2 *iface, REFIID riid,
955 void **ppv )
956{
958 return IDirectPlayX_QueryInterface( &This->IDirectPlay4_iface, riid, ppv );
959}
962 void **ppv )
963{
965 return IDirectPlayX_QueryInterface( &This->IDirectPlay4A_iface, riid, ppv );
966}
968static HRESULT WINAPI IDirectPlay3Impl_QueryInterface( IDirectPlay3 *iface, REFIID riid,
969 void **ppv )
970{
972 return IDirectPlayX_QueryInterface( &This->IDirectPlay4_iface, riid, ppv );
973}
976 void **ppv )
977{
979 return IDirectPlayX_QueryInterface( &This->IDirectPlay4_iface, riid, ppv );
980}
982static HRESULT WINAPI IDirectPlay4Impl_QueryInterface( IDirectPlay4 *iface, REFIID riid,
983 void **ppv )
984{
986
987 if ( IsEqualGUID( &IID_IUnknown, riid ) )
988 {
989 TRACE( "(%p)->(IID_IUnknown %p)\n", This, ppv );
990 *ppv = &This->IDirectPlay_iface;
991 }
992 else if ( IsEqualGUID( &IID_IDirectPlay, riid ) )
993 {
994 TRACE( "(%p)->(IID_IDirectPlay %p)\n", This, ppv );
995 *ppv = &This->IDirectPlay_iface;
996 }
997 else if ( IsEqualGUID( &IID_IDirectPlay2A, riid ) )
998 {
999 TRACE( "(%p)->(IID_IDirectPlay2A %p)\n", This, ppv );
1000 *ppv = &This->IDirectPlay2A_iface;
1001 }
1002 else if ( IsEqualGUID( &IID_IDirectPlay2, riid ) )
1003 {
1004 TRACE( "(%p)->(IID_IDirectPlay2 %p)\n", This, ppv );
1005 *ppv = &This->IDirectPlay2_iface;
1006 }
1007 else if ( IsEqualGUID( &IID_IDirectPlay3A, riid ) )
1008 {
1009 TRACE( "(%p)->(IID_IDirectPlay3A %p)\n", This, ppv );
1010 *ppv = &This->IDirectPlay3A_iface;
1011 }
1012 else if ( IsEqualGUID( &IID_IDirectPlay3, riid ) )
1013 {
1014 TRACE( "(%p)->(IID_IDirectPlay3 %p)\n", This, ppv );
1015 *ppv = &This->IDirectPlay3_iface;
1016 }
1017 else if ( IsEqualGUID( &IID_IDirectPlay4A, riid ) )
1018 {
1019 TRACE( "(%p)->(IID_IDirectPlay4A %p)\n", This, ppv );
1020 *ppv = &This->IDirectPlay4A_iface;
1021 }
1022 else if ( IsEqualGUID( &IID_IDirectPlay4, riid ) )
1023 {
1024 TRACE( "(%p)->(IID_IDirectPlay4 %p)\n", This, ppv );
1025 *ppv = &This->IDirectPlay4_iface;
1026 }
1027 else
1028 {
1029 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1030 *ppv = NULL;
1031 return E_NOINTERFACE;
1032 }
1033
1034 IUnknown_AddRef((IUnknown*)*ppv);
1035 return S_OK;
1036}
1039{
1042
1043 TRACE( "(%p) ref=%ld\n", This, ref );
1044
1045 return ref;
1046}
1048static ULONG WINAPI IDirectPlay2Impl_AddRef( IDirectPlay2 *iface )
1049{
1052
1053 TRACE( "(%p) ref=%ld\n", This, ref );
1054
1055 return ref;
1056}
1059{
1062
1063 TRACE( "(%p) ref=%ld\n", This, ref );
1064
1065 return ref;
1066}
1068static ULONG WINAPI IDirectPlay3Impl_AddRef( IDirectPlay3 *iface )
1069{
1072
1073 TRACE( "(%p) ref=%ld\n", This, ref );
1074
1075 return ref;
1076}
1079{
1082
1083 TRACE( "(%p) ref=%ld\n", This, ref );
1084
1085 return ref;
1086}
1088static ULONG WINAPI IDirectPlay4Impl_AddRef(IDirectPlay4 *iface)
1089{
1092
1093 TRACE( "(%p) ref=%ld\n", This, ref );
1094
1095 return ref;
1096}
1099{
1102
1103 TRACE( "(%p) ref=%ld\n", This, ref );
1104
1105 if ( !ref )
1107
1108 return ref;
1109}
1111static ULONG WINAPI IDirectPlay2Impl_Release( IDirectPlay2 *iface )
1112{
1115
1116 TRACE( "(%p) ref=%ld\n", This, ref );
1117
1118 if ( !ref )
1120
1121 return ref;
1122}
1125{
1128
1129 TRACE( "(%p) ref=%ld\n", This, ref );
1130
1131 if ( !ref )
1133
1134 return ref;
1135}
1137static ULONG WINAPI IDirectPlay3Impl_Release( IDirectPlay3 *iface )
1138{
1141
1142 TRACE( "(%p) ref=%ld\n", This, ref );
1143
1144 if ( !ref )
1146
1147 return ref;
1148}
1151{
1154
1155 TRACE( "(%p) ref=%ld\n", This, ref );
1156
1157 if ( !ref )
1159
1160 return ref;
1161}
1163static ULONG WINAPI IDirectPlay4Impl_Release(IDirectPlay4 *iface)
1164{
1167
1168 TRACE( "(%p) ref=%ld\n", This, ref );
1169
1170 if ( !ref )
1172
1173 return ref;
1174}
1177 DPID player )
1178{
1180 return IDirectPlayX_AddPlayerToGroup( &This->IDirectPlay4A_iface, group, player );
1181}
1183static HRESULT WINAPI IDirectPlay2Impl_AddPlayerToGroup( IDirectPlay2 *iface, DPID group,
1184 DPID player )
1185{
1187 return IDirectPlayX_AddPlayerToGroup( &This->IDirectPlay4_iface, group, player );
1188}
1191 DPID player )
1192{
1194 return IDirectPlayX_AddPlayerToGroup( &This->IDirectPlay4A_iface, group, player );
1195}
1197static HRESULT WINAPI IDirectPlay3Impl_AddPlayerToGroup( IDirectPlay3 *iface, DPID group,
1198 DPID player )
1199{
1201 return IDirectPlayX_AddPlayerToGroup( &This->IDirectPlay4_iface, group, player );
1202}
1205 DPID player )
1206{
1208 return IDirectPlayX_AddPlayerToGroup( &This->IDirectPlay4_iface, group, player );
1209}
1212{
1213 DPMSG_ADDPLAYERTOGROUP addPlayerToGroupMsg;
1214 lpGroupData gdata;
1216 lpPlayerList newplist;
1217 HRESULT hr;
1218
1219 /* Find the group */
1220 if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL )
1221 return DPERR_INVALIDGROUP;
1222
1223 /* Find the player */
1224 if ( ( plist = DP_FindPlayer( This, player ) ) == NULL )
1225 return DPERR_INVALIDPLAYER;
1226
1227 /* Create a player list (ie "shortcut" ) */
1228 newplist = calloc( 1, sizeof( *newplist ) );
1229 if ( !newplist )
1230 return DPERR_CANTADDPLAYER;
1231
1232 /* Add the shortcut */
1233 plist->lpPData->uRef++;
1234 newplist->lpPData = plist->lpPData;
1235
1236 /* Add the player to the list of players for this group */
1237 DPQ_INSERT(gdata->players, newplist, players);
1238
1239 /* Let the SP know that we've added a player to the group */
1240 if ( This->dp2->spData.lpCB->AddPlayerToGroup )
1241 {
1243
1244 TRACE( "Calling SP AddPlayerToGroup\n" );
1245
1246 data.idPlayer = player;
1247 data.idGroup = group;
1248 data.lpISP = This->dp2->spData.lpISP;
1249
1250 hr = (*This->dp2->spData.lpCB->AddPlayerToGroup)( &data );
1251 if ( FAILED( hr ) )
1252 {
1253 DPQ_REMOVE( gdata->players, newplist, players );
1254 --plist->lpPData->uRef;
1255 free( newplist );
1256 return hr;
1257 }
1258 }
1259
1260 addPlayerToGroupMsg.dwType = DPSYS_ADDPLAYERTOGROUP;
1261 addPlayerToGroupMsg.dpIdGroup = group;
1262 addPlayerToGroupMsg.dpIdPlayer = player;
1263
1264 hr = DP_QueueMessage( This, DPID_SYSMSG, DPID_ALLPLAYERS, 0, &addPlayerToGroupMsg,
1266 if ( FAILED( hr ) )
1267 {
1268 if ( This->dp2->spData.lpCB->RemovePlayerFromGroup )
1269 {
1271 data.idPlayer = player;
1272 data.idGroup = group;
1273 data.lpISP = This->dp2->spData.lpISP;
1274 This->dp2->spData.lpCB->RemovePlayerFromGroup( &data );
1275 }
1276 DPQ_REMOVE( gdata->players, newplist, players );
1277 --plist->lpPData->uRef;
1278 free( newplist );
1279 return hr;
1280 }
1281
1282 return DP_OK;
1283}
1285static HRESULT WINAPI IDirectPlay4Impl_AddPlayerToGroup( IDirectPlay4 *iface, DPID group,
1286 DPID player )
1287{
1289 HRESULT hr;
1290
1291 TRACE( "(%p)->(0x%08lx,0x%08lx)\n", This, group, player );
1292
1293 if ( This->dp2->connectionInitialized == NO_PROVIDER )
1294 return DPERR_UNINITIALIZED;
1295
1296 EnterCriticalSection( &This->lock );
1297
1298 hr = DP_AddPlayerToGroup( This, group, player );
1299 if ( FAILED( hr ) )
1300 {
1301 LeaveCriticalSection( &This->lock );
1302 return hr;
1303 }
1304
1305 /* Inform all other peers of the addition of player to the group. If there are
1306 * no peers keep this event quiet.
1307 * Also, if this event was the result of another machine sending it to us,
1308 * don't bother rebroadcasting it.
1309 */
1311 if( FAILED( hr ) )
1312 {
1313 LeaveCriticalSection( &This->lock );
1314 return hr;
1315 }
1316
1317 LeaveCriticalSection( &This->lock );
1318
1319 return DP_OK;
1320}
1323{
1325 return IDirectPlayX_Close( &This->IDirectPlay4A_iface );
1326}
1328static HRESULT WINAPI IDirectPlay2Impl_Close( IDirectPlay2 *iface )
1329{
1331 return IDirectPlayX_Close( &This->IDirectPlay4_iface );
1332}
1335{
1337 return IDirectPlayX_Close( &This->IDirectPlay4A_iface );
1338}
1340static HRESULT WINAPI IDirectPlay3Impl_Close( IDirectPlay3 *iface )
1341{
1343 return IDirectPlayX_Close( &This->IDirectPlay4_iface );
1344}
1347{
1349 return IDirectPlayX_Close( &This->IDirectPlay4_iface);
1350}
1352static HRESULT WINAPI IDirectPlay4Impl_Close( IDirectPlay4 *iface )
1353{
1355 HRESULT hr = DP_OK;
1356
1357 TRACE( "(%p)\n", This );
1358
1359 EnterCriticalSection( &This->lock );
1360
1361 This->dp2->bConnectionOpen = FALSE;
1362
1363 LeaveCriticalSection( &This->lock );
1364
1365 /* FIXME: Need to find a new host I assume (how?) */
1366 /* FIXME: Need to destroy all local groups */
1367 /* FIXME: Need to migrate all remotely visible players to the new host */
1368
1369 /* Invoke the SP callback to inform of session close */
1370 if( This->dp2->spData.lpCB->CloseEx )
1371 {
1373
1374 TRACE( "Calling SP CloseEx\n" );
1375 data.lpISP = This->dp2->spData.lpISP;
1376 hr = (*This->dp2->spData.lpCB->CloseEx)( &data );
1377 }
1378 else if ( This->dp2->spData.lpCB->Close ) /* Try obsolete version */
1379 {
1380 TRACE( "Calling SP Close (obsolete interface)\n" );
1381 hr = (*This->dp2->spData.lpCB->Close)();
1382 }
1383
1384 return hr;
1385}
1387HRESULT DP_CreateGroup( IDirectPlayImpl *This, void *msgHeader, const DPID *lpid,
1388 const DPNAME *lpName, void *data, DWORD dataSize, DWORD dwFlags, DPID idParent,
1389 BOOL bAnsi )
1390{
1391 struct GroupList *groupList = NULL;
1392 struct GroupData *parent = NULL;
1393 lpGroupData lpGData;
1394 HRESULT hr;
1395
1396 if( DPID_SYSTEM_GROUP != *lpid )
1397 {
1398 parent = DP_FindAnyGroup( This, idParent );
1399 if( !parent )
1400 return DPERR_INVALIDGROUP;
1401 }
1402
1403 /* Allocate the new space and add to end of high level group list */
1404 lpGData = calloc( 1, sizeof( *lpGData ) );
1405
1406 if( lpGData == NULL )
1407 {
1408 return DPERR_OUTOFMEMORY;
1409 }
1410
1411 DPQ_INIT(lpGData->groups);
1412 DPQ_INIT(lpGData->players);
1413
1414 /* Set the desired player ID - no sanity checking to see if it exists */
1415 lpGData->dpid = *lpid;
1416
1417 lpGData->name = DP_DuplicateName( lpName, FALSE, bAnsi );
1418 if ( !lpGData->name )
1419 {
1420 free( lpGData );
1421 return DPERR_OUTOFMEMORY;
1422 }
1423
1424 lpGData->nameA = DP_DuplicateName( lpName, TRUE, bAnsi );
1425 if ( !lpGData->nameA )
1426 {
1427 free( lpGData->name );
1428 free( lpGData );
1429 return DPERR_OUTOFMEMORY;
1430 }
1431
1432 lpGData->parent = idParent;
1433
1434 /* FIXME: Should we validate the dwFlags? */
1435 lpGData->dwFlags = dwFlags;
1436
1437 /* Initialize the SP data section */
1439 if ( !lpGData->lpSPPlayerData )
1440 {
1441 free( lpGData->nameA );
1442 free( lpGData->name );
1443 free( lpGData );
1444 return DPERR_OUTOFMEMORY;
1445 }
1446
1447 if( DPID_SYSTEM_GROUP == *lpid )
1448 {
1449 This->dp2->lpSysGroup = lpGData;
1450 TRACE( "Inserting system group\n" );
1451 }
1452 else
1453 {
1454 /* Insert into the parent group */
1455 groupList = calloc( 1, sizeof( *groupList ) );
1456 if( !groupList )
1457 {
1458 free( lpGData->nameA );
1459 free( lpGData->name );
1460 free( lpGData );
1461 return DPERR_OUTOFMEMORY;
1462 }
1463 groupList->lpGData = lpGData;
1464
1465 DPQ_INSERT( parent->groups, groupList, groups );
1466 }
1467
1468 /* Something is now referencing this data */
1469 lpGData->uRef++;
1470
1472
1473 /* FIXME: We should only create the system group if GetCaps returns
1474 * DPCAPS_GROUPOPTIMIZED.
1475 */
1476
1477 /* Let the SP know that we've created this group */
1478 if( This->dp2->spData.lpCB->CreateGroup )
1479 {
1481 DWORD dwCreateFlags = 0;
1482
1483 TRACE( "Calling SP CreateGroup\n" );
1484
1485 if( !parent )
1486 dwCreateFlags |= DPLAYI_GROUP_SYSGROUP;
1487
1488 if( !msgHeader )
1489 dwCreateFlags |= DPLAYI_PLAYER_PLAYERLOCAL;
1490
1491 if( dwFlags & DPGROUP_HIDDEN )
1492 dwCreateFlags |= DPLAYI_GROUP_HIDDEN;
1493
1494 data.idGroup = *lpid;
1495 data.dwFlags = dwCreateFlags;
1496 data.lpSPMessageHeader = msgHeader;
1497 data.lpISP = This->dp2->spData.lpISP;
1498
1499 hr = (*This->dp2->spData.lpCB->CreateGroup)( &data );
1500 if( FAILED( hr ) )
1501 {
1502 if( groupList )
1503 {
1504 DPQ_REMOVE( parent->groups, groupList, groups );
1505 free( groupList );
1506 }
1507 else
1508 {
1509 This->dp2->lpSysGroup = NULL;
1510 }
1511 free( lpGData->nameA );
1512 free( lpGData->name );
1513 free( lpGData );
1514 return hr;
1515 }
1516 }
1517
1518 TRACE( "Created group id 0x%08lx\n", *lpid );
1519
1520 return DP_OK;
1521}
1522
1523/* This method assumes that all links to it are already deleted */
1525{
1526 lpGroupList lpGList;
1527
1528 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
1529
1530 DPQ_REMOVE_ENTRY( This->dp2->lpSysGroup->groups, groups, lpGData->dpid, ==, dpid, lpGList );
1531
1532 if( lpGList == NULL )
1533 {
1534 ERR( "DPID 0x%08lx not found\n", dpid );
1535 return;
1536 }
1537
1538 if( --(lpGList->lpGData->uRef) )
1539 {
1540 FIXME( "Why is this not the last reference to group?\n" );
1541 DebugBreak();
1542 }
1543
1544 /* Delete player */
1545 free( lpGList->lpGData->lpSPPlayerData );
1546 free( lpGList->lpGData->nameA );
1547 free( lpGList->lpGData->name );
1548 free( lpGList->lpGData );
1549
1550 /* Remove and Delete Player List object */
1551 free( lpGList );
1552
1553}
1556{
1557 lpGroupList lpGroups;
1558
1559 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
1560
1561 if( dpid == DPID_SYSTEM_GROUP )
1562 {
1563 return This->dp2->lpSysGroup;
1564 }
1565
1566 if( This->dp2->lpSysGroup == NULL )
1567 return NULL;
1568
1569 DPQ_FIND_ENTRY( This->dp2->lpSysGroup->groups, groups, lpGData->dpid, ==, dpid, lpGroups );
1570
1571 if( lpGroups == NULL )
1572 {
1573 return NULL;
1574 }
1575
1576 return lpGroups->lpGData;
1577}
1579static HRESULT DP_IF_CreateGroup( IDirectPlayImpl *This, void *lpMsgHdr, DPID *lpidGroup,
1580 DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi )
1581{
1582 HRESULT hr;
1583
1584 TRACE( "(%p)->(%p,%p,%p,%p,0x%08lx,0x%08lx,%u)\n",
1585 This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize,
1586 dwFlags, bAnsi );
1587
1588 if( This->dp2->connectionInitialized == NO_PROVIDER )
1589 {
1590 return DPERR_UNINITIALIZED;
1591 }
1592
1593 EnterCriticalSection( &This->lock );
1594
1595 /* If the name is not specified, we must provide one */
1596 if( DPID_UNKNOWN == *lpidGroup )
1597 {
1598 /* If we are the name server, we decide on the group ids. If not, we
1599 * must ask for one before attempting a creation.
1600 */
1601 if( This->dp2->bHostInterface )
1602 {
1603 *lpidGroup = DP_NextObjectId();
1604 }
1605 else
1606 {
1607 *lpidGroup = DP_GetRemoteNextObjectId();
1608 }
1609 }
1610
1611 hr = DP_CreateGroup( This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags,
1612 DPID_NOPARENT_GROUP, bAnsi );
1613
1614 if( FAILED( hr ) )
1615 {
1616 LeaveCriticalSection( &This->lock );
1617 return hr;
1618 }
1619
1620 /* Inform all other peers of the creation of a new group. If there are
1621 * no peers keep this event quiet.
1622 * Also if this message was sent to us, don't rebroadcast.
1623 */
1624 if( ( lpMsgHdr == NULL ) &&
1625 This->dp2->lpSessionDesc &&
1626 ( This->dp2->lpSessionDesc->dwFlags & DPSESSION_MULTICASTSERVER ) )
1627 {
1630
1631 msg.dwPlayerType = DPPLAYERTYPE_GROUP;
1632 msg.dpId = *lpidGroup;
1633 msg.dwCurrentPlayers = 0; /* FIXME: Incorrect? */
1634 msg.lpData = lpData;
1635 msg.dwDataSize = dwDataSize;
1636 msg.dpnName = *lpGroupName;
1637 msg.dpIdParent = DPID_NOPARENT_GROUP;
1639
1640 /* FIXME: Correct to just use send effectively? */
1641 /* FIXME: Should size include data w/ message or just message "header" */
1642 /* FIXME: Check return code */
1643 IDirectPlayX_SendEx( &This->IDirectPlay4_iface, DPID_SERVERPLAYER, DPID_ALLPLAYERS, 0, &msg,
1644 sizeof( msg ), 0, 0, NULL, NULL );
1645 }
1646
1647 LeaveCriticalSection( &This->lock );
1648
1649 return DP_OK;
1650}
1653 DPNAME *name, void *data, DWORD size, DWORD flags )
1654{
1656 return IDirectPlayX_CreateGroup( &This->IDirectPlay4A_iface, lpidGroup, name, data, size,
1657 flags );
1658}
1660static HRESULT WINAPI IDirectPlay2Impl_CreateGroup( IDirectPlay2 *iface, DPID *lpidGroup,
1661 DPNAME *name, void *data, DWORD size, DWORD flags )
1662{
1664 return IDirectPlayX_CreateGroup( &This->IDirectPlay4_iface, lpidGroup, name, data, size,
1665 flags );
1666}
1669 DPNAME *name, void *data, DWORD size, DWORD flags )
1670{
1672 return IDirectPlayX_CreateGroup( &This->IDirectPlay4A_iface, group, name, data, size,
1673 flags );
1674}
1676static HRESULT WINAPI IDirectPlay3Impl_CreateGroup( IDirectPlay3 *iface, DPID *lpidGroup,
1677 DPNAME *name, void *data, DWORD size, DWORD flags )
1678{
1680 return IDirectPlayX_CreateGroup( &This->IDirectPlay4_iface, lpidGroup, name, data, size,
1681 flags );
1682}
1685 DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags )
1686{
1688
1689 *lpidGroup = DPID_UNKNOWN;
1690
1691 return DP_IF_CreateGroup( This, NULL, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags,
1692 TRUE );
1693}
1695static HRESULT WINAPI IDirectPlay4Impl_CreateGroup( IDirectPlay4 *iface, DPID *lpidGroup,
1696 DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags )
1697{
1699
1700 *lpidGroup = DPID_UNKNOWN;
1701
1702 return DP_IF_CreateGroup( This, NULL, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags,
1703 FALSE );
1704}
1705
1706
1707static void
1709 LPVOID lpData, DWORD dwDataSize )
1710{
1711 /* Clear out the data with this player */
1712 if( dwFlags & DPSET_LOCAL )
1713 {
1714 if ( lpGData->dwLocalDataSize != 0 )
1715 {
1716 free( lpGData->lpLocalData );
1717 lpGData->lpLocalData = NULL;
1718 lpGData->dwLocalDataSize = 0;
1719 }
1720 }
1721 else
1722 {
1723 if( lpGData->dwRemoteDataSize != 0 )
1724 {
1725 free( lpGData->lpRemoteData );
1726 lpGData->lpRemoteData = NULL;
1727 lpGData->dwRemoteDataSize = 0;
1728 }
1729 }
1730
1731 /* Reallocate for new data */
1732 if( lpData != NULL )
1733 {
1734 if( dwFlags & DPSET_LOCAL )
1735 {
1736 lpGData->lpLocalData = lpData;
1737 lpGData->dwLocalDataSize = dwDataSize;
1738 }
1739 else
1740 {
1741 lpGData->lpRemoteData = malloc( dwDataSize );
1742 CopyMemory( lpGData->lpRemoteData, lpData, dwDataSize );
1743 lpGData->dwRemoteDataSize = dwDataSize;
1744 }
1745 }
1746
1747}
1749static HRESULT DP_CreateSPPlayer( IDirectPlayImpl *This, DPID dpid, DWORD flags, void *msgHeader )
1750{
1751 HRESULT hr;
1752
1753 /* Let the SP know that we've created this player */
1754 if( This->dp2->spData.lpCB->CreatePlayer )
1755 {
1757
1758 data.idPlayer = dpid;
1759 data.dwFlags = flags;
1760 data.lpSPMessageHeader = msgHeader;
1761 data.lpISP = This->dp2->spData.lpISP;
1762
1763 TRACE( "Calling SP CreatePlayer 0x%08lx: dwFlags: 0x%08lx lpMsgHdr: %p\n", dpid, flags,
1764 msgHeader );
1765
1766 hr = (*This->dp2->spData.lpCB->CreatePlayer)( &data );
1767 if( FAILED( hr ) )
1768 {
1769 ERR( "Failed to create player with sp: %s\n", DPLAYX_HresultToString( hr ) );
1770 return hr;
1771 }
1772 }
1773
1774 /* Now let the SP know that this player is a member of the system group */
1775 if( This->dp2->spData.lpCB->AddPlayerToGroup )
1776 {
1778
1779 data.idPlayer = dpid;
1780 data.idGroup = DPID_SYSTEM_GROUP;
1781 data.lpISP = This->dp2->spData.lpISP;
1782
1783 TRACE( "Calling SP AddPlayerToGroup (sys group)\n" );
1784
1785 hr = (*This->dp2->spData.lpCB->AddPlayerToGroup)( &data );
1786 if( FAILED( hr ) )
1787 {
1788 ERR( "Failed to add player to sys group with sp: %s\n", DPLAYX_HresultToString( hr ) );
1789 if ( This->dp2->spData.lpCB->DeletePlayer )
1790 {
1792 data.idPlayer = dpid;
1793 data.dwFlags = 0;
1794 data.lpISP = This->dp2->spData.lpISP;
1795 This->dp2->spData.lpCB->DeletePlayer( &data );
1796 }
1797 return hr;
1798 }
1799 }
1800
1801 return DP_OK;
1802}
1805{
1806 if ( This->dp2->spData.lpCB->RemovePlayerFromGroup )
1807 {
1809 data.idPlayer = dpid;
1810 data.idGroup = DPID_SYSTEM_GROUP;
1811 data.lpISP = This->dp2->spData.lpISP;
1812 This->dp2->spData.lpCB->RemovePlayerFromGroup( &data );
1813 }
1814 if ( This->dp2->spData.lpCB->DeletePlayer )
1815 {
1817 data.idPlayer = dpid;
1818 data.dwFlags = 0;
1819 data.lpISP = This->dp2->spData.lpISP;
1820 This->dp2->spData.lpCB->DeletePlayer( &data );
1821 }
1822}
1824HRESULT DP_CreatePlayer( IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPNAME *lpName,
1825 void *data, DWORD dataSize, void *spData, DWORD spDataSize, DWORD dwFlags, HANDLE hEvent,
1826 struct PlayerData **playerData, BOOL bAnsi )
1827{
1828 lpPlayerData lpPData;
1829 lpPlayerList lpPList;
1830 HRESULT hr;
1831
1832 TRACE( "(%p)->(%p,%p,%u)\n", This, lpid, lpName, bAnsi );
1833
1834 /* Allocate the storage for the player and associate it with list element */
1835 lpPData = calloc( 1, sizeof( *lpPData ) );
1836 if( lpPData == NULL )
1837 return DPERR_OUTOFMEMORY;
1838
1839 /* Set the desired player ID */
1840 lpPData->dpid = *lpid;
1841
1842 lpPData->name = DP_DuplicateName( lpName, FALSE, bAnsi );
1843 if ( !lpPData->name )
1844 {
1845 free( lpPData );
1846 return DPERR_OUTOFMEMORY;
1847 }
1848
1849 lpPData->nameA = DP_DuplicateName( lpName, TRUE, bAnsi );
1850 if ( !lpPData->nameA )
1851 {
1852 free( lpPData->name );
1853 free( lpPData );
1854 return DPERR_OUTOFMEMORY;
1855 }
1856
1857 lpPData->dwFlags = dwFlags;
1858
1859 /* If we were given an event handle, duplicate it */
1860 if( hEvent != 0 )
1861 {
1863 GetCurrentProcess(), &lpPData->hEvent,
1865 )
1866 {
1867 /* FIXME: Memory leak */
1868 ERR( "Can't duplicate player msg handle %p\n", hEvent );
1869 }
1870 }
1871
1872 /* Initialize the SP data section */
1874
1875 /* Create the list object and link it in */
1876 lpPList = calloc( 1, sizeof( *lpPList ) );
1877 if( !lpPList )
1878 {
1879 free( lpPData->lpSPPlayerData );
1880 CloseHandle( lpPData->hEvent );
1881 free( lpPData->nameA );
1882 free( lpPData->name );
1883 free( lpPData );
1884 return DPERR_OUTOFMEMORY;
1885 }
1886
1887 lpPData->uRef = 1;
1888 lpPList->lpPData = lpPData;
1889
1890 /* Add the player to the system group */
1891 DPQ_INSERT( This->dp2->lpSysGroup->players, lpPList, players );
1892
1894
1895 hr = IDirectPlaySP_SetSPPlayerData( This->dp2->spData.lpISP, *lpid, spData, spDataSize,
1896 DPSET_REMOTE );
1897 if ( FAILED( hr ) )
1898 {
1899 free( lpPData->lpRemoteData );
1900 DPQ_REMOVE( This->dp2->lpSysGroup->players, lpPList, players );
1901 free( lpPList );
1902 free( lpPData->lpSPPlayerData );
1903 CloseHandle( lpPData->hEvent );
1904 free( lpPData->nameA );
1905 free( lpPData->name );
1906 free( lpPData );
1907 return hr;
1908 }
1909
1910 hr = DP_CreateSPPlayer( This, *lpid, dwFlags, msgHeader );
1911 if ( FAILED( hr ) )
1912 {
1913 free( lpPData->lpRemoteData );
1914 DPQ_REMOVE( This->dp2->lpSysGroup->players, lpPList, players );
1915 free( lpPList );
1916 free( lpPData->lpSPPlayerData );
1917 CloseHandle( lpPData->hEvent );
1918 free( lpPData->nameA );
1919 free( lpPData->name );
1920 free( lpPData );
1921 return hr;
1922 }
1923
1925 {
1927 DWORD currentPlayers;
1928
1929 currentPlayers = This->dp2->lpSessionDesc->dwCurrentPlayers;
1931 ++currentPlayers;
1932
1934 msg.dwPlayerType = DPPLAYERTYPE_PLAYER;
1935 msg.dpId = *lpid;
1936 msg.dwCurrentPlayers = currentPlayers;
1937 msg.lpData = data;
1938 msg.dwDataSize = dataSize;
1939 msg.dpnName = *lpPData->name;
1940 msg.dpIdParent = 0;
1941 msg.dwFlags = dwFlags;
1942
1945 if ( FAILED( hr ) )
1946 {
1947 DP_DeleteSPPlayer( This, *lpid );
1948 free( lpPData->lpLocalData );
1949 free( lpPData->lpRemoteData );
1950 DPQ_REMOVE( This->dp2->lpSysGroup->players, lpPList, players );
1951 free( lpPList );
1952 CloseHandle( lpPData->hEvent );
1953 free( lpPData->nameA );
1954 free( lpPData->name );
1955 free( lpPData );
1956 return hr;
1957 }
1958
1959 This->dp2->lpSessionDesc->dwCurrentPlayers++;
1960 }
1961
1962 TRACE( "Created player id 0x%08lx\n", *lpid );
1963
1964 if( playerData )
1965 *playerData = lpPData;
1966
1967 return DP_OK;
1968}
1969
1970/* This method assumes that all links to it are already deleted */
1972{
1973 lpPlayerList lpPList;
1974
1975 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
1976
1977 DPQ_REMOVE_ENTRY( This->dp2->lpSysGroup->players, players, lpPData->dpid, ==, dpid, lpPList );
1978
1979 if( lpPList == NULL )
1980 {
1981 ERR( "DPID 0x%08lx not found\n", dpid );
1982 return;
1983 }
1984
1985 /* Verify that this is the last reference to the data */
1986 if( --(lpPList->lpPData->uRef) )
1987 {
1988 FIXME( "Why is this not the last reference to player?\n" );
1989 DebugBreak();
1990 }
1991
1992 /* Delete player */
1993 free( lpPList->lpPData->nameA );
1994 free( lpPList->lpPData->name );
1995
1996 CloseHandle( lpPList->lpPData->hEvent );
1997 free( lpPList->lpPData );
1998
1999 /* Delete Player List object */
2000 free( lpPList );
2001}
2004{
2005 lpPlayerList lpPlayers;
2006
2007 TRACE( "(%p)->(0x%08lx)\n", This, dpid );
2008
2009 if(This->dp2->lpSysGroup == NULL)
2010 return NULL;
2011
2012 DPQ_FIND_ENTRY( This->dp2->lpSysGroup->players, players, lpPData->dpid, ==, dpid, lpPlayers );
2013
2014 return lpPlayers;
2015}
2017static DWORD DP_CopyName( DPNAME *dst, const DPNAME *src, BOOL dstAnsi, BOOL srcAnsi )
2018{
2019 DWORD offset = sizeof( DPNAME );
2020
2021 if ( !src )
2022 {
2023 if ( dst )
2024 {
2025 memset( dst, 0, sizeof( DPNAME ) );
2026 dst->dwSize = sizeof( DPNAME );
2027 }
2028 return offset;
2029 }
2030
2031 if ( dst )
2032 {
2033 *dst = *src;
2034 dst->dwSize = sizeof( DPNAME );
2035 }
2036
2037 offset += DP_CopyString( &dst->lpszShortNameA, src->lpszShortNameA, dstAnsi, srcAnsi, dst,
2038 offset );
2039 offset += DP_CopyString( &dst->lpszLongNameA, src->lpszLongNameA, dstAnsi, srcAnsi, dst,
2040 offset );
2041
2042 return offset;
2043}
2045static DPNAME *DP_DuplicateName( const DPNAME *src, BOOL dstAnsi, BOOL srcAnsi )
2046{
2047 DPNAME *dst;
2048 DWORD size;
2049
2050 size = DP_CopyName( NULL, src, dstAnsi, srcAnsi );
2051
2052 dst = malloc( size );
2053 if ( !dst )
2054 return NULL;
2055
2056 DP_CopyName( dst, src, dstAnsi, srcAnsi );
2057
2058 return dst;
2059}
2060
2061static void
2063 LPVOID lpData, DWORD dwDataSize )
2064{
2065 /* Clear out the data with this player */
2066 if( dwFlags & DPSET_LOCAL )
2067 {
2068 if ( lpPData->dwLocalDataSize != 0 )
2069 {
2070 free( lpPData->lpLocalData );
2071 lpPData->lpLocalData = NULL;
2072 lpPData->dwLocalDataSize = 0;
2073 }
2074 }
2075 else
2076 {
2077 if( lpPData->dwRemoteDataSize != 0 )
2078 {
2079 free( lpPData->lpRemoteData );
2080 lpPData->lpRemoteData = NULL;
2081 lpPData->dwRemoteDataSize = 0;
2082 }
2083 }
2084
2085 /* Reallocate for new data */
2086 if( lpData != NULL )
2087 {
2088
2089 if( dwFlags & DPSET_LOCAL )
2090 {
2091 lpPData->lpLocalData = lpData;
2092 lpPData->dwLocalDataSize = dwDataSize;
2093 }
2094 else
2095 {
2096 lpPData->lpRemoteData = malloc( dwDataSize );
2097 CopyMemory( lpPData->lpRemoteData, lpData, dwDataSize );
2098 lpPData->dwRemoteDataSize = dwDataSize;
2099 }
2100 }
2101
2102}
2104static HRESULT DP_IF_CreatePlayer( IDirectPlayImpl *This, DPID *lpidPlayer,
2105 DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags,
2106 BOOL bAnsi )
2107{
2108 struct PlayerData *player;
2109 HRESULT hr = DP_OK;
2110 DWORD dwCreateFlags;
2111
2112 TRACE( "(%p)->(%p,%p,%p,%p,0x%08lx,0x%08lx,%u)\n",
2113 This, lpidPlayer, lpPlayerName, hEvent, lpData,
2114 dwDataSize, dwFlags, bAnsi );
2115 if( This->dp2->connectionInitialized == NO_PROVIDER )
2116 {
2117 return DPERR_UNINITIALIZED;
2118 }
2119
2120 EnterCriticalSection( &This->lock );
2121 if( !This->dp2->bConnectionOpen )
2122 {
2123 LeaveCriticalSection( &This->lock );
2124 return DPERR_INVALIDPARAM;
2125 }
2126 LeaveCriticalSection( &This->lock );
2127
2128 if( lpidPlayer == NULL )
2129 {
2130 return DPERR_INVALIDPARAMS;
2131 }
2132
2133
2134 /* Determine the creation flags for the player. These will be passed
2135 * to the name server if requesting a player id and to the SP when
2136 * informing it of the player creation
2137 */
2138 dwCreateFlags = dwFlags | DPLAYI_PLAYER_PLAYERLOCAL;
2139
2140 /* Verify we know how to handle all the flags */
2141 if( !( ( dwFlags & DPPLAYER_SERVERPLAYER ) ||
2143 )
2144 )
2145 {
2146 /* Assume non fatal failure */
2147 ERR( "unknown dwFlags = 0x%08lx\n", dwFlags );
2148 }
2149
2150 /* If the name is not specified, we must provide one */
2152 {
2153 /* If we are the session master, we dish out the group/player ids */
2154 if( This->dp2->bHostInterface )
2155 {
2156 *lpidPlayer = DP_NextObjectId();
2157 }
2158 else
2159 {
2160 hr = DP_MSG_SendRequestPlayerId( This, dwCreateFlags, lpidPlayer );
2161
2162 if( FAILED(hr) )
2163 {
2164 ERR( "Request for ID failed: %s\n", DPLAYX_HresultToString( hr ) );
2165 return hr;
2166 }
2167 }
2168 }
2169 else
2170 {
2171 /* FIXME: Would be nice to perhaps verify that we don't already have
2172 * this player.
2173 */
2174 *lpidPlayer = DPID_SERVERPLAYER;
2175 }
2176
2177 EnterCriticalSection( &This->lock );
2178
2179 /* We pass creation flags, so we can distinguish sysplayers and not count them in the current
2180 player total */
2181 hr = DP_CreatePlayer( This, NULL, lpidPlayer, lpPlayerName, lpData, dwDataSize, NULL, 0,
2182 dwCreateFlags, hEvent, &player, bAnsi );
2183 if( FAILED( hr ) )
2184 {
2185 LeaveCriticalSection( &This->lock );
2186 return hr;
2187 }
2188
2189 hr = DP_MSG_SendCreatePlayer( This, DPID_ALLPLAYERS, *lpidPlayer, dwCreateFlags, player->name,
2190 lpData, dwDataSize, This->dp2->systemPlayerId );
2191 if( FAILED( hr ) )
2192 {
2193 LeaveCriticalSection( &This->lock );
2194 return hr;
2195 }
2196
2197 LeaveCriticalSection( &This->lock );
2198
2199 return hr;
2200}
2204{
2206 return IDirectPlayX_CreatePlayer( &This->IDirectPlay4A_iface, lpidPlayer, name, event, data,
2207 size, flags );
2208}
2210static HRESULT WINAPI IDirectPlay2Impl_CreatePlayer( IDirectPlay2 *iface, DPID *lpidPlayer,
2212{
2214 return IDirectPlayX_CreatePlayer( &This->IDirectPlay4_iface, lpidPlayer, name, event, data,
2215 size, flags );
2216}
2220{
2222 return IDirectPlayX_CreatePlayer( &This->IDirectPlay4A_iface, lpidPlayer, name, event, data,
2223 size, flags );
2224}
2226static HRESULT WINAPI IDirectPlay3Impl_CreatePlayer( IDirectPlay3 *iface, DPID *lpidPlayer,
2228{
2230 return IDirectPlayX_CreatePlayer( &This->IDirectPlay4_iface, lpidPlayer, name, event, data,
2231 size, flags );
2232}
2235 DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags )
2236{
2238 return DP_IF_CreatePlayer( This, lpidPlayer, lpPlayerName, hEvent,
2239 lpData, dwDataSize, dwFlags, TRUE );
2240}
2242static HRESULT WINAPI IDirectPlay4Impl_CreatePlayer( IDirectPlay4 *iface, DPID *lpidPlayer,
2243 DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags )
2244{
2246 return DP_IF_CreatePlayer( This, lpidPlayer, lpPlayerName, hEvent,
2247 lpData, dwDataSize, dwFlags, FALSE );
2248}
2250static DPID DP_GetRemoteNextObjectId(void)
2251{
2252 FIXME( ":stub\n" );
2253
2254 /* Hack solution */
2255 return DP_NextObjectId();
2256}
2259 DPID player )
2260{
2262 return IDirectPlayX_DeletePlayerFromGroup( &This->IDirectPlay4A_iface, group, player );
2263}
2266 DPID player )
2267{
2269 return IDirectPlayX_DeletePlayerFromGroup( &This->IDirectPlay4_iface, group, player );
2270}
2273 DPID player )
2274{
2276 return IDirectPlayX_DeletePlayerFromGroup( &This->IDirectPlay4A_iface, group, player );
2277}
2280 DPID player )
2281{
2283 return IDirectPlayX_DeletePlayerFromGroup( &This->IDirectPlay4_iface, group, player );
2284}
2287 DPID player )
2288{
2290 return IDirectPlayX_DeletePlayerFromGroup( &This->IDirectPlay4_iface, group, player );
2291}
2294 DPID player )
2295{
2297 HRESULT hr = DP_OK;
2298
2299 lpGroupData gdata;
2301
2302 TRACE( "(%p)->(0x%08lx,0x%08lx)\n", This, group, player );
2303
2304 EnterCriticalSection( &This->lock );
2305
2306 /* Find the group */
2307 if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL )
2308 {
2309 LeaveCriticalSection( &This->lock );
2310 return DPERR_INVALIDGROUP;
2311 }
2312
2313 /* Find the player */
2314 if ( DP_FindPlayer( This, player ) == NULL )
2315 {
2316 LeaveCriticalSection( &This->lock );
2317 return DPERR_INVALIDPLAYER;
2318 }
2319
2320 /* Remove the player shortcut from the group */
2321 DPQ_REMOVE_ENTRY( gdata->players, players, lpPData->dpid, ==, player, plist );
2322
2323 if ( !plist )
2324 {
2325 LeaveCriticalSection( &This->lock );
2326 return DPERR_INVALIDPLAYER;
2327 }
2328
2329 /* One less reference */
2330 plist->lpPData->uRef--;
2331
2332 /* Delete the Player List element */
2333 free( plist );
2334
2335 /* Inform the SP if they care */
2336 if ( This->dp2->spData.lpCB->RemovePlayerFromGroup )
2337 {
2339
2340 TRACE( "Calling SP RemovePlayerFromGroup\n" );
2341 data.idPlayer = player;
2342 data.idGroup = group;
2343 data.lpISP = This->dp2->spData.lpISP;
2344 hr = (*This->dp2->spData.lpCB->RemovePlayerFromGroup)( &data );
2345 }
2346
2347 /* Need to send a DELETEPLAYERFROMGROUP message */
2348 FIXME( "Need to send a message\n" );
2349
2350 LeaveCriticalSection( &This->lock );
2351
2352 return hr;
2353}
2355typedef struct _DPRGOPContext
2361
2364 DPID dpId,
2365 DWORD dwPlayerType,
2367 DWORD dwFlags,
2368 LPVOID lpContext )
2369{
2370 lpDPRGOPContext lpCtxt = (lpDPRGOPContext)lpContext;
2371
2372 TRACE( "Removing element:0x%08lx (type:0x%08lx) from element:0x%08lx\n",
2373 dpId, dwPlayerType, lpCtxt->idGroup );
2374
2375 if( dwPlayerType == DPPLAYERTYPE_GROUP )
2376 {
2378 lpCtxt->idGroup, dpId ) ) )
2379 ERR( "Unable to delete group 0x%08lx from group 0x%08lx\n", dpId, lpCtxt->idGroup );
2380 }
2382 lpCtxt->idGroup, dpId ) ) )
2383 ERR( "Unable to delete player 0x%08lx from grp 0x%08lx\n", dpId, lpCtxt->idGroup );
2384
2385 return TRUE; /* Continue enumeration */
2386}
2388static HRESULT DP_IF_DestroyGroup( IDirectPlayImpl *This, void *lpMsgHdr, DPID idGroup, BOOL bAnsi )
2389{
2390 lpGroupData lpGData;
2392
2393 FIXME( "(%p)->(%p,0x%08lx,%u): semi stub\n",
2394 This, lpMsgHdr, idGroup, bAnsi );
2395
2396 EnterCriticalSection( &This->lock );
2397
2398 /* Find the group */
2399 if( ( lpGData = DP_FindAnyGroup( This, idGroup ) ) == NULL )
2400 {
2401 LeaveCriticalSection( &This->lock );
2402 return DPERR_INVALIDPLAYER; /* yes player */
2403 }
2404
2405 context.This = This;
2406 context.bAnsi = bAnsi;
2407 context.idGroup = idGroup;
2408
2409 /* Remove all players that this group has */
2410 IDirectPlayX_EnumGroupPlayers( &This->IDirectPlay4_iface, idGroup, NULL, cbRemoveGroupOrPlayer,
2411 &context, 0 );
2412
2413 /* Remove all links to groups that this group has since this is dp3 */
2414 IDirectPlayX_EnumGroupsInGroup( &This->IDirectPlay4_iface, idGroup, NULL, cbRemoveGroupOrPlayer,
2415 (void*)&context, 0 );
2416
2417 /* Remove this group from the parent group - if it has one */
2418 if( ( idGroup != DPID_SYSTEM_GROUP ) && ( lpGData->parent != DPID_SYSTEM_GROUP ) )
2419 IDirectPlayX_DeleteGroupFromGroup( &This->IDirectPlay4_iface, lpGData->parent, idGroup );
2420
2421 /* Now delete this group data and list from the system group */
2422 DP_DeleteGroup( This, idGroup );
2423
2424 /* Let the SP know that we've destroyed this group */
2425 if( This->dp2->spData.lpCB->DeleteGroup )
2426 {
2428
2429 FIXME( "data.dwFlags is incorrect\n" );
2430
2431 data.idGroup = idGroup;
2432 data.dwFlags = 0;
2433 data.lpISP = This->dp2->spData.lpISP;
2434
2435 (*This->dp2->spData.lpCB->DeleteGroup)( &data );
2436 }
2437
2438 FIXME( "Send out a DESTORYPLAYERORGROUP message\n" );
2439
2440 LeaveCriticalSection( &This->lock );
2441
2442 return DP_OK;
2443}
2446{
2448 return IDirectPlayX_DestroyGroup( &This->IDirectPlay4A_iface, group );
2449}
2451static HRESULT WINAPI IDirectPlay2Impl_DestroyGroup( IDirectPlay2 *iface, DPID group )
2452{
2454 return IDirectPlayX_DestroyGroup( &This->IDirectPlay4_iface, group );
2455}
2458{
2460 return IDirectPlayX_DestroyGroup( &This->IDirectPlay4A_iface, group );
2461}
2463static HRESULT WINAPI IDirectPlay3Impl_DestroyGroup( IDirectPlay3 *iface, DPID group )
2464{
2466 return IDirectPlayX_DestroyGroup( &This->IDirectPlay4_iface, group );
2467}
2470{
2472 return DP_IF_DestroyGroup( This, NULL, idGroup, TRUE );
2473}
2475static HRESULT WINAPI IDirectPlay4Impl_DestroyGroup( IDirectPlay4 *iface, DPID idGroup )
2476{
2478 return DP_IF_DestroyGroup( This, NULL, idGroup, FALSE );
2479}
2481typedef struct _DPFAGContext
2488static HRESULT DP_IF_DestroyPlayer( IDirectPlayImpl *This, void *lpMsgHdr, DPID idPlayer,
2489 BOOL bAnsi )
2490{
2491 DPFAGContext cbContext;
2492
2493 FIXME( "(%p)->(%p,0x%08lx,%u): semi stub\n",
2494 This, lpMsgHdr, idPlayer, bAnsi );
2495
2496 if( This->dp2->connectionInitialized == NO_PROVIDER )
2497 {
2498 return DPERR_UNINITIALIZED;
2499 }
2500
2501 EnterCriticalSection( &This->lock );
2502
2503 if( DP_FindPlayer( This, idPlayer ) == NULL )
2504 {
2505 LeaveCriticalSection( &This->lock );
2506 return DPERR_INVALIDPLAYER;
2507 }
2508
2509 /* FIXME: If the player is remote, we must be the host to delete this */
2510
2511 cbContext.This = This;
2512 cbContext.idPlayer = idPlayer;
2513 cbContext.bAnsi = bAnsi;
2514
2515 /* Find each group and call DeletePlayerFromGroup if the player is a
2516 member of the group */
2517 IDirectPlayX_EnumGroups( &This->IDirectPlay4_iface, NULL, cbDeletePlayerFromAllGroups, &cbContext,
2519
2520 /* Now delete player and player list from the sys group */
2521 DP_DeletePlayer( This, idPlayer );
2522
2523 /* Let the SP know that we've destroyed this group */
2524 if( This->dp2->spData.lpCB->DeletePlayer )
2525 {
2527
2528 FIXME( "data.dwFlags is incorrect\n" );
2529
2530 data.idPlayer = idPlayer;
2531 data.dwFlags = 0;
2532 data.lpISP = This->dp2->spData.lpISP;
2533
2534 (*This->dp2->spData.lpCB->DeletePlayer)( &data );
2535 }
2536
2537 FIXME( "Send a DELETEPLAYERORGROUP msg\n" );
2538
2539 LeaveCriticalSection( &This->lock );
2540
2541 return DP_OK;
2542}
2543
2546 DPID dpId,
2547 DWORD dwPlayerType,
2549 DWORD dwFlags,
2550 LPVOID lpContext )
2551{
2552 lpDPFAGContext lpCtxt = (lpDPFAGContext)lpContext;
2553
2554 if( dwPlayerType == DPPLAYERTYPE_GROUP )
2555 {
2557
2558 /* Enumerate all groups in this group since this will normally only
2559 * be called for top level groups
2560 */
2563
2564 }
2565 else
2566 {
2567 ERR( "Group callback has dwPlayerType = 0x%08lx\n", dwPlayerType );
2568 }
2569
2570 return TRUE;
2571}
2574{
2576 return IDirectPlayX_DestroyPlayer( &This->IDirectPlay4A_iface, player );
2577}
2579static HRESULT WINAPI IDirectPlay2Impl_DestroyPlayer( IDirectPlay2 *iface, DPID player )
2580{
2582 return IDirectPlayX_DestroyPlayer( &This->IDirectPlay4_iface, player );
2583}
2586{
2588 return IDirectPlayX_DestroyPlayer( &This->IDirectPlay4A_iface, player );
2589}
2591static HRESULT WINAPI IDirectPlay3Impl_DestroyPlayer( IDirectPlay3 *iface, DPID player )
2592{
2594 return IDirectPlayX_DestroyPlayer( &This->IDirectPlay4_iface, player );
2595}
2598{
2600 return DP_IF_DestroyPlayer( This, NULL, idPlayer, TRUE );
2601}
2603static HRESULT WINAPI IDirectPlay4Impl_DestroyPlayer( IDirectPlay4 *iface, DPID idPlayer )
2604{
2606 return DP_IF_DestroyPlayer( This, NULL, idPlayer, FALSE );
2607}
2610 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2611{
2613 return IDirectPlayX_EnumGroupPlayers( &This->IDirectPlay4A_iface, group, instance,
2614 enumplayercb, context, flags );
2615}
2617static HRESULT WINAPI IDirectPlay2Impl_EnumGroupPlayers( IDirectPlay2 *iface, DPID group,
2618 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2619{
2621 return IDirectPlayX_EnumGroupPlayers( &This->IDirectPlay4_iface, group, instance,
2622 enumplayercb, context, flags );
2623}
2626 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2627{
2629 return IDirectPlayX_EnumGroupPlayers( &This->IDirectPlay4A_iface, group, instance,
2630 enumplayercb, context, flags );
2631}
2633static HRESULT WINAPI IDirectPlay3Impl_EnumGroupPlayers( IDirectPlay3 *iface, DPID group,
2634 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2635{
2637 return IDirectPlayX_EnumGroupPlayers( &This->IDirectPlay4_iface, group, instance,
2638 enumplayercb, context, flags );
2639}
2642 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags, BOOL ansi )
2643{
2644 lpGroupData gdata;
2646
2647 FIXME( "(%p)->(0x%08lx,%p,%p,%p,0x%08lx): semi stub\n", This, group, instance, enumplayercb,
2648 context, flags );
2649
2650 if ( This->dp2->connectionInitialized == NO_PROVIDER )
2651 return DPERR_UNINITIALIZED;
2652
2653 EnterCriticalSection( &This->lock );
2654
2655 /* Find the group */
2656 if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL )
2657 {
2658 LeaveCriticalSection( &This->lock );
2659 return DPERR_INVALIDGROUP;
2660 }
2661
2662 /* Walk the players in this group */
2663 for( plist = DPQ_FIRST( gdata->players ); plist; plist = DPQ_NEXT( plist->players ) )
2664 {
2665 DWORD playerFlags;
2666
2667 /* We do not enum the name server or app server as they are of no
2668 * consequence to the end user.
2669 */
2670 if ( plist->lpPData->dwFlags & DPLAYI_PLAYER_SYSPLAYER )
2671 continue;
2672
2673 if ( (plist->lpPData->dwFlags & flags) != (flags & ~DPENUMPLAYERS_REMOTE) )
2674 continue;
2675 if ( (plist->lpPData->dwFlags & DPENUMPLAYERS_LOCAL) && (flags & DPENUMPLAYERS_REMOTE) )
2676 continue;
2677
2678 playerFlags = plist->lpPData->dwFlags;
2680 playerFlags |= flags;
2681
2682 if ( !enumplayercb( plist->lpPData->dpid, DPPLAYERTYPE_PLAYER,
2683 ansi ? plist->lpPData->nameA : plist->lpPData->name,
2684 playerFlags, context ) )
2685 /* User requested break */
2686 break;
2687 }
2688
2689 LeaveCriticalSection( &This->lock );
2690
2691 return DP_OK;
2692}
2695 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2696{
2698 return DP_IF_EnumGroupPlayers( This, group, instance, enumplayercb, context, flags, TRUE );
2699}
2701static HRESULT WINAPI IDirectPlay4Impl_EnumGroupPlayers( IDirectPlay4 *iface, DPID group,
2702 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2703{
2705 return DP_IF_EnumGroupPlayers( This, group, instance, enumplayercb, context, flags, FALSE );
2706}
2707
2708/* NOTE: This only enumerates top level groups (created with CreateGroup) */
2710 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2711{
2713 return IDirectPlayX_EnumGroups( &This->IDirectPlay4A_iface, instance, enumplayercb, context,
2714 flags );
2715}
2717static HRESULT WINAPI IDirectPlay2Impl_EnumGroups( IDirectPlay2 *iface, GUID *instance,
2718 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2719{
2721 return IDirectPlayX_EnumGroups( &This->IDirectPlay4_iface, instance, enumplayercb, context,
2722 flags );
2723}
2726 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2727{
2729 return IDirectPlayX_EnumGroups( &This->IDirectPlay4A_iface, instance, enumplayercb, context,
2730 flags );
2731}
2733static HRESULT WINAPI IDirectPlay3Impl_EnumGroups( IDirectPlay3 *iface, GUID *instance,
2734 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2735{
2737 return IDirectPlayX_EnumGroups( &This->IDirectPlay4_iface, instance, enumplayercb, context,
2738 flags );
2739}
2742 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2743{
2744 return IDirectPlayX_EnumGroupsInGroup( iface, DPID_SYSTEM_GROUP, instance, enumplayercb,
2745 context, flags );
2746}
2748static HRESULT WINAPI IDirectPlay4Impl_EnumGroups ( IDirectPlay4 *iface, GUID *instance,
2749 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2750{
2751 return IDirectPlayX_EnumGroupsInGroup( iface, DPID_SYSTEM_GROUP, instance, enumplayercb,
2752 context, flags );
2753}
2756 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2757{
2759 return IDirectPlayX_EnumPlayers( &This->IDirectPlay4A_iface, instance, enumplayercb, context,
2760 flags );
2761}
2763static HRESULT WINAPI IDirectPlay2Impl_EnumPlayers( IDirectPlay2 *iface, GUID *instance,
2764 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2765{
2767 return IDirectPlayX_EnumPlayers( &This->IDirectPlay4_iface, instance, enumplayercb, context,
2768 flags );
2769}
2772 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2773{
2775 return IDirectPlayX_EnumPlayers( &This->IDirectPlay4A_iface, instance, enumplayercb, context,
2776 flags );
2777}
2779static HRESULT WINAPI IDirectPlay3Impl_EnumPlayers( IDirectPlay3 *iface, GUID *instance,
2780 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2781{
2783 return IDirectPlayX_EnumPlayers( &This->IDirectPlay4_iface, instance, enumplayercb, context,
2784 flags );
2785}
2788 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2789{
2790 return IDirectPlayX_EnumGroupPlayers( iface, DPID_SYSTEM_GROUP, instance, enumplayercb,
2791 context, flags );
2792}
2794static HRESULT WINAPI IDirectPlay4Impl_EnumPlayers( IDirectPlay4 *iface, GUID *instance,
2795 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
2796{
2797 return IDirectPlayX_EnumGroupPlayers( iface, DPID_SYSTEM_GROUP, instance, enumplayercb,
2798 context, flags );
2799}
2800
2801/* This function should call the registered callback function that the user
2802 passed into EnumSessions for each entry available.
2805 ( LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2,
2806 LPVOID lpNSInfo,
2807 DWORD *timeout,
2808 LPVOID lpContext,
2809 BOOL ansi )
2810{
2811 LPDPSESSIONDESC2 lpSessionDesc;
2812
2813 FIXME( ": not checking for conditions\n" );
2814
2815 /* Enumerate all sessions */
2816 /* FIXME: Need to indicate ANSI */
2817 while( (lpSessionDesc = NS_WalkSessions( lpNSInfo, NULL, ansi ) ) != NULL )
2818 {
2819 TRACE( "EnumSessionsCallback2 invoked\n" );
2820 if( !lpEnumSessionsCallback2( lpSessionDesc, timeout, 0, lpContext ) )
2821 return FALSE;
2822 }
2823
2824 /* Invoke one last time to indicate that there is no more to come */
2825 return lpEnumSessionsCallback2( NULL, timeout, DPESC_TIMEDOUT, lpContext );
2826}
2829{
2831 HANDLE hSuicideRequest = data->hSuicideRequest;
2832 DWORD dwTimeout = data->dwTimeout;
2833
2834 TRACE( "Thread started with timeout = 0x%08lx\n", dwTimeout );
2835
2836 for( ;; )
2837 {
2838 HRESULT hr;
2839
2840 /* Sleep up to dwTimeout waiting for request to terminate thread */
2841 if( WaitForSingleObject( hSuicideRequest, dwTimeout ) == WAIT_OBJECT_0 )
2842 {
2843 TRACE( "Thread terminating on terminate request\n" );
2844 break;
2845 }
2846
2847 /* Now resend the enum request */
2848 hr = NS_SendSessionRequestBroadcast( &data->requestGuid,
2849 data->dwEnumSessionFlags,
2850 data->password,
2851 data->lpSpData );
2852
2853 if( FAILED(hr) )
2854 {
2855 ERR( "Enum broadcase request failed: %s\n", DPLAYX_HresultToString(hr) );
2856 /* FIXME: Should we kill this thread? How to inform the main thread? */
2857 }
2858
2859 }
2860
2861 TRACE( "Thread terminating\n" );
2862
2863 /* Clean up the thread data */
2864 CloseHandle( hSuicideRequest );
2865 free( data->password );
2866 free( lpContext );
2867
2868 /* FIXME: Need to have some notification to main app thread that this is
2869 * dead. It would serve two purposes. 1) allow sync on termination
2870 * so that we don't actually send something to ourselves when we
2871 * become name server (race condition) and 2) so that if we die
2872 * abnormally something else will be able to tell.
2873 */
2874
2875 return 1;
2876}
2879{
2880 /* Does a thread exist? If so we were doing an async enum session */
2881 if( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
2882 {
2883 TRACE( "Killing EnumSession thread %p\n",
2884 This->dp2->hEnumSessionThread );
2885
2886 /* Request that the thread kill itself nicely */
2887 SetEvent( This->dp2->hKillEnumSessionThreadEvent );
2888 CloseHandle( This->dp2->hKillEnumSessionThreadEvent );
2889
2890 /* We no longer need to know about the thread */
2891 CloseHandle( This->dp2->hEnumSessionThread );
2892
2893 This->dp2->hEnumSessionThread = INVALID_HANDLE_VALUE;
2894 }
2895}
2898 DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags )
2899{
2901 return IDirectPlayX_EnumSessions( &This->IDirectPlay4A_iface, sdesc, timeout, enumsessioncb,
2902 context, flags );
2903}
2905static HRESULT WINAPI IDirectPlay2Impl_EnumSessions( IDirectPlay2 *iface, DPSESSIONDESC2 *sdesc,
2906 DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags )
2907{
2909 return IDirectPlayX_EnumSessions( &This->IDirectPlay4_iface, sdesc, timeout, enumsessioncb,
2910 context, flags );
2911}
2914 DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags )
2915{
2917 return IDirectPlayX_EnumSessions( &This->IDirectPlay4A_iface, sdesc, timeout, enumsessioncb,
2918 context, flags );
2919}
2921static HRESULT WINAPI IDirectPlay3Impl_EnumSessions( IDirectPlay3 *iface, DPSESSIONDESC2 *sdesc,
2922 DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags )
2923{
2925 return IDirectPlayX_EnumSessions( &This->IDirectPlay4_iface, sdesc, timeout, enumsessioncb,
2926 context, flags );
2927}
2931 BOOL ansi )
2932{
2934 WCHAR *password = NULL;
2935 DWORD defaultTimeout;
2936 void *connection;
2937 DPCAPS caps;
2938 DWORD size;
2939 HRESULT hr;
2940 DWORD tid;
2941
2942 TRACE( "(%p)->(%p,0x%08lx,%p,%p,0x%08lx)\n", This, sdesc, timeout, enumsessioncb,
2943 context, flags );
2944
2945 if ( This->dp2->connectionInitialized == NO_PROVIDER )
2946 return DPERR_UNINITIALIZED;
2947
2948 if ( !sdesc )
2949 return DPERR_INVALIDPARAM;
2950
2951 if ( sdesc->dwSize != sizeof( DPSESSIONDESC2 ) )
2952 return DPERR_INVALIDPARAM;
2953
2954 /* Can't enumerate if the interface is already open */
2955 EnterCriticalSection( &This->lock );
2956 if ( This->dp2->bConnectionOpen )
2957 {
2958 LeaveCriticalSection( &This->lock );
2959 return DPERR_GENERIC;
2960 }
2961 LeaveCriticalSection( &This->lock );
2962
2963 /* The loading of a lobby provider _seems_ to require a backdoor loading
2964 * of the service provider to also associate with this DP object. This is
2965 * because the app doesn't seem to have to call EnumConnections and
2966 * InitializeConnection for the SP before calling this method. As such
2967 * we'll do their dirty work for them with a quick hack so as to always
2968 * load the TCP/IP service provider.
2969 *
2970 * The correct solution would seem to involve creating a dialog box which
2971 * contains the possible SPs. These dialog boxes most likely follow SDK
2972 * examples.
2973 */
2974 if ( This->dp2->bDPLSPInitialized && !This->dp2->bSPInitialized )
2975 {
2976 WARN( "Hack providing TCP/IP SP for lobby provider activated\n" );
2977
2978 if ( !DP_BuildSPCompoundAddr( (GUID*)&DPSPGUID_TCPIP, &connection, &size ) )
2979 {
2980 ERR( "Can't build compound addr\n" );
2981 return DPERR_GENERIC;
2982 }
2983
2984 hr = IDirectPlayX_InitializeConnection( &This->IDirectPlay4_iface, connection, 0 );
2985 if ( FAILED(hr) )
2986 return hr;
2987
2988 free( connection );
2989 This->dp2->bSPInitialized = TRUE;
2990 }
2991
2992 caps.dwSize = sizeof( caps );
2993 IDirectPlayX_GetCaps( &This->IDirectPlay4_iface, &caps, 0 );
2994 defaultTimeout = caps.dwTimeout;
2995 if ( !defaultTimeout )
2996 defaultTimeout = DPMSG_WAIT_5_SECS; /* Provide the TCP/IP default */
2997
2999 {
3001 return DP_OK;
3002 }
3003
3005 if ( !password && sdesc->lpszPassword )
3006 return DPERR_OUTOFMEMORY;
3007
3008 for ( ;; )
3009 {
3010 if ( !(flags & DPENUMSESSIONS_ASYNC) )
3011 {
3012 EnterCriticalSection( &This->lock );
3013
3014 /* Invalidate the session cache for the interface */
3015 NS_InvalidateSessionCache( This->dp2->lpNameServerData );
3016
3017 LeaveCriticalSection( &This->lock );
3018
3019 /* Send the broadcast for session enumeration */
3021 &This->dp2->spData );
3022 if ( FAILED( hr ) )
3023 {
3024 free( password );
3025 return hr;
3026 }
3027 SleepEx( timeout ? timeout : defaultTimeout, FALSE );
3028 }
3029
3030 EnterCriticalSection( &This->lock );
3031
3032 NS_PruneSessionCache( This->dp2->lpNameServerData );
3033 NS_ResetSessionEnumeration( This->dp2->lpNameServerData );
3034
3035 LeaveCriticalSection( &This->lock );
3036
3037 if ( !DP_InvokeEnumSessionCallbacks( enumsessioncb, This->dp2->lpNameServerData, &timeout,
3038 context, ansi ) )
3039 break;
3040 }
3041
3042 if ( !(flags & DPENUMSESSIONS_ASYNC) )
3043 {
3044 free( password );
3045 return DP_OK;
3046 }
3047
3048 /* Async enumeration */
3049
3050 if ( This->dp2->dwEnumSessionLock )
3051 {
3052 free( password );
3053 return DPERR_CONNECTING;
3054 }
3055
3056 /* See if we've already created a thread to service this interface */
3057 if ( This->dp2->hEnumSessionThread != INVALID_HANDLE_VALUE )
3058 {
3059 free( password );
3060 return DP_OK;
3061 }
3062
3063 This->dp2->dwEnumSessionLock++;
3064
3065 /* Send the first enum request inline since the user may cancel a dialog
3066 * if one is presented. Also, may also have a connecting return code.
3067 */
3069 &This->dp2->spData );
3070 if ( FAILED( hr ) )
3071 {
3072 This->dp2->dwEnumSessionLock--;
3073 free( password );
3074 return hr;
3075 }
3076
3077 data = calloc( 1, sizeof( *data ) );
3078 /* FIXME: need to kill the thread on object deletion */
3079 data->lpSpData = &This->dp2->spData;
3080 data->requestGuid = sdesc->guidApplication;
3081 data->dwEnumSessionFlags = flags;
3082 data->dwTimeout = timeout ? timeout : defaultTimeout;
3083 data->password = password;
3084
3085 This->dp2->hKillEnumSessionThreadEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
3086 if ( !DuplicateHandle( GetCurrentProcess(), This->dp2->hKillEnumSessionThreadEvent,
3087 GetCurrentProcess(), &data->hSuicideRequest, 0, FALSE,
3089 ERR( "Can't duplicate thread killing handle\n" );
3090
3091 TRACE( ": creating EnumSessionsRequest thread\n" );
3092 This->dp2->hEnumSessionThread = CreateThread( NULL, 0, DP_EnumSessionsSendAsyncRequestThread,
3093 data, 0, &tid );
3094 if ( !This->dp2->hEnumSessionThread )
3095 free( password );
3096
3097 This->dp2->dwEnumSessionLock--;
3098
3099 return DP_OK;
3100}
3103 DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags )
3104{
3106 return DP_IF_EnumSessions( This, sdesc, timeout, enumsessioncb, context, flags, TRUE );
3107}
3109static HRESULT WINAPI IDirectPlay4Impl_EnumSessions( IDirectPlay4 *iface, DPSESSIONDESC2 *sdesc,
3110 DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags )
3111{
3113 return DP_IF_EnumSessions( This, sdesc, timeout, enumsessioncb, context, flags, FALSE );
3114}
3117{
3119 return IDirectPlayX_GetCaps( &This->IDirectPlay4A_iface, caps, flags );
3120}
3122static HRESULT WINAPI IDirectPlay2Impl_GetCaps( IDirectPlay2 *iface, DPCAPS *caps, DWORD flags )
3123{
3125 return IDirectPlayX_GetCaps( &This->IDirectPlay4_iface, caps, flags );
3126}
3129{
3131 return IDirectPlayX_GetCaps( &This->IDirectPlay4A_iface, caps, flags );
3132}
3134static HRESULT WINAPI IDirectPlay3Impl_GetCaps( IDirectPlay3 *iface, DPCAPS *caps, DWORD flags )
3135{
3137 return IDirectPlayX_GetCaps( &This->IDirectPlay4_iface, caps, flags );
3138}
3141{
3142 return IDirectPlayX_GetPlayerCaps( iface, DPID_ALLPLAYERS, caps, flags );
3143}
3145static HRESULT WINAPI IDirectPlay4Impl_GetCaps( IDirectPlay4 *iface, DPCAPS *caps, DWORD flags )
3146{
3147 return IDirectPlayX_GetPlayerCaps( iface, DPID_ALLPLAYERS, caps, flags );
3148}
3151 DWORD *size, DWORD flags )
3152{
3154 return IDirectPlayX_GetGroupData( &This->IDirectPlay4A_iface, group, data, size, flags );
3155}
3157static HRESULT WINAPI IDirectPlay2Impl_GetGroupData( IDirectPlay2 *iface, DPID group, void *data,
3158 DWORD *size, DWORD flags )
3159{
3161 return IDirectPlayX_GetGroupData( &This->IDirectPlay4_iface, group, data, size, flags );
3162}
3165 DWORD *size, DWORD flags )
3166{
3168 return IDirectPlayX_GetGroupData( &This->IDirectPlay4A_iface, group, data, size, flags );
3169}
3171static HRESULT WINAPI IDirectPlay3Impl_GetGroupData( IDirectPlay3 *iface, DPID group, void *data,
3172 DWORD *size, DWORD flags )
3173{
3175 return IDirectPlayX_GetGroupData( &This->IDirectPlay4_iface, group, data, size, flags );
3176}
3179 void *data, DWORD *size, DWORD flags )
3180{
3182 return IDirectPlayX_GetGroupData( &This->IDirectPlay4_iface, group, data, size, flags );
3183}
3185static HRESULT WINAPI IDirectPlay4Impl_GetGroupData( IDirectPlay4 *iface, DPID group,
3186 void *data, DWORD *size, DWORD flags )
3187{
3189 lpGroupData gdata;
3190 DWORD bufsize;
3191 void *src;
3192
3193 TRACE( "(%p)->(0x%08lx,%p,%p,0x%08lx)\n", This, group, data, size, flags );
3194
3195 EnterCriticalSection( &This->lock );
3196
3197 if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL )
3198 {
3199 LeaveCriticalSection( &This->lock );
3200 return DPERR_INVALIDGROUP;
3201 }
3202
3203 /* How much buffer is required? */
3204 if ( flags & DPSET_LOCAL )
3205 {
3206 bufsize = gdata->dwLocalDataSize;
3207 src = gdata->lpLocalData;
3208 }
3209 else
3210 {
3211 bufsize = gdata->dwRemoteDataSize;
3212 src = gdata->lpRemoteData;
3213 }
3214
3215 *size = bufsize;
3216
3217 /* Is the user requesting to know how big a buffer is required? */
3218 if ( !data || *size < bufsize )
3219 {
3220 LeaveCriticalSection( &This->lock );
3221 return DPERR_BUFFERTOOSMALL;
3222 }
3223
3225
3226 LeaveCriticalSection( &This->lock );
3227
3228 return DP_OK;
3229}
3231static HRESULT DP_IF_GetGroupName( IDirectPlayImpl *This, DPID idGroup, void *lpData,
3232 DWORD *lpdwDataSize, BOOL bAnsi )
3233{
3234 lpGroupData lpGData;
3235 DWORD dwRequiredDataSize;
3236
3237 FIXME("(%p)->(0x%08lx,%p,%p,%u) ANSI ignored\n",
3238 This, idGroup, lpData, lpdwDataSize, bAnsi );
3239
3240 EnterCriticalSection( &This->lock );
3241
3242 if( ( lpGData = DP_FindAnyGroup( This, idGroup ) ) == NULL )
3243 {
3244 LeaveCriticalSection( &This->lock );
3245 return DPERR_INVALIDGROUP;
3246 }
3247
3248 dwRequiredDataSize = DP_CopyName( NULL, bAnsi ? lpGData->nameA : lpGData->name, bAnsi, bAnsi );
3249
3250 if( ( lpData == NULL ) ||
3251 ( *lpdwDataSize < dwRequiredDataSize )
3252 )
3253 {
3254 *lpdwDataSize = dwRequiredDataSize;
3255 LeaveCriticalSection( &This->lock );
3256 return DPERR_BUFFERTOOSMALL;
3257 }
3258
3259 DP_CopyName( lpData, bAnsi ? lpGData->nameA : lpGData->name, bAnsi, bAnsi );
3260
3261 LeaveCriticalSection( &This->lock );
3262
3263 return DP_OK;
3264}
3267 DWORD *size )
3268{
3270 return IDirectPlayX_GetGroupName( &This->IDirectPlay4A_iface, group, data, size );
3271}
3273static HRESULT WINAPI IDirectPlay2Impl_GetGroupName( IDirectPlay2 *iface, DPID group, void *data,
3274 DWORD *size )
3275{
3277 return IDirectPlayX_GetGroupName( &This->IDirectPlay4_iface, group, data, size );
3278}
3281 DWORD *size )
3282{
3284 return IDirectPlayX_GetGroupName( &This->IDirectPlay4A_iface, group, data, size );
3285}
3287static HRESULT WINAPI IDirectPlay3Impl_GetGroupName( IDirectPlay3 *iface, DPID group, void *data,
3288 DWORD *size )
3289{
3291 return IDirectPlayX_GetGroupName( &This->IDirectPlay4_iface, group, data, size );
3292}
3295 void *lpData, DWORD *lpdwDataSize )
3296{
3298 return DP_IF_GetGroupName( This, idGroup, lpData, lpdwDataSize, TRUE );
3299}
3301static HRESULT WINAPI IDirectPlay4Impl_GetGroupName( IDirectPlay4 *iface, DPID idGroup,
3302 void *lpData, DWORD *lpdwDataSize )
3303{
3305 return DP_IF_GetGroupName( This, idGroup, lpData, lpdwDataSize, FALSE );
3306}
3309 DWORD *count )
3310{
3312 return IDirectPlayX_GetMessageCount( &This->IDirectPlay4A_iface, player, count );
3313}
3315static HRESULT WINAPI IDirectPlay2Impl_GetMessageCount( IDirectPlay2 *iface, DPID player,
3316 DWORD *count )
3317{
3319 return IDirectPlayX_GetMessageCount( &This->IDirectPlay4_iface, player, count );
3320}
3323 DWORD *count )
3324{
3326 return IDirectPlayX_GetMessageCount( &This->IDirectPlay4A_iface, player, count );
3327}
3329static HRESULT WINAPI IDirectPlay3Impl_GetMessageCount( IDirectPlay3 *iface, DPID player,
3330 DWORD *count )
3331{
3333 return IDirectPlayX_GetMessageCount( &This->IDirectPlay4_iface, player, count );
3334}
3337 DWORD *count )
3338{
3339 return IDirectPlayX_GetMessageQueue( iface, 0, player, DPMESSAGEQUEUE_RECEIVE, count, NULL );
3340}
3342static HRESULT WINAPI IDirectPlay4Impl_GetMessageCount( IDirectPlay4 *iface, DPID player,
3343 DWORD *count )
3344{
3345 return IDirectPlayX_GetMessageQueue( iface, 0, player, DPMESSAGEQUEUE_RECEIVE, count, NULL );
3346}
3349 void *data, DWORD *size )
3350{
3352 return IDirectPlayX_GetPlayerAddress( &This->IDirectPlay4A_iface, player, data, size );
3353}
3355static HRESULT WINAPI IDirectPlay2Impl_GetPlayerAddress( IDirectPlay2 *iface, DPID player,
3356 void *data, DWORD *size )
3357{
3359 return IDirectPlayX_GetPlayerAddress( &This->IDirectPlay4_iface, player, data, size );
3360}
3363 void *data, DWORD *size )
3364{
3366 return IDirectPlayX_GetPlayerAddress( &This->IDirectPlay4A_iface, player, data, size );
3367}
3369static HRESULT WINAPI IDirectPlay3Impl_GetPlayerAddress( IDirectPlay3 *iface, DPID player,
3370 void *data, DWORD *size )
3371{
3373 return IDirectPlayX_GetPlayerAddress( &This->IDirectPlay4_iface, player, data, size );
3374}
3377 void *data, DWORD *size )
3378{
3380 FIXME("(%p)->(0x%08lx,%p,%p): stub\n", This, player, data, size );
3381 return DP_OK;
3382}
3384static HRESULT WINAPI IDirectPlay4Impl_GetPlayerAddress( IDirectPlay4 *iface, DPID player,
3385 void *data, DWORD *size )
3386{
3388 FIXME( "(%p)->(0x%08lx,%p,%p): stub\n", This, player, data, size );
3389 return DP_OK;
3390}
3393 DPCAPS *caps, DWORD flags )
3394{
3396 return IDirectPlayX_GetPlayerCaps( &This->IDirectPlay4A_iface, player, caps, flags );
3397}
3399static HRESULT WINAPI IDirectPlay2Impl_GetPlayerCaps( IDirectPlay2 *iface, DPID player,
3400 DPCAPS *caps, DWORD flags )
3401{
3403 return IDirectPlayX_GetPlayerCaps( &This->IDirectPlay4_iface, player, caps, flags );
3404}
3407 DPCAPS *caps, DWORD flags )
3408{
3410 return IDirectPlayX_GetPlayerCaps( &This->IDirectPlay4A_iface, player, caps, flags );
3411}
3413static HRESULT WINAPI IDirectPlay3Impl_GetPlayerCaps( IDirectPlay3 *iface, DPID player,
3414 DPCAPS *caps, DWORD flags )
3415{
3417 return IDirectPlayX_GetPlayerCaps( &This->IDirectPlay4_iface, player, caps, flags );
3418}
3421 DPCAPS *caps, DWORD flags )
3422{
3424 return IDirectPlayX_GetPlayerCaps( &This->IDirectPlay4_iface, player, caps, flags );
3425}
3427static HRESULT WINAPI IDirectPlay4Impl_GetPlayerCaps( IDirectPlay4 *iface, DPID player,
3428 DPCAPS *caps, DWORD flags )
3429{
3432
3433 TRACE( "(%p)->(0x%08lx,%p,0x%08lx)\n", This, player, caps, flags);
3434
3435 if ( !caps )
3436 return DPERR_INVALIDPARAMS;
3437
3438 if ( This->dp2->connectionInitialized == NO_PROVIDER )
3439 return DPERR_UNINITIALIZED;
3440
3441 if( caps->dwSize != sizeof(DPCAPS) )
3442 return DPERR_INVALIDPARAMS;
3443
3444 /* Query the service provider */
3445 data.idPlayer = player;
3446 data.dwFlags = flags;
3447 data.lpCaps = caps;
3448 data.lpISP = This->dp2->spData.lpISP;
3449
3450 return (*This->dp2->spData.lpCB->GetCaps)( &data );
3451}
3454 void *data, DWORD *size, DWORD flags )
3455{
3457 return IDirectPlayX_GetPlayerData( &This->IDirectPlay4A_iface, player, data, size, flags );
3458}
3460static HRESULT WINAPI IDirectPlay2Impl_GetPlayerData( IDirectPlay2 *iface, DPID player,
3461 void *data, DWORD *size, DWORD flags )
3462{
3464 return IDirectPlayX_GetPlayerData( &This->IDirectPlay4_iface, player, data, size, flags );
3465}
3468 void *data, DWORD *size, DWORD flags )
3469{
3471 return IDirectPlayX_GetPlayerData( &This->IDirectPlay4A_iface, player, data, size, flags );
3472}
3474static HRESULT WINAPI IDirectPlay3Impl_GetPlayerData( IDirectPlay3 *iface, DPID player,
3475 void *data, DWORD *size, DWORD flags )
3476{
3478 return IDirectPlayX_GetPlayerData( &This->IDirectPlay4_iface, player, data, size, flags );
3479}
3482 void *data, DWORD *size, DWORD flags )
3483{
3485 return IDirectPlayX_GetPlayerData( &This->IDirectPlay4_iface, player, data, size, flags );
3486}
3488static HRESULT WINAPI IDirectPlay4Impl_GetPlayerData( IDirectPlay4 *iface, DPID player,
3489 void *data, DWORD *size, DWORD flags )
3490{
3493 DWORD bufsize;
3494 void *src;
3495
3496 TRACE( "(%p)->(0x%08lx,%p,%p,0x%08lx)\n", This, player, data, size, flags );
3497
3498 if ( This->dp2->connectionInitialized == NO_PROVIDER )
3499 return DPERR_UNINITIALIZED;
3500
3501 EnterCriticalSection( &This->lock );
3502
3503 if ( ( plist = DP_FindPlayer( This, player ) ) == NULL )
3504 {
3505 LeaveCriticalSection( &This->lock );
3506 return DPERR_INVALIDPLAYER;
3507 }
3508
3509 if ( flags & DPSET_LOCAL )
3510 {
3511 bufsize = plist->lpPData->dwLocalDataSize;
3512 src = plist->lpPData->lpLocalData;
3513 }
3514 else
3515 {
3516 bufsize = plist->lpPData->dwRemoteDataSize;
3517 src = plist->lpPData->lpRemoteData;
3518 }
3519
3520 *size = bufsize;
3521
3522 /* Is the user requesting to know how big a buffer is required? */
3523 if ( !data || *size < bufsize )
3524 {
3525 LeaveCriticalSection( &This->lock );
3526 return DPERR_BUFFERTOOSMALL;
3527 }
3528
3530
3531 LeaveCriticalSection( &This->lock );
3532
3533 return DP_OK;
3534}
3536static HRESULT DP_IF_GetPlayerName( IDirectPlayImpl *This, DPID idPlayer, void *lpData,
3537 DWORD *lpdwDataSize, BOOL bAnsi )
3538{
3539 lpPlayerList lpPList;
3540 DWORD dwRequiredDataSize;
3541
3542 FIXME( "(%p)->(0x%08lx,%p,%p,%u): ANSI\n",
3543 This, idPlayer, lpData, lpdwDataSize, bAnsi );
3544
3545 if( This->dp2->connectionInitialized == NO_PROVIDER )
3546 {
3547 return DPERR_UNINITIALIZED;
3548 }
3549
3550 EnterCriticalSection( &This->lock );
3551
3552 if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
3553 {
3554 LeaveCriticalSection( &This->lock );
3555 return DPERR_INVALIDPLAYER;
3556 }
3557
3558 dwRequiredDataSize = DP_CopyName( NULL, bAnsi ? lpPList->lpPData->nameA : lpPList->lpPData->name,
3559 bAnsi, bAnsi );
3560
3561 if( ( lpData == NULL ) ||
3562 ( *lpdwDataSize < dwRequiredDataSize )
3563 )
3564 {
3565 *lpdwDataSize = dwRequiredDataSize;
3566 LeaveCriticalSection( &This->lock );
3567 return DPERR_BUFFERTOOSMALL;
3568 }
3569
3570 DP_CopyName( lpData, bAnsi ? lpPList->lpPData->nameA : lpPList->lpPData->name, bAnsi, bAnsi );
3571
3572 LeaveCriticalSection( &This->lock );
3573
3574 return DP_OK;
3575}
3578 void *data, DWORD *size )
3579{
3581 return IDirectPlayX_GetPlayerName( &This->IDirectPlay4A_iface, player, data, size );
3582}
3584static HRESULT WINAPI IDirectPlay2Impl_GetPlayerName( IDirectPlay2 *iface, DPID player,
3585 void *data, DWORD *size )
3586{
3588 return IDirectPlayX_GetPlayerName( &This->IDirectPlay4_iface, player, data, size );
3589}
3592 void *data, DWORD *size )
3593{
3595 return IDirectPlayX_GetPlayerName( &This->IDirectPlay4A_iface, player, data, size );
3596}
3598static HRESULT WINAPI IDirectPlay3Impl_GetPlayerName( IDirectPlay3 *iface, DPID player,
3599 void *data, DWORD *size )
3600{
3602 return IDirectPlayX_GetPlayerName( &This->IDirectPlay4_iface, player, data, size );
3603}
3606 void *lpData, DWORD *lpdwDataSize )
3607{
3609 return DP_IF_GetPlayerName( This, idPlayer, lpData, lpdwDataSize, TRUE );
3610}
3612static HRESULT WINAPI IDirectPlay4Impl_GetPlayerName( IDirectPlay4 *iface, DPID idPlayer,
3613 void *lpData, DWORD *lpdwDataSize )
3614{
3616 return DP_IF_GetPlayerName( This, idPlayer, lpData, lpdwDataSize, FALSE );
3617}
3619static HRESULT DP_GetSessionDesc( IDirectPlayImpl *This, void *lpData, DWORD *lpdwDataSize,
3620 BOOL bAnsi )
3621{
3622 DWORD dwRequiredSize;
3623
3624 TRACE( "(%p)->(%p,%p,%u)\n", This, lpData, lpdwDataSize, bAnsi );
3625
3626 if( This->dp2->connectionInitialized == NO_PROVIDER )
3627 {
3628 return DPERR_UNINITIALIZED;
3629 }
3630
3631 if( ( lpData == NULL ) && ( lpdwDataSize == NULL ) )
3632 {
3633 return DPERR_INVALIDPARAMS;
3634 }
3635
3636 EnterCriticalSection( &This->lock );
3637
3638 dwRequiredSize = DP_CopySessionDesc( NULL, This->dp2->lpSessionDesc, bAnsi, bAnsi );
3639
3640 if ( ( lpData == NULL ) ||
3641 ( *lpdwDataSize < dwRequiredSize )
3642 )
3643 {
3644 *lpdwDataSize = dwRequiredSize;
3645 LeaveCriticalSection( &This->lock );
3646 return DPERR_BUFFERTOOSMALL;
3647 }
3648
3649 DP_CopySessionDesc( lpData, This->dp2->lpSessionDesc, bAnsi, bAnsi );
3650
3651 LeaveCriticalSection( &This->lock );
3652
3653 return DP_OK;
3654}
3657 DWORD *size )
3658{
3660 return IDirectPlayX_GetSessionDesc( &This->IDirectPlay4A_iface, data, size );
3661}
3663static HRESULT WINAPI IDirectPlay2Impl_GetSessionDesc( IDirectPlay2 *iface, void *data,
3664 DWORD *size )
3665{
3667 return IDirectPlayX_GetSessionDesc( &This->IDirectPlay4_iface, data, size );
3668}
3671 DWORD *size )
3672{
3674 return IDirectPlayX_GetSessionDesc( &This->IDirectPlay4A_iface, data, size );
3675}
3677static HRESULT WINAPI IDirectPlay3Impl_GetSessionDesc( IDirectPlay3 *iface, void *data,
3678 DWORD *size )
3679{
3681 return IDirectPlayX_GetSessionDesc( &This->IDirectPlay4_iface, data, size );
3682}
3685 DWORD *lpdwDataSize )
3686{
3688 return DP_GetSessionDesc( This, lpData, lpdwDataSize, TRUE );
3689}
3691static HRESULT WINAPI IDirectPlay4Impl_GetSessionDesc( IDirectPlay4 *iface, void *lpData,
3692 DWORD *lpdwDataSize )
3693{
3695 return DP_GetSessionDesc( This, lpData, lpdwDataSize, TRUE );
3696}
3699{
3701 return IDirectPlayX_Initialize( &This->IDirectPlay4A_iface, guid );
3702}
3704static HRESULT WINAPI IDirectPlay2Impl_Initialize( IDirectPlay2 *iface, GUID *guid )
3705{
3707 return IDirectPlayX_Initialize( &This->IDirectPlay4_iface, guid );
3708}
3711{
3713 return IDirectPlayX_Initialize( &This->IDirectPlay4A_iface, guid );
3714}
3716static HRESULT WINAPI IDirectPlay3Impl_Initialize( IDirectPlay3 *iface, GUID *guid )
3717{
3719 return IDirectPlayX_Initialize( &This->IDirectPlay4_iface, guid );
3720}
3721
3722/* Intended only for COM compatibility. Always returns an error. */
3724{
3726 TRACE("(%p)->(%p): no-op\n", This, guid );
3728}
3730static HRESULT WINAPI IDirectPlay4Impl_Initialize( IDirectPlay4 *iface, GUID *guid )
3731{
3733 TRACE( "(%p)->(%p): no-op\n", This, guid );
3735}
3736
3739 const DPSECURITYDESC *lpSecurity, const DPCREDENTIALS *lpCredentials, BOOL bAnsi )
3740{
3741 void *spMessageHeader = NULL;
3742 HRESULT hr;
3743
3744 FIXME( "(%p)->(%p,0x%08lx,%p,%p): partial stub\n",
3745 This, lpsd, dwFlags, lpSecurity, lpCredentials );
3746
3747 if( lpsd->dwSize != sizeof(DPSESSIONDESC2) )
3748 {
3749 TRACE( ": rejecting invalid dpsd size (%ld).\n", lpsd->dwSize );
3750 return DPERR_INVALIDPARAMS;
3751 }
3752
3753 if( This->dp2->connectionInitialized == NO_PROVIDER )
3754 {
3755 return DPERR_UNINITIALIZED;
3756 }
3757
3758 EnterCriticalSection( &This->lock );
3759 if( This->dp2->bConnectionOpen )
3760 {
3761 TRACE( ": rejecting already open connection.\n" );
3762 LeaveCriticalSection( &This->lock );
3764 }
3765 LeaveCriticalSection( &This->lock );
3766
3767 /* If we're enumerating, kill the thread */
3769
3770 if( dwFlags & DPOPEN_CREATE )
3771 {
3772 /* Rightoo - this computer is the host and the local computer needs to be
3773 the name server so that others can join this session */
3774 NS_SetLocalComputerAsNameServer( lpsd, This->dp2->lpNameServerData );
3775
3776 This->dp2->bHostInterface = TRUE;
3777
3778 hr = DP_SetSessionDesc( This, lpsd, 0, TRUE, bAnsi );
3779 if( FAILED( hr ) )
3780 {
3781 ERR( "Unable to set session desc: %s\n", DPLAYX_HresultToString( hr ) );
3782 return hr;
3783 }
3784 }
3785 else
3786 {
3787 DPSESSIONDESC2 *sessionDesc;
3788
3789 EnterCriticalSection( &This->lock );
3790
3791 NS_ResetSessionEnumeration( This->dp2->lpNameServerData );
3792
3793 LeaveCriticalSection( &This->lock );
3794
3795 for ( ;; )
3796 {
3797 sessionDesc = NS_WalkSessions( This->dp2->lpNameServerData, &spMessageHeader, bAnsi );
3798 if ( !sessionDesc )
3799 return DPERR_NOSESSIONS;
3800 if ( IsEqualGUID( &sessionDesc->guidInstance, &lpsd->guidInstance ) )
3801 break;
3802 }
3803
3804 /* No need to enter the critical section here as the messaging thread won't access the data
3805 * while bConnectionOpen is FALSE. */
3806
3807 free( This->dp2->lpSessionDesc );
3808 This->dp2->lpSessionDesc = DP_DuplicateSessionDesc( sessionDesc, bAnsi, bAnsi );
3809 if ( !This->dp2->lpSessionDesc )
3810 return DPERR_OUTOFMEMORY;
3811 }
3812
3813 /* Invoke the conditional callback for the service provider */
3814 if( This->dp2->spData.lpCB->Open )
3815 {
3817
3818 FIXME( "Not all data fields are correct. Need new parameter\n" );
3819
3820 data.bCreate = (dwFlags & DPOPEN_CREATE ) != 0;
3821 data.lpSPMessageHeader = spMessageHeader;
3822 data.lpISP = This->dp2->spData.lpISP;
3823 data.bReturnStatus = (dwFlags & DPOPEN_RETURNSTATUS) != 0;
3824 data.dwOpenFlags = dwFlags;
3825 data.dwSessionFlags = This->dp2->lpSessionDesc->dwFlags;
3826
3827 hr = (*This->dp2->spData.lpCB->Open)(&data);
3828 if( FAILED( hr ) )
3829 {
3830 ERR( "Unable to open session: %s\n", DPLAYX_HresultToString( hr ) );
3831 return hr;
3832 }
3833 }
3834
3835 {
3836 /* Create the system group of which everything is a part of */
3837 DPID systemGroup = DPID_SYSTEM_GROUP;
3838
3839 hr = DP_IF_CreateGroup( This, NULL, &systemGroup, NULL,
3840 NULL, 0, 0, TRUE );
3841 if ( FAILED( hr ) )
3842 {
3843 if( This->dp2->spData.lpCB->CloseEx )
3844 {
3846 data.lpISP = This->dp2->spData.lpISP;
3847 (*This->dp2->spData.lpCB->CloseEx)( &data );
3848 }
3849 return hr;
3850 }
3851 }
3852
3853 if( dwFlags & DPOPEN_JOIN )
3854 {
3856 WCHAR *password;
3857
3858 password = DP_DuplicateString( lpsd->lpszPassword, FALSE, bAnsi );
3859 if ( !password && lpsd->lpszPassword )
3860 {
3862 if( This->dp2->spData.lpCB->CloseEx )
3863 {
3865 data.lpISP = This->dp2->spData.lpISP;
3866 (*This->dp2->spData.lpCB->CloseEx)( &data );
3867 }
3868 return DPERR_OUTOFMEMORY;
3869 }
3870
3871 /* Create the server player for this interface. This way we can receive
3872 * messages for this session.
3873 */
3874 /* FIXME: I suppose that we should be setting an event for a receive
3875 * type of thing. That way the messaging thread could know to wake
3876 * up. DPlay would then trigger the hEvent for the player the
3877 * message is directed to.
3878 */
3879 hr = DP_MSG_SendRequestPlayerId( This, createFlags, &This->dp2->systemPlayerId );
3880 if( FAILED( hr ) )
3881 {
3882 ERR( "Request for ID failed: %s\n", DPLAYX_HresultToString( hr ) );
3883 free( password );
3885 if( This->dp2->spData.lpCB->CloseEx )
3886 {
3888 data.lpISP = This->dp2->spData.lpISP;
3889 (*This->dp2->spData.lpCB->CloseEx)( &data );
3890 }
3891 return hr;
3892 }
3893
3894 /* No need to enter the critical section here as the messaging thread won't access the data
3895 * while bConnectionOpen is FALSE. */
3896
3897 hr = DP_CreatePlayer( This, NULL, &This->dp2->systemPlayerId, NULL, NULL, 0, NULL, 0,
3898 createFlags, NULL, NULL, bAnsi );
3899 if( FAILED( hr ) )
3900 {
3901 free( password );
3903 if( This->dp2->spData.lpCB->CloseEx )
3904 {
3906 data.lpISP = This->dp2->spData.lpISP;
3907 (*This->dp2->spData.lpCB->CloseEx)( &data );
3908 }
3909 return hr;
3910 }
3911
3912 hr = DP_MSG_ForwardPlayerCreation( This, This->dp2->systemPlayerId, password );
3913 free( password );
3914 if( FAILED( hr ) )
3915 {
3916 DP_DeletePlayer( This, This->dp2->systemPlayerId );
3918 if( This->dp2->spData.lpCB->CloseEx )
3919 {
3921 data.lpISP = This->dp2->spData.lpISP;
3922 (*This->dp2->spData.lpCB->CloseEx)( &data );
3923 }
3924 return hr;
3925 }
3926 }
3927 else if( dwFlags & DPOPEN_CREATE )
3928 {
3930
3931 This->dp2->systemPlayerId = DP_NextObjectId();
3932
3933 hr = DP_CreatePlayer( This, NULL, &This->dp2->systemPlayerId, NULL, NULL, 0, NULL, 0,
3934 createFlags, NULL, NULL, bAnsi );
3935 if( FAILED( hr ) )
3936 {
3938 if( This->dp2->spData.lpCB->CloseEx )
3939 {
3941 data.lpISP = This->dp2->spData.lpISP;
3942 (*This->dp2->spData.lpCB->CloseEx)( &data );
3943 }
3944 return hr;
3945 }
3946 }
3947
3948 EnterCriticalSection( &This->lock );
3949
3950 This->dp2->bConnectionOpen = TRUE;
3951
3952 LeaveCriticalSection( &This->lock );
3953
3954 return DP_OK;
3955}
3958 DWORD flags )
3959{
3961 return IDirectPlayX_Open( &This->IDirectPlay4A_iface, sdesc, flags );
3962}
3964static HRESULT WINAPI IDirectPlay2Impl_Open( IDirectPlay2 *iface, DPSESSIONDESC2 *sdesc,
3965 DWORD flags )
3966{
3968 return IDirectPlayX_Open( &This->IDirectPlay4_iface, sdesc, flags );
3969}
3972 DWORD flags )
3973{
3975 return IDirectPlayX_Open( &This->IDirectPlay4A_iface, sdesc, flags );
3976}
3978static HRESULT WINAPI IDirectPlay3Impl_Open( IDirectPlay3 *iface, DPSESSIONDESC2 *sdesc,
3979 DWORD flags )
3980{
3982 return IDirectPlayX_Open( &This->IDirectPlay4_iface, sdesc, flags );
3983}
3986 DWORD flags )
3987{
3988 return IDirectPlayX_SecureOpen( iface, sdesc, flags, NULL, NULL );
3989}
3991static HRESULT WINAPI IDirectPlay4Impl_Open( IDirectPlay4 *iface, DPSESSIONDESC2 *sdesc,
3992 DWORD flags )
3993{
3994 return IDirectPlayX_SecureOpen( iface, sdesc, flags, NULL, NULL );
3995}
3997static HRESULT DP_IF_Receive( IDirectPlayImpl *This, DPID *lpidFrom, DPID *lpidTo, DWORD dwFlags,
3998 void *lpData, DWORD *lpdwDataSize, BOOL bAnsi )
3999{
4000 LPDPMSG lpMsg = NULL;
4001 DWORD msgSize;
4002
4003 TRACE( "(%p)->(%p,%p,0x%08lx,%p,%p,%u)\n",
4004 This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize, bAnsi );
4005
4006 if( This->dp2->connectionInitialized == NO_PROVIDER )
4007 {
4008 return DPERR_UNINITIALIZED;
4009 }
4010
4011 EnterCriticalSection( &This->lock );
4012
4013 for( lpMsg = DPQ_FIRST( This->dp2->receiveMsgs ); lpMsg; lpMsg = DPQ_NEXT( lpMsg->msgs ) )
4014 {
4015 if( ( dwFlags & DPRECEIVE_TOPLAYER ) && ( lpMsg->toId != *lpidTo ) )
4016 continue;
4017 if( ( dwFlags & DPRECEIVE_FROMPLAYER ) && ( lpMsg->fromId != *lpidFrom ) )
4018 continue;
4019 break;
4020 }
4021
4022 if( lpMsg == NULL )
4023 {
4024 LeaveCriticalSection( &This->lock );
4025 return DPERR_NOMESSAGES;
4026 }
4027
4028 msgSize = lpMsg->copyMessage( NULL, lpMsg->msg, lpMsg->genericSize, bAnsi );
4029
4030 if( *lpdwDataSize < msgSize || !lpData )
4031 {
4032 *lpdwDataSize = msgSize;
4033 LeaveCriticalSection( &This->lock );
4034 return DPERR_BUFFERTOOSMALL;
4035 }
4036
4037 *lpidFrom = lpMsg->fromId;
4038 *lpidTo = lpMsg->toId;
4039 *lpdwDataSize = msgSize;
4040
4041 /* Copy into the provided buffer */
4042 lpMsg->copyMessage( lpData, lpMsg->msg, lpMsg->genericSize, bAnsi );
4043
4044 if( !( dwFlags & DPRECEIVE_PEEK ) )
4045 {
4046 DPQ_REMOVE( This->dp2->receiveMsgs, lpMsg, msgs );
4047 free( lpMsg->msg );
4048 free( lpMsg );
4049 }
4050
4051 LeaveCriticalSection( &This->lock );
4052
4053 return DP_OK;
4054}
4057 DWORD flags, void *data, DWORD *size )
4058{
4060 return IDirectPlayX_Receive( &This->IDirectPlay4A_iface, from, to, flags, data, size );
4061}
4063static HRESULT WINAPI IDirectPlay2Impl_Receive( IDirectPlay2 *iface, DPID *from, DPID *to,
4064 DWORD flags, void *data, DWORD *size )
4065{
4067 return IDirectPlayX_Receive( &This->IDirectPlay4_iface, from, to, flags, data, size );
4068}
4071 DWORD flags, void *data, DWORD *size )
4072{
4074 return IDirectPlayX_Receive( &This->IDirectPlay4A_iface, from, to, flags, data, size );
4075}
4077static HRESULT WINAPI IDirectPlay3Impl_Receive( IDirectPlay3 *iface, DPID *from, DPID *to,
4078 DWORD flags, void *data, DWORD *size )
4079{
4081 return IDirectPlayX_Receive( &This->IDirectPlay4_iface, from, to, flags, data, size );
4082}
4085 DPID *lpidTo, DWORD dwFlags, void *lpData, DWORD *lpdwDataSize )
4086{
4088 return DP_IF_Receive( This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize, TRUE );
4089}
4091static HRESULT WINAPI IDirectPlay4Impl_Receive( IDirectPlay4 *iface, DPID *lpidFrom,
4092 DPID *lpidTo, DWORD dwFlags, void *lpData, DWORD *lpdwDataSize )
4093{
4095 return DP_IF_Receive( This, lpidFrom, lpidTo, dwFlags, lpData, lpdwDataSize, FALSE );
4096}
4099 DWORD flags, void *data, DWORD size )
4100{
4102 return IDirectPlayX_Send( &This->IDirectPlay4A_iface, from, to, flags, data, size );
4103}
4105static HRESULT WINAPI IDirectPlay2Impl_Send( IDirectPlay2 *iface, DPID from, DPID to,
4106 DWORD flags, void *data, DWORD size )
4107{
4109 return IDirectPlayX_Send( &This->IDirectPlay4_iface, from, to, flags, data, size );
4110}
4113 DWORD flags, void *data, DWORD size )
4114{
4116 return IDirectPlayX_Send( &This->IDirectPlay4A_iface, from, to, flags, data, size );
4117}
4119static HRESULT WINAPI IDirectPlay3Impl_Send( IDirectPlay3 *iface, DPID from, DPID to,
4120 DWORD flags, void *data, DWORD size )
4121{
4123 return IDirectPlayX_Send( &This->IDirectPlay4_iface, from, to, flags, data, size );
4124}
4127 DWORD flags, void *data, DWORD size )
4128{
4129 return IDirectPlayX_SendEx( iface, from, to, flags, data, size, 0, 0, NULL, NULL );
4130}
4132static HRESULT WINAPI IDirectPlay4Impl_Send( IDirectPlay4 *iface, DPID from, DPID to,
4133 DWORD flags, void *data, DWORD size )
4134{
4135 return IDirectPlayX_SendEx( iface, from, to, flags, data, size, 0, 0, NULL, NULL );
4136}
4140{
4142 return IDirectPlayX_SetGroupData( &This->IDirectPlay4A_iface, group, data, size, flags );
4143}
4145static HRESULT WINAPI IDirectPlay2Impl_SetGroupData( IDirectPlay2 *iface, DPID group, void *data,
4147{
4149 return IDirectPlayX_SetGroupData( &This->IDirectPlay4_iface, group, data, size, flags );
4150}
4154{
4156 return IDirectPlayX_SetGroupData( &This->IDirectPlay4A_iface, group, data, size, flags );
4157}
4159static HRESULT WINAPI IDirectPlay3Impl_SetGroupData( IDirectPlay3 *iface, DPID group, void *data,
4161{
4163 return IDirectPlayX_SetGroupData( &This->IDirectPlay4_iface, group, data, size, flags );
4164}
4168{
4170 return IDirectPlayX_SetGroupData( &This->IDirectPlay4_iface, group, data, size, flags );
4171}
4173static HRESULT WINAPI IDirectPlay4Impl_SetGroupData( IDirectPlay4 *iface, DPID group, void *data,
4175{
4177 lpGroupData gdata;
4178
4179 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n", This, group, data, size, flags );
4180
4181 /* Parameter check */
4182 if ( !data && size )
4183 return DPERR_INVALIDPARAMS;
4184
4185 EnterCriticalSection( &This->lock );
4186
4187 /* Find the pointer to the data for this player */
4188 if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL )
4189 {
4190 LeaveCriticalSection( &This->lock );
4191 return DPERR_INVALIDOBJECT;
4192 }
4193
4194 if ( !(flags & DPSET_LOCAL) )
4195 {
4196 FIXME( "Was this group created by this interface?\n" );
4197 /* FIXME: If this is a remote update need to allow it but not
4198 * send a message.
4199 */
4200 }
4201
4202 DP_SetGroupData( gdata, flags, data, size );
4203
4204 /* FIXME: Only send a message if this group is local to the session otherwise
4205 * it will have been rejected above
4206 */
4207 if ( !(flags & DPSET_LOCAL) )
4208 FIXME( "Send msg?\n" );
4209
4210 LeaveCriticalSection( &This->lock );
4211
4212 return DP_OK;
4213}
4215static HRESULT DP_IF_SetGroupName( IDirectPlayImpl *This, DPID idGroup, DPNAME *lpGroupName,
4216 DWORD dwFlags, BOOL bAnsi )
4217{
4218 lpGroupData lpGData;
4219 DPNAME *nameA;
4220 DPNAME *name;
4221
4222 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,%u)\n", This, idGroup,
4223 lpGroupName, dwFlags, bAnsi );
4224
4225 EnterCriticalSection( &This->lock );
4226
4227 if( ( lpGData = DP_FindAnyGroup( This, idGroup ) ) == NULL )
4228 {
4229 LeaveCriticalSection( &This->lock );
4230 return DPERR_INVALIDGROUP;
4231 }
4232
4233 name = DP_DuplicateName( lpGroupName, FALSE, bAnsi );
4234 if ( !name )
4235 {
4236 LeaveCriticalSection( &This->lock );
4237 return DPERR_OUTOFMEMORY;
4238 }
4239
4240 nameA = DP_DuplicateName( lpGroupName, TRUE, bAnsi );
4241 if ( !nameA )
4242 {
4243 free( name );
4244 LeaveCriticalSection( &This->lock );
4245 return DPERR_OUTOFMEMORY;
4246 }
4247
4248 lpGData->name = name;
4249 lpGData->nameA = nameA;
4250
4251 /* Should send a DPMSG_SETPLAYERORGROUPNAME message */
4252 FIXME( "Message not sent and dwFlags ignored\n" );
4253
4254 LeaveCriticalSection( &This->lock );
4255
4256 return DP_OK;
4257}
4261{
4263 return IDirectPlayX_SetGroupName( &This->IDirectPlay4A_iface, group, name, flags );
4264}
4266static HRESULT WINAPI IDirectPlay2Impl_SetGroupName( IDirectPlay2 *iface, DPID group,
4268{
4270 return IDirectPlayX_SetGroupName( &This->IDirectPlay4_iface, group, name, flags );
4271}
4275{
4277 return IDirectPlayX_SetGroupName( &This->IDirectPlay4A_iface, group, name, flags );
4278}
4280static HRESULT WINAPI IDirectPlay3Impl_SetGroupName( IDirectPlay3 *iface, DPID group,
4282{
4284 return IDirectPlayX_SetGroupName( &This->IDirectPlay4_iface, group, name, flags );
4285}
4288 DPNAME *lpGroupName, DWORD dwFlags )
4289{
4291 return DP_IF_SetGroupName( This, idGroup, lpGroupName, dwFlags, TRUE );
4292}
4294static HRESULT WINAPI IDirectPlay4Impl_SetGroupName( IDirectPlay4 *iface, DPID idGroup,
4295 DPNAME *lpGroupName, DWORD dwFlags )
4296{
4298 return DP_IF_SetGroupName( This, idGroup, lpGroupName, dwFlags, FALSE );
4299}
4302 void *data, DWORD size, DWORD flags )
4303{
4305 return IDirectPlayX_SetPlayerData( &This->IDirectPlay4A_iface, player, data, size, flags );
4306}
4308static HRESULT WINAPI IDirectPlay2Impl_SetPlayerData( IDirectPlay2 *iface, DPID player,
4309 void *data, DWORD size, DWORD flags )
4310{
4312 return IDirectPlayX_SetPlayerData( &This->IDirectPlay4_iface, player, data, size, flags );
4313}
4316 void *data, DWORD size, DWORD flags )
4317{
4319 return IDirectPlayX_SetPlayerData( &This->IDirectPlay4A_iface, player, data, size, flags );
4320}
4322static HRESULT WINAPI IDirectPlay3Impl_SetPlayerData( IDirectPlay3 *iface, DPID player,
4323 void *data, DWORD size, DWORD flags )
4324{
4326 return IDirectPlayX_SetPlayerData( &This->IDirectPlay4_iface, player, data, size, flags );
4327}
4330 void *data, DWORD size, DWORD flags )
4331{
4333 return IDirectPlayX_SetPlayerData( &This->IDirectPlay4_iface, player, data, size, flags );
4334}
4336static HRESULT WINAPI IDirectPlay4Impl_SetPlayerData( IDirectPlay4 *iface, DPID player,
4337 void *data, DWORD size, DWORD flags )
4338{
4341
4342 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n", This, player, data, size, flags );
4343
4344 if ( This->dp2->connectionInitialized == NO_PROVIDER )
4345 return DPERR_UNINITIALIZED;
4346
4347 /* Parameter check */
4348 if ( !data && size )
4349 return DPERR_INVALIDPARAMS;
4350
4351 EnterCriticalSection( &This->lock );
4352
4353 /* Find the pointer to the data for this player */
4354 if ( (plist = DP_FindPlayer( This, player )) == NULL )
4355 {
4356 LeaveCriticalSection( &This->lock );
4357 return DPERR_INVALIDPLAYER;
4358 }
4359
4360 if ( !(flags & DPSET_LOCAL) )
4361 {
4362 FIXME( "Was this group created by this interface?\n" );
4363 /* FIXME: If this is a remote update need to allow it but not
4364 * send a message.
4365 */
4366 }
4367
4368 DP_SetPlayerData( plist->lpPData, flags, data, size );
4369
4370 if ( !(flags & DPSET_LOCAL) )
4371 FIXME( "Send msg?\n" );
4372
4373 LeaveCriticalSection( &This->lock );
4374
4375 return DP_OK;
4376}
4378static HRESULT DP_IF_SetPlayerName( IDirectPlayImpl *This, DPID idPlayer, DPNAME *lpPlayerName,
4379 DWORD dwFlags, BOOL bAnsi )
4380{
4381 lpPlayerList lpPList;
4382 DPNAME *nameA;
4383 DPNAME *name;
4384
4385 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,%u)\n",
4386 This, idPlayer, lpPlayerName, dwFlags, bAnsi );
4387
4388 if( This->dp2->connectionInitialized == NO_PROVIDER )
4389 {
4390 return DPERR_UNINITIALIZED;
4391 }
4392
4393 EnterCriticalSection( &This->lock );
4394
4395 if( ( lpPList = DP_FindPlayer( This, idPlayer ) ) == NULL )
4396 {
4397 LeaveCriticalSection( &This->lock );
4398 return DPERR_INVALIDGROUP;
4399 }
4400
4401 name = DP_DuplicateName( lpPlayerName, FALSE, bAnsi );
4402 if ( !name )
4403 {
4404 LeaveCriticalSection( &This->lock );
4405 return DPERR_OUTOFMEMORY;
4406 }
4407
4408 nameA = DP_DuplicateName( lpPlayerName, TRUE, bAnsi );
4409 if ( !nameA )
4410 {
4411 free( name );
4412 LeaveCriticalSection( &This->lock );
4413 return DPERR_OUTOFMEMORY;
4414 }
4415
4416 lpPList->lpPData->name = name;
4417 lpPList->lpPData->nameA = nameA;
4418
4419 /* Should send a DPMSG_SETPLAYERORGROUPNAME message */
4420 FIXME( "Message not sent and dwFlags ignored\n" );
4421
4422 LeaveCriticalSection( &This->lock );
4423
4424 return DP_OK;
4425}
4429{
4431 return IDirectPlayX_SetPlayerName( &This->IDirectPlay4A_iface, player, name, flags );
4432}
4434static HRESULT WINAPI IDirectPlay2Impl_SetPlayerName( IDirectPlay2 *iface, DPID player,
4436{
4438 return IDirectPlayX_SetPlayerName( &This->IDirectPlay4_iface, player, name, flags );
4439}
4443{
4445 return IDirectPlayX_SetPlayerName( &This->IDirectPlay4A_iface, player, name, flags );
4446}
4448static HRESULT WINAPI IDirectPlay3Impl_SetPlayerName( IDirectPlay3 *iface, DPID player,
4450{
4452 return IDirectPlayX_SetPlayerName( &This->IDirectPlay4_iface, player, name, flags );
4453}
4456 DPNAME *lpPlayerName, DWORD dwFlags )
4457{
4459 return DP_IF_SetPlayerName( This, idPlayer, lpPlayerName, dwFlags, TRUE );
4460}
4462static HRESULT WINAPI IDirectPlay4Impl_SetPlayerName( IDirectPlay4 *iface, DPID idPlayer,
4463 DPNAME *lpPlayerName, DWORD dwFlags )
4464{
4466 return DP_IF_SetPlayerName( This, idPlayer, lpPlayerName, dwFlags, FALSE );
4467}
4469static HRESULT DP_SetSessionDesc( IDirectPlayImpl *This, const DPSESSIONDESC2 *lpSessDesc,
4470 DWORD dwFlags, BOOL bInitial, BOOL bAnsi )
4471{
4472 LPDPSESSIONDESC2 lpTempSessDesc;
4473
4474 TRACE( "(%p)->(%p,0x%08lx,%u,%u)\n",
4475 This, lpSessDesc, dwFlags, bInitial, bAnsi );
4476
4477 if( This->dp2->connectionInitialized == NO_PROVIDER )
4478 {
4479 return DPERR_UNINITIALIZED;
4480 }
4481
4482 if( dwFlags )
4483 {
4484 return DPERR_INVALIDPARAMS;
4485 }
4486
4487 /* Only the host is allowed to update the session desc */
4488 if( !This->dp2->bHostInterface )
4489 {
4490 return DPERR_ACCESSDENIED;
4491 }
4492
4493 EnterCriticalSection( &This->lock );
4494
4495 lpTempSessDesc = DP_DuplicateSessionDesc( lpSessDesc, bAnsi, bAnsi );
4496
4497 if( lpTempSessDesc == NULL )
4498 {
4499 LeaveCriticalSection( &This->lock );
4500 return DPERR_OUTOFMEMORY;
4501 }
4502
4503 /* Free the old */
4504 free( This->dp2->lpSessionDesc );
4505
4506 This->dp2->lpSessionDesc = lpTempSessDesc;
4507
4508 /* If this is an external invocation of the interface, we should be
4509 * letting everyone know that things have changed. Otherwise this is
4510 * just an initialization and it doesn't need to be propagated.
4511 */
4512 if( !bInitial )
4513 {
4514 FIXME( "Need to send a DPMSG_SETSESSIONDESC msg to everyone\n" );
4515 }
4516
4517 LeaveCriticalSection( &This->lock );
4518
4519 return DP_OK;
4520}
4523 DWORD flags )
4524{
4526 return IDirectPlayX_SetSessionDesc( &This->IDirectPlay4A_iface, sdesc, flags );
4527}
4529static HRESULT WINAPI IDirectPlay2Impl_SetSessionDesc( IDirectPlay2 *iface, DPSESSIONDESC2 *sdesc,
4530 DWORD flags )
4531{
4533 return IDirectPlayX_SetSessionDesc( &This->IDirectPlay4_iface, sdesc, flags );
4534}
4537 DWORD flags )
4538{
4540 return IDirectPlayX_SetSessionDesc( &This->IDirectPlay4A_iface, sdesc, flags );
4541}
4543static HRESULT WINAPI IDirectPlay3Impl_SetSessionDesc( IDirectPlay3 *iface, DPSESSIONDESC2 *sdesc,
4544 DWORD flags )
4545{
4547 return IDirectPlayX_SetSessionDesc( &This->IDirectPlay4_iface, sdesc, flags );
4548}
4551 DPSESSIONDESC2 *lpSessDesc, DWORD dwFlags )
4552{
4554 return DP_SetSessionDesc( This, lpSessDesc, dwFlags, FALSE, TRUE );
4555}
4557static HRESULT WINAPI IDirectPlay4Impl_SetSessionDesc( IDirectPlay4 *iface,
4558 DPSESSIONDESC2 *lpSessDesc, DWORD dwFlags )
4559{
4561 return DP_SetSessionDesc( This, lpSessDesc, dwFlags, FALSE, TRUE );
4562}
4564static DWORD DP_CopySessionDesc( LPDPSESSIONDESC2 lpSessionDest,
4565 LPCDPSESSIONDESC2 lpSessionSrc, BOOL dstAnsi, BOOL srcAnsi )
4566{
4567 DWORD offset = sizeof( DPSESSIONDESC2 );
4568
4569 if( lpSessionDest )
4570 CopyMemory( lpSessionDest, lpSessionSrc, sizeof( *lpSessionSrc ) );
4571
4572 offset += DP_CopyString( &lpSessionDest->lpszSessionNameA, lpSessionSrc->lpszSessionNameA,
4573 dstAnsi, srcAnsi, lpSessionDest, offset );
4574 offset += DP_CopyString( &lpSessionDest->lpszPasswordA, lpSessionSrc->lpszPasswordA,
4575 dstAnsi, srcAnsi, lpSessionDest, offset );
4576
4577 return offset;
4578}
4581{
4583 DWORD size;
4584
4585 size = DP_CopySessionDesc( NULL, src, dstAnsi, srcAnsi );
4586
4587 dst = malloc( size );
4588 if ( !dst )
4589 return NULL;
4590
4591 DP_CopySessionDesc( dst, src, dstAnsi, srcAnsi );
4592
4593 return dst;
4594}
4597 DPID group )
4598{
4600 return IDirectPlayX_AddGroupToGroup( &This->IDirectPlay4A_iface, parent, group );
4601}
4603static HRESULT WINAPI IDirectPlay3Impl_AddGroupToGroup( IDirectPlay3 *iface, DPID parent,
4604 DPID group )
4605{
4607 return IDirectPlayX_AddGroupToGroup( &This->IDirectPlay4_iface, parent, group );
4608}
4611 DPID group )
4612{
4614 return IDirectPlayX_AddGroupToGroup( &This->IDirectPlay4_iface, parent, group );
4615}
4617static HRESULT WINAPI IDirectPlay4Impl_AddGroupToGroup( IDirectPlay4 *iface, DPID parent,
4618 DPID group )
4619{
4621 lpGroupData gdata;
4623
4624 TRACE( "(%p)->(0x%08lx,0x%08lx)\n", This, parent, group );
4625
4626 if ( This->dp2->connectionInitialized == NO_PROVIDER )
4627 return DPERR_UNINITIALIZED;
4628
4629 EnterCriticalSection( &This->lock );
4630
4631 if ( !DP_FindAnyGroup(This, parent ) )
4632 {
4633 LeaveCriticalSection( &This->lock );
4634 return DPERR_INVALIDGROUP;
4635 }
4636
4637 if ( ( gdata = DP_FindAnyGroup(This, group ) ) == NULL )
4638 {
4639 LeaveCriticalSection( &This->lock );
4640 return DPERR_INVALIDGROUP;
4641 }
4642
4643 /* Create a player list (ie "shortcut" ) */
4644 glist = calloc( 1, sizeof( *glist ) );
4645 if ( !glist )
4646 {
4647 LeaveCriticalSection( &This->lock );
4648 return DPERR_CANTADDPLAYER;
4649 }
4650
4651 /* Add the shortcut */
4652 gdata->uRef++;
4653 glist->lpGData = gdata;
4654
4655 /* Add the player to the list of players for this group */
4656 DPQ_INSERT( gdata->groups, glist, groups );
4657
4658 /* Send a ADDGROUPTOGROUP message */
4659 FIXME( "Not sending message\n" );
4660
4661 LeaveCriticalSection( &This->lock );
4662
4663 return DP_OK;
4664}
4666static HRESULT DP_IF_CreateGroupInGroup( IDirectPlayImpl *This, void *lpMsgHdr, DPID idParentGroup,
4667 DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags,
4668 BOOL bAnsi )
4669{
4670 HRESULT hr;
4671
4672 TRACE( "(%p)->(0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,%u)\n",
4673 This, idParentGroup, lpidGroup, lpGroupName, lpData,
4674 dwDataSize, dwFlags, bAnsi );
4675
4676 if( This->dp2->connectionInitialized == NO_PROVIDER )
4677 {
4678 return DPERR_UNINITIALIZED;
4679 }
4680
4681 EnterCriticalSection( &This->lock );
4682
4683 hr = DP_CreateGroup(This, lpMsgHdr, lpidGroup, lpGroupName, lpData, dwDataSize, dwFlags,
4684 idParentGroup, bAnsi );
4685
4686 if( FAILED( hr ) )
4687 {
4688 LeaveCriticalSection( &This->lock );
4689 return hr;
4690 }
4691
4692 /* Inform all other peers of the creation of a new group. If there are
4693 * no peers keep this quiet.
4694 */
4695 if( This->dp2->lpSessionDesc &&
4696 ( This->dp2->lpSessionDesc->dwFlags & DPSESSION_MULTICASTSERVER ) )
4697 {
4699
4701 msg.dwPlayerType = DPPLAYERTYPE_GROUP;
4702 msg.dpId = *lpidGroup;
4703 msg.dwCurrentPlayers = idParentGroup; /* FIXME: Incorrect? */
4704 msg.lpData = lpData;
4705 msg.dwDataSize = dwDataSize;
4706 msg.dpnName = *lpGroupName;
4707
4708 /* FIXME: Correct to just use send effectively? */
4709 /* FIXME: Should size include data w/ message or just message "header" */
4710 /* FIXME: Check return code */
4711 IDirectPlayX_SendEx( &This->IDirectPlay4_iface, DPID_SERVERPLAYER, DPID_ALLPLAYERS, 0, &msg,
4712 sizeof( msg ), 0, 0, NULL, NULL );
4713 }
4714
4715 LeaveCriticalSection( &This->lock );
4716
4717 return DP_OK;
4718}
4721 DPID *group, DPNAME *name, void *data, DWORD size, DWORD flags )
4722{
4724 return IDirectPlayX_CreateGroupInGroup( &This->IDirectPlay4A_iface, parent, group, name,
4725 data, size, flags );
4726}
4728static HRESULT WINAPI IDirectPlay3Impl_CreateGroupInGroup( IDirectPlay3 *iface, DPID parent,
4729 DPID *group, DPNAME *name, void *data, DWORD size, DWORD flags )
4730{
4732 return IDirectPlayX_CreateGroupInGroup( &This->IDirectPlay4_iface, parent, group, name,
4733 data, size, flags );
4734}
4737 DPID idParentGroup, DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize,
4738 DWORD dwFlags )
4739{
4741
4742 *lpidGroup = DPID_UNKNOWN;
4743
4744 return DP_IF_CreateGroupInGroup( This, NULL, idParentGroup, lpidGroup, lpGroupName, lpData,
4745 dwDataSize, dwFlags, TRUE );
4746}
4748static HRESULT WINAPI IDirectPlay4Impl_CreateGroupInGroup( IDirectPlay4 *iface, DPID idParentGroup,
4749 DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags )
4750{
4752
4753 *lpidGroup = DPID_UNKNOWN;
4754
4755 return DP_IF_CreateGroupInGroup( This, NULL, idParentGroup, lpidGroup, lpGroupName, lpData,
4756 dwDataSize, dwFlags, FALSE );
4757}
4760 DPID group )
4761{
4763 return IDirectPlayX_DeleteGroupFromGroup( &This->IDirectPlay4A_iface, parent, group );
4764}
4767 DPID group )
4768{
4770 return IDirectPlayX_DeleteGroupFromGroup( &This->IDirectPlay4_iface, parent, group );
4771}
4774 DPID group )
4775{
4777 return IDirectPlayX_DeleteGroupFromGroup( &This->IDirectPlay4_iface, parent, group );
4778}
4781 DPID group )
4782{
4785 lpGroupData parentdata;
4786
4787 TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, parent, group );
4788
4789 EnterCriticalSection( &This->lock );
4790
4791 /* Is the parent group valid? */
4792 if ( ( parentdata = DP_FindAnyGroup(This, parent ) ) == NULL )
4793 {
4794 LeaveCriticalSection( &This->lock );
4795 return DPERR_INVALIDGROUP;
4796 }
4797
4798 /* Remove the group from the parent group queue */
4799 DPQ_REMOVE_ENTRY( parentdata->groups, groups, lpGData->dpid, ==, group, glist );
4800
4801 if ( glist == NULL )
4802 {
4803 LeaveCriticalSection( &This->lock );
4804 return DPERR_INVALIDGROUP;
4805 }
4806
4807 /* Decrement the ref count */
4808 glist->lpGData->uRef--;
4809
4810 /* Free up the list item */
4811 free( glist );
4812
4813 /* Should send a DELETEGROUPFROMGROUP message */
4814 FIXME( "message not sent\n" );
4815
4816 LeaveCriticalSection( &This->lock );
4817
4818 return DP_OK;
4819}
4821static BOOL DP_BuildSPCompoundAddr( LPGUID lpcSpGuid, LPVOID* lplpAddrBuf,
4822 LPDWORD lpdwBufSize )
4823{
4824 DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
4825 HRESULT hr;
4826
4827 dpCompoundAddress.dwDataSize = sizeof( GUID );
4828 dpCompoundAddress.guidDataType = DPAID_ServiceProvider;
4829 dpCompoundAddress.lpData = lpcSpGuid;
4830
4831 *lplpAddrBuf = NULL;
4832 *lpdwBufSize = 0;
4833
4834 hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, *lplpAddrBuf,
4835 lpdwBufSize, TRUE );
4836
4837 if( hr != DPERR_BUFFERTOOSMALL )
4838 {
4839 ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
4840 return FALSE;
4841 }
4842
4843 /* Now allocate the buffer */
4844 *lplpAddrBuf = calloc( 1, *lpdwBufSize );
4845
4846 hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, *lplpAddrBuf,
4847 lpdwBufSize, TRUE );
4848 if( FAILED(hr) )
4849 {
4850 ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
4851 free( *lplpAddrBuf );
4852 return FALSE;
4853 }
4854
4855 return TRUE;
4856}
4859 const GUID *application, LPDPENUMCONNECTIONSCALLBACK enumcb, void *context, DWORD flags )
4860{
4862 return IDirectPlayX_EnumConnections( &This->IDirectPlay4A_iface, application, enumcb, context,
4863 flags );
4864}
4866static HRESULT WINAPI IDirectPlay3Impl_EnumConnections( IDirectPlay3 *iface,
4867 const GUID *application, LPDPENUMCONNECTIONSCALLBACK enumcb, void *context, DWORD flags )
4868{
4870 return IDirectPlayX_EnumConnections( &This->IDirectPlay4_iface, application, enumcb, context,
4871 flags );
4872}
4874static BOOL DP_GetRegString( HKEY key, const void *name, const char *defaultValue, void **outValue,
4875 BOOL ansi )
4876{
4877 DWORD size = 0;
4879 void *value;
4880
4881 if ( ansi )
4883 else
4885
4886 if ( status == ERROR_SUCCESS )
4887 {
4888 value = malloc( size );
4889 if ( !value )
4890 return FALSE;
4891
4892 if ( ansi )
4894 else
4896
4897 if ( status == ERROR_SUCCESS )
4898 {
4899 *outValue = value;
4900 return TRUE;
4901 }
4902
4903 free( value );
4904 }
4905
4906 value = DP_DuplicateString( defaultValue, ansi, TRUE );
4907 if ( !value )
4908 return FALSE;
4909
4910 *outValue = value;
4911 return TRUE;
4912}
4914static BOOL DP_GetRegStringW( HKEY key, const WCHAR *name, const char *defaultValue, WCHAR **outValue )
4915{
4916 return DP_GetRegString( key, name, defaultValue, (void **) outValue, FALSE );
4917}
4919static BOOL DP_GetRegStringA( HKEY key, const char *name, const char *defaultValue, char **outValue )
4920{
4921 return DP_GetRegString( key, name, defaultValue, (void **) outValue, TRUE );
4922}
4924static BOOL DP_GetRegDword( HKEY key, const WCHAR *name, DWORD *value )
4925{
4926 DWORD size = sizeof( DWORD );
4927 WCHAR *buffer;
4928
4930 return TRUE;
4931
4932 buffer = malloc( size );
4933 if ( !buffer )
4934 return FALSE;
4935
4937 {
4938 free( buffer );
4939 return FALSE;
4940 }
4941
4942 if ( 1 != swscanf( buffer, L"%lu", value ) )
4943 {
4944 free( buffer );
4945 return FALSE;
4946 }
4947
4948 free( buffer );
4949
4950 return TRUE;
4951}
4953static void DP_ReadConnections( const char *searchSubKey, DWORD dwFlags,
4954 const GUID *addressDataType, struct list *connections )
4955{
4956 HKEY hkResult;
4957 char subKeyName[51];
4958 DWORD dwIndex, sizeOfSubKeyName=50;
4959 FILETIME filetime;
4960
4961 /* Need to loop over the service providers in the registry */
4962 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
4963 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
4964 {
4965 /* Hmmm. Does this mean that there are no service providers? */
4966 ERR(": no service providers?\n");
4967 return;
4968 }
4969
4970
4971 /* Traverse all the service providers we have available */
4972 for( dwIndex=0;
4973 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
4974 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
4975 ++dwIndex, sizeOfSubKeyName=51 )
4976 {
4977
4978 HKEY hkServiceProvider;
4979 WCHAR *spGuid;
4980 HRESULT hr;
4981
4982 DPCOMPOUNDADDRESSELEMENT dpCompoundAddress;
4984
4985 TRACE(" this time through: %s\n", subKeyName );
4986
4987 /* Get a handle for this particular service provider */
4988 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
4989 &hkServiceProvider ) != ERROR_SUCCESS )
4990 {
4991 ERR(": what the heck is going on?\n" );
4992 continue;
4993 }
4994
4995 connection = calloc( 1, sizeof( DPCONNECTION) );
4996 if( !connection )
4997 {
4998 RegCloseKey( hkServiceProvider );
4999 continue;
5000 }
5001
5002 connection->flags = dwFlags;
5003
5004 if( !DP_GetRegStringW( hkServiceProvider, L"Guid", NULL, &spGuid ) )
5005 {
5006 ERR(": missing GUID registry data members\n" );
5007 free( connection );
5008 RegCloseKey(hkServiceProvider);
5009 continue;
5010 }
5011 CLSIDFromString( spGuid, &connection->spGuid );
5012 free( spGuid );
5013
5014 /* Fill in the DPNAME struct for the service provider */
5015
5016 connection->name.dwSize = sizeof( DPNAME );
5017 if( !DP_GetRegStringW( hkServiceProvider, L"DescriptionW", subKeyName,
5018 &connection->name.lpszShortName ) )
5019 {
5020 free( connection );
5021 RegCloseKey( hkServiceProvider );
5022 continue;
5023 }
5024
5025 connection->nameA.dwSize = sizeof( DPNAME );
5026 if( !DP_GetRegStringA( hkServiceProvider, "DescriptionA", subKeyName,
5027 &connection->nameA.lpszShortNameA ) )
5028 {
5029 free( connection->name.lpszShortName );
5030 free( connection );
5031 RegCloseKey( hkServiceProvider );
5032 continue;
5033 }
5034
5035 if( !DP_GetRegDword( hkServiceProvider, L"dwReserved1", &connection->reserved1 ) )
5036 {
5037 free( connection->nameA.lpszShortNameA );
5038 free( connection->name.lpszShortName );
5039 free( connection );
5040 RegCloseKey( hkServiceProvider );
5041 continue;
5042 }
5043
5044 if( !DP_GetRegDword( hkServiceProvider, L"dwReserved2", &connection->reserved2 ) )
5045 {
5046 free( connection->nameA.lpszShortNameA );
5047 free( connection->name.lpszShortName );
5048 free( connection );
5049 RegCloseKey( hkServiceProvider );
5050 continue;
5051 }
5052
5053 if( !DP_GetRegStringA( hkServiceProvider, "Path", NULL, &connection->path ) )
5054 {
5055 free( connection->nameA.lpszShortNameA );
5056 free( connection->name.lpszShortName );
5057 free( connection );
5058 RegCloseKey( hkServiceProvider );
5059 continue;
5060 }
5061
5062 RegCloseKey( hkServiceProvider );
5063
5064 /* Create the compound address for the service provider.
5065 * NOTE: This is a gruesome architectural scar right now. DP
5066 * uses DPL and DPL uses DP. Nasty stuff. This may be why the
5067 * native dll just gets around this little bit by allocating an
5068 * 80 byte buffer which isn't even filled with a valid compound
5069 * address. Oh well. Creating a proper compound address is the
5070 * way to go anyways despite this method taking slightly more
5071 * heap space and realtime :) */
5072
5073 dpCompoundAddress.guidDataType = *addressDataType;
5074 dpCompoundAddress.dwDataSize = sizeof( GUID );
5075 dpCompoundAddress.lpData = &connection->spGuid;
5076
5077 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, connection->address,
5078 &connection->addressSize, TRUE ) ) != DPERR_BUFFERTOOSMALL )
5079 {
5080 ERR( "can't get buffer size: %s\n", DPLAYX_HresultToString( hr ) );
5081 free( connection->path );
5082 free( connection->nameA.lpszShortNameA );
5083 free( connection->name.lpszShortName );
5084 free( connection );
5085 continue;
5086 }
5087
5088 /* Now allocate the buffer */
5089 connection->address = calloc( 1, connection->addressSize );
5090
5091 if( ( hr = DPL_CreateCompoundAddress( &dpCompoundAddress, 1, connection->address,
5092 &connection->addressSize, TRUE ) ) != DP_OK )
5093 {
5094 ERR( "can't create address: %s\n", DPLAYX_HresultToString( hr ) );
5095 free( connection->address );
5096 free( connection->path );
5097 free( connection->nameA.lpszShortNameA );
5098 free( connection->name.lpszShortName );
5099 free( connection );
5100 continue;
5101 }
5102
5104 }
5105}
5109static BOOL WINAPI DP_InitConnections( INIT_ONCE *initOnce, void *param, void **context )
5110{
5111 struct list *connections = param;
5112
5113 DP_ReadConnections( "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers",
5114 DPCONNECTION_DIRECTPLAY, &DPAID_ServiceProvider, connections );
5115
5116 DP_ReadConnections( "SOFTWARE\\Microsoft\\DirectPlay\\Lobby Providers",
5117 DPCONNECTION_DIRECTPLAYLOBBY, &DPAID_LobbyProvider, connections );
5118
5120
5121 return TRUE;
5122}
5124static struct list *DP_GetConnections(void)
5125{
5126 static struct list connections = LIST_INIT( connections );
5127 static INIT_ONCE initOnce = INIT_ONCE_STATIC_INIT;
5128
5130
5131 return &connections;
5132}
5134void DP_FreeConnections(void)
5135{
5136 struct list *connections;
5137
5139 return;
5140
5142
5143 while ( !list_empty( connections ) )
5144 {
5146
5147 list_remove( &connection->entry );
5148 free( connection->nameA.lpszShortNameA );
5149 free( connection->name.lpszShortName );
5150 free( connection->path );
5151 free( connection->address );
5152 free( connection );
5153 }
5154}
5157 const GUID *lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, void *lpContext,
5159{
5161 struct list *connections;
5162
5163 TRACE("(%p)->(%p,%p,%p,0x%08lx)\n", This, lpguidApplication, lpEnumCallback, lpContext, dwFlags );
5164
5165 /* A default dwFlags (0) is backwards compatible -- DPCONNECTION_DIRECTPLAY */
5166 if( dwFlags == 0 )
5167 {
5169 }
5170
5171 if( ! ( ( dwFlags & DPCONNECTION_DIRECTPLAY ) ||
5173 )
5174 {
5175 return DPERR_INVALIDFLAGS;
5176 }
5177
5178 if( !lpEnumCallback )
5179 {
5180 return DPERR_INVALIDPARAMS;
5181 }
5182
5184
5186 {
5187 if ( !(connection->flags & dwFlags) )
5188 continue;
5189
5190 if ( !lpEnumCallback( &connection->spGuid, connection->address, connection->addressSize,
5191 ansi ? &connection->nameA : &connection->name, dwFlags, lpContext ) )
5192 break;
5193 }
5194
5195 return DP_OK;
5196}
5199 const GUID *lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, void *lpContext,
5200 DWORD dwFlags )
5201{
5203 return DP_IF_EnumConnections( This, lpguidApplication, lpEnumCallback, lpContext, dwFlags, TRUE );
5204}
5206static HRESULT WINAPI IDirectPlay4Impl_EnumConnections( IDirectPlay4 *iface,
5207 const GUID *application, LPDPENUMCONNECTIONSCALLBACK enumcb, void *context, DWORD flags )
5208{
5210 return DP_IF_EnumConnections( This, application, enumcb, context, flags, FALSE );
5211}
5214 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
5215{
5217 return IDirectPlayX_EnumGroupsInGroup( &This->IDirectPlay4A_iface, group, instance,
5218 enumplayercb, context, flags );
5219}
5221static HRESULT WINAPI IDirectPlay3Impl_EnumGroupsInGroup( IDirectPlay3 *iface, DPID group,
5222 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
5223{
5225 return IDirectPlayX_EnumGroupsInGroup( &This->IDirectPlay4_iface, group, instance,
5226 enumplayercb, context, flags );
5227}
5230 LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags, BOOL ansi )
5231{
5233 lpGroupData gdata;
5234
5235 FIXME( "(%p)->(0x%08lx,%p,%p,%p,0x%08lx): semi stub\n", This, group, instance, enumplayercb,
5236 context, flags );
5237
5238 if ( This->dp2->connectionInitialized == NO_PROVIDER )
5239 return DPERR_UNINITIALIZED;
5240
5241 EnterCriticalSection( &This->lock );
5242
5243 if ( ( gdata = DP_FindAnyGroup(This, group ) ) == NULL )
5244 {
5245 LeaveCriticalSection( &This->lock );
5246 return DPERR_INVALIDGROUP;
5247 }
5248
5249 for( glist = DPQ_FIRST( gdata->groups ); glist; glist = DPQ_NEXT( glist->groups ) )
5250 {
5251 DWORD groupFlags;
5252
5253 if ( (glist->lpGData->dwFlags & flags) != (flags & ~DPENUMGROUPS_REMOTE) )
5254 continue;
5255 if ( (glist->lpGData->dwFlags & DPENUMGROUPS_LOCAL) && (flags & DPENUMGROUPS_REMOTE) )
5256 continue;
5257
5258 groupFlags = glist->lpGData->dwFlags;
5259 groupFlags &= ~(DPENUMGROUPS_LOCAL | DPLAYI_GROUP_DPLAYOWNS);
5260 groupFlags |= flags;
5261
5262 if ( !(*enumplayercb)( glist->lpGData->dpid, DPPLAYERTYPE_GROUP,
5263 ansi ? glist->lpGData->nameA : glist->lpGData->name, groupFlags, context ) )
5264 break; /* User requested break */
5265 }
5266
5267 LeaveCriticalSection( &This->lock );
5268
5269 return DP_OK;
5270}
5273 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
5274{
5276 return DP_IF_EnumGroupsInGroup( This, group, instance, enumplayercb, context, flags, TRUE );
5277}
5279static HRESULT WINAPI IDirectPlay4Impl_EnumGroupsInGroup( IDirectPlay4 *iface, DPID group,
5280 GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags )
5281{
5283 return DP_IF_EnumGroupsInGroup( This, group, instance, enumplayercb, context, flags, FALSE );
5284}
5287 DWORD flags, DPID group, void *data, DWORD *size )
5288{
5290 return IDirectPlayX_GetGroupConnectionSettings( &This->IDirectPlay4A_iface, flags, group,
5291 data, size );
5292}
5295 DWORD flags, DPID group, void *data, DWORD *size )
5296{
5298 return IDirectPlayX_GetGroupConnectionSettings( &This->IDirectPlay4_iface, flags, group,
5299 data, size );
5300}
5303 DWORD flags, DPID group, void *data, DWORD *size )
5304{
5306 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, flags, group, data, size );
5307 return DP_OK;
5308}
5311 DPID group, void *data, DWORD *size )
5312{
5314 FIXME( "(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, flags, group, data, size );
5315 return DP_OK;
5316}
5319 REFGUID guidDataType,
5320 DWORD dwDataSize,
5321 LPCVOID lpData,
5322 LPVOID lpContext )
5323{
5324 /* Looking for the GUID of the provider to load */
5325 if( ( IsEqualGUID( guidDataType, &DPAID_ServiceProvider ) ) ||
5326 ( IsEqualGUID( guidDataType, &DPAID_LobbyProvider ) )
5327 )
5328 {
5329 TRACE( "Found SP/LP (%s) %s (data size = 0x%08lx)\n",
5330 debugstr_guid( guidDataType ), debugstr_guid( lpData ), dwDataSize );
5331
5332 if( dwDataSize != sizeof( GUID ) )
5333 {
5334 ERR( "Invalid sp/lp guid size 0x%08lx\n", dwDataSize );
5335 }
5336
5337 memcpy( lpContext, lpData, dwDataSize );
5338
5339 /* There shouldn't be more than 1 GUID/compound address */
5340 return FALSE;
5341 }
5342
5343 /* Still waiting for what we want */
5344 return TRUE;
5345}
5346
5347
5348/* Find and perform a LoadLibrary on the requested SP or LP GUID */
5349static HMODULE DP_LoadSP( LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDpSp )
5350{
5352 struct list *connections;
5353
5354 TRACE( " request to load %s\n", debugstr_guid( lpcGuid ) );
5355
5357
5359 {
5360 /* Determine if this is the Service Provider that the user asked for */
5361 if( !IsEqualGUID( &connection->spGuid, lpcGuid ) )
5362 {
5363 continue;
5364 }
5365
5366 if( connection->flags & DPCONNECTION_DIRECTPLAY )
5367 {
5368 lpSpData->lpszName = connection->name.lpszShortName;
5369 lpSpData->dwReserved1 = connection->reserved1;
5370 lpSpData->dwReserved2 = connection->reserved2;
5371 }
5372
5373 *lpbIsDpSp = !!(connection->flags & DPCONNECTION_DIRECTPLAY);
5374
5375 TRACE( "Loading %s\n", connection->path );
5376 return LoadLibraryA( connection->path );
5377 }
5378
5379 return 0;
5380}
5382static HRESULT DP_InitializeDPSP( IDirectPlayImpl *This, HMODULE hServiceProvider )
5383{
5384 HRESULT hr;
5386
5387 /* Initialize the service provider by calling SPInit */
5388 SPInit = (LPDPSP_SPINIT)GetProcAddress( hServiceProvider, "SPInit" );
5389
5390 if( SPInit == NULL )
5391 {
5392 ERR( "Service provider doesn't provide SPInit interface?\n" );
5393 FreeLibrary( hServiceProvider );
5394 return DPERR_UNAVAILABLE;
5395 }
5396
5397 TRACE( "Calling SPInit (DP SP entry point)\n" );
5398
5399 hr = (*SPInit)( &This->dp2->spData );
5400
5401 if( FAILED(hr) )
5402 {
5403 ERR( "DP SP Initialization failed: %s\n", DPLAYX_HresultToString(hr) );
5404 FreeLibrary( hServiceProvider );
5405 return hr;
5406 }
5407
5408 /* FIXME: Need to verify the sanity of the returned callback table
5409 * using IsBadCodePtr */
5410 This->dp2->bSPInitialized = TRUE;
5411
5412 /* This interface is now initialized as a DP object */
5413 This->dp2->connectionInitialized = DP_SERVICE_PROVIDER;
5414
5415 /* Store the handle of the module so that we can unload it later */
5416 This->dp2->hServiceProvider = hServiceProvider;
5417
5418 return hr;
5419}
5421static HRESULT DP_InitializeDPLSP( IDirectPlayImpl *This, HMODULE hLobbyProvider )
5422{
5423 HRESULT hr;
5424 LPSP_INIT DPLSPInit;
5425
5426 /* Initialize the service provider by calling SPInit */
5427 DPLSPInit = (LPSP_INIT)GetProcAddress( hLobbyProvider, "DPLSPInit" );
5428
5429 if( DPLSPInit == NULL )
5430 {
5431 ERR( "Service provider doesn't provide DPLSPInit interface?\n" );
5432 FreeLibrary( hLobbyProvider );
5433 return DPERR_UNAVAILABLE;
5434 }
5435
5436 TRACE( "Calling DPLSPInit (DPL SP entry point)\n" );
5437
5438 hr = (*DPLSPInit)( &This->dp2->dplspData );
5439
5440 if( FAILED(hr) )
5441 {
5442 ERR( "DPL SP Initialization failed: %s\n", DPLAYX_HresultToString(hr) );
5443 FreeLibrary( hLobbyProvider );
5444 return hr;
5445 }
5446
5447 /* FIXME: Need to verify the sanity of the returned callback table
5448 * using IsBadCodePtr */
5449
5450 This->dp2->bDPLSPInitialized = TRUE;
5451
5452 /* This interface is now initialized as a lobby object */
5453 This->dp2->connectionInitialized = DP_LOBBY_PROVIDER;
5454
5455 /* Store the handle of the module so that we can unload it later */
5456 This->dp2->hDPLobbyProvider = hLobbyProvider;
5457
5458 return hr;
5459}
5462 void *connection, DWORD flags )
5463{
5465 return IDirectPlayX_InitializeConnection( &This->IDirectPlay4A_iface, connection, flags );
5466}
5468static HRESULT WINAPI IDirectPlay3Impl_InitializeConnection( IDirectPlay3 *iface,
5469 void *connection, DWORD flags )
5470{
5472 return IDirectPlayX_InitializeConnection( &This->IDirectPlay4_iface, connection, flags );
5473}
5476 void *connection, DWORD flags )
5477{
5479 return IDirectPlayX_InitializeConnection( &This->IDirectPlay4_iface, connection, flags );
5480}
5482static HRESULT WINAPI IDirectPlay4Impl_InitializeConnection( IDirectPlay4 *iface,
5483 void *connection, DWORD flags )
5484{
5486 HMODULE servprov;
5487 GUID sp;
5488 const DWORD size = 80; /* FIXME: Need to calculate it correctly */
5489 BOOL is_dp_sp; /* TRUE if Direct Play SP, FALSE if Direct Play Lobby SP */
5490 HRESULT hr;
5491
5492 TRACE( "(%p)->(%p,0x%08lx)\n", This, connection, flags );
5493
5494 if ( !connection )
5495 return DPERR_INVALIDPARAMS;
5496
5497 if ( flags )
5498 return DPERR_INVALIDFLAGS;
5499
5500 if ( This->dp2->connectionInitialized != NO_PROVIDER )
5502
5503 /* Find out what the requested SP is and how large this buffer is */
5505
5506 if ( FAILED(hr) )
5507 {
5508 ERR( "Invalid compound address?\n" );
5509 return DPERR_UNAVAILABLE;
5510 }
5511
5512 /* Load the service provider */
5513 servprov = DP_LoadSP( &sp, &This->dp2->spData, &is_dp_sp );
5514
5515 if ( !servprov )
5516 {
5517 ERR( "Unable to load service provider %s\n", debugstr_guid(&sp) );
5518 return DPERR_UNAVAILABLE;
5519 }
5520
5521 if ( is_dp_sp )
5522 {
5523 /* Fill in what we can of the Service Provider required information.
5524 * The rest was be done in DP_LoadSP
5525 */
5526 This->dp2->spData.lpAddress = connection;
5527 This->dp2->spData.dwAddressSize = size;
5528 This->dp2->spData.lpGuid = &sp;
5529 hr = DP_InitializeDPSP( This, servprov );
5530 }
5531 else
5532 {
5533 This->dp2->dplspData.lpAddress = connection;
5534 hr = DP_InitializeDPLSP( This, servprov );
5535 }
5536
5537 if ( FAILED(hr) )
5538 return hr;
5539
5540 return DP_OK;
5541}
5544 const DPSESSIONDESC2 *sdesc, DWORD flags, const DPSECURITYDESC *security,
5545 const DPCREDENTIALS *credentials )
5546{
5548 return IDirectPlayX_SecureOpen( &This->IDirectPlay4A_iface, sdesc, flags, security,
5549 credentials );
5550}
5552static HRESULT WINAPI IDirectPlay3Impl_SecureOpen( IDirectPlay3 *iface,
5553 const DPSESSIONDESC2 *sdesc, DWORD flags, const DPSECURITYDESC *security,
5554 const DPCREDENTIALS *credentials )
5555{
5557 return IDirectPlayX_SecureOpen( &This->IDirectPlay4_iface, sdesc, flags, security,
5558 credentials );
5559}
5562 const DPSESSIONDESC2 *lpsd, DWORD dwFlags, const DPSECURITYDESC *lpSecurity,
5563 const DPCREDENTIALS *lpCredentials )
5564{
5566 return DP_SecureOpen( This, lpsd, dwFlags, lpSecurity, lpCredentials, TRUE );
5567}
5569static HRESULT WINAPI IDirectPlay4Impl_SecureOpen( IDirectPlay4 *iface,
5570 const DPSESSIONDESC2 *lpsd, DWORD dwFlags, const DPSECURITYDESC *lpSecurity,
5571 const DPCREDENTIALS *lpCredentials )
5572{
5574 return DP_SecureOpen( This, lpsd, dwFlags, lpSecurity, lpCredentials, FALSE );
5575}
5578 DWORD flags, DPCHAT *chatmsg )
5579{
5581 return IDirectPlayX_SendChatMessage( &This->IDirectPlay4A_iface, from, to, flags, chatmsg );
5582}
5584static HRESULT WINAPI IDirectPlay3Impl_SendChatMessage( IDirectPlay3 *iface, DPID from, DPID to,
5585 DWORD flags, DPCHAT *chatmsg )
5586{
5588 return IDirectPlayX_SendChatMessage( &This->IDirectPlay4_iface, from, to, flags, chatmsg );
5589}
5592 DPID to, DWORD flags, DPCHAT *chatmsg )
5593{
5595 FIXME("(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, from, to, flags, chatmsg );
5596 return DP_OK;
5597}
5599static HRESULT WINAPI IDirectPlay4Impl_SendChatMessage( IDirectPlay4 *iface, DPID from, DPID to,
5600 DWORD flags, DPCHAT *chatmsg )
5601{
5603 FIXME( "(%p)->(0x%08lx,0x%08lx,0x%08lx,%p): stub\n", This, from, to, flags, chatmsg );
5604 return DP_OK;
5605}
5609{
5611 return IDirectPlayX_SetGroupConnectionSettings( &This->IDirectPlay4A_iface, flags, group,
5612 connection );
5613}
5617{
5619 return IDirectPlayX_SetGroupConnectionSettings( &This->IDirectPlay4_iface, flags, group,
5620 connection );
5621}
5625{
5627 FIXME("(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, flags, group, connection );
5628 return DP_OK;
5629}
5633{
5635 FIXME( "(%p)->(0x%08lx,0x%08lx,%p): stub\n", This, flags, group, connection );
5636 return DP_OK;
5637}
5640 DPID group )
5641{
5643 return IDirectPlayX_StartSession( &This->IDirectPlay4A_iface, flags, group );
5644}
5646static HRESULT WINAPI IDirectPlay3Impl_StartSession( IDirectPlay3 *iface, DWORD flags,
5647 DPID group )
5648{
5650 return IDirectPlayX_StartSession( &This->IDirectPlay4_iface, flags, group );
5651}
5654 DPID group )
5655{
5657 return IDirectPlayX_StartSession( &This->IDirectPlay4_iface, flags, group );
5658}
5660static HRESULT WINAPI IDirectPlay4Impl_StartSession( IDirectPlay4 *iface, DWORD flags, DPID group )
5661{
5663 FIXME( "(%p)->(0x%08lx,0x%08lx): stub\n", This, flags, group );
5664 return DP_OK;
5665}
5668 DWORD *flags )
5669{
5671 return IDirectPlayX_GetGroupFlags( &This->IDirectPlay4A_iface, group, flags );
5672}
5674static HRESULT WINAPI IDirectPlay3Impl_GetGroupFlags( IDirectPlay3 *iface, DPID group,
5675 DWORD *flags )
5676{
5678 return IDirectPlayX_GetGroupFlags( &This->IDirectPlay4_iface, group, flags );
5679}
5682 DWORD *flags )
5683{
5685 return IDirectPlayX_GetGroupFlags( &This->IDirectPlay4_iface, group, flags );
5686}
5688static HRESULT WINAPI IDirectPlay4Impl_GetGroupFlags( IDirectPlay4 *iface, DPID group,
5689 DWORD *flags )
5690{
5692 FIXME( "(%p)->(0x%08lx,%p): stub\n", This, group, flags );
5693 return DP_OK;
5694}
5697 DPID *parent )
5698{
5700 return IDirectPlayX_GetGroupParent( &This->IDirectPlay4A_iface, group, parent );
5701}
5703static HRESULT WINAPI IDirectPlay3Impl_GetGroupParent( IDirectPlay3 *iface, DPID group,
5704 DPID *parent )
5705{
5707 return IDirectPlayX_GetGroupParent( &This->IDirectPlay4_iface, group, parent );
5708}
5711 DPID *parent )
5712{
5714 return IDirectPlayX_GetGroupParent( &This->IDirectPlay4_iface, group, parent );
5715}
5717static HRESULT WINAPI IDirectPlay4Impl_GetGroupParent( IDirectPlay4 *iface, DPID group,
5718 DPID *parent )
5719{
5721 lpGroupData gdata;
5722
5723 TRACE( "(%p)->(0x%08lx,%p)\n", This, group, parent );
5724
5725 EnterCriticalSection( &This->lock );
5726
5727 if ( ( gdata = DP_FindAnyGroup( This, group ) ) == NULL )
5728 {
5729 LeaveCriticalSection( &This->lock );
5730 return DPERR_INVALIDGROUP;
5731 }
5732
5733 *parent = gdata->dpid;
5734
5735 LeaveCriticalSection( &This->lock );
5736
5737 return DP_OK;
5738}
5741 DWORD flags, void *data, DWORD *size )
5742{
5744 return IDirectPlayX_GetPlayerAccount( &This->IDirectPlay4A_iface, player, flags, data, size );
5745}
5747static HRESULT WINAPI IDirectPlay3Impl_GetPlayerAccount( IDirectPlay3 *iface, DPID player,
5748 DWORD flags, void *data, DWORD *size )
5749{
5751 return IDirectPlayX_GetPlayerAccount( &This->IDirectPlay4_iface, player, flags, data, size );
5752}
5755 DWORD flags, void *data, DWORD *size )
5756{
5758 FIXME("(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, player, flags, data, size );
5759 return DP_OK;
5760}
5762static HRESULT WINAPI IDirectPlay4Impl_GetPlayerAccount( IDirectPlay4 *iface, DPID player,
5763 DWORD flags, void *data, DWORD *size )
5764{
5766 FIXME( "(%p)->(0x%08lx,0x%08lx,%p,%p): stub\n", This, player, flags, data, size );
5767 return DP_OK;
5768}
5771 DWORD *flags )
5772{
5774 return IDirectPlayX_GetPlayerFlags( &This->IDirectPlay4A_iface, player, flags );
5775}
5777static HRESULT WINAPI IDirectPlay3Impl_GetPlayerFlags( IDirectPlay3 *iface, DPID player,
5778 DWORD *flags )
5779{
5781 return IDirectPlayX_GetPlayerFlags( &This->IDirectPlay4_iface, player, flags );
5782}
5785 DWORD *flags )
5786{
5788 return IDirectPlayX_GetPlayerFlags( &This->IDirectPlay4_iface, player, flags );
5789}
5791static HRESULT WINAPI IDirectPlay4Impl_GetPlayerFlags( IDirectPlay4 *iface, DPID player,
5792 DWORD *flags )
5793{
5795 FIXME( "(%p)->(0x%08lx,%p): stub\n", This, player, flags );
5796 return DP_OK;
5797}
5800 DPID *owner )
5801{
5803 return IDirectPlayX_GetGroupOwner( &This->IDirectPlay4_iface, group, owner );
5804}
5806static HRESULT WINAPI IDirectPlay4Impl_GetGroupOwner( IDirectPlay4 *iface, DPID group,
5807 DPID *owner )
5808{
5810 FIXME( "(%p)->(0x%08lx,%p): stub\n", This, group, owner );
5811 return DP_OK;
5812}
5815 DPID owner )
5816{
5818 return IDirectPlayX_SetGroupOwner( &This->IDirectPlay4_iface, group, owner );
5819}
5821static HRESULT WINAPI IDirectPlay4Impl_SetGroupOwner( IDirectPlay4 *iface, DPID group ,
5822 DPID owner )
5823{
5825 FIXME( "(%p)->(0x%08lx,0x%08lx): stub\n", This, group, owner );
5826 return DP_OK;
5827}
5831 DWORD *msgid )
5832{
5834 return IDirectPlayX_SendEx( &This->IDirectPlay4_iface, from, to, flags, data, size, priority,
5835 timeout, context, msgid );
5836}
5838static HRESULT WINAPI IDirectPlay4Impl_SendEx( IDirectPlay4 *iface, DPID from, DPID to,
5840 DWORD *msgid )
5841{
5843 DPMSG_SYSMSGENVELOPE envelope;
5844 SGBUFFER buffers[ 3 ] = { 0 };
5845 HRESULT hr;
5846
5847 TRACE( "(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx,0x%08lx,0x%08lx,%p,%p)\n",
5848 This, from, to, flags, data, size, priority, timeout, context, msgid );
5849
5850 if ( This->dp2->connectionInitialized == NO_PROVIDER )
5851 return DPERR_UNINITIALIZED;
5852
5853 /* FIXME: Add parameter checking */
5854 /* FIXME: First call to this needs to acquire a message id which will be
5855 * used for multiple sends
5856 */
5857
5858 /* NOTE: Can't send messages to yourself - this will be trapped in receive */
5859
5860 EnterCriticalSection( &This->lock );
5861
5862 /* Verify that the message is being sent from a valid local player. The
5863 * from player may be anonymous DPID_UNKNOWN
5864 */
5865 if ( from != DPID_UNKNOWN && !DP_FindPlayer( This, from ) )
5866 {
5867 WARN( "INFO: Invalid from player 0x%08lx\n", from );
5868 LeaveCriticalSection( &This->lock );
5869 return DPERR_INVALIDPLAYER;
5870 }
5871
5873 if ( FAILED( hr ) )
5874 {
5875 LeaveCriticalSection( &This->lock );
5876 return hr;
5877 }
5878
5879 envelope.dwPlayerFrom = from;
5880 envelope.dwPlayerTo = to;
5881
5882 buffers[ 0 ].len = This->dp2->spData.dwSPHeaderSize;
5883 buffers[ 0 ].pData = NULL;
5884 buffers[ 1 ].len = sizeof( envelope );
5885 buffers[ 1 ].pData = (UCHAR *)&envelope;
5886 buffers[ 2 ].len = size;
5887 buffers[ 2 ].pData = data;
5888
5889 /* Verify that the message is being sent to a valid player, group or to
5890 * everyone. If it's valid, send it to those players.
5891 */
5892 if ( DP_FindPlayer( This, to ) )
5893 {
5894 if ( This->dp2->spData.lpCB->SendEx )
5895 {
5896 DPSP_SENDEXDATA sendData;
5897
5898 sendData.lpISP = This->dp2->spData.lpISP;
5899 sendData.dwFlags = flags;
5900 sendData.idPlayerTo = to;
5901 sendData.idPlayerFrom = from;
5902 sendData.lpSendBuffers = ( flags & DPSEND_GUARANTEED ) ? buffers : &buffers[ 1 ];
5903 sendData.cBuffers = ( flags & DPSEND_GUARANTEED ) ? 3 : 2;
5905 sendData.cBuffers );
5906 sendData.dwPriority = priority;
5907 sendData.dwTimeout = timeout;
5908 sendData.lpDPContext = context;
5909 sendData.lpdwSPMsgID = msgid;
5910 sendData.bSystemMessage = FALSE;
5911
5912 hr = This->dp2->spData.lpCB->SendEx( &sendData );
5913
5914 LeaveCriticalSection( &This->lock );
5915
5916 return hr;
5917 }
5918 else
5919 FIXME( "Use obsolete send\n" );
5920 }
5921 else if ( DP_FindAnyGroup( This, to ) )
5922 {
5923 /* See if SP has the ability to multicast. If so, use it */
5924 if ( This->dp2->spData.lpCB->SendToGroupEx )
5925 {
5926 DPSP_SENDTOGROUPEXDATA sendData;
5927
5928 sendData.lpISP = This->dp2->spData.lpISP;
5929 sendData.dwFlags = flags;
5930 sendData.idGroupTo = to;
5931 sendData.idPlayerFrom = from;
5932 sendData.lpSendBuffers = ( flags & DPSEND_GUARANTEED ) ? buffers : &buffers[ 1 ];
5933 sendData.cBuffers = ( flags & DPSEND_GUARANTEED ) ? 3 : 2;
5935 sendData.cBuffers );
5936 sendData.dwPriority = priority;
5937 sendData.dwTimeout = timeout;
5938 sendData.lpDPContext = context;
5939 sendData.lpdwSPMsgID = msgid;
5940
5941 hr = This->dp2->spData.lpCB->SendToGroupEx( &sendData );
5942
5943 LeaveCriticalSection( &This->lock );
5944
5945 return hr;
5946 }
5947 else if ( This->dp2->spData.lpCB->SendToGroup ) /* obsolete interface */
5948 FIXME( "Use obsolete group send to group\n" );
5949 else /* No multicast, multiplicate */
5950 FIXME( "Send to all players using EnumPlayersInGroup\n" );
5951
5952 }
5953 else
5954 {
5955 LeaveCriticalSection( &This->lock );
5956 return DPERR_INVALIDPLAYER;
5957 }
5958
5959 LeaveCriticalSection( &This->lock );
5960
5961 return DP_OK;
5962}
5965 DWORD flags, DWORD *msgs, DWORD *bytes )
5966{
5968 return IDirectPlayX_GetMessageQueue( &This->IDirectPlay4_iface, from, to, flags, msgs, bytes );
5969}
5971static HRESULT WINAPI IDirectPlay4Impl_GetMessageQueue( IDirectPlay4 *iface, DPID from, DPID to,
5972 DWORD flags, DWORD *msgs, DWORD *bytes )
5973{
5975 struct PlayerList *playerFrom = NULL;
5976 struct PlayerList *playerTo = NULL;
5977 HRESULT hr = DP_OK;
5978
5979 TRACE( "(%p)->(0x%08lx,0x%08lx,0x%08lx,%p,%p)\n", This, from, to, flags, msgs, bytes );
5980
5981 if ( This->dp2->connectionInitialized == NO_PROVIDER )
5982 return DPERR_UNINITIALIZED;
5983
5984 if ( !flags )
5986
5988 return DPERR_INVALIDFLAGS;
5989
5990 EnterCriticalSection( &This->lock );
5991
5992 if ( to )
5993 {
5994 playerTo = DP_FindPlayer( This, to );
5995 if ( !playerTo )
5996 {
5997 LeaveCriticalSection( &This->lock );
5998 return DPERR_INVALIDPLAYER;
5999 }
6000 }
6001
6002 if ( from )
6003 {
6004 playerFrom = DP_FindPlayer( This, from );
6005 if ( !playerFrom )
6006 {
6007 LeaveCriticalSection( &This->lock );
6008 return DPERR_INVALIDPLAYER;
6009 }
6010 }
6011
6013 {
6014 DWORD byteCount = 0;
6015 DWORD msgCount = 0;
6016 struct DPMSG *msg;
6017
6018 if ( playerTo && !(playerTo->lpPData->dwFlags & DPPLAYER_LOCAL) )
6019 {
6020 LeaveCriticalSection( &This->lock );
6021 return DPERR_INVALIDPLAYER;
6022 }
6023
6024 for ( msg = DPQ_FIRST( This->dp2->receiveMsgs ); msg; msg = DPQ_NEXT( msg->msgs ) )
6025 {
6026 if( from && msg->fromId != from )
6027 continue;
6028 if( to && msg->toId != to )
6029 continue;
6030
6031 ++msgCount;
6032 byteCount += msg->copyMessage( NULL, msg->msg, msg->genericSize, FALSE );
6033 }
6034
6035 if ( msgs )
6036 *msgs = msgCount;
6037 if ( bytes )
6038 *bytes = byteCount;
6039
6040 LeaveCriticalSection( &This->lock );
6041
6042 return DP_OK;
6043 }
6044
6045 /* FIXME: Do we need to do from and to sanity checking here? */
6046 /* FIXME: What about sends which are not immediate? */
6047
6048 if ( This->dp2->spData.lpCB->GetMessageQueue )
6049 {
6051
6052 FIXME( "Calling SP GetMessageQueue - is it right?\n" );
6053
6054 /* FIXME: None of this is documented :( */
6055 data.lpISP = This->dp2->spData.lpISP;
6056 data.dwFlags = flags;
6057 data.idFrom = from;
6058 data.idTo = to;
6059 data.lpdwNumMsgs = msgs;
6060 data.lpdwNumBytes = bytes;
6061
6062 hr = (*This->dp2->spData.lpCB->GetMessageQueue)( &data );
6063 }
6064 else
6065 FIXME( "No SP for GetMessageQueue - fake some data\n" );
6066
6067 LeaveCriticalSection( &This->lock );
6068
6069 return hr;
6070}
6073 DWORD maxprio )
6074{
6075 HRESULT hr = DP_OK;
6076
6077 FIXME( "(%p)->(0x%08lx,0x%08lx): semi stub\n", This, msgid, flags );
6078
6079 if ( This->dp2->spData.lpCB->Cancel )
6080 {
6082
6083 TRACE( "Calling SP Cancel\n" );
6084
6085 /* FIXME: Undocumented callback */
6086
6087 data.lpISP = This->dp2->spData.lpISP;
6088 data.dwFlags = flags;
6089 data.lprglpvSPMsgID = NULL;
6090 data.cSPMsgID = msgid;
6091 data.dwMinPriority = minprio;
6092 data.dwMaxPriority = maxprio;
6093
6094 hr = (*This->dp2->spData.lpCB->Cancel)( &data );
6095 }
6096 else
6097 FIXME( "SP doesn't implement Cancel\n" );
6098
6099 return hr;
6100}
6103 DWORD flags )
6104{
6106 return IDirectPlayX_CancelMessage( &This->IDirectPlay4_iface, msgid, flags );
6107}
6109static HRESULT WINAPI IDirectPlay4Impl_CancelMessage( IDirectPlay4 *iface, DWORD msgid,
6110 DWORD flags )
6111{
6113
6114 if ( flags != 0 )
6115 return DPERR_INVALIDFLAGS;
6116
6117 if ( msgid == 0 )
6119
6120 return dplay_cancelmsg( This, msgid, flags, 0, 0 );
6121}
6124 DWORD maxprio, DWORD flags )
6125{
6127 return IDirectPlayX_CancelPriority( &This->IDirectPlay4_iface, minprio, maxprio, flags );
6128}
6130static HRESULT WINAPI IDirectPlay4Impl_CancelPriority( IDirectPlay4 *iface, DWORD minprio,
6131 DWORD maxprio, DWORD flags )
6132{
6134
6135 if ( flags != 0 )
6136 return DPERR_INVALIDFLAGS;
6137
6138 return dplay_cancelmsg( This, 0, DPCANCELSEND_PRIORITY, minprio, maxprio );
6139}
6141static const IDirectPlay2Vtbl dp2_vt =
6142{
6175};
6177static const IDirectPlay2Vtbl dp2A_vt =
6178{
6211};
6213static const IDirectPlay3Vtbl dp3_vt =
6214{
6262};
6264static const IDirectPlay3Vtbl dp3A_vt =
6265{
6313};
6315static const IDirectPlay4Vtbl dp4_vt =
6316{
6370};
6372static const IDirectPlay4Vtbl dp4A_vt =
6373{
6427};
6430{
6432 HRESULT hr;
6433
6434 TRACE( "(%s, %p)\n", debugstr_guid( riid ), ppv );
6435
6436 *ppv = NULL;
6437 obj = malloc( sizeof( *obj ) );
6438 if ( !obj )
6439 return DPERR_OUTOFMEMORY;
6440
6441 obj->IDirectPlay_iface.lpVtbl = &dp_vt;
6442 obj->IDirectPlay2A_iface.lpVtbl = &dp2A_vt;
6443 obj->IDirectPlay2_iface.lpVtbl = &dp2_vt;
6444 obj->IDirectPlay3A_iface.lpVtbl = &dp3A_vt;
6445 obj->IDirectPlay3_iface.lpVtbl = &dp3_vt;
6446 obj->IDirectPlay4A_iface.lpVtbl = &dp4A_vt;
6447 obj->IDirectPlay4_iface.lpVtbl = &dp4_vt;
6448 obj->ref = 1;
6449
6451 obj->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectPlayImpl.lock");
6452
6453 if ( DP_CreateDirectPlay2( obj ) )
6454 hr = IDirectPlayX_QueryInterface( &obj->IDirectPlay4_iface, riid, ppv );
6455 else
6457 IDirectPlayX_Release( &obj->IDirectPlay4_iface );
6458
6459 return hr;
6460}
6461
6463HRESULT DP_GetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void **lplpData )
6464{
6465 struct GroupData *group;
6466 lpPlayerList lpPlayer;
6467
6468 EnterCriticalSection( &lpDP->lock );
6469
6470 lpPlayer = DP_FindPlayer( lpDP, idPlayer );
6471 if( lpPlayer )
6472 {
6473 *lplpData = lpPlayer->lpPData->lpSPPlayerData;
6474 LeaveCriticalSection( &lpDP->lock );
6475 return DP_OK;
6476 }
6477
6478 group = DP_FindAnyGroup( lpDP, idPlayer );
6479 if( group )
6480 {
6481 *lplpData = group->lpSPPlayerData;
6482 LeaveCriticalSection( &lpDP->lock );
6483 return DP_OK;
6484 }
6485
6486 LeaveCriticalSection( &lpDP->lock );
6487
6488 return DPERR_INVALIDPLAYER;
6489}
6491HRESULT DP_SetSPPlayerData( IDirectPlayImpl *lpDP, DPID idPlayer, void *lpData )
6492{
6493 struct GroupData *group;
6494 lpPlayerList lpPlayer;
6495
6496 EnterCriticalSection( &lpDP->lock );
6497
6498 lpPlayer = DP_FindPlayer( lpDP, idPlayer );
6499 if( lpPlayer )
6500 {
6501 lpPlayer->lpPData->lpSPPlayerData = lpData;
6502 LeaveCriticalSection( &lpDP->lock );
6503 return DP_OK;
6504 }
6505
6506 group = DP_FindAnyGroup( lpDP, idPlayer );
6507 if( group )
6508 {
6509 group->lpSPPlayerData = lpData;
6510 LeaveCriticalSection( &lpDP->lock );
6511 return DP_OK;
6512 }
6513
6514 LeaveCriticalSection( &lpDP->lock );
6515
6516 return DPERR_INVALIDPLAYER;
6517}
6518
6519/***************************************************************************
6520 * DirectPlayEnumerateAW
6521 *
6522 * The pointer to the structure lpContext will be filled with the
6523 * appropriate data for each service offered by the OS. These services are
6524 * not necessarily available on this particular machine but are defined
6525 * as simple service providers under the "Service Providers" registry key.
6526 * This structure is then passed to lpEnumCallback for each of the different
6527 * services.
6528 *
6529 * This API is useful only for applications written using DirectX3 or
6530 * worse. It is superseded by IDirectPlay3::EnumConnections which also
6531 * gives information on the actual connections.
6532 *
6533 * defn of a service provider:
6534 * A dynamic-link library used by DirectPlay to communicate over a network.
6535 * The service provider contains all the network-specific code required
6536 * to send and receive messages. Online services and network operators can
6537 * supply service providers to use specialized hardware, protocols, communications
6538 * media, and network resources.
6539 *
6542 LPDPENUMDPCALLBACKW lpEnumCallbackW,
6543 LPVOID lpContext)
6544{
6546 struct list *connections;
6547
6548 if (!lpEnumCallbackA && !lpEnumCallbackW)
6549 {
6550 return DPERR_INVALIDPARAMS;
6551 }
6552
6554
6556 {
6557 if (!(connection->flags & DPCONNECTION_DIRECTPLAY))
6558 continue;
6559
6560 /* The enumeration will return FALSE if we are not to continue.
6561 *
6562 * Note: on my windows box, major / minor version is 6 / 0 for all service providers
6563 * and have no relation to any of the two dwReserved1 and dwReserved2 keys.
6564 * I think that it simply means that they are in-line with DirectX 6.0
6565 */
6566 if (lpEnumCallbackA)
6567 {
6568 if (!lpEnumCallbackA(&connection->spGuid, connection->nameA.lpszShortNameA, 6, 0,
6569 lpContext))
6570 break;
6571 }
6572 else
6573 {
6574 if (!lpEnumCallbackW(&connection->spGuid, connection->name.lpszShortName, 6, 0,
6575 lpContext))
6576 break;
6577 }
6578 }
6579
6580 return DP_OK;
6581}
6582
6583/***************************************************************************
6584 * DirectPlayEnumerate [DPLAYX.9]
6585 * DirectPlayEnumerateA [DPLAYX.2]
6588{
6589 TRACE("(%p,%p)\n", lpEnumCallback, lpContext);
6590
6591 return DirectPlayEnumerateAW(lpEnumCallback, NULL, lpContext);
6592}
6593
6594/***************************************************************************
6595 * DirectPlayEnumerateW [DPLAYX.3]
6598{
6599 TRACE("(%p,%p)\n", lpEnumCallback, lpContext);
6600
6601 return DirectPlayEnumerateAW(NULL, lpEnumCallback, lpContext);
6602}
6604typedef struct tagCreateEnum
6609
6610/* Find and copy the matching connection for the SP guid */
6612 LPCGUID lpguidSP,
6613 LPVOID lpConnection,
6614 DWORD dwConnectionSize,
6616 DWORD dwFlags,
6617 LPVOID lpContext)
6618{
6619 lpCreateEnumData lpData = (lpCreateEnumData)lpContext;
6620
6621 if( IsEqualGUID( lpguidSP, lpData->lpGuid ) )
6622 {
6623 TRACE( "Found SP entry with guid %s\n", debugstr_guid(lpData->lpGuid) );
6624
6625 lpData->lpConn = malloc( dwConnectionSize );
6626 CopyMemory( lpData->lpConn, lpConnection, dwConnectionSize );
6627
6628 /* Found the record that we were looking for */
6629 return FALSE;
6630 }
6631
6632 /* Haven't found what were looking for yet */
6633 return TRUE;
6634}
6635
6636
6637/***************************************************************************
6638 * DirectPlayCreate [DPLAYX.1]
6639 *
6642( LPGUID lpGUID, LPDIRECTPLAY *lplpDP, IUnknown *pUnk )
6643{
6644 HRESULT hr;
6645 LPDIRECTPLAY3A lpDP3A;
6647
6648 TRACE( "lpGUID=%s lplpDP=%p pUnk=%p\n", debugstr_guid(lpGUID), lplpDP, pUnk );
6649
6650 if( pUnk != NULL )
6651 {
6652 return CLASS_E_NOAGGREGATION;
6653 }
6654
6655 if( (lplpDP == NULL) || (lpGUID == NULL) )
6656 {
6657 return DPERR_INVALIDPARAMS;
6658 }
6659
6660 if ( dplay_create( &IID_IDirectPlay, (void**)lplpDP ) != DP_OK )
6661 return DPERR_UNAVAILABLE;
6662
6663 if( IsEqualGUID( &GUID_NULL, lpGUID ) )
6664 {
6665 /* The GUID_NULL means don't bind a service provider. Just return the
6666 interface as is */
6667 return DP_OK;
6668 }
6669
6670 /* Bind the desired service provider since lpGUID is non NULL */
6671 TRACE( "Service Provider binding for %s\n", debugstr_guid(lpGUID) );
6672
6673 /* We're going to use a DP3 interface */
6674 hr = IDirectPlayX_QueryInterface( *lplpDP, &IID_IDirectPlay3A,
6675 (LPVOID*)&lpDP3A );
6676 if( FAILED(hr) )
6677 {
6678 ERR( "Failed to get DP3 interface: %s\n", DPLAYX_HresultToString(hr) );
6679 return hr;
6680 }
6681
6682 cbData.lpConn = NULL;
6683 cbData.lpGuid = lpGUID;
6684
6685 /* We were given a service provider, find info about it... */
6688 if( ( FAILED(hr) ) ||
6689 ( cbData.lpConn == NULL )
6690 )
6691 {
6692 ERR( "Failed to get Enum for SP: %s\n", DPLAYX_HresultToString(hr) );
6693 IDirectPlayX_Release( lpDP3A );
6694 return DPERR_UNAVAILABLE;
6695 }
6696
6697 /* Initialize the service provider */
6698 hr = IDirectPlayX_InitializeConnection( lpDP3A, cbData.lpConn, 0 );
6699 if( FAILED(hr) )
6700 {
6701 ERR( "Failed to Initialize SP: %s\n", DPLAYX_HresultToString(hr) );
6702 free( cbData.lpConn );
6703 IDirectPlayX_Release( lpDP3A );
6704 return hr;
6705 }
6706
6707 /* Release our version of the interface now that we're done with it */
6708 IDirectPlayX_Release( lpDP3A );
6709 free( cbData.lpConn );
6710
6711 return DP_OK;
6712}
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
static UCHAR password[]
Definition: bcrypt.c:520
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: list.h:39
static const WCHAR connections[]
Definition: connections.c:41
#define E_NOTIMPL
Definition: ddrawi.h:99
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HINSTANCE instance
Definition: main.c:35
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LSTATUS WINAPI RegGetValueA(HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:2037
LONG WINAPI RegEnumKeyExA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2419
HRESULT WINAPI CLSIDFromString(LPCOLESTR str, LPCLSID clsid)
Definition: combase.c:1470
#define CloseHandle
Definition: compat.h:739
#define CP_ACP
Definition: compat.h:109
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define GetCurrentProcess()
Definition: compat.h:759
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
HINTERNET connection
Definition: port.c:65
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:587
BOOL WINAPI InitOnceExecuteOnce(_Inout_ PINIT_ONCE InitOnce, _In_ __callback PINIT_ONCE_FN InitFn, _Inout_opt_ PVOID Parameter, _Outptr_opt_result_maybenull_ LPVOID *Context)
Definition: InitOnce.c:12
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
GUID guid
Definition: version.c:147
_ACRTIMP int __cdecl swscanf(const wchar_t *, const wchar_t *,...)
Definition: scanf.c:438
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
#define INT_MAX
Definition: limits.h:26
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
static HRESULT WINAPI IDirectPlay4Impl_SecureOpen(IDirectPlay4 *iface, const DPSESSIONDESC2 *lpsd, DWORD dwFlags, const DPSECURITYDESC *lpSecurity, const DPCREDENTIALS *lpCredentials)
Definition: dplay.c:5568
#define DPMSG_CREATEGROUP_DWFLAGS(x)
Definition: dplay.c:79
static HRESULT WINAPI IDirectPlay4AImpl_EnumGroupPlayers(IDirectPlay4A *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2693
static HRESULT WINAPI IDirectPlay4AImpl_SetPlayerData(IDirectPlay4A *iface, DPID player, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4328
static HRESULT DP_IF_DestroyPlayer(IDirectPlayImpl *This, void *lpMsgHdr, DPID idPlayer, BOOL bAnsi)
Definition: dplay.c:2487
static HRESULT WINAPI IDirectPlayImpl_SetPlayerName(IDirectPlay *iface, DPID player, LPSTR name, LPSTR fullname)
Definition: dplay.c:907
static HRESULT WINAPI IDirectPlay3Impl_GetPlayerData(IDirectPlay3 *iface, DPID player, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3473
static HRESULT WINAPI IDirectPlay2AImpl_CreateGroup(IDirectPlay2A *iface, DPID *lpidGroup, DPNAME *name, void *data, DWORD size, DWORD flags)
Definition: dplay.c:1651
static HRESULT WINAPI IDirectPlay4Impl_EnumSessions(IDirectPlay4 *iface, DPSESSIONDESC2 *sdesc, DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags)
Definition: dplay.c:3108
static HRESULT WINAPI IDirectPlay3AImpl_GetPlayerAccount(IDirectPlay3A *iface, DPID player, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:5739
static HRESULT WINAPI IDirectPlay2Impl_SetPlayerData(IDirectPlay2 *iface, DPID player, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4307
static HRESULT WINAPI IDirectPlay2Impl_SetGroupData(IDirectPlay2 *iface, DPID group, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4144
static HRESULT WINAPI IDirectPlay2AImpl_GetGroupName(IDirectPlay2A *iface, DPID group, void *data, DWORD *size)
Definition: dplay.c:3265
#define DPID_SYSTEM_GROUP
Definition: dplay.c:75
static HRESULT WINAPI IDirectPlay4Impl_GetGroupFlags(IDirectPlay4 *iface, DPID group, DWORD *flags)
Definition: dplay.c:5687
static HRESULT WINAPI IDirectPlay4AImpl_GetGroupParent(IDirectPlay4A *iface, DPID group, DPID *parent)
Definition: dplay.c:5709
static HRESULT WINAPI IDirectPlayImpl_Close(IDirectPlay *iface)
Definition: dplay.c:753
static HRESULT WINAPI IDirectPlay3AImpl_DeletePlayerFromGroup(IDirectPlay3A *iface, DPID group, DPID player)
Definition: dplay.c:2271
static HRESULT WINAPI IDirectPlay4Impl_EnumGroupPlayers(IDirectPlay4 *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2700
static HRESULT WINAPI IDirectPlay2AImpl_Open(IDirectPlay2A *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:3956
static HRESULT WINAPI IDirectPlay3AImpl_CreateGroup(IDirectPlay3A *iface, DPID *group, DPNAME *name, void *data, DWORD size, DWORD flags)
Definition: dplay.c:1667
static HRESULT WINAPI IDirectPlay4Impl_AddPlayerToGroup(IDirectPlay4 *iface, DPID group, DPID player)
Definition: dplay.c:1284
static HRESULT WINAPI IDirectPlay3Impl_GetPlayerCaps(IDirectPlay3 *iface, DPID player, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3412
static IDirectPlayImpl * impl_from_IDirectPlay(IDirectPlay *iface)
Definition: dplay.c:87
static HRESULT WINAPI IDirectPlay2AImpl_GetMessageCount(IDirectPlay2A *iface, DPID player, DWORD *count)
Definition: dplay.c:3307
static HRESULT WINAPI IDirectPlay4AImpl_DestroyGroup(IDirectPlay4A *iface, DPID idGroup)
Definition: dplay.c:2468
static HRESULT WINAPI IDirectPlay3AImpl_Open(IDirectPlay3A *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:3970
static HRESULT WINAPI IDirectPlay3AImpl_Initialize(IDirectPlay3A *iface, GUID *guid)
Definition: dplay.c:3709
static BOOL DP_CreateDirectPlay2(LPVOID lpDP)
Definition: dplay.c:122
static HRESULT WINAPI IDirectPlay4Impl_GetGroupData(IDirectPlay4 *iface, DPID group, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3184
static HRESULT WINAPI IDirectPlay4Impl_GetMessageCount(IDirectPlay4 *iface, DPID player, DWORD *count)
Definition: dplay.c:3341
static HRESULT WINAPI IDirectPlay3Impl_GetPlayerAccount(IDirectPlay3 *iface, DPID player, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:5746
static HRESULT WINAPI IDirectPlay4Impl_GetPlayerName(IDirectPlay4 *iface, DPID idPlayer, void *lpData, DWORD *lpdwDataSize)
Definition: dplay.c:3611
static HRESULT WINAPI IDirectPlay4Impl_Send(IDirectPlay4 *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size)
Definition: dplay.c:4131
static HRESULT WINAPI IDirectPlayImpl_CreatePlayer(IDirectPlay *iface, DPID *player, LPSTR name, LPSTR fullname, HANDLE *event)
Definition: dplay.c:760
static HRESULT WINAPI IDirectPlay3Impl_GetGroupParent(IDirectPlay3 *iface, DPID group, DPID *parent)
Definition: dplay.c:5702
static void dplay_destroy(IDirectPlayImpl *obj)
Definition: dplay.c:247
static HRESULT WINAPI IDirectPlay4AImpl_DeleteGroupFromGroup(IDirectPlay4A *iface, DPID parent, DPID group)
Definition: dplay.c:4772
static HRESULT WINAPI IDirectPlay2Impl_EnumGroupPlayers(IDirectPlay2 *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2616
HRESULT DP_SetSPPlayerData(IDirectPlayImpl *lpDP, DPID idPlayer, void *lpData)
Definition: dplay.c:6490
static HRESULT WINAPI IDirectPlay3AImpl_GetGroupData(IDirectPlay3A *iface, DPID group, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3163
static HRESULT WINAPI IDirectPlay2AImpl_Receive(IDirectPlay2A *iface, DPID *from, DPID *to, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:4055
static HRESULT WINAPI IDirectPlay4Impl_SetPlayerData(IDirectPlay4 *iface, DPID player, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4335
static BOOL DP_GetRegDword(HKEY key, const WCHAR *name, DWORD *value)
Definition: dplay.c:4923
static HRESULT WINAPI IDirectPlay3Impl_SetSessionDesc(IDirectPlay3 *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:4542
static HRESULT WINAPI IDirectPlayImpl_Initialize(IDirectPlay *iface, GUID *guid)
Definition: dplay.c:870
static HRESULT WINAPI IDirectPlay2Impl_SetPlayerName(IDirectPlay2 *iface, DPID player, DPNAME *name, DWORD flags)
Definition: dplay.c:4433
static HRESULT WINAPI IDirectPlay3Impl_CreateGroupInGroup(IDirectPlay3 *iface, DPID parent, DPID *group, DPNAME *name, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4727
static HRESULT WINAPI IDirectPlay2Impl_GetPlayerName(IDirectPlay2 *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3583
static HRESULT WINAPI IDirectPlay4AImpl_GetPlayerCaps(IDirectPlay4A *iface, DPID player, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3419
static HRESULT WINAPI IDirectPlay3AImpl_EnumSessions(IDirectPlay3A *iface, DPSESSIONDESC2 *sdesc, DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags)
Definition: dplay.c:2912
static HRESULT WINAPI IDirectPlay4Impl_SetGroupConnectionSettings(IDirectPlay4 *iface, DWORD flags, DPID group, DPLCONNECTION *connection)
Definition: dplay.c:5630
static HRESULT WINAPI IDirectPlay2Impl_GetPlayerAddress(IDirectPlay2 *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3354
static HRESULT DP_IF_CreateGroup(IDirectPlayImpl *This, void *lpMsgHdr, DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi)
Definition: dplay.c:1578
HRESULT WINAPI DirectPlayCreate(LPGUID lpGUID, LPDIRECTPLAY *lplpDP, IUnknown *pUnk)
Definition: dplay.c:6641
HRESULT DP_HandleMessage(IDirectPlayImpl *This, void *messageBody, DWORD dwMessageBodySize, void *messageHeader, WORD wCommandId, WORD wVersion, void **lplpReply, DWORD *lpdwMsgSize)
Definition: dplay.c:453
static HRESULT DP_InitializeDPLSP(IDirectPlayImpl *This, HMODULE hLobbyProvider)
Definition: dplay.c:5420
static HRESULT WINAPI IDirectPlay3Impl_SetPlayerName(IDirectPlay3 *iface, DPID player, DPNAME *name, DWORD flags)
Definition: dplay.c:4447
static HRESULT WINAPI IDirectPlay3Impl_SendChatMessage(IDirectPlay3 *iface, DPID from, DPID to, DWORD flags, DPCHAT *chatmsg)
Definition: dplay.c:5583
static const IDirectPlay4Vtbl dp4_vt
Definition: dplay.c:6314
static HRESULT WINAPI IDirectPlay4Impl_DeleteGroupFromGroup(IDirectPlay4 *iface, DPID parent, DPID group)
Definition: dplay.c:4779
static HRESULT WINAPI IDirectPlay4Impl_DestroyPlayer(IDirectPlay4 *iface, DPID idPlayer)
Definition: dplay.c:2602
static HRESULT WINAPI IDirectPlay4AImpl_AddGroupToGroup(IDirectPlay4A *iface, DPID parent, DPID group)
Definition: dplay.c:4609
static HRESULT WINAPI IDirectPlay4AImpl_QueryInterface(IDirectPlay4A *iface, REFIID riid, void **ppv)
Definition: dplay.c:974
static HRESULT WINAPI IDirectPlay4AImpl_GetGroupFlags(IDirectPlay4A *iface, DPID group, DWORD *flags)
Definition: dplay.c:5680
static HRESULT WINAPI IDirectPlay4AImpl_EnumGroups(IDirectPlay4A *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2740
static HRESULT WINAPI IDirectPlay3Impl_Send(IDirectPlay3 *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size)
Definition: dplay.c:4118
static HRESULT WINAPI IDirectPlay2AImpl_EnumGroupPlayers(IDirectPlay2A *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2608
static HRESULT WINAPI IDirectPlay2Impl_GetMessageCount(IDirectPlay2 *iface, DPID player, DWORD *count)
Definition: dplay.c:3314
static HRESULT WINAPI IDirectPlay3AImpl_GetPlayerAddress(IDirectPlay3A *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3361
static HRESULT WINAPI IDirectPlay4AImpl_CreateGroupInGroup(IDirectPlay4A *iface, DPID idParentGroup, DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags)
Definition: dplay.c:4735
static HRESULT WINAPI IDirectPlay4Impl_GetPlayerAddress(IDirectPlay4 *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3383
static HRESULT WINAPI IDirectPlay3Impl_GetPlayerAddress(IDirectPlay3 *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3368
static HRESULT WINAPI IDirectPlay3Impl_EnumGroups(IDirectPlay3 *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2732
static HRESULT WINAPI IDirectPlay3Impl_CreatePlayer(IDirectPlay3 *iface, DPID *lpidPlayer, DPNAME *name, HANDLE event, void *data, DWORD size, DWORD flags)
Definition: dplay.c:2225
static void DP_KillEnumSessionThread(IDirectPlayImpl *This)
Definition: dplay.c:2877
static HRESULT WINAPI IDirectPlay2Impl_QueryInterface(IDirectPlay2 *iface, REFIID riid, void **ppv)
Definition: dplay.c:953
static HRESULT WINAPI IDirectPlay3AImpl_GetPlayerFlags(IDirectPlay3A *iface, DPID player, DWORD *flags)
Definition: dplay.c:5769
struct tagCreateEnum * lpCreateEnumData
static ULONG WINAPI IDirectPlay2AImpl_Release(IDirectPlay2A *iface)
Definition: dplay.c:1097
static HRESULT WINAPI IDirectPlay2Impl_GetPlayerData(IDirectPlay2 *iface, DPID player, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3459
static HRESULT WINAPI IDirectPlay3Impl_GetMessageCount(IDirectPlay3 *iface, DPID player, DWORD *count)
Definition: dplay.c:3328
static HRESULT WINAPI IDirectPlay3AImpl_EnumConnections(IDirectPlay3A *iface, const GUID *application, LPDPENUMCONNECTIONSCALLBACK enumcb, void *context, DWORD flags)
Definition: dplay.c:4857
static HRESULT WINAPI IDirectPlay2Impl_GetSessionDesc(IDirectPlay2 *iface, void *data, DWORD *size)
Definition: dplay.c:3662
static HRESULT WINAPI IDirectPlay3AImpl_StartSession(IDirectPlay3A *iface, DWORD flags, DPID group)
Definition: dplay.c:5638
static HRESULT WINAPI IDirectPlay3AImpl_DestroyGroup(IDirectPlay3A *iface, DPID group)
Definition: dplay.c:2456
static HRESULT WINAPI IDirectPlay3Impl_QueryInterface(IDirectPlay3 *iface, REFIID riid, void **ppv)
Definition: dplay.c:967
static HRESULT WINAPI IDirectPlay4AImpl_GetPlayerAddress(IDirectPlay4A *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3375
static HRESULT WINAPI IDirectPlay3Impl_StartSession(IDirectPlay3 *iface, DWORD flags, DPID group)
Definition: dplay.c:5645
static HRESULT WINAPI IDirectPlay2Impl_DestroyPlayer(IDirectPlay2 *iface, DPID player)
Definition: dplay.c:2578
static HRESULT WINAPI IDirectPlay3AImpl_GetGroupConnectionSettings(IDirectPlay3A *iface, DWORD flags, DPID group, void *data, DWORD *size)
Definition: dplay.c:5285
struct _DPFAGContext * lpDPFAGContext
static HRESULT WINAPI IDirectPlayImpl_Receive(IDirectPlay *iface, DPID *from, DPID *to, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:884
static HRESULT WINAPI IDirectPlay2Impl_SetGroupName(IDirectPlay2 *iface, DPID group, DPNAME *name, DWORD flags)
Definition: dplay.c:4265
static HRESULT WINAPI IDirectPlay3Impl_SetPlayerData(IDirectPlay3 *iface, DPID player, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4321
static void DP_DeleteGroup(IDirectPlayImpl *This, DPID dpid)
Definition: dplay.c:1523
static HRESULT WINAPI IDirectPlay3AImpl_Send(IDirectPlay3A *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size)
Definition: dplay.c:4111
static HRESULT WINAPI IDirectPlay3AImpl_EnumPlayers(IDirectPlay3A *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2770
static HRESULT WINAPI IDirectPlay2AImpl_CreatePlayer(IDirectPlay2A *iface, DPID *lpidPlayer, DPNAME *name, HANDLE event, void *data, DWORD size, DWORD flags)
Definition: dplay.c:2201
static BOOL CALLBACK cbRemoveGroupOrPlayer(DPID dpId, DWORD dwPlayerType, LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)
Definition: dplay.c:2362
static HRESULT WINAPI IDirectPlay4AImpl_EnumSessions(IDirectPlay4A *iface, DPSESSIONDESC2 *sdesc, DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags)
Definition: dplay.c:3101
static HRESULT WINAPI IDirectPlay2Impl_Close(IDirectPlay2 *iface)
Definition: dplay.c:1327
static lpGroupData DP_FindAnyGroup(IDirectPlayImpl *This, DPID dpid)
Definition: dplay.c:1554
static HRESULT WINAPI IDirectPlay3Impl_DeletePlayerFromGroup(IDirectPlay3 *iface, DPID group, DPID player)
Definition: dplay.c:2278
static BOOL DP_BuildSPCompoundAddr(LPGUID lpcSpGuid, LPVOID *lplpAddrBuf, LPDWORD lpdwBufSize)
Definition: dplay.c:4820
static HRESULT dplay_cancelmsg(IDirectPlayImpl *This, DWORD msgid, DWORD flags, DWORD minprio, DWORD maxprio)
Definition: dplay.c:6071
static HRESULT WINAPI IDirectPlay2Impl_EnumSessions(IDirectPlay2 *iface, DPSESSIONDESC2 *sdesc, DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags)
Definition: dplay.c:2904
static HRESULT WINAPI IDirectPlay2AImpl_AddPlayerToGroup(IDirectPlay2A *iface, DPID group, DPID player)
Definition: dplay.c:1175
static HRESULT WINAPI IDirectPlay2AImpl_Close(IDirectPlay2A *iface)
Definition: dplay.c:1321
static HRESULT WINAPI IDirectPlay3Impl_GetPlayerFlags(IDirectPlay3 *iface, DPID player, DWORD *flags)
Definition: dplay.c:5776
static DWORD DP_CopySessionDesc(LPDPSESSIONDESC2 destSessionDesc, LPCDPSESSIONDESC2 srcSessDesc, BOOL dstAnsi, BOOL srcAnsi)
Definition: dplay.c:4563
static HRESULT DP_IF_EnumGroupPlayers(IDirectPlayImpl *This, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags, BOOL ansi)
Definition: dplay.c:2640
static HRESULT WINAPI IDirectPlay2AImpl_Send(IDirectPlay2A *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size)
Definition: dplay.c:4097
static ULONG WINAPI IDirectPlay2Impl_Release(IDirectPlay2 *iface)
Definition: dplay.c:1110
static HRESULT DP_IF_CreateGroupInGroup(IDirectPlayImpl *This, void *lpMsgHdr, DPID idParentGroup, DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi)
Definition: dplay.c:4665
static HRESULT DP_IF_EnumGroupsInGroup(IDirectPlayImpl *This, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags, BOOL ansi)
Definition: dplay.c:5228
static struct list * DP_GetConnections(void)
Definition: dplay.c:5123
static void * DP_DuplicateString(const void *src, BOOL dstAnsi, BOOL srcAnsi)
Definition: dplay.c:302
static HRESULT WINAPI IDirectPlay2AImpl_GetGroupData(IDirectPlay2A *iface, DPID group, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3149
struct _DPRGOPContext DPRGOPContext
static ULONG WINAPI IDirectPlay3Impl_AddRef(IDirectPlay3 *iface)
Definition: dplay.c:1067
static HRESULT WINAPI IDirectPlay3AImpl_CreateGroupInGroup(IDirectPlay3A *iface, DPID parent, DPID *group, DPNAME *name, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4719
static HRESULT WINAPI IDirectPlay2Impl_EnumGroups(IDirectPlay2 *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2716
static HRESULT WINAPI IDirectPlay3Impl_GetGroupFlags(IDirectPlay3 *iface, DPID group, DWORD *flags)
Definition: dplay.c:5673
static HRESULT WINAPI IDirectPlay4AImpl_SetGroupOwner(IDirectPlay4A *iface, DPID group, DPID owner)
Definition: dplay.c:5813
static HRESULT WINAPI IDirectPlay2Impl_Open(IDirectPlay2 *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:3963
static HRESULT WINAPI IDirectPlay3Impl_DestroyPlayer(IDirectPlay3 *iface, DPID player)
Definition: dplay.c:2590
static HRESULT WINAPI IDirectPlay3Impl_AddPlayerToGroup(IDirectPlay3 *iface, DPID group, DPID player)
Definition: dplay.c:1196
static HRESULT DirectPlayEnumerateAW(LPDPENUMDPCALLBACKA lpEnumCallbackA, LPDPENUMDPCALLBACKW lpEnumCallbackW, LPVOID lpContext)
Definition: dplay.c:6540
static HRESULT WINAPI IDirectPlay2AImpl_SetGroupData(IDirectPlay2A *iface, DPID group, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4137
static HRESULT WINAPI IDirectPlay3Impl_GetGroupName(IDirectPlay3 *iface, DPID group, void *data, DWORD *size)
Definition: dplay.c:3286
static HRESULT WINAPI IDirectPlay3Impl_InitializeConnection(IDirectPlay3 *iface, void *connection, DWORD flags)
Definition: dplay.c:5467
static HRESULT WINAPI IDirectPlay4Impl_QueryInterface(IDirectPlay4 *iface, REFIID riid, void **ppv)
Definition: dplay.c:981
static HRESULT WINAPI IDirectPlay2Impl_DeletePlayerFromGroup(IDirectPlay2 *iface, DPID group, DPID player)
Definition: dplay.c:2264
static HRESULT DP_QueueMessage(IDirectPlayImpl *This, DPID fromId, DPID toId, DPID excludeId, void *msg, FN_COPY_MESSAGE *copyMessage, DWORD genericSize)
Definition: dplay.c:361
static HRESULT WINAPI IDirectPlay4AImpl_GetPlayerAccount(IDirectPlay4A *iface, DPID player, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:5753
static HRESULT WINAPI IDirectPlay3AImpl_GetGroupParent(IDirectPlay3A *iface, DPID group, DPID *parent)
Definition: dplay.c:5695
static HRESULT WINAPI IDirectPlay3Impl_SetGroupName(IDirectPlay3 *iface, DPID group, DPNAME *name, DWORD flags)
Definition: dplay.c:4279
static HRESULT WINAPI IDirectPlay3Impl_DeleteGroupFromGroup(IDirectPlay3 *iface, DPID parent, DPID group)
Definition: dplay.c:4765
static HRESULT WINAPI IDirectPlay4AImpl_Send(IDirectPlay4A *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size)
Definition: dplay.c:4125
static ULONG WINAPI IDirectPlay4Impl_AddRef(IDirectPlay4 *iface)
Definition: dplay.c:1087
static HRESULT WINAPI IDirectPlay4Impl_SendChatMessage(IDirectPlay4 *iface, DPID from, DPID to, DWORD flags, DPCHAT *chatmsg)
Definition: dplay.c:5598
static HRESULT WINAPI IDirectPlay4Impl_SetGroupOwner(IDirectPlay4 *iface, DPID group, DPID owner)
Definition: dplay.c:5820
static HRESULT WINAPI IDirectPlay4Impl_GetSessionDesc(IDirectPlay4 *iface, void *lpData, DWORD *lpdwDataSize)
Definition: dplay.c:3690
static LONG kludgePlayerGroupId
Definition: dplay.c:84
static HRESULT WINAPI IDirectPlay3Impl_EnumPlayers(IDirectPlay3 *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2778
static void DP_SetGroupData(lpGroupData lpGData, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize)
Definition: dplay.c:1707
static HRESULT WINAPI IDirectPlay4Impl_CancelMessage(IDirectPlay4 *iface, DWORD msgid, DWORD flags)
Definition: dplay.c:6108
static BOOL DP_InvokeEnumSessionCallbacks(LPDPENUMSESSIONSCALLBACK2 lpEnumSessionsCallback2, LPVOID lpNSInfo, DWORD *timeout, LPVOID lpContext, BOOL ansi)
Definition: dplay.c:2804
static HRESULT DP_GetSessionDesc(IDirectPlayImpl *This, void *lpData, DWORD *lpdwDataSize, BOOL bAnsi)
Definition: dplay.c:3618
static HRESULT WINAPI IDirectPlay4Impl_CreateGroup(IDirectPlay4 *iface, DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags)
Definition: dplay.c:1694
static const IDirectPlay2Vtbl dp2_vt
Definition: dplay.c:6140
static HRESULT WINAPI IDirectPlay4Impl_DeletePlayerFromGroup(IDirectPlay4 *iface, DPID group, DPID player)
Definition: dplay.c:2292
static HRESULT WINAPI IDirectPlay4Impl_SetPlayerName(IDirectPlay4 *iface, DPID idPlayer, DPNAME *lpPlayerName, DWORD dwFlags)
Definition: dplay.c:4461
static IDirectPlayImpl * impl_from_IDirectPlay4A(IDirectPlay4A *iface)
Definition: dplay.c:112
static HRESULT WINAPI IDirectPlay2Impl_CreatePlayer(IDirectPlay2 *iface, DPID *lpidPlayer, DPNAME *name, HANDLE event, void *data, DWORD size, DWORD flags)
Definition: dplay.c:2209
static HRESULT WINAPI IDirectPlay3AImpl_AddGroupToGroup(IDirectPlay3A *iface, DPID parent, DPID group)
Definition: dplay.c:4595
static HRESULT WINAPI IDirectPlayImpl_AddPlayerToGroup(IDirectPlay *iface, DPID group, DPID player)
Definition: dplay.c:745
static HRESULT WINAPI IDirectPlay3AImpl_SetSessionDesc(IDirectPlay3A *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:4535
static HRESULT DP_IF_SetPlayerName(IDirectPlayImpl *This, DPID idPlayer, DPNAME *lpPlayerName, DWORD dwFlags, BOOL bAnsi)
Definition: dplay.c:4377
static HRESULT WINAPI IDirectPlay4Impl_EnumGroups(IDirectPlay4 *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2747
static HRESULT WINAPI IDirectPlay4AImpl_SetPlayerName(IDirectPlay4A *iface, DPID idPlayer, DPNAME *lpPlayerName, DWORD dwFlags)
Definition: dplay.c:4454
static HRESULT WINAPI IDirectPlay4Impl_DestroyGroup(IDirectPlay4 *iface, DPID idGroup)
Definition: dplay.c:2474
static HRESULT WINAPI IDirectPlay2Impl_GetGroupData(IDirectPlay2 *iface, DPID group, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3156
static HRESULT WINAPI IDirectPlay4AImpl_Initialize(IDirectPlay4A *iface, GUID *guid)
Definition: dplay.c:3722
static HRESULT WINAPI IDirectPlay2Impl_AddPlayerToGroup(IDirectPlay2 *iface, DPID group, DPID player)
Definition: dplay.c:1182
static HRESULT DP_CreateSPPlayer(IDirectPlayImpl *This, DPID dpid, DWORD flags, void *msgHeader)
Definition: dplay.c:1748
static IDirectPlayImpl * impl_from_IDirectPlay3A(IDirectPlay3A *iface)
Definition: dplay.c:102
static HRESULT DP_InitializeDPSP(IDirectPlayImpl *This, HMODULE hServiceProvider)
Definition: dplay.c:5381
static HRESULT WINAPI IDirectPlay4AImpl_CreatePlayer(IDirectPlay4A *iface, DPID *lpidPlayer, DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags)
Definition: dplay.c:2233
static HRESULT WINAPI IDirectPlay3AImpl_AddPlayerToGroup(IDirectPlay3A *iface, DPID group, DPID player)
Definition: dplay.c:1189
static HRESULT WINAPI IDirectPlay4AImpl_AddPlayerToGroup(IDirectPlay4A *iface, DPID group, DPID player)
Definition: dplay.c:1203
static HRESULT WINAPI IDirectPlay2AImpl_GetPlayerData(IDirectPlay2A *iface, DPID player, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3452
static HRESULT WINAPI IDirectPlayImpl_EnumGroupPlayers(IDirectPlay *iface, DPID group, LPDPENUMPLAYERSCALLBACK enumplayercb, void *context, DWORD flags)
Definition: dplay.c:806
static HRESULT WINAPI IDirectPlay3Impl_SetGroupData(IDirectPlay3 *iface, DPID group, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4158
static HRESULT WINAPI IDirectPlay3Impl_GetGroupConnectionSettings(IDirectPlay3 *iface, DWORD flags, DPID group, void *data, DWORD *size)
Definition: dplay.c:5293
static HRESULT WINAPI IDirectPlay3AImpl_GetCaps(IDirectPlay3A *iface, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3127
static HRESULT WINAPI IDirectPlay3Impl_DestroyGroup(IDirectPlay3 *iface, DPID group)
Definition: dplay.c:2462
static HMODULE DP_LoadSP(LPCGUID lpcGuid, LPSPINITDATA lpSpData, LPBOOL lpbIsDpSp)
Definition: dplay.c:5348
static HRESULT WINAPI IDirectPlay4Impl_SetGroupData(IDirectPlay4 *iface, DPID group, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4172
static HRESULT WINAPI IDirectPlay2Impl_GetPlayerCaps(IDirectPlay2 *iface, DPID player, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3398
static ULONG WINAPI IDirectPlay4AImpl_AddRef(IDirectPlay4A *iface)
Definition: dplay.c:1077
static HRESULT WINAPI IDirectPlay3AImpl_QueryInterface(IDirectPlay3A *iface, REFIID riid, void **ppv)
Definition: dplay.c:960
static HRESULT WINAPI IDirectPlay2Impl_CreateGroup(IDirectPlay2 *iface, DPID *lpidGroup, DPNAME *name, void *data, DWORD size, DWORD flags)
Definition: dplay.c:1659
static HRESULT WINAPI IDirectPlay4AImpl_EnumPlayers(IDirectPlay4A *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2786
static HRESULT WINAPI IDirectPlay4AImpl_Close(IDirectPlay4A *iface)
Definition: dplay.c:1345
HRESULT DPL_CreateCompoundAddress(LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount, LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface)
Definition: dplobby.c:1109
static HRESULT WINAPI IDirectPlay2Impl_EnumPlayers(IDirectPlay2 *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2762
static HRESULT WINAPI IDirectPlay2AImpl_GetPlayerCaps(IDirectPlay2A *iface, DPID player, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3391
static HRESULT WINAPI IDirectPlay3AImpl_DeleteGroupFromGroup(IDirectPlay3A *iface, DPID parent, DPID group)
Definition: dplay.c:4758
static HRESULT WINAPI IDirectPlay2Impl_Initialize(IDirectPlay2 *iface, GUID *guid)
Definition: dplay.c:3703
static HRESULT WINAPI IDirectPlay3AImpl_GetPlayerName(IDirectPlay3A *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3590
static const IDirectPlay3Vtbl dp3_vt
Definition: dplay.c:6212
static HRESULT WINAPI IDirectPlay4Impl_GetGroupConnectionSettings(IDirectPlay4 *iface, DWORD flags, DPID group, void *data, DWORD *size)
Definition: dplay.c:5309
static HRESULT WINAPI IDirectPlay4Impl_GetPlayerCaps(IDirectPlay4 *iface, DPID player, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3426
static DWORD DP_CopyGeneric(DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, DWORD genericSize, BOOL ansi)
Definition: dplay.c:390
static HRESULT WINAPI IDirectPlay2Impl_Send(IDirectPlay2 *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size)
Definition: dplay.c:4104
static HRESULT WINAPI IDirectPlay4AImpl_DestroyPlayer(IDirectPlay4A *iface, DPID idPlayer)
Definition: dplay.c:2596
static HRESULT WINAPI IDirectPlay4AImpl_GetGroupOwner(IDirectPlay4A *iface, DPID group, DPID *owner)
Definition: dplay.c:5798
static HRESULT WINAPI IDirectPlay3Impl_GetPlayerName(IDirectPlay3 *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3597
static HRESULT WINAPI IDirectPlay3Impl_EnumConnections(IDirectPlay3 *iface, const GUID *application, LPDPENUMCONNECTIONSCALLBACK enumcb, void *context, DWORD flags)
Definition: dplay.c:4865
static ULONG WINAPI IDirectPlay2AImpl_AddRef(IDirectPlay2A *iface)
Definition: dplay.c:1037
HRESULT DP_CreatePlayer(IDirectPlayImpl *This, void *msgHeader, DPID *lpid, DPNAME *lpName, void *data, DWORD dataSize, void *spData, DWORD spDataSize, DWORD dwFlags, HANDLE hEvent, struct PlayerData **playerData, BOOL bAnsi)
Definition: dplay.c:1823
static HRESULT WINAPI IDirectPlay3AImpl_InitializeConnection(IDirectPlay3A *iface, void *connection, DWORD flags)
Definition: dplay.c:5460
static HRESULT WINAPI IDirectPlay4Impl_InitializeConnection(IDirectPlay4 *iface, void *connection, DWORD flags)
Definition: dplay.c:5481
static HRESULT DP_IF_CreatePlayer(IDirectPlayImpl *This, DPID *lpidPlayer, DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags, BOOL bAnsi)
Definition: dplay.c:2103
static HRESULT DP_IF_DestroyGroup(IDirectPlayImpl *This, void *lpMsgHdr, DPID idGroup, BOOL bAnsi)
Definition: dplay.c:2387
static HRESULT DP_IF_EnumConnections(IDirectPlayImpl *This, const GUID *lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, void *lpContext, DWORD dwFlags, BOOL ansi)
Definition: dplay.c:5155
static DWORD DP_CopySetPlayerOrGroupData(DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, DWORD genericSize, BOOL ansi)
Definition: dplay.c:429
static HRESULT WINAPI IDirectPlay4AImpl_GetMessageQueue(IDirectPlay4A *iface, DPID from, DPID to, DWORD flags, DWORD *msgs, DWORD *bytes)
Definition: dplay.c:5963
static HRESULT WINAPI IDirectPlay4AImpl_CreateGroup(IDirectPlay4A *iface, DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags)
Definition: dplay.c:1683
static BOOL CALLBACK DP_GetSpLpGuidFromCompoundAddress(REFGUID guidDataType, DWORD dwDataSize, LPCVOID lpData, LPVOID lpContext)
Definition: dplay.c:5317
static HRESULT WINAPI IDirectPlay3AImpl_EnumGroups(IDirectPlay3A *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2724
static IDirectPlayImpl * impl_from_IDirectPlay4(IDirectPlay4 *iface)
Definition: dplay.c:117
static HRESULT DP_IF_EnumSessions(IDirectPlayImpl *This, DPSESSIONDESC2 *sdesc, DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags, BOOL ansi)
Definition: dplay.c:2928
HRESULT WINAPI DirectPlayEnumerateA(LPDPENUMDPCALLBACKA lpEnumCallback, LPVOID lpContext)
Definition: dplay.c:6586
static HRESULT WINAPI IDirectPlayImpl_DeletePlayerFromGroup(IDirectPlay *iface, DPID group, DPID player)
Definition: dplay.c:777
static HRESULT WINAPI IDirectPlay4Impl_EnumConnections(IDirectPlay4 *iface, const GUID *application, LPDPENUMCONNECTIONSCALLBACK enumcb, void *context, DWORD flags)
Definition: dplay.c:5205
static const IDirectPlay2Vtbl dp2A_vt
Definition: dplay.c:6176
static HRESULT WINAPI IDirectPlay2Impl_GetGroupName(IDirectPlay2 *iface, DPID group, void *data, DWORD *size)
Definition: dplay.c:3272
static HRESULT WINAPI IDirectPlayImpl_Open(IDirectPlay *iface, DPSESSIONDESC *sdesc)
Definition: dplay.c:877
static HRESULT WINAPI IDirectPlay3AImpl_GetMessageCount(IDirectPlay3A *iface, DPID player, DWORD *count)
Definition: dplay.c:3321
static HRESULT WINAPI IDirectPlay3Impl_Open(IDirectPlay3 *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:3977
static HRESULT WINAPI IDirectPlay2Impl_SetSessionDesc(IDirectPlay2 *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:4528
static HRESULT WINAPI IDirectPlay3AImpl_GetPlayerData(IDirectPlay3A *iface, DPID player, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3466
static HRESULT WINAPI IDirectPlay4AImpl_Receive(IDirectPlay4A *iface, DPID *lpidFrom, DPID *lpidTo, DWORD dwFlags, void *lpData, DWORD *lpdwDataSize)
Definition: dplay.c:4083
static HRESULT WINAPI IDirectPlay4AImpl_GetPlayerData(IDirectPlay4A *iface, DPID player, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3480
static HRESULT WINAPI IDirectPlay4AImpl_GetPlayerName(IDirectPlay4A *iface, DPID idPlayer, void *lpData, DWORD *lpdwDataSize)
Definition: dplay.c:3604
static BOOL CALLBACK cbDPCreateEnumConnections(LPCGUID lpguidSP, LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)
Definition: dplay.c:6610
static HRESULT DP_IF_GetPlayerName(IDirectPlayImpl *This, DPID idPlayer, void *lpData, DWORD *lpdwDataSize, BOOL bAnsi)
Definition: dplay.c:3535
static HRESULT DP_IF_GetGroupName(IDirectPlayImpl *This, DPID idGroup, void *lpData, DWORD *lpdwDataSize, BOOL bAnsi)
Definition: dplay.c:3230
static ULONG WINAPI IDirectPlay3AImpl_AddRef(IDirectPlay3A *iface)
Definition: dplay.c:1057
#define DPID_NOPARENT_GROUP
Definition: dplay.c:74
static HRESULT WINAPI IDirectPlayImpl_CreateGroup(IDirectPlay *iface, DPID *group, LPSTR name, LPSTR fullname)
Definition: dplay.c:769
static HRESULT WINAPI IDirectPlay3Impl_Receive(IDirectPlay3 *iface, DPID *from, DPID *to, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:4076
static HRESULT WINAPI IDirectPlay3Impl_CreateGroup(IDirectPlay3 *iface, DPID *lpidGroup, DPNAME *name, void *data, DWORD size, DWORD flags)
Definition: dplay.c:1675
static HRESULT WINAPI IDirectPlay2AImpl_Initialize(IDirectPlay2A *iface, GUID *guid)
Definition: dplay.c:3697
struct tagCreateEnum CreateEnumData
static HRESULT WINAPI IDirectPlay4AImpl_Open(IDirectPlay4A *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:3984
static HRESULT WINAPI IDirectPlayImpl_EnumGroups(IDirectPlay *iface, DWORD session, LPDPENUMPLAYERSCALLBACK enumplayercb, void *context, DWORD flags)
Definition: dplay.c:814
static HRESULT DP_IF_SetGroupName(IDirectPlayImpl *This, DPID idGroup, DPNAME *lpGroupName, DWORD dwFlags, BOOL bAnsi)
Definition: dplay.c:4214
static HRESULT WINAPI IDirectPlay2AImpl_GetPlayerName(IDirectPlay2A *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3576
static HRESULT WINAPI IDirectPlay4Impl_GetPlayerData(IDirectPlay4 *iface, DPID player, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3487
static DWORD DP_CopyName(DPNAME *dst, const DPNAME *src, BOOL dstAnsi, BOOL srcAnsi)
Definition: dplay.c:2016
static BOOL DP_GetRegStringA(HKEY key, const char *name, const char *defaultValue, char **outValue)
Definition: dplay.c:4918
static HRESULT WINAPI IDirectPlayImpl_EnumSessions(IDirectPlay *iface, DPSESSIONDESC *sdesc, DWORD timeout, LPDPENUMSESSIONSCALLBACK enumsessioncb, void *context, DWORD flags)
Definition: dplay.c:830
static DPID DP_NextObjectId(void)
Definition: dplay.c:255
HRESULT DP_HandleGameMessage(IDirectPlayImpl *This, void *messageBody, DWORD messageBodySize, DPID fromId, DPID toId)
Definition: dplay.c:695
static HRESULT WINAPI IDirectPlay4AImpl_EnumConnections(IDirectPlay4A *iface, const GUID *lpguidApplication, LPDPENUMCONNECTIONSCALLBACK lpEnumCallback, void *lpContext, DWORD dwFlags)
Definition: dplay.c:5197
static HRESULT WINAPI IDirectPlay4AImpl_InitializeConnection(IDirectPlay4A *iface, void *connection, DWORD flags)
Definition: dplay.c:5474
static HRESULT WINAPI IDirectPlay4Impl_StartSession(IDirectPlay4 *iface, DWORD flags, DPID group)
Definition: dplay.c:5659
static HRESULT WINAPI IDirectPlay3AImpl_CreatePlayer(IDirectPlay3A *iface, DPID *lpidPlayer, DPNAME *name, HANDLE event, void *data, DWORD size, DWORD flags)
Definition: dplay.c:2217
static DWORD DP_CopyString(char **dst, const void *src, BOOL dstAnsi, BOOL srcAnsi, void *buffer, DWORD offset)
Definition: dplay.c:260
static HRESULT WINAPI IDirectPlay4AImpl_GetSessionDesc(IDirectPlay4A *iface, void *lpData, DWORD *lpdwDataSize)
Definition: dplay.c:3683
static HRESULT WINAPI IDirectPlay4AImpl_SendEx(IDirectPlay4A *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size, DWORD priority, DWORD timeout, void *context, DWORD *msgid)
Definition: dplay.c:5828
static HRESULT WINAPI IDirectPlay2AImpl_QueryInterface(IDirectPlay2A *iface, REFIID riid, void **ppv)
Definition: dplay.c:946
static HRESULT WINAPI IDirectPlay4Impl_CreatePlayer(IDirectPlay4 *iface, DPID *lpidPlayer, DPNAME *lpPlayerName, HANDLE hEvent, void *lpData, DWORD dwDataSize, DWORD dwFlags)
Definition: dplay.c:2241
static HRESULT WINAPI IDirectPlayImpl_EnableNewPlayers(IDirectPlay *iface, BOOL enable)
Definition: dplay.c:799
static HRESULT WINAPI IDirectPlay4Impl_AddGroupToGroup(IDirectPlay4 *iface, DPID parent, DPID group)
Definition: dplay.c:4616
static IDirectPlayImpl * impl_from_IDirectPlay2A(IDirectPlay2A *iface)
Definition: dplay.c:97
static HRESULT WINAPI IDirectPlay3Impl_Close(IDirectPlay3 *iface)
Definition: dplay.c:1339
static HRESULT WINAPI IDirectPlay3AImpl_SendChatMessage(IDirectPlay3A *iface, DPID from, DPID to, DWORD flags, DPCHAT *chatmsg)
Definition: dplay.c:5576
static HRESULT WINAPI IDirectPlay4AImpl_GetMessageCount(IDirectPlay4A *iface, DPID player, DWORD *count)
Definition: dplay.c:3335
struct _DPRGOPContext * lpDPRGOPContext
HRESULT DP_AddPlayerToGroup(IDirectPlayImpl *This, DPID group, DPID player)
Definition: dplay.c:1210
static HRESULT WINAPI IDirectPlay4Impl_GetMessageQueue(IDirectPlay4 *iface, DPID from, DPID to, DWORD flags, DWORD *msgs, DWORD *bytes)
Definition: dplay.c:5970
static HRESULT WINAPI IDirectPlay4Impl_Open(IDirectPlay4 *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:3990
static HRESULT WINAPI IDirectPlay2AImpl_DestroyGroup(IDirectPlay2A *iface, DPID group)
Definition: dplay.c:2444
static DWORD DP_CopyCreatePlayerOrGroup(DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, DWORD genericSize, BOOL ansi)
Definition: dplay.c:401
static HRESULT WINAPI IDirectPlay3AImpl_SetPlayerName(IDirectPlay3A *iface, DPID player, DPNAME *name, DWORD flags)
Definition: dplay.c:4440
HRESULT dplay_create(REFIID riid, void **ppv)
Definition: dplay.c:6428
static HRESULT WINAPI IDirectPlayImpl_GetPlayerCaps(IDirectPlay *iface, DPID player, DPCAPS *caps)
Definition: dplay.c:854
static ULONG WINAPI IDirectPlay3AImpl_Release(IDirectPlay3A *iface)
Definition: dplay.c:1123
static HRESULT WINAPI IDirectPlay3Impl_GetSessionDesc(IDirectPlay3 *iface, void *data, DWORD *size)
Definition: dplay.c:3676
static HRESULT WINAPI IDirectPlayImpl_DestroyPlayer(IDirectPlay *iface, DPID player)
Definition: dplay.c:785
static HRESULT WINAPI IDirectPlay4AImpl_SetGroupData(IDirectPlay4A *iface, DPID group, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4165
static HRESULT DP_SetSessionDesc(IDirectPlayImpl *This, const DPSESSIONDESC2 *lpSessDesc, DWORD dwFlags, BOOL bInitial, BOOL bAnsi)
Definition: dplay.c:4468
static HRESULT WINAPI IDirectPlay2Impl_GetCaps(IDirectPlay2 *iface, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3121
static HRESULT WINAPI IDirectPlay3Impl_EnumSessions(IDirectPlay3 *iface, DPSESSIONDESC2 *sdesc, DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags)
Definition: dplay.c:2920
static HRESULT WINAPI IDirectPlay4Impl_Initialize(IDirectPlay4 *iface, GUID *guid)
Definition: dplay.c:3729
static HRESULT WINAPI IDirectPlay3AImpl_SetGroupData(IDirectPlay3A *iface, DPID group, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4151
static HRESULT WINAPI IDirectPlay2AImpl_SetSessionDesc(IDirectPlay2A *iface, DPSESSIONDESC2 *sdesc, DWORD flags)
Definition: dplay.c:4521
HRESULT DP_CreateGroup(IDirectPlayImpl *This, void *msgHeader, const DPID *lpid, const DPNAME *lpName, void *data, DWORD dataSize, DWORD dwFlags, DPID idParent, BOOL bAnsi)
Definition: dplay.c:1386
static HRESULT WINAPI IDirectPlay2AImpl_GetPlayerAddress(IDirectPlay2A *iface, DPID player, void *data, DWORD *size)
Definition: dplay.c:3347
static HRESULT WINAPI IDirectPlay3Impl_EnumGroupPlayers(IDirectPlay3 *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2632
static ULONG WINAPI IDirectPlay2Impl_AddRef(IDirectPlay2 *iface)
Definition: dplay.c:1047
static HRESULT WINAPI IDirectPlayImpl_GetMessageCount(IDirectPlay *iface, DPID player, DWORD *count)
Definition: dplay.c:846
static HRESULT WINAPI IDirectPlay3AImpl_SecureOpen(IDirectPlay3A *iface, const DPSESSIONDESC2 *sdesc, DWORD flags, const DPSECURITYDESC *security, const DPCREDENTIALS *credentials)
Definition: dplay.c:5542
static BOOL connectionsInitialized
Definition: dplay.c:5106
static HRESULT WINAPI IDirectPlay3Impl_Initialize(IDirectPlay3 *iface, GUID *guid)
Definition: dplay.c:3715
static HRESULT WINAPI IDirectPlay4AImpl_SetGroupName(IDirectPlay4A *iface, DPID idGroup, DPNAME *lpGroupName, DWORD dwFlags)
Definition: dplay.c:4286
static HRESULT WINAPI IDirectPlay4AImpl_SecureOpen(IDirectPlay4A *iface, const DPSESSIONDESC2 *lpsd, DWORD dwFlags, const DPSECURITYDESC *lpSecurity, const DPCREDENTIALS *lpCredentials)
Definition: dplay.c:5560
static ULONG WINAPI IDirectPlayImpl_AddRef(IDirectPlay *iface)
Definition: dplay.c:722
static HRESULT WINAPI IDirectPlay3AImpl_Receive(IDirectPlay3A *iface, DPID *from, DPID *to, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:4069
static BOOL CALLBACK cbDeletePlayerFromAllGroups(DPID dpId, DWORD dwPlayerType, LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)
Definition: dplay.c:2544
static HRESULT WINAPI IDirectPlay3AImpl_GetPlayerCaps(IDirectPlay3A *iface, DPID player, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3405
static BOOL WINAPI DP_InitConnections(INIT_ONCE *initOnce, void *param, void **context)
Definition: dplay.c:5108
static HRESULT WINAPI IDirectPlayImpl_GetPlayerName(IDirectPlay *iface, DPID player, LPSTR name, DWORD *size_name, LPSTR fullname, DWORD *size_fullname)
Definition: dplay.c:861
static BOOL DP_DestroyDirectPlay2(LPVOID lpDP)
Definition: dplay.c:193
static HRESULT WINAPI IDirectPlayImpl_Send(IDirectPlay *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size)
Definition: dplay.c:899
static HRESULT WINAPI IDirectPlay3AImpl_DestroyPlayer(IDirectPlay3A *iface, DPID player)
Definition: dplay.c:2584
static IDirectPlayImpl * impl_from_IDirectPlay2(IDirectPlay2 *iface)
Definition: dplay.c:92
static ULONG WINAPI IDirectPlayImpl_Release(IDirectPlay *iface)
Definition: dplay.c:732
static HRESULT WINAPI IDirectPlay3Impl_SecureOpen(IDirectPlay3 *iface, const DPSESSIONDESC2 *sdesc, DWORD flags, const DPSECURITYDESC *security, const DPCREDENTIALS *credentials)
Definition: dplay.c:5551
static HRESULT WINAPI IDirectPlayImpl_QueryInterface(IDirectPlay *iface, REFIID riid, void **ppv)
Definition: dplay.c:716
HRESULT WINAPI DirectPlayEnumerateW(LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext)
Definition: dplay.c:6596
static HRESULT WINAPI IDirectPlay4Impl_GetPlayerFlags(IDirectPlay4 *iface, DPID player, DWORD *flags)
Definition: dplay.c:5790
static HRESULT WINAPI IDirectPlay3AImpl_EnumGroupsInGroup(IDirectPlay3A *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:5212
static HRESULT WINAPI IDirectPlay2AImpl_SetGroupName(IDirectPlay2A *iface, DPID group, DPNAME *name, DWORD flags)
Definition: dplay.c:4258
static HRESULT WINAPI IDirectPlayImpl_DestroyGroup(IDirectPlay *iface, DPID group)
Definition: dplay.c:792
static HRESULT WINAPI IDirectPlay4Impl_GetPlayerAccount(IDirectPlay4 *iface, DPID player, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:5761
static HRESULT WINAPI IDirectPlay4Impl_CancelPriority(IDirectPlay4 *iface, DWORD minprio, DWORD maxprio, DWORD flags)
Definition: dplay.c:6129
static HRESULT WINAPI IDirectPlay3Impl_SetGroupConnectionSettings(IDirectPlay3 *iface, DWORD flags, DPID group, DPLCONNECTION *connection)
Definition: dplay.c:5614
static HRESULT WINAPI IDirectPlay4Impl_EnumGroupsInGroup(IDirectPlay4 *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:5278
static void DP_DeletePlayer(IDirectPlayImpl *This, DPID dpid)
Definition: dplay.c:1970
static HRESULT WINAPI IDirectPlayImpl_EnumPlayers(IDirectPlay *iface, DWORD session, LPDPENUMPLAYERSCALLBACK enumplayercb, void *context, DWORD flags)
Definition: dplay.c:822
static DWORD CALLBACK DP_EnumSessionsSendAsyncRequestThread(LPVOID lpContext)
Definition: dplay.c:2827
static HRESULT WINAPI IDirectPlay4Impl_GetGroupName(IDirectPlay4 *iface, DPID idGroup, void *lpData, DWORD *lpdwDataSize)
Definition: dplay.c:3300
static HRESULT WINAPI IDirectPlay4AImpl_CancelMessage(IDirectPlay4A *iface, DWORD msgid, DWORD flags)
Definition: dplay.c:6101
static HRESULT WINAPI IDirectPlay2AImpl_EnumPlayers(IDirectPlay2A *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2754
static BOOL DP_GetRegStringW(HKEY key, const WCHAR *name, const char *defaultValue, WCHAR **outValue)
Definition: dplay.c:4913
static HRESULT WINAPI IDirectPlay4Impl_SendEx(IDirectPlay4 *iface, DPID from, DPID to, DWORD flags, void *data, DWORD size, DWORD priority, DWORD timeout, void *context, DWORD *msgid)
Definition: dplay.c:5837
static HRESULT WINAPI IDirectPlay3AImpl_GetGroupName(IDirectPlay3A *iface, DPID group, void *data, DWORD *size)
Definition: dplay.c:3279
static HRESULT WINAPI IDirectPlay4AImpl_GetPlayerFlags(IDirectPlay4A *iface, DPID player, DWORD *flags)
Definition: dplay.c:5783
static HRESULT WINAPI IDirectPlayImpl_SaveSession(IDirectPlay *iface, LPSTR reserved)
Definition: dplay.c:892
static HRESULT WINAPI IDirectPlay4Impl_SetGroupName(IDirectPlay4 *iface, DPID idGroup, DPNAME *lpGroupName, DWORD dwFlags)
Definition: dplay.c:4293
static HRESULT WINAPI IDirectPlay3AImpl_GetSessionDesc(IDirectPlay3A *iface, void *data, DWORD *size)
Definition: dplay.c:3669
static HRESULT WINAPI IDirectPlay3AImpl_SetPlayerData(IDirectPlay3A *iface, DPID player, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4314
static HRESULT WINAPI IDirectPlay4Impl_CreateGroupInGroup(IDirectPlay4 *iface, DPID idParentGroup, DPID *lpidGroup, DPNAME *lpGroupName, void *lpData, DWORD dwDataSize, DWORD dwFlags)
Definition: dplay.c:4747
static HRESULT WINAPI IDirectPlay3Impl_GetGroupData(IDirectPlay3 *iface, DPID group, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3170
static HRESULT WINAPI IDirectPlay2AImpl_EnumSessions(IDirectPlay2A *iface, DPSESSIONDESC2 *sdesc, DWORD timeout, LPDPENUMSESSIONSCALLBACK2 enumsessioncb, void *context, DWORD flags)
Definition: dplay.c:2896
static HRESULT WINAPI IDirectPlay3Impl_AddGroupToGroup(IDirectPlay3 *iface, DPID parent, DPID group)
Definition: dplay.c:4602
static void DP_ReadConnections(const char *searchSubKey, DWORD dwFlags, const GUID *addressDataType, struct list *connections)
Definition: dplay.c:4952
static lpPlayerList DP_FindPlayer(IDirectPlayImpl *This, DPID dpid)
Definition: dplay.c:2002
static HRESULT WINAPI IDirectPlay4Impl_GetGroupParent(IDirectPlay4 *iface, DPID group, DPID *parent)
Definition: dplay.c:5716
static DPNAME * DP_DuplicateName(const DPNAME *src, BOOL dstAnsi, BOOL srcAnsi)
Definition: dplay.c:2044
static void DP_SetPlayerData(lpPlayerData lpPData, DWORD dwFlags, LPVOID lpData, DWORD dwDataSize)
Definition: dplay.c:2061
static IDirectPlayImpl * impl_from_IDirectPlay3(IDirectPlay3 *iface)
Definition: dplay.c:107
static HRESULT WINAPI IDirectPlay4Impl_Close(IDirectPlay4 *iface)
Definition: dplay.c:1351
static HRESULT WINAPI IDirectPlay2AImpl_EnumGroups(IDirectPlay2A *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2708
static HRESULT WINAPI IDirectPlay2AImpl_GetSessionDesc(IDirectPlay2A *iface, void *data, DWORD *size)
Definition: dplay.c:3655
static const IDirectPlay3Vtbl dp3A_vt
Definition: dplay.c:6263
struct _DPFAGContext DPFAGContext
static HRESULT WINAPI IDirectPlay2AImpl_SetPlayerData(IDirectPlay2A *iface, DPID player, void *data, DWORD size, DWORD flags)
Definition: dplay.c:4300
static HRESULT WINAPI IDirectPlay2Impl_Receive(IDirectPlay2 *iface, DPID *from, DPID *to, DWORD flags, void *data, DWORD *size)
Definition: dplay.c:4062
static const IDirectPlayVtbl dp_vt
Definition: dplay.c:916
static HRESULT WINAPI IDirectPlay2AImpl_SetPlayerName(IDirectPlay2A *iface, DPID player, DPNAME *name, DWORD flags)
Definition: dplay.c:4426
static HRESULT WINAPI IDirectPlay4AImpl_DeletePlayerFromGroup(IDirectPlay4A *iface, DPID group, DPID player)
Definition: dplay.c:2285
static HRESULT WINAPI IDirectPlay3Impl_EnumGroupsInGroup(IDirectPlay3 *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:5220
static HRESULT WINAPI IDirectPlay2AImpl_DeletePlayerFromGroup(IDirectPlay2A *iface, DPID group, DPID player)
Definition: dplay.c:2257
static HRESULT WINAPI IDirectPlay4Impl_SetSessionDesc(IDirectPlay4 *iface, DPSESSIONDESC2 *lpSessDesc, DWORD dwFlags)
Definition: dplay.c:4556
void DP_FreeConnections(void)
Definition: dplay.c:5133
HRESULT DP_GetSPPlayerData(IDirectPlayImpl *lpDP, DPID idPlayer, void **lplpData)
Definition: dplay.c:6462
static HRESULT WINAPI IDirectPlay4AImpl_SetSessionDesc(IDirectPlay4A *iface, DPSESSIONDESC2 *lpSessDesc, DWORD dwFlags)
Definition: dplay.c:4549
static HRESULT WINAPI IDirectPlay4AImpl_GetGroupConnectionSettings(IDirectPlay4A *iface, DWORD flags, DPID group, void *data, DWORD *size)
Definition: dplay.c:5301
static HRESULT WINAPI IDirectPlay3AImpl_EnumGroupPlayers(IDirectPlay3A *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2624
static const IDirectPlay4Vtbl dp4A_vt
Definition: dplay.c:6371
static HRESULT WINAPI IDirectPlay2AImpl_DestroyPlayer(IDirectPlay2A *iface, DPID player)
Definition: dplay.c:2572
static HRESULT WINAPI IDirectPlay2AImpl_GetCaps(IDirectPlay2A *iface, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3115
static HRESULT WINAPI IDirectPlay4AImpl_SendChatMessage(IDirectPlay4A *iface, DPID from, DPID to, DWORD flags, DPCHAT *chatmsg)
Definition: dplay.c:5590
static HRESULT DP_IF_Receive(IDirectPlayImpl *This, DPID *lpidFrom, DPID *lpidTo, DWORD dwFlags, void *lpData, DWORD *lpdwDataSize, BOOL bAnsi)
Definition: dplay.c:3996
static HRESULT WINAPI IDirectPlay3AImpl_SetGroupConnectionSettings(IDirectPlay3A *iface, DWORD flags, DPID group, DPLCONNECTION *connection)
Definition: dplay.c:5606
static HRESULT WINAPI IDirectPlay4Impl_GetCaps(IDirectPlay4 *iface, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3144
static HRESULT WINAPI IDirectPlay4AImpl_SetGroupConnectionSettings(IDirectPlay4A *iface, DWORD flags, DPID group, DPLCONNECTION *connection)
Definition: dplay.c:5622
static HRESULT WINAPI IDirectPlay4AImpl_EnumGroupsInGroup(IDirectPlay4A *iface, DPID group, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:5271
static HRESULT DP_QueuePlayerMessage(IDirectPlayImpl *This, DPID fromId, struct PlayerData *player, DPID excludeId, void *msg, FN_COPY_MESSAGE *copyMessage, DWORD genericSize)
Definition: dplay.c:321
static HRESULT WINAPI IDirectPlay3AImpl_Close(IDirectPlay3A *iface)
Definition: dplay.c:1333
static HRESULT WINAPI IDirectPlayImpl_GetCaps(IDirectPlay *iface, DPCAPS *caps)
Definition: dplay.c:839
static HRESULT WINAPI IDirectPlay4AImpl_StartSession(IDirectPlay4A *iface, DWORD flags, DPID group)
Definition: dplay.c:5652
static HRESULT WINAPI IDirectPlay4Impl_GetGroupOwner(IDirectPlay4 *iface, DPID group, DPID *owner)
Definition: dplay.c:5805
DPSESSIONDESC2 * DP_DuplicateSessionDesc(const DPSESSIONDESC2 *src, BOOL dstAnsi, BOOL srcAnsi)
Definition: dplay.c:4579
static ULONG WINAPI IDirectPlay4Impl_Release(IDirectPlay4 *iface)
Definition: dplay.c:1162
static DPID DP_GetRemoteNextObjectId(void)
Definition: dplay.c:2249
static HRESULT WINAPI IDirectPlay3AImpl_GetGroupFlags(IDirectPlay3A *iface, DPID group, DWORD *flags)
Definition: dplay.c:5666
static HRESULT WINAPI IDirectPlay4AImpl_CancelPriority(IDirectPlay4A *iface, DWORD minprio, DWORD maxprio, DWORD flags)
Definition: dplay.c:6122
static void DP_DeleteSPPlayer(IDirectPlayImpl *This, DPID dpid)
Definition: dplay.c:1803
static HRESULT WINAPI IDirectPlay4AImpl_GetGroupName(IDirectPlay4A *iface, DPID idGroup, void *lpData, DWORD *lpdwDataSize)
Definition: dplay.c:3293
static HRESULT WINAPI IDirectPlay2Impl_DestroyGroup(IDirectPlay2 *iface, DPID group)
Definition: dplay.c:2450
static HRESULT WINAPI IDirectPlay4AImpl_GetGroupData(IDirectPlay4A *iface, DPID group, void *data, DWORD *size, DWORD flags)
Definition: dplay.c:3177
static HRESULT WINAPI IDirectPlay3Impl_GetCaps(IDirectPlay3 *iface, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3133
static HRESULT DP_SecureOpen(IDirectPlayImpl *This, const DPSESSIONDESC2 *lpsd, DWORD dwFlags, const DPSECURITYDESC *lpSecurity, const DPCREDENTIALS *lpCredentials, BOOL bAnsi)
Definition: dplay.c:3737
static HRESULT WINAPI IDirectPlay4Impl_EnumPlayers(IDirectPlay4 *iface, GUID *instance, LPDPENUMPLAYERSCALLBACK2 enumplayercb, void *context, DWORD flags)
Definition: dplay.c:2793
static ULONG WINAPI IDirectPlay4AImpl_Release(IDirectPlay4A *iface)
Definition: dplay.c:1149
static BOOL DP_GetRegString(HKEY key, const void *name, const char *defaultValue, void **outValue, BOOL ansi)
Definition: dplay.c:4873
static HRESULT WINAPI IDirectPlay4AImpl_GetCaps(IDirectPlay4A *iface, DPCAPS *caps, DWORD flags)
Definition: dplay.c:3139
static HRESULT WINAPI IDirectPlay3AImpl_SetGroupName(IDirectPlay3A *iface, DPID group, DPNAME *name, DWORD flags)
Definition: dplay.c:4272
static ULONG WINAPI IDirectPlay3Impl_Release(IDirectPlay3 *iface)
Definition: dplay.c:1136
static HRESULT WINAPI IDirectPlay4Impl_Receive(IDirectPlay4 *iface, DPID *lpidFrom, DPID *lpidTo, DWORD dwFlags, void *lpData, DWORD *lpdwDataSize)
Definition: dplay.c:4090
#define DPID_UNKNOWN
Definition: dplay.h:164
#define IDirectPlayX_Initialize(p, a)
Definition: dplay.h:888
#define IDirectPlayX_Release(p)
Definition: dplay.h:866
#define DPERR_INVALIDOBJECT
Definition: dplay.h:101
#define DPENUMPLAYERS_LOCAL
Definition: dplay.h:987
#define IDirectPlayX_GetGroupOwner(p, a, b)
Definition: dplay.h:914
#define DPERR_ACCESSDENIED
Definition: dplay.h:90
#define IDirectPlayX_CancelPriority(p, a, b, c)
Definition: dplay.h:919
#define DPERR_GENERIC
Definition: dplay.h:99
#define DPPLAYERTYPE_PLAYER
Definition: dplay.h:1135
#define DPERR_NOSESSIONS
Definition: dplay.h:113
#define IDirectPlayX_SetGroupConnectionSettings(p, a, b, c)
Definition: dplay.h:907
#define DPENUMPLAYERS_GROUP
Definition: dplay.h:989
#define IDirectPlayX_QueryInterface(p, a, b)
Definition: dplay.h:864
#define DPGROUP_HIDDEN
Definition: dplay.h:1013
#define DPSET_REMOTE
Definition: dplay.h:1056
#define IDirectPlayX_Receive(p, a, b, c, d, e)
Definition: dplay.h:890
#define IDirectPlayX_Open(p, a, b)
Definition: dplay.h:889
struct IDirectPlay3 * LPDIRECTPLAY3A
Definition: dplay.h:53
#define DPERR_CANTADDPLAYER
Definition: dplay.h:93
#define IDirectPlayX_GetPlayerName(p, a, b, c)
Definition: dplay.h:886
#define IDirectPlayX_SecureOpen(p, a, b, c, d)
Definition: dplay.h:905
#define IDirectPlayX_AddGroupToGroup(p, a, b)
Definition: dplay.h:898
#define IDirectPlayX_CreatePlayer(p, a, b, c, d, e, f)
Definition: dplay.h:871
struct IDirectPlay * LPDIRECTPLAY
Definition: dplay.h:41
#define IDirectPlayX_CreateGroup(p, a, b, c, d, e)
Definition: dplay.h:870
#define IDirectPlayX_SetPlayerName(p, a, b, c)
Definition: dplay.h:895
#define DPID_SERVERPLAYER
Definition: dplay.h:163
#define IDirectPlayX_GetGroupFlags(p, a, b)
Definition: dplay.h:909
BOOL(CALLBACK * LPDPENUMSESSIONSCALLBACK)(LPDPSESSIONDESC lpDPSessionDesc, LPVOID lpContext, LPDWORD lpdwTimeOut, DWORD dwFlags)
Definition: dplay.h:389
#define IDirectPlayX_SendChatMessage(p, a, b, c, d)
Definition: dplay.h:906
#define DPERR_UNINITIALIZED
Definition: dplay.h:125
#define IDirectPlayX_Send(p, a, b, c, d, e)
Definition: dplay.h:891
#define DPERR_INVALIDGROUP
Definition: dplay.h:105
#define IDirectPlayX_CreateGroupInGroup(p, a, b, c, d, e, f)
Definition: dplay.h:899
#define DPPLAYER_SERVERPLAYER
Definition: dplay.h:1005
#define DPSET_LOCAL
Definition: dplay.h:1057
#define DPRECEIVE_TOPLAYER
Definition: dplay.h:1032
#define IDirectPlayX_EnumConnections(p, a, b, c, d)
Definition: dplay.h:901
#define DPENUMGROUPS_ALL
Definition: dplay.h:995
#define IDirectPlayX_EnumGroupPlayers(p, a, b, c, d, e)
Definition: dplay.h:875
#define DPOPEN_CREATE
Definition: dplay.h:264
#define IDirectPlayX_CancelMessage(p, a, b)
Definition: dplay.h:918
#define DPENUMPLAYERS_REMOTE
Definition: dplay.h:988
#define IDirectPlayX_GetGroupData(p, a, b, c, d)
Definition: dplay.h:880
struct tagDPMSG_SETPLAYERORGROUPDATA DPMSG_SETPLAYERORGROUPDATA
#define IDirectPlayX_AddPlayerToGroup(p, a, b)
Definition: dplay.h:868
#define IDirectPlayX_EnumPlayers(p, a, b, c, d)
Definition: dplay.h:877
#define DPPLAYER_SPECTATOR
Definition: dplay.h:1006
#define DPID_SYSMSG
Definition: dplay.h:161
#define IDirectPlayX_SetPlayerData(p, a, b, c, d)
Definition: dplay.h:894
#define DPERR_CONNECTING
Definition: dplay.h:128
#define DPENUMSESSIONS_ASYNC
Definition: dplay.h:1018
#define DPERR_NOMEMORY
Definition: dplay.h:108
#define DPCONNECTION_DIRECTPLAY
Definition: dplay.h:982
#define IDirectPlayX_StartSession(p, a, b)
Definition: dplay.h:908
#define DPSEND_GUARANTEED
Definition: dplay.h:1038
#define DPERR_BUFFERTOOSMALL
Definition: dplay.h:92
#define DPOPEN_RETURNSTATUS
Definition: dplay.h:265
#define DPERR_ALREADYINITIALIZED
Definition: dplay.h:89
#define DPOPEN_JOIN
Definition: dplay.h:263
#define DPERR_INVALIDFLAGS
Definition: dplay.h:100
#define DPPLAYERTYPE_GROUP
Definition: dplay.h:1134
#define IDirectPlayX_SetGroupData(p, a, b, c, d)
Definition: dplay.h:892
BOOL(CALLBACK * LPDPENUMCONNECTIONSCALLBACK)(LPCGUID lpguidSP, LPVOID lpConnection, DWORD dwConnectionSize, LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)
Definition: dplay.h:381
#define IDirectPlayX_SendEx(p, a, b, c, d, e, f, g, h, i)
Definition: dplay.h:916
#define DPENUMGROUPS_REMOTE
Definition: dplay.h:997
#define DPSESSION_MULTICASTSERVER
Definition: dplay.h:276
#define DPENUMPLAYERS_OWNER
Definition: dplay.h:993
#define DPRECEIVE_PEEK
Definition: dplay.h:1034
#define IDirectPlayX_DestroyGroup(p, a)
Definition: dplay.h:873
#define IDirectPlayX_DeletePlayerFromGroup(p, a, b)
Definition: dplay.h:872
#define IDirectPlayX_GetGroupParent(p, a, b)
Definition: dplay.h:910
BOOL(CALLBACK * LPDPENUMPLAYERSCALLBACK)(DPID dpId, LPSTR lpFriendlyName, LPSTR lpFormalName, DWORD dwFlags, LPVOID lpContext)
Definition: dplay.h:400
#define DP_OK
Definition: dplay.h:88
#define DPSYS_SETPLAYERORGROUPDATA
Definition: dplay.h:1103
#define IDirectPlayX_GetMessageQueue(p, a, b, c, d, e)
Definition: dplay.h:917
#define DPENUMSESSIONS_STOPASYNC
Definition: dplay.h:1019
#define IDirectPlayX_DestroyPlayer(p, a)
Definition: dplay.h:874
#define IDirectPlayX_InitializeConnection(p, a, b)
Definition: dplay.h:904
struct tagDPNAME DPNAME
#define IDirectPlayX_GetCaps(p, a, b)
Definition: dplay.h:879
DWORD DPID
Definition: dplay.h:158
#define DPERR_UNAVAILABLE
Definition: dplay.h:117
#define DPMESSAGEQUEUE_RECEIVE
Definition: dplay.h:1062
BOOL(CALLBACK * LPDPENUMSESSIONSCALLBACK2)(LPCDPSESSIONDESC2 lpThisSD, LPDWORD lpdwTimeOut, DWORD dwFlags, LPVOID lpContext)
Definition: dplay.h:414
#define IDirectPlayX_GetPlayerFlags(p, a, b)
Definition: dplay.h:912
struct tagDPMSG_CREATEPLAYERORGROUP DPMSG_CREATEPLAYERORGROUP
#define DPERR_INVALIDPLAYER
Definition: dplay.h:104
struct IDirectPlay3 IDirectPlay3A
Definition: dplay.h:53
#define DPERR_INVALIDPARAMS
Definition: dplay.h:103
#define DPSYS_CREATEPLAYERORGROUP
Definition: dplay.h:1085
struct IDirectPlay4 IDirectPlay4A
Definition: dplay.h:59
#define IDirectPlayX_GetGroupName(p, a, b, c)
Definition: dplay.h:881
#define IDirectPlayX_GetPlayerData(p, a, b, c, d)
Definition: dplay.h:885
#define IDirectPlayX_SetGroupName(p, a, b, c)
Definition: dplay.h:893
#define DPERR_OUTOFMEMORY
Definition: dplay.h:109
#define IDirectPlayX_EnumGroupsInGroup(p, a, b, c, d, e)
Definition: dplay.h:902
#define DPESC_TIMEDOUT
Definition: dplay.h:420
#define DPERR_INVALIDPARAM
Definition: dplay.h:102
#define IDirectPlayX_EnumSessions(p, a, b, c, d, e)
Definition: dplay.h:878
#define DPMESSAGEQUEUE_SEND
Definition: dplay.h:1061
BOOL(CALLBACK * LPDPENUMDPCALLBACKA)(LPGUID lpguidSP, LPSTR lpSPName, DWORD dwMajorVersion, DWORD dwMinorVersion, LPVOID lpContext)
Definition: dplay.h:367
struct IDirectPlay2 IDirectPlay2A
Definition: dplay.h:47
#define IDirectPlayX_Close(p)
Definition: dplay.h:869
#define DPRECEIVE_FROMPLAYER
Definition: dplay.h:1033
BOOL(CALLBACK * LPDPENUMPLAYERSCALLBACK2)(DPID dpId, DWORD dwPlayerType, LPCDPNAME lpName, DWORD dwFlags, LPVOID lpContext)
Definition: dplay.h:407
#define DPID_ALLPLAYERS
Definition: dplay.h:162
#define IDirectPlayX_GetPlayerAddress(p, a, b, c)
Definition: dplay.h:883
#define IDirectPlayX_GetPlayerCaps(p, a, b, c)
Definition: dplay.h:884
#define IDirectPlayX_GetPlayerAccount(p, a, b, c, d)
Definition: dplay.h:911
#define DPSYS_ADDPLAYERTOGROUP
Definition: dplay.h:1091
#define IDirectPlayX_GetGroupConnectionSettings(p, a, b, c, d)
Definition: dplay.h:903
#define IDirectPlayX_EnumGroups(p, a, b, c, d)
Definition: dplay.h:876
#define DPPLAYER_LOCAL
Definition: dplay.h:1007
#define IDirectPlayX_GetMessageCount(p, a, b)
Definition: dplay.h:882
#define IDirectPlayX_GetSessionDesc(p, a, b)
Definition: dplay.h:887
#define DPENUMGROUPS_LOCAL
Definition: dplay.h:996
#define DPCONNECTION_DIRECTPLAYLOBBY
Definition: dplay.h:983
#define IDirectPlayX_SetSessionDesc(p, a, b)
Definition: dplay.h:896
BOOL(CALLBACK * LPDPENUMDPCALLBACKW)(LPGUID lpguidSP, LPWSTR lpSPName, DWORD dwMajorVersion, DWORD dwMinorVersion, LPVOID lpContext)
Definition: dplay.h:360
#define DPERR_NOMESSAGES
Definition: dplay.h:110
struct tagDPSESSIONDESC2 DPSESSIONDESC2
#define IDirectPlayX_SetGroupOwner(p, a, b)
Definition: dplay.h:915
#define IDirectPlayX_DeleteGroupFromGroup(p, a, b)
Definition: dplay.h:900
@ DP_LOBBY_PROVIDER
Definition: dplay_global.h:168
@ NO_PROVIDER
Definition: dplay_global.h:166
@ DP_SERVICE_PROVIDER
Definition: dplay_global.h:167
DWORD FN_COPY_MESSAGE(DPMSG_GENERIC *genericDst, DPMSG_GENERIC *genericSrc, DWORD genericSize, BOOL ansi)
Definition: dplay_global.h:150
LPVOID DPSP_CreateSPPlayerData(void)
Definition: dplaysp.c:721
HRESULT DPL_EnumAddress(LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, LPCVOID lpAddress, DWORD dwAddressSize, LPVOID lpContext)
Definition: dplobby.c:368
HRESULT dplobbysp_create(REFIID riid, void **ppv, IDirectPlayImpl *dp)
Definition: lobbysp.c:230
HRESULT dplaysp_create(REFIID riid, void **ppv, IDirectPlayImpl *dp)
Definition: dplaysp.c:696
#define DPLAYI_GROUP_HIDDEN
Definition: dplaysp.h:63
#define IDirectPlaySP_SetSPPlayerData(p, a, b, c, d)
Definition: dplaysp.h:106
HRESULT(WINAPI * LPDPSP_SPINIT)(LPSPINITDATA)
Definition: dplaysp.h:366
#define IDirectPlaySP_Release(p)
Definition: dplaysp.h:97
#define DPLAYI_GROUP_SYSGROUP
Definition: dplaysp.h:60
#define DPSP_MAJORVERSION
Definition: dplaysp.h:40
#define DPLAYI_PLAYER_PLAYERLOCAL
Definition: dplaysp.h:59
#define DPCANCELSEND_ALL
Definition: dplaysp.h:278
#define DPCANCELSEND_PRIORITY
Definition: dplaysp.h:277
#define DPLAYI_GROUP_DPLAYOWNS
Definition: dplaysp.h:61
#define DPLAYI_PLAYER_APPSERVER
Definition: dplaysp.h:62
#define DPLAYI_PLAYER_SYSPLAYER
Definition: dplaysp.h:56
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:41
static void *static void *static LPDIRECTPLAY * lplpDP
Definition: dplayx.c:41
LPCSTR DPLAYX_HresultToString(HRESULT hr)
HRESULT DP_MSG_ReadPackedPlayer(char *data, DWORD *inoutOffset, DWORD maxSize, DPPLAYERINFO *playerInfo)
void DP_MSG_ReplyReceived(IDirectPlayImpl *This, WORD wCommandId, const void *lpcMsgBody, DWORD dwMsgBodySize, const void *msgHeader)
HRESULT DP_MSG_SendAddPlayerToGroup(IDirectPlayImpl *This, DPID toId, DPID playerId, DPID groupId)
HRESULT DP_MSG_ForwardPlayerCreation(IDirectPlayImpl *This, DPID dpidServer, WCHAR *password)
void DP_MSG_ToSelf(IDirectPlayImpl *This, DPID dpidSelf)
HRESULT DP_MSG_SendPingReply(IDirectPlayImpl *This, DPID toId, DPID fromId, DWORD tickCount)
HRESULT DP_MSG_SendAddForwardAck(IDirectPlayImpl *This, DPID id)
HRESULT DP_MSG_SendRequestPlayerId(IDirectPlayImpl *This, DWORD dwFlags, DPID *lpdpidAllocatedId)
DWORD DP_MSG_ComputeMessageSize(SGBUFFER *buffers, DWORD bufferCount)
HRESULT DP_MSG_SendCreatePlayer(IDirectPlayImpl *This, DPID toId, DPID id, DWORD flags, DPNAME *name, void *playerData, DWORD playerDataSize, DPID systemPlayerId)
#define DPMSGCMD_GROUPDATACHANGED
#define DPMSGCMD_SUPERENUMPLAYERSREPLY
#define DPMSGVER_DP6
#define DPMSGCMD_ENUMSESSIONSREQUEST
#define DPMSGCMD_CREATESESSION
#define DPMSGCMD_PING
#define DPMSGCMD_GETNAMETABLEREPLY
struct tagDPMSG_CREATESESSION DPMSG_CREATESESSION
#define DPMSG_WAIT_5_SECS
#define DPMSGCMD_FORWARDADDPLAYER
#define DPMSGCMD_ENUMSESSIONSREPLY
#define DPMSGCMD_REQUESTNEWPLAYERID
#define DPMSGCMD_NEWPLAYERIDREPLY
#define DPMSGCMD_ADDFORWARD
#define DPMSGCMD_JUSTENVELOPE
struct tagDPMSG_SYSMSGENVELOPE DPMSG_SYSMSGENVELOPE
#define DPMSGCMD_FORWARDADDPLAYERNACK
struct tagDPMSG_NEWPLAYERIDREPLY * LPDPMSG_NEWPLAYERIDREPLY
#define DPMSGMAGIC_DPLAYMSG
#define DPQ_REMOVE_ENTRY(head, elm, field, fieldCompareOperator, fieldToCompare, rc)
Definition: dplayx_queue.h:162
#define DPQ_INIT(head)
Definition: dplayx_queue.h:54
#define DPQ_INSERT(a, b, c)
Definition: dplayx_queue.h:34
#define DPQ_NEXT(elem)
Definition: dplayx_queue.h:67
#define DPQ_FIRST(head)
Definition: dplayx_queue.h:61
#define DPQ_INSERT_IN_TAIL(head, elm, field)
Definition: dplayx_queue.h:73
#define DPQ_FIND_ENTRY(head, elm, field, fieldCompareOperator, fieldToCompare, rc)
Definition: dplayx_queue.h:100
#define DPQ_REMOVE(head, elm, field)
Definition: dplayx_queue.h:82
#define DPQ_DECL_DELETECB(name, type)
Definition: dplayx_queue.h:211
HRESULT WINAPI SPInit(LPSPINITDATA)
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
r reserved
Definition: btrfs.c:3006
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizei GLuint * groups
Definition: glext.h:11113
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLboolean GLuint group
Definition: glext.h:11120
GLenum GLsizei dataSize
Definition: glext.h:11123
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
GLboolean enable
Definition: glext.h:11120
GLfloat param
Definition: glext.h:5796
const GLuint * buffers
Definition: glext.h:5916
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
static TfClientId tid
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define GUID_NULL
Definition: ks.h:106
HRESULT(WINAPI * LPSP_INIT)(LPSPDATA_INIT)
Definition: lobbysp.h:460
#define CopyMemory
Definition: minwinbase.h:29
BOOL * LPBOOL
Definition: minwindef.h:138
CONST void * LPCVOID
Definition: minwindef.h:164
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
const char * fullname
Definition: shader.c:1979
static HANDLE hEvent
Definition: comm.c:54
static const WCHAR sp[]
Definition: suminfo.c:433
static size_t elem
Definition: string.c:71
static int priority
Definition: timer.c:163
HRESULT NS_SendSessionRequestBroadcast(LPCGUID lpcGuid, DWORD dwFlags, WCHAR *password, const SPINITDATA *lpSpData)
Definition: name_server.c:192
void NS_SetLocalComputerAsNameServer(LPCDPSESSIONDESC2 lpsd, LPVOID lpNSInfo)
Definition: name_server.c:88
BOOL NS_InitializeSessionCache(LPVOID *lplpNSInfo)
Definition: name_server.c:262
void NS_InvalidateSessionCache(LPVOID lpNSInfo)
Definition: name_server.c:245
void NS_ReplyToEnumSessionsRequest(const void *lpcMsg, void **lplpReplyData, DWORD *lpdwReplySize, IDirectPlayImpl *lpDP)
Definition: name_server.c:371
void NS_AddRemoteComputerAsNameServer(LPCVOID lpcNSAddrHdr, DWORD dwHdrSize, LPCDPMSG_ENUMSESSIONSREPLY lpcMsg, DWORD msgSize, LPVOID lpNSInfo)
Definition: name_server.c:101
void NS_ResetSessionEnumeration(LPVOID lpNSInfo)
Definition: name_server.c:290
void NS_PruneSessionCache(LPVOID lpNSInfo)
Definition: name_server.c:332
LPDPSESSIONDESC2 NS_WalkSessions(LPVOID lpNSInfo, void **spMessageHeader, BOOL ansi)
Definition: name_server.c:306
void NS_SetLocalAddr(LPVOID lpNSInfo, LPCVOID lpHdr, DWORD dwHdrSize)
Definition: name_server.c:180
void NS_DeleteSessionCache(LPVOID lpNSInfo)
Definition: name_server.c:283
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define KEY_READ
Definition: nt_native.h:1026
#define DWORD
Definition: nt_native.h:44
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
#define calloc
Definition: rosglue.h:14
static Parse plist[]
Definition: dwarfinfo.c:339
UCHAR byteCount
Definition: scsi.h:3755
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
__WINE_SERVER_LIST_INLINE struct list * list_tail(const struct list *list)
Definition: list.h:139
#define memset(x, y, z)
Definition: compat.h:39
LOCAL siconvt_t * glist
Definition: sic_nls.c:92
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
DPID toId
Definition: dplay_global.h:157
DWORD genericSize
Definition: dplay_global.h:160
DPID fromId
Definition: dplay_global.h:156
FN_COPY_MESSAGE * copyMessage
Definition: dplay_global.h:159
DPMSG_GENERIC * msg
Definition: dplay_global.h:158
DWORD playerDataLength
LPVOID lpSPPlayerData
Definition: dplay_global.h:137
DWORD dwLocalDataSize
Definition: dplay_global.h:130
DWORD dwRemoteDataSize
Definition: dplay_global.h:134
LPVOID lpRemoteData
Definition: dplay_global.h:133
DWORD dwFlags
Definition: dplay_global.h:122
DPNAME * nameA
Definition: dplay_global.h:126
ULONG uRef
Definition: dplay_global.h:115
LPVOID lpLocalData
Definition: dplay_global.h:129
DPNAME * name
Definition: dplay_global.h:125
lpGroupData lpGData
Definition: dplay_global.h:146
CRITICAL_SECTION lock
Definition: dplay_global.h:224
IDirectPlay4 IDirectPlay4_iface
Definition: dplay_global.h:222
int name
Definition: dwarfinfo.c:331
ULONG uRef
Definition: dplay_global.h:85
DWORD dwLocalDataSize
Definition: dplay_global.h:89
LPVOID lpRemoteData
Definition: dplay_global.h:92
LPVOID lpSPPlayerData
Definition: dplay_global.h:96
LPVOID lpLocalData
Definition: dplay_global.h:88
DPNAME * nameA
Definition: dplay_global.h:82
DWORD dwRemoteDataSize
Definition: dplay_global.h:93
DPNAME * name
Definition: dplay_global.h:81
HANDLE hEvent
Definition: dplay_global.h:83
DWORD dwFlags
Definition: dplay_global.h:98
lpPlayerData lpPData
Definition: dplay_global.h:106
DPID idPlayer
Definition: dplay.c:2483
IDirectPlayImpl * This
Definition: dplay.c:2482
BOOL bAnsi
Definition: dplay.c:2484
IDirectPlayImpl * This
Definition: dplay.c:2356
DPID idGroup
Definition: dplay.c:2358
BOOL bAnsi
Definition: dplay.c:2357
Definition: scsiwmi.h:51
Definition: http.c:7252
Definition: filter.c:185
Definition: copy.c:22
Definition: name.c:39
Definition: send.c:48
Definition: ps.c:97
LPCGUID lpGuid
Definition: dplay.c:6606
LPVOID lpConn
Definition: dplay.c:6605
DWORD dwSize
Definition: dplay.h:169
DWORD dwTimeout
Definition: dplay.h:180
DPMSG_SENDENVELOPE envelope
LPSTR lpszSessionNameA
Definition: dplay.h:244
LPSTR lpszPasswordA
Definition: dplay.h:250
GUID guidApplication
Definition: dplay.h:235
LPWSTR lpszPassword
Definition: dplay.h:249
GUID guidInstance
Definition: dplay.h:234
DWORD dwSize
Definition: dplay.h:232
LPDWORD lpdwSPMsgID
Definition: dplaysp.h:248
IDirectPlaySP * lpISP
Definition: dplaysp.h:238
DWORD dwMessageSize
Definition: dplaysp.h:244
LPSGBUFFER lpSendBuffers
Definition: dplaysp.h:242
LPVOID lpDPContext
Definition: dplaysp.h:247
LPSGBUFFER lpSendBuffers
Definition: dplaysp.h:258
IDirectPlaySP * lpISP
Definition: dplaysp.h:254
DWORD dwReserved2
Definition: dplaysp.h:359
LPWSTR lpszName
Definition: dplaysp.h:356
DWORD dwReserved1
Definition: dplaysp.h:358
Definition: dhcpd.h:248
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:738
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
#define LIST_INIT(head)
Definition: queue.h:197
#define LIST_ENTRY(type)
Definition: queue.h:175
#define DWORD_PTR
Definition: treelist.c:76
unsigned char UCHAR
Definition: typedefs.h:53
uint32_t * LPDWORD
Definition: typedefs.h:59
char * LPSTR
Definition: typedefs.h:51
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:64
static UINT WPARAM LPARAM BOOL ansi
Definition: misc.c:135
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
_In_ LPCSTR lpName
Definition: winbase.h:2519
void WINAPI DebugBreak(void)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
RTL_RUN_ONCE INIT_ONCE
Definition: winbase.h:3654
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:591
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define RRF_RT_DWORD
Definition: winreg.h:64
#define RRF_RT_REG_SZ
Definition: winreg.h:58
#define DUPLICATE_SAME_ACCESS
unsigned char BYTE
Definition: xxhash.c:193