source: trunk/src/DPlayX/dplaysp.cpp

Last change on this file was 21494, checked in by dmik, 15 years ago

Fixed broken build after r21492 by sorting out a huuuuge wagon of duplicates, wrong include order and other dirty mess.

File size: 24.7 KB
Line 
1// $Id: dplaysp.cpp,v 1.4 2001-03-13 23:13:27 hugh Exp $
2/* This contains the implementation of the interface Service
3 * Providers require to communicate with Direct Play
4 *
5 * Copyright 2000 Peter Hunnisett <hunnise@nortelnetworks.com>
6 */
7
8#include <string.h>
9
10#include <odin.h>
11#define CINTERFACE
12
13#include "winerror.h"
14#include "heap.h"
15#include "debugtools.h"
16
17#include "dpinit.h"
18#include "dplaysp.h"
19#include "dplay_global.h"
20#include "name_server.h"
21#include "dplayx_messages.h"
22
23#include "dplayx_global.h" /* FIXME: For global hack */
24
25/* FIXME: Need to add interface locking inside procedures */
26
27DEFAULT_DEBUG_CHANNEL(dplay);
28
29#undef debugstr_guid
30#define debugstr_guid(a) a
31
32
33/* Prototypes */
34static BOOL DPSP_CreateIUnknown( LPVOID lpSP );
35static BOOL DPSP_DestroyIUnknown( LPVOID lpSP );
36static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp );
37static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP );
38
39
40/* Predefine the interface */
41typedef struct IDirectPlaySPImpl IDirectPlaySPImpl;
42
43typedef struct tagDirectPlaySPIUnknownData
44{
45 ULONG ulObjRef;
46 CRITICAL_SECTION DPSP_lock;
47} DirectPlaySPIUnknownData;
48
49typedef struct tagDirectPlaySPData
50{
51 LPVOID lpSpRemoteData;
52 DWORD dwSpRemoteDataSize; /* Size of data pointed to by lpSpRemoteData */
53
54 LPVOID lpSpLocalData;
55 DWORD dwSpLocalDataSize; /* Size of data pointed to by lpSpLocalData */
56
57 IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */
58
59} DirectPlaySPData;
60
61#define DPSP_IMPL_FIELDS \
62 ULONG ulInterfaceRef; \
63 DirectPlaySPIUnknownData* unk; \
64 DirectPlaySPData* sp;
65
66struct IDirectPlaySPImpl
67{
68 ICOM_VFIELD(IDirectPlaySP);
69 DPSP_IMPL_FIELDS
70};
71
72/* Forward declaration of virtual tables */
73extern ICOM_VTABLE(IDirectPlaySP) directPlaySPVT;
74
75/* This structure is passed to the DP object for safe keeping */
76typedef struct tagDP_SPPLAYERDATA
77{
78 LPVOID lpPlayerLocalData;
79 DWORD dwPlayerLocalDataSize;
80
81 LPVOID lpPlayerRemoteData;
82 DWORD dwPlayerRemoteDataSize;
83} DP_SPPLAYERDATA, *LPDP_SPPLAYERDATA;
84
85
86
87/* Create the SP interface */
88extern
89HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp )
90{
91 TRACE( " for %s\n", debugstr_guid( riid ) );
92
93 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
94 sizeof( IDirectPlaySPImpl ) );
95
96 if( *ppvObj == NULL )
97 {
98 return DPERR_OUTOFMEMORY;
99 }
100
101 if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
102 {
103 ICOM_THIS(IDirectPlaySPImpl,*ppvObj);
104 ICOM_VTBL(This) = &directPlaySPVT;
105 }
106 else
107 {
108 /* Unsupported interface */
109 HeapFree( GetProcessHeap(), 0, *ppvObj );
110 *ppvObj = NULL;
111
112 return E_NOINTERFACE;
113 }
114
115 /* Initialize it */
116 if( DPSP_CreateIUnknown( *ppvObj ) &&
117 DPSP_CreateDirectPlaySP( *ppvObj, dp )
118 )
119 {
120 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
121 return S_OK;
122 }
123
124 /* Initialize failed, destroy it */
125 DPSP_DestroyDirectPlaySP( *ppvObj );
126 DPSP_DestroyIUnknown( *ppvObj );
127
128 HeapFree( GetProcessHeap(), 0, *ppvObj );
129 *ppvObj = NULL;
130
131 return DPERR_NOMEMORY;
132}
133
134static BOOL DPSP_CreateIUnknown( LPVOID lpSP )
135{
136 ICOM_THIS(IDirectPlaySPImpl,lpSP);
137
138 This->unk = (DirectPlaySPIUnknownData*)HeapAlloc( GetProcessHeap(),
139 HEAP_ZERO_MEMORY,
140 sizeof( *(This->unk) ) );
141
142 if ( This->unk == NULL )
143 {
144 return FALSE;
145 }
146
147 InitializeCriticalSection( &This->unk->DPSP_lock );
148
149 return TRUE;
150}
151
152static BOOL DPSP_DestroyIUnknown( LPVOID lpSP )
153{
154 ICOM_THIS(IDirectPlaySPImpl,lpSP);
155
156 DeleteCriticalSection( &This->unk->DPSP_lock );
157 HeapFree( GetProcessHeap(), 0, This->unk );
158
159 return TRUE;
160}
161
162
163static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp )
164{
165 ICOM_THIS(IDirectPlaySPImpl,lpSP);
166
167 This->sp = (DirectPlaySPData*)HeapAlloc( GetProcessHeap(),
168 HEAP_ZERO_MEMORY,
169 sizeof( *(This->sp) ) );
170
171 if ( This->sp == NULL )
172 {
173 return FALSE;
174 }
175
176 This->sp->dplay = dp;
177
178 /* Normally we should be keeping a reference, but since only the dplay
179 * interface that created us can destroy us, we do not keep a reference
180 * to it (ie we'd be stuck with always having one reference to the dplay
181 * object, and hence us, around).
182 * NOTE: The dp object does reference count us.
183 */
184 /* IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp ); */
185
186 /* FIXME: This is a kludge to get around a problem where a queryinterface
187 * is used to get a new interface and then is closed. We will then
188 * reference garbage. However, with this we will never deallocate
189 * the interface we store. The correct fix is to require all
190 * DP internal interfaces to use the This->dp2 interface which
191 * should be changed to This->dp
192 */
193 IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp );
194
195 return TRUE;
196}
197
198static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP )
199{
200 ICOM_THIS(IDirectPlaySPImpl,lpSP);
201
202 /* Normally we should be keeping a reference, but since only the dplay
203 * interface that created us can destroy us, we do not keep a reference
204 * to it (ie we'd be stuck with always having one reference to the dplay
205 * object, and hence us, around).
206 * NOTE: The dp object does reference count us.
207 */
208 /*IDirectPlayX_Release( (LPDIRECTPLAY2)This->sp->dplay ); */
209
210 HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
211 HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
212
213 /* FIXME: Need to delete player queue */
214
215 HeapFree( GetProcessHeap(), 0, This->sp );
216 return TRUE;
217}
218
219/* Interface implementation */
220
221static HRESULT WINAPI DPSP_QueryInterface
222( LPDIRECTPLAYSP iface,
223 REFIID riid,
224 LPVOID* ppvObj )
225{
226 ICOM_THIS(IDirectPlaySPImpl,iface);
227 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj );
228
229 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
230 sizeof( IDirectPlaySPImpl ) );
231
232 if( *ppvObj == NULL )
233 {
234 return DPERR_OUTOFMEMORY;
235 }
236
237 CopyMemory( *ppvObj, iface, sizeof( IDirectPlaySPImpl ) );
238 (*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0;
239
240 if( IsEqualGUID( &IID_IDirectPlaySP, riid ) )
241 {
242 ICOM_THIS(IDirectPlaySPImpl,*ppvObj);
243 ICOM_VTBL(This) = &directPlaySPVT;
244 }
245 else
246 {
247 /* Unsupported interface */
248 HeapFree( GetProcessHeap(), 0, *ppvObj );
249 *ppvObj = NULL;
250
251 return E_NOINTERFACE;
252 }
253
254 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj );
255
256 return S_OK;
257}
258
259static ULONG WINAPI DPSP_AddRef
260( LPDIRECTPLAYSP iface )
261{
262 ULONG ulInterfaceRefCount, ulObjRefCount;
263 ICOM_THIS(IDirectPlaySPImpl,iface);
264
265 ulObjRefCount = InterlockedIncrement( (LPLONG)&This->unk->ulObjRef );
266 ulInterfaceRefCount = InterlockedIncrement( (LPLONG)&This->ulInterfaceRef );
267
268 TRACE( "ref count incremented to %lu:%lu for %p\n",
269 ulInterfaceRefCount, ulObjRefCount, This );
270
271 return ulObjRefCount;
272}
273
274static ULONG WINAPI DPSP_Release
275( LPDIRECTPLAYSP iface )
276{
277 ULONG ulInterfaceRefCount, ulObjRefCount;
278 ICOM_THIS(IDirectPlaySPImpl,iface);
279
280 ulObjRefCount = InterlockedDecrement( (LPLONG)&This->unk->ulObjRef );
281 ulInterfaceRefCount = InterlockedDecrement( (LPLONG)&This->ulInterfaceRef );
282
283 TRACE( "ref count decremented to %lu:%lu for %p\n",
284 ulInterfaceRefCount, ulObjRefCount, This );
285
286 /* Deallocate if this is the last reference to the object */
287 if( ulObjRefCount == 0 )
288 {
289 DPSP_DestroyDirectPlaySP( This );
290 DPSP_DestroyIUnknown( This );
291 }
292
293 if( ulInterfaceRefCount == 0 )
294 {
295 HeapFree( GetProcessHeap(), 0, This );
296 }
297
298 return ulInterfaceRefCount;
299}
300
301static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry
302( LPDIRECTPLAYSP iface,
303 LPCWSTR lpSection,
304 LPCWSTR lpKey,
305 LPCVOID lpData,
306 DWORD dwDataSize,
307 DWORD dwMaxEntries
308)
309{
310 ICOM_THIS(IDirectPlaySPImpl,iface);
311
312 FIXME( "(%p)->(%p,%p%p,0x%08lx,0x%08lx): stub\n",
313 This, lpSection, lpKey, lpData, dwDataSize, dwMaxEntries );
314
315 return DP_OK;
316}
317
318static HRESULT WINAPI IDirectPlaySPImpl_CreateAddress
319( LPDIRECTPLAYSP iface,
320 REFGUID guidSP,
321 REFGUID guidDataType,
322 LPCVOID lpData,
323 DWORD dwDataSize,
324 LPVOID lpAddress,
325 LPDWORD lpdwAddressSize
326)
327{
328 ICOM_THIS(IDirectPlaySPImpl,iface);
329
330 FIXME( "(%p)->(%s,%s,%p,0x%08lx,%p,%p): stub\n",
331 This, debugstr_guid(guidSP), debugstr_guid(guidDataType),
332 lpData, dwDataSize, lpAddress, lpdwAddressSize );
333
334 return DP_OK;
335}
336
337static HRESULT WINAPI IDirectPlaySPImpl_EnumAddress
338( LPDIRECTPLAYSP iface,
339 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback,
340 LPCVOID lpAddress,
341 DWORD dwAddressSize,
342 LPVOID lpContext
343)
344{
345 ICOM_THIS(IDirectPlaySPImpl,iface);
346
347 TRACE( "(%p)->(%p,%p,0x%08lx,%p)\n",
348 This, lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
349
350 DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext );
351
352 return DP_OK;
353}
354
355static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries
356( LPDIRECTPLAYSP iface,
357 LPCWSTR lpSection,
358 LPCWSTR lpKey,
359 LPENUMMRUCALLBACK lpEnumMRUCallback,
360 LPVOID lpContext
361)
362{
363 ICOM_THIS(IDirectPlaySPImpl,iface);
364
365 FIXME( "(%p)->(%p,%p,%p,%p,): stub\n",
366 This, lpSection, lpKey, lpEnumMRUCallback, lpContext );
367
368 return DP_OK;
369}
370
371static HRESULT WINAPI IDirectPlaySPImpl_GetPlayerFlags
372( LPDIRECTPLAYSP iface,
373 DPID idPlayer,
374 LPDWORD lpdwPlayerFlags
375)
376{
377 ICOM_THIS(IDirectPlaySPImpl,iface);
378
379 FIXME( "(%p)->(0x%08lx,%p): stub\n",
380 This, idPlayer, lpdwPlayerFlags );
381
382 return DP_OK;
383}
384
385static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData
386( LPDIRECTPLAYSP iface,
387 DPID idPlayer,
388 LPVOID* lplpData,
389 LPDWORD lpdwDataSize,
390 DWORD dwFlags
391)
392{
393 HRESULT hr;
394 LPDP_SPPLAYERDATA lpPlayerData;
395 ICOM_THIS(IDirectPlaySPImpl,iface);
396
397/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
398 TRACE( "(%p)->(0x%08lx,%p,%p,0x%08lx)\n",
399 This, idPlayer, lplpData, lpdwDataSize, dwFlags );
400
401 hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerData );
402
403 if( FAILED(hr) )
404 {
405 TRACE( "Couldn't get player data: %s\n", DPLAYX_HresultToString(hr) );
406 return DPERR_INVALIDPLAYER;
407 }
408
409 /* What to do in the case where there is nothing set yet? */
410 if( dwFlags == DPSET_LOCAL )
411 {
412 if( lpPlayerData->lpPlayerLocalData )
413 {
414 HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerLocalData );
415 }
416
417 *lplpData = lpPlayerData->lpPlayerLocalData;
418 *lpdwDataSize = lpPlayerData->dwPlayerLocalDataSize;
419 }
420 else if( dwFlags == DPSET_REMOTE )
421 {
422 if( lpPlayerData->lpPlayerRemoteData )
423 {
424 HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerRemoteData );
425 }
426
427 *lplpData = lpPlayerData->lpPlayerRemoteData;
428 *lpdwDataSize = lpPlayerData->dwPlayerRemoteDataSize;
429 }
430
431 if( *lplpData == NULL )
432 {
433 hr = DPERR_GENERIC;
434 }
435
436 return hr;
437}
438
439static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage
440( LPDIRECTPLAYSP iface,
441 LPVOID lpMessageBody,
442 DWORD dwMessageBodySize,
443 LPVOID lpMessageHeader
444)
445{
446 LPDPMSG_SENDENVELOPE lpMsg = (LPDPMSG_SENDENVELOPE)lpMessageBody;
447 HRESULT hr = DPERR_GENERIC;
448 WORD wCommandId;
449 WORD wVersion;
450
451 ICOM_THIS(IDirectPlaySPImpl,iface);
452
453/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
454 FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n",
455 This, lpMessageBody, dwMessageBodySize, lpMessageHeader );
456
457 wCommandId = lpMsg->wCommandId;
458 wVersion = lpMsg->wVersion;
459
460 TRACE( "Incomming message has envelope of 0x%08lx, %u, %u\n",
461 lpMsg->dwMagic, wCommandId, wVersion );
462
463 if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG )
464 {
465 ERR( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic );
466 }
467
468 switch( lpMsg->wCommandId )
469 {
470 /* Name server needs to handle this request */
471 /* FIXME: This should be done in direct play handler */
472 case DPMSGCMD_ENUMSESSIONSREQUEST:
473 {
474 DPSP_REPLYDATA data;
475
476 data.lpSPMessageHeader = lpMessageHeader;
477 data.idNameServer = 0;
478 data.lpISP = iface;
479
480 NS_ReplyToEnumSessionsRequest( lpMessageBody, &data, This->sp->dplay );
481
482 hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
483
484 if( FAILED(hr) )
485 {
486 ERR( "Reply failed 0x%08lx\n", hr );
487 }
488
489 break;
490 }
491
492 /* Name server needs to handle this request */
493 /* FIXME: This should be done in direct play handler */
494 case DPMSGCMD_ENUMSESSIONSREPLY:
495 {
496 NS_SetRemoteComputerAsNameServer( lpMessageHeader,
497 This->sp->dplay->dp2->spData.dwSPHeaderSize,
498 (LPDPMSG_ENUMSESSIONSREPLY)lpMessageBody,
499 This->sp->dplay->dp2->lpNameServerData );
500
501 /* No reply expected */
502 hr = DP_OK;
503
504 break;
505 }
506
507 /* Pass everything else to Direct Play */
508 default:
509 {
510 DPSP_REPLYDATA data;
511
512 data.lpMessage = NULL;
513 data.dwMessageSize = 0;
514
515 /* Pass this message to the dplay interface to handle */
516 hr = DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize,
517 lpMessageHeader, wCommandId, wVersion,
518 &data.lpMessage, &data.dwMessageSize );
519
520 /* Do we want a reply? */
521 if( data.lpMessage != NULL )
522 {
523 HRESULT hr;
524
525 data.lpSPMessageHeader = lpMessageHeader;
526 data.idNameServer = 0;
527 data.lpISP = iface;
528
529 hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data );
530
531 if( FAILED(hr) )
532 {
533 ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr) );
534 }
535 }
536
537 break;
538 }
539 }
540
541#if 0
542 HRESULT hr = DP_OK;
543 HANDLE hReceiveEvent = 0;
544 /* FIXME: Aquire some sort of interface lock */
545 /* FIXME: Need some sort of context for this callback. Need to determine
546 * how this is actually done with the SP
547 */
548 /* FIXME: Who needs to delete the message when done? */
549 switch( lpMsg->dwType )
550 {
551 case DPSYS_CREATEPLAYERORGROUP:
552 {
553 LPDPMSG_CREATEPLAYERORGROUP msg = (LPDPMSG_CREATEPLAYERORGROUP)lpMsg;
554
555 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
556 {
557 hr = DP_IF_CreatePlayer( This, lpMessageHeader, msg->dpId,
558 &msg->dpnName, 0, msg->lpData,
559 msg->dwDataSize, msg->dwFlags, ... );
560 }
561 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
562 {
563 /* Group in group situation? */
564 if( msg->dpIdParent == DPID_NOPARENT_GROUP )
565 {
566 hr = DP_IF_CreateGroup( This, lpMessageHeader, msg->dpId,
567 &msg->dpnName, 0, msg->lpData,
568 msg->dwDataSize, msg->dwFlags, ... );
569 }
570 else /* Group in Group */
571 {
572 hr = DP_IF_CreateGroupInGroup( This, lpMessageHeader, msg->dpIdParent,
573 &msg->dpnName, 0, msg->lpData,
574 msg->dwDataSize, msg->dwFlags, ... );
575 }
576 }
577 else /* Hmmm? */
578 {
579 ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" );
580 return;
581 }
582
583 break;
584 }
585
586 case DPSYS_DESTROYPLAYERORGROUP:
587 {
588 LPDPMSG_DESTROYPLAYERORGROUP msg = (LPDPMSG_DESTROYPLAYERORGROUP)lpMsg;
589
590 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
591 {
592 hr = DP_IF_DestroyPlayer( This, msg->dpId, ... );
593 }
594 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
595 {
596 hr = DP_IF_DestroyGroup( This, msg->dpId, ... );
597 }
598 else /* Hmmm? */
599 {
600 ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" );
601 return;
602 }
603
604 break;
605 }
606
607 case DPSYS_ADDPLAYERTOGROUP:
608 {
609 LPDPMSG_ADDPLAYERTOGROUP msg = (LPDPMSG_ADDPLAYERTOGROUP)lpMsg;
610
611 hr = DP_IF_AddPlayerToGroup( This, msg->dpIdGroup, msg->dpIdPlayer, ... );
612 break;
613 }
614
615 case DPSYS_DELETEPLAYERFROMGROUP:
616 {
617 LPDPMSG_DELETEPLAYERFROMGROUP msg = (LPDPMSG_DELETEPLAYERFROMGROUP)lpMsg;
618
619 hr = DP_IF_DeletePlayerFromGroup( This, msg->dpIdGroup, msg->dpIdPlayer,
620 ... );
621
622 break;
623 }
624
625 case DPSYS_SESSIONLOST:
626 {
627 LPDPMSG_SESSIONLOST msg = (LPDPMSG_SESSIONLOST)lpMsg;
628
629 FIXME( "DPSYS_SESSIONLOST not handled\n" );
630
631 break;
632 }
633
634 case DPSYS_HOST:
635 {
636 LPDPMSG_HOST msg = (LPDPMSG_HOST)lpMsg;
637
638 FIXME( "DPSYS_HOST not handled\n" );
639
640 break;
641 }
642
643 case DPSYS_SETPLAYERORGROUPDATA:
644 {
645 LPDPMSG_SETPLAYERORGROUPDATA msg = (LPDPMSG_SETPLAYERORGROUPDATA)lpMsg;
646
647 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
648 {
649 hr = DP_IF_SetPlayerData( This, msg->dpId, msg->lpData, msg->dwDataSize, DPSET_REMOTE, ... );
650 }
651 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
652 {
653 hr = DP_IF_SetGroupData( This, msg->dpId, msg->lpData, msg->dwDataSize,
654 DPSET_REMOTE, ... );
655 }
656 else /* Hmmm? */
657 {
658 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
659 return;
660 }
661
662 break;
663 }
664
665 case DPSYS_SETPLAYERORGROUPNAME:
666 {
667 LPDPMSG_SETPLAYERORGROUPNAME msg = (LPDPMSG_SETPLAYERORGROUPNAME)lpMsg;
668
669 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER )
670 {
671 hr = DP_IF_SetPlayerName( This, msg->dpId, msg->dpnName, ... );
672 }
673 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP )
674 {
675 hr = DP_IF_SetGroupName( This, msg->dpId, msg->dpnName, ... );
676 }
677 else /* Hmmm? */
678 {
679 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" );
680 return;
681 }
682
683 break;
684 }
685
686 case DPSYS_SETSESSIONDESC;
687 {
688 LPDPMSG_SETSESSIONDESC msg = (LPDPMSG_SETSESSIONDESC)lpMsg;
689
690 hr = DP_IF_SetSessionDesc( This, &msg->dpDesc );
691
692 break;
693 }
694
695 case DPSYS_ADDGROUPTOGROUP:
696 {
697 LPDPMSG_ADDGROUPTOGROUP msg = (LPDPMSG_ADDGROUPTOGROUP)lpMsg;
698
699 hr = DP_IF_AddGroupToGroup( This, msg->dpIdParentGroup, msg->dpIdGroup,
700 ... );
701
702 break;
703 }
704
705 case DPSYS_DELETEGROUPFROMGROUP:
706 {
707 LPDPMSG_DELETEGROUPFROMGROUP msg = (LPDPMSG_DELETEGROUPFROMGROUP)lpMsg;
708
709 hr = DP_IF_DeleteGroupFromGroup( This, msg->dpIdParentGroup,
710 msg->dpIdGroup, ... );
711
712 break;
713 }
714
715 case DPSYS_SECUREMESSAGE:
716 {
717 LPDPMSG_SECUREMESSAGE msg = (LPDPMSG_SECUREMESSAGE)lpMsg;
718
719 FIXME( "DPSYS_SECUREMESSAGE not implemented\n" );
720
721 break;
722 }
723
724 case DPSYS_STARTSESSION:
725 {
726 LPDPMSG_STARTSESSION msg = (LPDPMSG_STARTSESSION)lpMsg;
727
728 FIXME( "DPSYS_STARTSESSION not implemented\n" );
729
730 break;
731 }
732
733 case DPSYS_CHAT:
734 {
735 LPDPMSG_CHAT msg = (LPDPMSG_CHAT)lpMsg;
736
737 FIXME( "DPSYS_CHAT not implemeneted\n" );
738
739 break;
740 }
741
742 case DPSYS_SETGROUPOWNER:
743 {
744 LPDPMSG_SETGROUPOWNER msg = (LPDPMSG_SETGROUPOWNER)lpMsg;
745
746 FIXME( "DPSYS_SETGROUPOWNER not implemented\n" );
747
748 break;
749 }
750
751 case DPSYS_SENDCOMPLETE:
752 {
753 LPDPMSG_SENDCOMPLETE msg = (LPDPMSG_SENDCOMPLETE)lpMsg;
754
755 FIXME( "DPSYS_SENDCOMPLETE not implemented\n" );
756
757 break;
758 }
759
760 default:
761 {
762 /* NOTE: This should be a user defined type. There is nothing that we
763 * need to do with it except queue it.
764 */
765 TRACE( "Received user message type(?) 0x%08lx through SP.\n",
766 lpMsg->dwType );
767 break;
768 }
769 }
770
771 FIXME( "Queue message in the receive queue. Need some context data!\n" );
772
773 if( FAILED(hr) )
774 {
775 ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg->dwType );
776 }
777 /* If a receieve event was registered for this player, invoke it */
778 if( hReceiveEvent )
779 {
780 SetEvent( hReceiveEvent );
781 }
782#endif
783
784 return hr;
785}
786
787static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData
788( LPDIRECTPLAYSP iface,
789 DPID idPlayer,
790 LPVOID lpData,
791 DWORD dwDataSize,
792 DWORD dwFlags
793)
794{
795 HRESULT hr;
796 LPDP_SPPLAYERDATA lpPlayerEntry;
797 LPVOID lpPlayerData;
798
799 ICOM_THIS(IDirectPlaySPImpl,iface);
800
801/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
802 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n",
803 This, idPlayer, lpData, dwDataSize, dwFlags );
804
805 hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerEntry );
806 if( FAILED(hr) )
807 {
808 /* Player must not exist */
809 return DPERR_INVALIDPLAYER;
810 }
811
812 lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
813 CopyMemory( lpPlayerData, lpData, dwDataSize );
814
815 if( dwFlags == DPSET_LOCAL )
816 {
817 lpPlayerEntry->lpPlayerLocalData = lpPlayerData;
818 lpPlayerEntry->dwPlayerLocalDataSize = dwDataSize;
819 }
820 else if( dwFlags == DPSET_REMOTE )
821 {
822 lpPlayerEntry->lpPlayerRemoteData = lpPlayerData;
823 lpPlayerEntry->dwPlayerRemoteDataSize = dwDataSize;
824 }
825
826 hr = DP_SetSPPlayerData( This->sp->dplay, idPlayer, lpPlayerEntry );
827
828 return hr;
829}
830
831static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress
832( LPDIRECTPLAYSP iface,
833 LPCDPCOMPOUNDADDRESSELEMENT lpElements,
834 DWORD dwElementCount,
835 LPVOID lpAddress,
836 LPDWORD lpdwAddressSize
837)
838{
839 ICOM_THIS(IDirectPlaySPImpl,iface);
840
841 FIXME( "(%p)->(%p,0x%08lx,%p,%p): stub\n",
842 This, lpElements, dwElementCount, lpAddress, lpdwAddressSize );
843
844 return DP_OK;
845}
846
847static HRESULT WINAPI IDirectPlaySPImpl_GetSPData
848( LPDIRECTPLAYSP iface,
849 LPVOID* lplpData,
850 LPDWORD lpdwDataSize,
851 DWORD dwFlags
852)
853{
854 HRESULT hr = DP_OK;
855 ICOM_THIS(IDirectPlaySPImpl,iface);
856
857/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
858 TRACE( "(%p)->(%p,%p,0x%08lx)\n",
859 This, lplpData, lpdwDataSize, dwFlags );
860
861#if 0
862 /* This is what the documentation says... */
863 if( dwFlags != DPSET_REMOTE )
864 {
865 return DPERR_INVALIDPARAMS;
866 }
867#else
868 /* ... but most service providers call this with 1 */
869 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
870 * thing?
871 */
872 if( dwFlags != DPSET_REMOTE )
873 {
874 FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
875 }
876#endif
877
878 /* FIXME: What to do in the case where this isn't initialized yet? */
879
880 /* Yes, we're supposed to return a pointer to the memory we have stored! */
881 if( dwFlags == DPSET_REMOTE )
882 {
883 *lpdwDataSize = This->sp->dwSpRemoteDataSize;
884 *lplpData = This->sp->lpSpRemoteData;
885
886 if( This->sp->lpSpRemoteData == NULL )
887 {
888 hr = DPERR_GENERIC;
889 }
890 }
891 else if( dwFlags == DPSET_LOCAL )
892 {
893 *lpdwDataSize = This->sp->dwSpLocalDataSize;
894 *lplpData = This->sp->lpSpLocalData;
895
896 if( This->sp->lpSpLocalData == NULL )
897 {
898 hr = DPERR_GENERIC;
899 }
900 }
901
902 return hr;
903}
904
905static HRESULT WINAPI IDirectPlaySPImpl_SetSPData
906( LPDIRECTPLAYSP iface,
907 LPVOID lpData,
908 DWORD dwDataSize,
909 DWORD dwFlags
910)
911{
912 LPVOID lpSpData;
913
914 ICOM_THIS(IDirectPlaySPImpl,iface);
915
916/* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */
917 TRACE( "(%p)->(%p,0x%08lx,0x%08lx)\n",
918 This, lpData, dwDataSize, dwFlags );
919
920#if 0
921 /* This is what the documentation says... */
922 if( dwFlags != DPSET_REMOTE )
923 {
924 return DPERR_INVALIDPARAMS;
925 }
926#else
927 /* ... but most service providers call this with 1 */
928 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of
929 * thing?
930 */
931 if( dwFlags != DPSET_REMOTE )
932 {
933 FIXME( "Undocumented dwFlags 0x%08lx used\n", dwFlags );
934 }
935#endif
936
937 lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize );
938 CopyMemory( lpSpData, lpData, dwDataSize );
939
940 /* If we have data already allocated, free it and replace it */
941 if( dwFlags == DPSET_REMOTE )
942 {
943 if( This->sp->lpSpRemoteData )
944 {
945 HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData );
946 }
947
948 This->sp->dwSpRemoteDataSize = dwDataSize;
949 This->sp->lpSpRemoteData = lpSpData;
950 }
951 else if ( dwFlags == DPSET_LOCAL )
952 {
953 if( This->sp->lpSpLocalData )
954 {
955 HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData );
956 }
957
958 This->sp->lpSpLocalData = lpSpData;
959 This->sp->dwSpLocalDataSize = dwDataSize;
960 }
961
962 return DP_OK;
963}
964
965static VOID WINAPI IDirectPlaySPImpl_SendComplete
966( LPDIRECTPLAYSP iface,
967 LPVOID unknownA,
968 DWORD unknownB
969)
970{
971 ICOM_THIS(IDirectPlaySPImpl,iface);
972
973 FIXME( "(%p)->(%p,0x%08lx): stub\n",
974 This, unknownA, unknownB );
975}
976
977
978struct ICOM_VTABLE(IDirectPlaySP) directPlaySPVT =
979{
980 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
981
982 DPSP_QueryInterface,
983 DPSP_AddRef,
984 DPSP_Release,
985
986 IDirectPlaySPImpl_AddMRUEntry,
987 IDirectPlaySPImpl_CreateAddress,
988 IDirectPlaySPImpl_EnumAddress,
989 IDirectPlaySPImpl_EnumMRUEntries,
990 IDirectPlaySPImpl_GetPlayerFlags,
991 IDirectPlaySPImpl_GetSPPlayerData,
992 IDirectPlaySPImpl_HandleMessage,
993 IDirectPlaySPImpl_SetSPPlayerData,
994 IDirectPlaySPImpl_CreateCompoundAddress,
995 IDirectPlaySPImpl_GetSPData,
996 IDirectPlaySPImpl_SetSPData,
997 IDirectPlaySPImpl_SendComplete
998};
999
1000
1001/* DP external interfaces to call into DPSP interface */
1002
1003/* Allocate the structure */
1004extern LPVOID DPSP_CreateSPPlayerData(void)
1005{
1006 TRACE( "Creating SPPlayer data struct\n" );
1007 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
1008 sizeof( DP_SPPLAYERDATA ) );
1009}
1010
Note: See TracBrowser for help on using the repository browser.