ReactOS 0.4.17-dev-923-g4c9a150
dpwsockx_main.c
Go to the documentation of this file.
1/* Internet TCP/IP and IPX Connection For DirectPlay
2 *
3 * Copyright 2008 Ismael Barros Barros
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20
21#include <stdarg.h>
22
23#include "windef.h"
24#include "winbase.h"
25#include "winsock2.h"
26#include "dpwsockx_dll.h"
27#include "wine/debug.h"
28#include "dplay.h"
29#include "wine/dplaysp.h"
30
32
33#define DPWS_PORT 47624
34#define DPWS_START_TCP_PORT 2300
35#define DPWS_END_TCP_PORT 2350
36#define DPWS_START_UDP_PORT 2350
37#define DPWS_END_UDP_PORT 2400
38
40
41static int DPWS_CompareConnections( const void *key, const struct rb_entry *entry )
42{
44 DPWS_CONNECTION_KEY *connection_key = (DPWS_CONNECTION_KEY *)key;
45
46 if ( connection_key->addr.sin_port < connection->key.addr.sin_port )
47 return -1;
48 if ( connection_key->addr.sin_port > connection->key.addr.sin_port )
49 return 1;
50
51 if ( connection_key->addr.sin_addr.s_addr < connection->key.addr.sin_addr.s_addr )
52 return -1;
53 if ( connection_key->addr.sin_addr.s_addr > connection->key.addr.sin_addr.s_addr )
54 return 1;
55
56 if ( connection_key->guaranteed < connection->key.guaranteed )
57 return -1;
58 if ( connection_key->guaranteed > connection->key.guaranteed )
59 return 1;
60
61 return 0;
62}
63
64static int DPWS_CompareConnectionRefs( const void *key, const struct rb_entry *entry )
65{
67
68 return DPWS_CompareConnections( key, &connectionRef->connection->entry );
69}
70
71static HRESULT DPWS_BindToFreePort( SOCKET sock, SOCKADDR_IN *addr, int startPort, int endPort )
72{
73 int port;
74
75 memset( addr, 0, sizeof( *addr ) );
76 addr->sin_family = AF_INET;
77 addr->sin_addr.s_addr = htonl( INADDR_ANY );
78
79 for ( port = startPort; port < endPort; ++port )
80 {
81 addr->sin_port = htons( port );
82
83 if ( SOCKET_ERROR != bind( sock, (SOCKADDR *) addr, sizeof( *addr ) ) )
84 return DP_OK;
85
87 continue;
88
89 ERR( "bind() failed\n" );
90 return DPERR_UNAVAILABLE;
91 }
92
93 ERR( "no free ports\n" );
94 return DPERR_UNAVAILABLE;
95}
96
98{
99 list_remove( &connection->entry );
100 closesocket( connection->tcpSock );
101 free( connection->buffer );
102 free( connection );
103}
104
107{
109
110 if ( error != ERROR_SUCCESS )
111 {
112 ERR( "WSARecv() failed\n" );
114 return;
115 }
116
117 if ( !transferred )
118 {
120 return;
121 }
122
123 if ( transferred < connection->wsaBuffer.len )
124 {
125 connection->wsaBuffer.len -= transferred;
126 connection->wsaBuffer.buf += transferred;
127
128 if ( SOCKET_ERROR == WSARecv( connection->tcpSock, &connection->wsaBuffer, 1, &transferred,
129 &flags, &connection->overlapped, DPWS_TcpReceiveCompleted ) )
130 {
132 {
133 ERR( "WSARecv() failed\n" );
135 return;
136 }
137 }
138 return;
139 }
140
141 connection->completionRoutine( connection );
142}
143
145 DPWS_COMPLETION_ROUTINE *completionRoutine )
146{
147 DWORD transferred;
148 DWORD flags = 0;
149
150 connection->wsaBuffer.len = size;
151 connection->wsaBuffer.buf = data;
152
153 connection->completionRoutine = completionRoutine;
154
155 if ( SOCKET_ERROR == WSARecv( connection->tcpSock, &connection->wsaBuffer, 1, &transferred,
156 &flags, &connection->overlapped, DPWS_TcpReceiveCompleted ) )
157 {
159 {
160 ERR( "WSARecv() failed\n" );
161 return DPERR_UNAVAILABLE;
162 }
163 }
164
165 return DP_OK;
166}
167
169{
170 int messageBodySize;
171 int messageSize;
172
173 messageSize = DPSP_MSG_SIZE( connection->header.mixed );
174 if ( messageSize < sizeof( DPSP_MSG_HEADER ))
175 {
176 ERR( "message is too short: %d\n", messageSize );
178 return;
179 }
180 messageBodySize = messageSize - sizeof( DPSP_MSG_HEADER );
181
182 if ( messageBodySize > DPWS_GUARANTEED_MAXBUFFERSIZE )
183 {
184 ERR( "message is too long: %d\n", messageSize );
186 return;
187 }
188
189 if ( connection->bufferSize < messageBodySize )
190 {
191 int newSize = max( connection->bufferSize * 2, messageBodySize );
192 char *newBuffer = malloc( newSize );
193 if ( !newBuffer )
194 {
195 ERR( "failed to allocate required memory.\n" );
197 return;
198 }
199 free( connection->buffer );
200 connection->buffer = newBuffer;
201 connection->bufferSize = newSize;
202 }
203
204 if ( FAILED( DPWS_TcpReceive( connection, connection->buffer, messageBodySize,
206 {
208 return;
209 }
210}
211
213{
214 int messageBodySize;
215 int messageSize;
216
217 if ( connection->header.SockAddr.sin_addr.s_addr == INADDR_ANY )
218 connection->header.SockAddr.sin_addr = connection->addr.sin_addr;
219
220 messageSize = DPSP_MSG_SIZE( connection->header.mixed );
221 messageBodySize = messageSize - sizeof( DPSP_MSG_HEADER );
222
223 IDirectPlaySP_HandleMessage( connection->sp, connection->buffer, messageBodySize,
224 &connection->header );
225
226 if ( FAILED( DPWS_TcpReceive( connection, &connection->header, sizeof( DPSP_MSG_HEADER ),
228 {
230 return;
231 }
232}
233
236{
237 DPWS_DATA *dpwsData = (DPWS_DATA *)overlapped->hEvent;
239 int messageBodySize;
240 char *messageBody;
241
242 if ( error != ERROR_SUCCESS )
243 {
244 ERR( "WSARecv() failed\n" );
245 return;
246 }
247
248 messageBody = dpwsData->buffer;
249 messageBodySize = transferred;
250 header = NULL;
251
252 if ( transferred >= sizeof( DPSP_MSG_HEADER ) + sizeof( DWORD ) )
253 {
254 DWORD signature = *(DWORD *)&dpwsData->buffer[ sizeof( DPSP_MSG_HEADER ) ];
255 if ( signature == 0x79616c70 )
256 {
257 int messageSize;
258
259 header = (DPSP_MSG_HEADER *)dpwsData->buffer;
260 messageSize = DPSP_MSG_SIZE( header->mixed );
261
262 if ( messageSize < sizeof( DPSP_MSG_HEADER ))
263 {
264 ERR( "message is too short: %d\n", messageSize );
265 return;
266 }
267 if ( messageSize > transferred )
268 {
269 ERR( "truncated message\n" );
270 return;
271 }
272
273 messageBody = dpwsData->buffer + sizeof( DPSP_MSG_HEADER );
274 messageBodySize = messageSize - sizeof( DPSP_MSG_HEADER );
275 }
276 }
277
278 IDirectPlaySP_HandleMessage( dpwsData->lpISP, messageBody, messageBodySize, header );
279
280 if ( SOCKET_ERROR == WSARecv( dpwsData->udpSock, &dpwsData->wsaBuffer, 1, &transferred, &flags,
282 {
284 {
285 ERR( "WSARecv() failed\n" );
286 return;
287 }
288 }
289}
290
292{
293 DPWS_DATA *dpwsData = (DPWS_DATA *)param;
294 DWORD transferred;
295 DWORD flags = 0;
296
298
299 if ( SOCKET_ERROR == WSARecv( dpwsData->udpSock, &dpwsData->wsaBuffer, 1, &transferred, &flags,
301 {
303 {
304 ERR( "WSARecv() failed\n" );
305 return 0;
306 }
307 }
308
309 for ( ;; )
310 {
312 WSANETWORKEVENTS networkEvents;
313 WSAEVENT events[2];
315 DWORD waitResult;
316 int addrSize;
317 SOCKET sock;
318
319 events[ 0 ] = dpwsData->stopEvent;
320 events[ 1 ] = dpwsData->acceptEvent;
322 TRUE );
323 if ( waitResult == WSA_WAIT_FAILED )
324 {
325 ERR( "WSAWaitForMultipleEvents() failed\n" );
326 break;
327 }
328 if ( waitResult == WSA_WAIT_IO_COMPLETION )
329 continue;
330 if ( waitResult == WSA_WAIT_EVENT_0 )
331 break;
332
333 if ( SOCKET_ERROR == WSAEnumNetworkEvents( dpwsData->tcpSock, dpwsData->acceptEvent,
334 &networkEvents ) )
335 {
336 ERR( "WSAEnumNetworkEvents() failed\n" );
337 break;
338 }
339
340 addrSize = sizeof( addr );
341 sock = accept( dpwsData->tcpSock, (SOCKADDR *)&addr, &addrSize );
342 if ( sock == INVALID_SOCKET )
343 {
345 continue;
346 ERR( "accept() failed\n" );
347 break;
348 }
349
350 connection = calloc( 1, sizeof( DPWS_IN_CONNECTION ) );
351 if ( !connection )
352 {
353 ERR( "failed to allocate required memory.\n" );
354 closesocket( sock );
355 continue;
356 }
357
358 connection->addr = addr;
359 connection->tcpSock = sock;
360 connection->overlapped.hEvent = connection;
361 connection->sp = dpwsData->lpISP;
362
363 list_add_tail( &dpwsData->inConnections, &connection->entry );
364
365 if ( FAILED( DPWS_TcpReceive( connection, &connection->header, sizeof( DPSP_MSG_HEADER ),
367 {
369 continue;
370 }
371 }
372
373 return 0;
374}
375
376static HRESULT DPWS_Start( DPWS_DATA *dpwsData )
377{
378 HRESULT hr;
379
380 if ( dpwsData->started )
381 return S_OK;
382
384 if ( dpwsData->tcpSock == INVALID_SOCKET )
385 {
386 ERR( "socket() failed\n" );
387 return DPERR_UNAVAILABLE;
388 }
389
390 hr = DPWS_BindToFreePort( dpwsData->tcpSock, &dpwsData->tcpAddr, DPWS_START_TCP_PORT,
392 if ( FAILED( hr ) )
393 {
394 closesocket( dpwsData->tcpSock );
395 return hr;
396 }
397
398 if ( SOCKET_ERROR == listen( dpwsData->tcpSock, SOMAXCONN ) )
399 {
400 ERR( "listen() failed\n" );
401 closesocket( dpwsData->tcpSock );
402 return DPERR_UNAVAILABLE;
403 }
404
405 dpwsData->acceptEvent = WSACreateEvent();
406 if ( !dpwsData->acceptEvent )
407 {
408 ERR( "WSACreateEvent() failed\n" );
409 closesocket( dpwsData->tcpSock );
410 return DPERR_UNAVAILABLE;
411 }
412
413 if ( SOCKET_ERROR == WSAEventSelect( dpwsData->tcpSock, dpwsData->acceptEvent, FD_ACCEPT ) )
414 {
415 ERR( "WSAEventSelect() failed\n" );
416 WSACloseEvent( dpwsData->acceptEvent );
417 closesocket( dpwsData->tcpSock );
418 return DPERR_UNAVAILABLE;
419 }
420
421 list_init( &dpwsData->inConnections );
422
424 if ( dpwsData->udpSock == INVALID_SOCKET )
425 {
426 ERR( "socket() failed\n" );
427 WSACloseEvent( dpwsData->acceptEvent );
428 closesocket( dpwsData->tcpSock );
429 return DPERR_UNAVAILABLE;
430 }
431
432 hr = DPWS_BindToFreePort( dpwsData->udpSock, &dpwsData->udpAddr, DPWS_START_UDP_PORT,
434 if ( FAILED( hr ) )
435 {
436 closesocket( dpwsData->udpSock );
437 WSACloseEvent( dpwsData->acceptEvent );
438 closesocket( dpwsData->tcpSock );
439 return hr;
440 }
441
442 dpwsData->overlapped.hEvent = (HANDLE)dpwsData;
443 dpwsData->wsaBuffer.len = sizeof( dpwsData->buffer );
444 dpwsData->wsaBuffer.buf = dpwsData->buffer;
445
447
448 dpwsData->stopEvent = WSACreateEvent();
449 if ( !dpwsData->stopEvent )
450 {
451 ERR( "WSACreateEvent() failed\n" );
452 closesocket( dpwsData->udpSock );
453 WSACloseEvent( dpwsData->acceptEvent );
454 closesocket( dpwsData->tcpSock );
455 return DPERR_UNAVAILABLE;
456 }
457
458 InitializeCriticalSection( &dpwsData->sendCs );
459
460 dpwsData->thread = CreateThread( NULL, 0, DPWS_ThreadProc, dpwsData, 0, NULL );
461 if ( !dpwsData->thread )
462 {
463 ERR( "CreateThread() failed\n" );
464 DeleteCriticalSection( &dpwsData->sendCs );
465 WSACloseEvent( dpwsData->stopEvent );
466 closesocket( dpwsData->udpSock );
467 WSACloseEvent( dpwsData->acceptEvent );
468 closesocket( dpwsData->tcpSock );
469 return DPERR_UNAVAILABLE;
470 }
471
472 dpwsData->started = TRUE;
473
474 return S_OK;
475}
476
477static void DPWS_Stop( DPWS_DATA *dpwsData )
478{
479 DPWS_OUT_CONNECTION *outConnection2;
480 DPWS_OUT_CONNECTION *outConnection;
481 DPWS_IN_CONNECTION *inConnection2;
482 DPWS_IN_CONNECTION *inConnection;
483
484 if ( !dpwsData->started )
485 return;
486
487 dpwsData->started = FALSE;
488
489 WSASetEvent( dpwsData->stopEvent );
490 WaitForSingleObject( dpwsData->thread, INFINITE );
491 CloseHandle( dpwsData->thread );
492
493 RB_FOR_EACH_ENTRY_DESTRUCTOR( outConnection, outConnection2, &dpwsData->connections,
495 {
496 rb_remove( &dpwsData->connections, &outConnection->entry );
497 if ( outConnection->tcpSock != INVALID_SOCKET )
498 closesocket( outConnection->tcpSock );
499 free( outConnection );
500 }
501
502 LIST_FOR_EACH_ENTRY_SAFE( inConnection, inConnection2, &dpwsData->inConnections,
504 DPWS_RemoveInConnection( inConnection );
505
506 DeleteCriticalSection( &dpwsData->sendCs );
507 WSACloseEvent( dpwsData->stopEvent );
508 closesocket( dpwsData->udpSock );
509 WSACloseEvent( dpwsData->acceptEvent );
510 closesocket( dpwsData->tcpSock );
511}
512
514{
515 DPSP_MSG_HEADER *header = (DPSP_MSG_HEADER *) data->lpMessage;
516 DPWS_DATA *dpwsData;
517 DWORD dpwsDataSize;
519 BOOL trueflag = TRUE;
520 SOCKET sock;
521 HRESULT hr;
522
523 TRACE( "(%p,%ld,%p,%u)\n",
524 data->lpMessage, data->dwMessageSize,
525 data->lpISP, data->bReturnStatus );
526
527 hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL );
528 if ( FAILED( hr ) )
529 return hr;
530
531 hr = DPWS_Start( dpwsData );
532 if ( FAILED (hr) )
533 return hr;
534
536 if ( sock == INVALID_SOCKET )
537 {
538 ERR( "socket() failed\n" );
539 return DPERR_UNAVAILABLE;
540 }
541
543 (const char *) &trueflag,
544 sizeof( trueflag ) ) )
545 {
546 ERR( "setsockopt() failed\n" );
547 closesocket( sock );
548 return DPERR_UNAVAILABLE;
549 }
550
551 memset( header, 0, sizeof( DPSP_MSG_HEADER ) );
552 header->mixed = DPSP_MSG_MAKE_MIXED( data->dwMessageSize, DPSP_MSG_TOKEN_REMOTE );
553 header->SockAddr.sin_family = AF_INET;
554 header->SockAddr.sin_port = dpwsData->tcpAddr.sin_port;
555
556 memset( &addr, 0, sizeof( addr ) );
557 addr.sin_family = AF_INET;
558 addr.sin_addr.s_addr = htonl( INADDR_BROADCAST );
559 addr.sin_port = htons( DPWS_PORT );
560
561 if ( SOCKET_ERROR == sendto( sock, data->lpMessage, data->dwMessageSize, 0, (SOCKADDR *) &addr,
562 sizeof( addr ) ) )
563 {
564 ERR( "sendto() failed\n" );
565 closesocket( sock );
566 return DPERR_UNAVAILABLE;
567 }
568
569 closesocket( sock );
570
571 return DP_OK;
572}
573
575{
576 FIXME( "(%p,%p,%ld,%ld,%p) stub\n",
577 data->lpSPMessageHeader, data->lpMessage, data->dwMessageSize,
578 data->idNameServer, data->lpISP );
579 return DPERR_UNSUPPORTED;
580}
581
583{
584 FIXME( "(0x%08lx,%ld,%ld,%p,%ld,%u,%p) stub\n",
585 data->dwFlags, data->idPlayerTo, data->idPlayerFrom,
586 data->lpMessage, data->dwMessageSize,
587 data->bSystemMessage, data->lpISP );
588 return DPERR_UNSUPPORTED;
589}
590
592{
593 DPWS_CONNECTION_REF *playerConnectionRef;
594 DPWS_CONNECTION_REF *groupConnectionRef;
595 struct rb_entry *entry;
596 DPWS_PLAYER *player;
598 DWORD playerSize;
599 DWORD groupSize;
600 HRESULT hr;
601
602 TRACE( "(%ld,%ld,%p)\n", data->idPlayer, data->idGroup, data->lpISP );
603
604 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer, (void **) &player, &playerSize,
605 DPSET_LOCAL );
606 if ( FAILED( hr ) )
607 return hr;
608
609 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroup, (void **) &group, &groupSize,
610 DPSET_LOCAL );
611 if ( FAILED( hr ) )
612 return hr;
613
614 RB_FOR_EACH_ENTRY( playerConnectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry )
615 {
616 entry = rb_get( &group->connectionRefs, &playerConnectionRef->connection->key );
617 if ( entry )
618 {
619 groupConnectionRef = RB_ENTRY_VALUE( entry, DPWS_CONNECTION_REF, entry );
620 ++groupConnectionRef->ref;
621 continue;
622 }
623 groupConnectionRef = calloc( 1, sizeof( DPWS_CONNECTION_REF ) );
624 if ( !groupConnectionRef )
625 return DPERR_OUTOFMEMORY;
626 groupConnectionRef->ref = 1;
627 groupConnectionRef->connection = playerConnectionRef->connection;
628 rb_put( &group->connectionRefs, &groupConnectionRef->connection->key,
629 &groupConnectionRef->entry );
630 }
631
632 return DP_OK;
633}
634
636{
637 DPWS_PLAYER groupPlaceholder = { 0 };
639 DWORD groupSize;
640 HRESULT hr;
641
642 TRACE( "(%ld,0x%08lx,%p,%p)\n", data->idGroup, data->dwFlags, data->lpSPMessageHeader,
643 data->lpISP );
644
645 hr = IDirectPlaySP_SetSPPlayerData( data->lpISP, data->idGroup, &groupPlaceholder,
646 sizeof( groupPlaceholder ), DPSET_LOCAL );
647 if ( FAILED( hr ) )
648 return hr;
649
650 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroup, (void **) &group, &groupSize,
651 DPSET_LOCAL );
652 if ( FAILED( hr ) )
653 return hr;
654
655 rb_init( &group->connectionRefs, DPWS_CompareConnectionRefs );
656
657 return DP_OK;
658}
659
660static HRESULT DPWS_GetConnection( DPWS_DATA *dpwsData, SOCKADDR_IN *addr, BOOL guaranteed,
662{
664 struct rb_entry *entry;
665
666 key.addr = *addr;
667 key.guaranteed = guaranteed;
668
669 entry = rb_get( &dpwsData->connections, &key );
670 if ( entry )
671 {
673 return DP_OK;
674 }
675
676 *connection = calloc( 1, sizeof( DPWS_OUT_CONNECTION ) );
677 if ( !*connection )
678 return DPERR_OUTOFMEMORY;
679
680 (*connection)->key = key;
681 (*connection)->tcpSock = INVALID_SOCKET;
682
683 rb_put( &dpwsData->connections, &(*connection)->key, &(*connection)->entry );
684
685 return DP_OK;
686}
687
689{
690 DPWS_CONNECTION_REF *tcpConnectionRef;
691 DPWS_CONNECTION_REF *udpConnectionRef;
692 DPWS_PLAYER playerPlaceholder = { 0 };
693 DPWS_PLAYERDATA *playerData;
694 DWORD playerDataSize;
695 DPWS_PLAYER *player;
696 DPWS_DATA *dpwsData;
697 DWORD dpwsDataSize;
698 DWORD playerSize;
699 HRESULT hr;
700
701 TRACE( "(%ld,0x%08lx,%p,%p)\n",
702 data->idPlayer, data->dwFlags,
703 data->lpSPMessageHeader, data->lpISP );
704
705 hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL );
706 if ( FAILED( hr ) )
707 return hr;
708
709 if ( !data->lpSPMessageHeader )
710 {
711 DPWS_PLAYERDATA playerDataPlaceholder = { 0 };
712 hr = IDirectPlaySP_SetSPPlayerData( data->lpISP, data->idPlayer,
713 (void *) &playerDataPlaceholder,
714 sizeof( playerDataPlaceholder ), DPSET_REMOTE );
715 if ( FAILED( hr ) )
716 return hr;
717 }
718
719 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer, (void **) &playerData,
720 &playerDataSize, DPSET_REMOTE );
721 if ( FAILED( hr ) )
722 return hr;
723 if ( playerDataSize != sizeof( DPWS_PLAYERDATA ) )
724 return DPERR_GENERIC;
725
726 if ( data->lpSPMessageHeader )
727 {
728 DPSP_MSG_HEADER *header = data->lpSPMessageHeader;
729 if ( !playerData->tcpAddr.sin_addr.s_addr )
730 playerData->tcpAddr.sin_addr = header->SockAddr.sin_addr;
731 if ( !playerData->udpAddr.sin_addr.s_addr )
732 playerData->udpAddr.sin_addr = header->SockAddr.sin_addr;
733 }
734 else
735 {
736 playerData->tcpAddr.sin_family = AF_INET;
737 playerData->tcpAddr.sin_port = dpwsData->tcpAddr.sin_port;
738 playerData->udpAddr.sin_family = AF_INET;
739 playerData->udpAddr.sin_port = dpwsData->udpAddr.sin_port;
740 }
741
742 hr = IDirectPlaySP_SetSPPlayerData( data->lpISP, data->idPlayer, (void *) &playerPlaceholder,
743 sizeof( playerPlaceholder ), DPSET_LOCAL );
744 if ( FAILED( hr ) )
745 return hr;
746
747 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer,
748 (void **) &player, &playerSize, DPSET_LOCAL );
749 if ( FAILED( hr ) )
750 return hr;
751
753
754 if ( data->dwFlags & DPLAYI_PLAYER_PLAYERLOCAL )
755 return DP_OK;
756
757 tcpConnectionRef = calloc( 1, sizeof( DPWS_CONNECTION_REF ) );
758 if ( !tcpConnectionRef )
759 {
760 free( player );
761 return DPERR_OUTOFMEMORY;
762 }
763
764 tcpConnectionRef->ref = 1;
765
766 hr = DPWS_GetConnection( dpwsData, &playerData->tcpAddr, TRUE, &tcpConnectionRef->connection );
767 if ( FAILED( hr ) )
768 {
769 free( tcpConnectionRef );
770 free( player );
771 return hr;
772 }
773
774 udpConnectionRef = calloc( 1, sizeof( DPWS_CONNECTION_REF ) );
775 if ( !udpConnectionRef )
776 {
777 free( tcpConnectionRef );
778 free( player );
779 return DPERR_OUTOFMEMORY;
780 }
781
782 udpConnectionRef->ref = 1;
783
784 hr = DPWS_GetConnection( dpwsData, &playerData->udpAddr, FALSE, &udpConnectionRef->connection );
785 if ( FAILED( hr ) )
786 {
787 free( udpConnectionRef );
788 free( tcpConnectionRef );
789 free( player );
790 return hr;
791 }
792
793 rb_put( &player->connectionRefs, &tcpConnectionRef->connection->key, &tcpConnectionRef->entry );
794 rb_put( &player->connectionRefs, &udpConnectionRef->connection->key, &udpConnectionRef->entry );
795
796 return DP_OK;
797}
798
800{
801 DPWS_CONNECTION_REF *connectionRef2;
802 DPWS_CONNECTION_REF *connectionRef;
804 DWORD groupSize;
805 HRESULT hr;
806
807 TRACE( "(%ld,0x%08lx,%p)\n", data->idGroup, data->dwFlags, data->lpISP );
808
809 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroup, (void **) &group, &groupSize,
810 DPSET_LOCAL );
811 if ( FAILED( hr ) )
812 return hr;
813
814 RB_FOR_EACH_ENTRY_DESTRUCTOR( connectionRef, connectionRef2, &group->connectionRefs,
816 {
817 rb_remove( &group->connectionRefs, &connectionRef->entry );
818 free( connectionRef );
819 }
820
821 return DP_OK;
822}
823
825{
826 DPWS_CONNECTION_REF *connectionRef2;
827 DPWS_CONNECTION_REF *connectionRef;
828 DPWS_PLAYER *player;
829 DWORD playerSize;
830 HRESULT hr;
831
832 TRACE( "(%ld,0x%08lx,%p)\n",
833 data->idPlayer, data->dwFlags, data->lpISP );
834
835 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer, (void **) &player, &playerSize,
836 DPSET_LOCAL );
837 if ( FAILED( hr ) )
838 return hr;
839
840 RB_FOR_EACH_ENTRY_DESTRUCTOR( connectionRef, connectionRef2, &player->connectionRefs,
842 {
843 rb_remove( &player->connectionRefs, &connectionRef->entry );
844 free( connectionRef );
845 }
846
847 return DP_OK;
848}
849
851{
852 FIXME( "(%ld,0x%08lx,%p,%p,%p) stub\n",
853 data->idPlayer, data->dwFlags, data->lpAddress,
854 data->lpdwAddressSize, data->lpISP );
855 return DPERR_UNSUPPORTED;
856}
857
859{
860 TRACE( "(%ld,%p,0x%08lx,%p)\n",
861 data->idPlayer, data->lpCaps, data->dwFlags, data->lpISP );
862
863 data->lpCaps->dwFlags = ( DPCAPS_ASYNCSUPPORTED |
866
867 data->lpCaps->dwMaxQueueSize = DPWS_MAXQUEUESIZE;
868 data->lpCaps->dwHundredBaud = DPWS_HUNDREDBAUD;
869 data->lpCaps->dwLatency = DPWS_LATENCY;
870 data->lpCaps->dwMaxLocalPlayers = DPWS_MAXLOCALPLAYERS;
871 data->lpCaps->dwHeaderLength = sizeof(DPSP_MSG_HEADER);
872 data->lpCaps->dwTimeout = DPWS_TIMEOUT;
873
874 if ( data->dwFlags & DPGETCAPS_GUARANTEED )
875 {
876 data->lpCaps->dwMaxBufferSize = DPWS_GUARANTEED_MAXBUFFERSIZE;
877 data->lpCaps->dwMaxPlayers = DPWS_GUARANTEED_MAXPLAYERS;
878 }
879 else
880 {
881 data->lpCaps->dwMaxBufferSize = DPWS_MAXBUFFERSIZE;
882 data->lpCaps->dwMaxPlayers = DPWS_MAXPLAYERS;
883 }
884
885 return DP_OK;
886}
887
889{
890 DPSP_MSG_HEADER *header = (DPSP_MSG_HEADER *) data->lpSPMessageHeader;
891 SOCKADDR_IN nameserverAddr;
892 DPWS_DATA *dpwsData;
893 DWORD dpwsDataSize;
894 HRESULT hr;
895
896 TRACE( "(%u,%p,%p,%u,0x%08lx,0x%08lx)\n",
897 data->bCreate, data->lpSPMessageHeader, data->lpISP,
898 data->bReturnStatus, data->dwOpenFlags, data->dwSessionFlags );
899
900 if ( data->bCreate )
901 {
902 FIXME( "session creation is not yet supported\n" );
903 return DPERR_UNSUPPORTED;
904 }
905
906 hr = IDirectPlaySP_GetSPData( data->lpISP, (void **)&dpwsData, &dpwsDataSize, DPSET_LOCAL );
907 if ( FAILED( hr ) )
908 return hr;
909
910 hr = DPWS_Start( dpwsData );
911 if ( FAILED (hr) )
912 return hr;
913
914 memset( &nameserverAddr, 0, sizeof( nameserverAddr ) );
915 nameserverAddr.sin_family = AF_INET;
916 nameserverAddr.sin_addr = header->SockAddr.sin_addr;
917 nameserverAddr.sin_port = header->SockAddr.sin_port;
918
919 rb_init( &dpwsData->nameserver.connectionRefs, DPWS_CompareConnectionRefs );
920
921 hr = DPWS_GetConnection( dpwsData, &nameserverAddr, TRUE,
922 &dpwsData->nameserverConnectionRef.connection );
923 if ( FAILED( hr ) )
924 return hr;
925
926 rb_put( &dpwsData->nameserver.connectionRefs,
927 &dpwsData->nameserverConnectionRef.connection->key,
928 &dpwsData->nameserverConnectionRef.entry );
929
930 return DP_OK;
931}
932
934{
935 DPWS_CONNECTION_REF *playerConnectionRef;
936 DPWS_CONNECTION_REF *groupConnectionRef;
937 struct rb_entry *entry;
938 DPWS_PLAYER *player;
940 DWORD playerSize;
941 DWORD groupSize;
942 HRESULT hr;
943
944 TRACE( "(%ld,%ld,%p)\n", data->idPlayer, data->idGroup, data->lpISP );
945
946 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayer, (void **) &player, &playerSize,
947 DPSET_LOCAL );
948 if ( FAILED( hr ) )
949 return hr;
950
951 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroup, (void **) &group, &groupSize,
952 DPSET_LOCAL );
953 if ( FAILED( hr ) )
954 return hr;
955
956 RB_FOR_EACH_ENTRY( playerConnectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry )
957 {
958 entry = rb_get( &group->connectionRefs, &playerConnectionRef->connection->key );
959 if ( !entry )
960 continue;
961 groupConnectionRef = RB_ENTRY_VALUE( entry, DPWS_CONNECTION_REF, entry );
962 --groupConnectionRef->ref;
963 if ( groupConnectionRef->ref )
964 continue;
965 rb_remove( &player->connectionRefs, &groupConnectionRef->entry );
966 free( groupConnectionRef );
967 }
968
969 return DP_OK;
970}
971
973{
974 DPWS_DATA *dpwsData;
975 DWORD dpwsDataSize;
976 HRESULT hr;
977
978 TRACE( "(%p)\n", data->lpISP );
979
980 hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL );
981 if ( FAILED( hr ) )
982 return hr;
983
984 DPWS_Stop( dpwsData );
985
986 return DP_OK;
987}
988
990{
991 DPWS_DATA *dpwsData;
992 DWORD dpwsDataSize;
993 HRESULT hr;
994
995 TRACE( "(%p)\n", data->lpISP );
996
997 hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL );
998 if ( FAILED( hr ) )
999 return hr;
1000
1001 DPWS_Stop( dpwsData );
1002
1003 WSACleanup();
1004
1005 return DP_OK;
1006}
1007
1009{
1010 FIXME( "(%p,%p,%p) stub\n",
1011 data->lpAddress, data->lpdwAddressSize, data->lpISP );
1012 return DPERR_UNSUPPORTED;
1013}
1014
1016 DWORD bufferCount, DWORD messageSize, BOOL guaranteed, BOOL system )
1017{
1018 DPWS_CONNECTION_REF *connectionRef;
1019 DPSP_MSG_HEADER header = { 0 };
1020 HRESULT sendResult;
1021
1022 if ( guaranteed || system )
1023 {
1024 header.mixed = DPSP_MSG_MAKE_MIXED( messageSize, DPSP_MSG_TOKEN_REMOTE );
1025 header.SockAddr.sin_family = AF_INET;
1026 header.SockAddr.sin_port = dpwsData->tcpAddr.sin_port;
1027
1028 buffers[ 0 ].pData = (unsigned char *) &header;
1029 }
1030
1031 EnterCriticalSection( &dpwsData->sendCs );
1032
1033 if ( guaranteed )
1034 {
1035 RB_FOR_EACH_ENTRY( connectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry )
1036 {
1037 DPWS_OUT_CONNECTION *connection = connectionRef->connection;
1038
1039 if ( !connection->key.guaranteed )
1040 continue;
1041 if ( connection->tcpSock != INVALID_SOCKET )
1042 continue;
1043
1045 if ( connection->tcpSock == INVALID_SOCKET )
1046 {
1047 ERR( "socket() failed\n" );
1048 LeaveCriticalSection( &dpwsData->sendCs );
1049 return DPERR_UNAVAILABLE;
1050 }
1051
1052 if ( SOCKET_ERROR == connect( connection->tcpSock, (SOCKADDR *) &connection->key.addr,
1053 sizeof( connection->key.addr ) ) )
1054 {
1055 ERR( "connect() failed\n" );
1056 closesocket( connection->tcpSock );
1057 connection->tcpSock = INVALID_SOCKET;
1058 LeaveCriticalSection( &dpwsData->sendCs );
1059 return DPERR_UNAVAILABLE;
1060 }
1061 }
1062 }
1063
1064 sendResult = DP_OK;
1065
1066 RB_FOR_EACH_ENTRY( connectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry )
1067 {
1068 DPWS_OUT_CONNECTION *connection = connectionRef->connection;
1069 DWORD transferred;
1070
1071 if ( connection->key.guaranteed != guaranteed )
1072 continue;
1073
1074 if ( guaranteed )
1075 {
1076 if ( SOCKET_ERROR == WSASend( connection->tcpSock, (WSABUF *) buffers, bufferCount,
1077 &transferred, 0, &connection->overlapped, NULL ) )
1078 {
1080 {
1081 ERR( "WSASend() failed\n" );
1082 LeaveCriticalSection( &dpwsData->sendCs );
1083 return DPERR_UNAVAILABLE;
1084 }
1085 }
1086 }
1087 else
1088 {
1089 if ( SOCKET_ERROR == WSASendTo( dpwsData->udpSock, (WSABUF *) buffers, bufferCount,
1090 &transferred, 0, (SOCKADDR *) &connection->key.addr,
1091 sizeof( connection->key.addr ), &connection->overlapped,
1092 NULL ) )
1093 {
1095 {
1096 ERR( "WSASendTo() failed\n" );
1097 LeaveCriticalSection( &dpwsData->sendCs );
1098 return DPERR_UNAVAILABLE;
1099 }
1100 }
1101 }
1102 }
1103
1104 RB_FOR_EACH_ENTRY( connectionRef, &player->connectionRefs, DPWS_CONNECTION_REF, entry )
1105 {
1106 DPWS_OUT_CONNECTION *connection = connectionRef->connection;
1107 DWORD transferred;
1108#ifdef __REACTOS__
1109 DWORD flags;
1110#endif
1111 SOCKET sock;
1112
1113 if ( connection->key.guaranteed != guaranteed )
1114 continue;
1115
1116 sock = guaranteed ? connection->tcpSock : dpwsData->udpSock;
1117
1118#ifdef __REACTOS__
1119 if ( !WSAGetOverlappedResult( sock, &connection->overlapped, &transferred, TRUE, &flags ) )
1120#else
1121 if ( !WSAGetOverlappedResult( sock, &connection->overlapped, &transferred, TRUE, NULL ) )
1122#endif
1123 {
1124 ERR( "WSAGetOverlappedResult() failed\n" );
1125 sendResult = DPERR_UNAVAILABLE;
1126 continue;
1127 }
1128
1129 if ( guaranteed && transferred < messageSize )
1130 {
1131 ERR( "lost connection\n" );
1132 closesocket( connection->tcpSock );
1133 connection->tcpSock = INVALID_SOCKET;
1134 sendResult = DPERR_CONNECTIONLOST;
1135 continue;
1136 }
1137 }
1138
1139 LeaveCriticalSection( &dpwsData->sendCs );
1140
1141 return sendResult;
1142}
1143
1145{
1146 DPWS_PLAYER *player;
1147 DPWS_DATA *dpwsData;
1148 DWORD dpwsDataSize;
1149 HRESULT hr;
1150
1151 TRACE( "(%p,0x%08lx,%ld,%ld,%p,%ld,%ld,%ld,%ld,%p,%p,%u)\n",
1152 data->lpISP, data->dwFlags, data->idPlayerTo, data->idPlayerFrom,
1153 data->lpSendBuffers, data->cBuffers, data->dwMessageSize,
1154 data->dwPriority, data->dwTimeout, data->lpDPContext,
1155 data->lpdwSPMsgID, data->bSystemMessage );
1156
1157 if ( data->dwFlags & DPSEND_ASYNC )
1158 {
1159 FIXME("asynchronous send is not yet supported\n");
1160 return DPERR_UNSUPPORTED;
1161 }
1162
1163 hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL );
1164 if ( FAILED( hr ) )
1165 return hr;
1166
1167 if ( data->idPlayerTo )
1168 {
1169 DWORD playerSize;
1170 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idPlayerTo, (void **) &player,
1171 &playerSize, DPSET_LOCAL );
1172 if ( FAILED( hr ) )
1173 return hr;
1174 }
1175 else
1176 {
1177 player = &dpwsData->nameserver;
1178 }
1179
1180 return DPWS_SendImpl( dpwsData, player, data->lpSendBuffers, data->cBuffers,
1181 data->dwMessageSize, !!( data->dwFlags & DPSEND_GUARANTEED ),
1182 data->bSystemMessage );
1183}
1184
1186{
1187 DPWS_DATA *dpwsData;
1189 DWORD dpwsDataSize;
1190 DWORD groupSize;
1191 HRESULT hr;
1192
1193 TRACE( "(%p,0x%08lx,%ld,%ld,%p,%ld,%ld,%ld,%ld,%p,%p)\n",
1194 data->lpISP, data->dwFlags, data->idGroupTo, data->idPlayerFrom,
1195 data->lpSendBuffers, data->cBuffers, data->dwMessageSize,
1196 data->dwPriority, data->dwTimeout, data->lpDPContext,
1197 data->lpdwSPMsgID );
1198
1199 if ( data->dwFlags & DPSEND_ASYNC )
1200 {
1201 FIXME("asynchronous send is not yet supported\n");
1202 return DPERR_UNSUPPORTED;
1203 }
1204
1205 hr = IDirectPlaySP_GetSPData( data->lpISP, (void **) &dpwsData, &dpwsDataSize, DPSET_LOCAL );
1206 if ( FAILED( hr ) )
1207 return hr;
1208
1209 hr = IDirectPlaySP_GetSPPlayerData( data->lpISP, data->idGroupTo, (void **) &group, &groupSize,
1210 DPSET_LOCAL );
1211 if ( FAILED( hr ) )
1212 return hr;
1213
1214 return DPWS_SendImpl( dpwsData, group, data->lpSendBuffers, data->cBuffers, data->dwMessageSize,
1215 !!( data->dwFlags & DPSEND_GUARANTEED ), FALSE );
1216}
1217
1219{
1220 FIXME( "(%p,0x%08lx,%p,%ld,0x%08lx,0x%08lx) stub\n",
1221 data->lpISP, data->dwFlags, data->lprglpvSPMsgID, data->cSPMsgID,
1222 data->dwMinPriority, data->dwMaxPriority );
1223 return DPERR_UNSUPPORTED;
1224}
1225
1227{
1228 FIXME( "(%p,0x%08lx,%ld,%ld,%p,%p) stub\n",
1229 data->lpISP, data->dwFlags, data->idFrom, data->idTo,
1230 data->lpdwNumMsgs, data->lpdwNumBytes );
1231 return DPERR_UNSUPPORTED;
1232}
1233
1235{
1237 lpCB->Reply = DPWSCB_Reply;
1238 lpCB->Send = DPWSCB_Send;
1245 lpCB->GetCaps = DPWSCB_GetCaps;
1246 lpCB->Open = DPWSCB_Open;
1248 lpCB->CloseEx = DPWSCB_CloseEx;
1251 lpCB->SendEx = DPWSCB_SendEx;
1253 lpCB->Cancel = DPWSCB_Cancel;
1255
1256 lpCB->Close = NULL;
1257 lpCB->SendToGroup = NULL;
1258 lpCB->Shutdown = NULL;
1259}
1260
1261
1262
1263/******************************************************************
1264 * SPInit (DPWSOCKX.1)
1265 */
1267{
1268 WSADATA wsaData;
1269 DPWS_DATA dpwsData;
1270
1271 TRACE( "Initializing library for %s (%s)\n",
1272 wine_dbgstr_guid(lpspData->lpGuid), debugstr_w(lpspData->lpszName) );
1273
1274 /* We only support TCP/IP service */
1275 if ( !IsEqualGUID(lpspData->lpGuid, &DPSPGUID_TCPIP) )
1276 {
1277 return DPERR_UNAVAILABLE;
1278 }
1279
1280 /* Assign callback functions */
1281 setup_callbacks( lpspData->lpCB );
1282
1283 /* Load Winsock 2.0 DLL */
1284 if ( WSAStartup( MAKEWORD(2, 0), &wsaData ) != 0 )
1285 {
1286 ERR( "WSAStartup() failed\n" );
1287 return DPERR_UNAVAILABLE;
1288 }
1289
1290 /* Initialize internal data */
1291 memset( &dpwsData, 0, sizeof(DPWS_DATA) );
1292 dpwsData.lpISP = lpspData->lpISP;
1293 IDirectPlaySP_SetSPData( lpspData->lpISP, &dpwsData, sizeof(DPWS_DATA),
1294 DPSET_LOCAL );
1295
1296 /* dplay needs to know the size of the header */
1297 lpspData->dwSPHeaderSize = sizeof(DPSP_MSG_HEADER);
1298
1299 return DP_OK;
1300}
HRESULT WINAPI DECLSPEC_HOTPATCH SetThreadDescription(_In_ HANDLE hThread, _In_ PCWSTR lpThreadDescription)
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define ARRAYSIZE(a)
Definition: cat.c:25
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
HINTERNET connection
Definition: port.c:65
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
_ACRTIMP int __cdecl system(const char *)
Definition: process.c:1297
USHORT port
Definition: uri.c:210
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
INT WSAAPI WSAEnumNetworkEvents(IN SOCKET s, IN WSAEVENT hEventObject, OUT LPWSANETWORKEVENTS lpNetworkEvents)
Definition: event.c:94
BOOL WSAAPI WSASetEvent(IN WSAEVENT hEvent)
Definition: event.c:64
DWORD WSAAPI WSAWaitForMultipleEvents(IN DWORD cEvents, IN CONST WSAEVENT FAR *lphEvents, IN BOOL fWaitAll, IN DWORD dwTimeout, IN BOOL fAlertable)
Definition: event.c:75
INT WSAAPI WSARecv(IN SOCKET s, IN OUT LPWSABUF lpBuffers, IN DWORD dwBufferCount, OUT LPDWORD lpNumberOfBytesRecvd, IN OUT LPDWORD lpFlags, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: recv.c:155
INT WSAAPI WSAEventSelect(IN SOCKET s, IN WSAEVENT hEventObject, IN LONG lNetworkEvents)
Definition: select.c:182
INT WSAAPI sendto(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags, IN CONST struct sockaddr *to, IN INT tolen)
Definition: send.c:82
INT WSAAPI WSASend(IN SOCKET s, IN LPWSABUF lpBuffers, IN DWORD dwBufferCount, OUT LPDWORD lpNumberOfBytesSent, IN DWORD dwFlags, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: send.c:145
INT WSAAPI WSASendTo(IN SOCKET s, IN LPWSABUF lpBuffers, IN DWORD dwBufferCount, OUT LPDWORD lpNumberOfBytesSent, IN DWORD dwFlags, IN CONST struct sockaddr *lpTo, IN INT iToLen, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: send.c:247
#define DPCAPS_GUARANTEEDSUPPORTED
Definition: dplay.h:1072
#define DPERR_GENERIC
Definition: dplay.h:99
#define DPSET_REMOTE
Definition: dplay.h:1056
#define DPSET_LOCAL
Definition: dplay.h:1057
#define DPCAPS_ASYNCSUPPORTED
Definition: dplay.h:1080
#define DPSEND_GUARANTEED
Definition: dplay.h:1038
#define DPERR_CONNECTIONLOST
Definition: dplay.h:129
#define DPERR_UNSUPPORTED
Definition: dplay.h:118
#define DP_OK
Definition: dplay.h:88
#define DPERR_UNAVAILABLE
Definition: dplay.h:117
#define DPERR_OUTOFMEMORY
Definition: dplay.h:109
#define DPCAPS_GUARANTEEDOPTIMIZED
Definition: dplay.h:1071
#define DPSEND_ASYNC
Definition: dplay.h:1045
#define DPGETCAPS_GUARANTEED
Definition: dplay.h:1024
#define IDirectPlaySP_SetSPData(p, a, b, c)
Definition: dplaysp.h:109
#define IDirectPlaySP_SetSPPlayerData(p, a, b, c, d)
Definition: dplaysp.h:106
#define IDirectPlaySP_GetSPPlayerData(p, a, b, c, d)
Definition: dplaysp.h:104
#define DPLAYI_PLAYER_PLAYERLOCAL
Definition: dplaysp.h:59
#define IDirectPlaySP_HandleMessage(p, a, b, c)
Definition: dplaysp.h:105
#define IDirectPlaySP_GetSPData(p, a, b, c)
Definition: dplaysp.h:108
#define DPWS_MAXPLAYERS
Definition: dpwsockx_dll.h:36
void DPWS_COMPLETION_ROUTINE(DPWS_IN_CONNECTION *connection)
Definition: dpwsockx_dll.h:58
#define DPSP_MSG_SIZE(m)
Definition: dpwsockx_dll.h:136
#define DPSP_MSG_TOKEN_REMOTE
Definition: dpwsockx_dll.h:131
#define DPWS_MAXLOCALPLAYERS
Definition: dpwsockx_dll.h:33
#define DPWS_LATENCY
Definition: dpwsockx_dll.h:32
#define DPWS_HUNDREDBAUD
Definition: dpwsockx_dll.h:31
#define DPWS_MAXQUEUESIZE
Definition: dpwsockx_dll.h:30
struct tagDPSP_MSG_HEADER DPSP_MSG_HEADER
#define DPWS_GUARANTEED_MAXPLAYERS
Definition: dpwsockx_dll.h:38
#define DPWS_GUARANTEED_MAXBUFFERSIZE
Definition: dpwsockx_dll.h:37
#define DPWS_TIMEOUT
Definition: dpwsockx_dll.h:34
#define DPSP_MSG_MAKE_MIXED(s, t)
Definition: dpwsockx_dll.h:135
#define DPWS_MAXBUFFERSIZE
Definition: dpwsockx_dll.h:35
static HRESULT WINAPI DPWSCB_CloseEx(LPDPSP_CLOSEDATA data)
static HRESULT WINAPI DPWSCB_CreateGroup(DPSP_CREATEGROUPDATA *data)
#define DPWS_START_TCP_PORT
Definition: dpwsockx_main.c:34
static HRESULT WINAPI DPWSCB_SendToGroupEx(LPDPSP_SENDTOGROUPEXDATA data)
static int DPWS_CompareConnectionRefs(const void *key, const struct rb_entry *entry)
Definition: dpwsockx_main.c:64
static HRESULT WINAPI DPWSCB_GetAddress(LPDPSP_GETADDRESSDATA data)
static HRESULT WINAPI DPWSCB_GetAddressChoices(LPDPSP_GETADDRESSCHOICESDATA data)
#define DPWS_START_UDP_PORT
Definition: dpwsockx_main.c:36
HRESULT WINAPI SPInit(LPSPINITDATA lpspData)
#define DPWS_PORT
Definition: dpwsockx_main.c:33
static int DPWS_CompareConnections(const void *key, const struct rb_entry *entry)
Definition: dpwsockx_main.c:41
static HRESULT WINAPI DPWSCB_Reply(LPDPSP_REPLYDATA data)
#define DPWS_END_UDP_PORT
Definition: dpwsockx_main.c:37
static HRESULT WINAPI DPWSCB_ShutdownEx(LPDPSP_SHUTDOWNDATA data)
static HRESULT WINAPI DPWSCB_Send(LPDPSP_SENDDATA data)
static HRESULT DPWS_GetConnection(DPWS_DATA *dpwsData, SOCKADDR_IN *addr, BOOL guaranteed, DPWS_OUT_CONNECTION **connection)
static void DPWS_MessageBodyReceiveCompleted(DPWS_IN_CONNECTION *connection)
static HRESULT DPWS_BindToFreePort(SOCKET sock, SOCKADDR_IN *addr, int startPort, int endPort)
Definition: dpwsockx_main.c:71
static HRESULT WINAPI DPWSCB_DeleteGroup(DPSP_DELETEGROUPDATA *data)
static HRESULT WINAPI DPWSCB_GetMessageQueue(LPDPSP_GETMESSAGEQUEUEDATA data)
static HRESULT WINAPI DPWSCB_GetCaps(LPDPSP_GETCAPSDATA data)
static HRESULT WINAPI DPWSCB_DeletePlayer(LPDPSP_DELETEPLAYERDATA data)
static HRESULT DPWS_TcpReceive(DPWS_IN_CONNECTION *connection, void *data, DWORD size, DPWS_COMPLETION_ROUTINE *completionRoutine)
static void DPWS_HeaderReceiveCompleted(DPWS_IN_CONNECTION *connection)
static HRESULT WINAPI DPWSCB_SendEx(LPDPSP_SENDEXDATA data)
static HRESULT WINAPI DPWSCB_RemovePlayerFromGroup(DPSP_REMOVEPLAYERFROMGROUPDATA *data)
static HRESULT WINAPI DPWSCB_AddPlayerToGroup(DPSP_ADDPLAYERTOGROUPDATA *data)
static void WINAPI DPWS_TcpReceiveCompleted(DWORD error, DWORD transferred, WSAOVERLAPPED *overlapped, DWORD flags)
static void WINAPI DPWS_UdpReceiveCompleted(DWORD error, DWORD transferred, WSAOVERLAPPED *overlapped, DWORD flags)
static HRESULT WINAPI DPWSCB_EnumSessions(LPDPSP_ENUMSESSIONSDATA data)
static HRESULT WINAPI DPWSCB_Cancel(LPDPSP_CANCELDATA data)
static void DPWS_RemoveInConnection(DPWS_IN_CONNECTION *connection)
Definition: dpwsockx_main.c:97
static HRESULT DPWS_SendImpl(DPWS_DATA *dpwsData, DPWS_PLAYER *player, SGBUFFER *buffers, DWORD bufferCount, DWORD messageSize, BOOL guaranteed, BOOL system)
static HRESULT WINAPI DPWSCB_CreatePlayer(LPDPSP_CREATEPLAYERDATA data)
#define DPWS_END_TCP_PORT
Definition: dpwsockx_main.c:35
static void DPWS_Stop(DPWS_DATA *dpwsData)
static HRESULT DPWS_Start(DPWS_DATA *dpwsData)
static DWORD WINAPI DPWS_ThreadProc(void *param)
static void setup_callbacks(LPDPSP_SPCALLBACKS lpCB)
static HRESULT WINAPI DPWSCB_Open(LPDPSP_OPENDATA data)
#define L(x)
Definition: resources.c:13
#define IPPROTO_TCP
Definition: ip.h:197
#define IPPROTO_UDP
Definition: ip.h:198
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLboolean GLuint group
Definition: glext.h:11120
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat param
Definition: glext.h:5796
const GLuint * buffers
Definition: glext.h:5916
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
#define INADDR_BROADCAST
Definition: inet.h:82
#define INADDR_ANY
Definition: inet.h:80
#define error(str)
Definition: mkdosfs.c:1605
#define htons(x)
Definition: module.h:215
#define htonl(x)
Definition: module.h:214
HANDLE events[2]
Definition: event.c:4
#define closesocket
Definition: ncftp.h:477
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define calloc
Definition: rosglue.h:14
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
#define RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:26
#define RB_FOR_EACH_ENTRY_DESTRUCTOR(elem, elem2, tree, type, field)
Definition: rbtree.h:160
static int rb_put(struct rb_tree *tree, const void *key, struct rb_entry *entry)
Definition: rbtree.h:204
static struct rb_entry * rb_get(const struct rb_tree *tree, const void *key)
Definition: rbtree.h:192
#define RB_FOR_EACH_ENTRY(elem, tree, type, field)
Definition: rbtree.h:148
static void rb_remove(struct rb_tree *tree, struct rb_entry *entry)
Definition: rbtree.h:272
static void rb_init(struct rb_tree *tree, rb_compare_func_t compare)
Definition: rbtree.h:173
#define memset(x, y, z)
Definition: compat.h:39
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED * overlapped
Definition: sock.c:81
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
BOOL WSAAPI WSAGetOverlappedResult(IN SOCKET s, IN LPWSAOVERLAPPED lpOverlapped, OUT LPDWORD lpcbTransfer, IN BOOL fWait, OUT LPDWORD lpdwFlags)
Definition: sockctrl.c:603
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
#define TRACE(s)
Definition: solgame.cpp:4
SOCKADDR_IN addr
Definition: dpwsockx_dll.h:79
DPWS_OUT_CONNECTION * connection
Definition: dpwsockx_dll.h:96
struct rb_entry entry
Definition: dpwsockx_dll.h:94
DPWS_CONNECTION_KEY key
Definition: dpwsockx_dll.h:86
struct rb_entry entry
Definition: dpwsockx_dll.h:85
SOCKADDR_IN tcpAddr
Definition: dpwsockx_dll.h:51
SOCKADDR_IN udpAddr
Definition: dpwsockx_dll.h:52
struct rb_tree connectionRefs
Definition: dpwsockx_dll.h:103
ULONG len
Definition: ws2def.h:525
CHAR FAR * buf
Definition: ws2def.h:526
WSAEVENT hEvent
Definition: winsock2.h:607
Definition: copy.c:22
Definition: rbtree.h:30
Definition: tcpcore.h:1455
struct in_addr sin_addr
Definition: winsock.h:506
short sin_family
Definition: winsock.h:504
u_short sin_port
Definition: winsock.h:505
LPDPSP_GETADDRESS GetAddress
Definition: dplaysp.h:335
LPDPSP_GETMESSAGEQUEUE GetMessageQueue
Definition: dplaysp.h:349
LPDPSP_DELETEGROUP DeleteGroup
Definition: dplaysp.h:333
LPDPSP_SEND Send
Definition: dplaysp.h:328
LPDPSP_CLOSE Close
Definition: dplaysp.h:330
LPDPSP_SHUTDOWNEX ShutdownEx
Definition: dplaysp.h:343
LPDPSP_OPEN Open
Definition: dplaysp.h:337
LPDPSP_ENUMSESSIONS EnumSessions
Definition: dplaysp.h:326
LPDPSP_SHUTDOWN Shutdown
Definition: dplaysp.h:340
LPDPSP_REMOVEPLAYERFROMGROUP RemovePlayerFromGroup
Definition: dplaysp.h:338
LPDPSP_CANCEL Cancel
Definition: dplaysp.h:348
LPDPSP_GETADDRESSCHOICES GetAddressChoices
Definition: dplaysp.h:344
LPDPSP_CLOSEEX CloseEx
Definition: dplaysp.h:342
LPDPSP_SENDTOGROUP SendToGroup
Definition: dplaysp.h:339
LPDPSP_CREATEGROUP CreateGroup
Definition: dplaysp.h:331
LPDPSP_SENDEX SendEx
Definition: dplaysp.h:346
LPDPSP_REPLY Reply
Definition: dplaysp.h:327
LPDPSP_CREATEPLAYER CreatePlayer
Definition: dplaysp.h:332
LPDPSP_ADDPLAYERTOGROUP AddPlayerToGroup
Definition: dplaysp.h:329
LPDPSP_DELETEPLAYER DeletePlayer
Definition: dplaysp.h:334
LPDPSP_GETCAPS GetCaps
Definition: dplaysp.h:336
LPDPSP_SENDTOGROUPEX SendToGroupEx
Definition: dplaysp.h:347
struct rb_tree connections
Definition: dpwsockx_dll.h:124
struct list inConnections
Definition: dpwsockx_dll.h:113
char buffer[65536]
Definition: dpwsockx_dll.h:119
WSABUF wsaBuffer
Definition: dpwsockx_dll.h:118
SOCKADDR_IN tcpAddr
Definition: dpwsockx_dll.h:111
WSAEVENT stopEvent
Definition: dpwsockx_dll.h:128
CRITICAL_SECTION sendCs
Definition: dpwsockx_dll.h:121
WSAEVENT acceptEvent
Definition: dpwsockx_dll.h:112
SOCKADDR_IN udpAddr
Definition: dpwsockx_dll.h:116
SOCKET udpSock
Definition: dpwsockx_dll.h:115
SOCKET tcpSock
Definition: dpwsockx_dll.h:110
DPWS_PLAYER nameserver
Definition: dpwsockx_dll.h:122
WSAOVERLAPPED overlapped
Definition: dpwsockx_dll.h:117
LPDIRECTPLAYSP lpISP
Definition: dpwsockx_dll.h:108
LPDPSP_SPCALLBACKS lpCB
Definition: dplaysp.h:354
LPWSTR lpszName
Definition: dplaysp.h:356
IDirectPlaySP * lpISP
Definition: dplaysp.h:355
DWORD dwSPHeaderSize
Definition: dplaysp.h:360
LPGUID lpGuid
Definition: dplaysp.h:357
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:687
CHAR_INFO * newBuffer()
Definition: tconsole.cpp:995
#define MAKEWORD(a, b)
Definition: typedefs.h:248
PVOID HANDLE
Definition: typedefs.h:73
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1195
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WINAPI
Definition: msvc.h:6
#define WSAEWOULDBLOCK
Definition: winerror.h:2851
#define WSAEADDRINUSE
Definition: winerror.h:2864
#define WSA_WAIT_FAILED
Definition: winsock2.h:619
#define WSA_WAIT_EVENT_0
Definition: winsock2.h:620
#define WSA_INFINITE
Definition: winsock2.h:622
WINSOCK_API_LINKAGE WSAEVENT WSAAPI WSACreateEvent(void)
Definition: event.c:42
#define WSA_IO_PENDING
Definition: winsock2.h:610
DWORD WSAEVENT
Definition: winsock2.h:600
#define SOMAXCONN
Definition: winsock.h:393
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:131
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define INVALID_SOCKET
Definition: winsock.h:326
#define SOCK_DGRAM
Definition: winsock.h:330
UINT_PTR SOCKET
Definition: winsock.h:41
#define SOCKET_ERROR
Definition: winsock.h:327
#define SOL_SOCKET
Definition: winsock.h:392
#define SO_BROADCAST
Definition: winsock.h:177
#define FD_ACCEPT
Definition: winsock.h:402