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

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

Added ID tags

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