source: trunk/src/DPlayX/dplaysp.cpp@ 10367

Last change on this file since 10367 was 5311, checked in by hugh, 24 years ago

Synced with WINE

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