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

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

Updated to latest wine version

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