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

Last change on this file since 4446 was 4446, checked in by hugh, 25 years ago

Updated to latest WINE

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